<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<section id="JCR.JBossCacheConfigurationTemplates">
  <title>JBoss Cache configuration</title>

  <para>This section will show you how to use and configure Jboss Cache in the
  clustered environment. Also, you will know how to use a template-based
  configuration offered by eXo JCR for JBoss Cache instances.</para>

  <section id="JCR.JBossCacheConfigurationTemplates.JBoss_Cache_Config_for_Indexer">
    <title>JBoss cache configuration for indexer, lock manager and data
    container</title>

    <para>Each mentioned components uses instances of JBoss Cache product for
    caching in clustered environment. So every element has its own transport
    and has to be configured in a proper way. As usual, workspaces have
    similar configuration but with different cluster-names and may-be some
    other parameters. The simplest way to configure them is to define their
    own configuration files for each component in each workspace:</para>

    <programlisting language="xml">&lt;property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock-db1-ws1.xml" /&gt;</programlisting>

    <para>But if there are few workspaces, configuring them in such a way can
    be painful and hard-manageable. eXo JCR offers a template-based
    configuration for JBoss Cache instances. You can have one template for
    Lock Manager, one for Indexer and one for data container and use them in
    all the workspaces, defining the map of substitution parameters in a main
    configuration file. Just simply define ${jbosscache-&lt;parameter
    name&gt;} inside xml-template and list correct value in JCR configuration
    file just below "jbosscache-configuration", as shown:</para>

    <para>Template:</para>

    <programlisting language="xml">...
&lt;clustering mode="replication" clusterName="${jbosscache-cluster-name}"&gt;
  &lt;stateRetrieval timeout="20000" fetchInMemoryState="false" /&gt;
...</programlisting>

    <para>and JCR configuration file:</para>

    <programlisting language="xml">...
&lt;property name="jbosscache-configuration" value="jar:/conf/portal/jbosscache-lock.xml" /&gt;
&lt;property name="jbosscache-cluster-name" value="JCR-cluster-locks-db1-ws" /&gt;
...</programlisting>
  </section>

  <section id="JCR.JBossCacheConfigurationTemplates.Jboss_Configuration">
    <title>JGroups configuration</title>

    <para>JGroups is used by JBoss Cache for network communications and
    transport in a clustered environment. If property "jgroups-configuration"
    is defined in component configuration, it will be injected into the JBoss
    Cache instance on startup.</para>

    <programlisting language="xml">&lt;property name="jgroups-configuration" value="your/path/to/modified-udp.xml" /&gt;</programlisting>

    <para>As mentioned above, each component (lock manager, data container and
    query handler) for each workspace requires its own clustered environment.
    In other words, they have their own clusters with unique names. By
    default, each cluster should perform multi-casts on a separate port. This
    configuration leads to much unnecessary overhead on cluster. That's why
    JGroups offers multiplexer feature, providing ability to use one single
    channel for set of clusters. This feature reduces network overheads and
    increase performance and stability of application. To enable multiplexer
    stack, you should define appropriate configuration file (upd-mux.xml is
    pre-shipped one with eXo JCR) and set "jgroups-multiplexer-stack" to
    "true".</para>

    <programlisting language="xml">&lt;property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /&gt;
&lt;property name="jgroups-multiplexer-stack" value="true" /&gt;</programlisting>

    <para>I<emphasis>t is now highly recommended to use the shared transport
    instead of the multiplexer</emphasis>, to do so simply disable the
    multiplexer stack in the configuration of each component by setting the
    property <emphasis>jgroups-multiplexer-stack</emphasis> to
    <emphasis>false</emphasis> then you will need to ensure that the format of
    your jgroups configuration is not anymore a jgroups stack definitions but
    a normal configuration and finally you will need to set the property
    <emphasis>singleton_name</emphasis> of your JGroups configuration to a
    unique name (this name must not be the same from one portal container to
    another).</para>

    <programlisting language="xml">&lt;property name="jgroups-configuration" value="jar:/conf/portal/udp-mux.xml" /&gt;
&lt;property name="jgroups-multiplexer-stack" value="false" /&gt;</programlisting>
  </section>

  <section id="JCR.JBossCacheConfigurationTemplates.Allow_to_share_JBOSS_Cache_Instances">
    <title>Allow to share JBoss Cache instances</title>

    <para>A JBoss Cache instance is quite resource consuming and by default we
    will have 3 JBoss Cache instances (one instance for the indexer, one for
    the lock manager and one for the data container) for each workspace, so if
    you intend to have a lot of workspaces it could make sense to decide to
    share one JBoss Cache instance with several cache instances of the same
    type (i.e. indexer, lock manager or data container). This feature is
    disabled by default and can be enabled at component configuration level
    (i.e. indexer configuration, lock manager configuration and/or data
    container configuration) by setting the property "jbosscache-shareable" to
    true as below:</para>

    <programlisting language="xml">&lt;property name="jbosscache-shareable" value="true" /&gt;</programlisting>

    <para>Once enabled this feature will allow the JBoss Cache instance used
    by the component to be re-used by another components of the same type
    (i.e. indexer, lock manager or data container) with the exact same JBoss
    Cache configuration (except the eviction configuration that cans be
    different), which means that all the parameters of type
    ${jbosscache-&lt;parameter name&gt;} must be identical between the
    components of same type of different workspaces. In other words, if we use
    the same values for the parameters of type ${jbosscache-&lt;parameter
    name&gt;} in each workspace, we will have only 3 JBoss Cache instances
    (one instance for the indexer, one for the lock manager and one for the
    data container) used whatever the total amount of workspaces
    defined.</para>
  </section>

  <section id="JCR.JBossCacheConfigurationTemplates.Shipped_Jboss_Cache_Config_template">
    <title>Shipped JBoss Cache configuration templates</title>

    <para>eXo JCR implementation is shipped with ready-to-use JBoss Cache
    configuration templates for JCR's components. They are situated in
    application package in /conf/porta/ folder.</para>

    <section id="JCR.JBossCacheConfigurationTemplates.Shipped_Jboss_Cache_Config_template.Data_container_template">
      <title>Data container template</title>

      <para>Data container template is "jbosscache-data.xml":</para>

      <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1"&gt;

   &lt;locking useLockStriping="false" concurrencyLevel="500" lockParentForChildInsertRemove="false"
      lockAcquisitionTimeout="20000" /&gt;

   &lt;clustering mode="replication" clusterName="${jbosscache-cluster-name}"&gt;
      &lt;stateRetrieval timeout="20000" fetchInMemoryState="false" /&gt;
      &lt;sync /&gt;
   &lt;/clustering&gt;

   &lt;!-- Eviction configuration --&gt;
   &lt;eviction wakeUpInterval="5000"&gt;
      &lt;default algorithmClass="org.jboss.cache.eviction.ExpirationAlgorithm"
         actionPolicyClass="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.ParentNodeEvictionActionPolicy"
         eventQueueSize="1000000"&gt;
         &lt;property name="maxNodes" value="1000000" /&gt;
         &lt;property name="warnNoExpirationKey" value="false" /&gt;
      &lt;/default&gt;
   &lt;/eviction&gt;
&lt;/jbosscache&gt;</programlisting>

      <table>
        <title>Template variables</title>

        <tgroup cols="2">
          <thead>
            <row>
              <entry align="center">Variable</entry>

              <entry align="center">Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>jbosscache-cluster-name</entry>

              <entry>cluster name (must be unique)</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>

    <section id="JCR.JBossCacheConfigurationTemplates.Shipped_Jboss_Cache_Config_template.Lock_manager_template">
      <title>Lock manager template</title>

      <para>It's template name is "jbosscache-lock.xml"</para>

      <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1"&gt;

   &lt;locking useLockStriping="false" concurrencyLevel="500" lockParentForChildInsertRemove="false"
      lockAcquisitionTimeout="20000" /&gt;
   &lt;clustering mode="replication" clusterName="${jbosscache-cluster-name}"&gt;
      &lt;stateRetrieval timeout="20000" fetchInMemoryState="false" /&gt;
      &lt;sync /&gt;
   &lt;/clustering&gt;
   &lt;loaders passivation="false" shared="true"&gt;
      &lt;preload&gt;
         &lt;node fqn="/" /&gt;
      &lt;/preload&gt;
      &lt;loader class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.JDBCCacheLoader" async="false" fetchPersistentState="false"
         ignoreModifications="false" purgeOnStartup="false"&gt;
         &lt;properties&gt;
            cache.jdbc.table.name=${jbosscache-cl-cache.jdbc.table.name}
            cache.jdbc.table.create=${jbosscache-cl-cache.jdbc.table.create}
            cache.jdbc.table.drop=${jbosscache-cl-cache.jdbc.table.drop}
            cache.jdbc.table.primarykey=${jbosscache-cl-cache.jdbc.table.primarykey}
            cache.jdbc.fqn.column=${jbosscache-cl-cache.jdbc.fqn.column}
            cache.jdbc.fqn.type=${jbosscache-cl-cache.jdbc.fqn.type}
            cache.jdbc.node.column=${jbosscache-cl-cache.jdbc.node.column}
            cache.jdbc.node.type=${jbosscache-cl-cache.jdbc.node.type}
            cache.jdbc.parent.column=${jbosscache-cl-cache.jdbc.parent.column}
            cache.jdbc.datasource=${jbosscache-cl-cache.jdbc.datasource}
         &lt;/properties&gt;
      &lt;/loader&gt;
   &lt;/loaders&gt;
&lt;/jbosscache&gt;</programlisting>

      <note>
        <para>To prevent any consistency issue regarding the lock data please
        ensure that your cache loader is
        <emphasis>org.exoplatform.services.jcr.impl.core.lock.jbosscache.JDBCCacheLoader</emphasis>
        and that your database engine is transactional.</para>
      </note>

      <table>
        <title>Template variables</title>

        <tgroup cols="2">
          <thead>
            <row>
              <entry align="center">Variable</entry>

              <entry align="center">Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>jbosscache-cluster-name</entry>

              <entry>cluster name (must be unique)</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.table.name</entry>

              <entry>the name of the table.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.table.create</entry>

              <entry>can be true or false. Indicates whether to create the
              table during startup. If true, the table is created if it
              doesn't already exist. The default value is true.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.table.drop</entry>

              <entry>can be true or false. Indicates whether to drop the table
              during shutdown. The default value is true.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.table.primarykey</entry>

              <entry>the name of the primary key for the table.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.fqn.column</entry>

              <entry>FQN column name. The default value is 'fqn'.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.fqn.type</entry>

              <entry>FQN column type. The default value is
              'varchar(255)'.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.node.column</entry>

              <entry>node contents column name. The default value is
              'node'.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.node.type</entry>

              <entry>node contents column type. The default value is 'blob'.
              This type must specify a valid binary data type for the database
              being used.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.parent.column</entry>

              <entry>Parent column name. The default value is
              'parent'.</entry>
            </row>

            <row>
              <entry>jbosscache-cl-cache.jdbc.datasource</entry>

              <entry>JNDI name of the DataSource.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>

    <section id="JCR.JBossCacheConfigurationTemplates.Shipped_Jboss_Cache_Config_template.Query_handler">
      <title>Query handler (indexer) template</title>

      <para>Have a look at "jbosscache-indexer.xml"</para>

      <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1"&gt;
   &lt;locking useLockStriping="false" concurrencyLevel="500" lockParentForChildInsertRemove="false"
      lockAcquisitionTimeout="20000" /&gt;
   &lt;clustering mode="replication" clusterName="${jbosscache-cluster-name}"&gt;
      &lt;stateRetrieval timeout="20000" fetchInMemoryState="false" /&gt;
      &lt;sync /&gt;
   &lt;/clustering&gt;
&lt;/jbosscache&gt;</programlisting>

      <table>
        <title>Template variables</title>

        <tgroup cols="2">
          <thead>
            <row>
              <entry align="center">Variable</entry>

              <entry align="center">Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>jbosscache-cluster-name</entry>

              <entry>cluster name (must be unique)</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>
  </section>
</section>
