More on Using Configuration Manager

This section describes how to use configuration manager. For examples please see sample applications provided with the configuration manager and configuration manager tests provided with the source distribution of configuration manager.

Creating Configuration.xml file

Configuration.xml file is based on ConfigurationManagerSchema.xsd schema. By default it should be located in the "root of the class path". You can specify a different location/ filename to be used as a configuration by calling ConfigurationManagerFactory.setConfigurationFile() as a first call to the configuration management engine.

Configuration Manager file consists of several sections:

  • Root configuration manager with key - the top (root) level xml tag defining configuration manager and it's name:
    			<configurationManager 
    				xmlns="ConfigurationManagerSchema" 
    				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    				xsi:schemaLocation="ConfigurationManagerSchema ConfigurationManagerSchema.xsd "
    		
    				key="Test Configuration"
    				jmx="true"
    				>
    			
    Key will be used to retrieve this configuration (mainly for management purposes). JMX is a boolean entry, optional and true by default, which instructs configuration manager to register with an MBeanServer under "configurationManager:type=Manager" registration. You can use schema as defined above to be able to validate the configuration manager against the ConfigurationManagerSchema.xsd schema.
  • Log4J segment with key and filename - filename will define which log4j file to use for log4j configuration and key will be used to retrieve this configuration (mainly for management purposes). Once log4j configuration is parsed from the file specified, log4j engine is initialized with the configuration provided. You can have more than one log4j configuration, and you can use either XML or Property log4j configuration.
    				<log4j key="log4jProperties" fileName="part1Log4J.propeties" />
    				<log4j key="log4jXml" fileName="part2Log4J.xml" />
    			
    Log4J segment is a child of configuration manager segment.
  • Properties section with key and filename - filename will define which property file to load, and the key will be used to retrieve this configuration, for both your program and management purposes. You can have multiple property sections defined in you configuration manager file.
    				<properties key="testProps" fileName="test.properties" />
    			
    Properties segment is a child of configuration manager segment.
  • Simple xml section with key, filename and className - filename will define which xml file to load, className will define which class will get instantiated and loaded updated with values from the xml file, and key will be used to retrieve the instance of the class from the configuration manager.
    				<xml key="simplexml" fileName="simpleXml.xml" className="org.naftulin.configmgr.parsers.SimpleXml" />	
    			
    Simple xml segment is a child of configuration manager segment.
  • Database direct section with key, driver class, connection Url, sql, user, password, key colum name, value column name and set of name-value pair that are used when connection to the database is established.
    				<dbdirect key="dbproperty" 
    						driverClass="org.hsqldb.jdbcDriver"  
    						connectionURl="jdbc:hsqldb:file:config_test"		
    						sql="select key, value from config_test where 1=1"
    						user="sa"
    						password=""
    						keyColumnName="key"
    						valueColumnName="value" >
    						<param name="subKey1" value="subValue1" />
    				</dbdirect>	
    			
    Database direct segment is a child of configuration manager segment. Once database is accessed (during loading or reloading of the configuration), the Map object with key-value pairs is stored as configuration content where keys are read from key column and values are read from value column. The Map object is hashed then, and does not reflect changes in the underlying table, unless refresh command is issued via configuration manager.
  • Database jndi section with key, jndiName, initialContextFactory, sql, keyColumnName, valueColumnName, and set of name-value pair that are used when jndi context is created (via a call to new InitialContext(props))
    				<dbjndi key="dbJndiConfiguration" 
    						jndiName="jndi name to be looked up in container"  
    						initialContextFactory="optional class name for initial context factory"		
    						sql="select key, value from config_test where 1=1"
    						keyColumnName="key"
    						valueColumnName="value" >
    						<param name="subKey1" value="subValue1" />
    				</dbjndi>	
    			
    Database jndi segment is a child of configuration manager segment. Once database is accessed (during loading or reloading of the configuration), the Map object with key-value pairs is stored as configuration content where keys are read from key column and values are read from value column. The Map object is hashed then, and does not reflect changes in the underlying table, unless refresh command is issued via configuration manager.
  • Jndi section with key, jndiName, initialContextFactory, and set of name-value pair that are used when jndi context is created (via a call to new InitialContext(props)).
    				<jndi key="jndiConfiguration" 
    						jndiName="jndi name to be looked up in container"  
    						initialContextFactory="optional class name for initial context factory"		
    						 >
    						<param name="subKey1" value="subValue1" />
    				</jndi>	
    			
    Jndi segment is a child of configuration manager segment.
  • External configuration with key adaptor class and parameters - adapter class will determine which class will be instantiated when configuration manager needs to load a configuration or a reload message would be sent to. The adaptor class is responsible to communicate with configurations external to configuration manager, for example rule engine configuration. Parameters are name-value pair sub-elements of external configuration that allow adaptor to connect to/ manage the external configuration.
    				<external key="testExternal" configEntryAdaptorClass="org.naftulin.configmgr.parsers.DummyExternalAdapter">
    					<param name="subKey1" value="subValue1" />
    					<param name="subKey2" value="subValue2" />
    				</external>
    			
    External xml segment is a child of configuration manager segment.

Properties Files

To add properties configuration to your configuration manager, add a property configuration segment to the configuration file, as described in the above . To get the properties, once they are loaded into configuration manager use the following code:

				ConfigurationManager manager = ConfigurationManagerFactory.getConfigurationManager();
				Properties props = (Properties) manager.getConfiguration("yourKey");
			

Log4J files

To add log4j configuration to your configuration manager, add a log4j configuration segment to the configuration file, as described in the above . Once log4j configuration is loaded by the configuration manager, log4j engine is configured to log the categories specified in the file pointed by configuration manager. You can have multiple log4j configurations in you configuration manager file - though you might want to be careful with making sure that log4j appenders are not named identically.

Simple XML files

To add simple XML configuration to your configuration manager, add a xml configuration segment to the configuration file, as described in the above . XML configuration is based on betwixt implementation (Jakarta Commons), which by default uses simple XML <-> Java conversion. You can check a few tests that test XML behavior (distributed with the sources). The main idea is that if you have a <tag> in XML you will have a bean setter with the name getTag(SimpleType param) where simple type is int, float, String, etc. You can also get a collection of items loaded from your xmls. For example to get a collection of names descried as following in your xml:

				<names>
					<name>Abc</name>
					<name>Xyz</name>
				</names>
			
you can use the following Java code:
				private List names = new ArrayList();
				public void setNames(List names) { this.names = names; }
				public void addName(String name) { names.add(name); }
			
Please see sample application1 for example of an XML configuration. Note: please make sure that class name is the same as the top level of your xml configuration. For example if your class in com.you.ServerConfigs then please have XML start with <ServerConfigs> ... inner tags ... </ServerConfigs>

Database Direct Configuration

To add database configuration to your configuration manager, add a dbdirect configuration segment to the configuration file as described above . Once database direct configuration is loaded by the configuration manager, the content of database configuration is a Map with key, value pairs as read from the database table. You can have multiple direct dabase configuration is the same configuration file. One way to keep user/ passwords out of the development environment is to have token values in there, and have the token values be substituted at the build time.

Database JNDI Configuration

To add database configuration that gets connection from JNDI, add a dbjndi configuration segment to the configuration file as described above . Once database jndi configuration is loaded by the configuration manager, the content of database configuration is a Map with key, value pairs as read from the database table. You can have multiple direct dabase configuration is the same configuration file.

Object from JNDI Configuration

To have a configuration content read from JNDI, add a jndi configuration segment to the configuration file as described above . Once jndi configuration is loaded by the configuration manager, the content of jndi configuration is an object stored in the JNDI under the jndiName. The object is then read and cached in configuration manager, and is reloaded when a reload command is issued.

External Configurations

To add external XML configuration to your configuration manager, add an external configuration segment to the configuration file, as described in the above . Use external configuration when you need to adapt an external component that uses some form of configuration to your overall configuration strategy. Log4j is a good example - it needs a configuration file to be initialized and you might want to reload the log4j configuration. A rule engine would be another good example. To implement an adaptor for your external configuration you need to implement 2 methods: load and reload. Each method is passed a list of name-value pairs -- the same list that you specified in the configuration file. For each of the methods, get the values you need from the list and call an appropriate method in your target. For example for log4j the target method is PropertyConfigurator.configure() and parameter is a log4j configuration file. It is that simple!

Sample Applications

There are currently 2 sample applications that are shipped with configuration manager, located in binary distribution under sampleapps directory. To run, please change directory to sampleapps and run app1.bat or app2.bat. These applications read the configurations and the properties from sampleapps/config, display the properties and reload them. App1 is build as an interactive demonstrations, and App2 (source code App2Properties) is most probably the way one would be refactoring old code and adding configuration manager.

Sample Web Application

There is a sample web application that is shipped with configuration manager, located in binary distribution under samplewebapp/strutswebapp directory. To run, please deploy configmanagerwebapp.war in the web container. For example in tomcat, running on the local server you will use the url http://localhost:8080/configmanagerwebapp/. You should be able to see all the configurations loaded with configuration manager, and also check details on each of the configurations. For configurations that use properties (or sub-class of Map) you will also be able to overwrite values in web ui.

Thank you for visiting configuration manager page, hope this utility will make your project easier to code!

Henry