Placeful Configuration

Table of Contents

25.1. Introduction
25.2. Using Placeful Configuration
25.3. Contributing a placeful configuration
25.4. Available storage
25.4.1. In memory storage
25.4.2. Directory storage
25.5. Exemple of extension definition

25.1. Introduction

The placeful configuration service allows configuration to be placed on a node in a repository. It is possible to update, remove this configuration and merged it with all the configuration located from this node to the root of the repository.

Placeful Configuration (PC in the rest of this chapter) is useful when you have a number of nodes much bigger than the number of configuration. It allows to change and merge these configuration without having to travel the repository tree.

25.2. Using Placeful Configuration

The PlacefulConfigurationManager is used for all interaction with PC. This service is available via the extension point org.nuxeo.ecm.platform.placeful.configuration.service.PlacefulConfigurationService. Before using it, you need to associate a configuration with a storage in the component definition ???.

You can then use the placeful configuration service. The following code snippet show the basic usage:

Path p1 = new Path("/mon/path");
RepositoryLocation repo = new RepositoryLocation("monrepo");
NuxeoPrincipal principal = new NuxeoPrincipalImpl("myself");

PlacefulConfigurationManager pcs = Framework.getService(PlacefulConfigurationManager.class);
LocalTheme lt1 = pcs.createConfigurationEntry(LocalTheme.class, p1, repo, principal);
lt1.setMode("myMode");
pcs.saveConfigurationEntry(lt1);

Map<String, Object> map = new HashMap<String, Object>();
map.put("mode", "myMode");
List<LocalTheme> list =  pcs.getAllConfigurations(LocalTheme.class, map);                (1)

LocalTheme lt = pcs.getConfiguration(LocalTheme.class, repo, p, principal);
LocalTheme ltMerge = pcs.getMergedConfiguration(LocalTheme.class, repo, p, principal);
pcs.removeConfiguration(LocalTheme.class, repo, p1, principal);
1

Query the storage for all the PC that have those field/value.

Note that:

  • you never create a PlacefulConfiguration yourself but ask the manager for one.

  • You need to save the PC after modification.

  • You can not move a PC, you need to remove it and create a new one.

For more information on available methods and class, have a look at the Javadoc.

25.3. Contributing a placeful configuration

A PC is composed of two distinct types of information:

  • The information specific to this configuration, for example, a local theme configuration has a mode, a page or a docId.

  • The information relative to its "placefulness": the path, principal and repository.

To contribute a configuration to the service you only have to gives the information specific to the configuration. The "placeful" part is taken care of by the service. You also need to give a way to merge the PC. We will create a simple config as an exemple. A "Simple" PC that has only one field: value.

  • Create an interface specific for your configuration.

    interface SimpleConfig {
        setValue();
        getValue();
    }
              
  • Create the empty interface that will be manipulated by the user. It needs to extends PlacefulConfiguration, Serializable and your specific interface.

    public interface Simple extends PlacefulConfiguration, SimpleConfig, Serializable {}
              
  • Create the implementation of the specific configuration. It needs to implement your specific interface and PlacefulConfigurationConfig. The PlacefulConfigurationConfig interface adds the getAssociatedInterface() methods. It returns the "user" interface:

    SimpleConfigImpl implements SimpleConfig, PlacefulConfigurationConfig {
        private String value;
        public String getValue() {
             return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        public Class<Simple> getAssociatedInterface() {
            return Simple.class;
        }
    }
              
  • Create the class for the merge algorithm. It has to implement PlacefulConfigurationAlgorithm. Its only method takes a PC and a storage and returns a merged PC. Our Simple configuration will do no merge at all:

    public class SimpleMergeAlgorithm implements PlacefulConfigurationMergeAlgorithm {
        Simple mergeEntries(Simple pc, PlacefulConfigurationStorage storage) {
            return pc;
        }
    }
                
  • Finally the "user" interface has to know the implementing and merge class. You add the @configurationClass annotation on the "user" interface:

    @ConfigurationClass(value=SimpleConfigImpl.class, mergeAlgorithm=SimpleMergeAlgorithm.class)
    public interface Simple extends PlacefulConfiguration, SimpleConfig, Serializable {};
              
  • If you want your PC to be usable by a Directory storage you also need to provide a schema Section 25.4.2, “Directory storage”

In most case you want your merge algorithm to merge all entries from the root to the node of the configuration. For this, you can extend the class AbstractBaseMergeAlgorithm. You then only need to add a method to merge 2 entries.

If your PC is a simple JavaBean, then you can extend BeanMergeAlgorithm . The only things you need to pass is the class of your bean. For each property, the merge algorithm will return the nearest value from the node that is not null.

25.4. Available storage

A storage specifies where the configuration is stored. You can pass specific values to each storage using the properties map (see Section 25.5, “Exemple of extension definition”). The storage gives you also the possibility to define fields that will be indexed. When a user query the storage, only the indexed fields can be queried. At the moment, only String field can be queried and indexed.

It is assumed that an indexed field is a property of the PC and so available via getters. By default, all the "placeful" values (principal, path, repository) are indexed and don't need to be added to the fields list.

25.4.1. In memory storage

The InMemory storage does not use any persistence. You should only use in it in very simple situation such as test. The storageBackend class is: org.nuxeo.ecm.platform.placeful.configuration.storage.InMemoryPlacefulConfigurationStorage. You can pass comma-separated values in the fields property. Each value represent a property of the PC. In the backend, an index will be created for each property. You can then use it as a search field in the map passed to manager to find configurations (Section 25.2, “Using Placeful Configuration”).

25.4.2. Directory storage

org.nuxeo.ecm.platform.placeful.configuration.storage.SQLDirectoryPlacefulConfigurationStorage implements the storageBackend. You pass it as the class attribute. You also need to add the name of you directory:

<storageBackend name="SQL"
    class=
"org.nuxeo.ecm.platform.placeful.configuration.storage.SQLDirectoryPlacefulConfigurationStorage">
  <properties>
    <property name="directoryName">localTheme</property>
  </properties>
</storageBackend>

To use directory storage you need to define a directory and the associated schema. The schema only needs to include the base.xsd schemaLocation and the placefulConfiguration.xsd schemaLocation. You can also add any String element that you want to be indexed. Note that the "placeful" fields general for all configurations are included by default and don't need to be added.

Don't forget to declare the schema and directory to the extension point. It is assumed that each field to be indexed is a property of the PC and can be accessed by getters.

25.5. Exemple of extension definition

<component
    name="org.nuxeo.ecm.platform.placeful.configuration.defaultContrib">

  <extension
      target=
"org.nuxeo.ecm.platform.placeful.configuration.service.PlacefulConfigurationService"
      point="storage">                                                                   (1)(2)

    <storageBackend name="RAM"
        class=
"org.nuxeo.ecm.platform.placeful.configuration.storage.InMemoryPlacefulConfigurationStorage">
      <properties>
        <property name="fields">docId,theme,mode</property>                              (3)
      </properties>
    </storageBackend>

  </extension>

  <extension
      target=
"org.nuxeo.ecm.platform.placeful.configuration.service.PlacefulConfigurationService"
      point="configuration">                                                             (2)

    <configuration name="TestConfig" storage="RAM"
        class="org.nuxeo.ecm.platform.placeful.configuration.entry.LocalTheme" />

  </extension>

</component>
1

Definition of the storage.

2

The configuration reference the storage name using the storage attribute.

3

Storage specific values.