Plugin that enables multitenancy for mongodb. The plugin works by overrideing the mongoDatastore bean. All tenants have their own MongoTemplate for choosen tenant domain classes and thereby enabling them to create their own collections and database settings.Collections are postfixed with _tenantname_tenantid, and also the database is post fixed with an integer 'e.g. _0' for the first e.g. 500 tenants (depending on setting in config file)The plugin comes with 2 extra beans which is used by the overriden mongoDatastore bean
- tenantResolver which is responsible for resolving tenants. The default is a domain resover service which resolves against a tenantdomainmap
/** * Get the tenant database name, you can use the originalDatabaseName as a 'starting' point if you want * and just .e.g. append a tenant id to it or whatever you like. * * @param originalDatabaseName the database name it should have had if it wasn't a multi tenant * @return */ public String getTenantDatabaseName(String originalDatabaseName) /** * Get the collection name used for this tenant. * @param originalCollectionName name that it should have had if it wasnt a multi tenant * @return */ public String getTenantCollectionName(String originalCollectionName) /** * Gets the current tenant id, (eg. based on url resolving for example or currently logged in user or whatever) * @return */ public Object getTenantId() /** * override the current set tenant with this one * @param tenantid */ public void setTenantId(Object tenantid) /** * resets the tenant to the default tenant (based on url for example or logged in user or whatever) */ public void resetToDefaultTenant() //get the actual tenant object itself instead of it's id (could be same for simple tenants) public Object getTenant() public Object setTenant(Object tenant)
- tenantService which is a helper service for tenants, if you overide this you have to provide at least these methods:
Start of by generating your tenant domain classes which will create
//invokes a closure with a temporary tenantid, in this way superadmins and alike can reach all tenants in an easy way. public void doWithTenant(Object tenantId, Closure closure) throws Throwablepublic TenantProvider createOrGetDefaultTenant(String name)// creates a new tenant (TenantProvider) public TenantProvider createNewTenant(String name)
In your domains folder. These can be moved to any package but then you have to specify where in config.groovy (se example below)The Tenant implements the TenantProvider interface and can thus be replaced with any other class as long as it implements that interface, so you can choose to store your tenants in any way you like.You mark domain classes either through inclusion or exclusion by adding the config field in Config.groovyConfig options include:
You cannot specify both exclude and include at this stage. If specifying exclude then 'ALL' Domain classes except those in list will be tenant dependent. Specifying include -> only those domain classes are tenant dependent.
grails.mongo.tenant.tenantclassname = "your.package.TenantDomainclass" grails.mongo.tenant.tenantsPerDb = 500 grails.mongo.tenant.excludingdomainclasses =[Tenant,TenantDomainMap,SecRole] //alternatively grails.mongo.tenant.includingdomainclasses =[Author,Book,ContentItem,Article] … etc grails.mongo.tenant.defaultTenantName = "default" grails.mongo.tenant.defaultTenantId = new ObjectId()
- Sources: https://github.com/webinventions/mongodb-multitenant
- Docs: Here..
- Secure plugin with more tests and some cleanups.
- Right now it is not possible to have different 'ports / ips' etc for tenants.