Groovy scripts with Groovy

Download Groovy scripts with Groovy

Post on 14-Jul-2015

485 views

Category:

Software

3 download

Embed Size (px)

TRANSCRIPT

  • by Andrs 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 librarieso Can use the code of our Java services

    Source code almost compatible with Javao Main difference: == operator means equals()o If you make your script in Java, itll 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 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"

  • Grape: default config

  • Grape: default config

  • Grape: default config

  • Grape: add your repository

    (...)

  • Grape: add your repository

    (...)

  • Grape: updatable snapshots

  • Grape: updatable snapshots

  • Databases: Sql object@Grab('mysql:mysql-connector-java')@GrabConfig(systemClassLoader=true)import groovy.sql.Sqldef 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.Sqldef 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.Sqldef 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.Sqldef 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: CliBuilderdef 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: CliBuilderdef 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: CliBuilderdef 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.ch...