eXo Platform 3.0

- Prev
- Next

## Chapter 48. Container Configuration

## Intro

eXo Portal uses PicoContainer, which implements the Inversion of Control (IoC) design pattern. All eXo containers inherit from a PicoContainer. There are mainly two eXo containers used, each of them can provide one or several services. Each container service is delivered in a JAR file. This JAR file may contain a default configuration. The use of default configurations is recommended and most services provide it.

When a Pico Container searches for services and its configurations, each configurable service may be reconfigured to override default values or set additional parameters. If the service is configured in two or more places the configuration override mechanism will be used.

Confused? - You might be interested in the Service Configuration for Beginners article, which explains the basics.

## Kernel configuration namespace

To be effective, the namespace URI `http://www.exoplaform.org/xml/ns/kernel_1_1.xsd` must be target namespace of the XML configuration file.

    <xsd:schema
         targetNamespace="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
         xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         elementFormDefault="qualified"
         attributeFormDefault="unqualified"
         version="1.0">

       ...
    </xsd:schema>

## Understanding how configuration files are loaded

eXo Portal uses PicoContainer, which implements the Inversion of Control (IoC) design pattern. All eXo containers inherit from a PicoContainer. There are mainly two eXo containers used, each of them can provide one or several services. Each container service is delivered in a JAR file. This JAR file may contain a default configuration. The use of default configurations is recommended and most of services provide it.

When a Pico Container searches for services and its configurations, each configurable service may be reconfigured to override default values or set additional parameters. If the service is configured in two or more places, the configuration override mechanism will be used.

### Configuration Retrieval

The container performs the following steps to make eXo Container configuration retrieval, depending on the container type.

#### Configuration retrieval order for the `PortalContainer`

The container is initialized by looking into different locations. This container is used by portal applications. Configurations are overloaded in the following lookup sequence:

1. Services default `RootContainer` configurations from JAR files /conf/configuration.xml

2. External `RootContainer` configuration can be found at $AS_HOME/exo-conf/configuration.xml

3. Services default `PortalContainer` configurations from JAR files /conf/portal/configuration.xml

4. Web applications configurations from WAR files /WEB-INF/conf/configuration.xml

5. External configuration for services of named portal can be found at $AS_HOME/exo-conf/portal/$PORTAL_NAME/configuration.xml

#### Configuration retrieval for a `StandaloneContainer`

The container is initialized by looking into different locations. This container is used by non portal applications. Configurations are overloaded in the following lookup sequence:

1. Services default `RootContainer` configurations from JAR files /conf/configuration.xml

2. External `RootContainer` configuration can be found at $AS_HOME/exo-conf/configuration.xml

3. Services default `StandaloneContainer` configurations from JAR files /conf/portal/configuration.xml

4. Web applications configurations from WAR files /WEB-INF/conf/configuration.xml

5. Then depending on the `StandaloneContainer` configuration URL initialization:

   - if configuration URL was initialized to be added to services defaults, as below:

         // add configuration to the default services configurations from JARs/WARs
         StandaloneContainer.addConfigurationURL(containerConf);

     Configuration from added URL containerConf will override only services configured in the file

   - if configuration URL not initialized at all, it will be found at $AS_HOME/exo-configuration.xml. If $AS_HOME/exo-configuration.xml doesn't exist the container will try find it at $AS_HOME/exo-conf/exo-configuration.xml location and if it's still not found and the `StandaloneContainer` instance obtained with the dedicated configuration `ClassLoader` the container will try to retrieve the resource conf/exo-configuration.xml within the given `ClassLoader`.

#### General notes about the configuration retrieval

### Note

$AS_HOME - application server home directory, or user.dir JVM system property value in case of Java Standalone application.

### Note

$PORTAL_NAME - portal web application name.

### Note

External configuration location can be overridden with System property exo.conf.dir. If the property exists, its value will be used as path to eXo configuration directory, i.e. to $AS_HOME/exo-conf alternative. E.g. put property in command line java -Dexo.conf.dir=/path/to/exo/conf. In this particular use case, you do not need to use any prefix to import other files. For instance, if your configuration file is $AS_HOME/exo-conf/portal/PORTAL_NAME/configuration.xml and you want to import the configuration file $AS_HOME/exo-conf/portal/PORTAL_NAME/mySubConfDir/myConfig.xml, you can do it by adding <import>mySubConfDir/myConfig.xml</import> to your configuration file.

### Note

The name of the configuration folder that is by default "exo-conf", can be changed thanks to the System property exo.conf.dir.name.

### Note

Under JBoss application server exo-conf will be looked up in directory described by JBoss System property jboss.server.config.url. If the property is not found or empty $AS_HOME/exo-conf will be asked.

### Note

The search looks for a configuration file in each JAR/WAR available from the classpath using the current thread context classloader. During the search these configurations are added to a set. If the service was configured previously and the current JAR contains a new configuration of that service the latest (from the current JAR/WAR) will replace the previous one. The last one will be applied to the service during the services start phase.

### Warning

Take care to have no dependencies between configurations from JAR files (/conf/portal/configuration.xml and /conf/configuration.xml) since we have no way to know in advance the loading order of those configurations. In other words, if you want to overload some configuration located in the file /conf/portal/configuration.xml of a given JAR file, you must not do it from the file /conf/portal/configuration.xml of another JAR file but from another configuration file loaded after configurations from JAR files /conf/portal/configuration.xml.

After the processing of all configurations available in system, the container will initialize it and start each service in order of the dependency injection (DI).

The user/developer should be careful when configuring the same service in different configuration files. It's recommended to configure a service in its own JAR only. Or, in case of a portal configuration, strictly reconfigure the services in portal WAR files or in an external configuration.

There are services that can be (or should be) configured more than one time. This depends on business logic of the service. A service may initialize the same resource (shared with other services) or may add a particular object to a set of objects (shared with other services too). In the first case, it's critical who will be the last, i.e. whose configuration will be used. In the second case, it's no matter who is the first and who is the last (if the parameter objects are independent).

#### Configuration retrieval log

In case of problems with service configuration, it's important to know from which JAR/WAR it comes. For that purpose, the JVM system property org.exoplatform.container.configuration.debug can be used.

    java -Dorg.exoplatform.container.configuration.debug ...

If the property is enabled, the container configuration manager will log the configuration adding process at INFO level.

    ......
       Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.container-trunk.jar!/conf/portal/configuration.xml
       Add configuration jar:file:/D:/Projects/eXo/dev/exo-working/exo-tomcat/lib/exo.kernel.component.cache-trunk.jar!/conf/portal/configuration.xml
       Add configuration jndi:/localhost/portal/WEB-INF/conf/configuration.xml
            import jndi:/localhost/portal/WEB-INF/conf/common/common-configuration.xml
            import jndi:/localhost/portal/WEB-INF/conf/database/database-configuration.xml
            import jndi:/localhost/portal/WEB-INF/conf/ecm/jcr-component-plugins-configuration.xml
            import jndi:/localhost/portal/WEB-INF/conf/jcr/jcr-configuration.xml
       ......

#### Getting the effective configuration at Runtime

The effective configuration of the StandaloneContainer, RootContainer and/or PortalContainer can be known thanks to the method getConfigurationXML() that is exposed through JMX at the container's level. This method will give you the effective configuration in XML format that has been really interpreted by the kernel. This could be helpful to understand how a given component or plugin has been initialized.

### Advanced concepts for the PortalContainers

Since eXo JCR 1.12, we added a set of new features that have been designed to extend portal applications such as GateIn.

#### Add new configuration files from a WAR file

A `ServletContextListener` called `org.exoplatform.container.web.PortalContainerConfigOwner` has been added in order to notify the application that a given web application provides some configuration to the portal container, and this configuration file is the file WEB-INF/conf/configuration.xml available in the web application itself.

If your war file contains some configuration to add to the `PortalContainer` simply add the following lines in your web.xml file.

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                     "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
    ...
      <!-- ================================================================== -->
      <!--           LISTENER                                                 -->
      <!-- ================================================================== -->
      <listener>
        <listener-class>org.exoplatform.container.web.PortalContainerConfigOwner</listener-class>
      </listener>
    ...
    </web-app>

#### Creating your PortalContainers from a WAR file

A `ServletContextListener` called `org.exoplatform.container.web.PortalContainerCreator` has been added in order to create the current portal containers that have been registered. We assume that all the web applications have already been loaded before calling `PortalContainerCreator.contextInitialized`[.]``

### Note

In GateIn, the `PortalContainerCreator` is already managed by the file starter.war/ear.

#### Defining a PortalContainer with its dependencies and its settings

Now we can define precisely a portal container and its dependencies and settings thanks to the `PortalContainerDefinition` that currently contains the name of the portal container, the name of the rest context, the name of the realm, the web application dependencies ordered by loading priority (i.e. the first dependency must be loaded at first and so on..) and the settings.

To be able to define a `PortalContainerDefinition`, we need to ensure first of all that a `PortalContainerConfig` has been defined at the `RootContainer` level, see an example below:

      <component>
        <!-- The full qualified name of the PortalContainerConfig -->
        <type>org.exoplatform.container.definition.PortalContainerConfig</type>
        <init-params>
          <!-- The name of the default portal container -->
          <value-param>
            <name>default.portal.container</name>
            <value>myPortal</value>
          </value-param>
          <!-- The name of the default rest ServletContext -->
          <value-param>
            <name>default.rest.context</name>
            <value>myRest</value>
          </value-param>
          <!-- The name of the default realm -->
          <value-param>
            <name>default.realm.name</name>
            <value>my-exo-domain</value>
          </value-param>
         <!-- Indicates whether the unregistered webapps have to be ignored -->
         <value-param>
            <name>ignore.unregistered.webapp</name>
            <value>true</value>
         </value-param>
          <!-- The default portal container definition -->
          <!-- It cans be used to avoid duplicating configuration -->
          <object-param>
            <name>default.portal.definition</name>
            <object type="org.exoplatform.container.definition.PortalContainerDefinition">
              <!-- All the dependencies of the portal container ordered by loading priority -->
              <field name="dependencies">
                <collection type="java.util.ArrayList">
                  <value>
                    <string>foo</string>
                  </value>
                  <value>
                    <string>foo2</string>
                  </value>
                  <value>
                    <string>foo3</string>
                  </value>
                </collection>
              </field>
              <!-- A map of settings tied to the default portal container -->
              <field name="settings">
                <map type="java.util.HashMap">
                  <entry>
                    <key>
                      <string>foo5</string>
                    </key>
                    <value>
                      <string>value</string>
                    </value>
                  </entry>
                  <entry>
                    <key>
                      <string>string</string>
                    </key>
                    <value>
                      <string>value0</string>
                    </value>
                  </entry>
                  <entry>
                    <key>
                      <string>int</string>
                    </key>
                    <value>
                      <int>100</int>
                    </value>
                  </entry>
                </map>
              </field>
              <!-- The path to the external properties file -->
              <field name="externalSettingsPath">
                <string>classpath:/org/exoplatform/container/definition/default-settings.properties</string>
              </field>
            </object>
          </object-param>
        </init-params>
      </component>

Table 48.1. Descriptions of the fields of `PortalContainerConfig`

default.portal.container (*) | The name of the default portal container. This field is optional.
default.rest.context (*) | The name of the default rest `ServletContext`. This field is optional.
default.realm.name (*) | The name of the default realm. This field is optional.
ignore.unregistered.webapp (*) | Indicates whether the unregistered webapps have to be ignored. If a webapp has not been registered as a dependency of any portal container, the application will use the value of this parameter to know what to do: If it is set to false, this webapp will be considered by default as a dependency of all the portal containers. If it is set to true, this webapp won't be considered by default as a dependency of any portal container, it will be simply ignored. This field is optional and by default this parameter is set to false.
default.portal.definition | The definition of the default portal container. This field is optional. The expected type is `org.exoplatform.container.definition.PortalContainerDefinition` that is described below. Allow the parameters defined in this default `PortalContainerDefinition` will be the default values.

### Note

All the value of the parameters marked with a (*) can be defined thanks to System properties like any values in configuration files but also thanks to variables loaded by the PropertyConfigurator. For example in GateIn by default, it would be all the variables defined in the file configuration.properties.

A new `PortalContainerDefinition` can be defined at the `RootContainer` level thanks to an external plugin, see an example below:

      <external-component-plugins>
        <!-- The full qualified name of the PortalContainerConfig -->
        <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
        <component-plugin>
          <!-- The name of the plugin -->
          <name>Add PortalContainer Definitions</name>
          <!-- The name of the method to call on the PortalContainerConfig in order to register the PortalContainerDefinitions -->
          <set-method>registerPlugin</set-method>
          <!-- The full qualified name of the PortalContainerDefinitionPlugin -->
          <type>org.exoplatform.container.definition.PortalContainerDefinitionPlugin</type>
          <init-params>
            <object-param>
              <name>portal</name>
              <object type="org.exoplatform.container.definition.PortalContainerDefinition">
                <!-- The name of the portal container -->
                <field name="name">
                  <string>myPortal</string>
                </field>
                <!-- The name of the context name of the rest web application -->
                <field name="restContextName">
                  <string>myRest</string>
                </field>
                <!-- The name of the realm -->
                <field name="realmName">
                  <string>my-domain</string>
                </field>
                <!-- All the dependencies of the portal container ordered by loading priority -->
                <field name="dependencies">
                  <collection type="java.util.ArrayList">
                    <value>
                      <string>foo</string>
                    </value>
                    <value>
                      <string>foo2</string>
                    </value>
                    <value>
                      <string>foo3</string>
                    </value>
                  </collection>
                </field>
                <!-- A map of settings tied to the portal container -->
                <field name="settings">
                  <map type="java.util.HashMap">
                    <entry>
                      <key>
                        <string>foo</string>
                      </key>
                      <value>
                        <string>value</string>
                      </value>
                    </entry>
                    <entry>
                      <key>
                        <string>int</string>
                      </key>
                      <value>
                        <int>10</int>
                      </value>
                    </entry>
                    <entry>
                      <key>
                        <string>long</string>
                      </key>
                      <value>
                        <long>10</long>
                      </value>
                    </entry>
                    <entry>
                      <key>
                        <string>double</string>
                      </key>
                      <value>
                        <double>10</double>
                      </value>
                    </entry>
                    <entry>
                      <key>
                        <string>boolean</string>
                      </key>
                      <value>
                        <boolean>true</boolean>
                      </value>
                    </entry>
                  </map>
                </field>
                <!-- The path to the external properties file -->
                <field name="externalSettingsPath">
                  <string>classpath:/org/exoplatform/container/definition/settings.properties</string>
                </field>
              </object>
            </object-param>
          </init-params>
        </component-plugin>
      </external-component-plugins>

Table 48.2. Descriptions of the fields of a `PortalContainerDefinition` when it is used to define a new portal container

name (*) | The name of the portal container. This field is mandatory .
restContextName (*) | The name of the context name of the rest web application. This field is optional. The default value will be defined at the `PortalContainerConfig` level.
realmName (*) | The name of the realm. This field is optional. The default value will be defined at the `PortalContainerConfig` level.
dependencies | All the dependencies of the portal container ordered by loading priority. This field is optional. The default value will be defined at the `PortalContainerConfig` level. The dependencies are in fact the list of the context names of the web applications from which the portal container depends. This field is optional. The dependency order is really crucial since it will be interpreted the same way by several components of the platform. All those components, will consider the 1st element in the list less important than the second element and so on. It is currently used to: Know the loading order of all the dependencies. If we have several `PortalContainerConfigOwner` The `ServletContext` of all the `PortalContainerConfigOwner` will be unified, if we use the unified `ServletContext` (PortalContainer.getPortalContext()) to get a resource, it will try to get the resource in the `ServletContext` of the most important `PortalContainerConfigOwner` (i.e. last in the dependency list) and if it cans find it, it will try with the second most important `PortalContainerConfigOwner` and so on. The `ClassLoader` of all the `PortalContainerConfigOwner` will be unified, if we use the unified `ClassLoader` (PortalContainer.getPortalClassLoader()) to get a resource, it will try to get the resource in the `ClassLoader` of the most important `PortalContainerConfigOwner` (i.e. last in the dependency list) and if it can find it, it will try with the second most important `PortalContainerConfigOwner` and so on.
settings | A `java.util.Map` of internal parameters that we would like to tie the portal container. Those parameters could have any type of value. This field is optional. If some internal settings are defined at the `PortalContainerConfig` level, the two maps of settings will be merged. If a setting with the same name is defined in both maps, it will keep the value defined at the `PortalContainerDefinition` level.
externalSettingsPath | The path of the external properties file to load as default settings to the portal container. This field is optional. If some external settings are defined at the `PortalContainerConfig` level, the two maps of settings will be merged. If a setting with the same name is defined in both maps, it will keep the value defined at the `PortalContainerDefinition` level. The external properties files can be either of type "properties" or of type "xml". The path will be interpreted as follows: The path doesn't contain any prefix of type "classpath:", "jar:" or "file:", we assume that the file could be externalized so we apply the following rules: A file exists at ${exo-conf-dir}/portal/${portalContainerName}/${externalSettingsPath}, we will load this file. No file exists at the previous path, we then assume that the path cans be interpreted by the `ConfigurationManager`. The path contains a prefix, we then assume that the path cans be interpreted by the `ConfigurationManager`.

Table 48.3. Descriptions of the fields of a `PortalContainerDefinition` when it is used to define the default portal container

name (*) | The name of the portal container. This field is optional. The default portal name will be: If this field is not empty, then the default value will be the value of this field. If this field is empty and the value of the parameter default.portal.container is not empty, then the default value will be the value of the parameter. If this field and the parameter default.portal.container are both empty, the default value will be "portal".
restContextName (*) | The name of the context name of the rest web application. This field is optional. The default value wil be: If this field is not empty, then the default value will be the value of this field. If this field is empty and the value of the parameter default.rest.context is not empty, then the default value will be the value of the parameter. If this field and the parameter default.rest.context are both empty, the default value will be "rest".
realmName (*) | The name of the realm. This field is optional. The default value wil be: If this field is not empty, then the default value will be the value of this field. If this field is empty and the value of the parameter default.realm.name is not empty, then the default value will be the value of the parameter. If this field and the parameter default.realm.name are both empty, the default value will be "exo-domain".
dependencies | All the dependencies of the portal container ordered by loading priority. This field is optional. If this field has a non empty value, it will be the default list of dependencies.
settings | A `java.util.Map` of internal parameters that we would like to tie the default portal container. Those parameters could have any type of value. This field is optional.
externalSettingsPath | The path of the external properties file to load as default settings to the default portal container. This field is optional. The external properties files can be either of type "properties" or of type "xml". The path will be interpreted as follows: The path doesn't contain any prefix of type "classpath:", "jar:" or "file:", we assume that the file could be externalized so we apply the following rules: A file exists at ${exo-conf-dir}/portal/${externalSettingsPath}, we will load this file. No file exists at the previous path, we then assume that the path cans be interpreted by the `ConfigurationManager`. The path contains a prefix, we then assume that the path cans be interpreted by the `ConfigurationManager`.

### Note

All the value of the parameters marked with a (*) can be defined thanks to System properties like any values in configuration files but also thanks to variables loaded by the PropertyConfigurator. For example in GateIn by default, it would be all the variables defined in the file configuration.properties.

Internal and external settings are both optional, but if we give a non empty value for both the application will merge the settings. If the same setting name exists in both settings, we apply the following rules:

1. The value of the external setting is null, we ignore the value.

2. The value of the external setting is not null and the value of the internal setting is null, the final value will be the external setting value that is of type `String`.

3. Both values are not `null`, we will have to convert the external setting value into the target type which is the type of the internal setting value, thanks to the static method valueOf(String), the following sub-rules are then applied:

   1. The method cannot be found, the final value will be the external setting value that is of type `String`.

   2. The method can be found and the external setting value is an empty `String`, we ignore the external setting value.

   3. The method can be found and the external setting value is not an empty `String` but the method call fails, we ignore the external setting value.

   4. The method can be found and the external setting value is not an empty `String` and the method call succeeds, the final value will be the external setting value that is of type of the internal setting value.

#### `PortalContainer` settings

We can inject the value of the portal container settings into the portal container configuration files thanks to the variables which name start with "portal.container.", so to get the value of a setting called "foo", just use the following syntax ${portal.container.foo}. You can also use internal variables, such as:

Table 48.4. Definition of the internal variables

portal.container.name | Gives the name of the current portal container.
portal.container.rest | Gives the context name of the rest web application of the current portal container.
portal.container.realm | Gives the realm name of the current portal container.

You can find below an example of how to use the variables:

    <configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
      xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">
      <component>
        <type>org.exoplatform.container.TestPortalContainer$MyComponent</type>
        <init-params>
          <!-- The name of the portal container -->
          <value-param>
            <name>portal</name>
            <value>${portal.container.name}</value>
          </value-param>
          <!-- The name of the rest ServletContext -->
          <value-param>
            <name>rest</name>
            <value>${portal.container.rest}</value>
          </value-param>
          <!-- The name of the realm -->
          <value-param>
            <name>realm</name>
            <value>${portal.container.realm}</value>
          </value-param>
          <value-param>
            <name>foo</name>
            <value>${portal.container.foo}</value>
          </value-param>
          <value-param>
            <name>before foo after</name>
            <value>before ${portal.container.foo} after</value>
          </value-param>
        </init-params>
      </component>
    </configuration>

In the properties file corresponding to the external settings, you can reuse variables previously defined (in the external settings or in the internal settings) to create a new variable. In this case, the prefix "portal.container." is not needed, see an example below:

    my-var1=value 1
    my-var2=value 2
    complex-value=${my-var1}-${my-var2}

In the external and internal settings, you can also use create variables based on value of System paramaters. The System parameters can either be defined at launch time or thanks to the `PropertyConfigurator` (see next section for more details). See an example below:

    temp-dir=${java.io.tmpdir}${file.separator}my-temp

However, for the internal settings, you can use System parameters only to define settings of type `java.lang.String`.

It cans be also very usefull to define a generic variable in the settings of the default portal container, the value of this variable will change according to the current portal container. See below an example:

    my-generic-var=value of the portal container "${name}"

If this variable is defined at the default portal container level, the value of this variable for a portal container called "foo" will be value of the portal container "foo".

#### Adding dynamically settings and/or dependencies to a `PortalContainer`

It is possible to use `component-plugin` elements in order to dynamically change a PortalContainerDefinition. In the example below, we add the dependency `foo` to the default portal container and to the portal containers called `foo1` and `foo2`:

    <external-component-plugins>
      <!-- The full qualified name of the PortalContainerConfig -->
      <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
      <component-plugin>
        <!-- The name of the plugin -->
        <name>Change PortalContainer Definitions</name>
        <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
        <set-method>registerChangePlugin</set-method>
        <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
        <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
        <init-params>
          <value-param>
            <name>apply.default</name>
            <value>true</value>
          </value-param>
          <values-param>
            <name>apply.specific</name>
            <value>foo1</value>
            <value>foo2</value>
          </values-param>
          <object-param>
            <name>change</name>
            <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
              <!-- The list of name of the dependencies to add -->
              <field name="dependencies">
                <collection type="java.util.ArrayList">
                  <value>
                    <string>foo</string>
                  </value>
                </collection>
              </field>
            </object>
          </object-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

Table 48.5. Descriptions of the fields of a `PortalContainerDefinitionChangePlugin`

apply.all (*) | Indicates whether the changes have to be applied to all the portal containers or not. The default value of this field is `false`. This field is a `ValueParam` and is not mandatory.
apply.default (*) | Indicates whether the changes have to be applied to the default portal container or not. The default value of this field is `false`. This field is a `ValueParam` and is not mandatory.
apply.specific (*) | A set of specific portal container names to which we want to apply the changes. This field is a `ValuesParam` and is not mandatory.
`Rest of the expected parameters` | The rest of the expected paramaters are `ObjectParam` of type `PortalContainerDefinitionChange`. Those parameters are in fact the list of changes that we want to apply to one or several portal containers. If the list of changes is empty, the component plugin will be ignored. The supported implementations of PortalContainerDefinitionChange are described later in this section.

### Note

All the value of the parameters marked with a (*) can be defined thanks to System properties like any values in configuration files but also thanks to variables loaded by the PropertyConfigurator. For example in GateIn by default, it would be all the variables defined in the file configuration.properties.

To identify the portal containers to which the changes have to be applied, we use the follwing algorithm:

1. The parameter `apply.all` has been set to `true`. The corresponding changes will be applied to all the portal containers. The other parameters will be ignored.

2. The parameter `apply.default` has been set to `true` and the parameter `apply.specific` is `null`. The corresponding changes will be applied to the default portal container only.

3. The parameter `apply.default` has been set to `true` and the parameter `apply.specific` is not `null`. The corresponding changes will be applied to the default portal container and the given list of specific portal containers.

4. The parameter `apply.default` has been set to `false` or has not been set and the parameter `apply.specific` is `null`. The corresponding changes will be applied to the default portal container only.

5. The parameter `apply.default` has been set to `false` or has not been set and the parameter `apply.specific` is not `null`. The corresponding changes will be applied to the given list of specific portal containers.

##### The existing implementations of `PortalContainerDefinitionChange`

The modifications that can be applied to a `PortalContainerDefinition` must be a class of type `PortalContainerDefinitionChange`. The product proposes out of the box some implementations that we describe in the next sub sections.

###### `AddDependencies`

This modification adds a list of dependencies at the end of the list of dependencies defined into the `PortalContainerDefinition`. The full qualified name is org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies.

Table 48.6. Descriptions of the fields of an `AddDependencies`

dependencies | A list of String corresponding to the list of name of the dependencies to add. If the value of this field is empty, the change will be ignored.

See an example below, that will add `foo` at the end of the dependency list of the default portal container:

    <external-component-plugins>
      <!-- The full qualified name of the PortalContainerConfig -->
      <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
      <component-plugin>
        <!-- The name of the plugin -->
        <name>Change PortalContainer Definitions</name>
        <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
        <set-method>registerChangePlugin</set-method>
        <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
        <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
        <init-params>
          <value-param>
            <name>apply.default</name>
            <value>true</value>
          </value-param>
          <object-param>
            <name>change</name>
            <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependencies">
              <!-- The list of name of the dependencies to add -->
              <field name="dependencies">
                <collection type="java.util.ArrayList">
                  <value>
                    <string>foo</string>
                  </value>
                </collection>
              </field>
            </object>
          </object-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

###### `AddDependenciesBefore`

This modification adds a list of dependencies before a given target dependency defined into the list of dependencies of the `PortalContainerDefinition`. The full qualified name is org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesBefore.

Table 48.7. Descriptions of the fields of an `AddDependenciesBefore`

dependencies | A list of String corresponding to the list of name of the dependencies to add. If the value of this field is empty, the change will be ignored.
target | The name of the dependency before which we would like to add the new dependencies. If this field is `null` or the target dependency cannot be found in the list of dependencies defined into the `PortalContainerDefinition`, the new dependencies will be added in first position to the list.

See an example below, that will add `foo` before `foo2` in the dependency list of the default portal container:

    <external-component-plugins>
      <!-- The full qualified name of the PortalContainerConfig -->
      <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
      <component-plugin>
        <!-- The name of the plugin -->
        <name>Change PortalContainer Definitions</name>
        <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
        <set-method>registerChangePlugin</set-method>
        <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
        <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
        <init-params>
          <value-param>
            <name>apply.default</name>
            <value>true</value>
          </value-param>
          <object-param>
            <name>change</name>
            <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesBefore">
              <!-- The list of name of the dependencies to add -->
              <field name="dependencies">
                <collection type="java.util.ArrayList">
                  <value>
                    <string>foo</string>
                  </value>
                </collection>
              </field>
              <!-- The name of the target dependency -->
              <field name="target">
                <string>foo2</string>
              </field>
            </object>
          </object-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

###### `AddDependenciesAfter`

This modification adds a list of dependencies before a given target dependency defined into the list of dependencies of the `PortalContainerDefinition`. The full qualified name is org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesAfter.

Table 48.8. Descriptions of the fields of an `AddDependenciesAfter`

dependencies | A list of String corresponding to the list of name of the dependencies to add. If the value of this field is empty, the change will be ignored.
target | The name of the dependency after which we would like to add the new dependencies. If this field is `null` or the target dependency cannot be found in the list of dependencies defined into the `PortalContainerDefinition`, the new dependencies will be added in last position to the list.

See an example below, that will add `foo` after `foo2` in the dependency list of the default portal container:

    <external-component-plugins>
      <!-- The full qualified name of the PortalContainerConfig -->
      <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
      <component-plugin>
        <!-- The name of the plugin -->
        <name>Change PortalContainer Definitions</name>
        <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
        <set-method>registerChangePlugin</set-method>
        <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
        <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
        <init-params>
          <value-param>
            <name>apply.default</name>
            <value>true</value>
          </value-param>
          <object-param>
            <name>change</name>
            <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddDependenciesAfter">
              <!-- The list of name of the dependencies to add -->
              <field name="dependencies">
                <collection type="java.util.ArrayList">
                  <value>
                    <string>foo</string>
                  </value>
                </collection>
              </field>
              <!-- The name of the target dependency -->
              <field name="target">
                <string>foo2</string>
              </field>
            </object>
          </object-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

###### `AddSettings`

This modification adds new settings to a `PortalContainerDefinition`. The full qualified name is org.exoplatform.container.definition.PortalContainerDefinitionChange$AddSettings.

Table 48.9. Descriptions of the fields of an `AddSettings`

settings | A map of <String, Object> corresponding to the settings to add. If the value of this field is empty, the change will be ignored.

See an example below, that will add the settings `string` and `stringX` to the settings of the default portal container:

    <external-component-plugins>
      <!-- The full qualified name of the PortalContainerConfig -->
      <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
      <component-plugin>
        <!-- The name of the plugin -->
        <name>Change PortalContainer Definitions</name>
        <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
        <set-method>registerChangePlugin</set-method>
        <!-- The full qualified name of the PortalContainerDefinitionChangePlugin -->
        <type>org.exoplatform.container.definition.PortalContainerDefinitionChangePlugin</type>
        <init-params>
          <value-param>
            <name>apply.default</name>
            <value>true</value>
          </value-param>
          <object-param>
            <name>change</name>
            <object type="org.exoplatform.container.definition.PortalContainerDefinitionChange$AddSettings">
              <!-- The settings to add to the to the portal containers -->
              <field name="settings">
                <map type="java.util.HashMap">
                  <entry>
                    <key>
                      <string>string</string>
                    </key>
                    <value>
                      <string>value1</string>
                    </value>
                  </entry>
                  <entry>
                    <key>
                      <string>stringX</string>
                    </key>
                    <value>
                      <string>value1</string>
                    </value>
                  </entry>
                </map>
              </field>
            </object>
          </object-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

#### Disable dynamically a portal container

It is possible to use `component-plugin` elements in order to dynamically disable one or several portal containers. In the example below, we disable the portal container named `foo`:

    <external-component-plugins>
      <!-- The full qualified name of the PortalContainerConfig -->
      <target-component>org.exoplatform.container.definition.PortalContainerConfig</target-component>
      <component-plugin>
        <!-- The name of the plugin -->
        <name>Disable a PortalContainer</name>
        <!-- The name of the method to call on the PortalContainerConfig in order to register the changes on the PortalContainerDefinitions -->
        <set-method>registerDisablePlugin</set-method>
        <!-- The full qualified name of the PortalContainerDefinitionDisablePlugin -->
        <type>org.exoplatform.container.definition.PortalContainerDefinitionDisablePlugin</type>
        <init-params>
          <!-- The list of the name of the portal containers to disable -->
          <values-param>
            <name>names</name>
            <value>foo</value>
          </values-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

Table 48.10. Descriptions of the fields of a `PortalContainerDefinitionDisablePlugin`

names (*) | The list of the name of the portal containers to disable.

### Note

All the value of the parameters marked with a (*) can be defined thanks to System properties like any values in configuration files but also thanks to variables loaded by the PropertyConfigurator. For example in GateIn by default, it would be all the variables defined in the file configuration.properties.

To prevent any accesses to a web application corresponding to `PortalContainer` that has been disabled, you need to make sure that the following Http Filter (or a sub class of it) has been added to your web.xml in first position as below:

    <filter>
      <filter-name>PortalContainerFilter</filter-name>
      <filter-class>org.exoplatform.container.web.PortalContainerFilter</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>PortalContainerFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

### Note

It is only possible to disable a portal container when at least one PortalContainerDefinition has been registered.

## System property configuration

A new property configurator service has been developed for taking care of configuring system properties from the inline kernel configuration or from specified property files.

The services is scoped at the root container level because it is used by all the services in the different portal containers in the application runtime.

### Properties init param

The properties init param takes a property declared to configure various properties.

    <component>
      <key>PropertyManagerConfigurator</key>
      <type>org.exoplatform.container.PropertyConfigurator</type>
      <init-params>
        <properties-param>
          <name>properties</name>
          <property name="foo" value="bar"/>
        </properties-param>
      </init-params>
    </component>

### Properties URL init param

The properties URL init param allow to load an external file by specifying its URL. Both property and XML format are supported, see the javadoc of the `java.util.Properties` class for more information. When a property file is loaded the various property declarations are loaded in the order in which the properties are declared sequentially in the file.

    <component>
      <key>PropertyManagerConfigurator</key>
      <type>org.exoplatform.container.PropertyConfigurator</type>
      <init-params>
        <value-param>
          <name>properties.url</name>
          <value>classpath:configuration.properties</value>
        </value-param>
      </init-params>
    </component>

In the properties file corresponding to the external properties, you can reuse variables before defining to create a new variable. In this case, the prefix "portal.container." is not needed, see an example below:

    my-var1=value 1
    my-var2=value 2
    complex-value=${my-var1}-${my-var2}

### System Property configuration of the properties URL

It is possible to replace the properties URL init param by a system property that overwrites it. The name of that property is exo.properties.url.

## Runtime configuration profiles

The kernel configuration is able to handle configuration profiles at runtime (as opposed to packaging time).

### Profiles activation

An active profile list is obtained during the boot of the root container and is composed of the system property exo.profiles sliced according the "," delimiter and also a server specific profile value (tomcat for tomcat, jboss for jboss, etc...).

    # runs GateIn on Tomcat with the profiles tomcat and foo
    sh gatein.sh -Dexo.profiles=foo

    # runs GateIn on JBoss with the profiles jboss, foo and bar
    sh run.sh -Dexo.profiles=foo,bar

### Profiles configuration

Profiles are configured in the configuration files of the eXo kernel.

#### Profiles definition

Profile activation occurs at XML to configuration object unmarshalling time. It is based on an "profile" attribute that is present on some of the XML element of the configuration files. To enable this, the kernel configuration schema has been upgraded to kernel_1_1.xsd. The configuration is based on the following rules:

1. Any kernel element with the no profiles attribute will create a configuration object

2. Any kernel element having a profiles attribute containing at least one of the active profiles will create a configuration object

3. Any kernel element having a profiles attribute matching none of the active profile will not create a configuration object

4. Resolution of duplicates (such as two components with same type) is left up to the kernel

#### Profiles capable configuration elements

A configuration element is profiles capable when it carries a profiles element.

##### Component element

The component element declares a component when activated. It will shadow any element with the same key declared before in the same configuration file:

    <component>
      <key>Component</key>
      <type>Component</type>
    </component>

    <component profiles="foo">
      <key>Component</key>
      <type>FooComponent</type>
    </component>

##### Component plugin element

The component-plugin element is used to dynamically extend the configuration of a given component. Thanks to the profiles the component-plugins could be enabled or disabled:

    <external-component-plugins>
      <target-component>Component</target-component>
      <component-plugin profiles="foo">
        <name>foo</name>
        <set-method>addPlugin</set-method>
        <type>type</type>
        <init-params>
          <value-param>
            <name>param</name>
            <value>empty</value>
          </value-param>
        </init-params>
      </component-plugin>
    </external-component-plugins>

##### Import element

The import element imports a referenced configuration file when activated:

    <import>empty</import>
    <import profiles="foo">foo</import>
    <import profiles="bar">bar</import>

##### Init param element

The init param element configures the parameter argument of the construction of a component service:

    <component>
      <key>Component</key>
      <type>ComponentImpl</type>
      <init-params>
        <value-param>
          <name>param</name>
          <value>empty</value>
        </value-param>
        <value-param profiles="foo">
          <name>param</name>
          <value>foo</value>
        </value-param>
        <value-param profiles="bar">
          <name>param</name>
          <value>bar</value>
        </value-param>
      </init-params>
    </component>

##### Value collection element

The value collection element configures one of the value of collection data:

    <object type="org.exoplatform.container.configuration.ConfigParam">
      <field name="role">
        <collection type="java.util.ArrayList">
          <value><string>manager</string></value>
          <value profiles="foo"><string>foo_manager</string></value>
          <value profiles="foo,bar"><string>foo_bar_manager</string></value>
        </collection>
      </field>
    </object>

##### Field configuration element

The field configuration element configures the field of an object:

    <object-param>
      <name>test.configuration</name>
      <object type="org.exoplatform.container.configuration.ConfigParam">
        <field name="role">
          <collection type="java.util.ArrayList">
            <value><string>manager</string></value>
          </collection>
        </field>
        <field name="role" profiles="foo,bar">
          <collection type="java.util.ArrayList">
            <value><string>foo_bar_manager</string></value>
          </collection>
        </field>
        <field name="role" profiles="foo">
          <collection type="java.util.ArrayList">
            <value><string>foo_manager</string></value>
          </collection>
        </field>
      </object>
    </object-param>

## Component request life cycle

### Component request life cycle contract

The component request life cycle is an interface that defines a contract for a component for being involved into a request:

    public interface ComponentRequestLifecycle
    {
       /**
        * Start a request.
        * @param container the related container
        */
       void startRequest(ExoContainer container);

       /**
        * Ends a request.
        * @param container the related container
        */
       void endRequest(ExoContainer container);
    }

The container passed is the container to which the component is related. This contract is often used to setup a thread local based context that will be demarcated by a request.

For instance in the GateIn portal context, a component request life cycle is triggered for user requests. Another example is the initial data import in GateIn that demarcates using callbacks made to that interface.

### Request life cycle

The `RequestLifeCycle` class has several statics methods that are used to schedule the component request life cycle of components. Its main responsability is to perform scheduling while respecting the constraint to execute the request life cycle of a component only once even if it can be scheduled several times.

#### Scheduling a component request life cycle

    RequestLifeCycle.begin(component);
    try
    {
       // Do something
    }
    finally
    {
       RequestLifeCycle.end();
    }

#### Scheduling a container request life cycle

Scheduling a container triggers the component request life cyle of all the components that implement the interface `ComponentRequestLifeCycle`. If one of the component has already been scheduled before and then that component will not be scheduled again. When the local value is true, then the looked components will be those of the container, when it is false then the scheduler will also look at the components in the ancestor containers.

    RequestLifeCycle.begin(container, local);
    try
    {
       // Do something
    }
    finally
    {
       RequestLifeCycle.end();
    }

### When request life cycle is triggered

#### Portal request life cycle

Each portal request triggers the life cycle of the associated portal container.

#### JMX request Life Cycle

When a JMX bean is invoked, the request life cycle of the container to which it belongs it scheduled. Indeed JMX is an entry point of the system that may need component to have a request life cycle triggered.

- Prev
- Up
- Home
- Next