Extension Configuration

spmallette edited this page Mar 26, 2013 · 6 revisions

There are several aspects of configuration that apply to extensions. One aspect is the configuration of which extensions apply to which graphs. That aspect of configuration is described in the Rexster Configuration section. The other aspect of configuration is the ability to pass static configuration parameters to an extension. One set of configuration parameters can be supplied per extension, per graph. It is this second aspect of configuration that is defined within this section.

Configuration of an extension is supplied within the <configuration> component of a specific <extension>. The following is the configuration for the MapConfigurationExtension from the Sample Kibbles project:

<extension>
  <namespace>tp-sample</namespace>
  <name>map-config</name>
  <configuration>
    <some-key>some-value</some-key>
    <other-key>other-value</other-key>
  </configuration>
</extension>

The above configuration specifies the namespace and extension name to be configured followed by a <configuration> section which is extension specific. There are two options for what can be placed within the <configuration> element: simple name-value pairs (as shown in the example) or any valid HierarchicalConfiguration parseable XML given the specifications for the Apache Commons Configuration library.

To gain access to the configuration settings from within the extension, simply access the RexsterApplicationGraph and search for the required configuration as shown in the following code snippet from the sample:

@ExtensionDefinition(extensionPoint = ExtensionPoint.GRAPH)
public ExtensionResponse doConfiguredWork(@RexsterContext RexsterApplicationGraph rag) {

    // finds the configuration settings from the configured graph
    ExtensionConfiguration configuration = rag.findExtensionConfiguration(EXTENSION_NAMESPACE, EXTENSION_NAME);
    Map<String, String> map = configuration.tryGetMapFromConfiguration();

    return ExtensionResponse.ok(map);
}

The ExtensionConfiguration is a container for the XML configuration. When accessing a configuration containing simple name-value pairs, the tryGetMapFromConfiguration helper method converts the XML to a Map. In this case, the extension simply returns the configuration as JSON.

The other option is to get the more robust HierarchicalConfiguration object by using the getConfiguration method on the ExtensionConfiguration. The HierarchicalConfiguration object provides a far more robust approach to configuration, allowing for deep hierarchies, lists and other such constructs within the XML.

It is possible to validate the configuration of an extension. To have an extension support validation, implement or override the isConfigurationValid method from the RexsterExtension interface (when building an extension from the AbstractRexsterExtension, this method is implemented to default to always be valid). The following code snippet from the samples shows how to validate an extension configuration:

@Override
public boolean isConfigurationValid(ExtensionConfiguration extensionConfiguration) {
    boolean valid = false;

    if (extensionConfiguration != null) {
        Map<String, String> map = extensionConfiguration.tryGetMapFromConfiguration();
        valid = map != null && !map.isEmpty()
                && map.containsKey("some-key") && map.containsKey("other-key");
    }

    return valid;
}

In this case, the extension ensures that a configuration is present, it is a simple name/value pair configuration and that there are two keys supplied. In the event that the configuration is not valid, it will not appear as a configured extension.

When writing unit tests around configuration, ensure that the ExtensionConfiguration is mocked with values that are of type String if the tryGetMapFromConfiguration is used. That method will return as null (and log a message) if it fails to parse values to String from the configuration. When not expected that null can cause confusion as to why the configuration is not returning valid to the test.