Multi tenancy setup with grails

I was playing with multi tenancy setup with grails.

While there were some examples I found most them were old and werent updated for recent grails versions

Ran into a bunch of errors when I tried to use multitenancy plugin with spring security.

Had to try out a few things before i was able to correct all the errors and get this working.

I try here to give a step by step guide to setting up multitenancy for grails based apps.

 

Create a simple domain class

grails create-domain-class com.helloworld.Message

 

install spring security plugin

>grails install-plugin spring-security-core

 

Create the user and roles

grails s2-quickstart org.racetrack User Role

 

Install multitenant plugin

grails install-plugin multi-tenant

 

install Multi-Tenant Spring Security Integration

grails install-plugin multi-tenant-spring-security

 

Add to config.groovy

tenant {

mode = "multiTenant" // "singleTenant" OR "multiTenant"

datasourceResolver.type = "db"

resolver {

type = "request"

resolver.request.dns.type = "db"

request.dns.type = "db"

}

}

 

 

Annotate domain classes that are to be shared after importing Multitenat annotation

import com.infusion.tenant.groovy.compiler.MultiTenant;

 

@MultiTenant

 

Add to the User Class

/** for multi-tenant-acegi plugin **/

Integer userTenantId

Add the following constraints 

// Existing constraints

userTenantId(min: 0)

Create a dns map table

grails create-dns-map

Now with all the setup in place you should be able to run your app with multitenancy setup.

Drools and Grails - troubleshooting drools error when you install drools plugin for grails

I installed drools plugin to work with my grails app.

When I started the application, I got a SAXParseException.

Issue turns out to be a jar installed.

Navigate to

.grails\1.3.4\projects\<your-project>\plugins\drools-0.3\lib
NOTE:your grails version will dictate the directory

Delete this jar - xml-apis-1.0.b2.jar

Restart the application and all is well.

 

 

Grails - Email wtih mail plugin using your gsp templates

In this post I will walk through how to configure email using mail plugin.

1. Install mail plugin in your project.
grails install-plugin mail

2.
Add activation and mail jars to lib directory.
I use these jars
activation:1.1.1
mail-1.4.3

3.
To resources.groovy add mailSender definition and configure it

    mailSender(org.springframework.mail.javamail.JavaMailSenderImpl) {
        host = 'smtp.gmail.com'
        port = 465
        username = 'xxx@gmail.com'
        password = 'xxx'
        javaMailProperties = ['mail.smtp.auth': 'true',
                'mail.smtp.socketFactory.port': '465',
                'mail.smtp.socketFactory.class': 'javax.net.ssl.SSLSocketFactory',
                'mail.smtp.socketFactory.fallback': 'false']
    }
   
   
4. Add a email template(if needed)
Create a directory grails-app\views\emailtemplates
Add a email.gsp with code you want -sample below
<%@ page contentType="text/html" %>
<html>
<head><title>${mytitle}</title></head>
<body><h1>${mymail}</h1></body>
</html>

5. In your controller add the emailing code

           mailService.sendMail{
        to    "xxx@yahoo.com"
                from  "xxx@gmail.com"
                subject  "Email test"
            body  (
                view: "/emailtemplates/email",
                model: [mytitle: "My title", mymail: "Test Email"]

            )
            }
           
     If you dont need a template to render from just supply the body of the email.

Grails application: Scheduling with Quartz

Grails application: Scheduling with Quartz

In this post I will discuss how to Install and configure quartz with jobs persistent in a database( mysql)

1.

Get quartz distribution.
Unzip to a directory.
Run the table-creation SQL scripts in the "docs/dbTables" directory of the Quartz distribution

2.Install quartz plugin

grails install-plugin quartz


3.

Create a file, QuartzConfig.groovy in grails-app\conf
Specify quartz startup and storage options here like this:

quartz {
    autoStartup = true
    jdbcStore = true
    waitForJobsToCompleteOnShutdown = true
}

environments {
    test {
        quartz {
            autoStartup = true
        }
    }
}


4.
Create a file, quartz.properties in grails-app\conf
Configure your db name in URL as well as user name and password

org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass =
org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = prodDataSource
org.quartz.jobStore.isClustered = false
org.quartz.dataSource.prodDataSource.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.prodDataSource.URL = "jdbc:mysql://localhost:3306/xxx?autoreconnect=true">org.quartz.dataSource.prodDataSource.user=grails
org.quartz.dataSource.prodDataSource.password ="server"

5.

In resources.groovy in grails-app\conf\spring

add the imports:
import org.springframework.scheduling.quartz.SchedulerFactoryBean
import org.codehaus.groovy.grails.jobs.*
import org.codehaus.groovy.grails.plugins.quartz.listeners.*

add this to spring beans dsl:

quartzScheduler(SchedulerFactoryBean) {
autoStartup = false
dataSource = ref('dataSource')
transactionManager = ref('transactionManager')
configLocation = 'classpath:quartz.properties'
jobFactory = ref('quartzJobFactory')
jobListeners = [ref("${SessionBinderJobListener.NAME}")]
globalJobListeners = [ref("${ExceptionPrinterJobListener.NAME}")]
}   

6.

Create a service class(or where you would prefer to do this) with grails create-service
Enable the service class to be injeced with a scheduler by declaring like this
    def quartzScheduler
   
define a method which will do the scheduling for you.
In this eg I put in a domain object for later retrieval during job execution.

   def schedule(my.Motd m) {
       // execute task
    def jobDetail = new JobDetail(m?.message, group, MotdJob.class);
    jobDetail.getJobDataMap().put("job", m)

    SimpleDateFormat formatter  = new SimpleDateFormat ("yyyy.MM.dd hh:mm:ss");
    Date myDate = formatter.parse("2010.07.02 15:13:56");

    def myTrigger = new SimpleTrigger("myTrigger" + new Random().nextInt().toString(), "mygroup" + new Random().nextInt().toString(),  myDate,null,0,0)
    quartzScheduler.scheduleJob(jobDetail, myTrigger);
    }


7.

Create a quartz job using
grails create-job fully-qualified-job-name

In this class define a execute method and implement your business logic

    void execute(JobExecutionContext context) {
         String instName = context.getJobDetail().getName();
         println "I have been triggered to run instGroup"
         String instGroup = context.getJobDetail().getGroup();
   
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        def mo =dataMap.get("job")
        if(mo) {
            Motd m = (Motd)mo
        }
        else
        println "null job"
       
        return
    }


8.

If you job uses a domain class (like in example above) you need to create a jar with all the domain class used by quartz and add this to your lib directory
NOTE: This is at best a hack solution. Better option is doing this through classloader. But I wont go into it.

Thats it.

Enjoy and email me at trbala attherateof yahoo.com if you need an exmaple source or if you can offer me a good paying job in siliconvalley!!!