Note
This concept is valid to ICM version 7.10.11. For a later version of the document see Concept - Configuration (valid from 7.10.12).
The configuration framework is designed to let the administrator, not the developer, decide from where to read a configuration. The purpose of the configuration framework is to have the ability to ask one manager for a property, but to read, if necessary, from multiple sources.
The terms property and preference are used as synonyms in this context. The term configuration source is a placeholder for anything that can be a source for configurations, e.g., a file, a database table, an external resource etc.
The heart of the configuration is the file configuration.xml. This file includes the configuration of the configuration engine instance used at ConfigurationMgr.
Using the configuration framework is quite simple, as illustrated in the following examples. Every access is started at the ConfigurationMgr
(which starts a configuration engine and loads the configuration.xml).
import com.intershop.beehive.core.capi.configuration.ConfigurationMgr; // short notation to get string values String configString = ConfigurationMgr.getString("config.key.string","defaultValue") // long notation to get many types and other scopes Boolean configBool = ConfigurationMgr.getInstance().getConfiguration().getBoolean("config.key.boolean", true); // domain configuration Domain eTest = NamingMgr.getManager(DomainMgr.class).getDomainByName("eTest"); String configDomainString = ConfigurationMgr.getInstance().getConfiguration(eTest).getString("config.key.string", "defaultValue"); // or via domain - same thing other notation String configDomainString2 = eTest.getConfiguration().getString("config.key.string", "defaultValue");
These configuration examples are mostly used for debugging purposes or visualization in the SMC.
// get a configuration for scope=instance Configuration configInstance = ConfigurationMgr.getInstance().getInstanceConfiguration(); // get a configuration for scope=cluster Configuration configCluster = ConfigurationMgr.getInstance().getClusterConfiguration(); // full access to the configuration Configuration yourConfig = ConfigurationMgr.getInstance().getConfiguration(String scope, ConfigurationContext context);
The object path is often used in templates and queries. It is possible to access the configuration via the object path notation.
<isprint value="#CurrentSite:Configuration:String("<parameter>")#" /> <isprint value="#CurrentSite:Configuration:Integer(<group>.<subgroup>.<parameter-of-subgroup>)#" />
This file is located at ${IS_SHARE}/share/system/config/cluster; the source file can be found in <core-cartridge-source>/staticfiles/share/system/config/cluster.
<configuration-setup> <readers> <reader class="..." /> </readers> <finders> <finder name="..." class="..." /> </finders> <writers> <writer name="..." class="..." /> </writers> <scopes> <scope name="..." depends="..." /> </scopes> <sets> <set finder="..." scope="..." writer="..." defaultWriter="..." writableKeys="..." /> </sets> </configuration-setup>
<set fileName="..."/>
will trigger the setFileName(...)
methodNote
The order of the configuration sets (and associated writers) in this file is important. If you have to read from two different configuration sources, the property of the first will be returned as defined in the file.
The configuration engine can provide different configurations for different purposes. To this end, the concept of scopes was introduced. A scope is a logical structuring of configurations that are needed for this purpose.
Stating that a scope depends on (an)other scope(s) means that in order to load configurations for this scope (e.g., instance), you initially have to load all configurations on which this scope depends (startup). As startup uses the system configuration, which gives you any system properties (intershop.HomeDirectory),
the instance scope cannot be properly loaded as long as it depends on values from the startup scope.
The fact that one scope depends on another scope does not automatically mean that if you request a configuration for this scope, you will also have configuration sets of the dependent scopes in it. That is, if you request a configuration for the scope instance which depends on startup, any startup configuration set is not necessarily in the instance scope.
The following picture outlines the scopes currently used.
There is an implicit list of finders which provide URIs that can be read by the readers below.
Finder scheme | Attributes | Notes |
---|---|---|
system | read system and environment variables. All system variables will be prefixed with | |
app-folder |
| folder is predefined with ${IS_SHARE}/system/config/apps. The file name must match the |
cartridge |
| folder is predefined with ${IS_TARGET}/<cartridge-name>/release/config. The file name must match the "matches" attribute. The folder can be part of each source cartridge ${IS_SOURCE}/<cartridge-name>/staticfiles/cartridge/config and will be deployed automatically. |
cartridge-folder |
| folder is predefined with ${IS_SHARE}/system/config/cartridges. |
defaultprefs | default values from PreferenceDefinitionPO | |
domain-folder |
| folder is predefined with ${IS_SHARE}/system/config/domains. |
instance |
| read network interfaces to define instance-specific file |
preference | preference values from PreferencePO | |
property |
| read a single properties file |
xml |
| read a single XML file |
Configuration set will be configured with a finder and specific attribute values for this finder. Each attribute value can use the placeholder "${key}"
to reference an existing property of an upper scope. For example the sets for domain scope can use "cluster"
scoped configuration values.
The standard configuration.xml contains placeholders for system-specific folders and environments. The way it works, for example for environments, is shown below:
"environment=PRD"
) (is defined in scope "instance"
first).All "PRD"-specific configurations can be placed in "PRD.properties" if the configuration.xml contains the
<set finder="property" scope="cluster,server,domain" fileName="${IS_SHARE}/system/config/cluster/${environment}.properties"/>
The domain-specific configuration is more complex since a regular expression is used to check the matched files (e.g., PRD_uri.properties).
<set finder="domain-folder" scope="domain" matches="^${environment}_[\w&&[^_]]*$" fileExtensions="properties,xml"/>
In case domain properties should be environment and staging type dependent (staging.system.type
mostly defined at staging.properties
), an additional line in the configuration.xml will load such property files (e.g., PRD_editing_uri.properties).
<set finder="domain-folder" scope="domain" matches="^${environment}_${staging.system.type}_[\w&&[^_]]*$" fileExtensions="properties,xml"/>
This is the list of currently available readers (package names are abbreviated).
Reader (read URI) | Notes |
---|---|
ish-system | reads system environment |
ish-transient | provides access to the transient configuration set |
*.properties | only returns a configuration set for files ending with .properties |
*.xml | only returns a configuration set for files ending with .xml |
ish-preference | provides a configuration set that reads from preferences tables |
ish-defaultPreference | provides a configuration set that reads from preference definitions tables |
ish-domainFolder | provides a combined configuration set that has instances of configuration sets read from a folder that corresponds to the domain name (e.g., from ${IS_SHARE}/system/config/domains/<domain-name>_ |
ish-siteCartridge | provides a configuration combined set with instances of configuration sets for configuration files from ${IS_SHARE}/system/config/cartridges/_ for cartridges that are assigned to the current site |
The following writers are currently used:
Writer | Notes |
---|---|
transient | immediately updates the given configuration set, does not write the configuration to another place |
property | writes the given configuration set to the given URI as a property file, updates the given configuration set afterwards |
There should be at least one default writer in your system that will get any values set to the configuration framework - and not to lose them. Therefore, the transient writer has been created which updates the transient configuration set.
A writer will only be used to write keys he is allowed to write. To this end, the getWritableKeys()
function is used to check if a writer can write these keys. If no writer is found to write a key, the default writer will be used (if one is given).
someValue.
For development purposes, a reloading mechanism of property files has been implemented. It can be enabled by setting intershop.configuration.CheckSource
in appserver.properties to true
. The delay for checking (and necessarily reloading) the property files can be set using intershop.configuration.CheckSourceInterval
(which specifies the reloading interval in milliseconds).
A developer wants to open up an implementation for configuration values. So the developer has to include a line to get the configuration from the framework.
String value = ConfigurationMgr.getString(key,
defaultValue
);
Providing a default value in here is the direct and best way to do it, because the code does not depend on a further configuration step.
A developer of an application type can override this defaultValue
via a cartridge property file, located in the cartridge source directory <cartridge>/staticfiles/cartridge/config. These configurations are included with the configuration finder "cartridge".
Depending on the order in configuration.xml, you can put your configuration to these locations:
Purpose | Location |
---|---|
domain/site-specific configuration | IS_SHARE/system/config/domains/<domain-name> |
domain/site-specific and cartridge-specific | IS_SHARE/system/cartridges/<cartridge>/release/config or IS_TARGET/<cartridge>/release/config (depending on cartridge location) |
not site-specific / configuration coming with cartridges | IS_SHARE/system/config/cartridges |
instance/server-specific | IS_SHARE/system/config/servers |
Configuration values of business users should be stored in the database. Therefore, two possibilities are available, currently:
The developer of the business management application is responsible to decide which is the correct location of the property.
With Intershop 7 a new scope was introduced. The name of this scope is service and as it implies it is used for the Managed Service Framework.
A new finder, reader, and writer have been created for this scope. The finder creates URIs for the service scope which only the reader can read and for which only the writer is allowed to write.
The reader creates configuration sets which will look into the ServiceConfigurationPOAttributeValuePO
table using the ServiceConfigurationPO
which has to be provided in the context used to get the configuration values from the set.
The writer, on the other hand, writes in the same table, also using the ServiceConfigurationPO
provided in the context.
The service scope is somehow a standalone scope. If someone requests configurations from this scope, only one reader is triggered returning only one type of configuration set. Currently, you can be sure that this scope does not contain other properties than properties from the ServiceConfigurationPOAttributeValuePO
table, e.g., values from the appserver.properties or PreferencePO
table are not included. But of course, this can be changed any time by updating the configuration.xml file.