<?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.RepositoryCreationService">
  <title>RepositoryCreationService</title>

  <para><emphasis>RepositoryCreationService</emphasis> is the service which is
  used to create repositories in runtime. The service can be used in a
  standalone or cluster environment.</para>

  <section id="JCR.RepositoryCreationService.Dependencies">
    <title>Dependencies</title>

    <para>RepositoryConfigurationService depends to next components:</para>

    <itemizedlist>
      <listitem>
        <para><link linkend="Core.DBCreatorService">DBCreator</link> -
        DBCreator used to create new database for each unbinded
        datasource.</para>
      </listitem>

      <listitem>
        <para><link linkend="JCR.BackupService">BackupManager</link> -
        BackupManager used to created repository from backup.</para>
      </listitem>

      <listitem>
        <para><link linkend="Kernel.RPCService">RPCService</link> - RPCService
        used for communication between cluster-nodes</para>

        <note>
          <para>RPCService may not be configured - in this case,
          RepositoryService will work as standalone service.</para>
        </note>
      </listitem>
    </itemizedlist>
  </section>

  <section id="JCR.RepositoryCreationService.HowItWorks">
    <title>How it works</title>

    <itemizedlist>
      <listitem>
        <para>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.</para>
      </listitem>

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

      <listitem>
        <para>whan repository become created - user-node broadcast message to
        all clusterNodes with RepositoryEntry, so each cluster node starts new
        Repository.</para>
      </listitem>
    </itemizedlist>

    <para>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)).</para>
  </section>

  <section id="JCR.RepositoryCreationService.Configuration">
    <title>Configuration</title>

    <para>RepositoryCreationService configuration</para>

    <programlisting language="xml">&lt;component&gt;
   &lt;key&gt;org.exoplatform.services.jcr.ext.backup.BackupManager&lt;/key&gt;
   &lt;type&gt;org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl&lt;/type&gt;
   &lt;init-params&gt;
      &lt;properties-param&gt;
         &lt;name&gt;backup-properties&lt;/name&gt;
         &lt;property name="backup-dir" value="target/backup" /&gt;
      &lt;/properties-param&gt;
   &lt;/init-params&gt;
&lt;/component&gt;

&lt;component&gt;
   &lt;key&gt;org.exoplatform.services.database.creator.DBCreator&lt;/key&gt;
   &lt;type&gt;org.exoplatform.services.database.creator.DBCreator&lt;/type&gt;
   &lt;init-params&gt;
      &lt;properties-param&gt;
         &lt;name&gt;db-connection&lt;/name&gt;
         &lt;description&gt;database connection properties&lt;/description&gt;
         &lt;property name="driverClassName" value="org.hsqldb.jdbcDriver" /&gt;
         &lt;property name="url" value="jdbc:hsqldb:file:target/temp/data/" /&gt;
         &lt;property name="username" value="sa" /&gt;
         &lt;property name="password" value="" /&gt;
      &lt;/properties-param&gt;
      &lt;properties-param&gt;
         &lt;name&gt;db-creation&lt;/name&gt;
         &lt;description&gt;database creation properties&lt;/description&gt;
         &lt;property name="scriptPath" value="src/test/resources/test.sql" /&gt;
         &lt;property name="username" value="sa" /&gt;
         &lt;property name="password" value="" /&gt;
      &lt;/properties-param&gt;
   &lt;/init-params&gt;
&lt;/component&gt;

&lt;component&gt;
    &lt;key&gt;org.exoplatform.services.rpc.RPCService&lt;/key&gt;
    &lt;type&gt;org.exoplatform.services.rpc.jgv3.RPCServiceImpl&lt;/type&gt;
    &lt;init-params&gt;
        &lt;value-param&gt;
            &lt;name&gt;jgroups-configuration&lt;/name&gt;
            &lt;value&gt;jar:/conf/udp-mux.xml&lt;/value&gt;
        &lt;/value-param&gt;
        &lt;value-param&gt;
            &lt;name&gt;jgroups-cluster-name&lt;/name&gt;
            &lt;value&gt;RPCService-Cluster&lt;/value&gt;
        &lt;/value-param&gt;
        &lt;value-param&gt;
            &lt;name&gt;jgroups-default-timeout&lt;/name&gt;
            &lt;value&gt;0&lt;/value&gt;
        &lt;/value-param&gt;
    &lt;/init-params&gt;
&lt;/component&gt;  

&lt;component&gt;
   &lt;key&gt;org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationService&lt;/key&gt;
   &lt;type&gt;
      org.exoplatform.services.jcr.ext.repository.creation.RepositoryCreationServiceImpl
   &lt;/type&gt;
     &lt;init-params&gt; 
         &lt;value-param&gt; 
            &lt;name&gt;factory-class-name&lt;/name&gt; 
            &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt; 
         &lt;/value-param&gt; 
      &lt;/init-params&gt;
&lt;/component&gt;</programlisting>

    <itemizedlist>
      <listitem>
        <para>factory-class-name - is not mandatory parameter, indicates what
        the factory need to use to create DataSource objects</para>
      </listitem>
    </itemizedlist>
  </section>

  <section id="JCR.RepositoryCreationService.RepositoryCreationServiceInterface">
    <title>RepositoryCreationService Interface</title>

    <programlisting language="java">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;

   /**
    * 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;

}</programlisting>
  </section>

  <section id="JCR.RepositoryCreationService.ConclusionsAndRestrictions">
    <title>Conclusions and restrictions</title>

    <itemizedlist>
      <listitem>
        <para>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.</para>
      </listitem>

      <listitem>
        <para>RPCService is optional component, but without it,
        RepositoryCreatorService can not communicate with other cluster-nodes
        and works as standalone.</para>
      </listitem>
    </itemizedlist>
  </section>
</section>
