Administration

Table of Contents

38.1. SMTP Server configuration
38.2. RDBMS Storage and Database Configuration
38.2.1. Storages in Nuxeo EP
38.2.2. Install the JDBC driver
38.2.3. Configure Nuxeo Core storage
38.2.4. Configure Storage for other Nuxeo Services
38.2.5. Setting up a new repository configuration
38.3. LDAP Integration
38.3.1. For users/groups storage backend
38.4. OpenOffice.org server installation
38.5. Run Nuxeo EP with a specific IP binding
38.6. Virtual Hosting
38.6.1. Motivations for virtual hosting
38.6.2. Virtual hosting configuration for Apache 2.x
38.7. The Nuxeo Shell
38.7.1. Overview
38.7.2. User Manual
38.7.3. Extending the shell

In this chapter you will learn how to setup and manage a Nuxeo EP server in a production context (as opposed to a demo / evaluation or development context).

38.1. SMTP Server configuration

On the Nuxeo EP built-in types, you can manage e-mailing and notifications. Before getting this features working, you need to configure your SMTP server. Nuxeo EP relies on the application server mail service for mailing stuff. So you just need to configure the mail-service.xml file in $JBOSS_HOME/server/default/deploy/. You can find examples of how to use this file in the JBoss wiki, and detailed information about the properties of this file in the JavaMail Javadoc.

38.2. RDBMS Storage and Database Configuration

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 :

  • install the JDBC driver for your DBMS,

  • configure the Nuxeo Core storage, modifying the default repository configuration,

  • configure your database.

  • Eventually, configure storage for other Nuxeo services.

  • You may also add a new repository configuration (and optionally disable the old one).

38.2.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.

38.2.2. Install 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:

38.2.3. Configure Nuxeo Core storage

This part will explain you how to configure Nuxeo Core repository, using Jackrabbit as storage back-end, to store the repository's data into your RDBMS.

This documentation will use PostgreSQL 8.x as an example. The setup for other RDBMS should be very similar.

38.2.3.1. Set up the repository configuration

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 38.1. 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 improvment 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 38.2. 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 38.3. Sample configuration for a MySQL Jackrabbit repository


For JackRabbit, there are some persistance manager are specific to a 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

38.2.3.2. Set up your RDBMS

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

38.2.3.3. Start Nuxeo EP

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

38.2.4. Configure 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,

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

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

38.2.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 38.4. 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 38.5. 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

Special MySQL needs

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

The datasources use 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 use 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.

38.2.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.

38.2.4.3. Compass search engine dialect configuration

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/platform/ 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 .

38.2.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.

38.2.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 38.6. Sample configuration for a PostgreSQL Jackrabbit repository


38.2.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>
      

38.3. LDAP Integration

38.3.1. For users/groups storage backend

The user interface in Nuxeo EP gets the data from NXDirectory. As a consequence you can choose your source. By default, the users/groups data is stored in a SQL database. If you want to get the users from a LDAP directory, you need to deploy one of the following configuration:

  • Users in LDAP, groups in SQL

    Go to the examples sub-folder and copy the default-ldap-users-directory-bundle.xml file in the nuxeo.ear/config folder of the JBoss instance (or bundle it in a jar, cf packaging in this guide). This sample setup replaces the default userDirectory configuration SQL with users fetched from the LDAP server. The groupDirectory remains unaffected by this setup. You might want to copy the file default-virtual-groups-bundle.xml and adjust defaultAdministratorId to select a user from your LDAP that have administrative rights by default. You can also configure the section on defaultGroup to make all users members of some default group (typically the members group) so that they have default right without having to make them belong to groups explicitly.

  • Users and groups in LDAP

    Copy the users setup as previously; moreover copy the default-ldap-groups-directory-bundle.xml file in the nuxeo.ear/config folder of the JBoss instance. This sample setup which is dependent on the previous one additionally overrides the default groupDirectory setup to read the groups from the LDAP directory typically from groupOfUniqueNames entries with fully qualified dn references to the user entries or to subgroups. You can edit the nuxeo.ear/config/*.xml files on the JBoss instance, but you will need to restart JBoss to take changes into account.

38.4. OpenOffice.org server installation

OpenOffice.org (OOo) is used server-side for different tasks such as file transforms (eg. to PDF) or other advanced tasks. It has to run in listen mode and some tools has been developed to ease the settings. They are available at the Nuxeo svn tool section.

For OOo versions lower than 2.3, OOo has to run under a graphical interface. If the server that hosts OOo is Linux server that has no X installed, then the X virtual frame buffer tool Xvfb (or xvfb-run depending of your distribution) can be used to create a suitable display.

Xvfb :77 -auth Xperm -screen 0 1024x768x24

Since version 2.3.0, no display is required anymore so OpenOffice.org behaves as a real server. No more need of the above Xvfb and export DISPLAY commands.

The UNO protocol implies that OOo is opened in listen mode on a network interface. In our environment, the 8100 port is used. The interface to be used is the one that OOo will listen to. We use here localhost which imply that OOo will be called by the machine hosting it. On a local network, we will have to use the IP adress from when the connection will arrive.

This listening can be done by adding some arguments to the command line launching OOo or by adding this connection info in OOo Setup.xcu configuration file, so that it is automatic each time it is launched.

<node oor:name="Office">
  <prop oor:name="ooSetupConnectionURL">
    <value>socket,host=localhost,port=8100;urp;StarOffice.Service</value>
  </prop>
</node>

This OOo registry modification has been packaged as an extension that eases the deployment:

<OOoInstallatioPath>/program/unopkg add nxOOoAutoListen.oxt

Then OOo can be launched:

export DISPLAY=":77.0"
/opt/openoffice.org2.2/program/soffice -headless -nofirststartwizard

The -headless switch lets OOo manage to answer every question that may occur with a default response avoiding dead-locks. It also hides the OOo windows if a display is available by default (eg. Ms Windows). Note that the -invisible switch is not used as it is redundant and errors on PDF exports may occur. The -nofirststartwizard skips any post-install wizard, allowing to use OOo directly after the installation without any user parametrization. If the nxOOoAutoListen extension has not been installed, the following switch will let OOo listen on the correct interface:port "-accept=socket,host=localhost,port=8100;urp;StarOffice.Service".

Note that the platform used for both the JVM and OOo have to be consistent to allow UNO protocol to work: with a 32 bits JVM, you'll have to use the 32 bits OOo version while the 64 bits one will be mandatory for a 64 bits JVM.

38.5. Run Nuxeo EP with a specific IP binding

To be able to call the Nuxeo Services remotely using the Nuxeo Framework (e.g. when using Nuxeo RCP), you will need to bind an IP address when running the server. To do this, a few step are needed:

  • in $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/nuxeo.properties change the value of org.nuxeo.ecm.instance.host, remplace "localhost" by the IP adress of the JBoss server

  • in $JBOSS_HOME/server/default/deploy/nuxeo.ear/config/mbeans/core-events-client-service.xml for java.naming.provider.url replace the 127.0.0.1 value by the IP adress of the Jboss server

  • start jboss with the -b option:

    ./run.sh -b IP_adress_of_the_server

38.6. Virtual Hosting

The Nuxeo webapp can be virtual hosted behind a HTTP/HTTPS reverse proxy, like Apache.

38.6.1. Motivations for virtual hosting

Virtual hosting provides several advantages:

  • Support for HTTPS

    HTTPS support in Apache is easy and flexible to setup.

    Apache can also be used to handle certificate authentication.

  • URL filtering

    You can use Apache filtering tools to limit the URLs that can be accessed via the reverse proxy.

  • Handle HTTP cache for static resources

    Nuxeo 5 generates standard HTTP cache headers for all static resources (images, JavaScript...).

    These resources are by default cached on the client side (in the browser cache). For performance reasons, it can be useful to host these resources in the reverse proxy cache.

38.6.2. Virtual hosting configuration for Apache 2.x

38.6.2.1. Reverse proxy with mod_proxy

For this configuration, you will need to load and enable mod_proxy and mod_proxy_http modules.

ProxyPass /nuxeo/ http://Nuxeo5ServerInternalIp:8080/nuxeo/
ProxyPassReverse /nuxeo/ http://Nuxeo5ServerInternalIp:8080/nuxeo/

You can also use rewrite rules to achieve the same result:

ProxyVia On
ProxyRequests Off
RewriteEngine On
RewriteRule /nuxeo(.*) http://Nuxeo5ServerInternalIp:8080/nuxeo$1 [P,L]

This configuration will allow you to access the Nuxeo EP webapp via http://ApacheServer/nuxeo/.

The Nuxeo webapp will generate the URLs after reading the http header x-forwarded-host.

Unfortunately, this header does not specify the protocol used, so if your Apache is responding to HTTPS, you will need to send Nuxeo EP a specific header to indicate the base URL that the webapp must use when generating links.

RequestHeader append nuxeo-virtual-host "https://myDomainName/"
ProxyPass /nuxeo/ http://Nuxeo5ServerInternalIp:8080/nuxeo/
ProxyPassReverse /nuxeo/ http://Nuxeo5ServerInternalIp:8080/nuxeo/    

This will require you to load and activate mod_header module.

38.6.2.2. Reverse proxy with mod_jk

mod_jk allows you to communicate between Apache and Tomcat via the ajp1.3 protocol.

JkWorkersFile /etc/apache2/jk/workers.properties
JkLogFile     /var/log/mod_jk.log
JkLogLevel    info
JkMount /nuxeo ajp13
JkMount /nuxeo/* ajp13    

The workers.properties file will contain the list of Nuxeo EP Tomcat servers. The AJP13 tomcat listener should be enabled by default on port 8009.

worker.list=ajp13
worker.ajp13.port=8009
worker.ajp13.host=Nuxeo5ServerInternalIp
worker.ajp13.type=ajp13
worker.ajp13.socket_keepalive=1
worker.ajp13.connection_pool_size=50    

Once again, if you use HTTPS, you will need to set the Nuxeo-specific header to tell the webapp how to generate URLs:

RequestHeader append nuxeo-virtual-host "https://myDomainName/"

This will require you to load and activate the mod_header module.

38.6.2.3. Configuring http cache

The Nuxeo webapp includes a Servlet Filter that will automatically add header cache to some resources returned by the server.

By using the deployment-fragement.xml you can also put some specific resources behind this filter :

<extension target="web#FILTER">
  <filter-mapping>
    <filter-name>simpleCacheFilter</filter-name>
    <url-pattern>/MyURLsToCache/*</url-pattern>
  </filter-mapping>
</extension>

When Nuxeo EP is virtual hosted with apache you can use mod_cache to use the reverse-proxy as cache server.

You can also use Squid or any other caching system that is compliant with the standard HTTP caching policy.

38.7. The Nuxeo Shell

38.7.1. Overview

The Nuxeo Shell is a command line tool for everyone who needs simple and quick remote access to a Nuxeo EP server. You can see it as the swiss army knife for the Nuxeo EP world. It can be used by regular users to browse or modify content, by advanced users to administrate nuxeo servers, or by programmers to test and debug.

The Nuxeo Shell is designed as an intuitive and extensible command line application. It can both serve as a user, administrator or programmer tool, or as a framework to develop new Nuxeo command line clients.

The application is based on the Nuxeo Runtime framework and thus offers the same extension point mechanism you can find on the server application.

The main features of the command line tool are:

  • Two operating modes: an interactive and a batch mode.

  • Advanced command line editing like:

    • auto-completion

    • command history

    • command line colors

    • command line shortcuts like: CTRL+K, CTR+A, etc.

  • JSR223 scripting integration. You can thus connect and execute commands on a Nuxeo server in pure scripting mode.

  • Extensibility - using Nuxeo Runtime extension points

The advanced command line handling is done using the JLine library.

The only requirement is Java 5+. The tool works on any Unix-like OS, on Windows and on Mac OS X.

38.7.2. User Manual

The Nuxeo Shell application is packaged as a zip archive. To install it, you need to unzip and copy the content in a folder.

The application folder structure is as follow:

+ nxshell
  + app
    + bundles
    + config
    + data
    + lib
  + lib
  - Launcher.class
  - log4j.properties
  - launcher.properties
  - nxshell.sh

  • The lib folder contains JARs needed by the application launcher. The Launcher.class is the application launcher and launcher.properties contains configuration for the launcher.

  • log4j.properties is as you expect the configuration for log4j.

  • nxshell.sh is a shell script that launches the application.

  • The app folder contains the application code and data.

    • app/bundles contains the application OSGi bundles. These bundles will be deployed using a minimal implementation of OSGi (the same that is used on the server side). We may replace the default implementation by equinox later.

    • app/lib contains third party libraries needed by the application bundles.

    • app/config contains the application configuration files.

    • app/data contains temporary data.

The only file you may need to change is the nxshell.sh script. Here is the content of this file:

#!/bin/bash

#JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8788,server=y,suspend=y"
JAVA_OPTS="$JAVA_OPTS -Dorg.nuxeo.runtime.1.3.3.streaming.port=3233"
java $JAVA_OPTS Launcher launcher.properties $@

If you uncomment the first line, you will be able to run Nuxeo Shell in debug mode.

The second line [must] be commented out if on the server you are running on a nuxeo runtime 1.4.SNAPSHOT. When running against Nuxeo EP 5.1 you need to let this uncommented.

You can run the application in two modes:

  1. In batch mode - in this mode you need to specify the command that will be executed. After the command excecution the process will exit. Here is an example of a command executed in batch mode:

    ./nxshell.sh export /path/to/remote/doc /path/to/local/folder
  2. In interactive mode - in this mode you can share a single session to run multiple commands against the remote Nuxeo EP. To start the application in that mode you should run the "interactive" command as follows:

    ./nxshell.sh interactive

    After entering in interactive mode a command prompt will be displayed. At this prompt you can enter commands in the same way you specify them on the command line in batch mode.

    When not connected to a server, the prompt will be displayed as:

    |> 

    After connecting to a server named, let's say "nuxeo-platform", the prompt will be displayed as:

    |nuxeo-platform> 

So, as we've seen in the above examples, executing a command is done by using the the following syntax:

command [options] [parameters]

where options and parameters are optional and are specific to the command you run.

Example:

import -u /path/to/doc /path/to/local_file

In this case "import" is the command, "-u" is a flag option and "path/to/doc" and "/path/to/local_file" are both parameters

Parameters are stand alone arguments (they are not bound to a specific option) and can be retrieved programatically using their index. In the example above, the first parameter will have the index 0 while the second the index 1.

38.7.2.1. Command Options

Command options are defined by a name and optionally a shortcut (a short name). When referring to an option using its name you should prefix it by two hyphens '--'. When using short names you should only use one hyphen as a prefix. For example if you have an option named "host" and using a short name of "h" the following commands are equivalent:

./nxshell.sh interactive -h localhost

./nxshell.sh interactive --host localhost

Options may take values or may be used as flags turning on / off a specific option by their simple presence.

When using long names you should specify the option values immediately after the option. However when using short names you can group options together. Let say for example we have a command that support 4 options: a, v, i, o. a and v are flag options and both i and o takes an argument as value. In this case the you can group options like the following:

command -avi in_file -o out_file

or

command -avio in_file out_file

or anyhow you want. You should keep in mind that when grouping options that take arguments, these arguments will be assigned to each of this options in the order they were specified on the command line.

Global Options

Besides the specific options that commands may define, there are several global options that apply to all commands. These are:

  • host (--host or -h) the Nuxeo EP host where to connect - defaults to localhost

  • port (--port or -p) the Nuxeo EP port where to connect - defaults to 62474

  • username (--username or -u) the username to use - defaults to the "system" user

  • password (--password or -P) the password to use

38.7.2.2. Commands

There is the list of all built-in commands of nuxeo shell.

[Notes:]

  1. Many of these built-in commands are not yet implemented at the time of writing this document. I will mark them using *.

  2. The commands can be grouped in two categories:

    • offline commands - command that doesn't need a connection to work. Example: help, log etc.

    • online commands - commands that requires a connection to work. These commands are automatically connecting if no connection is currently established.

  3. Some commands make no sense and are not available in both modes (batch and interactive). This will be specified by each command if it is the case.

interactive

Runs in the interactive mode. This command is not available when already in interactive mode.

Has no specific options.

./nxshell.sh interactive
help

Displays the help page.

Takes an optional parameter which is the name of a command.

By default, displays the global help page. If a command is given as an argument, displays the help page for that command.

./nxshell.sh help ls
log *

Displays the client log. Available only in interactive mode

connect *

Connects to a given server. If a connection is already established, close it first.

Available only in interactive mode

disconnect *

Disconnects from the current connected server. If no connection exists, does nothing.

Available only in interactive mode

ls

Lists the children of the current folder in the repository.

By default, Folderish types are displayed in blue.

Available only in interactive mode

cd

Changes the current directory in the repository (to a Folderish document)

pwd

Displays the current path in the repository.

view

Views info about document. The information displayed can be controlled using these command options:

--all ( -a ) - view all data

--system (-s) - view only the system data

--acp - view the ACLs on that document

rm

Removes a document or a tree of documents.

mkdir

Creates a Folder document.

put

Uploads a blob to a file document. If the target document doesn't exists, creates it.

putx

Creates a document other than a file. Metadata (and blobs) are specified in the Nuxeo export format.

get

Downloads the blob from a File document.

getx

Gets a document as an XML file (as export, but only for a document).

export

Exports documents from the repository.

import

Imports documents into the repository.

chperm *

Changes a privilege on the given document.

adduser *

Creates a new user.

addgroup *

Creates a new group.

find *

Search the repository using the NXQL query language.

lstypes *

viewtype *

lsusers *

lsgroups *

viewuser *

viewgroup *

38.7.2.3. Examples

38.7.3. Extending the shell

If you a need a functionality not provided by the Nuxeo Shell, you can simply add it by writing a Java class and a XML file to describe your extensions. By using declarative extensions, you can control things like auto-completion and help pages for your own commands.

38.7.3.1. Registering Custom Commands

Defining help pages

Controlling auto-completion