SlideShare ist ein Scribd-Unternehmen logo
1 von 65
Downloaden Sie, um offline zu lesen
objectcomputing.com© 2020, Object Computing, Inc. (OCI). All rights reserved. No part of these notes may be reproduced, stored in a retrieval system, or transmitted, in
any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior, written permission of Object Computing,
Inc. (OCI)
Grails 4
Leveling Up Your Game!
© 2018, Object Computing, Inc. (OCI). All rights reserved.
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 2
• Senior Software Engineer
• Web and JVM developer with a decade of experience
• Husband and father
• OSS contributor
• 2GM Team Member at OCI
Zachary Klein
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• What’s New in Grails 4?
• Upgrade Steps
• Micronaut Integration
• Summary & Q&A
3
Agenda
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 4
Grails Timeline
• Grails 1.0: Released in 2008
• Based on Spring, Hibernate, Sitemesh, and other proven
technologies with Groovy as primary language
• Grails 2.0: Released in 2011
• Grails 3.0: Released in 2015
• Moved to Spring Boot and Gradle, many breaking changes
• Grails 4.0: Released in 2019
• Upgrade to foundational libraries, adds Micronaut integration
• Grails 4.1.0: Milestone 2 released in September 2020
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 5
1. Java 8 (minimum)
2. Groovy 2.5.6
3. Spring Boot 2.1.3
4. Spring 5.1.5
5. GORM 7 / Hibernate 5.4
6. Gradle 5.1.1
7. Spock 1.2
8. Micronaut Integration
What’s New in Grails 4?
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 6
Upgrading to Grails 4
≠
Grails 2
Grails 3
Grails 3
Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 7
• Read the upgrade notes:
• 2.x -> 3.x: http://docs.grails.org/3.2.13/guide/single.html#upgrading2x
• 3.x -> 4.x: http://docs.grails.org/4.0.4/guide/single.html#upgrading
• Move to Gradle project (BuildConfig.groovy -> build.gradle)
• If using Git, make use of git mv to preserve VCS history
• Controller actions must be methods, not closures
• Resources plugin no longer maintained - migrate to Asset Pipeline:
https://grails.org/blog/2016-09-12.html
Upgrade from Older Versions of Grails (3 >)
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• Most deprecated classes have been removed
• Some package restructuring
• No major breaking API changes
• Most plugins should just work
• Breaking changes in Spring, Hibernate, Groovy
• https://grails.github.io/grails-upgrade/latest/guide/index.html#upgradingTo4x
8
Grails 4 Upgrade Notes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Upgrade Grails version defined in gradle.properties
9
Upgrade Steps ➡ Bump up Grails Version
grailsVersion=4.0.0.RC1
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-
Migration-Guide
1. Many configuration changes
2. Embedded container API
• https://www.baeldung.com/embeddedservletcontainercustomizer-
configurableembeddedservletcontainer-spring-boot
3. Actuator Endpoints Changes
10
Upgrade Steps ➡ Spring Boot
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Actuator have changed substantially from Spring Boot 1.5 to 2
11
Upgrade Steps ➡ Actuator changes
endpoints:
enabled: false
jmx:
enabled: true
unique-names: true
Grails 3
spring:
jmx:
unique-names: true
management:
endpoints:
enabled-by-default: false
Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Spring Boot Developer Tools in
combination with a browser extension
such as the Chrome LiveReload
extension to get automatic browser
refresh when you change anything in
your Grails application.
12
Upgrade Steps ➡ Spring Boot Developer Tools
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
...
build.gradle
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
https://github.com/spring-projects/spring-integration/wiki/
Spring-Integration-4.3-to-5.0-Migration-Guide
Nothing that should impact the average Grails application
13
Upgrade Steps ➡ Spring Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
https://docs.gradle.org/current/userguide/upgrading_version_4.html
• Grails 4.0 upgraded to Gradle 5
• Gradle 3 no longer supported, 4 not officially supported
• Many breaking changes from 3 to 5
14
Upgrade Steps ➡ Gradle Changes
./gradlew wrapper --gradle-version 5.4.1
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Spring Boot Gradle plugin’s documentation.
15
Upgrade Steps ➡ Spring Boot Gradle Plugin Changes
bootRun {
addResources = true
…
}
build.gradle - Grails 3
bootRun {
sourceResources sourceSets.main
…
}
build.gradle - Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Spring Boot Gradle plugin’s documentation.
16
Upgrade Steps ➡ Building executable jars for Plugins
bootRepackage.enabled=false
build.gradle - Grails 3
bootJar.enabled=false
build.gradle - Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
http://gorm.grails.org/7.0.x/hibernate/manual/
index.html#upgradeNotes
1. All operations now require a transaction
2. Proxy behavior has changed
3. No more REST client
17
Upgrade Steps ➡ GORM / Hibernate Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Package Restructuring and Deprecations
• Previously deprecated classes have been deleted from this
release.
• In order to support Java 11 modules in the future, some
package re-structuring has occurred.
18
Upgrade Steps ➡ GORM / Hibernate Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Changes to Proxy Handling
• GORM no longer creates custom proxy factories nor automatically
unwraps Hibernate proxies.
19
Upgrade Steps ➡ GORM / Hibernate Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
20
Upgrade Steps ➡ GORM / Hibernate Changes
class Pet {
String name
}
Author author = Book.get(1).author
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 21
Upgrade Steps ➡ GORM / Hibernate Changes
class Pet {
String name
}
class Dog extends Pet {}
class Person {
String name
Pet pet
}
def person = Person.get(1)
assert person.pet instanceof Dog
assert person.pet.instanceOf(Dog)
assert Pet.get(person.petId).instanceOf(Dog)
assert Pet.get(person.petId) instanceof Dog
GRAILS 3
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
class Pet {
String name
}
class Dog extends Pet {}
class Person {
String name
Pet pet
}
def person = Person.get(1)
assert person.pet instanceof Dog
assert person.pet.instanceOf(Dog)
assert Pet.get(person.petId).instanceOf(Dog)
assert Pet.get(person.petId) instanceof Dog
22
Upgrade Steps ➡ GORM / Hibernate Changes
GRAILS 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
grails-validation Deprecated and Removed
• As of GORM 6.x the grails-validation module was deprecated
and replaced by grails-datastore-gorm-validation.
• Deprecated interfaces were maintained for backwards
compatibility. In GORM 7.0, these deprecated classes have
been removed and all dependency on grails-validation
removed.
23
Upgrade Steps ➡ GORM / Hibernate Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Transactions Now Required for all Operations
• Previous versions of Hibernate allowed read operation to be
executed without the presence of a declared transaction.
• Hibernate 5.2. and above require the presence of an active
transaction.
• If you see a javax.persistence.TransactionRequiredException
exception, it means your method lacks @Transactional (or
@ReadOnly) annotation around it.
24
Upgrade Steps ➡ GORM / Hibernate Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Upgrade project GORM version defined in gradle.properties:
25
Upgrade Steps ➡ Bump up GORM Version
gormVersion=6.1.12.RELEASE
gorm.version=7.0.1.RELEASE
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 26
Upgrade Steps ➡ Upgrading Hibernate
dependencies {
…
compile “org.grails.plugins.hibernate5”
compile “org.hibernate:hibernate-core:5.1.5.Final”
}
build.gradle - Grails 3
dependencies {
…
compile “org.grails.plugins.hibernate5”
compile “org.hibernate:hibernate-core:5.4.0.Final”
}
build.gradle - Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 27
org.grails:grails-datastore-rest-client deprecated in favor of Micronaut HTTP Client.
String uri = "http://repo.grails.org/grails/api/security/groups/test-group"
def resp = rest.put(uri){
auth System.getProperty("artifactory.user"),
System.getProperty("artifactory.pass")
contentType "application/vnd.org.jfrog.artifactory.security.Group+json"
json {
name = "test-group"
description = "A temporary test group"
}
}
RestClient Builder - Grails 3
Upgrade Steps ➡ RestClient Grails Plugin Removal
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 28
org.grails:grails-datastore-rest-client deprecated in favor of Micronaut HTTP Client.
Map<String, Object> payload = [name: "test-group",
description: "A temporary test group”]
String uri = "http://repo.grails.org/grails/api/security/groups/test-group"
HttpRequest request = HttpRequest.PUT(uri,payload)
.basicAuth(System.getProperty("artifactory.user"),
System.getProperty("artifactory.pass"))
.contentType("application/vnd.org.jfrog.artifactory.security.Group+json")
HttpResponse resp = client.toBlocking().exchange(request)
Micronaut HTTP Client - Grails 4
Upgrade Steps ➡ RestClient Grails Plugin Removal
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 29
Upgrade Steps ➡ Asset Pipeline
buildscript {
dependencies {
..
classpath: “com.bertramlabs.plugins:asset-pipeline-grails:2.14.1”
}
}
apply plugin “asset-pipeline”
dependencies {
..
runtime “com.bertramlabs.plugins:asset-pipeline-grails:2.14.1”
build.gradle - Grails 3
build.gradle - Grails 4
buildscript {
..
dependencies {
classpath: “com.bertramlabs.plugins:asset-pipeline-grails:3.0.10”
…
}
…
apply plugin “com.bertramlabs.asset-pipeline”
…
dependencies {
…
runtime “com.bertramlabs.plugins:asset-pipeline-grails:3.0.10”
http://www.asset-pipeline.com/manual/index.html
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 30
Upgrade Steps ➡ Spring Security Core
dependencies {
…
compile “org.grails.plugins:spring-security-core:3.2.0”
}
build.gradle - Grails 3
build.gradle - Grails 4
dependencies {
…
compile “org.grails.plugins:spring-security-core:4.0.0.RC2”
}
https://grails-plugins.github.io/grails-spring-security-core/
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 31
Upgrade Steps ➡ Spring Security Core
class User {
SpringSecurityService springSecurityService
…
…
def beforeInsert() { encodePassword() }
def beforeUpdate() {
if (isDirty(‘password’)) { encodePassword() }
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password)
}
}
grails-app/example/User.groovy - Grails 3
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 32
Upgrade Steps ➡ Spring Security Core
class User {
SpringSecurityService springSecurityService
…
…
def beforeInsert() { encodePassword() }
def beforeUpdate() {
if (isDirty(‘password’)) { encodePassword() }
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password)
}
}
grails-app/example/User.groovy - Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 33
Upgrade Steps ➡ Spring Security Core
import grails.plugin.springsecurity.SpringSecurityService
import org.grails.datastore.mapping.engine.event.*
import org.springframework.beans.factory.annotation.Autowired
import grails.events.annotation.gorm.Listener
@CompileStatic
class UserPasswordEncoderListener {
@Autowired SpringSecurityService springSecurityService
@Listener(User) void onPreInsertEvent(PreInsertEvent event) { encodePasswordForEvent(event) }
@Listener(User) void onPreUpdateEvent(PreUpdateEvent event) { encodePasswordForEvent(event) }
private void encodePasswordForEvent(AbstractPersistenceEvent event) {
if (event.entityObject instanceof User) {
User u = event.entityObject as User
if (u.password && ((event instanceof PreInsertEvent) || (event instanceof PreUpdateEvent &&
u.isDirty('password')))) {
event.getEntityAccess().setProperty('password', encodePassword(u.password))
}
}
}
private String encodePassword(String password) {
springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
}
src/main/groovy/example/UserPasswordEncoderListener.groovy - Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 34
Upgrade Steps ➡ Spring Security Core
import example.UserPasswordEncoderListener
beans = {
userPasswordEncoderListener(UserPasswordEncoderListener)
}
grails-app/conf/spring/resources.groovy - Grails 4
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Spring Security 5 changed the way password are encoded and
compared for matches.
{bcrypt}someencryptedpassword // using bcrypt
{noop}planintextpassword
35
Upgrade Steps ➡ Spring Security Core
https://www.baeldung.com/spring-security-5-password-storage
https://dzone.com/articles/password-encoder-migration-with-spring-security-5
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
http://groovy-lang.org/releasenotes/groovy-2.5.html
Notable:
1. No more groovy-all jar
2. New annotations (e.g, @AutoImplement, @MapConstructor)
3. Date extensions require a new dependency: groovy-dateutil
4. JDK 11 warnings not resolved
36
Upgrade Notes ➡ Groovy Changes
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Plugins should just work unless…
They use an API that has been changed or removed
GrailsDomainClass https://docs.grails.org/latest/guide/
upgrading.html#_grails_domain_class_api_deprecated
Spring Boot Embedded Server
37
Upgrade Notes ➡ Plugins
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• Micronaut a Foundational Library for
building applications of any type
• Focuses on Small Memory Footprint and
Speed
• Eliminates Reflection, Runtime Proxies
and Runtime Analysis
38
Micronaut Integration
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Micronaut has also been used to improve
startup and reduce overall memory
consumption of Grails applications (along
associated improvements in Spring Boot 2.1)
39
Micronaut Integration
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• Declarative HTTP Clients with @Client
• Declarative Clients for Kafka & RabbitMQ
• Use @RabbitListener for RabbitMQ
• Use @KafkaListener for Kafka
• Planned Support For Other Messaging Systems
40
Micronaut Messaging
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
EXAMPLE
Micronaut HTTP Client used by Grails
41
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 42
Micronaut Declarative Http Client in Grails 4
curl start.grails.org/versions
["3.1.13","3.1.14","3.1.15","3.1.16","3.1.17.BUILD-
SNAPSHOT","3.2.2","3.2.3","3.2.4","3.2.5","3.2.6","3.2.7","3.2.8","3.2.9","3.2.
10","3.2.11","3.2.12","3.2.13","3.2.14.BUILD-
SNAPSHOT","3.3.0","3.3.1","3.3.2","3.3.3","3.3.4","3.3.5","3.3.6","3.3.7","3.3.
8","3.3.9","3.3.10.BUILD-SNAPSHOT"]`
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 43
Using Micronaut Declarative Client from a Grails 4 app
package example.grails
interface GrailsClient {
List<String> versions()
}
src/main/groovy/example/grails/GrailsClient.groovy
package example.grails
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.annotation.Client
@Client("https://start.grails.org")
interface GrailsApplicationForge extends GrailsClient {
@Override
@Get("/versions")
List<String> versions();
}
src/main/groovy/example/grails/GrailsApplicationForge.groovy
…
dependencies {
…
compile 'io.micronaut:micronaut-http-client'
}
build.gradle
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 44
Using Micronaut Declarative Client from a Grails 4 app
grails-app/controllers/example/grails/VersionsController.groovy
package example.grails
import groovy.transform.CompileStatic
import org.springframework.beans.factory.annotation.Autowired
class VersionsController {
@Autowired
GrailsClient grailsClient
def index() {
render grailsClient.versions()
}
}
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
45
Micronaut Http Client in integration test of Grails 4
src/integration-test/groovy/example/grails/VersionsControllerSpec.groovy
package example.grails
import grails.testing.mixin.integration.Integration
import io.micronaut.http.HttpRequest
import io.micronaut.http.client.BlockingHttpClient
import io.micronaut.http.client.HttpClient
import spock.lang.Specification
@Integration
class VersionsControllerSpec extends Specification {
void "/versions/index returns Grails versions"() {
given:
BlockingHttpClient client = HttpClient.create(new URL("http://localhost:$serverPort".toString())).toBlocking()
when:
String versions = client.retrieve(HttpRequest.GET('/versions/index'), String)
then:
versions.contains('3.2.10')
versions.contains('3.3.1')
}
}
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
46
Using Micronaut Declarative Client from a Grails 4 app
micronaut:
http:
services:
appforge:
url: "https://start.grails.org"
grails-app/conf/application.yml
package example.grails
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.annotation.Client
@Client("appforge")
interface GrailsApplicationForge extends GrailsClient {
@Override
@Get("/versions")
List<String> versions();
}
src/main/groovy/example/grails/GrailsApplicationForge.groovy
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• Micronaut optimized for microservices and distributed
architectures
• Grails optimized for rapid development of monolithic apps
• Consider Building Configurations instead of Grails Plugins
• Configurations work with Micronaut, Spring (with
micronaut-spring) and Grails
• Note: some Grails features are only accessible via Plugins
(GSP/JSON views, taglibs etc.)
47
Micronaut vs Grails?
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
EXAMPLE
Micronaut Configuration used by Grails,
Micronaut and Spring Boot
48
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
49
Micronaut Configurations
├── build.gradle
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── grails-app
│   ├── conf
│   │   ├── application.yml
│   │   └── logback.groovy
│   ├── services
│   │   └── eu
│   │   └── vies
│   │   ├── VatService.groovy
│   ├── init
│   │   └── eu
│   │   └── vies
│   │   ├── Application.groovy
│   │   └── BootStrap.groovy
├── grails-wrapper.jar
├── grailsw
├── grailsw.bat
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
50
Micronaut Configurations
grails-plugin: grails-app/services/eu/vies/VatService.groovy
package eu.vies
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import wslite.soap.SOAPClient
import wslite.soap.SOAPResponse
@CompileStatic
class VatService {
String url = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService'
SOAPClient client = new SOAPClient("${url}.wsdl")
@CompileDynamic
Boolean validateVat(String memberStateCode, String vatNumberCode) {
SOAPResponse response = client.send(SOAPAction: url) {
body('xmlns': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types') {
checkVat {
countryCode(memberStateCode)
vatNumber(vatNumberCode)
}
}
}
response.checkVatResponse.valid.text() == 'true'
}
}
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 51
.
├── build.gradle
├── gradle.properties
└── src
├── main
│   └── groovy
│   └── eu
│   └── vies
│   └── VatService.groovy
└── test
└── groovy
└── eu
└── vies
└── VatServiceSpec.groovy
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 52
lib: build.gradle
plugins {
id 'groovy'
}
repositories {
jcenter()
}
dependencies {
compileOnly "io.micronaut:micronaut-inject-groovy:$micronautVersion"
compile 'org.codehaus.groovy:groovy-xml:2.5.7'
compile 'com.github.groovy-wslite:groovy-wslite:1.1.2'
testCompile("org.spockframework:spock-core:${spockVersion}") {
exclude module: 'groovy-all'
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
53
lib: src/main/groovy/eu/vies/VatService.groovy
package eu.vies
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import wslite.soap.SOAPClient
import wslite.soap.SOAPResponse
import javax.inject.Singleton
@CompileStatic
@Singleton
class VatService {
String url = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService'
SOAPClient client = new SOAPClient("${url}.wsdl")
@CompileDynamic
Boolean validateVat(String memberStateCode, String vatNumberCode) {
SOAPResponse response = client.send(SOAPAction: url) {
body('xmlns': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types') {
checkVat {
countryCode(memberStateCode)
vatNumber(vatNumberCode)
}
}
}
response.checkVatResponse.valid.text() == 'true'
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 54
grails: grails-app/controllers/example/grails/ViesController.groovy
.
package example.grails
import eu.vies.VatService
import groovy.transform.CompileStatic
import org.springframework.beans.factory.annotation.Autowired
@CompileStatic
class ViesController {
@Autowired
VatService vatService
def valid(String memberStateCode, String vatNumberCode) {
render vatService.validateVat(memberStateCode, vatNumberCode)
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 55
micronaut: src/main/example/micronaut/ViesController.groovy
.
package example.micronaut
import eu.vies.VatService
import groovy.transform.CompileStatic
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import javax.inject.Inject
@CompileStatic
@Controller('/vies')
class ViesController {
@Inject
VatService vatService
@Get('/valid')
Boolean valid(String memberStateCode, String vatNumberCode) {
vatService.validateVat(memberStateCode, vatNumberCode)
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 56
springboot: src/main/example/micronaut/ViesController.groovy
.
package example.springboot
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.ComponentScan
@ComponentScan(basePackages = "eu.vies",
basePackageClasses = SpringbootApplication.class)
@SpringBootApplication
class SpringbootApplication {
static void main(String[] args) {
SpringApplication.run(SpringbootApplication, args)
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
57
springboot: src/main/example/micronaut/ViesController.groovy
.
package example.springboot
import eu.vies.VatService
import groovy.transform.CompileStatic
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@CompileStatic
@RequestMapping('/vies')
@RestController
class ViesController {
@Autowired
VatService vatService
@GetMapping('/valid')
Boolean valid(@RequestParam(required = true) String memberStateCode,
@RequestParam(required = true) String vatNumberCode) {
vatService.validateVat(memberStateCode, vatNumberCode)
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
58
lib: build.gradle
plugins {
id 'groovy'
}
repositories {
jcenter()
}
dependencies {
compileOnly “io.micronaut:micronaut-inject-groovy:1.2.1”
compileOnly “io.micronaut.spring:micronautspring-annotation:1.0.1”
compileOnly “org.springframework.boot:spring-boot-starter:2.1.5.RELEASE”
compile 'org.codehaus.groovy:groovy-xml:2.5.7'
compile 'com.github.groovy-wslite:groovy-wslite:1.1.2'
testCompile("org.spockframework:spock-core:${spockVersion}") {
exclude module: 'groovy-all'
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
Previously the author variable would be a direct Author instance
Impacts domains with inheritance (instanceof)
59
lib: src/main/groovy/eu/vies/VatService.groovy
package eu.vies
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import wslite.soap.SOAPClient
import wslite.soap.SOAPResponse
import org.springframework.stereotype.Service
@CompileStatic
@Service
class VatService {
String url = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService'
SOAPClient client = new SOAPClient("${url}.wsdl")
@CompileDynamic
Boolean validateVat(String memberStateCode, String vatNumberCode) {
SOAPResponse response = client.send(SOAPAction: url) {
body('xmlns': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types') {
checkVat {
countryCode(memberStateCode)
vatNumber(vatNumberCode)
}
}
}
response.checkVatResponse.valid.text() == 'true'
}
}
Micronaut Configurations
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• Micronaut Configurations can provide:
• Configuration with @ConfigurationProperties
• Beans with @Singleton, @Factory etc.
• Conditional Behavior with @Requires
• Customization with @Replaces
60
Micronaut Configurations
© 2019, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com
• Upgrading very different compared to 2 -> 3
• Micronaut Provides an Awesome Foundation
• Building Blocks to Create Libraries, Configurations and Clients
• Most Micronaut Features Available in Grails
• Build Micronaut Libraries not Plugins
61
Summary
CONNECT WITH US
1+ (314) 579-0066
@objectcomputing
objectcomputing.com
© 2019, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 62
Questions?
CONNECT WITH US
1+ (314) 579-0066
@objectcomputing
objectcomputing.com
© 2019, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 63
Resources
• http://start.grails.org
• https://guides.grails.org
• https://grails.org/blog/index.html
• http://groovycalamari.com
© 2018, Object Computing, Inc. (OCI). All rights reserved.
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 64
Thank you!
Zachary Klein
Senior Software Engineer
2GM Team Member
kleinz@objectcomputing.com
http://twitter.com/ZacharyAKlein
https://github.com/ZacharyKlein
© 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 65
Thank you!
Zachary Klein
Senior Software Engineer
Grails & Micronaut Core Team Member
kleinz@objectcomputing.com
@ZacharyAKlein

Weitere ähnliche Inhalte

Was ist angesagt?

Introduction to rust: a low-level language with high-level abstractions
Introduction to rust: a low-level language with high-level abstractionsIntroduction to rust: a low-level language with high-level abstractions
Introduction to rust: a low-level language with high-level abstractionsyann_s
 
Advanced API Debugging
Advanced API DebuggingAdvanced API Debugging
Advanced API DebuggingPostman
 
Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...
Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...
Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...Simplilearn
 
Advanced task management with Celery
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with CeleryMahendra M
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
Blazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBlazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBrendan Gregg
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
Event-driven serverless functions with Next.js and Inngest
Event-driven serverless functions with Next.js and InngestEvent-driven serverless functions with Next.js and Inngest
Event-driven serverless functions with Next.js and InngestDan Farrelly
 
Grails Connecting to MySQL
Grails Connecting to MySQLGrails Connecting to MySQL
Grails Connecting to MySQLashishkirpan
 
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019Agile India
 
TypeScript Best Practices
TypeScript Best PracticesTypeScript Best Practices
TypeScript Best Practicesfelixbillon
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Philip Schwarz
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondKaushal Dhruw
 
Luigi presentation NYC Data Science
Luigi presentation NYC Data ScienceLuigi presentation NYC Data Science
Luigi presentation NYC Data ScienceErik Bernhardsson
 

Was ist angesagt? (20)

Introduction to rust: a low-level language with high-level abstractions
Introduction to rust: a low-level language with high-level abstractionsIntroduction to rust: a low-level language with high-level abstractions
Introduction to rust: a low-level language with high-level abstractions
 
Advanced API Debugging
Advanced API DebuggingAdvanced API Debugging
Advanced API Debugging
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...
Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...
Jenkins Pipeline Tutorial | Jenkins Build And Delivery Pipeline | Jenkins Tut...
 
Meta Programming in Groovy
Meta Programming in GroovyMeta Programming in Groovy
Meta Programming in Groovy
 
Advanced task management with Celery
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with Celery
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Blazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBlazing Performance with Flame Graphs
Blazing Performance with Flame Graphs
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Json
JsonJson
Json
 
Git for beginners
Git for beginnersGit for beginners
Git for beginners
 
Event-driven serverless functions with Next.js and Inngest
Event-driven serverless functions with Next.js and InngestEvent-driven serverless functions with Next.js and Inngest
Event-driven serverless functions with Next.js and Inngest
 
Grails Connecting to MySQL
Grails Connecting to MySQLGrails Connecting to MySQL
Grails Connecting to MySQL
 
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
 
TypeScript Best Practices
TypeScript Best PracticesTypeScript Best Practices
TypeScript Best Practices
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
 
D3 js
D3 jsD3 js
D3 js
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & Beyond
 
Luigi presentation NYC Data Science
Luigi presentation NYC Data ScienceLuigi presentation NYC Data Science
Luigi presentation NYC Data Science
 

Ähnlich wie Grails 4: Upgrade your Game!

What’s new in grails framework 5?
What’s new in grails framework 5?What’s new in grails framework 5?
What’s new in grails framework 5?Puneet Behl
 
Gretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with GradleGretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with GradleAndrey Hihlovsky
 
Git Gerrit Mit Teamforge
Git Gerrit Mit TeamforgeGit Gerrit Mit Teamforge
Git Gerrit Mit TeamforgeCollabNet
 
Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)
Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)
Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)Mark Hamstra
 
Git/Gerrit with TeamForge
Git/Gerrit with TeamForgeGit/Gerrit with TeamForge
Git/Gerrit with TeamForgeCollabNet
 
Digdag Updates 2020 July
Digdag Updates 2020 JulyDigdag Updates 2020 July
Digdag Updates 2020 JulyYou Yamagata
 
Optimize Your Enterprise Git Webinar
Optimize Your Enterprise Git WebinarOptimize Your Enterprise Git Webinar
Optimize Your Enterprise Git WebinarCollabNet
 
Webinar: End to End Security & Operations with Chainguard and Weave GitOps
Webinar: End to End Security & Operations with Chainguard and Weave GitOpsWebinar: End to End Security & Operations with Chainguard and Weave GitOps
Webinar: End to End Security & Operations with Chainguard and Weave GitOpsWeaveworks
 
GitPro Whitepaper
GitPro WhitepaperGitPro Whitepaper
GitPro WhitepaperERP Buddies
 
GitOps: Git come unica fonte di verità per applicazioni e infrastruttura
GitOps: Git come unica fonte di verità per applicazioni e infrastrutturaGitOps: Git come unica fonte di verità per applicazioni e infrastruttura
GitOps: Git come unica fonte di verità per applicazioni e infrastrutturasparkfabrik
 
You're doing it wrong! Git it right!
You're doing it wrong! Git it right!You're doing it wrong! Git it right!
You're doing it wrong! Git it right!Cory Webb
 
Groovy for Java Devs
Groovy for Java DevsGroovy for Java Devs
Groovy for Java DevsZachary Klein
 
Don't Let Git Get Your Goat!
Don't Let Git Get Your Goat!Don't Let Git Get Your Goat!
Don't Let Git Get Your Goat!CollabNet
 
gitopsthekubernetesway-201026090439.pdf
gitopsthekubernetesway-201026090439.pdfgitopsthekubernetesway-201026090439.pdf
gitopsthekubernetesway-201026090439.pdfsaraichiba2
 
Gitops: the kubernetes way
Gitops: the kubernetes wayGitops: the kubernetes way
Gitops: the kubernetes waysparkfabrik
 
Open up your platform with Open Source and GitHub
Open up your platform with Open Source and GitHubOpen up your platform with Open Source and GitHub
Open up your platform with Open Source and GitHubScott Graham
 
Groovy-Powered Microservices with Micronaut
Groovy-Powered Microservices with MicronautGroovy-Powered Microservices with Micronaut
Groovy-Powered Microservices with MicronautZachary Klein
 

Ähnlich wie Grails 4: Upgrade your Game! (20)

What’s new in grails framework 5?
What’s new in grails framework 5?What’s new in grails framework 5?
What’s new in grails framework 5?
 
Gretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with GradleGretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with Gradle
 
Introduction to git & github
Introduction to git & githubIntroduction to git & github
Introduction to git & github
 
Git Gerrit Mit Teamforge
Git Gerrit Mit TeamforgeGit Gerrit Mit Teamforge
Git Gerrit Mit Teamforge
 
Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)
Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)
Dev, Staging & Production Workflow with Gitify (at MODXpo 2015 in Munich)
 
Git/Gerrit with TeamForge
Git/Gerrit with TeamForgeGit/Gerrit with TeamForge
Git/Gerrit with TeamForge
 
Digdag Updates 2020 July
Digdag Updates 2020 JulyDigdag Updates 2020 July
Digdag Updates 2020 July
 
Optimize Your Enterprise Git Webinar
Optimize Your Enterprise Git WebinarOptimize Your Enterprise Git Webinar
Optimize Your Enterprise Git Webinar
 
Webinar: End to End Security & Operations with Chainguard and Weave GitOps
Webinar: End to End Security & Operations with Chainguard and Weave GitOpsWebinar: End to End Security & Operations with Chainguard and Weave GitOps
Webinar: End to End Security & Operations with Chainguard and Weave GitOps
 
GitPro Whitepaper
GitPro WhitepaperGitPro Whitepaper
GitPro Whitepaper
 
GitOps: Git come unica fonte di verità per applicazioni e infrastruttura
GitOps: Git come unica fonte di verità per applicazioni e infrastrutturaGitOps: Git come unica fonte di verità per applicazioni e infrastruttura
GitOps: Git come unica fonte di verità per applicazioni e infrastruttura
 
Gitops Hands On
Gitops Hands OnGitops Hands On
Gitops Hands On
 
Git for Windows
Git for WindowsGit for Windows
Git for Windows
 
You're doing it wrong! Git it right!
You're doing it wrong! Git it right!You're doing it wrong! Git it right!
You're doing it wrong! Git it right!
 
Groovy for Java Devs
Groovy for Java DevsGroovy for Java Devs
Groovy for Java Devs
 
Don't Let Git Get Your Goat!
Don't Let Git Get Your Goat!Don't Let Git Get Your Goat!
Don't Let Git Get Your Goat!
 
gitopsthekubernetesway-201026090439.pdf
gitopsthekubernetesway-201026090439.pdfgitopsthekubernetesway-201026090439.pdf
gitopsthekubernetesway-201026090439.pdf
 
Gitops: the kubernetes way
Gitops: the kubernetes wayGitops: the kubernetes way
Gitops: the kubernetes way
 
Open up your platform with Open Source and GitHub
Open up your platform with Open Source and GitHubOpen up your platform with Open Source and GitHub
Open up your platform with Open Source and GitHub
 
Groovy-Powered Microservices with Micronaut
Groovy-Powered Microservices with MicronautGroovy-Powered Microservices with Micronaut
Groovy-Powered Microservices with Micronaut
 

Mehr von Zachary Klein

Native Cloud-Native: Building Agile Microservices with the Micronaut Framework
Native Cloud-Native: Building Agile Microservices with the Micronaut FrameworkNative Cloud-Native: Building Agile Microservices with the Micronaut Framework
Native Cloud-Native: Building Agile Microservices with the Micronaut FrameworkZachary Klein
 
Micronaut: Changing the Micro Future
Micronaut: Changing the Micro FutureMicronaut: Changing the Micro Future
Micronaut: Changing the Micro FutureZachary Klein
 
Getting Groovy with JHipster and Micronaut
Getting Groovy with JHipster and MicronautGetting Groovy with JHipster and Micronaut
Getting Groovy with JHipster and MicronautZachary Klein
 
Micronaut For Single Page Apps
Micronaut For Single Page AppsMicronaut For Single Page Apps
Micronaut For Single Page AppsZachary Klein
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitZachary Klein
 
Room with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.jsRoom with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.jsZachary Klein
 
Shields Up! Securing React Apps
Shields Up! Securing React AppsShields Up! Securing React Apps
Shields Up! Securing React AppsZachary Klein
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3Zachary Klein
 

Mehr von Zachary Klein (9)

Native Cloud-Native: Building Agile Microservices with the Micronaut Framework
Native Cloud-Native: Building Agile Microservices with the Micronaut FrameworkNative Cloud-Native: Building Agile Microservices with the Micronaut Framework
Native Cloud-Native: Building Agile Microservices with the Micronaut Framework
 
Micronaut: Changing the Micro Future
Micronaut: Changing the Micro FutureMicronaut: Changing the Micro Future
Micronaut: Changing the Micro Future
 
Getting Groovy with JHipster and Micronaut
Getting Groovy with JHipster and MicronautGetting Groovy with JHipster and Micronaut
Getting Groovy with JHipster and Micronaut
 
Micronaut Launchpad
Micronaut LaunchpadMicronaut Launchpad
Micronaut Launchpad
 
Micronaut For Single Page Apps
Micronaut For Single Page AppsMicronaut For Single Page Apps
Micronaut For Single Page Apps
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to Orbit
 
Room with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.jsRoom with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.js
 
Shields Up! Securing React Apps
Shields Up! Securing React AppsShields Up! Securing React Apps
Shields Up! Securing React Apps
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3
 

Kürzlich hochgeladen

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 

Kürzlich hochgeladen (20)

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 

Grails 4: Upgrade your Game!

  • 1. objectcomputing.com© 2020, Object Computing, Inc. (OCI). All rights reserved. No part of these notes may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior, written permission of Object Computing, Inc. (OCI) Grails 4 Leveling Up Your Game!
  • 2. © 2018, Object Computing, Inc. (OCI). All rights reserved. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 2 • Senior Software Engineer • Web and JVM developer with a decade of experience • Husband and father • OSS contributor • 2GM Team Member at OCI Zachary Klein
  • 3. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • What’s New in Grails 4? • Upgrade Steps • Micronaut Integration • Summary & Q&A 3 Agenda
  • 4. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 4 Grails Timeline • Grails 1.0: Released in 2008 • Based on Spring, Hibernate, Sitemesh, and other proven technologies with Groovy as primary language • Grails 2.0: Released in 2011 • Grails 3.0: Released in 2015 • Moved to Spring Boot and Gradle, many breaking changes • Grails 4.0: Released in 2019 • Upgrade to foundational libraries, adds Micronaut integration • Grails 4.1.0: Milestone 2 released in September 2020
  • 5. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 5 1. Java 8 (minimum) 2. Groovy 2.5.6 3. Spring Boot 2.1.3 4. Spring 5.1.5 5. GORM 7 / Hibernate 5.4 6. Gradle 5.1.1 7. Spock 1.2 8. Micronaut Integration What’s New in Grails 4?
  • 6. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 6 Upgrading to Grails 4 ≠ Grails 2 Grails 3 Grails 3 Grails 4
  • 7. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 7 • Read the upgrade notes: • 2.x -> 3.x: http://docs.grails.org/3.2.13/guide/single.html#upgrading2x • 3.x -> 4.x: http://docs.grails.org/4.0.4/guide/single.html#upgrading • Move to Gradle project (BuildConfig.groovy -> build.gradle) • If using Git, make use of git mv to preserve VCS history • Controller actions must be methods, not closures • Resources plugin no longer maintained - migrate to Asset Pipeline: https://grails.org/blog/2016-09-12.html Upgrade from Older Versions of Grails (3 >)
  • 8. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • Most deprecated classes have been removed • Some package restructuring • No major breaking API changes • Most plugins should just work • Breaking changes in Spring, Hibernate, Groovy • https://grails.github.io/grails-upgrade/latest/guide/index.html#upgradingTo4x 8 Grails 4 Upgrade Notes
  • 9. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Upgrade Grails version defined in gradle.properties 9 Upgrade Steps ➡ Bump up Grails Version grailsVersion=4.0.0.RC1
  • 10. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0- Migration-Guide 1. Many configuration changes 2. Embedded container API • https://www.baeldung.com/embeddedservletcontainercustomizer- configurableembeddedservletcontainer-spring-boot 3. Actuator Endpoints Changes 10 Upgrade Steps ➡ Spring Boot
  • 11. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Actuator have changed substantially from Spring Boot 1.5 to 2 11 Upgrade Steps ➡ Actuator changes endpoints: enabled: false jmx: enabled: true unique-names: true Grails 3 spring: jmx: unique-names: true management: endpoints: enabled-by-default: false Grails 4
  • 12. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Spring Boot Developer Tools in combination with a browser extension such as the Chrome LiveReload extension to get automatic browser refresh when you change anything in your Grails application. 12 Upgrade Steps ➡ Spring Boot Developer Tools configurations { developmentOnly runtimeClasspath { extendsFrom developmentOnly } } dependencies { developmentOnly("org.springframework.boot:spring-boot-devtools") ... build.gradle
  • 13. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com https://github.com/spring-projects/spring-integration/wiki/ Spring-Integration-4.3-to-5.0-Migration-Guide Nothing that should impact the average Grails application 13 Upgrade Steps ➡ Spring Changes
  • 14. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com https://docs.gradle.org/current/userguide/upgrading_version_4.html • Grails 4.0 upgraded to Gradle 5 • Gradle 3 no longer supported, 4 not officially supported • Many breaking changes from 3 to 5 14 Upgrade Steps ➡ Gradle Changes ./gradlew wrapper --gradle-version 5.4.1
  • 15. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Spring Boot Gradle plugin’s documentation. 15 Upgrade Steps ➡ Spring Boot Gradle Plugin Changes bootRun { addResources = true … } build.gradle - Grails 3 bootRun { sourceResources sourceSets.main … } build.gradle - Grails 4
  • 16. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Spring Boot Gradle plugin’s documentation. 16 Upgrade Steps ➡ Building executable jars for Plugins bootRepackage.enabled=false build.gradle - Grails 3 bootJar.enabled=false build.gradle - Grails 4
  • 17. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com http://gorm.grails.org/7.0.x/hibernate/manual/ index.html#upgradeNotes 1. All operations now require a transaction 2. Proxy behavior has changed 3. No more REST client 17 Upgrade Steps ➡ GORM / Hibernate Changes
  • 18. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Package Restructuring and Deprecations • Previously deprecated classes have been deleted from this release. • In order to support Java 11 modules in the future, some package re-structuring has occurred. 18 Upgrade Steps ➡ GORM / Hibernate Changes
  • 19. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Changes to Proxy Handling • GORM no longer creates custom proxy factories nor automatically unwraps Hibernate proxies. 19 Upgrade Steps ➡ GORM / Hibernate Changes
  • 20. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 20 Upgrade Steps ➡ GORM / Hibernate Changes class Pet { String name } Author author = Book.get(1).author
  • 21. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 21 Upgrade Steps ➡ GORM / Hibernate Changes class Pet { String name } class Dog extends Pet {} class Person { String name Pet pet } def person = Person.get(1) assert person.pet instanceof Dog assert person.pet.instanceOf(Dog) assert Pet.get(person.petId).instanceOf(Dog) assert Pet.get(person.petId) instanceof Dog GRAILS 3
  • 22. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com class Pet { String name } class Dog extends Pet {} class Person { String name Pet pet } def person = Person.get(1) assert person.pet instanceof Dog assert person.pet.instanceOf(Dog) assert Pet.get(person.petId).instanceOf(Dog) assert Pet.get(person.petId) instanceof Dog 22 Upgrade Steps ➡ GORM / Hibernate Changes GRAILS 4
  • 23. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com grails-validation Deprecated and Removed • As of GORM 6.x the grails-validation module was deprecated and replaced by grails-datastore-gorm-validation. • Deprecated interfaces were maintained for backwards compatibility. In GORM 7.0, these deprecated classes have been removed and all dependency on grails-validation removed. 23 Upgrade Steps ➡ GORM / Hibernate Changes
  • 24. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Transactions Now Required for all Operations • Previous versions of Hibernate allowed read operation to be executed without the presence of a declared transaction. • Hibernate 5.2. and above require the presence of an active transaction. • If you see a javax.persistence.TransactionRequiredException exception, it means your method lacks @Transactional (or @ReadOnly) annotation around it. 24 Upgrade Steps ➡ GORM / Hibernate Changes
  • 25. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Upgrade project GORM version defined in gradle.properties: 25 Upgrade Steps ➡ Bump up GORM Version gormVersion=6.1.12.RELEASE gorm.version=7.0.1.RELEASE
  • 26. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 26 Upgrade Steps ➡ Upgrading Hibernate dependencies { … compile “org.grails.plugins.hibernate5” compile “org.hibernate:hibernate-core:5.1.5.Final” } build.gradle - Grails 3 dependencies { … compile “org.grails.plugins.hibernate5” compile “org.hibernate:hibernate-core:5.4.0.Final” } build.gradle - Grails 4
  • 27. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 27 org.grails:grails-datastore-rest-client deprecated in favor of Micronaut HTTP Client. String uri = "http://repo.grails.org/grails/api/security/groups/test-group" def resp = rest.put(uri){ auth System.getProperty("artifactory.user"), System.getProperty("artifactory.pass") contentType "application/vnd.org.jfrog.artifactory.security.Group+json" json { name = "test-group" description = "A temporary test group" } } RestClient Builder - Grails 3 Upgrade Steps ➡ RestClient Grails Plugin Removal
  • 28. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 28 org.grails:grails-datastore-rest-client deprecated in favor of Micronaut HTTP Client. Map<String, Object> payload = [name: "test-group", description: "A temporary test group”] String uri = "http://repo.grails.org/grails/api/security/groups/test-group" HttpRequest request = HttpRequest.PUT(uri,payload) .basicAuth(System.getProperty("artifactory.user"), System.getProperty("artifactory.pass")) .contentType("application/vnd.org.jfrog.artifactory.security.Group+json") HttpResponse resp = client.toBlocking().exchange(request) Micronaut HTTP Client - Grails 4 Upgrade Steps ➡ RestClient Grails Plugin Removal
  • 29. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 29 Upgrade Steps ➡ Asset Pipeline buildscript { dependencies { .. classpath: “com.bertramlabs.plugins:asset-pipeline-grails:2.14.1” } } apply plugin “asset-pipeline” dependencies { .. runtime “com.bertramlabs.plugins:asset-pipeline-grails:2.14.1” build.gradle - Grails 3 build.gradle - Grails 4 buildscript { .. dependencies { classpath: “com.bertramlabs.plugins:asset-pipeline-grails:3.0.10” … } … apply plugin “com.bertramlabs.asset-pipeline” … dependencies { … runtime “com.bertramlabs.plugins:asset-pipeline-grails:3.0.10” http://www.asset-pipeline.com/manual/index.html
  • 30. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 30 Upgrade Steps ➡ Spring Security Core dependencies { … compile “org.grails.plugins:spring-security-core:3.2.0” } build.gradle - Grails 3 build.gradle - Grails 4 dependencies { … compile “org.grails.plugins:spring-security-core:4.0.0.RC2” } https://grails-plugins.github.io/grails-spring-security-core/
  • 31. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 31 Upgrade Steps ➡ Spring Security Core class User { SpringSecurityService springSecurityService … … def beforeInsert() { encodePassword() } def beforeUpdate() { if (isDirty(‘password’)) { encodePassword() } } protected void encodePassword() { password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) } } grails-app/example/User.groovy - Grails 3
  • 32. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 32 Upgrade Steps ➡ Spring Security Core class User { SpringSecurityService springSecurityService … … def beforeInsert() { encodePassword() } def beforeUpdate() { if (isDirty(‘password’)) { encodePassword() } } protected void encodePassword() { password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) } } grails-app/example/User.groovy - Grails 4
  • 33. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 33 Upgrade Steps ➡ Spring Security Core import grails.plugin.springsecurity.SpringSecurityService import org.grails.datastore.mapping.engine.event.* import org.springframework.beans.factory.annotation.Autowired import grails.events.annotation.gorm.Listener @CompileStatic class UserPasswordEncoderListener { @Autowired SpringSecurityService springSecurityService @Listener(User) void onPreInsertEvent(PreInsertEvent event) { encodePasswordForEvent(event) } @Listener(User) void onPreUpdateEvent(PreUpdateEvent event) { encodePasswordForEvent(event) } private void encodePasswordForEvent(AbstractPersistenceEvent event) { if (event.entityObject instanceof User) { User u = event.entityObject as User if (u.password && ((event instanceof PreInsertEvent) || (event instanceof PreUpdateEvent && u.isDirty('password')))) { event.getEntityAccess().setProperty('password', encodePassword(u.password)) } } } private String encodePassword(String password) { springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password } } src/main/groovy/example/UserPasswordEncoderListener.groovy - Grails 4
  • 34. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 34 Upgrade Steps ➡ Spring Security Core import example.UserPasswordEncoderListener beans = { userPasswordEncoderListener(UserPasswordEncoderListener) } grails-app/conf/spring/resources.groovy - Grails 4
  • 35. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Spring Security 5 changed the way password are encoded and compared for matches. {bcrypt}someencryptedpassword // using bcrypt {noop}planintextpassword 35 Upgrade Steps ➡ Spring Security Core https://www.baeldung.com/spring-security-5-password-storage https://dzone.com/articles/password-encoder-migration-with-spring-security-5
  • 36. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com http://groovy-lang.org/releasenotes/groovy-2.5.html Notable: 1. No more groovy-all jar 2. New annotations (e.g, @AutoImplement, @MapConstructor) 3. Date extensions require a new dependency: groovy-dateutil 4. JDK 11 warnings not resolved 36 Upgrade Notes ➡ Groovy Changes
  • 37. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Plugins should just work unless… They use an API that has been changed or removed GrailsDomainClass https://docs.grails.org/latest/guide/ upgrading.html#_grails_domain_class_api_deprecated Spring Boot Embedded Server 37 Upgrade Notes ➡ Plugins
  • 38. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • Micronaut a Foundational Library for building applications of any type • Focuses on Small Memory Footprint and Speed • Eliminates Reflection, Runtime Proxies and Runtime Analysis 38 Micronaut Integration
  • 39. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Micronaut has also been used to improve startup and reduce overall memory consumption of Grails applications (along associated improvements in Spring Boot 2.1) 39 Micronaut Integration
  • 40. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • Declarative HTTP Clients with @Client • Declarative Clients for Kafka & RabbitMQ • Use @RabbitListener for RabbitMQ • Use @KafkaListener for Kafka • Planned Support For Other Messaging Systems 40 Micronaut Messaging
  • 41. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com EXAMPLE Micronaut HTTP Client used by Grails 41
  • 42. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 42 Micronaut Declarative Http Client in Grails 4 curl start.grails.org/versions ["3.1.13","3.1.14","3.1.15","3.1.16","3.1.17.BUILD- SNAPSHOT","3.2.2","3.2.3","3.2.4","3.2.5","3.2.6","3.2.7","3.2.8","3.2.9","3.2. 10","3.2.11","3.2.12","3.2.13","3.2.14.BUILD- SNAPSHOT","3.3.0","3.3.1","3.3.2","3.3.3","3.3.4","3.3.5","3.3.6","3.3.7","3.3. 8","3.3.9","3.3.10.BUILD-SNAPSHOT"]`
  • 43. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 43 Using Micronaut Declarative Client from a Grails 4 app package example.grails interface GrailsClient { List<String> versions() } src/main/groovy/example/grails/GrailsClient.groovy package example.grails import io.micronaut.http.annotation.Get import io.micronaut.http.client.annotation.Client @Client("https://start.grails.org") interface GrailsApplicationForge extends GrailsClient { @Override @Get("/versions") List<String> versions(); } src/main/groovy/example/grails/GrailsApplicationForge.groovy … dependencies { … compile 'io.micronaut:micronaut-http-client' } build.gradle
  • 44. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 44 Using Micronaut Declarative Client from a Grails 4 app grails-app/controllers/example/grails/VersionsController.groovy package example.grails import groovy.transform.CompileStatic import org.springframework.beans.factory.annotation.Autowired class VersionsController { @Autowired GrailsClient grailsClient def index() { render grailsClient.versions() } }
  • 45. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 45 Micronaut Http Client in integration test of Grails 4 src/integration-test/groovy/example/grails/VersionsControllerSpec.groovy package example.grails import grails.testing.mixin.integration.Integration import io.micronaut.http.HttpRequest import io.micronaut.http.client.BlockingHttpClient import io.micronaut.http.client.HttpClient import spock.lang.Specification @Integration class VersionsControllerSpec extends Specification { void "/versions/index returns Grails versions"() { given: BlockingHttpClient client = HttpClient.create(new URL("http://localhost:$serverPort".toString())).toBlocking() when: String versions = client.retrieve(HttpRequest.GET('/versions/index'), String) then: versions.contains('3.2.10') versions.contains('3.3.1') } }
  • 46. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 46 Using Micronaut Declarative Client from a Grails 4 app micronaut: http: services: appforge: url: "https://start.grails.org" grails-app/conf/application.yml package example.grails import io.micronaut.http.annotation.Get import io.micronaut.http.client.annotation.Client @Client("appforge") interface GrailsApplicationForge extends GrailsClient { @Override @Get("/versions") List<String> versions(); } src/main/groovy/example/grails/GrailsApplicationForge.groovy
  • 47. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • Micronaut optimized for microservices and distributed architectures • Grails optimized for rapid development of monolithic apps • Consider Building Configurations instead of Grails Plugins • Configurations work with Micronaut, Spring (with micronaut-spring) and Grails • Note: some Grails features are only accessible via Plugins (GSP/JSON views, taglibs etc.) 47 Micronaut vs Grails?
  • 48. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com EXAMPLE Micronaut Configuration used by Grails, Micronaut and Spring Boot 48
  • 49. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 49 Micronaut Configurations ├── build.gradle ├── gradle │   └── wrapper │   ├── gradle-wrapper.jar │   └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── grails-app │   ├── conf │   │   ├── application.yml │   │   └── logback.groovy │   ├── services │   │   └── eu │   │   └── vies │   │   ├── VatService.groovy │   ├── init │   │   └── eu │   │   └── vies │   │   ├── Application.groovy │   │   └── BootStrap.groovy ├── grails-wrapper.jar ├── grailsw ├── grailsw.bat
  • 50. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 50 Micronaut Configurations grails-plugin: grails-app/services/eu/vies/VatService.groovy package eu.vies import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import wslite.soap.SOAPClient import wslite.soap.SOAPResponse @CompileStatic class VatService { String url = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService' SOAPClient client = new SOAPClient("${url}.wsdl") @CompileDynamic Boolean validateVat(String memberStateCode, String vatNumberCode) { SOAPResponse response = client.send(SOAPAction: url) { body('xmlns': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types') { checkVat { countryCode(memberStateCode) vatNumber(vatNumberCode) } } } response.checkVatResponse.valid.text() == 'true' } }
  • 51. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 51 . ├── build.gradle ├── gradle.properties └── src ├── main │   └── groovy │   └── eu │   └── vies │   └── VatService.groovy └── test └── groovy └── eu └── vies └── VatServiceSpec.groovy Micronaut Configurations
  • 52. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 52 lib: build.gradle plugins { id 'groovy' } repositories { jcenter() } dependencies { compileOnly "io.micronaut:micronaut-inject-groovy:$micronautVersion" compile 'org.codehaus.groovy:groovy-xml:2.5.7' compile 'com.github.groovy-wslite:groovy-wslite:1.1.2' testCompile("org.spockframework:spock-core:${spockVersion}") { exclude module: 'groovy-all' } } Micronaut Configurations
  • 53. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 53 lib: src/main/groovy/eu/vies/VatService.groovy package eu.vies import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import wslite.soap.SOAPClient import wslite.soap.SOAPResponse import javax.inject.Singleton @CompileStatic @Singleton class VatService { String url = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService' SOAPClient client = new SOAPClient("${url}.wsdl") @CompileDynamic Boolean validateVat(String memberStateCode, String vatNumberCode) { SOAPResponse response = client.send(SOAPAction: url) { body('xmlns': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types') { checkVat { countryCode(memberStateCode) vatNumber(vatNumberCode) } } } response.checkVatResponse.valid.text() == 'true' } } Micronaut Configurations
  • 54. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 54 grails: grails-app/controllers/example/grails/ViesController.groovy . package example.grails import eu.vies.VatService import groovy.transform.CompileStatic import org.springframework.beans.factory.annotation.Autowired @CompileStatic class ViesController { @Autowired VatService vatService def valid(String memberStateCode, String vatNumberCode) { render vatService.validateVat(memberStateCode, vatNumberCode) } } Micronaut Configurations
  • 55. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 55 micronaut: src/main/example/micronaut/ViesController.groovy . package example.micronaut import eu.vies.VatService import groovy.transform.CompileStatic import io.micronaut.http.annotation.Controller import io.micronaut.http.annotation.Get import javax.inject.Inject @CompileStatic @Controller('/vies') class ViesController { @Inject VatService vatService @Get('/valid') Boolean valid(String memberStateCode, String vatNumberCode) { vatService.validateVat(memberStateCode, vatNumberCode) } } Micronaut Configurations
  • 56. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 56 springboot: src/main/example/micronaut/ViesController.groovy . package example.springboot import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.context.annotation.ComponentScan @ComponentScan(basePackages = "eu.vies", basePackageClasses = SpringbootApplication.class) @SpringBootApplication class SpringbootApplication { static void main(String[] args) { SpringApplication.run(SpringbootApplication, args) } } Micronaut Configurations
  • 57. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 57 springboot: src/main/example/micronaut/ViesController.groovy . package example.springboot import eu.vies.VatService import groovy.transform.CompileStatic import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController @CompileStatic @RequestMapping('/vies') @RestController class ViesController { @Autowired VatService vatService @GetMapping('/valid') Boolean valid(@RequestParam(required = true) String memberStateCode, @RequestParam(required = true) String vatNumberCode) { vatService.validateVat(memberStateCode, vatNumberCode) } } Micronaut Configurations
  • 58. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 58 lib: build.gradle plugins { id 'groovy' } repositories { jcenter() } dependencies { compileOnly “io.micronaut:micronaut-inject-groovy:1.2.1” compileOnly “io.micronaut.spring:micronautspring-annotation:1.0.1” compileOnly “org.springframework.boot:spring-boot-starter:2.1.5.RELEASE” compile 'org.codehaus.groovy:groovy-xml:2.5.7' compile 'com.github.groovy-wslite:groovy-wslite:1.1.2' testCompile("org.spockframework:spock-core:${spockVersion}") { exclude module: 'groovy-all' } } Micronaut Configurations
  • 59. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com Previously the author variable would be a direct Author instance Impacts domains with inheritance (instanceof) 59 lib: src/main/groovy/eu/vies/VatService.groovy package eu.vies import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import wslite.soap.SOAPClient import wslite.soap.SOAPResponse import org.springframework.stereotype.Service @CompileStatic @Service class VatService { String url = 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService' SOAPClient client = new SOAPClient("${url}.wsdl") @CompileDynamic Boolean validateVat(String memberStateCode, String vatNumberCode) { SOAPResponse response = client.send(SOAPAction: url) { body('xmlns': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types') { checkVat { countryCode(memberStateCode) vatNumber(vatNumberCode) } } } response.checkVatResponse.valid.text() == 'true' } } Micronaut Configurations
  • 60. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • Micronaut Configurations can provide: • Configuration with @ConfigurationProperties • Beans with @Singleton, @Factory etc. • Conditional Behavior with @Requires • Customization with @Replaces 60 Micronaut Configurations
  • 61. © 2019, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com • Upgrading very different compared to 2 -> 3 • Micronaut Provides an Awesome Foundation • Building Blocks to Create Libraries, Configurations and Clients • Most Micronaut Features Available in Grails • Build Micronaut Libraries not Plugins 61 Summary
  • 62. CONNECT WITH US 1+ (314) 579-0066 @objectcomputing objectcomputing.com © 2019, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 62 Questions?
  • 63. CONNECT WITH US 1+ (314) 579-0066 @objectcomputing objectcomputing.com © 2019, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 63 Resources • http://start.grails.org • https://guides.grails.org • https://grails.org/blog/index.html • http://groovycalamari.com
  • 64. © 2018, Object Computing, Inc. (OCI). All rights reserved. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 64 Thank you! Zachary Klein Senior Software Engineer 2GM Team Member kleinz@objectcomputing.com http://twitter.com/ZacharyAKlein https://github.com/ZacharyKlein
  • 65. © 2020, Object Computing, Inc. (OCI). All rights reserved. objectcomputing.com 65 Thank you! Zachary Klein Senior Software Engineer Grails & Micronaut Core Team Member kleinz@objectcomputing.com @ZacharyAKlein