...
Code Block |
---|
|
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.management.api.ClusterManagementResult;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.client.ClusterManagementServiceProvider;
public class MyApp {
public static void main(String[] args) {
//1. Get the service instance using a specific URL endpoint
ClusterManagementService cms =
ClusterManagementServiceProvider.getService("http://localhost:7070/geode-management");
//2. Create the config object, these are just JAXB generated POJOs
RegionConfig regionConfig = new RegionConfig(); //These are JAXB generated configuration objects
regionConfig.setName("ACCOUNTS");
regionConfig.setType("REPLICATE");
//3. Invoke create, update, delete or get depending on what you want to do.
ClusterManagementResult result = cms.create(regionConfig, "cluster"); //Returns a result or throws an exception
//4. you can deal with status code, depends on your logic
String statusCode =result.getStatusCode().toString();
}
} |
Gliffy Diagram |
---|
| |
---|
size | 600 |
---|
name | onClient-Sequence |
---|
pagePin | 2 |
---|
|
On Server
Here's how one can use CMS on a server.
Code Block |
---|
|
public class MyFunction implements Function<String> {
@Override
public void execute(FunctionContext context) {
//1. Get the service instance using a specific URL endpoint
ClusterManagementService cms = ClusterManagementServiceProvider.getService();
//2. Create the config object, these are just JAXB generated POJOs
RegionConfig regionConfig = new RegionConfig(); //These are JAXB generated configuration objects
regionConfig.setName("ACCOUNTS");
regionConfig.setType("REPLICATE");
//3. Invoke create, update, delete or get depending on what you want to do.
ClusterManagementResult result = cms.create(regionConfig, "cluster"); //Returns a result or throws an exception
}
} |
Gliffy Diagram |
---|
| |
---|
size | 600 |
---|
name | onServer-Sequence |
---|
pagePin | 5 |
---|
|
Behind the scenes
Following the effort here, Configuration Persistence Service, we already have a set of configuration objects derived from the cache XML schema. This would serve a common object that the developer would use to configure the config instance. The developer would then ask the cluster management service to persist it, either on the cache (creating the real thing on an existing cache) or on the configuration persistence service (persisting the configuration itself).
Gliffy Diagram |
---|
| |
---|
size | 600 |
---|
name | ConfigElement |
---|
pagePin | 10 |
---|
|
On the locator side, the configuration service framework will just handle the workflow. It's up to each individual ClusterConfigElement to implement how it needs to be persisted and applied.
Pros and Cons:
Pros:
- A common interface to call either on the locator/server/client side
- A common workflow to enforce behavior consistency
- Modularized implementation. The configuration object needs to implement the additional interfaces in order to be used in this API. This allows us to add functionality gradually and per function groups.
Cons:
- Existing gfsh commands need to be refactored to use this API as well, otherwise we would have duplicate implementations, or have different behaviors between this API and gfsh commands.
- When refactoring gfsh commands, some commands' behaviors will change if they want to strictly follow this workflow, unless we add additional APIs for specific configuration objects.
Migration Strategy:
Our current commands uses numerous options to configure the behavior of the commands. We will have to follow these steps to refactor the commands.
- Combine all the command options into one configuration object inside the command itself.
- Have the command execution call the public API if the command conforms to the new workflow. In this step, the config objects needs to implement the ClusterConfigElement.
- If the command can't use the common workflow, make a special method in the API for that specific configuration object. (We need to evaluate carefully - we don't want to make too many exceptions to the common workflow.)
The above work can be divided into functional groups so that different groups can share the workload.
Once all the commands are converted using the ClusterManagementService API, each command class can be reduced to a facade that collects the options and their values, builds the config object and calls into the API. At this point, the command objects can exist only on the gfsh client.
The end architecture would look like this:
Project Milestones
- API is clearly defined
- All commands are converted using this API
- Command classes exist only on a gfsh client. The GfshHttpInvoker uses the REST API to call this ClusterConfigurationService with the configuration objects directly.