Server Configuration - ARCAD-Software/AFS GitHub Wiki
This article describe the configuration management of the AFS Server.
The AFS Server use, when run into an OSGi platform, the OSGi Configuration Admin Service to manage its configuration. AFS propose an implementation of this service, and Web-Services that allow to access to some parts of the configuration, allowing a dynamic configuration of the server itself through remote access.
TODO: needs some rewrite:
- The product chose the storage file format... Default format CFG.
The Configuration Admin service use a whiteboard pattern based on the OSGi service: org.osgi.service.cm.ManagedService. Each service is associated to a configuration block, identified by an unique and persistent identifier (PID).
For convenience the AFS class: AbstractConfiguredActivator which implement this service and internally manage it, by convention the PID is then equal to the Bundle symbolic name (note that you can change this convention by overriding the method getConfigurationID() method). By using this class you just have to override the following method and get the configuration parameters:
public void updatedConfiguration(Dictionary<String, Object> properties)
The abstract Activator class also offer facilities to retreive other configuration PID and update this configuration from the java code of any bundle.
Note that the methods parseBooleanParameter, parseStringParameter and parseIntegerParameter can help you to manage the configuration parameters.
As the usage of the configuration Admin is compatible with legacy implementations (Equinox or Felix ones), AFS propose its own implementation. To use it you just have to put the bundle com.arcadsoftware.cm.simple in your platform (and be sure to remove any other implementation). For a easier staring process ensure that this bundle have a start level lower than the default level, and should be lower than the Log too (as the logger use the configuration Admin too !).
This implementation manage 3 different kind of storage, depending on how the configuration files are organized.
- If there is a JSON file that have the same name than a PID configuration the file will be used to store the configuration of this PID.
- If there is a CFG file (a java Properties file format) that have the same name than a PID configuration the file will be used to store the configuration of this PID.
- All other PID will be stored into a unique INI file.
This order define a priority order, that means that the INI file is loaded first and then any CFG file override the configurations PID and than the JSON files do the same. And when the configuration it written back to the disk, if a JSON file exist it is used, if not and a CFG file exists this is the file that is used, and at last the IN file is used to store all other PID. So, as it is not recommended to use JSON and CFG and the INI files at the same time, this is a viable solution.
These files location is defined relatively to the location of the ini file. The default location of this file is equal to the osgi.configuration.area property, its name is "osgi.cm.ini", so in a standard Equinox platform this is equivalent to: ./configuration/osgi.cm.ini
If osgi.configuration.area is not set and the ./configuration folder does not exist the configuration will be stored into the user home directory.
This can be changed with the framework property osgi.cm.storefile (to put in the config.ini file), this property can point to a .ini file (the .ini extension is mandatory !) or to a directory name (anything which does not ends with .ini). In that case the Configuration Admin Service will not use a .ini file as a default storage and all configuration will be stored into .json or, by default, .cfg files.
These files are loaded as soon as the Configuration Admin Service is started. By default any modification of a configuration PID is immediately written back into its corresponding configuration file. Then these file should not be modified while the OSGi platform is running, because:
- The configuration will not be immediately be updated, a restart will be necessary.
- The file modification may be overwritten if the configuration is modified into the OSGi platform.
The storage mechanism can me modified by using the framework property cm.state:
- cm.state=ro or readonly will disable the record of the configuration modification into the file.
- cm.state=delay or delayed will postpone the record of the configuration modification at the moment when the com.arcadsoftware.cm.simple bundle is stopped (when the platform is shutting down). Note that if the platform crash then the configuration modification can be lost !
Each JSON file (extension .json) must have the same name than a PID, case sensitive. This file must contain an simple JSON object following the standard JSON Object format. Object key must be equal to the configuration parameters name and the value must be simples (integer, boolean or string values).
A "_comment" key is used to store human readable information about the configuration.
Just like the JSON files, the CFG files name must be equal to a configuration PID, plus the extension .cfg. These file must follow the Java properties file format.
The final ini file format (extension .ini) if a kind of extension ou the .cfg file indroducing a "section" markup. In this file each PID is stored in this own section, the section name is equal to the PID surrounded by brackets, with the following exceptions:
- The "org.ops4j.pax.logging" PID is store in a [ Log ] section.
- The "osgi.console.ssh" and the "osgi.console.telnet" are store in sections, respectivelly [ Console SSH ] and [ Console TELNET ].
- All PID starting with "com.arcadsoftware.server.restful" is replaced by a section name starting with "REST " and where each name part (separated by a dot) is replaced by the equivalent word with a capital.
- All PID starting with "com.arcadsoftware" (except the above) is replace with a section name in which each name part (separated by a dot) is replaced by the equivalent word with a capital.
All sections are stored by alphabetic order, and all parameters into the section too.
Multi-lines values are supported, by escaping the return carriage (with \ ). Simple values are automatically converted to java corresponding objects, like, Integer, Boolean or Date (formatted with ISO format dd-MM-yyyyThh:mm:ss,xxxxZ" in GMT).
The configuration section can be documented, by adding automatically a predefined comment. In the INI format each properties can be completed by such a comment.
To add this comments "documentations" files must be added to the com.arcadsoftware.cm.simple bundle, via fragments. Each PID configuration section can be documented with a .properties file stored into a docs/ sub folder, the file name must be the PID itself. These files can contain the following properties :
- section : Define the section name associated to the PID. It will be used into the INI file only. Ensure that this name is unique on your platform.
- comment : is a comment line that will be put into the begining of the section in the INI file, or on top of CFG or JSON file (in the "_comment" key).
- x.comment : is a comment that will be put right before the property x definition in the INI file.
- x.default : define a default value for the property x in case the PID is not present into the configuration. (not yet implemented)
- x.storage : define the location of another file where to store the value of given property. (not yet implemented)
The Administrative console is a set of Web-Service that allow to serve Form that can be acceded by the client to manage the application configuration remotely while the server is running. These web-services are:
- /remote/console : return the list (GET) of all sections declared into the administrative console (basically the "sections" are OSGi services).
- /remote/console/{section} : return (GET) the form associated with the given section idsentifier (find if the above sections list).
- /remote/console/{section}/{action} : This resource execute an action (POST or PUT) from the given section. the actions are defined into the section forms. All section normally provide at least one action, used to record the value of the form fields.
These services can return XML, JSON or XSD (to get the format of the XML representation).
The first usage of this console is to give access to the Configuration Admin services. To do so the easiest way is to put a consoles.xml file in the META-INF folder of the corresponding bundle, the one the configuration belong to. This file define the forms as it will be presented to the user through the web-services. A basic consoles.xml file looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<sections xmlns="http://xml.arcadsoftware.com/1.0.0/console.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xml.arcadsoftware.com/1.0.0/console.xsd http://xml.arcadsoftware.com/1.0.0/console.xsd">
<configuration
order="9999080"
messages="/consolemessages"
icon="29">
<property id="property.key" default="default value" />
...
</configuration>
</sections>
The important part of this file are:
- The property tag define a property field, the id is the property name (as defined into the Configuration Admin) and the default attribute contain a default value.
- The messages attribute define a java resource properties file which will be used to get the human readable information and eventually translate it into different languages.
The messages.properties file must contain (for the given consoles.xml sample !) the following properties:
- console.category which is the label in which the section will be presented.
- console.label the human readable name of this section.
- property.key which is the human readable label associated with the "property.key" configuration property.
- and optionally, property.key.help which an help message, a tip, associated woth the corresponding configuration property.
You may expose some configuration properties through a web-service to allow to the authenticated user to access to these values. This service is implemented by the bundle com.arcadsoftware.server.console.
To do so you have to put a property public.system.parameters in your configuration PID. The value of this property is the list of public properties name separated by spaces.
These properties will be readable (with method GET) through the web-service /config/{pid} or /config/{pid}/{property name}
The web-service /config/ will list all installed PID serving some public properties.
This article list some useful configuration properties that way be set for an AFS server.
Most of the properties must be set into the config.ini file.
org.ops4j.pax.logging.DefaultServiceLog.level
This property set the default level of the Pax-Logging facade before the real configuration is loaded, setting a level like WARN allow to get rid of the debugging information that Pax-Logging log itself during its start up.
restlog.file
This property allow to set the destination file of the "restlog" file, this file contain the port number of the started HTTP and HTTPS server. setting an empty to this property disable the generation of this file.
osgi.cm.storefile
This property define the folder, or the .ini file, used to store the OSGi configuration, see Server Configuration Guide for details. with the following properties:
- cm.state this property can be set to the value "ro" or "readonly" to set the configuration is a read-only mode. or to "delay" or "delayed" to delay the recording of all the configuration modification at the end of the execution of the server.
com.arcadsoftware.trace.sql.requests
This property define a log file name in which all SQL requests generated by the Metadata SQL Mapper will by stored.
this debugging property may be useful to detect required optimization, like indexes, in the SQL requesting.
java.util.logging.config.file
This property allow to configure the java native Logger (JUL). This logger is managed by pax-logging. There is nothing to do expect to configure the Pax-Logging APi, see Log Configuration, but due to a bug in the Restlet framework you have to set it to an empty value, or all libraries using the JUL API will not be logged correctly (including the Restlet framework itself).
osgi.console.*
These properties are related to the configuration SSH Console and the TELNET Console of Equinox.
along with the properties:
- org.eclipse.equinox.console.jaas.file
- java.security.auth.login.config
com.arcadsoftware.masterkey
This property set the Master Key used to encrypt all password with the secured encryption algorithm defined in the Crypto API.
This property, or one of its variant should be define in production environments.
This property work with the following:
- com.arcadsoftware.salt.*
- com.arcadsoftware.iv.*
- com.arcadsoftware.hash.*
- com.arcadsoftware.cypher.*
For more details see Security and cryptography.
com.arcadsoftware.trace
This boolean property enable a very low level debug messages, which are not assumed to be used in production environments. Moreover, it requires a log level equal to DEBUG to be activated.
⚠️ Note that the trace log level may expose sensitive information in the log files. This is considered as a security flaw.
com.arcadsoftware.trace.timing
This boolean property may activate some debug message with time measurement. It requires a log level equal to DEBUG to be activated.
com.arcadsoftware.acme.force.production
If set to true this boolean property will force the generation of a "production" certificate through the Let's Encrypt API.
com.arcadsoftware.security.headers.disabled
If set to true this option disable all the security related HTTP headers, including the CSP one (see bellow), the CORP and
⚠️ Using this option will disable the security of remote javascript served by the application. This is considered as a security flaw.
com.arcadsoftware.csp.*.sources
The following properties allow to specify the value of the Content-Security-Policy (CSP) HTTP header added to all response returned from the application server. By default this header limit the origins of referenced resources to the same server. With this options an application can allow other origins.
⚠️ Using these options may allow cross site script attacks from remote javascript program served by the application. This is considered as a security flaw.
- com.arcadsoftware.csp.image.sources: Define the accepted origins for images references.
- com.arcadsoftware.csp.media.sources: Define the accepted origins of media objects.
- com.arcadsoftware.csp.font.sources: Define the accepted origins for fonts.
- com.arcadsoftware.csp.style.sources: Define the accepted origins for CSS files.
- com.arcadsoftware.csp.script.sources: Define the accepted origins for JavaScript files.
More details at: https://developer.mozilla.org/en/docs/Web/HTTP/Headers/Content-Security-Policy
com.arcadsoftware.corsservice.disabled
If used this option disable the security management of the Cross Origin resouce Sharing (CORS).
Two other properties allow to define some properties of this service:
- com.arcadsoftware.corsservice.skip.options: If equals to true, the OPTIONS method of the server resource will not be accessible for CORS requests and the HTTP header Access-Control-Allow-Methods will be set with the default methods (which may not be the actual ones).
- com.arcadsoftware.corsservice.maxage: Define the Access-Control-Max-Age HTTP header value to the given one, in seconds, the default is that the header is not set.
Some other properties must be set through the JVM argument line: -Dosgi.signedcontent.support=authority
This property enable the verification of the bundle signature.