Blog

Multi-Tenancy in Activity

Multi Tenancy Activity

Multi-tenancy refers to a single application instance that can serve multiple organizations and their user groups. For Activiti BPM, there are several approaches to implement multi-tenancy, including:

  • Single Engine – Shared Database
  • Multi Schema – Multi Engine
Single Engine – Shared Database

In this approach, a single Activiti database schema is used to store information (process instances, tasks, process instance variables, deployed processes, etc.) regarding multiple tenants. Though this looks promising, handling complex process deployments for each tenant is easier said than done. Because, all the DB queries and updates should be tenant specific.

For Example, to deploy a BPM for specific tenant, you have to use

processEngine.getRepositoryService().createDeployment().addClasspathResource("MainProcess. bpmn20.xml ").tenantId("tenant1").deploy() ;

Similarly, to deploy it for multiple tenants, you have to either loop it or deploy it multiple times for each tenant. To get all the tasks in a group, the API call should include tenant specific information as below:

taskService.createTaskQuery().taskCandidateGroup(groupName).taskTenantId("tenant1").list();

To get all the tasks related to a user, the API call should include:

taskService.createTaskQuery().taskTenantId("tenant1").taskAssignee(userName).list();
Multi Schema – Multi Engine

The idea here is to use a different schema for each tenant and segregate this information from the rest. This simplifies the deployment and management process for adding new tenants to the application. In this approach, a process engine is created for each DB schema, relating to the respective tenant. And for each tenant, respective process engine will perform the job.

To create a set of process engines, based on their specific tenants and DB URLs, we have to use

ArrayList<String> tenants = MyProcessEngine.getTenants();
	for(String curTenant:tenants){ 
		ProcessEngine processEngineInstance = ProcessEngineConfiguration
			.createStandaloneProcessEngineConfiguration()
			.setJdbcDriver(props.getProperty("JdbcDriver"))
			.setJdbcUrl(props.getProperty(""+curTenant))
			.setJdbcPassword(props.getProperty("JdbcPassword"))
			.setJdbcUsername(props.getProperty("JdbcUsername"))
			.buildProcessEngine();
		processEngineInstanceMap.put(curTenant, processEngineInstance);
	}

In the above code, the tenant specific DB URL is read from the properties file and a process engine specific to them is created and kept in a HashMap.

public static synchronized ProcessEngine getInstance(String tenant){
		return processEngineInstanceMap.get(tenant);
	}

With the help of above code, a process engine specific to a tenant is picked up and returned for further use.
For process deployments, the only difference from the shared DB multi-tenancy is that the tenant ID is not required here, as the DB schema itself relates to a single tenant. Similarly for API calls, the tenant specific information is not required as the engine instance itself is tenant specific.

Leave a Reply

Your email address will not be published. Required fields are marked *