Micronaut Groovy

Projects that enhance the Micronaut and Groovy language experience

Version:

1 Introduction

This project includes various subprojects that improve the Micronaut experience for Groovy users.

2 Release History

For this project, you can find a list of releases (with release notes) here:

3 Groovy Configuration

The micronaut-runtime-groovy module adds the ability to use Groovy to define configuration.

To use this module add the micronaut-runtime-groovy to your build configuration:

implementation("io.micronaut.groovy:micronaut-runtime-groovy")
<dependency>
    <groupId>io.micronaut.groovy</groupId>
    <artifactId>micronaut-runtime-groovy</artifactId>
</dependency>

You can then define configuration Groovy config in src/main/resources/application.groovy in ConfigSlurper format. Because property names in a ConfigSlurper configuration file must be valid Groovy identifiers and cannot contain dashes, you can specify configuration entries either by converting them to camel-case or snake-case.

application.groovy
//set server-url property
serverUrl = "https://localhost:8080"
//alternatively
server_url = "https://localhost:8080"

4 Groovy Functions

The micronaut-function-groovy adds the ability to define Serverless functions as Groovy scripts.

If you have the Micronaut CLI installed you can quickly create a Groovy function with mn create-function hello-world --lang groovy

To begin, add the function-groovy dependency (instead of the provider-specific dependency) which provides additional AST transformations that make writing functions simpler. For example, in build.gradle:

implementation("io.micronaut.groovy:micronaut-function-groovy")
<dependency>
    <groupId>io.micronaut.groovy</groupId>
    <artifactId>micronaut-function-groovy</artifactId>
</dependency>

You can now create your function as a Groovy script, under src/main/groovy. You will set your project’s main class property to this function (instead of FunctionApplication as in Java/Kotlin). For example:

Example build.gradle
mainClassName = "example.HelloGroovyFunction"
HelloGroovyFunction.groovy
String hello(String name) {
    "Hello ${name}!"
}

The function you define should follow the following rules:

  1. Define no more than 2 inputs

  2. Use either Java primitive or simple types or POJOs as the arguments and return values

In order to make use of dependency injection in your Groovy function, use the groovy.transform.Field annotation transform in addition to the @Inject annotation.

HelloGroovyFunction.groovy
import groovy.transform.Field
import javax.inject.Inject

@Field @Inject HelloService helloService

String hello(String name) {
    helloService.hello(name)
}

5 GORM Modules

The table summarizes the GORM modules and the dependencies you should add to your build to enable them.

Table 1. Data Access Configuration Modules
Dependency Description

io.micronaut.groovy:micronaut-hibernate-gorm

Configures GORM for Hibernate for Groovy applications

io.micronaut.groovy:micronaut-mongo-gorm

Configures GORM for MongoDB for Groovy applications

io.micronaut.groovy:micronaut-neo4j-gorm

Configures GORM for Neo4j for Groovy applications

Using GORM for Hibernate

Using the CLI

If you are creating your project using the Micronaut CLI, supply the hibernate-gorm feature to include GORM, a basic connection pool configuration, and a default H2 database driver in your project:

$ mn create-app my-app --features hibernate-gorm

For Groovy users and users familiar with the Grails framework, special support for GORM for Hibernate is available. To use GORM for Hibernate you should not include Micronaut’s built in SQL Support or the hibernate-jpa dependency since GORM itself takes responsibility for creating the DataSource, SessionFactory etc.

Rather, you only need to include the hibernate-gorm dependency in your project, a connection pool implementation, and the desired JDBC driver. For example:

implementation("io.micronaut.groovy:micronaut-hibernate-gorm")
<dependency>
    <groupId>io.micronaut.groovy</groupId>
    <artifactId>micronaut-hibernate-gorm</artifactId>
</dependency>

You will likely want to add a connection pool implementation and potentially the h2 database for in-memory testing:

Configuring GORM for Hibernate
  // Use Tomcat connection pool
  runtime 'org.apache.tomcat:tomcat-jdbc'
  // Use H2 database driver
  runtime  'com.h2database:h2'

You can now use the same configuration properties described in the GORM documentation. For example:

Configuring GORM for Hibernate
dataSource:
    pooled: true
    dbCreate: create-drop
    url: jdbc:h2:mem:devDb
    driverClassName: org.h2.Driver
    username: sa
    password:
hibernate:
    cache:
        queries: false
        use_second_level_cache: true
        use_query_cache: false
        region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory

The following should be noted regarding using GORM for Hibernate in Micronaut:

  • Each class you wish to be a GORM entity should be annotated with the grails.gorm.annotation.Entity annotation.

  • Each method that interacts with GORM should be annotated with GORM’s grails.gorm.transactions.Transactional to ensure a session is present. You can also add the @Transactional annotation to the class.

  • By default Micronaut will scan for entities relative to your Application class. If you wish to customize this specify additional packages via the ApplicationContextBuilder when starting your application.

Package scan

For example, if all your GORM entities are in the package example.micronaut.entities.

Instead of:

import io.micronaut.runtime.Micronaut
import groovy.transform.CompileStatic

@CompileStatic
class Application {
    static void main(String[] args) {
        Micronaut.run(Application)
    }
}

Use:

import io.micronaut.runtime.Micronaut
import groovy.transform.CompileStatic

@CompileStatic
class Application {
    static void main(String[] args) {
        Micronaut.build(args)
                .packages("example.micronaut.entities")
                .mainClass(Application.class)
                .start()
    }
}

In tests, where you start manually an ApplicationContext, use:

class BookServiceSpec extends Specification {

    @AutoCleanup
    @Shared
    ApplicationContext applicationContext = ApplicationContext.build()
            .packages("example.micronaut.entities")
            .build()
            .start()

    @Shared
    @Subject
    BookService bookService = applicationContext.getBean(BookService)

In tests, where you use @MicronautTest, use:

@MicronautTest(packages = "example.micronaut.entities")
class MicronautTestBookServiceSpec extends Specification {

    @Inject
    BookService bookService

Using GORM for MongoDB

Using the CLI

If you are creating your project using the Micronaut CLI, supply the mongo-gorm feature to configure GORM for MongoDB in your project:

$ mn create-app my-app --features mongo-gorm

For Groovy users and users familiar with Grails, special support has been added to Micronaut for using GORM for MongoDB.

To add support for GORM for MongoDB, first configure the MongoDB connection as per instructions earlier in the guide, then add the following dependency to your application:

implementation("io.micronaut.groovy:micronaut-mongo-gorm")
<dependency>
    <groupId>io.micronaut.groovy</groupId>
    <artifactId>micronaut-mongo-gorm</artifactId>
</dependency>

For GORM for MongoDB you will need to configure the database name separately as the grails.mongodb.datataseName property in application.yml.

The following should be noted regarding using GORM for MongoDB in Micronaut:

  • Each class you wish to be a GORM entity should be annotated with the grails.gorm.annotation.Entity annotation.

  • Each method that interacts with GORM should be annotated with GORM’s grails.gorm.transactions.Transactional to ensure a session is present. You can also add the @Transactional annotation to the class.

  • By default Micronaut will scan for entities relative to your Application class. If you wish to customize this specify additional packages via the ApplicationContextBuilder when starting your application.

Using GORM for Neo4j

Using the CLI

If you are creating your project using the Micronaut CLI, supply the neo4j-gorm feature to configure GORM for Neo4j in your project:

$ mn create-app my-app --features neo4j-gorm

For Groovy users and users familiar with Grails, special support has been added to Micronaut for using GORM for Neo4j.

To add support for GORM for Neo4j, first configure the Neo4j connection as per instructions earlier in the guide, then add the following dependency to your application:

implementation("io.micronaut.groovy:micronaut-neo4j-gorm")
<dependency>
    <groupId>io.micronaut.groovy</groupId>
    <artifactId>micronaut-neo4j-gorm</artifactId>
</dependency>

The following should be noted regarding using GORM for Neo4j in Micronaut:

  • Each class you wish to be a GORM entity should be annotated with the grails.gorm.annotation.Entity annotation.

  • Each method that interacts with GORM should be annotated with GORM’s grails.gorm.transactions.Transactional to ensure a session is present. You can also add the @Transactional annotation to the class.

  • By default Micronaut will scan for entities relative to your Application class. If you wish to customize this specify additional packages via the ApplicationContextBuilder when starting your application.

5.1 Multi-tenancy GORM

GORM supports Multi-tenancy and integrates with Micronaut Multi-tenancy support.

To use Micronaut and GORM multitenancy capabilities you must have the multitenancy-gorm dependency on your classpath. For example in build.gradle:

build.gradle
compile "io.micronaut.configuration:micronaut-multitenancy-gorm"

GORM is a powerful Groovy-based data access toolkit for the JVM with implementations several data access technologies (Hibernate, Neo4j, MongoDB, GraphQL …​).

GORM supports the following different multitenancy modes:

  • DATABASE - A separate database with a separate connection pool is used to store each tenants data.

  • SCHEMA - The same database, but different schemas are used to store each tenants data.

  • DISCRIMINATOR - The same database is used with a discriminator used to partition and isolate data.

In order to use GORM - Multitenancy you will need to configure the following properties: grails.gorm.multiTenancy.mode and grails.gorm.multiTenancy.tenantResolverClass.

Micronaut support for Multi-tenancy integrates with GORM.

The following table contains all of the TenantResolver implementations that ship with `multitenancy-gorm module and are usable out of the box.

name

description

CookieTenantResolver

Resolves the current tenant from an HTTP cookie.

FixedTenantResolver

Resolves against a fixed tenant id

HttpHeaderTenantResolver

Resolves the current tenant from the request HTTP Header.

PrincipalTenantResolver

Resolves the current tenant from the authenticated username.

SessionTenantResolver

Resolves the current tenant from the HTTP session.

SubdomainTenantResolver

Resolves the tenant id from the subdomain.

SystemPropertyTenantResolver

Resolves the tenant id from a system property.

You will need to add something like the following snippet to your app configuration:

grails:
    gorm:
        multiTenancy:
            mode: DISCRIMINATOR
            tenantResolverClass: 'io.micronaut.multitenancy.gorm.PrincipalTenantResolver'

Please, read GORM Multi-tenancy documentation to learn more.

6 Repository

You can find the source code of this project in this repository: