Chapter 43. RDBMS Storage and Database Configuration

Table of Contents

43.1. Storages in Nuxeo EP
43.2. Installing the JDBC driver
43.3. Configuring Nuxeo Core Storage
43.3.1. Visible Content Store configuration
43.3.2. JCR backend configuration
43.3.3. Set up your RDBMS
43.3.4. Start Nuxeo EP
43.4. Configuring Storage for other Nuxeo Services
43.4.1. Configuring datasources
43.4.2. Relation service configuration
43.4.3. Tag service configuration
43.4.4. Compass search engine dialect configuration
43.5. Setting up a new repository configuration
43.5.1. Add the new repository configuration
43.5.2. Declare the new repository to the platform

To run Nuxeo EP for real-world application, you need to get rid of the default embedded database and set up a real RDBMS server (such as PostgreSQL, MySQL, Oracle, etc.) to store Nuxeo EP's data.

In order to define a SQL DB as repository back-end you have to :

43.1. Storages in Nuxeo EP

Nuxeo EP manages several types of data: Documents, relations, audit trail, users, groups ...

Each type of data has its own storage engine and can be configured separately. All storages can use RDBMS but some of them can also use the filesystem.

This means you can have a RDBMS only configuration or a mixed configuration using RDBMS and filesystem. You can even use several RDBMS if you find a use case for that.

For a lot of services, RDBMS access are encapsulated by JPA or hibernate calls, so the storage should be RDBMS agnostic as long as there is a hibernate dialect for the DB.

43.2. Installing the JDBC driver

To enable the connection to the database, you first need to install the JDBC driver into $JBOSS_HOME/server/default/lib/.

Here are some drivers download locations:

43.3. Configuring Nuxeo Core Storage

Nuxeo Core stores data for the documents themselves: the hierarchy of documents, their metadata and security, and the attached files. There are two main Nuxeo Core Storage backends: the recent (available in Nuxeo 5.2) Visible Contents Store (VCS), based on a mapper to native RDBMS tables, and the previous JCR-based backend, using Jackrabbit.

This section will show you how to configure each backend, using PostgreSQL 8.3 as an example underlying storage. The setup for other RDBMS should be very similar.

43.3.1. Visible Content Store configuration

To set up VCS, you first need create a datasource for it. The datasource is not a standard JDBC datasource, so has different syntax, even though it contains information about JDBC connection parameters. This file is usually named $JBOSS_HOME/server/default/deploy/nuxeo.ear/datasources/default-repository-ds.xml.

<?xml version="1.0"?>
<connection-factories>
  <tx-connection-factory>
    <jndi-name>NXRepository/default</jndi-name>
    <xa-transaction/>
    <track-connection-by-tx/>
    <adapter-display-name>Nuxeo SQL Repository DataSource</adapter-display-name>
    <rar-name>nuxeo.ear#nuxeo-core-storage-sql-ra-1.5-SNAPSHOT.rar</rar-name>
    <connection-definition>org.nuxeo.ecm.core.storage.sql.Repository</connection-definition>
    <config-property name="name">default</config-property>
    <config-property name="xaDataSource" type="java.lang.String">org.postgresql.xa.PGXADataSource</config-property>
    <config-property name="property" type="java.lang.String">ServerName=localhost</config-property>
    <config-property name="property" type="java.lang.String">PortNumber/Integer=5432</config-property>
    <config-property name="property" type="java.lang.String">DatabaseName=nuxeo</config-property>
    <config-property name="property" type="java.lang.String">User=nuxeo</config-property>
    <config-property name="property" type="java.lang.String">Password=password</config-property>
    <max-pool-size>20</max-pool-size>
  </tx-connection-factory>
</connection-factories>

Example 43.1. Datasource for VCS using PostgreSQL


You will then need to specify the actual repository configuration, usually store in a file named $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/default-repository-config.xml

<?xml version="1.0"?>
<component name="default-repository-config">
  <extension target="org.nuxeo.ecm.core.repository.RepositoryService" point="repository">
    <repository name="default"
      factory="org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepositoryFactory">
      <repository name="default">
        <indexing>
          <!-- example configuration for H2
          <fulltext analyzer="org.apache.lucene.analysis.fr.FrenchAnalyzer"/>
          -->
          <!-- example configuration for PostgreSQL
          <fulltext analyzer="french"/>
          -->
          <!-- example configuration for Microsoft SQL Server
          <fulltext catalog="nuxeo" analyzer="french"/>
          -->
        </indexing>
        <!-- uncomment this to enable clustering
             delay is in milliseconds
               default delay is 0 (no delay before processing invalidations)
        <clustering enabled="true" delay="1000" />
        -->
      </repository>
    </repository>
  </extension>
</component>

Example 43.2. Repository Configuration for VCS


43.3.2. JCR backend configuration

First you have to specify a datasource in $JBOSS_HOME/server/default/deploy/nuxeo.ear/datasources/default-repository-ds.xml.

<?xml version="1.0"?>
<!DOCTYPE connection-factories PUBLIC
  "-//JBoss//DTD JBOSS JCA Config 1.5//EN"
  "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">
<connection-factories>
  <mbean code="org.nuxeo.ecm.core.repository.JBossRepository"
         name="nx:type=repository,name=default">
    <constructor>
      <arg type="java.lang.String" value="default"/>
    </constructor>
  </mbean>
  <tx-connection-factory>
    <jndi-name>NXRepository/default</jndi-name>
    <adapter-display-name>NX Repository Adapter</adapter-display-name>
    <rar-name>nuxeo.ear#nuxeo-core-jca-${project.version}.rar</rar-name>
    <connection-definition>org.nuxeo.ecm.core.model.Repository</connection-definition>
    <xa-transaction/>
    <!-- Configuration properties. -->
    <config-property name="name">default</config-property>
  </tx-connection-factory>
</connection-factories>

Example 43.3. Datasource for JCR backend


Then edit $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/default-repository-config.xml.

<?xml version="1.0"?>
<component name="default-repository-config">
  <documentation>
    Defines the default JackRabbit repository used for development and testing.
  </documentation>
  <extension target="org.nuxeo.ecm.core.repository.RepositoryService"
    point="repository">
    <documentation>
      Declare a JackRabbit repository to be used for development and tests. The
      extension content is the Jackrabbit XML configuration of the repository.
    </documentation>
    <repository name="default"
      factory="org.nuxeo.ecm.core.repository.jcr.JCRRepositoryFactory"
      securityManager="org.nuxeo.ecm.core.repository.jcr.JCRSecurityManager"
      forceReloadTypes="false">
      <Repository>
        <!--
          virtual file system where the repository stores global state
          (e.g. registered namespaces, custom node types, etc.)
        -->
        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
          <param name="path" value="${rep.home}/repository" />
        </FileSystem>
        <!--
          security configuration
        -->
        <Security appName="Jackrabbit">
          <!--
            access manager:
            class: FQN of class implementing the AccessManager interface
          -->
          <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
            <!-- <param name="config" value="${rep.home}/access.xml"/> -->
          </AccessManager>
          <LoginModule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
            <!-- anonymous user name ('anonymous' is the default value) -->
            <param name="anonymousId" value="anonymous" />
            <!--
              default user name to be used instead of the anonymous user
              when no login credentials are provided (unset by default)
            -->
            <!-- <param name="defaultUserId" value="superuser"/> -->
          </LoginModule>
        </Security>

        <!--
          location of workspaces root directory and name of default workspace
        -->
        <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default" />
        <!--
          workspace configuration template:
          used to create the initial workspace if there's no workspace yet
        -->
        <Workspace name="${wsp.name}">
          <!--
            virtual file system of the workspace:
            class: FQN of class implementing the FileSystem interface
          -->
          <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
            <param name="path" value="${wsp.home}" />
          </FileSystem>

          <!--
            persistence manager of the workspace:
            class: FQN of class implementing the PersistenceManager interface
          -->
          <PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager">
          </PersistenceManager>

          <!--
            Search index and the file system it uses.
            class: FQN of class implementing the QueryHandler interface
          -->
          <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
            <param name="path" value="${wsp.home}/index" />
          </SearchIndex>
        </Workspace>

        <!--
          Configures the versioning
        -->
        <Versioning rootPath="${rep.home}/version">
          <!--
            Configures the filesystem to use for versioning for the respective
            persistence manager
          -->
          <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
            <param name="path" value="${rep.home}/version" />
          </FileSystem>

          <!--
            Configures the persistence manager to be used for persisting version state.
            Please note that the current versioning implementation is based on
            a 'normal' persistence manager, but this could change in future
            implementations.
          -->
          <PersistenceManager class="org.apache.jackrabbit.core.state.obj.ObjectPersistenceManager">
          </PersistenceManager>
        </Versioning>

        <!--
          Search index for content that is shared repository wide
          (/jcr:system tree, contains mainly versions)
        -->
        <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
          <param name="path" value="${rep.home}/repository/index" />
        </SearchIndex>
      </Repository>
    </repository>
  </extension>
</component>

          

Example 43.4. Default repository configuration


Change the two PersistenceManager sections defining various database connection settings.

Refer to the Jackrabbit documentation for more information, and to the Jackrabbit Javadoc for details about configuring the PersistenceManager.

In particular, decide if you want the binary blobs stored inside the database or in the filesystem (change externalBLOBs to true if you want them outside the database, in the filesystem).

Using externalized Blobs can provide a performance improvement in particular if you need to store a lot of big files. Depending on the RDBMS used, there may also be a max size limit for blob if you store them in the RDBMS (for PostgeSQL 8.2 blobs are limited to 1 GB).

Here are some examples:

        <!-- Workspaces configuration. Nuxeo only uses the default workspace. -->
        (...)
          <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager">
            <param name="driver" value="org.postgresql.Driver"/>
            <param name="url" value="jdbc:postgresql://localhost/nuxeo"/>
            <param name="user" value="postgres"/>
            <param name="password" value="password"/>
            <param name="schema" value="postgresql"/>
            <param name="schemaObjectPrefix" value="jcr_${wsp.name}_"/>
            <param name="externalBLOBs" value="false"/>
          </PersistenceManager>
        (...)
        <!-- Versioning configuration. -->
          (...)
          <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager">
            <param name="driver" value="org.postgresql.Driver"/>
            <param name="url" value="jdbc:postgresql://localhost/nuxeo"/>
            <param name="user" value="postgres"/>
            <param name="password" value="password"/>
            <param name="schema" value="postgresql"/>
            <param name="schemaObjectPrefix" value="jcr_ver_"/>
            <param name="externalBLOBs" value="false"/>
          </PersistenceManager>

          

Example 43.5. Sample configuration for a PostgreSQL Jackrabbit repository


        <!-- Workspaces configuration. Nuxeo only uses the default workspace. -->
        (...)
          <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.MySqlPersistenceManager">
            <param name="driver" value="com.mysql.jdbc.Driver"/>
            <param name="url" value="jdbc:mysql://localhost/nuxeo"/>
            <param name="user" value="mysql"/>
            <param name="password" value="password"/>
            <param name="schema" value="mysql"/>
            <param name="schemaObjectPrefix" value="jcr_${wsp.name}_"/>
            <param name="externalBLOBs" value="true"/>
          </PersistenceManager>
        (...)
        <!-- Versioning configuration. -->
          (...)
          <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.MySqlPersistenceManager">
            <param name="driver" value="com.mysql.jdbc.Driver"/>
            <param name="url" value="jdbc:mysql://localhost/nuxeo"/>
            <param name="user" value="mysql"/>
            <param name="password" value="password"/>
            <param name="schema" value="mysql"/>
            <param name="schemaObjectPrefix" value="jcr_ver_"/>
            <param name="externalBLOBs" value="true"/>
          </PersistenceManager>

          

Example 43.6. Sample configuration for a MySQL Jackrabbit repository


Note: "schemaObjectPrefix" must have different values in workspace & versioning configuration

For JackRabbit, there are some persistence manager specific to each RDBMS :

  • for PostgreSQL: you may use org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager

  • for MySQL: you may use org.apache.jackrabbit.core.persistence.bundle.MySqlPersistenceManager

  • for Oracle 10: you may use org.apache.jackrabbit.core.persistence.bundle.OraclePersistenceManager

  • for MSSQL2005 you may use : org.apache.jackrabbit.core.persistence.bundle.MSSqlPersistenceManager

43.3.3. Set up your RDBMS

Create the database in the database server, enable IP connection, setup permissions and test the connection.

43.3.4. Start Nuxeo EP

You can now start JBoss AS and verify that your new repository is used!

43.4. Configuring Storage for other Nuxeo Services

Many services beyond Nuxeo Core Repository are using an SQL database to persist their data, such as:

  • Relations Service: RDF data is stored in SQL,

  • Audit Service: Audit logs are stored via JPA,

  • Tag Service: the tagging entities are stored in a table in the default Nuxeo DB via JPA,

  • Directories: entries can be stored into an SQL database.

By default, all these services use the JBoss AS's embedded HSQLDB.

43.4.1. Configuring datasources

Each service can use a dedicated datasource to define the database connection. However, to simplify configuration, all datasources are JNDI NamingAlias pointing to a single datasource (NuxeoDS). If you want to change the default database, you can simply do the following:

  • deploy the needed JDBC Driver in $JBOSS_HOME/server/default/lib,

  • modify the datasource definition file in $JBOSS_HOME/server/default/deploy/nuxeo.ear/datasources/unified-nuxeo-ds.xml.

The default configuration has a commented out PostgresSQL configuration.

To use a dedicated datasource for a service, you need to modify its configuration file. If you would like to store audit logs in PostgreSQL using its own datasource, remove the NamingAlias in nxaudit-logs-ds.xml and replace it with the datasource configuration example:

<?xml version="1.0"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>nxaudit-logs</jndi-name>
    <connection-url>jdbc:postgresql://localhost/logs</connection-url>
    <driver-class>org.postgresql.Driver</driver-class>
    <user-name>username</user-name>
    <password>password</password>
  </local-tx-datasource>
</datasources>
        

Example 43.7. Datasource for the Audit Service using PostgreSQL


We recommend to enable XA transactions if your database server support it (for PostgreSQL, you have to use 8.x versions). The following datasource definition example enables XA transaction for the Audit Service using PostgreSQL.

<?xml version="1.0"?>
<datasources>
   <xa-datasource>
     <jndi-name>nxaudit-logs</jndi-name>
     <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
     <xa-datasource-property name="ServerName">localhost</xa-datasource-property>
     <xa-datasource-property name="PortNumber">5432</xa-datasource-property>
     <xa-datasource-property name="DatabaseName">logs</xa-datasource-property>
     <xa-datasource-property name="User">postgres</xa-datasource-property>
     <xa-datasource-property name="Password">password</xa-datasource-property>
     <track-connection-by-tx/>
   </xa-datasource>
</datasources>
        

Example 43.8. Datasource for the Audit Service using PostgreSQL with XA transactions


See Datasources Configuration on the JBoss wiki for more examples of datasources.

This method works for most services:

  • Audit: nxaudit-logs-ds.xml

  • Placeful Configuration Service & Subscriptions: nxplaceful-ds.xml

  • UID generator: nxuidsequencer-ds.xml

  • jBPM engine: nxworkflow-jbpm-ds.xml

  • Workflow Document Service: nxworkflow-documents-ds.xml

  • Archive management: nxarchive-records-ds.xml

  • Relations: nxrelations-default-jena-ds.xml

  • Compass search engine: nxsearch-compass-ds.xml

43.4.1.1. Special MySQL needs

MySQL is a quirky database which sometimes needs very specific options to function properly.

The datasources used by Jena (nxrelations-default-jena-ds.xml and nxcomment-jena-ds.xml) need to use a "relax autocommit" mode. To enable that, change the connection-url in the datasources to something like:

<connection-url>
  jdbc:mysql://localhost/nuxeo?relaxAutoCommit=true
</connection-url>
        

The datasource used by Compass (nxsearch-compass-ds.xml) needs to be put in "relax autocommit" too, and in addition it needs an "emulate locators" option:

<connection-url>
  jdbc:mysql://localhost/nuxeo?relaxAutoCommit=true&amp;emulateLocators=true
</connection-url>
        

This is documented at http://static.compassframework.org/docs/latest/jdbcdirectory.html .

Note the &amp; syntax for the URL parameters instead of just & because the URL is embedded in an XML file.

43.4.2. Relation service configuration

The Relation Service uses a datasource to define the data storage. However modifying the datasource is not enough, you also have to tell to the Jena engine which database dialect is used, as it doesn't auto-detect it.

To do that, edit the sql.properties file in $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/ and change the definition of the org.nuxeo.ecm.sql.jena.databaseType property. The possible values are:

  • Derby

  • HSQL

  • MsSQL

  • MySQL

  • Oracle

  • PostgreSQL

In the same file, the property org.nuxeo.ecm.sql.jena.databaseTransactionEnabled is false by default, but must be set to true for Oracle.

Please refer to the Jena Site for more information about database support.

The value of the above properties are used as variables by the extension point defining the Jena configuration, so that they only have to be changed in one place.

43.4.3. Tag service configuration

The Tag Service uses a property file to define the data storage. The tagservice-db.properties file needs to be complaint with whatever is set in the default-repository-ds.xml file, as the service is using the same DB.

Also, the tag service allows initialization with through API supplied properties.

43.4.4. Compass search engine dialect configuration

Note that this section is obsolete in Nuxeo 5.2, and should not be used anymore.

The Compass plugin is configured using a datasource, but at the time of this writing it still needs some additional configuration in a file embedded in its Jar. You should go to $JBOSS_HOME/server/default/deploy/nuxeo.ear/system/ and inside the directory nuxeo-platform-search-compass-plugin-5.1-SNAPSHOT.jar (the version number may be different) then edit the file compass.cfg.xml. You will find a section like:

<connection>
  <jdbc managed="true"
    dialectClass="org.apache.lucene.store.jdbc.dialect.HSQLDialect"
    deleteMarkDeletedDelta="3600000">
    <dataSourceProvider>
      <jndi lookup="java:/nxsearch-compass" />
    </dataSourceProvider>
  </jdbc>
</connection>
      

The dialectClass has to be changed according to your datasource configuration. The possible values end with MySQLDialect, PostgreSQLDialect , etc. They are documented in the Compass documention about SQL dialects .

43.5. Setting up a new repository configuration

If you just want to change the default repository name appearing in the url http://.../nuxeo/nxdoc/default/, modify the repository name value in:

  • default-repository-config.xml

  • platform-config.xml

TODO: Nuxeo configuration has changed, the two above sections need to be updated.

43.5.1. Add the new repository configuration

Create a repository definition as a contribution to the extension point org.nuxeo.ecm.core.repository.RepositoryService (for example: MyRepo-repositoy-config.xml) in $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/.

You can take example on the default repository definition $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/default-repository-config.xml.

You have to properly configure the following aspects:

  • the name of the component (name="org.nuxeo.project.sample.repository.MyRepo"), which must be unique among component names,

  • the name of the repository (<repository name="MyRepo">), which is used to refer to it from your application and must also be unique among repository names,

  • the various database connection settings (driver, user, password, schema, etc.),

  • decide if you want the binary blobs stored inside the database or in the filesystem (change externalBLOBs to true if you want them outside the database).

Refer to the Jackrabbit documentation for more information, and to the Jackrabbit Javadoc for details about configuring the BundleDbPersistenceManager.

<?xml version="1.0"?>
<component name="org.nuxeo.project.sample.repository.MyRepo">
  <extension target="org.nuxeo.ecm.core.repository.RepositoryService" point="repository">
    <repository name="MyRepo"
                factory="org.nuxeo.ecm.core.repository.jcr.JCRRepositoryFactory"
                securityManager="org.nuxeo.ecm.core.repository.jcr.JCRSecurityManager"
                forceReloadTypes="false">
      <Repository>
        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
          <param name="path" value="${rep.home}/repository"/>
        </FileSystem>
        <Security appName="Jackrabbit">
          <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
        </AccessManager>
          <LoginModule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
            <param name="anonymousId" value="anonymous"/>
          </LoginModule>
        </Security>

        <!-- Workspaces configuration. Nuxeo only uses the default workspace. -->
        <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>
        <Workspace name="${wsp.name}">
          <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
            <param name="path" value="${wsp.home}"/>
          </FileSystem>
          <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager">
            <param name="driver" value="org.postgresql.Driver"/>
            <param name="url" value="jdbc:postgresql://localhost/nuxeo"/>
            <param name="user" value="postgres"/>
            <param name="password" value="password"/>
            <param name="schema" value="postgresql"/>
            <param name="schemaObjectPrefix" value="jcr_${wsp.name}_"/>
            <param name="externalBLOBs" value="false"/>
          </PersistenceManager>
          <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
            <param name="path" value="${wsp.home}/index"/>
          </SearchIndex>
        </Workspace>

        <!-- Versioning configuration. -->
        <Versioning rootPath="${rep.home}/version">
          <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
            <param name="path" value="${rep.home}/version"/>
          </FileSystem>
          <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager">
            <param name="driver" value="org.postgresql.Driver"/>
            <param name="url" value="jdbc:postgresql://localhost/nuxeo"/>
            <param name="user" value="postgres"/>
            <param name="password" value="password"/>
            <param name="schema" value="postgresql"/>
            <param name="schemaObjectPrefix" value="jcr_ver_"/>
            <param name="externalBLOBs" value="false"/>
          </PersistenceManager>
        </Versioning>

        <!-- Index for repository-wide information, mainly versions. -->
        <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
          <param name="path" value="${rep.home}/repository/index"/>
        </SearchIndex>
      </Repository>
    </repository>
  </extension>
</component>

Example 43.9. Sample configuration for a PostgreSQL Jackrabbit repository


43.5.2. Declare the new repository to the platform

TODO: this should be moved to a different section as it doesn't pertain to the SQL configuration itself.

You have now replaced the default repository (demo) with your newly defined one (MyRepo). To actually use it, create or edit the file MyPlatform-Layout-config.xml in $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/ and configure the parameters as shown in the following example.

<?xml version="1.0"?>
<component name="MyPlatformLayout">

  <require>org.nuxeo.ecm.platform.api.DefaultPlatform</require>

  <extension target="org.nuxeo.ecm.platform.util.LocationManagerService" point="location">
    <locationManagerPlugin> <!-- This disable the default (demo) repository -->
      <locationEnabled>false</locationEnabled>
      <locationName>demo</locationName>
    </locationManagerPlugin>
    <locationManagerPlugin> <!-- This enable your new repository -->
      <locationEnabled>true</locationEnabled>
      <locationName>MyRepo</locationName> <!-- Use the name of your repository -->
    </locationManagerPlugin>
  </extension>

 <extension target="org.nuxeo.ecm.core.api.repository.RepositoryManager"
    point="repositories">
    <documentation>The default repository</documentation>
    <repository name="MyRepo" label="My Repository"/>
  </extension>

  <extension target="org.nuxeo.runtime.api.ServiceManagement" point="services">
      <service class="org.nuxeo.ecm.core.api.CoreSession" name="MyRepo" group="core">
          <locator>%DocumentManagerBean</locator>
      </service>
  </extension>

</component>
      

This sample configuration creates a new repository in the core Group that will be assigned to the default server. If you want to have it located on an other server you can use:

<extension target="org.nuxeo.runtime.api.ServiceManagement" point="servers">
  <!-- define new locator for group MyGroup -->
  <server class="org.nuxeo.runtime.api.JBossServiceLocator">
    <group>MyGroup</group>
    <property name="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</property>
    <property name="java.naming.provider.url">jnp://MyServer:1099</property>
    <property name="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</property>
  </server>

  <!-- bind MyRepo to MyGroup -->
  <extension target="org.nuxeo.runtime.api.ServiceManagement" point="services">
    <service class="org.nuxeo.ecm.core.api.CoreSession" name="MyRepo" group="MyGroup">
      <locator>%DocumentManagerBean</locator>
    </service>
  </extension>

</extension>