groovy scripts with groovy
Post on 14-Jul-2015
547 Views
Preview:
TRANSCRIPT
by Andrés Viedma
scripts with
Restless Java lover
Software dinosaurmore than 20 years nagging
Working at
Usual suspect of MadridGUG and MadridJUG
Arquitecture at
Service DB
TService
TuentiNgDBs
tuenti-ng
Micro serviceTService
Micro serviceTService
Micro serviceTService
Arquitecture at
Service DB
TService
TuentiNgDBs
tuenti-ng
Micro serviceTService
Micro serviceTService
Micro serviceTService
PHP Script
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
Arquitecture at
Service DB
TService
TuentiNgDBs
tuenti-ng
Micro serviceTService
Micro serviceTService
Micro serviceTService
Arquitecture at
Service DB
TService
TuentiNgDBs
tuenti-ng
Micro serviceTService
Micro serviceTService
Micro serviceTService
Groovy Script
Arquitecture at
Service DB
TService
TuentiNgDBs
tuenti-ng
Micro serviceTService
Micro serviceTService
Micro serviceTService
Groovy Script
Mix your Production code with direct accesses to the
DB, config, TServices...
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
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!$
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!$
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!$
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!$
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 }}
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 }}
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 }}
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 }}
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 }}
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) }}
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) }}
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) }}
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) }}
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 = [ … ]
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"
<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
<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
<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
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>
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>
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>
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>
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 }}
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 }}
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 }}
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 }}
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(...)
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(...)
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(...)
Create your own utility classes
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
“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
“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 }}
“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 }}
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
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) } }}
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) } }}
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) } }}
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>
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>
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>
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
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); } (...)
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); } (...)
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); } (...)
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 ...)}
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 ...)}
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 ...)}
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 ...)}
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
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()}"
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()}"
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()
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()
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'))
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"')
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"')
Thanks!
Questions?
top related