Using Modular Configuration Files

You can break a complex server configuration file into fragments, and then assemble a top-level configuration file by including smaller fragments into the top-level file. This feature allows for greater reusability of standard or site-specific configuration file settings, and allows you to quickly switch between different configurations for development, testing, and production environments.

Include files are supported only for server configuration files, and not for any other StreamBase file type. For example, you cannot include the contents of a StreamBase deployment file into a server configuration file.

Include file support is provided in two ways:

  • With support for the <sb-include> element that is specific to StreamBase Server configuration files, and works only with such files. The <sb-include> element supports StreamBase smart merge features.

  • With support for the XML Inclusions specification, commonly called XInclude, which is a W3C standard method of including elements from one XML file into another XML file. For recent releases, StreamBase extended the XInclude standard to provide smart merge capabilities.

TIBCO recommends using the <sb-include> element over XIncludes.

You use <sb-include> and XInclude differently in server configuration files, depending on your StreamBase release:

Smart Merge XInclude Rules

Follow StreamBase-extended smart merge XInclude rules in releases after 7.2.

Smart Merge <sb-include> Rules

Use the StreamBase-specific <sb-include> element in releases after 7.2.

Differences Between XInclude and <sb-include>

The following table shows the differences between the <sb-include> element and XIncludes.

Feature <sb-config> XInclude
Origin StreamBase W3C.org
Applies to StreamBase Server configuration files only All XML file grammars
Namespace Built in to the server configuration file XML grammar. (You still need the namespaces for other reasons.) Requires namespace declaration in the top-level element.
Configuration file fragments Supported. Any element of the configuration file grammar can be used, but the fragment file must be enclosed in a <streambase-configuration> element. Supported. Top-level element of a fragment file can be any valid element. You can also enclose the fragment in a <streambase-configuration> element (recommended).
Use environment variables in the fragment file's path Supported Not supported
Supports StreamBase smart merge rules Yes Yes

<sb-include> Basics

Follow these steps to use <sb-include> to reference an included fragment file in your top-level server configuration file:

  1. Server configuration files generated by StreamBase 7.0 or later already have the necessary namespace declarations in their top-level element.

    If you are adding include support to an existing configuration file created in an earlier release, locate the top-level <streambase-configuration> element, and add the following namespace declaration attributes:

    <streambase-configuration 
      xmlns:xi="http://www.w3.org/2001/XInclude"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="http://www.streambase.com/schemas/sbconf">
    ...

    The xi namespace provides support for the XInclude standard, while the next two lines declare the namespace for server configuration files. These namespaces allow Studio's Configuration File Editor to provide syntax coloring, autocompletion, and context-aware tag proposal when you press Ctrl+Space.

  2. Create a configuration fragment file whose top-level element is <streambase-configuration>, and whose first-level element is any valid element in the configuration file syntax. For example, if your site has a standard set of security settings used by several StreamBase applications, you can place the standard settings in an XML file named security-settings.xml.

    <?xml version="1.0"?>
    <streambase-configuration>
      <security>
        <ssl-authentication>
          <param name="keystore" ...
          ...
      </security>
    </streambase-configuration>

    If your site has a large number of custom functions that you want to reuse in several StreamBase applications, you can place all custom function definitions in an XML file named custom-functions.xml:

    <?xml version="1.0"?>
    <streambase-configuration>
      <custom-functions>
        <custom-function alias="convertTimestamp" args="auto" class="...
        <custom-function alias="branchLocalTime" args="auto" class="...
        ...
      </custom-functions>
    </streambase-configuration>
  3. Choose a location in your top-level configuration file where the <security> or <custom-functions> elements would be valid entries. You must still follow all the standard rules of XML well-formedness and validity against the schema. In general, choose a location in the top-level file that would be valid if the fragment file's contents were typed there instead of included there.

    At a valid location in the receiving top-level configuration file, enter <sb-include> elements like the following examples:

    <sb-include file="./security-settings.xml" />
    <sb-include file="../../custom-functions.xml" />

    To avoid complications when bundling your configuration for running on different servers, specify relative file locations in the file attribute, relative to the Studio project root.

  4. You can use the ${param} syntax to reference an environment variable as part of the file path. Variables specified this way must be environment variables set in the shell from which StreamBase Server is started. You cannot reference StreamBase operator parameters or module parameters in an <sb-include> line, nor can you resolve environment variables specified in the Environment tab of a Run or Debug launch configuration in Studio.

    For example, if you have separate security-settings.xml files for development and production environments, you can keep them in project subfolders named dev and prod. Then you can specify:

    <sb-include file="./${RUNENV}/security-settings.xml" />

    where RUNENV is set to either "dev" or "prod" in the environment that launches the server.

You can use as many <sb-include> lines as your implementation requires. Included fragments can also have <sb-include> or XInclude lines, as long as the final, resolved file contains well-formed XML and is valid against the schema that defines server configuration files.

Your XML fragment files do not need to use the .sbconf extension. The example fragment files described above use the .xml extension, but even that is not required as long as you open the file with the XML Editor in Studio. For fragment files with non-standard extensions, you might need to right-click the file's name in the Project Explorer view, and select Open WithXML Editor from the context menu.

XInclude Basics

The steps to use XInclude to reference an included fragment file in your top-level server configuration file are almost the same as for <sb-include>, as described in the previous section. The differences are:

  • Use <xi:include> and href= instead of <sb-include> and file=. For example:

    <xi:include href="security-settings.xml" />
    <xi:include href="../../custom-functions.xml" />
  • You cannot use the ${param} syntax to place an environment variable in your href URL.

  • There are cases where you do not need to wrap the fragment file's top element in a <streambase-configuration> wrapper. For example:

    <?xml version="1.0"?>
    <security>
      <ssl-authentication>
        <param name="keystore" ...
      ...
    </security>

    However, since the <streambase-configuration> wrapper works with both <sb-include> and <xi:include>, TIBCO recommends using it in all configuration fragment files.

Using Strict XInclude Rules

Follow these guidelines for creating modular server configuration files when your StreamBase release supports only strict XInclude rules. In the final resolved configuration file, with all XIncludes resolved into XML elements:

  • There can be only one root <streambase-configuration> element.

  • There can be only one of each first-level element (<global>, <server>, <java-vm>, and so on).

  • Fragment files XIncluded in a top-level file must contain elements with valid XML, but cannot be fully valid server configuration files with a <streambase-configuration> root element.

    You can temporarily add a <streambase-configuration> root element to your fragment files to get the advantages of autocompletion and tag suggestion while using the Studio Configuration File Editor. When using strict rules, you must remove this root element before using the file as an XIncluded XML fragment.

Using StreamBase Smart Merge Inclusion Rules

In the releases that support smart merge file inclusion rules, StreamBase relaxes the strictness of the server configuration schema, and provides a preprocessor that merges elements that appear more than once. These rules apply when using both the StreamBase-specific <sb-include> element and the <xi:include> element provided by standard XInclude.

The following rules apply when constructing modular server configuration files with smart merge rules. In some cases, XML elements are shown in shorthand form, where <security/user> represents the same as:

    <security>
      <user ... />
    </security>

  • The <streambase-configuration> element can appear again as a child of the root <streambase-configuration> element. This allows you to combine two or more complete configuration files that are each valid in their own contexts.

  • Each <streambase-configuration> element can contain zero or more child elements.

  • At whatever nesting depth a <streambase-configuration> element appears as a child, all of its first-level child elements are considered added to the root <streambase-configuration> element of the resolved top-level file.

  • The above rules mean that a fragment file with <streambase-configuration> root element is a fully valid configuration file, and can take advantage of all the editing conveniences of the Studio Configuration File Editor.

  • There can be more than one of most elements that were formerly restricted to one each. This applies to the first-level elements (<global>, <server>, <java-vm>, and so on), and to non-list child elements of those.

  • If, after resolving all included fragments, the root level contains more than one of the same element, they are merged together into one element.

  • Despite the previous rule, the following elements are never merged because merging might compromise security, or because the union of their attributes has no logical value.

    <security/user>
    <custom_functions/custom_function>
    <operator_parameters/operator_parameter>
  • The following elements are considered list elements that can appear more than once under their parent and have no child nodes. The children of list elements are merged with special handling described below.

    <java-vm/jar>
    <java-vm/dir>
    <java-vm/library>
    <java-vm/sysproperty>
    <security/role>
    <error-handler/error>

StreamBase uses the following merge rules when combining two or more elements. When determining the order of elements, remember that all the lines of an included fragment appear in the resolved configuration file at the point of the <sb-include> or <xi:include> line in the top-level file.

  • If the resolved file contains more than one first-level element (<global>, <server>, <java-vm>, and so on), then regardless of the order in which they appear, they are each merged into a single element of the same name.

  • In general, if two merged fragments of the same first-level element define different child elements and thus have no conflicts, they are merged into a single element of that name. Later-appearing lines are appended to earlier-appearing lines for that element.

  • In general, if two merged fragments define the same element, the last-appearing definition wins. This allows you to override a setting made early in a file with a configuration fragment entered or included near the end of the file.

  • In general, if two merged fragments define the same attribute or define multiple <param> elements with the same name, the last-appearing attribute or <param name=/> wins. Exceptions:

    • For a conflict in the <java-vm/param name="jvm-args" .../> element, the last-appearing parameter value is prepended to the values defined in earlier jvm-args parameters.

    • For a conflict in the <global/plugin directory= .../>, the last-appearing directory path is prepended to earlier directory paths.

  • When parsing the configuration file with all includes resolved, StreamBase uses the following rules to detect elements and attributes that need to be merged:

    • Elements are matched by the same element name.

    • <param> elements are matched by the same value of their name= attributes.

    • Attributes are matched by the same attribute name.

  • When comparing a first-level element defined in the base configuration file with the same element defined or included later in the file, StreamBase looks for competing child elements of those first-level elements under comparison. Two child elements match when they meet all these criteria:

    • They have the same element name.

    • The element is not in the never-merged list, described above.

    • The element is not one of the list elements, described above.

    • If the child element has child nodes of its own, the attributes of the elements being compared have the same names and values (even if one of the comparison pair adds attributes compared to the other).

    If two compared child elements match, they are merged. This usually means the last-defined one wins, with exceptions noted above.

    If two compared child elements do not match, the later-defined child element is appended to the parent of the first-defined child element. Notice that this rule covers all children of list elements, which are simply appended top-to-bottom in the order parsed from the resolved configuration file.