eXo Platform 3.5

## Chapter 28. RepositoryCreationService

## Intro

RepositoryCreationService is the service for creation repositories in runtime. The service can be used in standalone or cluster environment.

## Dependencies

RepositoryConfigurationService depends to next components:

- DBCreator - DBCreator used to create new database for each unbinded datasource.

- BackupManager - BackupManager used to created repository from backup.

- RPCService - RPCService used for communication between cluster-nodes

  ### Note

  RPCService may not be configured - in this case, RepositoryService will work as standalone service.

## How it works

- User executes reserveRepositoryName(String repositoryName) - client-node calls coordinator-node to reserve repositoryName. If this name is already reserved or repository with this name exist, client-node will fetch RepositoryCreationException. If not Client will get token string.

- than user executes createRepository(String backupId, RepositoryEntry rEntry, String token). Coordinator-node checks the token, and creates Repository.

- whan repository become created - user-node broadcast message to all clusterNodes with RepositoryEntry, so each cluster node starts new Repository.

There is two ways to create repositry: make it in single step - just call createRepository(String backupId, RepositoryEntry); or reserve repositoryName at first (reserveRepositoryName(String repositoryName)), than create reserved repository (createRepository(String backupId, RepositoryEntry rEntry, String token)).

## Configuration

RepositoryCreationService configuration

    <component>

       <key>org.exoplatform.services.jcr.ext.backup.BackupManager</key>

       <type>org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl</type>

       <init-params>

          <properties-param>

             <name>backup-properties</name>

             <property name="backup-dir" value="target/backup" />

          </properties-param>

       </init-params>

    </component>

    <component>

       <key>org.exoplatform.services.database.creator.DBCreator</key>

       <type>org.exoplatform.services.database.creator.DBCreator</type>

       <init-params>

          <properties-param>

             <name>db-connection</name>

             <description>database connection properties</description>

             <property name="driverClassName" value="org.hsqldb.jdbcDriver" />

             <property name="url" value="jdbc:hsqldb:file:target/temp/data/" />

             <property name="username" value="sa" />

             <property name="password" value="" />

          </properties-param>

          <properties-param>

             <name>db-creation</name>

             <description>database creation properties</description>

             <property name="scriptPath" value="src/test/resources/test.sql" />

             <property name="username" value="sa" />

             <property name="password" value="" />

          </properties-param>

       </init-params>

    </component>

    <component>

       <key>org.exoplatform.services.rpc.RPCService</key>

       <type>org.exoplatform.services.rpc.impl.RPCServiceImpl</type>

       <init-params>

          <value-param>

             <name>jgroups-configuration</name>

             <value>jar:/conf/standalone/udp-mux.xml</value>

          </value-param>

          <value-param>

             <name>jgroups-cluster-name</name>

             <value>RPCService-Cluster</value>

          </value-param>

          <value-param>

             <name>jgroups-default-timeout</name>

             <value>0</value>

          </value-param>

       </init-params>

    </component>

    <component>

       <key>org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationService</key>

       <type>

          org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl

       </type>

         <init-params>

             <value-param>

                <name>factory-class-name</name>

                <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

             </value-param>

          </init-params>

    </component>

- factory-class-name - is not mandatory parameter, indicates what the factory need to use to create DataSource objects

## RepositoryCreationService Interface

    public interface RepositoryCreationService

    {

       /**

        * Reserves, validates and creates repository in a simplified form.

        *

        * @param rEntry - repository Entry - note that datasource must not exist.

        * @param backupId - backup id

        * @param creationProps - storage creation properties

        * @throws RepositoryConfigurationException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        * @throws RepositoryCreationServiceException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        */

       void createRepository(String backupId, RepositoryEntry rEntry, StorageCreationProperties creationProps)

          throws RepositoryConfigurationException, RepositoryCreationException;n

       /**

        * Reserves, validates and creates repository in a simplified form.

        *

        * @param rEntry - repository Entry - note that datasource must not exist.

        * @param backupId - backup id

        * @throws RepositoryConfigurationException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        * @throws RepositoryCreationServiceException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        */

       void createRepository(String backupId, RepositoryEntry rEntry) throws RepositoryConfigurationException,

          RepositoryCreationException;

       /**

        * Reserve repository name to prevent repository creation with same name from other place in same time

        * via this service.

        *

        * @param repositoryName - repositoryName

        * @return repository token. Anyone obtaining a token can later create a repository of reserved name.

        * @throws RepositoryCreationServiceException if can't reserve name

        */

       String reserveRepositoryName(String repositoryName) throws RepositoryCreationException;

       /**

        * Creates repository, using token of already reserved repository name.

        * Good for cases, when repository creation should be delayed or made asynchronously in dedicated thread.

        *

        * @param rEntry - repository entry - note, that datasource must not exist

        * @param backupId - backup id

        * @param rToken - token

        * @param creationProps - storage creation properties

        * @throws RepositoryConfigurationException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        * @throws RepositoryCreationServiceException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        */

       void createRepository(String backupId, RepositoryEntry rEntry, String rToken, StorageCreationProperties creationProps)

          throws RepositoryConfigurationException, RepositoryCreationException;

       /**

        * Creates  repository, using token of already reserved repository name. Good for cases, when repository creation should be delayed or

        * made asynchronously in dedicated thread.

        *

        * @param rEntry - repository entry - note, that datasource must not exist

        * @param backupId - backup id

        * @param rToken - token

        * @throws RepositoryConfigurationException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        * @throws RepositoryCreationServiceException

        *          if some exception occurred during repository creation or repository name is absent in reserved list

        */

       void createRepository(String backupId, RepositoryEntry rEntry, String rToken)

          throws RepositoryConfigurationException, RepositoryCreationException;

       /**

        * Remove previously created repository.

        *

        * @param repositoryName - the repository name to delete

        * @param forceRemove - force close all opened sessions

        * @throws RepositoryCreationServiceException

        *          if some exception occurred during repository removing occurred

        */

       void removeRepository(String repositoryName, boolean forceRemove) throws RepositoryCreationException;

    }

## Conclusions and restrictions

- Each datasource in RepositoryEntry of new Repository must have unbinded datasources. Thats mean, such datasource must have not databases behind them. This restriction exists to avoid corruption of existing repositories data.

- RPCService is optional component, but without it, RepositoryCreatorService can not communicate with other cluster-nodes and works as standalone.