Difference between revisions of "Grails Plugin - Multi Tenant"

From Blue-IT.org Wiki

(4. Build a MultiTenant environment in BootStrap.groovy)
(4. Build a MultiTenant environment in BootStrap.groovy)
Line 70: Line 70:
 
     def init = { servletContext ->
 
     def init = { servletContext ->
 
    
 
    
         // This refers to Config.groovy: ''grails.tenantDomain  = 'localhost'''
+
         // This refers to Config.groovy: ''grails.tenantDomain  = 'myweb1'''
 
         def domainName = ConfigurationHolder.config.grails.'''tenantDomain'''
 
         def domainName = ConfigurationHolder.config.grails.'''tenantDomain'''
  
        if ( '''DomainTenantMap.findByName('myweb1')''' ) {}
+
def myweb1Tenant = DomainTenantMap.findByName('myweb1_dev')
        else {
+
          new DomainTenantMap(
+
if ( myweb1Tenant ) {}
                      '''name:'myweb1'''',
+
else {
                      '''domainName:'sub.' + domainName''',
+
  myweb1Tenant = new DomainTenantMap(
                      '''mappedTenantId:1''').save(flush:true);
+
  name:'myweb1_dev',
        }
+
  domainName:domainName,
 +
  mappedTenantId:1)
 +
  if (myweb1Tenant.save(flush:true) ) {
 +
  println "TenantMap entry for myweb1 created."
 +
  } else {
 +
  println "Error creating TenantMap entry for myweb1."
 +
  }
 +
}
  
 
The property ''domainName'' refers to the correspondent field in the database ''domain_name''.
 
The property ''domainName'' refers to the correspondent field in the database ''domain_name''.
Line 88: Line 95:
 
  | id | version | domain_name    | mapped_tenant_id | name          |
 
  | id | version | domain_name    | mapped_tenant_id | name          |
 
  +----+---------+-----------------+------------------+----------------+
 
  +----+---------+-----------------+------------------+----------------+
  |  1 |      0 | domain.tld      |                1 | myweb1        |
+
  |  1 |      0 | myweb1          |                1 | myweb1_dev    |
 
  [...]
 
  [...]
  

Revision as of 12:08, 5 September 2011

An introduction on the concept of multitenant can be found at:

Documentation

1. Declare mode in Config.groovy

// Multi Tenant
tenant {
	// multiTenant is the default 
	// do "grails create-dns-map" when changing tenantDomains
	// this stroes the dns/tenant mappings into the database
	resolver.request.dns.type = "db"
}

Later on you can use tenant[dot] to refer to the TenantMap domain class (see later on).

You also have to set a per-environment serverUrl stem for creating absolute links depending on your hostname:

environments {
[...]
     development {
         grails.serverURL = "http://localhost:8080/${appName}"
         grails.tenant.domain = "localhost"

2. Declare Tenant Class

This class should be a top level class. E.g. "Organisation" hasMany "Users".

import grails.plugin.multitenant.core.groovy.compiler.MultiTenant;
@MultiTenant
class Organisation {

[...]

3. Create a TenantMap domain class

This is achieved by using the command

grails create-dns-map

This automatically creates a domain class with the name DomainTenantMap.groovy.

package tenant

/**
 * Maps domain name to tenantId
 */
class DomainTenantMap { 
	
  String domainName
  Integer mappedTenantId
  String name
 
  static constraints = {}
}

This class maps to a database table domain_tenant_map.

4. Build a MultiTenant environment in BootStrap.groovy

Tenants (e.g. organisations) are created by instantiating a new tenantDomain ConfigurationHolder.

import grails.plugin.multitenant.core.util.TenantUtils
import org.codehaus.groovy.grails.commons.ConfigurationHolder
import tenant.DomainTenantMap // was created with grails create-domain-map

class BootStrap {

   def init = { servletContext ->	
 
       // This refers to Config.groovy: grails.tenantDomain  = 'myweb1'
       def domainName = ConfigurationHolder.config.grails.tenantDomain

def myweb1Tenant = DomainTenantMap.findByName('myweb1_dev')

if ( myweb1Tenant ) {} else { myweb1Tenant = new DomainTenantMap( name:'myweb1_dev', domainName:domainName, mappedTenantId:1) if (myweb1Tenant.save(flush:true) ) { println "TenantMap entry for myweb1 created." } else { println "Error creating TenantMap entry for myweb1." } }

The property domainName refers to the correspondent field in the database domain_name. The property mappedtenantId to the field name.

mysql> select * from domain_tenant_map;
+----+---------+-----------------+------------------+----------------+
| id | version | domain_name     | mapped_tenant_id | name           |
+----+---------+-----------------+------------------+----------------+
|  1 |       0 | myweb1          |                1 | myweb1_dev     |
[...]

You can use sub.domain.tld by concatenating the strings when setting domainName.

5. Include a login from spring security plugin

import grails.plugin.multitenant.core.util.TenantUtils

class LoginController {

[...]

/**
 * Show the login page.
 */
def auth = {





 
}