Skip to content

agorapulse/micronaut-grails

Repository files navigation

Agorapulse Micronaut Libraries

download

Set of useful libraries for Micronaut. All of the libraries are available in JCenter repository.

The installation snippets expects having Gradle property micronautLibrariesVersion stored in gradle.properties file pointing to latest version of the libraries (see the badge above).

Micronaut HTTP Server Basic

Implementation agnostic black-box HTTP Server support for Micronaut.

Following example from AWS API Gateway Proxy implementation will show you how to implement you own HTTP server with Micronaut’s capabilities:

Creating Own HTTP Server Implementation
@Override
public final APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context lambdaContext) {
    ApplicationContext context = buildApplicationContext(lambdaContext);
    startEnvironment(context);
    context.registerSingleton(input);

    APIGatewayProxyRequestEvent.ProxyRequestContext requestContext = Optional.ofNullable(input.getRequestContext()).orElseGet(APIGatewayProxyRequestEvent.ProxyRequestContext::new);
    APIGatewayProxyRequestEvent.RequestIdentity requestIdentity = Optional.ofNullable(requestContext.getIdentity()).orElseGet(APIGatewayProxyRequestEvent.RequestIdentity::new);

    context.registerSingleton(requestContext);
    context.registerSingleton(requestIdentity);

    doWithApplicationContext(context);

    ObjectMapper mapper = context.getBean(ObjectMapper.class);
    ConversionService<?> conversionService = context.getConversionService();
    HttpRequest request = convertToMicronautHttpRequest(input, conversionService, mapper);  // (1)
    BasicRequestHandler inBoundHandler = context.getBean(BasicRequestHandler.class);        // (2)
    HttpResponse response = inBoundHandler.handleRequest(request);                          // (3)
    return convertToApiGatewayProxyResponse(response);                                      // (4)
}
  1. Convert the library’s request to Micronaut’s request

  2. Obtain the handler from the application context

  3. Handle the request

  4. Convert the Micronaut’s response to library’s response

Instalation

Gradle Installation
repositories {
    jcenter()
}

dependencies {
    compile "com.agorapulse:micronaut-http-server-basic:$micronautLibrariesVersion"
}

Micronaut Function for AWS API Gateway Proxy

API Gateway Lambda Proxy support for Micronaut which enables using most of the Micronaut HTTP Server features such as controllers, filters and annotation statuses. Follow Micronaut website for extensive documentation.

You can use api_gateway_proxy environment to distinguish the application is running using this library.

Following beans can be injected if necessary:

  • com.amazonaws.services.lambda.runtime.Context

  • com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent

  • com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent.ProxyRequestContext

  • com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent.RequestIdentity

Instalation

It is recommended to only include this library in the final deployment package and tests. This enables an option to run the application locally using the Netty-based Micronaut server which is the biggest advantage of using this library.

First create following file to share configuration between your lambda libraries in gradle/lambda.gradle:

lambda.gradle
configurations {
    lambda.extendsFrom runtime
    testCompile.extendsFrom lambda
}

dependencies {
    lambda "com.agorapulse:micronaut-function-aws-agp:$micronautLibrariesVersion"

    compile "io.micronaut:http-server"
    compile "io.micronaut:router"

    // gru for aws lambda can help you testing lambda fuctions
    // https://agorapulse.github.io/gru/
    testCompile "com.agorapulse:gru-api-gateway:0.6.3"
}

task buildZip(type: Zip) {
    from compileGroovy
    from processResources
    into('lib') {
        from configurations.lambda
    }
}

build.dependsOn buildZip

Then update your build.gradle file with the Lambda configuration:

build.gradle
import com.amazonaws.services.lambda.model.Runtime
import jp.classmethod.aws.gradle.lambda.AWSLambdaMigrateFunctionTask

buildscript {                                                                               // (1)
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "jp.classmethod.aws:gradle-aws-plugin:0.38"
    }
}

apply from: 'gradle/lambda.gradle'                                                          // (2)
apply plugin: 'jp.classmethod.aws.lambda'                                                   // (3)

task deployLambda(type: AWSLambdaMigrateFunctionTask, dependsOn: build, group: 'deploy')  { // (4)
    // these values must always be the same
    handler = 'com.agorapulse.micronaut.agp.ApiGatewayProxyHandler::handleRequest'
    runtime = Runtime.Java8
    zipFile = buildZip.archivePath

    // these values are up to you to reflect you configuration
    functionName = 'MicronautExamplePlanets'
    role = "arn:aws:iam::281741939716:role/service-role/MicronautExamples"
    memorySize = 512
    timeout = 60
}
  1. Add AWS Lambda Gradle Plugin to the Gradle’s classpath

  2. Apply the script we’ve created in the first step

  3. Apply AWS Lambda Gradle Plugin

  4. Create the deployment task

Local server

As your lambda is using Micronaut’s controllers and other capabilities you can easily run the lambdas using Micronaut HTTP Netty server. Here’s the example of local server’s build file:

apply plugin: "application"
apply plugin: "com.github.johnrengelman.shadow"

dependencies {
    // lambda projects
    compile project(':examples/planets')
    compile project(':examples/spacecrafts')

    // for local dynamodb mock
    compile "com.agorapulse:dru-client-dynamodb:${druVersion}"

    // for mocking of lambda context
    compile "com.agorapulse:gru-api-gateway:$gruVersion"


    // local netty server
    compile "io.micronaut:http-server-netty"

}


shadowJar {
    mergeServiceFiles()
}

runShadow {
    // run in dev environment by default
    systemProperties 'micronaut.environments': 'dev'
}

// your application class
mainClassName = "com.agorapulse.micronaut.http.examples.Application"

The application class looks very simple:

package com.agorapulse.micronaut.http.examples;

import io.micronaut.runtime.Micronaut;

class Application {

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

}

Now you can run the server using ./gradlew shadowRun. The server runs on random port by default. You can add following application-dev.yml file to src/main/resources of the local-server project to fix the number of the port:

application-dev.yml
micronaut:
  server:
    port: 46054

Micronaut Grails

Micronaut Grails package helps using Micronaut beans in the Grails application. There are two additional features which cannot be found the official Spring support for Micronaut:

  1. Micronaut beans' names defaults to lower-cased simple name of the class as expected by Grails

  2. Ability to reuse existing properties declared by Grails - e.g. grails.redis.port can be injected as @Value('${redis.port}')

Instalation

Gradle Installation
repositories {
    jcenter()
}

dependencies {
    compileOnly "com.agorapulse:micronaut-grails:$micronautLibrariesVersion"
}
Tip
If you plan to reuse same library for Micronaut and Grails, you can declare the dependency as compileOnly.

Usage

First, create a Spring configuration class which will create the processor bean:

package com.agorapulse.micronaut.grails.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.agorapulse.micronaut.grails.GrailsMicronautBeanProcessor;


@Configuration
public class GrailsConfig {

    @Bean
    public GrailsMicronautBeanProcessor widgetProcessor() {
        new GrailsMicronautBeanProcessor(Widget.class, Prototype.class);        // (1)
    }

}
  1. List all classes of beans you want to include into Spring application context. Alternatively, you can declare the common annotation of these beans such as `@Prototype.

Second, create spring.factories descriptor which will automatically load the configuration once on classpath.

spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.agorapulse.micronaut.grails.example.GrailsConfig