Search

Dark theme | Light theme
Showing posts with label Grails 3. Show all posts
Showing posts with label Grails 3. Show all posts

November 23, 2016

Grails Goodness: Enabling Grails View In IntelliJ IDEA For Grails 3

IntelliJ IDEA 2016.3 re-introduced the Grails view for Grails 3 applications. Grails 2 applications already were supported with a Grails view in IDEA. Using this view we get an overview of all the Grails artifacts like controller, services, views and more. We can easily navigate to the the class files we need. Now this view is also available for Grails 3 applications.

To enable the view we must click on the view selector in the project view:


We select the Grails option and we get an nice overview of our Grails project in the Grails view:


Also the New action is context sensitive in the Grails view. If we right click on the Services node we can see the option to create a new service class:


If we right click on the root node we get the option to create Grails artifacts:


Written with IntelliJ IDEA 2016.3 and Grails 3.2.2.

June 27, 2016

Grails Goodness: Pass JSON Configuration Via Command Line

We can use the environment variable SPRING_APPLICATION_JSON with a JSON value as configuration source for our Grails 3 application. The JSON value is parsed and merged with the configuration. Instead of the environment variable we can also use the Java system property spring.application.json.

Let's create a simple controller that reads the configuration property app.message:

// File: grails-app/controllers/mrhaki/grails/config/SampleController.groovy
package mrhaki.grails.config

import org.springframework.beans.factory.annotation.Value

class MessageController {
    
    @Value('${app.message}')
    String message

    def index() { 
        render message
    }
}

Next we start Grails and set the environment variable SPRING_APPLICATION_JSON with a value for app.message:

$ SPRING_APPLICATION_JSON='{"app":{"message":"Grails 3 is Spring Boot on steroids"}}' grails run-app
| Running application...
Grails application running at http://localhost:8080 in environment: development

When we request the sample endpoint we see the value of app.message:

$ http -b :8080/message
Grails 3 is Spring Boot on steroids
$

If we want to use the Java system property spring.application.json with the Grails command we must first configure the bootRun task so all system properties are passed along:

// File: build.gradle
...
bootRun {
    systemProperties System.properties
}
...

With the following command we pass the configuration as inline JSON:

$ grails -Dspring.application.json='{"app":{"message":"Grails 3 is Spring Boot on steroids"}}' run-app
| Running application...
Grails application running at http://localhost:8080 in environment: development

Written with Grails 3.1.8.

June 20, 2016

Grails Goodness: Creating A Fully Executable Jar

With Grails 3 we can create a so-called fat jar or war file. To run our application we only have to use java -jar followed by our archive file name and the application starts. Another option is to create a fully executable jar or war file, which adds a shell script in front of the jar or war file so we can immediately run the jar or war file. We don't have to use java -jar anymore to run our Grails application. The fully executable JAR file can only run on Unix-like systems and it is ready to be used as service using init.d or systemd.

To create a fully executable jar file for our Grails application we must add the following lines to our build.gradle file:

// File: build.gradle
...
// Disable war plugin to create a jar file
// otherwise a fully executable war file
// is created.
//apply plugin: 'war'

...
springBoot {
    // Enable the creation of a fully
    // executable archive file.
    executable = true
}

Next we execute the Gradle assemble task to create the fully executable archive:

grails> assemble
...
:compileGroovyPages
:jar
:bootRepackage
:assemble

BUILD SUCCESSFUL

Total time: 5.619 secs
| Built application to build/libs using environment: production
grails>

We can find the executable archive file in the build/libs directory. Suppose our Grails application is called grails-full-executable-jar and has version 0.1 we can execute the jar file grails-full-executable-jar-0.1.jar:

$ cd build/libs
$ ./grails-full-executable-jar-0.1.jar
Grails application running at http://localhost:8080 in environment: production

The launch script that is prepended to the archive file can be changed by defining a new launch script with the springBoot property embeddedLaunchScript. The default launch script that is used has some variable placeholders we can change using the embeddedLaunchScriptProperties property. For example the launch script can determine if the script is used to run the application standalone or as a Linux/Unix service and will act accordingly. We can also set the mode property to service so it will always act like a Linux/Unix service. Furthermore we can set some meta information for the launch script with several properties. To learn more about the different options see the Spring Boot documentation.

// File: build.gradle
...
springBoot {
    // Enable the creation of a fully
    // executable archive file.
    executable = true

    // Set values for variable placeholders
    // in the default launch script.
    embeddedLaunchScriptProperties =
        [initInfoDescription: project.description,
         initInfoShortDescription: project.name,
         initInfoProvides: jar.baseName,
         mode: 'service']
}

After we have recreated the archive file we can check the launch script that is created:

$ head -n 55 build/libs/grails-full-executable-jar-0.1.jar
#!/bin/bash
#
#    .   ____          _            __ _ _
#   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
#  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
#   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
#    '  |____| .__|_| |_|_| |_\__, | / / / /
#   =========|_|==============|___/=/_/_/_/
#   :: Spring Boot Startup Script ::
#

### BEGIN INIT INFO
# Provides:          grails-full-executable-jar
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: grails-full-executable-jar
# Description:       Sample Grails Application
# chkconfig:         2345 99 01
### END INIT INFO

[[ -n "$DEBUG" ]] && set -x

# Initialize variables that cannot be provided by a .conf file
WORKING_DIR="$(pwd)"
# shellcheck disable=SC2153
[[ -n "$JARFILE" ]] && jarfile="$JARFILE"
[[ -n "$APP_NAME" ]] && identity="$APP_NAME"

# Follow symlinks to find the real jar and detect init.d script
cd "$(dirname "$0")" || exit 1
[[ -z "$jarfile" ]] && jarfile=$(pwd)/$(basename "$0")
while [[ -L "$jarfile" ]]; do
  [[ "$jarfile" =~ init\.d ]] && init_script=$(basename "$jarfile")
  jarfile=$(readlink "$jarfile")
  cd "$(dirname "$jarfile")" || exit 1
  jarfile=$(pwd)/$(basename "$jarfile")
done
jarfolder="$(dirname "$jarfile")"
cd "$WORKING_DIR" || exit 1

# Source any config file
configfile="$(basename "${jarfile%.*}.conf")"
# shellcheck source=/dev/null
[[ -r "${jarfolder}/${configfile}" ]] && source "${jarfolder}/${configfile}"

# Initialize PID/LOG locations if they weren't provided by the config file
[[ -z "$PID_FOLDER" ]] && PID_FOLDER="/var/run"
[[ -z "$LOG_FOLDER" ]] && LOG_FOLDER="/var/log"
! [[ -x "$PID_FOLDER" ]] && PID_FOLDER="/tmp"
! [[ -x "$LOG_FOLDER" ]] && LOG_FOLDER="/tmp"

# Set up defaults
[[ -z "$MODE" ]] && MODE="service" # modes are "auto", "service" or "run"
$ cd build/libs
$ ./grails-full-executable-jar.0.1.jar
Usage: ./grails-full-executable-jar-0.1.jar {start|stop|restart|force-reload|status|run}
$

Written with Grails 3.1.8.

May 11, 2016

Grails Goodness: Use Random Server Port In Integration Tests

Because Grails 3 is based on Spring Boot we can use a lot of the functionality of Spring Boot in our Grails applications. For example we can start Grails 3 with a random available port number, which is useful in integration testing scenario's. To use a random port we must set the application property server.port to the value 0. If we want to use the random port number in our code we can access it via the @Value annotation with the expression ${local.server.port}.

Let's create a very simple controller with a corresponding integration test. The controller is called Sample:

// File: grails-app/controllers/mrhaki/SampleController.groovy
package mrhaki

class SampleController {

    def index() { 
        respond([message: 'Grails 3 is awesome!'])
    }
}

We write a Spock integration test that will start Grails and we use the HTTP Requests library to access the /sample endpoint of our application.

// File: src/integration-test/groovy/mrhaki/SampleControllerIntSpec.groovy
package mrhaki

import com.budjb.httprequests.HttpClient
import com.budjb.httprequests.HttpClientFactory
import grails.test.mixin.integration.Integration
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import spock.lang.Specification

@Integration
class SampleControllerIntSpec extends Specification {
    
    /**
     * Server port configuration for Grails test 
     * environment is set to server.port = 0, which
     * means a random available port is used each time
     * the application starts.
     * The value for the port number is accessible
     * via ${local.server.port} in our integration test.
     */
    @Value('${local.server.port}')
    Integer serverPort

    /**
     * HTTP test client from the HTTP Requests library:
     * http://budjb.github.io/http-requests/latest
     */
    @Autowired
    HttpClientFactory httpClientFactory

    private HttpClient client

    def setup() {
        // Create HTTP client for testing controller.
        client = httpClientFactory.createHttpClient()
    }

    void "sample should return JSON response"() {
        when:
        // Nice DSL to build a request.
        def response = client.get {
            // Here we use the serverPort variable.
            uri = "http://localhost:${serverPort}/sample"
            accept = 'application/json'
        }
        
        then:
        response.status == 200
        
        and:
        final Map responseData = response.getEntity(Map)
        responseData.message == 'Grails 3 is awesome!'
    }
}

Finally we add the server.port to the application configuration:

# File: grails-app/conf/application.yml
...
environments:
    test:
        server:
            port: 0 # Random available port
...

Let's run the integration test: $ grails test-app mrhaki.SampleControllerIntSpec -integration. When we open the test report and look at the standard output we can see that a random port is used:

Written with Grails 3.1.6.

January 13, 2016

Grails Goodness: Using Spring Cloud Config Server

The Spring Cloud project has several sub projects. One of them is the Spring Cloud Config Server. With the Config Server we have a central place to manage external properties for applications with support for different environments. Configuration files in several formats like YAML or properties are added to a Git repository. The server provides an REST API to get configuration values. But there is also a good integration for client applications written with Spring Boot. And because Grails (3) depends on Spring Boot we can leverage the same integration support. Because of the Spring Boot auto configuration we only have to add a dependency to our build file and add some configuration.

Before we look at how to use a Spring Cloud Config server in our Grails application we start our own server for testing. We use a local Git repository as backend for the configuration. And we use the Spring Boot CLI to start the server. We have the following Groovy source file to enable the configuration server:

// File: server.groovy
@DependencyManagementBom('org.springframework.cloud:spring-cloud-starter-parent:Brixton.M4')
@Grab('spring-cloud-config-server')
import org.springframework.cloud.config.server.EnableConfigServer

@EnableConfigServer
class ConfigServer {}

Next we create a new local Git repository with $ git init /Users/mrhaki/config-repo. We use the Spring Boot CLI and our Groovy script to start a sample Spring Cloud Config Server:

$ spring run server.groovy -- --server.port=9000 --spring.cloud.config.server.git.uri=file:///Users/mrhaki/config-repo --spring.config.name=configserver
...
2016-01-13 14:35:19.679  INFO 69933 --- [       runner-0] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 9000 (http)
2016-01-13 14:35:19.682  INFO 69933 --- [       runner-0] o.s.boot.SpringApplication               : Started application in 4.393 seconds (JVM running for 7.722)

Next we create a YAML configuration file with a configuration property app.message. The name of the configuration file must start with the application name that want to use the configuration. It is best to not use hyphens in the name. Optionally we can use a Spring profile name to override configuration properties for a specific profile. The profile maps to the Grails environment names so we can use the pattern also for our Grails configuration. To learn about even more possibilities we must read the Spring Cloud Config documentation.

Here are two configuration files with a default value and a override property for the development environment:

# grails_cloud_config.yml
app:
    message: Default message
# grails_cloud_config-development.yml
app:
    message: Running in development mode

We add and commit both files in our local Git repository.

Let's configure our Grails application so it uses the configuration from our Spring Cloud Config Server. First we change build.gradle and add a dependency on spring-cloud-starter-config. We also add an extra BOM for the Spring Cloud dependencies so the correct version is automatically used.

// File: build.gradle
...
dependencyManagement {
    imports {
        mavenBom "org.grails:grails-bom:$grailsVersion"
        mavenBom 'org.springframework.cloud:spring-cloud-starter-parent:Angel.SR4'
    }
    applyMavenExclusions false
}
...
dependencies {
    // Adding this dependency is enough to use
    // Spring Cloud Server. 
    compile "org.springframework.cloud:spring-cloud-starter-config"
}

Next we need to define the URL for our configuration server. We can set the system property spring.cloud.config.uri when we start our Grails application or we can add the file grails-app/conf/bootstrap.yml with the following contents:

# File: grails-app/conf/bootstrap.yml
spring:
    cloud:
        config:
            uri: http://localhost:9000

Finally we set our application name to grails_cloud_config which is used to get the configuration properties from the Config server:

# File: grails-app/conf/application.yml
...
spring:
    application:
        name: grails_cloud_config
...

That is it, we can now use properties defined in the configuration server in our Grails application. Let's add a controller which reads the configuration property app.message:

// File: grails-app/controllers/sample/MessageController.groovy
package sample

import org.springframework.beans.factory.annotation.Value

class MessageController {
    
    @Value('${app.message}')
    private String message

    def index() { 
        render message
    }
}

When we start our application with the development environment we get the following message:

$ http localhost:8080/message
HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Date: Wed, 13 Jan 2016 14:08:37 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
X-Application-Context: grails_cloud_config:development

Running in development mode

$

And when in production mode we get:

$ http localhost:8080/message
HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Date: Wed, 13 Jan 2016 14:08:37 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
X-Application-Context: grails_cloud_config:production

Default message

$

Written with Grails 3.0.11

October 20, 2015

Grails Goodness: Creating A Runnable Jar

Grails 3 makes it very easy to create a JAR file that is runnable with a simple $java -jar command. We must use the Grails command package or the Gradle task assemble to package our application as a so-called runnable JAR file. This JAR file has all the necessary classes to start up our Grails application.

In the following example we have a Grails application sample-app. We use the Gradle task assemble to package the application into a JAR file. The resulting JAR file can be found in the build/libs directory of our project:

$ gradle assemble
:assetCompile
Processing File 1 of 22 - apple-touch-icon-retina.png
Processing File 2 of 22 - apple-touch-icon.png
Processing File 3 of 22 - favicon.ico
Compressing File 3 of 22 - favicon
Processing File 4 of 22 - grails_logo.png
Processing File 5 of 22 - skin/database_add.png
Processing File 6 of 22 - skin/database_delete.png
Processing File 7 of 22 - skin/database_edit.png
Processing File 8 of 22 - skin/database_save.png
Processing File 9 of 22 - skin/database_table.png
Processing File 10 of 22 - skin/exclamation.png
Processing File 11 of 22 - skin/house.png
Processing File 12 of 22 - skin/information.png
Processing File 13 of 22 - skin/shadow.jpg
Processing File 14 of 22 - skin/sorted_asc.gif
Processing File 15 of 22 - skin/sorted_desc.gif
Processing File 16 of 22 - spinner.gif
Processing File 17 of 22 - application.js
Uglifying File 17 of 22 - application
Compressing File 17 of 22 - application
Processing File 18 of 22 - jquery-2.1.3.js
Uglifying File 18 of 22 - jquery-2.1.3
Compressing File 18 of 22 - jquery-2.1.3
Processing File 19 of 22 - application.css
Minifying File 19 of 22 - application
Compressing File 19 of 22 - application
Processing File 20 of 22 - errors.css
Minifying File 20 of 22 - errors
Compressing File 20 of 22 - errors
Processing File 21 of 22 - main.css
Minifying File 21 of 22 - main
Compressing File 21 of 22 - main
Processing File 22 of 22 - mobile.css
Minifying File 22 of 22 - mobile
Compressing File 22 of 22 - mobile
Finished Precompiling Assets
:buildProperties
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:compileTestJava UP-TO-DATE
:compileTestGroovy UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:compileIntegrationTestJava UP-TO-DATE
:compileIntegrationTestGroovy UP-TO-DATE
:compileWebappGroovyPages UP-TO-DATE
:compileGroovyPages
:jar
:findMainClass
:startScripts
:distTar
:distZip
:war
:bootRepackage
:assemble

BUILD SUCCESSFUL

Total time: 12.972 secs
$

Next we can run the generated JAR file:

$ java -jar build/libs/sample-app-0.1-jar
Grails application running at http://localhost:8080 in environment: production

We can also use command-line options to set configuration properties. In the following example we start the application on port number 9080:

$ java -jar build/libs/sample-app-0.1-jar --server.port=9080
Grails application running at http://localhost:9080 in environment: production

We can copy this JAR file to another location, for example a test or production server, and use the same command to run our Grails application.

All this works because the bootRepackage task of the Gradle Spring Boot plugin will use the JAR file of the jar task and converts it to a runnable JAR file. The original JAR file is overridden so next time when we execute the assemble task the JAR file is regenerated. To use Gradle's incremental build feature we can configure the bootRepackage task to create a new JAR file instead of overriding the default JAR file. In the following Gradle build script snippet we use a different name for the JAR file that is generated by the bootRepackage task:

...
// Use app classifier for new JAR file.
// For example sample-app-0.1.jar, becomes
// sample-app-0.1-app.jar.
bootRepackage.classifier = 'app'

// Instruct bootRepackage to only use
// JAR file from jar task.
bootRepackage.withJarTask = jar
...

Written with Grails 3.0.9.

September 28, 2015

Grails Goodness: Get List Of Application Profiles

Grails 3 introduced the concept of application profiles to Grails. A profile contains the application structure, dependencies, commands and more to configure Grails for a specific type of application. The profiles are stored on the Grails Profile repository on Github. We can go there and see which profiles are available, but it is much easier to use the list-profiles command. With this command we get an overview of all the available profiles we can use to create a new application or plugin.

The list-profiles task is only available when we are outside a Grails application directory. So just like the create-app and create-plugin we can run list-profiles from a non-Grails project directory.

$ grails list-profiles
| Available Profiles
--------------------
* base - The base profile extended by other profiles
* plugin - Profile for plugins designed to work across all profiles
* web - Profile for Web applications
* web-api - Profile for Web API applications
* web-micro - Profile for creating Micro Service applications run as Groovy scripts
* web-plugin - Profile for Plugins designed for Web applications
$

Once we know which profile we want to use we can use the name as value for the --profile option with the create-app command:

$ grails create-app sample-micro --profile=web-micro
| Application created at /Users/mrhaki/Projects/mrhaki.com/blog/posts/samples/grails3/sample-micro
$

Written with Grails 3.0.8.

Grails Goodness: Run Gradle Tasks In Grails Interactive Mode

To start Grails in interactive mode we simply type grails on the command line. This starts Grails and we get an environment to run Grails commands like compile and run-app. Since Grails 3 the underlying build system has changed from Gant to Gradle. We can invoke Gradle tasks in interactive mode with the gradle command. Just like we would use Gradle from the command line we can run the same tasks, but this time when Grails is in interactive mode. Grails will use the Gradle version that belongs to the current Grails version.
We even get TAB completion for Gradle tasks.

In the next example we start Grails in interactive mode and run the Gradle task components:

$ grails
| Enter a command name to run. Use TAB for completion:
grails> gradle components
:components

------------------------------------------------------------
Root project
------------------------------------------------------------

No components defined for this project.

Additional source sets
----------------------
Java source 'main:java'
    src/main/java
JVM resources 'main:resources'
    src/main/resources
    grails-app/views
    grails-app/i18n
    grails-app/conf
Java source 'test:java'
    src/test/java
JVM resources 'test:resources'
    src/test/resources
Java source 'integrationTest:java'
    src/integrationTest/java
JVM resources 'integrationTest:resources'
    src/integrationTest/resources

Additional binaries
-------------------
Classes 'integrationTest'
    build using task: :integrationTestClasses
    platform: java8
    tool chain: JDK 8 (1.8)
    classes dir: build/classes/integrationTest
    resources dir: build/resources/integrationTest
Classes 'main'
    build using task: :classes
    platform: java8
    tool chain: JDK 8 (1.8)
    classes dir: build/classes/main
    resources dir: build/resources/main
Classes 'test'
    build using task: :testClasses
    platform: java8
    tool chain: JDK 8 (1.8)
    classes dir: build/classes/test
    resources dir: build/resources/test

Note: currently not all plugins register their components, so some components may not be visible here.

BUILD SUCCESSFUL

Total time: 0.506 secs

Next we invoke gradle compile followed by TAB. We get all the Gradle tasks that start with compile:

grails> gradle compile<TAB>

compileGroovy                  compileGroovyPages             
compileIntegrationTestGroovy   compileIntegrationTestJava     
compileJava                    compileTestGroovy              
compileTestJava                compileWebappGroovyPages 
grails>

Written with Grails 3.0.8.

Grails Goodness: Update Application With Newer Grails Version

In this blog post we see how to update the Grails version of our application for a Grails 3 application. In previous Grails versions there was a special command to upgrade, but with Grails 3 it is much simpler. To update an application to a newer version in the Grails 3.0.x range we only have to change the value of the property grailsVersion in the file gradle.properties.

# gradle.properties
grailsVersion=3.0.8
gradleWrapperVersion=2.3

After we have changed the value we run the clean and compile tasks so all dependencies are up-to-date.

Written with Grails 3.0.8.

Grails Goodness: Use A Different Logging Configuration File

Since Grails 3 the logging configuration is in a separate file. Before Grails 3 we could specify the logging configuration in grails-app/conf/Config.groovy, since Grails 3 it is in the file grails-app/conf/logback.groovy. We also notice that since Grails 3 the default logging framework implementation is Logback. We can define a different Logback configuration file with the environment configuration property logging.config. We can set this property in grails-app/conf/application.yml, as Java system property (-Dlogging.config=<location>) or environment variable (LOGGING_CONFIG). Actually all rules for external configuration of Spring Boot apply for the configuration property logging.config.

In the following example configuration file we have a different way of logging in our Grails application. We save it as grails-app/conf/logback-grails.groovy:

// File: grails-app/conf/logback-grails.groovy
import grails.util.BuildSettings
import grails.util.Environment

import org.springframework.boot.ApplicationPid

import java.nio.charset.Charset

// Log information about the configuration.
statusListener(OnConsoleStatusListener)

// Get PID for Grails application.
// We use it in the logging output.
if (!System.getProperty("PID")) {
    System.setProperty("PID", (new ApplicationPid()).toString())
}

conversionRule 'clr', org.springframework.boot.logging.logback.ColorConverter
conversionRule 'wex', org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter

// See http://logback.qos.ch/manual/groovy.html for details on configuration
appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        charset = Charset.forName('UTF-8')
        pattern =
                '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date
                        '%clr(%5p) ' + // Log level
                        '%clr(%property{PID}){magenta} ' + // PID
                        '%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread
                        '%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger
                        '%m%n%wex' // Message
    }
}

root(WARN, ['STDOUT'])

if(Environment.current == Environment.DEVELOPMENT) {
    root(INFO, ['STDOUT'])

    def targetDir = BuildSettings.TARGET_DIR
    if(targetDir) {

        appender("FULL_STACKTRACE", FileAppender) {

            file = "${targetDir}/stacktrace.log"
            append = true
            encoder(PatternLayoutEncoder) {
                pattern = "%level %logger - %msg%n"
            }
        }
        logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )
    }
}

We use this configuration file with the following command:

$ LOGGING_CONFIG=classpath:logback-grails.groovy grails run-app
...
2015-09-28 16:52:38.758  INFO 26895 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'grailsDispatcherServlet'
2015-09-28 16:52:38.758  INFO 26895 --- [           main] o.g.w.s.mvc.GrailsDispatcherServlet      : FrameworkServlet 'grailsDispatcherServlet': initialization started
2015-09-28 16:52:38.769  INFO 26895 --- [           main] o.g.w.s.mvc.GrailsDispatcherServlet      : FrameworkServlet 'grailsDispatcherServlet': initialization completed in 11 ms
2015-09-28 16:52:38.769  INFO 26895 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
...

Written with Grails 3.0.8.

Grails Goodness: Change Base Name For External Configuration Files

With Grails 3 we get the Spring Boot mechanism for loading external configuration files. The default base name for configuration files is application. Grails creates for example the file grails-app/conf/application.yml to store configuration values if we use the create-app command. To change the base name from application to something else we must specify a value for the Java system property spring.config.name.

In the following example we start Grails with the value config for the Java system property spring.config.name. So now Grails looks for file names like config.yml, config.properties, config-{env}.properties and config-{env}.yml in the default locations config directory, root directory on the filesystem and in the class path.

$ grails -Dspring.config.name=config run-app
...

To pass the system properties when we use Grails commands we must change our build.gradle and reconfigure the run tasks so any Java system property from the command line are passed on to Grails:

...
tasks.findAll { task ->
    task.name  in ['run', 'bootRun']
}.each { task ->
    task.systemProperties System.properties
}

Remember that if we use this system property the default grails-app/conf/application.yml is no longer used.

Written with Grails 3.0.8.

Grails Goodness: Use Different External Configuration Files

A Grails 3 application uses the same mechanism to load external configuration files as a Spring Boot application. This means the default locations are the root directory or config/ directory in the class path and on the file system. If we want to specify a new directory to search for configuration files or specify the configuration files explicitly we can use the Java system property spring.config.location.

In the following example we have a configuration application.yml in the settings directory. The default base name for a configuration file is application, so we use that base name in our example. In this sample we use a YAML configuration file where we override the property sample.config for the Grails production environment.

# File: settings/application.yml
sample:
  config: From settings/.

---
environments:
  production:
    sample:
      config: From settings/ dir and production env.

Next we need to reconfigure the run and bootRun tasks, both of type JavaExcec, to pass on Java system properties we use from the command line when we use the Grails commands:

// File: build.gradle
...
tasks.withType(JavaExec).each { task ->
    task.systemProperties System.properties
}

Now we can start our Grails application with the Java system property spring.config.location. We add the settings directory as a search location for configuration files. We add both the directory as a local directory as well as a root package name in the class path:

$ grails -Dspring.config.location=settings/,classpath:/settings/ run-app
...

In the following example we have a configuration config.yml in the root of our project:

# File: config.yml
sample:
  config: From config.yml.

---
environments:
  production:
    sample:
      config: From config.yml dir and production env.

Now we start Grails and use the explicit file name as a value for the Java system property spring.config.location:

$ grails -Dspring.config.location=file:./config.yml run-app
...

We could specify multiple files separated by comma's. Or even combine it with directories like we used in the first example.

Written with Grails 3.0.8.

September 22, 2015

Grails Goodness: See Information About Plugins

In Grails we can use the list-plugins command to get a list of all available plugins. The list returns only the plugins that are available for the Grails version we are using. So if we invoke this command in Grails 3 we get a different list than a Grails 2.x version. To get more detailed information, like website, source code URL and dependency definition we use the plugin-info command.

Let's run the plugin-list command for Grails 3:

grails> list-plugins
| Available Plugins
* airbrake-grails
* ajax-tags
* asset-pipeline
* audit-logging
* aws-sdk
* cache
* cache-ehcache
* cache-headers
* cassandra
* clojure
* csv
* database-migration
* export
* facebook-sdk
* feature-switch
* feeds
* fields
* geb
* gorm-envers
* grails-console
* grails-hibernate-filter
* grails-http-builder-helper
* grails-json-apis
* grails-redis
* grails-spring-websocket
* greenmail
* grooscript
* gscripting
* hibernate
* jasypt-encryption
* jms
* joda-time
* json-annotations-marshaller
* mail
* mongodb
* newrelic
* oauth
* quartz
* quartz-monitor
* rateable
* recaptcha
* rendering
* request-tracelog
* scaffolding
* segment
* sentry
* simple-spring-security
* spring-security-acl
* spring-security-appinfo
* spring-security-core
* taggable
* views-gradle
* views-json
* views-markup
* wkhtmltopdf

If we want more information about the spring-security-core plugin we invoke the following command:

grails> plugin-inf spring-security-core
| Plugin Info: spring-security-core
| Latest Version: 3.0.0.M1
| All Versions: 3.0.0.M1
| Title: Spring Security Core Plugin

Spring Security Core plugin

* License: APACHE
* Documentation: http://grails-plugins.github.io/grails-spring-security-core/
* Issue Tracker: https://github.com/grails-plugins/grails-spring-security-core/issues
* Source: https://github.com/grails-plugins/grails-spring-security-core
* Definition:

dependencies {
    compile "org.grails.plugins:spring-security-core:3.0.0.M1"    
}

If we would invoke the command in for example Grails 2.5.1 we get different results:

grails> list-plugins

Plugins available in the grailsCentral repository are listed below:
-------------------------------------------------------------
DjangoTemplates Plugin<>               --  
None                <>               --  
acegi               <0.5.3.2>        --  Acegi Plugin
active-link         <1.0>            --  Active Link Tag Plugin
activemq            <0.5>            --  Grails ActiveMQ Plugin
activiti            <5.12.1>         --  Grails Activiti Plugin - Enabled Activiti BPM Suite support for Grails
activiti-shiro      <0.1.1>          --  This plugin integrates Shiro Security to Activiti.
activiti-spring-security<0.5.0>          --  Activiti Spring Security Integration
acts-as-taggable    <>               --  
address             <0.2>            --  Grails Address Plugin
address-lookup-zpfour<0.1.2>          --  Address Lookup via ZP4
admin-interface     <0.7.1>          --  Grails Admin Interface
adminlte-ui         <0.1.0>          --  AdminLTE UI Plugin
airbrake            <0.9.4>          --  Airbrake Plugin
ajax-proxy          <0.1.1>          --  Ajax Proxy Plugin
ajax-uploader       <1.1>            --  Ajax Uploader Plugin
ajaxanywhere        <1.0>            --  AjaxAnywhere Grails Plugin
ajaxdependancyselection<0.45-SNAPSHOT4> --  Ajax Dependancy Selection Plugin
ajaxflow            <0.2.4>          --  This plugin enables Ajaxified Webflows
akismet             <0.2>            --  Akismet Anti-Spam Plugin
akka                <2.2.4.1>        --  Akka Integration
alfresco            <0.4>            --  Alfresco DMS Integration

...

Plug-ins you currently have installed are listed below:
-------------------------------------------------------------
asset-pipeline      2.2.3            --  Asset Pipeline Plugin
cache               1.1.8            --  Cache Plugin
database-migration  1.4.0            --  Grails Database Migration Plugin
hibernate4          4.3.10           --  Hibernate 4 for Grails
jquery              1.11.1           --  jQuery for Grails
scaffolding         2.1.2            --  Grails Scaffolding Plugin
tomcat              7.0.55.3         --  Apache Tomcat plugin for Grails
webxml              1.4.1            --  WebXmlConfig

To find more info about plugin type 'grails plugin-info [NAME]'

To install type 'grails install-plugin [NAME] [VERSION]'

For further info visit http://grails.org/Plugins

grails> plugin-info spring-security-core

--------------------------------------------------------------------------
Information about Grails plugin
--------------------------------------------------------------------------
Name: spring-security-core | Latest release: 2.0-RC5
--------------------------------------------------------------------------
Spring Security Core Plugin
--------------------------------------------------------------------------
Author: Burt Beckwith
--------------------------------------------------------------------------
Author's e-mail: burt@burtbeckwith.com
--------------------------------------------------------------------------
Find more info here: http://grails-plugins.github.io/grails-spring-security-core/
--------------------------------------------------------------------------

Spring Security Core plugin


Dependency Definition
--------------------------------------------------------------------------
    :spring-security-core:2.0-RC5


To get info about specific release of plugin 'grails plugin-info [NAME] [VERSION]'

To get list of all plugins type 'grails list-plugins'

For further info visit http://grails.org/plugins

In Grails versions before Grails 3 we also have the command list-plugin-updates. This command will display if there are any version updates for the plugins installed in our application:

grails> list-plugin-updates

Plugins with available updates are listed below:
-------------------------------------------------------------
<plugin>            <current>         <available>
tomcat              7.0.55.3          8.0.22
hibernate4          4.3.10            4.3.8.2-SNAPSHOT
database-migration  1.4.0             1.4.2-SNAPSHOT
cache               1.1.8             1.1.9-SNAPSHOT
asset-pipeline      2.2.3             2.5.1

Written with Grails 3.0.7.

April 27, 2015

Grails Goodness: Custom Data Binding with @DataBinding Annotation

Grails has a data binding mechanism that will convert request parameters to properties of an object of different types. We can customize the default data binding in different ways. One of them is using the @DataBinding annotation. We use a closure as argument for the annotation in which we must return the converted value. We get two arguments, the first is the object the data binding is applied to and the second is the source with all original values of type SimpleMapDataBindingSource. The source could for example be a map like structure or the parameters of a request object.

In the next example code we have a Product class with a ProductId class. We write a custom data binding to convert the String value with the pattern {code}-{identifier} to a ProductId object:

package mrhaki.grails.binding

import grails.databinding.BindUsing

class Product {

    // Use custom data binding with @BindUsing annotation.
    @BindUsing({ product, source ->

        // Source parameter contains the original values.
        final String productId = source['productId']

        // ID format is like {code}-{identifier},
        // eg. TOYS-067e6162.
        final productIdParts = productId.split('-')

        // Closure must return the actual for 
        // the property.
        new ProductId(
            code: productIdParts[0],
            identifier: productIdParts[1])

    })
    ProductId productId

    String name

}

// Class for product identifier.
class ProductId {
    String code
    String identifier
}

The following specification shows the data binding in action:

package mrhaki.grails.binding

import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
import grails.databinding.SimpleMapDataBindingSource

@TestMixin(GrailsUnitTestMixin)
class ProductSpec extends Specification {

    def dataBinder

    def setup() {
        // Use Grails data binding
        dataBinder = applicationContext.getBean('grailsWebDataBinder')
    }

    void "productId parameter should be converted to a valid ProductId object"() {
        given:
        final Product product = new Product()

        and:
        final SimpleMapDataBindingSource source = 
            [productId: 'OFFCSPC-103910ab24', name: 'Swingline Stapler']

        when:
        dataBinder.bind(product, source)

        then:
        with(product) {
            name == 'Swingline Stapler'

            with(productId) {
                identifier == '103910ab24'
                code == 'OFFCSPC'
            }
        }
    }

}

If we would have a controller with the request parameters productId=OFFCSPC-103910ab24&name=Swingline%20Stapler the data binding of Grails can create a Product instance and set the properties with the correct values.

Written with Grails 2.5.0 and 3.0.1.

April 24, 2015

Grails Goodness: Adding Health Check Indicators

With Grails 3 we also get Spring Boot Actuator. We can use Spring Boot Actuator to add some production-ready features for monitoring and managing our Grails application. One of the features is the addition of some endpoints with information about our application. By default we already have a /health endpoint when we start a Grails (3+) application. It gives back a JSON response with status UP. Let's expand this endpoint and add a disk space, database and url health check indicator.

We can set the application property endpoints.health.sensitive to false (securing these endpoints will be another blog post) and we automatically get a disk space health indicator. The default threshold is set to 10MB, so when the disk space is lower than 10MB the status is set to DOWN. The following snippet shows the change in the grails-app/conf/application.yml to set the property:

...
---
endpoints:
    health:
        sensitive: false
...

If we invoke the /health endpoint we get the following output:

{
    "status": "UP",
    "diskSpace": {
        "status": "UP",
        "free": 97169154048,
        "threshold": 10485760
    }
}

If we want to change the threshold we can create a Spring bean of type DiskSpaceHealthIndicatorProperties and name diskSpaceHealthIndicatorProperties to override the default bean. Since Grails 3 we can override doWithSpring method in the Application class to define Spring beans:

package healthcheck

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.boot.actuate.health.DiskSpaceHealthIndicatorProperties

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        GrailsApp.run(Application)
    }

    @Override
    Closure doWithSpring() {
        { ->
            diskSpaceHealthIndicatorProperties(DiskSpaceHealthIndicatorProperties) {
                // Set threshold to 250MB.
                threshold = 250 * 1024 * 1024
            }
        }
    }
}

Spring Boot Actuator already contains implementations for checking SQL databases, Mongo, Redis, Solr and RabbitMQ. We can activate those when we add them as Spring beans to our application context. Then they are automatically picked up and added to the results of the /health endpoint. In the following example we create a Spring bean databaseHealth of type DataSourceHealthIndicator:

package healthcheck

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.boot.actuate.health.DataSourceHealthIndicator
import org.springframework.boot.actuate.health.DiskSpaceHealthIndicatorProperties

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        GrailsApp.run(Application)
    }

    @Override
    Closure doWithSpring() {
        { ->
            // Configure data source health indicator based
            // on the dataSource in the application context.
            databaseHealthCheck(DataSourceHealthIndicator, dataSource)

            diskSpaceHealthIndicatorProperties(DiskSpaceHealthIndicatorProperties) {
                threshold = 250 * 1024 * 1024
            }
        }
    }
}

To create our own health indicator class we must implement the HealthIndicator interface. The easiest way is to extend the AbstractHealthIndicator class and override the method doHealthCheck. It might be nice to have a health indicator that can check if a URL is reachable. For example if we need to access a REST API reachable through HTTP in our application we can check if it is available.

package healthcheck

import org.springframework.boot.actuate.health.AbstractHealthIndicator
import org.springframework.boot.actuate.health.Health

class UrlHealthIndicator extends AbstractHealthIndicator {

    private final String url

    private final int timeout

    UrlHealthIndicator(final String url, final int timeout = 10 * 1000) {
        this.url = url
        this.timeout = timeout
    }

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        final HttpURLConnection urlConnection =
                (HttpURLConnection) url.toURL().openConnection()

        final int responseCode =
                urlConnection.with {
                    requestMethod = 'HEAD'
                    readTimeout = timeout
                    connectTimeout = timeout
                    connect()
                    responseCode
                }

        // If code in 200 to 399 range everything is fine.
        responseCode in (200..399) ?
                builder.up() :
                builder.down(
                        new Exception(
                                "Invalid responseCode '${responseCode}' checking '${url}'."))
    }
}

In our Application class we create a Spring bean for this health indicator so it is picked up by the Spring Boot Actuator code:

package healthcheck

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.boot.actuate.health.DataSourceHealthIndicator
import org.springframework.boot.actuate.health.DiskSpaceHealthIndicatorProperties

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        GrailsApp.run(Application)
    }

    @Override
    Closure doWithSpring() {
        { ->
            // Create instance for URL health indicator.
            urlHealthCheck(UrlHealthIndicator, 'http://intranet', 2000)

            databaseHealthCheck(DataSourceHealthIndicator, dataSource)

            diskSpaceHealthIndicatorProperties(DiskSpaceHealthIndicatorProperties) {
                threshold = 250 * 1024 * 1024
            }
        }
    }
}

Now when we run our Grails application and access the /health endpoint we get the following JSON:

{
    "status": "DOWN",
    "urlHealthCheck": {
        "status": "DOWN"
        "error": "java.net.UnknownHostException: intranet",
    },
    "databaseHealthCheck": {
        "status": "UP"
        "database": "H2",
        "hello": 1,
    },
    "diskSpace": {
        "status": "UP",
        "free": 96622411776,
        "threshold": 262144000
    },
}

Notice that the URL health check fails so the complete status is set to DOWN.

Written with Grails 3.0.1.

April 23, 2015

Grails Goodness: Log Startup Info

We can let Grails log some extra information when the application starts. Like the process ID (PID) of the application and on which machine the application starts. And the time needed to start the application. The GrailsApp class has a property logStartupInfo which is true by default. If the property is true than some extra lines are logged at INFO and DEBUG level of the logger of our Application class.

So in order to see this information we must configure our logging in the logback.groovy file. Suppose our Application class is in the package mrhaki.grails.sample.Application then we add the following line to see the output of the startup logging on the console:

...
logger 'mrhaki.grails.sample.Application', DEBUG, ['STDOUT'], false
...

When we run our Grails application we see the following in our console:

...
INFO mrhaki.grails.sample.Application - Starting Application on mrhaki-jdriven.local with PID 20948 (/Users/mrhaki/Projects/blog/posts/sample/build/classes/main started by mrhaki in /Users/mrhaki/Projects/mrhaki.com/blog/posts/sample/)
DEBUG mrhaki.grails.sample.Application - Running with Spring Boot v1.2.3.RELEASE, Spring v4.1.6.RELEASE
INFO mrhaki.grails.sample.Application - Started Application in 8.29 seconds (JVM running for 9.906)
Grails application running at http://localhost:8080
...

If we want to add some extra logging we can override the logStartupInfo method:

package mrhaki.grails.sample

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import grails.util.*
import groovy.transform.InheritConstructors

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        // Use extended GrailsApp to run.
        new StartupGrailsApp(Application).run(args)
    }

}

@InheritConstructors
class StartupGrailsApp extends GrailsApp {
    @Override
    protected void logStartupInfo(boolean isRoot) {
        // Show default info.
        super.logStartupInfo(isRoot)

        // And add some extra logging information.
        // We use the same logger if we get the
        // applicationLog property.
        if (applicationLog.debugEnabled) {
            final metaInfo = Metadata.getCurrent()
            final String grailsVersion = GrailsUtil.grailsVersion
            applicationLog.debug "Running with Grails v${grailsVersion}"

            final sysprops = System.properties
            applicationLog.debug "Running on ${sysprops.'os.name'} v${sysprops.'os.version'}"
        }
    }
}

If we run the application we see in the console:

...
DEBUG mrhaki.grails.sample.Application - Running with Spring Boot v1.2.3.RELEASE, Spring v4.1.6.RELEASE
DEBUG mrhaki.grails.sample.Application - Running with Grails v3.0.0
DEBUG mrhaki.grails.sample.Application - Running on Mac OS X v10.10.3
...

Written with Grails 3.0.1.

April 22, 2015

Grails Goodness: Save Application PID in File

Since Grails 3 we can borrow a lot of the Spring Boot features in our applications. If we look in our Application.groovy file that is created when we create a new Grails application we see the class GrailsApp. This class extends SpringApplication so we can use all the methods and properties of SpringApplication in our Grails application. Spring Boot and Grails comes with the class ApplicationPidFileWriter in the package org.springframework.boot.actuate.system. This class saves the application PID (Process ID) in a file application.pid when the application starts.

In the following example Application.groovy we create an instance of ApplicationPidFileWriter and register it with the GrailsApp:

package mrhaki.grails.sample

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.boot.actuate.system.ApplicationPidFileWriter

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        final GrailsApp app = new GrailsApp(Application)

        // Register PID file writer.
        app.addListeners(new ApplicationPidFileWriter())

        app.run(args)
    }

}

So when we run our application a new file application.pid is created in the current directory and contains the PID:

$ grails run-app

From another console we read the contents of the file with the PID:

$ cat application.pid
20634
$

The default file name is application.pid, but we can use another name if we want to. We can use another constructor for the ApplicationPidFileWriter where we specify the file name. Or we can use a system property or environment variable with the name PIDFILE. But we can also set it with the configuration property spring.pidfile. We use the latest option in our Grails application. In the next example application.yml we set this property:

...
spring:
    pidfile: sample-app.pid
...

When we start our Grails application we get the file sample-app.pid with the application PID as contents.

Written with Grails 3.0.1.

April 16, 2015

Grails Goodness: Add Some Color to Our Logging

Grails 3 is based on Spring Boot. This means we can use a lot of the stuff that is available in Spring Boot now in our Grails application. If we look at the logging of a plain Spring Boot application we notice the logging has colors by default if our console supports ANSI. We can also configure our Grails logging so that we get colors.

First we need to change our logging configuration in the file grails-app/conf/logback.groovy:

// File: grails-app/conf/logback.groovy
import grails.util.BuildSettings
import grails.util.Environment
import org.springframework.boot.ApplicationPid

import java.nio.charset.Charset

// Get PID for Grails application.
// We use it in the logging output.
if (!System.getProperty("PID")) {
    System.setProperty("PID", (new ApplicationPid()).toString())
}

// Mimic Spring Boot logging configuration.
conversionRule 'clr', org.springframework.boot.logging.logback.ColorConverter
conversionRule 'wex', org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter

appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        charset = Charset.forName('UTF-8')

        // Define pattern with clr converter to get colors.
        pattern =
                '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date
                '%clr(%5p) ' + // Log level
                '%clr(%property{PID}){magenta} ' + // PID
                '%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread
                '%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger
                '%m%n%wex' // Message
    }
}

// Change root log level to INFO,
// so we get some more logging.
root(INFO, ['STDOUT'])
...

Normally when we would run our application Grails should check if the console support ANSI colors. If the console supports it the color logging is enabled, otherwise we still get non-colored logging. On my Mac OSX the check doesn't work correctly, but we can set an environment property spring.output.ansi.enabled to the value always to force colors in our logging output. The default value is detect to auto detect the support for colors. We can set this property in different ways. For example we could add it to our application configuration or we could add it as a Java system property to the JVM arguments of the bootRun task. In the following build file we use the JVM arguments for the bootRun task:

// File: build.gradle
...
bootRun {
    // If System.console() return non null instance,
    // we force ANSI color support with 'always', 
    // otherwise use default 'detect'.
    jvmArgs = ['-Dspring.output.ansi.enabled=' + (System.console() ? 'always' : 'detect')]
}
...

When we run the Grails application using bootRun we get for example the following output:

Written with Grails 3.0.1.

April 15, 2015

Grails Goodness: Set Log Level for Grails Artifacts

A good thing in Grails is that in Grails artifacts like controllers and services we have a log property to add log statements in our code. If we want to have the output of these log statements we must use a special naming convention for the log names. Each logger is prefixed with grails.app followed by the Grails artifact. Valid artifact values are controllers, services, domain, filters, conf and taglib. This is followed by the actual class name. So for example we have a controller SampleController in the package mrhaki.grails then the complete logger name is grails.app.controllers.mrhaki.grails.SampleContoller.

The following sample configuration is for pre-Grails 3:

// File: grails-app/conf/Config.groovy
...
log4j = {
    ...
    info 'grails.app.controllers'
    debug 'grails.app.controllers.mrhaki.grails.SampleController'
    info 'grails.app.services'
    ...
}
...

In Grails 3 we can use a common Logback configuration file. In the following part of the configuration we set the log levels:

// File: grails-app/conf/logback.groovy
...
logger 'grails.app.controllers', INFO, ['STDOUT']
logger 'grails.app.controllers.mrhaki.grails.SampleController', DEBUG, ['STDOUT']
logger 'grails.app.services', INFO, ['STDOUT']
...

Written with Grails 2.5.0 and 3.0.1.