Search

Dark theme | Light theme

April 29, 2015

Awesome Asciidoctor Notebook is Published

Today Awesome Asciidoctor Notebook is published as a free book. This book is an electronic publication with all Awesome Asciidoctor blog posts about the Asciidoctor tool bundled.

The book is published at Leanpub and is available in three formats: PDF, MOBI (for Kindle) and EPUB (for iPad). Updates for the book are also free. So when new Awesome Asciidoctor blog posts are added to the book you will get those updates for free.

I hope you will enjoy the book and I will keep it up-to-date with new content when I publish new Awesome Asciidoctor blog posts.

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.

Awesome Asciidoctor: Display Keyboard Shortcuts

When we want to explain in our documentation which keys a user must press to get to a function we can use the keyboard macro in Asciidoctor. The macro will output the key nicely formatted as a real key on the keyboard. The syntax of the macro is kbd:[key]. To get the desired output we must set the document attribute experimental otherwise the macro is not used.

In the next Asciidoctor example file we use the keyboard macro:

= Keyboard macro

With the keyboard macro `kbd:[shortcut]`
we can include nicely formatted keyboard
shortcuts.

// We must enable experimental attribute.
:experimental:

// Define unicode for Apple Command key.
:commandkey: ⌘

Press kbd:[{commandkey} + 1] or kbd:[Ctrl + 1] 
to access the _Project_ view.

To zoom out press kbd:[Ctrl + -].

Find files with kbd:[Ctrl + Alt + N] or kbd:[{commandkey} + Shift + N].

When we transform this to HTML with the built-in HTML5 templates we get the following output:

Written with Asciidoctor 1.5.2.

Gradle Goodness: Handle Copying Duplicate Files

In Gradle we can configure how duplicate files should be handled by the Copy task. Actually we can configure how duplicate files are handled by any task that implements the CopySpec interface. For example archive tasks also implements this interface. We must use the setDuplicatesStrategy method to configure how Gradle behaves. The parameter is a value of the enumeration DuplicatesStrategy. We can use the values from the enum class or use String values, which are automatically converted to enum DuplicatesStrategy values.

We can choose the following strategies:

  • include: default strategy where the last duplicate file 'wins'.
  • exclude: only the first found duplicate file is copied and 'wins'.
  • warn: shows a warning on the console, but the last duplicate file 'wins' like with the include strategy.
  • fail: the build fails where duplicate files are found.

The following build file create four task of type Copy, each with a different duplicate strategy. In the directories src/manual and src/website we have a file COPY.txt. The content is simply a text line respectively COPY from src/manual and COPY from src/website:

// For each duplicate strategy we create a copy task.
['warn', 'include', 'exclude', 'fail'].each { strategy ->
    task "copyDuplicatesStrategy${strategy.capitalize()}"(type: Copy) {
        from 'src/manual'
        from 'src/webroot'

        into "$buildDir/copy"

        // Only the value for this property differs for
        // each created task.
        duplicatesStrategy = strategy

        // Print the used duplicates strategy when 
        // the task starts.
        doFirst {
            println "Copying with duplicates strategy '${strategy}'."
        }

        // Print the contents of the copied file COPY.txt.
        doLast {
            println "Contents of COPY.txt:"
            println file("$buildDir/copy/COPY.txt").text
        }
    }
}

We can now invoke the four tasks and see how Gradle reacts:

$ gradle copyDuplicatesStrategyWarn
:copyDuplicatesStrategyWarn
Copying with duplicates strategy 'warn'.
Encountered duplicate path "COPY.txt" during copy operation configured with DuplicatesStrategy.WARN
Contents of COPY.txt:
COPY from src/webroot


BUILD SUCCESSFUL

Total time: 3.728 secs
$ gradle copyDuplicatesStrategyInclude
:copyDuplicatesStrategyInclude
Copying with duplicates strategy 'include'.
Contents of COPY.txt:
COPY from src/webroot


BUILD SUCCESSFUL

Total time: 2.744 secs
$ gradle copyDuplicatesStrategyExclude 
:copyDuplicatesStrategyExclude
Copying with duplicates strategy 'exclude'.
Contents of COPY.txt:
COPY from src/manual


BUILD SUCCESSFUL

Total time: 2.784 secs
$ gradle copyDuplicatesStrategyFail
:copyDuplicatesStrategyFail
Copying with duplicates strategy 'fail'.
:copyDuplicatesStrategyFail FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':copyDuplicatesStrategyFail'.
> Encountered duplicate path "COPY.txt" during copy operation configured with DuplicatesStrategy.FAIL

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 2.786 secs

Written with Gradle 2.3.

Gradle Goodness: Use Git Commit Id in Build Script

The nice thing about Gradle is that we can use Java libraries in our build script. This way we can add extra functionality to our build script in an easy way. We must use the classpath dependency configuration for our build script to include the library. For example we can include the library Grgit, which provides an easy way to interact with Git from Java or Groovy code. This library is also the basis for the Gradle Git plugin.

In the next example build file we add the Grgit library to our build script classpath. Then we use the open method of the Grgit class. From the returned object we invoke the head to get the commit id identified as id. With the abbreviatedId property we get the shorter version of the Git commit id. The build file also includes the application plugin. We customize the applicationDistribution CopySpec from the plugin and expand the properties in a VERSION file. This way our distribution always includes a plain text file VERSION with the Git commit id of the code.

buildscript {

    repositories {
        jcenter()
    }

    dependencies {
        // Add dependency for build script,
        // so we can access Git from our
        // build script.
        classpath 'org.ajoberstar:grgit:1.1.0'
    }

}

apply plugin: 'java'
apply plugin: 'application'

ext {
    // Open the Git repository in the current directory.
    git = org.ajoberstar.grgit.Grgit.open(file('.'))

    // Get commit id of HEAD.
    revision = git.head().id
    // Alternative is using abbreviatedId of head() method.
    // revision = git.head().abbreviatedId
}

// Use abbreviatedId commit id in the version.
version = "2.0.1.${git.head().abbreviatedId}"

// application plugin extension properties.
mainClassName = 'sample.Hello'
applicationName = 'sample'

// Customize applicationDistribution
// CopySpec from application plugin extension.
applicationDistribution.with {
    from('src/dist') {
        include 'VERSION'
        expand(
            buildDate: new Date(), 
            // Use revision with Git commit id:
            revision : revision,
            version  : project.version,
            appName  : applicationName)
    }
}

// Contents for src/dist/VERSION:
/*
Version: ${version}
Revision: ${revision}
Build-date: ${buildDate.format('dd-MM-yyyy HH:mm:ss')}
Application-name: ${appName}
*/

assemble.dependsOn installDist

When we run the build task for our project we get the following contents in our VERSION file:

Version: 2.0.1.e2ab261
Revision: e2ab2614011ff4be18c03e4dc1f86ab9ec565e6c
Build-date: 22-04-2015 13:53:31
Application-name: sample

Written with Gradle 2.3.

April 20, 2015

Awesome Asciidoctor: Adding Custom Content to Head and Footer

When we convert our Asciidoctor markup to HTML we automatically get a head and footer element. We can add custom content to the HTML head element and to the HTML div with id footer. We must set a document attribute and create the files that contain the HTML that needs to be added to the head or footer. We have three different document attributes we can set to include the custom content files:

  • :docinfo: include document specific content. Files to be included must be named <docname>-docinfo.html for head element and <docname>-docinfo-footer.html for footer content.
  • :docinfo1: include general custom content. Files to be included must be named docinfo.html for head element and docinfo-footer.html for footer content.
  • :docinfo2: include document specific and general custom content. Files to be included must be named <docname>-docinfo.html and docinfo.html for head element and <docname>-docinfo-footer.html and docinfo-footer.html for footer content.

In this sample we create the files docinfo.html and docinfo-footer.html we want to include in the generated output from the following Asciidoctor source file:

= Asciidoctor custom header and footer
Hubert A. Klein Ikkink
// Document specific and general custom
// content files are used:
:docinfo2: 
// Include general custom content files:
//:docinfo1:
// Include document specific content files:
//:docinfo:
// In generated HTML this is transformed
// to <meta name="description" content="..."/>
:description: Sample document with custom header and footer parts.
// In generated HTML this is transformed
// to <meta name="keywords" content="..."/>
:keywords: Asciidoctor, header, footer, docinfo

Using the `docinfo` attributes we can include custom content
in the header and footer. Contents of the files 
named `docinfo.html` and `docinfo-footer.html` are included.

We can choose between general or document specific custom
header and footer content.

Our docinfo.html looks like this:

<!-- Change some CSS. -->
<style>
/* Change CSS overflow for table of contents. */
#toc.toc2, #toc { overflow: scroll; }

/* Change styling for footer text. */
.footer-text { color: rgba(255,255,255,.8); }
</style>

<!-- We could also include Javascript 
     for example in this document. -->

For the custom footer we create the file docinfo-footer.html:

<p class="footer-text">
<!-- We can use document attributes: -->
Generated with Asciidoctor v{asciidoctor-version}.
</p>

The following screenshot shows the generated HTML page:

And here is part of the generated head element:

<head>

...

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.2">
<meta name="description" content="Sample document with custom header and footer parts.">
<meta name="keywords" content="Asciidoctor, header, footer, docinfo">
<meta name="author" content="Hubert A. Klein Ikkink">
<title>Asciidoctor custom header and footer</title>

...

<!-- Change some CSS. -->
<style>
/* Change CSS overflow for table of contents. */
#toc.toc2, #toc { overflow: scroll; }

/* Change styling for footer text. */
.footer-text { color: rgba(255,255,255,.8); }
</style>

<!-- We could also include Javascript
     for example in this document. -->
</head>

Written with Asciidoctor 1.5.2.

April 19, 2015

Gradle Goodness: Alter Start Scripts from Application Plugin

For Java or Groovy projects we can use the application plugin in Gradle to run and package our application. The plugin adds for example the startScripts task which creates OS specific scripts to run the project as a JVM application. This task is then used again by the installDist that installs the application, and distZip and distTar tasks that create a distributable archive of the application. The startScripts tasks has the properties unixScript and windowsScript that are the actual OS specific script files to run the application. We can use these properties to change the contents of the files.

In the following sample we add the directory configuration to the CLASSPATH definition:

...
startScripts {

    // Support closures to add an additional element to 
    // CLASSPATH definition in the start script files.
    def configureClasspathVar = { findClasspath, pathSeparator, line ->

        // Looking for the line that starts with either CLASSPATH=
        // or set CLASSPATH=, defined by the findClasspath closure argument.
        line = line.replaceAll(~/^${findClasspath}=.*$/) { original ->

            // Get original line and append it 
            // with the configuration directory.
            // Use specified path separator, which is different
            // for Windows or Unix systems.
            original += "${pathSeparator}configuration"
        }

    }

    def configureUnixClasspath = configureClasspathVar.curry('CLASSPATH', ':')
    def configureWindowsClasspath = configureClasspathVar.curry('set CLASSPATH', ';')

    // The default script content is generated and
    // with the doLast method we can still alter
    // the contents before the complete task ends.
    doLast {

        // Alter the start script for Unix systems.
        unixScript.text = 
            unixScript
                .readLines()
                .collect(configureUnixClasspath)
                .join('\n')

        // Alter the start script for Windows systems.
        windowsScript.text = 
            windowsScript
                .readLines()
                .collect(configureWindowsClasspath)
                .join('\r\n')

    }

}
...

This post was inspired by the Gradle build file I saw at the Gaiden project.

Written with Gradle 2.3.

April 17, 2015

Spring Sweets: Using @Value for Constructor Arguments

In Spring we can use the @Value annotation to set property or arguments values based on a SpEL expression. If we want to use the @Value annotation for a constructor argument we must not forget to add the @Autowired annotation on the constructor as well.

// File: sample/Message.groovy
package sample

import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*

@Component
class Message {

    final String text

    // Use @Autowired to get @Value to work.
    @Autowired
    Message(
        // Refer to configuration property
        // app.message.text to set value for 
        // constructor argument text.
        @Value('${app.message.text}') final String text) {
        this.text = text
    }

}

Written with Spring 4.1.6.

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.

Grails Goodness: Add Banner to Grails Application

Grails 3 is based on Spring Boot. This means we get a lot of the functionality of Spring Boot into our Grails applications. A Spring Boot application has by default a banner that is shown when the application starts. The default Grails application overrides Spring Boot's behavior and disables the display of a banner. To add a banner again to our Grails application we have different options.

First we can add a file banner.txt to our classpath. If Grails finds the file it will display the contents when we start the application. Let's add a simple banner with Grails3 in Ascii art in the file src/main/resources/banner.txt. By placing the file in src/main/resources we can assure it is in the classpath as classpath:/banner.txt:

________             .__.__         ________
 /  _____/___________  |__|  |   _____\_____  \
/   \  __\_  __ \__  \ |  |  |  /  ___/ _(__  <
\    \_\  \  | \// __ \|  |  |__\___ \ /       \
 \______  /__|  (____  /__|____/____  >______  /
        \/           \/             \/       \/

Let's run our application with the bootRun task:

$ gradle bootRun
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources
:classes
:findMainClass
:bootRun

  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\_____  \
/   \  __\_  __ \__  \ |  |  |  /  ___/ _(__  <
\    \_\  \  | \// __ \|  |  |__\___ \ /       \
 \______  /__|  (____  /__|____/____  >______  /
        \/           \/             \/       \/

Grails application running at http://localhost:8080
...

To have more information in the banner we can implement the org.springframework.boot.Banner interface. This interface has a printBanner method in which we can write the implementation for the banner. To use it we must create an instance of the GrailsApp class and set the banner property:

// File: grails-app/init/banner/Application.groovy
package banner

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import grails.util.Environment
import org.springframework.boot.Banner

import static grails.util.Metadata.current as metaInfo

class Application extends GrailsAutoConfiguration {
    static void main(String[] args) {
        final GrailsApp app = new GrailsApp(Application)
        app.banner = new GrailsBanner()
        app.run(args)
    }
}

/**
 * Class that implements Spring Boot Banner
 * interface to show information on application startup.
 */
class GrailsBanner implements Banner {

    private static final String BANNER = '''
  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\\_____  \\
/   \\  __\\_  __ \\__  \\ |  |  |  /  ___/ _(__  <
\\    \\_\\  \\  | \\// __ \\|  |  |__\\___ \\ /       \\
 \\______  /__|  (____  /__|____/____  >______  /
        \\/           \\/             \\/       \\/'''

    @Override
    void printBanner(
            org.springframework.core.env.Environment environment,
            Class<?> sourceClass,
            PrintStream out) {

        out.println BANNER

        row 'App version', metaInfo.getApplicationVersion(), out
        row 'App name', metaInfo.getApplicationName(), out
        row 'Grails version', metaInfo.getGrailsVersion(), out
        row 'Groovy version', GroovySystem.version, out
        row 'JVM version', System.getProperty('java.version'), out
        row 'Reloading active', Environment.reloadingAgentEnabled, out
        row 'Environment', Environment.current.name, out

        out.println()
    }

    private void row(final String description, final value, final PrintStream out) {
        out.print ':: '
        out.print description.padRight(16)
        out.print ' :: '
        out.println value
    }

}

Now we run the bootRun task again:

$ gradle bootRun
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:findMainClass
:bootRun

  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\_____  \
/   \  __\_  __ \__  \ |  |  |  /  ___/ _(__  <
\    \_\  \  | \// __ \|  |  |__\___ \ /       \
 \______  /__|  (____  /__|____/____  >______  /
        \/           \/             \/       \/
:: App version      :: 0.1
:: App name         :: grails-banner-sample
:: Grails version   :: 3.0.1
:: Groovy version   :: 2.4.3
:: JVM version      :: 1.8.0_45
:: Reloading active :: true
:: Environment      :: development

Grails application running at http://localhost:8080
...

Written with Grails 3.0.1.

Ascii art is generated with this website.

Groovy Goodness: Use Closures as Java Lambda Expressions

Java 8 introduced lambda expressions we can use for example with the new Java Streams API. The Groovy syntax doesn't support the lambda expressions, but we can rely on closure coersion to use Groovy closures as Java lambda expressions in our code.

In the following sample we use the Java Streams API. Instead of lambda expressions for the filter and map methods we use Groovy closures. They are automatically transformed to lambda expressions, so it is very easy to use Java streams from Groovy code.

import groovy.transform.*

/**
 * Simple class to describe
 * a Building.
 */
@Canonical
class Building {
    String name
    int floors
    boolean officeSpace
}

// Create Building objects.
def officeSpace = new Building('Initech office', 3, true)
def theOffice = new Building('Wernham Hogg Paper Company', 4, true)
def coffeeShop = new Building('Hunter Green', 1, false)

// And add to a list.
def buildings = [officeSpace, theOffice, coffeeShop]

// Create a closure which we will use 
// later in our code.
def mapBuildingName = { building -> building.name }


// Invoke Java Streams API with lambda methods,
// but we use Groovy closures.
def officeBuildingNames = 
    buildings
        .stream() // Get Java streams.
        .filter { building -> 
            building.officeSpace && building.floors > 2 
        } // 'anonymous' closure.
        .map(mapBuildingName) // Predefined closure.
        .collect()
        
assert officeBuildingNames == ['Initech office', 'Wernham Hogg Paper Company']

Code written with Groovy 2.4.3.

April 14, 2015

Greach 2015 Conference Report

So this year I got the opportunity to speak and visit Greach 2015 in Madrid, Spain. I've never been in Spain before, but after visiting I definitely want to go back. Although the trip to Madrid was more cumbersome than planned, because of the strikes in France, I arrived at the speaker's dinner on time. Just go to mention that the Madrid metro is a very pleasant way to go around in Madrid. It was good to see old and new faces and to catch up and just have fun. Friday April 10th was the first day of the conference. The conference is held at the university in the south of Madrid. Jochen Theodorou, one of the Groovy core developers, opened the day with the keynote about Groovy's past, present and future. He gave a very nice overview of how Groovy evolved over the years and Groovy has been around already for a long time. Of course the latest news this year is Pivotal's hands off of Groovy and Grails. Jochen explained he first gets a good vacation and then decides what to do himself. Groovy is now in the process of getting an Apache project so the continuity of the development of the language should be saved. Then the rest of the day two tracks were presented at the same time. And there were difficult choices to make. Fortunately all talks are recorded and they will be added to the Greach Youtube channel.

I went to the talk Groovy and Scala: Friends or Foes by Marco Vermeulen. He showed how we can use Spock with Groovy to test Scala code using a Gradle build. So both worlds can live together and we can intermingle where possible. The application written in Scala was pragmatic and that is something I missed when I looked at Scala for the first time. This talk really got me interested to learn more about Scala. Next up was the talk AST - Groovy Transformers: More than meets the eye! by one of the conference organizers Iván López. He showed a lot of the (local) AST transformation that are already available in Groovy and that we can use everyday in our programs. Each AST transformation was clearly explained and he showed samples on how to use them. After his talk it was my time to present Grails Goodness. In this talk I live coded a selection of the blog posts about Grails I did write. Somehow there is always to little time to show everything I wanted, but still I think I was able to show some nice features of Grails.

After a very good lunch it was time to attend Hacking the Grails Spring Security 2.0 Plugin by Burt Beckwith. It is always fun to attend a session by Burt Beckwith and this was no exception. The plugin is almost ready to be released and he showed us the components that make up the plugin and how to customize things in our applications. The plugin provides some defaults, but they can easily be overwritten or changed if we want to. The next talk was a discussion Gr8Workshop: A Guided Discussion about Teaching and Diversity in the Groovy Community by Jennifer Strater. She first showed some basic principles of teaching something, followed by experiences she had with Groovy workshops both for beginners and more advanced developers. It was interesting to hear to Groovy can of course also be the first programming language for a developer. Normally I am used that Java developers learn Groovy, but also developers from a different background or just new developers get used to Groovy quickly. Russel Winder told that in the UK programming is a mandatory subject at school for children starting from 5 years. I think it is great that kids learn more about programming and solving problems at a young age. He also said that children learn by playing and sometimes we forget that adults can learn the same way.

I went to Advanced Microservice Concerns by Steve Pember where he presented his real world experiences working with microservices. For example to have separate code repositories and that the DRY (Don't Repeat Yourself) principle doesn't need to apply among microservices, we want as less dependencies as possible between services. He also showed his preference for using a message broker to communicate between microservices in a flexible way. Other concerns like monitoring and logging were also covered, for example he showed the Elastic search, Logstash and Kibana (ELK) stack. The last session of the day was about The Groovy Ecosystem by Andres Almiray. He gave a good overview of all the projects related to Groovy that are out there. And there a lot of Groovy related and influenced things we can use, besides maybe the obvious Gradle, Grails and Groovy itself. He also gave GVM a special place, because GVM ties it all together and gives us very easy access to a lot of the tools and projects.

The second day of the conference was even more packed with now three tracks to choose from. I am glad the talks are recorded so I can still see what I missed afterwards. We could choose to follow a workshop or between two talks. I didn't attend the workshop, but followed the talks. The first one was Grooscript in Action by Jorge Franco. He created a Grooscript, which is a tool to convert Groovy code to Javascript. The tool is really impressive, it can already do so many things and I was amazed by how much of the Groovy syntax is supported. There is also a Gradle plugin for Grooscript. He showed a very nice working application with a Spring Boot backend and a Javascript fronted which was created with Grooscript. With this tool it is very easy to write Groovy code (we already know) and have Javascript application transformed for us. And it is not a small subset of Groovy we can use, we can use a lot already. The following talk was Documentation brought to life: Asciidoctor & Gradle by Markus Schlichting. He showed why we would want to have our documentation written in Asciidoctor, close to our sources and integrated with our build automation as compared to for example writing documentation in Word. He had some nice example on how to setup our Gradle builds to working Asciidoctor. I liked the watch plugin that he used, so every time the Asciidoc source file changes it is automatically transformed.

The next talk was DSL'ing your Groovy by Alonso Torres Ortiz. He gave a good overview of the different options we have to build a DSL in Groovy. For example using closures, builders, meta programming, AST and scripting. For each option he had some nice examples. I really liked how he wrote a AST transformation to mimic the data table syntax from Spock in his own DSL. Up next was Groovy enVironment Manager (2015) by the author of GVM Marco Vermeulen. He showed the components that make up GVM and his plans with the tool. GVM is now targeted to Groovy stuff, but he will create SDKenv that will support other SDK's as well. I also liked to hear about the components that make up GVM, like the Broadcast API we can use. Tools that are included in GVM can themselves add the tool or SDK to GVM and automatically it will be available for us to install.

After lunch Trisha Gee presented Is Groovy better for testing than Java?. She showed her real world experience of transforming JUnit tests to Spock. The different features of Spock and Groovy were shown like data tables and mocking and stubbing. It turned out that Java developers didn't have any real issues to use Groovy for their testing and still Java for the production code. The mental shift between Java and Groovy wasn't that big and the readability and terse syntax of the Spock specifications really added to better and more tests in the project. Burt Beckwith presented Little Did He Know... with non-related observations and tips about Groovy and Grails. The title of the presentation is based on a movie Stranger than fiction. He started with explaining some of the magic that happens with domain classes and constructors in Grails and Groovy. It turns out that Grails has an AST that will add a non-argument constructor to domain classes, but this intervenes with argument constructors we like to add ourselves. The talk was filled with nice examples and very useful tips.

Schalk W. Cronjé presented Idiomatic Gradle Plugin Writing. He is (co-)author of for example the JRuby and Asciidoctor Gradle plugins and had some very nice tips on writing plugin code. Especially to have some conventions on how the plugin and tasks need to be configured. I really liked the code that showed how to be flexible in accepting input files for your plugin to work with. With his example code of just a couple of lines it is possible to accept String, File and Closures to get files. He stressed it is important to be consist and prefer methods over property assignments. The last talk of the conference was Groovy on the Shell by Alexander (Sasha) Klein. Groovy is of course also a very good scripting language and why not use it in our shell as well. We know the syntax and he showed it is very easy to write shell scripts in Groovy. For example with Grab annotation and she bang operator we can write self contained scripts that can be executed by anyone as long they have Groovy.

The Greach conference is a great conference. The organizers did a very good job and presented a very good program. It was difficult to choose between tracks and therefore it is a good thing the talks are all video taped and will be available on Youtube. The attendees and speakers are all very passionate about their profession and working with Groovy and Groovy related tools and languages. It is a good place to catch up on the latest developments and speak with the people behind the projects and the users. Hopefully I will be back next year and enjoy another Greach.