Configure Service Connections for Grails

Page last updated: December 24, 2015

Cloud Foundry provides extensive support for connecting a Grails application to services such as MySQL, Postgres, MongoDB, Redis, and RabbitMQ. In many cases, a Grails application running on Cloud Foundry can automatically detect and configure connections to services. For more advanced cases, you can control service connection parameters yourself.

Auto-Configuration

Grails provides plugins for accessing SQL (using Hibernate), MongoDB, and Redis services. If you install any of these plugins and configure them in your Config.groovy or DataSource.groovy file, Cloud Foundry re-configures the plugin with connection information when your app starts.

If you were using all three types of services, your configuration might look like this:

environments {
  production {
    dataSource {
      url = 'jdbc:mysql://localhost/db?useUnicode=true&characterEncoding=utf8'
      dialect = org.hibernate.dialect.MySQLInnoDBDialect
      driverClassName = 'com.mysql.jdbc.Driver'
      username = 'user'
      password = "password"
    }
    grails {
      mongo {
        host = 'localhost'
        port = 27107
        databaseName = "foo"
        username = 'user'
        password = 'password'
      }
      redis {
        host = 'localhost'
        port = 6379
        password = 'password'
        timeout = 2000
      }
    }
  }
}

The url, host, port, databaseName, username, and password fields in this configuration will be overriden by the Cloud Foundry auto-reconfiguration if it detects that the application is running in a Cloud Foundry environment. If you want to test the application locally against your own services, you can put real values in these fields. If the application will only be run against Cloud Foundry services, you can put placeholder values as shown here, but the fields must exist in the configuration.

Manual Configuration

If you do not want to use auto-configuration, you can configure the Cloud Foundry service connections manually.

Follow the steps below to manually configure a service connection.

  1. Add the spring-cloud library to the dependencies section of your BuildConfig.groovy file.

      repositories {
        grailsHome()
        mavenCentral()
        grailsCentral()
        mavenRepo "http://repo.spring.io/milestone"
      }
    
      dependencies {
        compile "org.springframework.cloud:spring-cloud-cloudfoundry-connector:1.0.0.RELEASE"
        compile "org.springframework.cloud:spring-cloud-spring-service-connector:1.0.0.RELEASE"
    }
    

    Adding the spring-cloud library allows you to disable auto-configuration and use the spring-cloud API in your DataSource.groovy file to set the connection parameters.

  2. Add the following to your grails-app/conf/spring/resources.groovy file to disable auto-configuration:

    beans = {
        cloudFactory(org.springframework.cloud.CloudFactory)
    }
    
  3. Add the following imports to your DataSource.groovy file to allow spring-cloud API commands:

    import org.springframework.cloud.CloudFactory
    import org.springframework.cloud.CloudException
    
  4. Add the following code to your DataSource.groovy file to enable Cloud Foundry’s getCloud method to function locally or in other environments outside of a cloud.

    def cloud = null
    try {
        cloud = new CloudFactory().cloud
    } catch (CloudException) {}
    
  5. Use code like the following to access the cloud object:

    def dbInfo = cloud?.getServiceInfo('myapp-mysql')
    url = dbInfo?.jdbcUrl
    username = dbInfo?.userName
    password = dbInfo?.password
    

The example DataSource.groovy file below contains the following:

  • The imports that allow spring-cloud API commands
  • The code that enables the getCloud method to function locally or in other environments outside of a cloud
  • Code to access the cloud object for SQL, MongoDB, and Redis services
import org.springframework.cloud.CloudFactory
import org.springframework.cloud.CloudException

def cloud = null
try {
    cloud = new CloudFactory().cloud
} catch (CloudException) {}

dataSource {
    pooled = true
    dbCreate = 'update'
    driverClassName = 'com.mysql.jdbc.Driver'
}

environments {
    production {
        dataSource {
            def dbInfo = cloud?.getServiceInfo('myapp-mysql')
            url = dbInfo?.jdbcUrl
            username = dbInfo?.userName
            password = dbInfo?.password
        }
        grails {
            mongo {
                def mongoInfo = cloud?.getServiceInfo('myapp-mongodb')
                host = mongoInfo?.host
                port = mongoInfo?.port
                databaseName = mongoInfo?.database
                username = mongoInfo?.userName
                password = mongoInfo?.password
            }
            redis {
                def redisInfo = cloud?.getServiceInfo('myapp-redis')
                host = redisInfo?.host
                port = redisInfo?.port
                password = redisInfo?.password
            }
        }
    }
    development {
        dataSource {
            url = 'jdbc:mysql://localhost:5432/myapp'
            username = 'sa'
            password = ''
        }
        grails {
            mongo {
                host = 'localhost'
                port = 27107
                databaseName = 'foo'
                username = 'user'
                password = 'password'
            }
            redis {
                host = 'localhost'
                port = 6379
                password = 'password'
            }
        }
    }
}