Top Banner
by Andrés Viedma scripts with
71

Groovy scripts with Groovy

Jul 14, 2015

Download

Software

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Groovy scripts with Groovy

by Andrés Viedma

scripts with

Page 2: Groovy scripts with Groovy

Restless Java lover

Software dinosaurmore than 20 years nagging

Working at

Usual suspect of MadridGUG and MadridJUG

Page 3: Groovy scripts with Groovy
Page 4: Groovy scripts with Groovy
Page 5: Groovy scripts with Groovy
Page 6: Groovy scripts with Groovy

Arquitecture at

Service DB

TService

TuentiNgDBs

tuenti-ng

Micro serviceTService

Micro serviceTService

Micro serviceTService

Page 7: Groovy scripts with Groovy

Arquitecture at

Service DB

TService

TuentiNgDBs

tuenti-ng

Micro serviceTService

Micro serviceTService

Micro serviceTService

PHP Script

Page 8: Groovy scripts with Groovy

About Groovy

● Dynamic Language, prepared for scripting

● Runs in the JVM

o Lots of Java libraries

o Can use the code of our Java services

● Source code “almost” compatible with Java

o Main difference: == operator means equals()

o If you make your script in Java, it’ll WORK

● Other “cool” features, mainly inspired by Python

Page 9: Groovy scripts with Groovy

Arquitecture at

Service DB

TService

TuentiNgDBs

tuenti-ng

Micro serviceTService

Micro serviceTService

Micro serviceTService

Page 10: Groovy scripts with Groovy

Arquitecture at

Service DB

TService

TuentiNgDBs

tuenti-ng

Micro serviceTService

Micro serviceTService

Micro serviceTService

Groovy Script

Page 11: Groovy scripts with Groovy

Arquitecture at

Service DB

TService

TuentiNgDBs

tuenti-ng

Micro serviceTService

Micro serviceTService

Micro serviceTService

Groovy Script

Page 12: Groovy scripts with Groovy

Mix your Production code with direct accesses to the

DB, config, TServices...

Page 13: Groovy scripts with Groovy

Hello World (Java, but works also as Groovy)

import utils.*;

World world = new World();world.setId("mongo");world.setName("Mongo");

System.out.println("Hello " + world.getName() + "!");

package utils;

public class World { private String id; private String name;

public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}

$GRSCRIPTS/helloworld.groovy $GRSCRIPTS/utils/World.groovy

Page 14: Groovy scripts with Groovy

Hello World (Groovy style)

def world = new World(id: "mongo", name: "Mongo")println "Hello ${world.name}!"

class World { String id String name}

$GRSCRIPTS/helloworld.groovy

$ cd $GRSCRIPTS$ groovy helloworld.groovyHello Mongo!$

Page 15: Groovy scripts with Groovy

Hello World (Groovy style)

def world = new World(id: "mongo", name: "Mongo")println "Hello ${world.name}!"

class World { String id String name}

$GRSCRIPTS/helloworld.groovy

$ cd $GRSCRIPTS$ groovy helloworld.groovyHello Mongo!$

Page 16: Groovy scripts with Groovy

Hello World (Groovy style)

def world = new World(id: "mongo", name: "Mongo")println "Hello ${world.name}!"

class World { String id String name}

$GRSCRIPTS/helloworld.groovy

$ cd $GRSCRIPTS$ groovy helloworld.groovyHello Mongo!$

Page 17: Groovy scripts with Groovy

Hello World (Groovy style)

def world = new World(id: "mongo", name: "Mongo")println "Hello ${world.name}!"

class World { String id String name}

$GRSCRIPTS/helloworld.groovy

$ cd $GRSCRIPTS$ groovy helloworld.groovyHello Mongo!$

Page 18: Groovy scripts with Groovy

Closures / collectionsdef worlds = [ new World(id: "mongo", name: "Mongo"), new World(id: "mars", name: "Mars"), new World(id: "wonderland", name: "Wonderland")] as ArrayList

def heroesByWorld = [ mongo: ["Flash Gordon", "Prince Barin"], mars: ["John Carter"], wonderland: ["Alice", "Queen of Hearts"]]

heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } println "*** World: ${world.name}"

def heroList = worldEntry.value heroList.each { hero -> println hero }}

Page 19: Groovy scripts with Groovy

Closures / collectionsdef worlds = [ new World(id: "mongo", name: "Mongo"), new World(id: "mars", name: "Mars"), new World(id: "wonderland", name: "Wonderland")] as ArrayList

def heroesByWorld = [ mongo: ["Flash Gordon", "Prince Barin"], mars: ["John Carter"], wonderland: ["Alice", "Queen of Hearts"]]

heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } println "*** World: ${world.name}"

def heroList = worldEntry.value heroList.each { hero -> println hero }}

Page 20: Groovy scripts with Groovy

Closures / collectionsdef worlds = [ new World(id: "mongo", name: "Mongo"), new World(id: "mars", name: "Mars"), new World(id: "wonderland", name: "Wonderland")] as ArrayList

def heroesByWorld = [ mongo: ["Flash Gordon", "Prince Barin"], mars: ["John Carter"], wonderland: ["Alice", "Queen of Hearts"]]

heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } println "*** World: ${world.name}"

def heroList = worldEntry.value heroList.each { hero -> println hero }}

Page 21: Groovy scripts with Groovy

Closures / collectionsdef worlds = [ new World(id: "mongo", name: "Mongo"), new World(id: "mars", name: "Mars"), new World(id: "wonderland", name: "Wonderland")] as ArrayList

def heroesByWorld = [ mongo: ["Flash Gordon", "Prince Barin"], mars: ["John Carter"], wonderland: ["Alice", "Queen of Hearts"]]

heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } println "*** World: ${world.name}"

def heroList = worldEntry.value heroList.each { hero -> println hero }}

Page 22: Groovy scripts with Groovy

Closures / collectionsdef worlds = [ new World(id: "mongo", name: "Mongo"), new World(id: "mars", name: "Mars"), new World(id: "wonderland", name: "Wonderland")] as ArrayList

def heroesByWorld = [ mongo: ["Flash Gordon", "Prince Barin"], mars: ["John Carter"], wonderland: ["Alice", "Queen of Hearts"]]

heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } println "*** World: ${world.name}"

def heroList = worldEntry.value heroList.each { hero -> println hero }}

Page 23: Groovy scripts with Groovy

Functions and scope of variablesdef worlds = [ … ]def heroesByWorld = [ … ]

eachWorld { world, heroes -> println "*** World: ${world.name}" heroes.each { hero -> println hero }}

void eachWorld(Closure closure) { heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } def heroList = worldEntry.value closure(world, heroList) }}

Page 24: Groovy scripts with Groovy

Functions and scope of variablesdef worlds = [ … ]def heroesByWorld = [ … ]

eachWorld { world, heroes -> println "*** World: ${world.name}" heroes.each { hero -> println hero }}

void eachWorld(Closure closure) { heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } def heroList = worldEntry.value closure(world, heroList) }}

Page 25: Groovy scripts with Groovy

Functions and scope of variablesdef worlds = [ … ]def heroesByWorld = [ … ]

eachWorld { world, heroes -> println "*** World: ${world.name}" heroes.each { hero -> println hero }}

void eachWorld(Closure closure) { heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } def heroList = worldEntry.value closure(world, heroList) }}

Page 26: Groovy scripts with Groovy

Functions and scope of variablesdef worlds = [ … ]def heroesByWorld = [ … ]

eachWorld { world, heroes -> println "*** World: ${world.name}" heroes.each { hero -> println hero }}

void eachWorld(Closure closure) { heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } def heroList = worldEntry.value closure(world, heroList) }}

Page 27: Groovy scripts with Groovy

Functions and scope of variablesdef worlds = [ … ]def heroesByWorld = [ … ]

eachWorld { world, heroes -> println "*** World: ${world.name}" heroes.each { hero -> println hero }}

void eachWorld(Closure closure) { heroesByWorld.each { worldEntry -> def worldId = worldEntry.key def world = worlds.find { it.id == worldId } def heroList = worldEntry.value closure(world, heroList) }}

● worlds = [ … ]

● @Field def worlds = [ … ]

● @Field List<World> worlds = [ … ]

Page 28: Groovy scripts with Groovy

Grape: libraries from Maven repos@Grab(group='org.apache.commons', module='commons-email', version='1.3.3')

import org.apache.commons.mail.*

def usr, pwd, toAddress = [ … ]

println "Creating email object"Email email = new SimpleEmail( hostName: "smtp.googlemail.com", smtpPort: 465, authenticator: new DefaultAuthenticator(usr, pwd), SSLOnConnect: true, from: usr, subject: "Groovy mail!", msg: "You're hot and you know it ... :-)" )

email.addTo(toAddress);

println "Sending email..."email.send()println "OK"

Page 29: Groovy scripts with Groovy

<ivysettings> <settings defaultResolver="downloadGrapes"/> <resolvers> <chain name="downloadGrapes"> <filesystem name="cachedGrapes"> <ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/> <artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/> </filesystem> <ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/> <ibiblio name="ibiblio" m2compatible="true"/> <ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/> </chain> </resolvers></ivysettings>

Grape: default config

Page 30: Groovy scripts with Groovy

<ivysettings> <settings defaultResolver="downloadGrapes"/> <resolvers> <chain name="downloadGrapes"> <filesystem name="cachedGrapes"> <ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/> <artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/> </filesystem> <ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/> <ibiblio name="ibiblio" m2compatible="true"/> <ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/> </chain> </resolvers></ivysettings>

Grape: default config

Page 31: Groovy scripts with Groovy

<ivysettings> <settings defaultResolver="downloadGrapes"/> <resolvers> <chain name="downloadGrapes"> <filesystem name="cachedGrapes"> <ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/> <artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/> </filesystem> <ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/> <ibiblio name="ibiblio" m2compatible="true"/> <ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/> </chain> </resolvers></ivysettings>

Grape: default config

Page 32: Groovy scripts with Groovy

Grape: add your repository

<ivysettings> <settings defaultResolver="downloadGrapes"/>

<credentials host="nexus.xxx.xxx" realm="Sonatype Nexus Repository Manager" username="xxxx" passwd="xxxx"/> <property name="nexus-root" value="http://nexus.xxx.xxx/content/groups/public/"/>

<resolvers> <chain name="downloadGrapes"> <ibiblio name="nexus" root="${nexus-root}" m2compatible="true" /> (...) </chain> </resolvers></ivysettings>

Page 33: Groovy scripts with Groovy

Grape: add your repository

<ivysettings> <settings defaultResolver="downloadGrapes"/>

<credentials host="nexus.xxx.xxx" realm="Sonatype Nexus Repository Manager" username="xxxx" passwd="xxxx"/> <property name="nexus-root" value="http://nexus.xxx.xxx/content/groups/public/"/>

<resolvers> <chain name="downloadGrapes"> <ibiblio name="nexus" root="${nexus-root}" m2compatible="true" /> (...) </chain> </resolvers></ivysettings>

Page 34: Groovy scripts with Groovy

Grape: updatable snapshots

<ivysettings> <settings defaultResolver="downloadGrapes"/>

<credentials host="nexus.xxx.xxx" realm="Sonatype Nexus Repository Manager" username="xxxx" passwd="xxxx"/> <property name="nexus-root" value="http://nexus.xxx.xxx/content/groups/public/"/>

<resolvers> <ibiblio name="downloadGrapes" root="${nexus-root}" m2compatible="true" /> </resolvers></ivysettings>

Page 35: Groovy scripts with Groovy

Grape: updatable snapshots

<ivysettings> <settings defaultResolver="downloadGrapes"/>

<credentials host="nexus.xxx.xxx" realm="Sonatype Nexus Repository Manager" username="xxxx" passwd="xxxx"/> <property name="nexus-root" value="http://nexus.xxx.xxx/content/groups/public/"/>

<resolvers> <ibiblio name="downloadGrapes" root="${nexus-root}" m2compatible="true" /> </resolvers></ivysettings>

Page 36: Groovy scripts with Groovy

Databases: Sql object@Grab('mysql:mysql-connector-java')@GrabConfig(systemClassLoader=true)import groovy.sql.Sql

def sql = Sql.newInstance("jdbc:mysql://localhost:3306/simfonics_charging", "tuenti_developer", "lalala", "com.mysql.jdbc.Driver")sql.resultSetConcurrency = java.sql.ResultSet.CONCUR_UPDATABLE

def version = 2def newVersion = 3def type = "BUNDLEDEF"

sql.eachRow("""select * from charging_element_definition where version = ${version} and element_type = ${type}""" ) { row -> if (row.element_id.startsWith("PG0.")) { println "Bundle ${row.element_id} version ${row.version}" + " to ${newVersion}" row.version = newVersion }}

Page 37: Groovy scripts with Groovy

Databases: Sql object@Grab('mysql:mysql-connector-java')@GrabConfig(systemClassLoader=true)import groovy.sql.Sql

def sql = Sql.newInstance("jdbc:mysql://localhost:3306/simfonics_charging", "tuenti_developer", "lalala", "com.mysql.jdbc.Driver")sql.resultSetConcurrency = java.sql.ResultSet.CONCUR_UPDATABLE

def version = 2def newVersion = 3def type = "BUNDLEDEF"

sql.eachRow("""select * from charging_element_definition where version = ${version} and element_type = ${type}""" ) { row -> if (row.element_id.startsWith("PG0.")) { println "Bundle ${row.element_id} version ${row.version}" + " to ${newVersion}" row.version = newVersion }}

Page 38: Groovy scripts with Groovy

Databases: Sql object@Grab('mysql:mysql-connector-java')@GrabConfig(systemClassLoader=true)import groovy.sql.Sql

def sql = Sql.newInstance("jdbc:mysql://localhost:3306/simfonics_charging", "tuenti_developer", "lalala", "com.mysql.jdbc.Driver")sql.resultSetConcurrency = java.sql.ResultSet.CONCUR_UPDATABLE

def version = 2def newVersion = 3def type = "BUNDLEDEF"

sql.eachRow("""select * from charging_element_definition where version = ${version} and element_type = ${type}""" ) { row -> if (row.element_id.startsWith("PG0.")) { println "Bundle ${row.element_id} version ${row.version}" + " to ${newVersion}" row.version = newVersion }}

Page 39: Groovy scripts with Groovy

Databases: Sql object@Grab('mysql:mysql-connector-java')@GrabConfig(systemClassLoader=true)import groovy.sql.Sql

def sql = Sql.newInstance("jdbc:mysql://localhost:3306/simfonics_charging", "tuenti_developer", "lalala", "com.mysql.jdbc.Driver")sql.resultSetConcurrency = java.sql.ResultSet.CONCUR_UPDATABLE

def version = 2def newVersion = 3def type = "BUNDLEDEF"

sql.eachRow("""select * from charging_element_definition where version = ${version} and element_type = ${type}""" ) { row -> if (row.element_id.startsWith("PG0.")) { println "Bundle ${row.element_id} version ${row.version}" + " to ${newVersion}" row.version = newVersion }}

Page 40: Groovy scripts with Groovy

Script arguments: CliBuilder

def cli = new CliBuilder(usage:'simpleHtmlServer -p PORT -d DIRECTORY')cli.with { h longOpt:'help', 'Usage information' p longOpt:'port',argName:'port', args:1, type:Number.class,'Def is 8080' d longOpt:'dir', argName:'directory', args:1, 'Default is .'} def opts = cli.parse(args)if(!opts) returnif(opts.help) { cli.usage() return}

def directory = opts.ddef port = opts.port(...)

Page 41: Groovy scripts with Groovy

Script arguments: CliBuilder

def cli = new CliBuilder(usage:'simpleHtmlServer -p PORT -d DIRECTORY')cli.with { h longOpt:'help', 'Usage information' p longOpt:'port',argName:'port', args:1, type:Number.class,'Def is 8080' d longOpt:'dir', argName:'directory', args:1, 'Default is .'} def opts = cli.parse(args)if(!opts) returnif(opts.help) { cli.usage() return}

def directory = opts.ddef port = opts.port(...)

Page 42: Groovy scripts with Groovy

Script arguments: CliBuilder

def cli = new CliBuilder(usage:'simpleHtmlServer -p PORT -d DIRECTORY')cli.with { h longOpt:'help', 'Usage information' p longOpt:'port',argName:'port', args:1, type:Number.class,'Def is 8080' d longOpt:'dir', argName:'directory', args:1, 'Default is .'} def opts = cli.parse(args)if(!opts) returnif(opts.help) { cli.usage() return}

def directory = opts.ddef port = opts.port(...)

Page 43: Groovy scripts with Groovy

Create your own utility classes

Page 44: Groovy scripts with Groovy

Grapes in reusable files

import utils.*

PlatformLibs.load()

(...)

package utils

@Grab('commons-logging:commons-logging:1.1.3')@Grab('org.apache.logging.log4j:log4j-api:2.1')@Grab('...')(...)

class PlatformLibs { static void load() {}}

(Script) utils/PlatformLibs.groovy

Page 45: Groovy scripts with Groovy

“Clean” Services Clients

import utils.*

TServiceClient subscriptionService = new TServiceClient( base: "http://xxxxx/SubscriptionService/")

def statusData = subscriptionService.getSubscriptionStatus([id: 80644970])

println "Result of the call: ${statusData}"println "Subscription status: ${statusData.status}"

● Generic, equivalent to CURLs

● Using dynamic Groovy features

● Methods of the service are used transparently as if it were a “real” client interface

Page 46: Groovy scripts with Groovy

“Clean” clients trick@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7')(...)class TServiceClient {

(...) def methodMissing(String name, args) { def jsonResult = jsonCall(name, args)

(...) }

String jsonCall(String name, args) { def http = getHttpClient() def json = http.request(POST, JSON) { req -> body = [ "jsonrpc": "2.0", "id": callId, "method": interface + "." + version + "." + name, "params": [ "params": args, "gid": gid, "rid": rid ] ] } return json }}

Page 47: Groovy scripts with Groovy

“Clean” clients trick@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7')(...)class TServiceClient {

(...) def methodMissing(String name, args) { def jsonResult = jsonCall(name, args)

(...) }

String jsonCall(String name, args) { def http = getHttpClient() def json = http.request(POST, JSON) { req -> body = [ "jsonrpc": "2.0", "id": callId, "method": interface + "." + version + "." + name, "params": [ "params": args, "gid": gid, "rid": rid ] ] } return json }}

Page 48: Groovy scripts with Groovy

Classes for named access to the environment

import utils.*import groovy.sql.*

def chargingService = TuentiEnv.jsc.prod.chargingdef balanceData = chargingService.getBalance([id: 80644970], "es")

Sql chargingDb = TuentiEnv.jsc.prod.charging.sql

● Easy named access to:

o Databases

o Service clients

o For every environment

Page 49: Groovy scripts with Groovy

Environment helperpackage utils

@GrabConfig(systemClassLoader=true, initContextClassLoader=true)@Grab('mysql:mysql-connector-java')@GrabExclude('xml-apis:xml-apis')import groovy.sql.Sql

class TuentiEnv {(... properties with common configuration ...)

static void initConsole() { Object.metaClass.tu = TuentiEnv.metaClass Object.metaClass.sim = TuentiEnv.simfonics Object.metaClass.jsc = TuentiEnv.jsc (...)

Object.metaClass.pretty = { obj ->(new groovy.json.JsonBuilder(obj)).toPrettyString() } Object.metaClass.tservice = { String base, String

iface = null -> return new TServiceClient(base: base,

iface: iface) } }}

Page 50: Groovy scripts with Groovy

Environment helperpackage utils

@GrabConfig(systemClassLoader=true, initContextClassLoader=true)@Grab('mysql:mysql-connector-java')@GrabExclude('xml-apis:xml-apis')import groovy.sql.Sql

class TuentiEnv {(... properties with common configuration ...)

static void initConsole() { Object.metaClass.tu = TuentiEnv.metaClass Object.metaClass.sim = TuentiEnv.simfonics Object.metaClass.jsc = TuentiEnv.jsc (...)

Object.metaClass.pretty = { obj ->(new groovy.json.JsonBuilder(obj)).toPrettyString() } Object.metaClass.tservice = { String base, String

iface = null -> return new TServiceClient(base: base,

iface: iface) } }}

Page 51: Groovy scripts with Groovy

Environment helperpackage utils

@GrabConfig(systemClassLoader=true, initContextClassLoader=true)@Grab('mysql:mysql-connector-java')@GrabExclude('xml-apis:xml-apis')import groovy.sql.Sql

class TuentiEnv {(... properties with common configuration ...)

static void initConsole() { Object.metaClass.tu = TuentiEnv.metaClass Object.metaClass.sim = TuentiEnv.simfonics Object.metaClass.jsc = TuentiEnv.jsc (...)

Object.metaClass.pretty = { obj ->(new groovy.json.JsonBuilder(obj)).toPrettyString() } Object.metaClass.tservice = { String base, String

iface = null -> return new TServiceClient(base: base,

iface: iface) } }}

Page 52: Groovy scripts with Groovy

Services Console: easily test your services

aviedma@dev6:~$ groovysh

Groovy Shell (2.2.2, JVM: 1.6.0_26)Type ':help' or ':h' for help.---------------------------------------------------------------------groovy:000> utils.TuentiEnv.initConsole()===> nullgroovy:000> jsc.prod.charging.getBalance([id: 80644970], "es")===> [amount:[amountInMillieuros:0], isAvailable:true]groovy:000> pretty jsc.prod.subscription.getSubscriptionStatus([id: 80644970])===> { "isAvailable": true, "lastUpdateTime": 1423501862, "status": "active"}groovy:000>

Page 53: Groovy scripts with Groovy

Services Console: easily test your services

aviedma@dev6:~$ groovysh

Groovy Shell (2.2.2, JVM: 1.6.0_26)Type ':help' or ':h' for help.---------------------------------------------------------------------groovy:000> utils.TuentiEnv.initConsole()===> nullgroovy:000> jsc.prod.charging.getBalance([id: 80644970], "es")===> [amount:[amountInMillieuros:0], isAvailable:true]groovy:000> pretty jsc.prod.subscription.getSubscriptionStatus([id: 80644970])===> { "isAvailable": true, "lastUpdateTime": 1423501862, "status": "active"}groovy:000>

Page 54: Groovy scripts with Groovy

Services Console: easily test your services

aviedma@dev6:~$ groovysh

Groovy Shell (2.2.2, JVM: 1.6.0_26)Type ':help' or ':h' for help.---------------------------------------------------------------------groovy:000> utils.TuentiEnv.initConsole()===> nullgroovy:000> jsc.prod.charging.getBalance([id: 80644970], "es")===> [amount:[amountInMillieuros:0], isAvailable:true]groovy:000> pretty jsc.prod.subscription.getSubscriptionStatus([id: 80644970])===> { "isAvailable": true, "lastUpdateTime": 1423501862, "status": "active"}groovy:000>

Page 55: Groovy scripts with Groovy

Tracking scripts execution

import utils.*

TuScript.track("Say hello to the world”)

println "Hello world!"(...)

● A single line at the beginning of the script

o Logs start-end time and duration of the run (even if it fails or is killed)

o Without changes in the scripts, it can be used to register the script execution for monitoring

Page 56: Groovy scripts with Groovy

Tracking scripts executionclass TuScript { public static void track(String description) { if (metadata != null) { finishCurrentScript() } else { addShutdownHook { finishCurrentScript() } captureSignal("INT") captureSignal("TERM") } metadata = new ScriptMetadata(description: description) logScriptStart() } public static void finishCurrentScript() { if (metadata != null) {

logScriptEnd() } metadata = null }

private static void captureSignal(String signal) { def oldHandler = Signal.handle(new Signal(signal), [handle: { sig -> logSignal(signal) if (oldHandler) oldHandler.handle(sig) }] as SignalHandler); } (...)

Page 57: Groovy scripts with Groovy

Tracking scripts executionclass TuScript { public static void track(String description) { if (metadata != null) { finishCurrentScript() } else { addShutdownHook { finishCurrentScript() } captureSignal("INT") captureSignal("TERM") } metadata = new ScriptMetadata(description: description) logScriptStart() } public static void finishCurrentScript() { if (metadata != null) {

logScriptEnd() } metadata = null }

private static void captureSignal(String signal) { def oldHandler = Signal.handle(new Signal(signal), [handle: { sig -> logSignal(signal) if (oldHandler) oldHandler.handle(sig) }] as SignalHandler); } (...)

Page 58: Groovy scripts with Groovy

Tracking scripts executionclass TuScript { public static void track(String description) { if (metadata != null) { finishCurrentScript() } else { addShutdownHook { finishCurrentScript() } captureSignal("INT") captureSignal("TERM") } metadata = new ScriptMetadata(description: description) logScriptStart() } public static void finishCurrentScript() { if (metadata != null) {

logScriptEnd() } metadata = null }

private static void captureSignal(String signal) { def oldHandler = Signal.handle(new Signal(signal), [handle: { sig -> logSignal(signal) if (oldHandler) oldHandler.handle(sig) }] as SignalHandler); } (...)

Page 59: Groovy scripts with Groovy

Split execution in stepssql.eachRow("""

<loooooong SQL> """) { row -> processRow(row)}

void processRow(row) { println "${row.id}: ${row.name} ${row.surname}" (... lots and lots of processing ...)}

Page 60: Groovy scripts with Groovy

Split execution in stepssql.eachRow("""

<loooooong SQL> """) { row -> processRow(row)}

void processRow(row) { println "${row.id}: ${row.name} ${row.surname}" (... lots and lots of processing ...)}

Page 61: Groovy scripts with Groovy

Split execution in stepsvoid step1(String file) { Dump dump = new Dump(file) dump.withWriter(fieldNames) { out -> sql.eachRow(""" <loooooong SQL> """) { row -> out.insert(row) } }}

void step2(String file) { Dump dump = new Dump(file) dump.eachRow { out -> processRow(row) }}

void processRow(row) { println "${row.id}: ${row.name} ${row.surname}" (... lots and lots of processing ...)}

Page 62: Groovy scripts with Groovy

Split execution in stepsvoid step1(String file) { Dump dump = new Dump(file) dump.withWriter(fieldNames) { out -> sql.eachRow(""" <loooooong SQL> """) { row -> out.insert(row) } }}

void step2(String file) { Dump dump = new Dump(file) dump.eachRow { out -> processRow(row) }}

void processRow(row) { println "${row.id}: ${row.name} ${row.surname}" (... lots and lots of processing ...)}

Page 63: Groovy scripts with Groovy

Split execution in stepsvoid step1(String file) { Dump dump = new Dump(file) dump.withWriter(fieldNames) { out -> sql.eachRow(""" <loooooong SQL> """) { row -> out.insert(row) } }}

void step2(String file) { Dump dump = new Dump(file) dump.eachRow { out -> processRow(row) }}

void processRow(row) { println "${row.id}: ${row.name} ${row.surname}" (... lots and lots of processing ...)}

Same processing code, no changes needed

Page 64: Groovy scripts with Groovy

Running Shell commandsdef process = 'ls /home/andres'.execute()def procOutput = new InputStreamReader(process.in)procOutput.eachLine { line -> println line}process.waitFor()println "** Return code: ${process.exitValue()}"

Page 65: Groovy scripts with Groovy

Running Shell commandsdef process = 'ls /home/andres'.execute()def procOutput = new InputStreamReader(process.in)procOutput.eachLine { line -> println line}process.waitFor()println "** Return code: ${process.exitValue()}"

Page 66: Groovy scripts with Groovy

Running Shell commandsdef process = 'ls /home/andres'.execute()def procOutput = new InputStreamReader(process.in)procOutput.eachLine { line -> println line}process.waitFor()println "** Return code: ${process.exitValue()}"

def process = 'echo "Hola caracola"'.execute()println process.text

def process = ['echo', 'Hola caracola'].execute()

Page 67: Groovy scripts with Groovy

Running Shell commandsdef process = 'ls /home/andres'.execute()def procOutput = new InputStreamReader(process.in)procOutput.eachLine { line -> println line}process.waitFor()println "** Return code: ${process.exitValue()}"

def process = 'echo "Hola caracola"'.execute()println process.text

def process = ['echo', 'Hola caracola'].execute()

def process = 'ls /home/andres/*'.execute()

def process = ['sh', '-c', 'ls /home/andres/*'].execute()

Page 68: Groovy scripts with Groovy

Running Shell commandsdef process = 'ls /home/andres'.execute()def procOutput = new InputStreamReader(process.in)procOutput.eachLine { line -> println line}process.waitFor()println "** Return code: ${process.exitValue()}"

def process = 'echo "Hola caracola"'.execute()println process.text

def process = ['echo', 'Hola caracola'].execute()

def process = 'ls /home/andres/*'.execute()

def process = ['sh', '-c', 'ls /home/andres/*'].execute()

def process = 'ls'.execute()

def process = 'ls'.execute([], new File('/home/andres'))

Page 69: Groovy scripts with Groovy

Running Shell commandsclass Shell { File currentDir = new File('.') final Map environment = [:] Process run(String command) { return ['sh', '-c', command].execute( environment.collect { "${it.key}=${it.value}" }, currentDir) } String runAndGet(String command) { def proc = run(command) proc.waitFor() return proc.text }}

Shell shell = new Shell(currentDir: new File("/home/andres/temp"))shell.environment["GREETINGS"] = "Hi!"

print shell.runAndGet('echo $GREETINGS')print shell.runAndGet("ls i*")print shell.runAndGet('echo "Hola caracola"')

Page 70: Groovy scripts with Groovy

Running Shell commandsclass Shell { File currentDir = new File('.') final Map environment = [:] Process run(String command) { return ['sh', '-c', command].execute( environment.collect { "${it.key}=${it.value}" }, currentDir) } String runAndGet(String command) { def proc = run(command) proc.waitFor() return proc.text }}

Shell shell = new Shell(currentDir: new File("/home/andres/temp"))shell.environment["GREETINGS"] = "Hi!"

print shell.runAndGet('echo $GREETINGS')print shell.runAndGet("ls i*")print shell.runAndGet('echo "Hola caracola"')

Page 71: Groovy scripts with Groovy

Thanks!

Questions?