Overview
The
org.lsst.ccs.config package deals with configuration data.
Data used to fire subsystems and modules may be modified for testing purposes or to run the code
in specific conditions.
This data is registered to a database so it can be queried to run a worker subsystem
and to know about any parameter value which was used at a given moment in time.
This means that the database registers configuration data and worker subsystem executions
(An agent on the buses listens to subsystem start and end operations and must know
which configuration set was used).
Data describing a subsystem and its configuration is split in two parts:
- Description data: created and edited by subsystem designers.
The initial descriptions of components and the properties of their parameters is in a resource file.
The internal java structure used to describe and start a subsystem is an instance of DescriptiveNode
(a "tree" structure). These can be generated from a Groovy DSL (Domain Specific Language) or from plain Java code.
Thus the resource file can be a Serialized java object or a Groovy text that is dynamically compiled at runtime.
This java Object can be used to extract information to create Description objects that will be stored
in the database. Parameter data is stored in a Set of ConfigurationParameter objects referenced by the
overall description object.
Parameter descriptions can be directly extracted from detailed information contained in the DescriptiveNode
object but it can also be edited and modified through a GUI before a description is saved through the Configuration
Service.
- Configuration data: created and edited by engineers.
This data modifies a standard description that has been previously stored by the Configuration Service.
The "edition" of this configuration data can be through text ( a simple ".properties" file) or through a GUI.
A configuration object is an instance of Configuration and contains a set of ConfigurationParameterValue.
Each ConfigurationParameterValue object references the corresponding ConfigurationParameter
So modifications to parameter values can be checked as soon as possible by matching the value to the description
constraints.
Other Objects are stored in the database :
- PreparedConfiguration that contains a "ready to use" component node that results from the merging
of default description data with data modified by a configuration
(todo: reassess the need or use of this data)
- MachineConfiguration that describes the configuration to be run by a specific machine (known by its
MacAddress).
- ConfigurationRun which tells which subsystem with which configuration was running at any moment in time
Since historical data is important to know what happened the deprecated descriptions and configurations are kept in the
database. Each deprecated Data is described by a different class with slightly different properties.
Important note: objects that are "alive" and objects that are "in history" should be recorded
in different database tables. This pattern is important for databse management.
There are right now two exceptions (that may need to modify the code)
- ConfigurationRun : (may be we should create a table of active runs,)
- MachineConfiguration : (should we historicise these?)
So , due to this dual vision ("alive" and "in history"), each description or configuration is known by client codes through abstract classes and there are different
actual (package friendly) subclasses to describe objects that are "alive" and object that are deprecated.
Thus :
- Description is subclassed by ADescription for "active" objects
and by GhostDescription objects.
The Ghost objects are peculiar: they are created in parallel with the active object
they represent but they are ready to handle deprecation. Suppose you have a Configuration X
that references Description Y, and now Configuration X is deprecated before Y. then the deprecated
X references the ghost object. When Y is deprecated then only the "end date" of the ghost object
is modified.
- ConfigurationParameter is subclassed by AConfigurationParameter
and GhostConfigurationParameter
- Configuration is subclassed by AConfiguration and PastConfiguration
(these are not "ghost" objects: they are created only when the object is deprecated)
- ConfigurationParameterValue is subclassed by AConfigurationParameterValue
and PastConfigurationParameterValue
The reason for the presence of "ghost" objects if this:
- when you deprecate a Description then you will deprecate all
Configuration that reference it.
But if deprecated Configurations referenced an active Description the result
will be wrong. So deprecated Configurations should point to a ghost instead of an
active description.
All these objects are immutable once registered in the database (except date for ghost objects, and list of values
in
ConfigurationParameterValue objects handled during engineering mode)
The handling of complex strategies on top of the database is made through a
ConfigurationFacade
Object. But this is still a rather low level methods collection.
So client codes are encouraged to use higher level codes that deal only with abstract classes:
- the Factories class provides static factory methods to create/copy objects
(todo: make this class package protected and accessed only through ConfigurationFacade)
- the remote.ConfigurationService interface and its implementations give access to
a simpler "Configuration service"
A Collection of codes that can be used to start a subsystem can be found in the
org.lsst.ccs.startup package: some use purely local data, some use a remote configuration
service.
Implementation of Configuration server can be found in org.lsst.ccs.config.remote
package.