Activiti: Multi-schema multi-tenant not work

My issue: Activiti generated successful tables for all databases of each tenant which I configured. However, all my action (create model, deploy model, start process instance with tenant id) were recorded to 1 db which config for default tenant (empty string “”). Detail Below is my implementation: MultiTenantProcessEngineConfiguration

import javax.sql.DataSource;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.impl.cfg.multitenant.MultiSchemaMultiTenantProcessEngineConfiguration;
import org.activiti.engine.impl.cfg.multitenant.TenantInfoHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;

import com.mysql.jdbc.Driver;

import sdk.activiti.model.VNGTenantInfoHolder;

public class VNGMultiTenantProcessEngineConfiguration extends MultiSchemaMultiTenantProcessEngineConfiguration {
    protected static final Log log = LogFactory.getLog(VNGMultiTenantProcessEngineConfiguration.class);
    public static final String DEFAULT_TENANT = "";
    public static final String VNG_TENANT = "vng";
    public static final String FPT_TENANT = "fpt";

    public VNGMultiTenantProcessEngineConfiguration() {
        super(getTenantInfoHolder());
    }

    public VNGMultiTenantProcessEngineConfiguration(TenantInfoHolder tenantInfoHolder) {
        super(tenantInfoHolder);
    }

    @Override
    public ProcessEngine buildProcessEngine() {
        this.setDatabaseType(MultiSchemaMultiTenantProcessEngineConfiguration.DATABASE_TYPE_MYSQL);
        this.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE);

        // We must register datasource for null tenant, if not we will get can
        // not get datasource for tenant null.
        registerTenant(null,
                createDataSource(
                        "jdbc:mysql://10.30.47.242:3306/activiti6default?autoReconnect=true&failOverReadOnly=false&maxReconnects=5",
                        "u_activiti", "activiti"));
        registerTenant(DEFAULT_TENANT,
                createDataSource(
                        "jdbc:mysql://10.30.47.242:3306/activiti6default?autoReconnect=true&failOverReadOnly=false&maxReconnects=5",
                        "u_activiti", "activiti"));
        registerTenant(VNG_TENANT,
                createDataSource(
                        "jdbc:mysql://10.30.47.242:3306/activiti6vng?autoReconnect=true&failOverReadOnly=false&maxReconnects=5",
                        "u_activiti", "activiti"));
        registerTenant(FPT_TENANT,
                createDataSource(
                        "jdbc:mysql://10.30.47.242:3306/activiti6fpt?autoReconnect=true&failOverReadOnly=false&maxReconnects=5",
                        "u_activiti", "activiti"));

        return super.buildProcessEngine();
    }

    private DataSource createDataSource(String connectionStr, String user, String password) {
        try {
            return new SimpleDriverDataSource(new Driver(), connectionStr, user, password);
        } catch (SQLException e) {
            log.error(String.format("Can not create DataSource with connection string '%s'\nERROR MESSAGE: %s",
                    connectionStr, e.getMessage()));
            return null;
        }
    }

    private static TenantInfoHolder getTenantInfoHolder() {
        VNGTenantInfoHolder tenantInfoHolder = new VNGTenantInfoHolder();

        tenantInfoHolder.addTenant(DEFAULT_TENANT);
        tenantInfoHolder.addUser(DEFAULT_TENANT, "kermit");

        tenantInfoHolder.addTenant(VNG_TENANT);
        tenantInfoHolder.addUser(VNG_TENANT, "kermit");

        tenantInfoHolder.addTenant(FPT_TENANT);
        tenantInfoHolder.addUser(FPT_TENANT, "kermit");

        return tenantInfoHolder;
    }
}

The bean config

  <bean id="processEngineConfiguration" class="sdk.activiti.configuration.VNGMultiTenantProcessEngineConfiguration" />
  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
      <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>
  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
  <bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
  <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />

When I create model, deploy, and create instance for tenant ‘vng’ (using REST API), all data were stored in db activiti6default (my expectation is activiti6vng).

https://stackoverflow.com/questions/46948778/activiti-6-multi-schema-multi-tenant

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 28 (12 by maintainers)

Most upvoted comments

@daisuke-yoshimoto according to this post - http://www.jorambarrez.be/blog/2015/10/06/multi-tenancy-separate-database-schemas-in-activiti/, I think activiti can support separate data sources for each tenant with one engine, that why the class MultiSchemaMultiTenantProcessEngineConfiguration has the function registerTenant(tenantId, datasource). How about your ideas?

@daisuke-yoshimoto I tried latest release i.e. v5.23.0 (Aug-2019) of Activiti 5.x and it works perfectly fine with multiple tenants if you have proper implementation of TenantAwareDataSource and TenantInfoHolder. It is creating activiti schema on different tenant schema and I am using single ProcessEngine with MultiSchemaMultiTenantProcessEngineConfiguration. I tried it on oracle and it works fine. You can close this issue.

Please share your full code.

@paksboda I do not work on the project anymore … so don’t expect any status update from my side… also check the activity of the 5.x branch… you might get an idea if things are progressing there or not. HTH

@daisuke-yoshimoto this issue coming while generating activiti tables on startup not while doing process transitions. As i have mentioned in the other issue, we were using DbSqlSessionFactory only, since its not working as expected we have extended it as i’ve mentioned in that thread.