Configurations of components within ESF are controlled via the Configuration Manager (CM) Service. The CM can look complex but can be quite easy to use. It acts as a gateway between configuration providers and configuration consumers. The basic idea is that configurations may come from many places. They can come from the Cloud, a local web console, a plain text properties file, or via another bundle within ESF. Once received, they need to be distributed to the appropriate bundles that require those parameters. From there the bundles that receive the configurations can deal with them as needed. For example, say you have a configuration but the configuration is spread across three different bundles. Bundle A needs a binary File Object for its configuration, Bundle B expects a Properties Object for its configuration, and Bundle C needs an XML file for its configuration. The CM is able to parse a larger object into its smaller components and distribute them as needed to their appropriate services.
The CM can also archive configurations so individual bundles don’t have to. Depending on how a component chooses to implement the IConfigurableComponentService API, the CM can automatically archive the configuration to persistent storage.
A bundle is capable of receiving a configuration from the CM if it implements the com.esf.core.configuration.service.IConfigurableComponentService interface. By implementing this service, it is registering with the CM as an OSGi service to receive any configurations that come in for this bundle’s symbolic name. By implementing the interface, the bundle also has to implement the following method.
public Object receiveConfig(Object config) throws EsfConfigurationException;
This method is called by the CM any time a new configuration is received for this component. It is also called any time the bundle registers if the CM has an archived configuration for this component. This is handy in that the driving of the bundle is triggered by the CM at start up. The bundle only has to properly implement the receiveConfig method and doesn’t require two separate methods for starting up and for receiving a new configuration.
The Object sent from the CM to the implementer of the IConfigurableComponentService must be a Java Object. It must also be known to the implementer of the receiveConfig method in that it must know how to parse the configuration. The CM is unaware of the details of this Object other than it knows it is an Object.
The receiveConfig method can return in one of the following ways:
· Return an Object that represents the new configuration
o This should be done if the configuration was successfully parsed and valid. The Object should be stored in persistent memory in the CM.
o This ensures that on subsequent ESF startups the receiveConfig method will be called with the same Object.
· Return null
o This will cause the CM to not store the configuration in persistent memory.
o This is ideal if the configuration is for an OS-level component that stores the configuration elsewhere in persistent memory.
o This is also convenient for ‘one off’ actions. Bundles can essentially receive commands via the CM this way. For example, say a bundle typically receives a configuration as a Properties Object and we want to execute some commands by receiving a File Object. The receiveConfig method can check the Object type and put the new parameters into effect if needed or parse the file and execute some commands.
· Throw an EsfConfigurationException
o This should be done in the event that an invalid configuration is received. This tells the CM that the configuration was received but is not valid. This will in turn cause the CM to return an error to the provider of the configuration.
There are many different ways to provide configurations to a component. A bundle can provide the configurations via the com.esf.core.configuration.service.IEsfConfigProviderService, or a configuration may be received through some ‘native’ mechanisms within the CM itself. An example that is currently implemented is an HTTP Servlet at the address http://[ip_addr]/com/esf/core/configuration/cpi/HttpServer, if it is enabled. There are also some existing implementations of the IEsfConfigProviderService that enable web ui input mechanisms and also receipt of configurations from the Cloud service.
The IEsfConfigProviderService can be used by more than one component in a given system. It is simply an interface that allows configurations into the CM. The CM implements the IEsfConfigProviderService.
The following are four methods associated with this service:
public void submit(Hashtable props) throws Exception;
public Boolean configChangePending(String name);
public Hashtable getRejectedConfigs();
public String getSucceededConfigs();
The submit method is what is used to send configurations to the CM. The configuration is a Hashtable where the keys are the symbolic names of the bundles to receive the configurations and the values are the Objects that are the configurations. The CM will throw an Exception if one or more configurations are invalid or if the Hashtable is not correctly constructed.
The configChangePending method will return true if the configurations are still being processed. Otherwise, it will return false. The getRejectedConfigs and getSucceededConfig methods will return the configurations that were not properly received or were properly received respectively.
The CM also has some built-in mechanisms for receiving configurations. Currently, these mechanisms are via a web servlet that listens on http://[ip_addr]/com/esf/core/configuration/cpi/HttpServer. Figure 1 shows a screen shot of that interface.
The configuration file that is uploaded to the HTTP Servlet must be in a very specific form. As of this writing, there are two supported types. Types are defined by the com.esf.core.configuration.service.TypedConfigurationData. The two types currently supported are TCD_FILE_ZIP_1 and TCD_FILE_TGZ_1. These types are very similar to each other with the only difference being that one is a .zip file and the other is a .tgz file. The contents of the files are the same.
The TCD_FILE_ZIP_1 must be named tcd_file_zip_1.zip. The TCD_FILE_TGZ_1 must be named tcd_file_tgz_1.tgz. If they are not named appropriately, the CM will not be able to parse the contents of the file.
Each file contains a flat directory structure where the files are named by their symbolic name followed by an Object type. The Object types are also defined in the com.esf.core.configuration.service.TypedConfigurationData class that tells the CM what to cast the files to. The following is an example of a properties file that should be delivered to the com.esf.device.gps.ublox.lea5h bundle.
Another built-in way to send configs to the CM is to use the /opt/jvm/esf/deploy_config directory. The files that are placed in that directory should follow the same rules as the files that are inside the TCD_FILE_ZIP_1 or TCD_FILE_TGZ_1 files. The following is an example file that can be placed in the /opt/jvm/esf/deploy_config directory.
The CM checks this directory every five seconds for new configurations and deploys the configurations if they are present.