Personal tools
You are here: Home Developer Infrastructure Teams Architecture Kepler Configuration Proposed Future Kepler Configuration System

Proposed Future Kepler Configuration System

This page documents ideas for configuration system that simplifies the configuration of Kepler and also provides more robust support for multiple modules. See bug 3948 for more information.

Goals (from #)

For modules to be effective, they need to be able to be configured at run time.  They need to be able to store configuration properties about their own state, and they must be able to read configuration properties about the other modules running in Kepler.  They also need to be able to modify existing configuration properties that control Kepler's existing extension points without overriding the entire global configuration set, as that almost instantly guarantees modules will be incompatible with one another.   Addressing these needs will be the focus of the Configuration system for Kepler 2.0.  However, changing the set of extension points and refactoring the GUI to provide new extension capabilities will not be part of this release.  The principal needs to be addressed by the configuration system should be:

 

Need for modules to be able to manage their own configuration properties.  This should include  a simple API for setting and reading configuration, a standardized approach for the system to load module configuration values at run time, and a way for modules to listen for property change events that might be initiated by other modules.

Need to consolidate configuration file serialization formats to allow easier management of configurations.

Need to be able to let modules set configuration properties in the *existing* Kepler system, allowing them to set configuration values that are compatible with the existing architecture and GUI (e.g., such as the names of factory classes)

 

Configuration System Requirements

1) A module is able to add configuration properties to the configuration

2) A module is able to read its own configuration properties

3) A module is able to add or override configuration properties added by other modules.

4) A module is able to overwrite another module's configuration properties

5) A module can indicate whether a property is mutable (i.e., if property changes are noticed and incorporated without restarting the application).  At runtime, only mutable properties can be overwritten.  It is the responsibility of all modules to utilize mutable properties to monitor those properties and respond appropriately to changes.

6) A configuration property can have either or both of a single scalar value or a list of subordinate configuration properties.  Subordinate configuration properties must have unique names within their parent property.

7) The configuration system is able to notify modules or other registered listeners that a configuration change has taken place

8) The configuration system is able to serialize each module's configuration properties as text

9) The configuration serialization should be able to store different language versions of each property file (internationalizable)

10)  Each module can have its own configuration and can organize its configuration into any number of namespaces, allowing the module to organize its properties into groups.  One use case for this is to allow a module to separate its UI strings from other configuration properties.

11) The configuration system is able to tell which module owns a configuration property

12) The configuration system is able to store default configuration properties separately from user-modified configuration properties. Consider whether user preference files, including loading and sharing of such files, is in scope or not.

13) The configuration system should be loaded under all variants of the Kepler application and should have minimal dependencies.

14) The configuration system should be able to store and make accessible documentation about configuration properties (name, description(s), etc.)

15) The configuration system stores strings only.  It is up to a module to cast strings to implied value types.
    -- desire to include data types as as part of the model (rather than only accept strings)
    -- desire to have utility methods for doing casting (e.g., getValueAsInt)
    -- change this requirement to:  The configuration system will support basic types.  If no type is specified, the type will default to String.
    -- basic types TBD.

16) The config system should define the set of allowable characters for use in names (e.g., no spaces, or should be java identifiers)

17) The configuration system should specifically consider if and how configuration values or sets of values from the command-line, environment variables, module.txt and other sources should be merged or provided with values from configuration files

Configuration Implementation Details

1) The configuration system will serialize each configuration property as a string

2) The configuration system will read default values from a module's resources/configurations directory

3) The configuration system will NOT write files to a module's resources/configurations directory because that directory can be inaccessible at runtime (i.e. in a jar file or in an administrator controlled directory).

4) The configuration system will write files to the appropriate location (TBD) in .kepler (using the DotKeplerManager.getModuleWriteableDirectory() or similar method to determine where to store files) 

5) The configuration system will notify all listeners when a configuration property is changed

6) A module will define a configuration property within a unique namespaces.  There will be a default namespace within each module for simplicity of use.

7) A module will listen for updates to its own as well as other modules' configuration changes

8) The system will not allow modules to change the value of a property based solely on its name.

Preliminary Proposed Class Structure


Misc Notes

Example configuration entries in the current config.xml file:

*Note: even though these structures are represented in XML, that does not mean that XML will be used as the serialization format for the configuration system.  These are just general structures found in the current Kepler configuration files.


<viewPaneTabPanes>
  <viewPane>
    <name>Kepler Classic</name>
    <viewPaneLocation>
      <location>W</location>
      <tabPane>Components</tabPane>
      <tabPane>Data</tabPane>
      <tabPane>Outline</tabPane>
    </viewPaneLocation>
    <viewPaneLocation>
      <location>E</location>
    </viewPaneLocation>
  </viewPane>
</viewPaneTabPanes>

<property>
  <name>_about</name>
  <class>ptolemy.kernel.attributes.FileAttribute</class>
  <value>$CLASSPATH/ptolemy/configs/kepler/intro.htm</value>
</property>
      
<property>
  <name>_applicationCopyright</name>
  <class>ptolemy.kernel.util.StringAttribute</class>
  <value>ptolemy/configs/kepler/copyright.htm</value>
</property>

<log_file>false</log_file>

Example of how this entry would map into the proposed structure:       

//Example to get the location property and associated properties
//Assume this information is stored in the 'core' Module
Module core = moduleTree.getModule("core");
ConfigurationManager config = ConfigurationManager.getInstance();
//get the list of 'veiewPaneTabPanes' from the configuration manager
List l = config.getProperty(core, "viewPaneTabPanes")
  .getProperty("viewPane")
    .getProperties("viewPaneLocation");
//get the first viewPaneLocation
ConfigurationProperty viewPaneLocationProp = (ConfigurationProperty)l.get(0);
//returns "W"
String location = viewPaneLocationProp.getProperty("location").getValue();
//note you could also iterate through this structure to get the other
//values that exist within the viewPaneLocation element

//example to get the values in all 'properties' elements
List l = config.getProperties(core, "property");
ConfigurationProperty prop1 = (ConfigurationProperty)l.get(0);
//returns "_about"
String name = prop1.getProperty("name").getValue();
//returns "$CLASSPATH/ptolemy/configs/kepler/intro.htm"
String value = prop1.getProperty("value").getValue();
ConfigurationProperty newprop2 = (ConfigurationProperty)l.get(1);
//get the values for the 2nd property
ConfigurationProperty prop2 = (ConfigurationProperty)l.get(1);
//returns _applicationCopyright
String name2 = prop2.getProperty("name").getValue();
//returns "ptolemy.kernel.util.StringAttribute"
String class2 = prop2.getProperty("class").getValue();

//example to get the log_file value
//returns "false"
String logFileValue = config.getProperty(core, "log_file").getValue();

Shortcut Naming

Because the use of nested getProperty() calls can be cumbersome, the getProperty and getProperties methods should also include the ability to use a shortcut naming system.  The Apache Commons Configuration project uses a system of dot notations do do this.  See the code below for an example.

//The call
List l = config.getProperty(core, "viewPaneTabPanes")
  .getProperty("viewPane")
    .getProperties("viewPaneLocation");
//would be replaced by
List l = config.getProperties(core, "viewPaneTabPanes.viewPane.ViewPaneLocation");

 

This would make the code much more readable and be less cumbersome to program.

 

 

Standard naming conventions for i18n internationalized files

foo.yaml

foo-string_en_US.yaml

foo-string_en_UK.yaml

foo-string_de.yaml

See also the Java i18n tutorial at http://java.sun.com/docs/books/tutorial/i18n/index.html

Technologies to consider for serialization

YAML

  http://yaml.org/type/index.html

  • Multiple Java implementations: JvYaml, SnakeYAML, YamlBeans, JYaml
  • nested simple text format
  • nesting delineated by indentation
  • data typing depends on implementation used but the YAML spec supports it
  • libraries for reading/writing yaml in many different languages
  • no apparent support for i18n in the java implementations 
  • Accessing nested data is hard (7 calls to get data nested 4 levels deep) unless you create custom java classes for each config section.

  http://commons.apache.org/sandbox/i18n/quickstart.html

  • Open source apache project
  • Multiple storage formats:
    • Properties files
    • XML documents
    • Windows INI files
    • Property list files (plist)
    • JNDI
    • JDBC Datasource
    • System properties
    • Applet parameters
    • Servlet parameters
  • Fully customizable storage schema
  • xpath-like shortcut system for accessing nested properties
  • Built in typed getters/setters.  i.e.:
    Double double = config.getDouble("number");
    
  • Built in event/error listeners
  • Support for i18n
  • Ability to mix heterogenous properties files into one configuration object


Java Resource Bundles

http://java.sun.com/docs/books/tutorial/i18n/resbundle/concept.html

  • Standard Java configuration system
  • no nesting, flat files only
  • full i18n support
  • well known and well supported file format and API
  • Strings only


JFig

http://jfig.sourceforge.net/

  • Open source project.  Last updated 2005.
  • Storage is in jFig custom XML schema
  • full framework for reading/writing properties
  • properties can be organized by section
  • nesting does not seem to be an option
  • allows variables within the config file
  • no apparent built in support for i18n
  • Strings only, no types
  • Built in event listeners
  • example:
<configuration>

<include name=”base.config.xml”/>

<section name=”locos”>
  <entry key=”instance” value=”development” />
</section>

<section name=”Paths”>
  <entry key=”locosHome” value=”d:/[locos]{instance}/project/” />
  <entry key=”locosExternal” value=”d:/external/[locos]{instance}/” />
</section>

<section name=”attachments”>
  <entry key=”attachmentDirectory” value=”[paths]{locosExternal}attachments/”/>
</section>

</configuration>

Document Actions