How To Create Multi Tenant In Opentaps

Posted By : Murari Kumar | 28-Jun-2017

In this blogs I am going to describe how to create multi tenant in opentaps. I am going to describe step to create multi tenant which is given below:-

1.Add Database Name with prefix ofbiz_<DATABASE NAME>.

2.Add ofbiz_<DATABASE NAME>.cfg.xml file at location(skulocity-opentaps/opentaps/opentaps-common/config/). 

3.This file includes same copy of localpostgres.cfg.xml just change the line number 5 from this <property name="ofbiz.helperName">localpostgres</property> to <property name="ofbiz.helperName">ofbiz_<DATABASE NAME> </property>.

4.set multitenant=Y in general.properties file(skulocity-opentaps/framework/common/config/general.properties).

5.Add delegater in entityengine.xml file (/skulocity-opentaps/framework/entity/config/entityengine.xml).

<delegator name="default#<DATABASE NAME>" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main">
        <group-map group-name="org.ofbiz" datasource-name="ofbiz_<DATABASE NAME>"/>
        <group-map group-name="org.ofbiz.tenant" datasource-name="localpostnewtenants"/>
    </delegator>
 
6.Add datasource-name in entityengine.xml file (skulocity-opentaps/framework/entity/config/entityengine.xml) 
with ofbiz_<DATABASE NAME> name.
 
<datasource name="ofbiz_<DATABASE NAME>"
                helper-class="org.ofbiz.entity.datasource.GenericHelperDAO"
                schema-name="public"
                field-type-name="postnew"
                check-on-start="true"
                add-missing-on-start="true"
                use-fk-initially-deferred="false"
                alias-view-columns="false"
                join-style="ansi"
                result-fetch-size="50"
                use-binary-type-for-blob="true">
        <read-data reader-name="seed"/>
        <read-data reader-name="seed-initial"/>
        <read-data reader-name="demo"/>
        <read-data reader-name="ext"/>
        <inline-jdbc
                jdbc-driver="org.postgresql.Driver"
                jdbc-uri="jdbc:postgresql://127.0.0.1/ofbiz_<DATABASE NAME>"
                jdbc-username="skulocity"
                jdbc-password="skulocity"
                isolation-level="ReadCommitted"
                pool-minsize="2"
                pool-maxsize="250"
                time-between-eviction-runs-millis="600000"/>
    </datasource>
7.Add ant task in build.xml file. 
<target name="create-tenant"
            depends="create-tenant-on-Derby,create-tenant-on-MySQL,create-tenant-on-Oracle,create-tenant-on-PostgreSQL"
            description="Create a new tenant in your environment, create the delegator, load initial data with admin-user and password 
(needs multitenant=Y in general.properties)">
            <tstamp/>
</target>
    
    <!-- description="This creates entity Tenant and TenantDataSource in default, installs data in the delegator and creates 
the admin-user and password for the tenant" sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
 
<target name="get-tenant-data">
        <input addproperty="tenantId" message="Enter Id for the tenant: "/>
        <input addproperty="tenantName" message="Enter name for tenant: "/>
        <input addproperty="data-readers" message="Enter data to install.Choices are e.g. seed,seed-initial,ext,demo.
Multipe datasets must be separated with a comma: "/>
        <input addproperty="db-Platform" message="Select your default database platform, D = Derby,M = MySQL, O = Oracle, P = PostgreSQL"
                validargs="D,M,O,P"/>
        <echo message="Please make sure that the driver of the platform is installed and that the databases have been created 
(in function of the entityengine.xml datasource-names)"/>
        <input addproperty="db-IP" message="Enter IP address of the database server (you may add a port number)"/>
        <input addproperty="db-User" message="Enter userID of database user: "/>
        <input addproperty="db-Password" message="Enter password of database user: "/>
        <condition property="isDerby">
            <equals arg1="${db-Platform}" arg2="D"/>
        </condition>
        <condition property="isMySQL">
            <equals arg1="${db-Platform}" arg2="M"/>
        </condition>
        <condition property="isOracle">
            <equals arg1="${db-Platform}" arg2="O"/>
        </condition>
        <condition property="isPostgreSQL">
            <equals arg1="${db-Platform}" arg2="P"/>
        </condition>
        <antcall target="tenant-data-entry"/>
    </target>
 
    <!-- description="Creates tenant data and instance" sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
 
    <target name="create-tenant-on-Derby" depends="get-tenant-data" if="isDerby">
      <echo message="Installing on Derby"/>
        <copy file="${basedir}/framework/resources/templates/AdminNewTenantData-Derby.xml" tofile="runtime/tmp/tmpTenantData.xml">
            <filterset>
                <filter token="tenantId" value="${tenantId}"/>
                <filter token="tenantName" value="${tenantName}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
          <param name="data-file" value="runtime/tmp/tmpTenantData.xml"/>
        </antcall>
        <delete file="runtime/tmp/tmpTenantData.xml"/>
        <antcall target="load-tenant-data-readers"/>
        <antcall target="load-tenant-admin-user-login">
            <param name="userLoginId" value="${tenantId}-admin"/>
            <param name="delegatorId" value="default#${tenantId}"/>
        </antcall>
    </target>
 
    <target name="load-file" depends="build" description="Load data using the command line argument 'data-file' 
to load data from a given file using the 'default' delegator or a delegator specified in the command line argument 'delegator'">
        <property name="delegator" value="default" />
        <java jar="ofbiz.jar" fork="true">
            <jvmarg value="${memory.initial.param}"/>
            <jvmarg value="${memory.max.param}"/>
            <jvmarg value="${memory.maxpermsize.param}"/>
            <arg value="install"/>
            <arg value="delegator=${delegator}"/>
            <arg value="file=${data-file}"/>
        </java>
    </target>
 
   <!-- description="Creates tenant data and instance. Don't forget db driver(s) and already created DBs in function of the entityengine.xml datasource-names"
        sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
 
    <target name="create-tenant-on-MySQL" depends="get-tenant-data" if="isMySQL">
        <echo message="Installing on MySQL"/>
        <copy file="${basedir}/framework/resources/templates/AdminNewTenantData-MySQL.xml" tofile="runtime/tmp/tmpTenantData.xml">
            <filterset>
                <filter token="tenantId" value="${tenantId}"/>
<filter token="tenantName" value="${tenantName}"/>
<filter token="db-IP" value="${db-IP}"/>
<filter token="db-User" value="${db-User}"/>
<filter token="db-Password" value="${db-Password}"/>
            </filterset>
</copy>
<antcall target="load-file">
   <param name="data-file" value="runtime/tmp/tmpTenantData.xml"/>
</antcall>
<delete file="runtime/tmp/tmpTenantData.xml"/>
<antcall target="load-tenant-data-readers"/>
<antcall target="load-tenant-admin-user-login">
   <param name="userLoginId" value="${tenantId}-admin"/>
   <param name="delegatorId" value="default#${tenantId}"/>
</antcall>
    </target>
    <!-- description="Creates tenant data and instance. Don't forget db driver(s) and already created DBs in function of the entityengine.xml 
datasource-names" sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
 
<target name="create-tenant-on-Oracle" depends="get-tenant-data" if="isOracle">
<echo message="Installing on Oracle"/>
<copy file="${basedir}/framework/resources/templates/AdminNewTenantData-Oracle.xml" tofile="runtime/tmp/tmpTenantData.xml">
   <filterset>
<filter token="tenantId" value="${tenantId}"/>
<filter token="tenantName" value="${tenantName}"/>
<filter token="db-IP" value="${db-IP}"/>
<filter token="db-User" value="${db-User}"/>
<filter token="db-Password" value="${db-Password}"/>
   </filterset>
</copy>
<antcall target="load-file">
   <param name="data-file" value="runtime/tmp/tmpTenantData.xml"/>
</antcall>
<delete file="runtime/tmp/tmpTenantData.xml"/>
<antcall target="load-tenant-data-readers"/>
<antcall target="load-tenant-admin-user-login">
   <param name="userLoginId" value="${tenantId}-admin"/>
   <param name="delegatorId" value="default#${tenantId}"/>
</antcall>
 </target>
 
    <!-- description="Creates tenant data and instance. Don't forget db driver(s) and already created DBs in function of the entityengine.xml 
datasource-names" sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
 
    <target name="create-tenant-on-PostgreSQL" depends="get-tenant-data" if="isPostgreSQL">
<echo message="Installing on PostgreSQL"/>
<copy file="${basedir}/framework/resources/templates/AdminNewTenantData-PostgreSQL.xml" tofile="runtime/tmp/tmpTenantData.xml">
   <filterset>
<filter token="tenantId" value="${tenantId}"/>
<filter token="tenantName" value="${tenantName}"/>
<filter token="db-IP" value="${db-IP}"/>
<filter token="db-User" value="${db-User}"/>
<filter token="db-Password" value="${db-Password}"/>
   </filterset>
</copy>
<antcall target="load-file">
   <param name="data-file" value="runtime/tmp/tmpTenantData.xml"/>
</antcall>
<delete file="runtime/tmp/tmpTenantData.xml"/>
<antcall target="load-tenant-data-readers"/>
<antcall target="load-tenant-admin-user-login">
   <param name="userLoginId" value="${tenantId}-admin"/>
   <param name="delegatorId" value="default#${tenantId}"/>
</antcall>
    </target>
 
    <!-- description="displays tenant data"  sub-target of get-tenant-data, can't used alone => no description, to not clutter "ant -p" -->
 
    <target name="tenant-data-entry">
<echo>------------------------------------</echo>
<echo message="tenantId = ${tenantId}"/>
<echo>tenantName = ${tenantName}</echo>
<echo>db-Platform = ${db-Platform}</echo>
<echo>db-IP = ${db-IP}</echo>
<echo>db-User = ${db-User}</echo>
<echo>db-Password = ${db-Password}</echo>
<echo>------------------------------------</echo>
<echo>database for tenant data will be 'ofbiz_${tenantId}'</echo>
<echo>database for tenant olap data will be 'ofbizolap_${tenantId}</echo>
<echo message="Please make sure that the driver of the platform is installed and that the databases have been created 
(Check names just above)"/>
<echo>------------------------------------</echo>
<input addproperty="continueYN" message="Continue Y or N" validargs="N,n,Y,y"/>
 
    </target>
 
    <target name="load-tenant-admin-user-login" description="Create the admin login for the tenant with admin privileges, and a 
temporay password equal to 'ofbiz'. Password must be changed on first login">
<echo>------------------------------------</echo>
<echo message="Installing the admin for the tenant"/>
<echo message="Delegator = ${delegatorId}"/>
<echo message="Tenant admin = '${userLoginId}'"/>
<echo message="Password for tenant admin is 'ofbiz' must change on first login"/>
<echo>------------------------------------</echo>
<input addproperty="continueYN" message="Continue Y or N" validargs="N,n,Y,y"/>
<copy file="${basedir}/framework/resources/templates/AdminUserLoginData.xml" tofile="runtime/tmp/tmpUserLogin.xml">
   <filterset>
<filter token="userLoginId" value="${userLoginId}"/>
   </filterset>
</copy>
<antcall target="load-file">
   <param name="data-file" value="runtime/tmp/tmpUserLogin.xml"/>
   <param name="delegator" value="${delegatorId}"/>
</antcall>
<delete file="runtime/tmp/tmpUserLogin.xml"/>
    </target>
 
    <target name="load-tenant-data-readers" description="Load data of given data-readers in the tenant database. 
Example: ./ant load-tenant-data-readers -Ddata-readers=seed,seed-initial -DtenantId=demo">
<echo>------------------------------------</echo>
<echo message="Loading selected data-readers in tenant database"/>
<echo message="Delegator = default#${tenantId}"/>
<echo message="Data-readers = ${data-readers}"/>
<echo>------------------------------------</echo>
<java jar="ofbiz.jar" fork="true">
   <jvmarg value="${memory.initial.param}"/>
   <jvmarg value="${memory.max.param}"/>
   <jvmarg value="${memory.maxpermsize.param}"/>
   <arg value="install"/>
   <arg value="readers=${data-readers}"/>
   <arg value="delegator=default#${tenantId}"/>
</java>
    </target>
 
    <target name="load-extseed" depends="build" description="Load seed, seed-initial and ext data; meant for manual/generic testing,
development, or going into production with a derived system based on stock OFBiz where the ext data basically
replaces the demo data">
<java jar="ofbiz.jar" fork="true">
   <jvmarg value="${memory.initial.param}"/>
   <jvmarg value="${memory.max.param}"/>
   <jvmarg value="${memory.maxpermsize.param}"/>
   <arg value="install"/>
   <arg value="readers=seed,seed-initial,ext"/>
</java>
    </target>
 
After following above given steps run  command which is given below:-
 
1. ./ant load-extseed
2. ./ant create-admin-user-login
3. ./ant create-tenant
  enter “TENANT1” for “Id”
      enter “Tenant 1” for “name”
      enter “seed,seed-initial,ext” for “data to install” select (seed,ext)
    enter “P” for “default database platform” which referes to Postgres
      enter “127.0.0.1” for “IP address of the database server”
      enter “db-user-name” for “userID of database user”
      enter “db-password” for “password of database user”
      enter “Y” to confirm “Tenant data”
4. Run opentabs.

About Author

Author Image
Murari Kumar

Murari is a bright Web developer. He has expertise in Java.

Request for Proposal

Name is required

Comment is required

Sending message..