Last week, while presenting at the IndicThreads Cloud Conference, we got into a very interesting discussion. How to make the existing application that we have multi-tenant without changing a hell lot of code or may be without changing even minimal code.
Before we get to that question, let us do a quick recap of multi-tenancy.
Multi-tenancy is the ability to run multiple customers on a single software instance installed on multiple servers to increase resource utilization by allowing load balancing among tenants, and to reduce operational complexity and cost in managing the software to deliver the service. Multi-tenancy is not multi-instance architecture where separate software instances (or hardware systems) are set up for different client organizations.
There are primarily two ways of achieving multi-tenancy.
- Hypervisor model – In this model, the same software is installed on the likes of VMWare. Each customer has his own hypervisor and hence is abstracted away from rest of the tenants. The advantages of this approach being that it is easy to implement but is not very efficient on the cost.
- Database Model – Another model is to have a single instance of the application, but manage the multi-tenancy at the db level. At the db level, there are again 2 ways to manage it.

- By adding a tenant id to all (majority) the tables of the database so that while querying you are only fetching the data for the tenant who has logged in.
- By having individual tables for each tenant so that data is fetched only from the region which belongs to the tenant. Incidentally Google App Engine came up with a similar approach for multi-tenancy when they came up with their Namespaces API as a part of their 1.3.6 sdk release.



For more information please refer to my presentation on multi-tenancy.
So coming back to the question of how do we make an existing application multi-tenant without changing a lot of code?
The answer lies in the power of Aspects and Namespaces.
Let us assume that you have an @EnhanceWithTenant annotation which can be applied on your DAO. So ideally, your code method would be looking something like this
[sourcecode language=”java”]
@EnhanceWithTenant
public ProjectAssignment findProjectAssignmentByKey(String key) {
ProjectAssignment projectAssignment = (ProjectAssignment) getEntityManager()
.createQuery("SELECT FROM ProjectAssignment WHERE encodedKey=:key").setParameter("key", key)
.getSingleResult();
return projectAssignment;
}
[/sourcecode]
Now, as soon as this method is called, the aspect associated with the annotation reworks the query to fire the query on the namespace which has been earmarked for the logged in tenant.
Scenario One
This is what would happen,
- The aspect would fetch the tenant_id from the logged in information
- From the tenant_id, it would fetch the namespace, where this tenant belongs
- It would now enhance the query which is being executed to goto the Namespace which is relevant for this tenant.
Thus, just by adding an annotation and making use of the aspects, you would be able to make your application multi-tenant.
Scenario Two
In this scenario, assume that making a separate Namespace for each tenant is not possible. The query however, somehow needs to know that it needs to fetch data for the logged in tenant only.
In this case, you would have to add the tenant_id as a column to all the relevant tables of the database. Once the method is executed and the annotation is encountered, the aspect would apply a where clause to the statement which would be matching on the tenant_id of the logged in user.
Thus, here instead of pointing to a Namespace, the query would get an additional where clause which would match the tenant_id.
It may quite be the case that the additional where clause might have to be constructed intelligently and would be based on some logic, however with this approach one would be able to achieve multi-tenancy with little changes in the existing legacy code.