ninja tricks for groovy system scripting for javaland 2016

101
01

Upload: andrey-adamovich

Post on 07-Apr-2017

1.913 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Ninja tricks for groovy system scripting for JavaLand 2016

01

Page 2: Ninja tricks for groovy system scripting for JavaLand 2016

About me02

Page 3: Ninja tricks for groovy system scripting for JavaLand 2016

Andrey AdamovichBio: Developer, coach, speaker, author

Company: Aestas/IT (http://aestasit.com)

E­mail: [email protected]

Linkedin: http://www.linkedin.com/in/andreyadamovich

Lanyrd: http://lanyrd.com/profile/andrey­adamovich

GitHub: https://github.com/aadamovich

SO: http://stackoverflow.com/users/162792/andrey­adamovich

Twitter: @codingandrey, @aestasit

••••••••

03

Page 4: Ninja tricks for groovy system scripting for JavaLand 2016

Exposed to operationsMaintenance scripts (backup, cleaning, monitoring)

Scheduled/CRON jobs (transfers, conversions, notifications)

Automation tasks (deployment, packaging, testing)

Web applications (status pages, back doors, dashboards)

••••

04

Page 5: Ninja tricks for groovy system scripting for JavaLand 2016

Why Groovy?05

Page 6: Ninja tricks for groovy system scripting for JavaLand 2016

Native system scriptingBash, Dash, Zsh, Fish, Csh etc.

Bat, Cmd and, eventually, PowerShell (PoSH)••

06

Page 7: Ninja tricks for groovy system scripting for JavaLand 2016

Arrays in BAT?

07

Page 8: Ninja tricks for groovy system scripting for JavaLand 2016

BASH vs. PoSH

08

Page 9: Ninja tricks for groovy system scripting for JavaLand 2016

Scripting languagesPerl

Python

Ruby

Lua

Javascript

...

••••••

09

Page 10: Ninja tricks for groovy system scripting for JavaLand 2016

Multi­platformsupport

10

Page 11: Ninja tricks for groovy system scripting for JavaLand 2016

Does it workon Windows?

11

Page 12: Ninja tricks for groovy system scripting for JavaLand 2016

Operationalsimplicity

12

Page 13: Ninja tricks for groovy system scripting for JavaLand 2016

Maintainablecode

13

Page 14: Ninja tricks for groovy system scripting for JavaLand 2016

Stableecosystem14

Page 15: Ninja tricks for groovy system scripting for JavaLand 2016

Richextensionlibrary

15

Page 16: Ninja tricks for groovy system scripting for JavaLand 2016

Groovy is just a JAR

16

Page 17: Ninja tricks for groovy system scripting for JavaLand 2016

Reuse JVMknowledge17

Page 18: Ninja tricks for groovy system scripting for JavaLand 2016

sdkman.io

18

Page 19: Ninja tricks for groovy system scripting for JavaLand 2016

sdkman.iocurl ‐s http://get.sdkman.io | bash

sdk install groovy 2.4.6

sdk default groovy 2.4.6

sdk list groovy

01.

02.

03.

04.

19

Page 20: Ninja tricks for groovy system scripting for JavaLand 2016

PoSH GVM> posh‐gvm.psm1 cannot be loaded 

> because the execution of scripts 

> is disabled on this system.

01.

02.

03.

20

Page 21: Ninja tricks for groovy system scripting for JavaLand 2016

Speed up!21

Page 22: Ninja tricks for groovy system scripting for JavaLand 2016

GroovyServ

22

Page 23: Ninja tricks for groovy system scripting for JavaLand 2016

Files,directories,and otheranimals23

Page 24: Ninja tricks for groovy system scripting for JavaLand 2016

Readingf = new File('test.txt')

String textContent = f.text

byte[] binaryContent = file.bytes

01.

02.

03.

24

Page 25: Ninja tricks for groovy system scripting for JavaLand 2016

Writing If << 'hello, this is a test file'

f.text = new URL('http://server/my_data.json').text

file.bytes = [ 65, 66, 67, 68 ] as byte[]

01.

02.

03.

25

Page 26: Ninja tricks for groovy system scripting for JavaLand 2016

Writing IIfile.text = '''What's in a name? That which we call a rose

By any other name would smell as sweet.'''

file << 'What\'s in a name? That which we call a rose\n'

file << 'By any other name would smell as sweet.'

01.

02.

03.04.

05.

26

Page 27: Ninja tricks for groovy system scripting for JavaLand 2016

Writing IIIfile.withWriter { Writer writer ‐>

  writer << 'What\'s in a name? That which we call a rose\n'

  writer << 'By any other name would smell as sweet.'

}

file.withOutputStream { OutputStream stream ‐>

  stream << 'What\'s in a name? That which we call a rose\n'

  stream << 'By any other name would smell as sweet.'

}

01.

02.

03.

04.

05.06.

07.

08.

09.

27

Page 28: Ninja tricks for groovy system scripting for JavaLand 2016

Line­by­linedef lines = f.readLines()

lines.each { String line ‐>

  println line

}

01.

02.

03.

04.

28

Page 29: Ninja tricks for groovy system scripting for JavaLand 2016

eachLine and eachBytef.eachLine { String line ‐>

  println line

}

file.eachByte { int b ‐>

  ...

}

01.

02.

03.

04.

05.

06.

29

Page 30: Ninja tricks for groovy system scripting for JavaLand 2016

Filtering IoutputFile.withPrintWriter { writer ‐>

  inputFile.eachLine { line ‐>

    if (!line.startsWith('#')) {

      writer.println(line)

    }

  }

}

01.

02.

03.

04.

05.

06.

07.

30

Page 31: Ninja tricks for groovy system scripting for JavaLand 2016

Filtering IIinputFile.filterLine(outputFile.newWriter()) { line ‐>

  !line.startsWith('#')

}

01.

02.

03.

31

Page 32: Ninja tricks for groovy system scripting for JavaLand 2016

Filtering IIIoutputFile.withWriter { Writer writer ‐>

  inputFile.withReader { Reader reader ‐>

    reader.transformLine(writer) { String line ‐>

      line.replaceAll('\t', '  ')

    }

  }

}

01.

02.

03.

04.

05.

06.

07.

32

Page 33: Ninja tricks for groovy system scripting for JavaLand 2016

Filtering IVinputFile.withReader { reader ‐>

  reader.transformLine(outputFile.newWriter()) { line ‐>

    line.replaceAll('\t', '  ')

  }

}

01.

02.

03.

04.

05.

33

Page 34: Ninja tricks for groovy system scripting for JavaLand 2016

Filtering VoutputFile.text = inputFile.text.replaceAll('\t', '  ')01.

34

Page 35: Ninja tricks for groovy system scripting for JavaLand 2016

Walking thepath

35

Page 36: Ninja tricks for groovy system scripting for JavaLand 2016

eachFile and eachDirf.eachFile { File file ‐>

  ...

}

f.eachDir { File dir ‐>

  ...

}

01.

02.

03.

04.

05.

06.

36

Page 37: Ninja tricks for groovy system scripting for JavaLand 2016

Recursive walking IcurrentDir.eachFileRecurse { File file ‐>

  println file.name

}

currentDir.eachDirRecurse { File dir ‐>

  println dir.name

}

01.

02.

03.

04.

05.

06.

37

Page 38: Ninja tricks for groovy system scripting for JavaLand 2016

Recursive walking IIcurrentDir.traverse { File file ‐>

  if (file.name.endsWith('.groovy')) {

    println file.name

  }

}

01.

02.

03.

04.

05.

38

Page 39: Ninja tricks for groovy system scripting for JavaLand 2016

Recursive walking IIIcurrentDir.traverse(nameFilter: ~/.*\.groovy/) { File file ‐>

  println file.name

}

01.

02.

03.

39

Page 40: Ninja tricks for groovy system scripting for JavaLand 2016

Recursive walking IVimport static groovy.io.FileType.*

...

currentDir.traverse(

  type: FILES,

  nameFilter: ~/.*\.groovy/,

  excludeNameFilter: ~/^C.*$/) { File file ‐>

    println file.name

}

01.

02.

03.

04.

05.

06.

07.

08.

40

Page 41: Ninja tricks for groovy system scripting for JavaLand 2016

Extending File IFile.metaClass.safeDelete = {

  if (exists()) {

    if (isDirectory()) {

      if (!deleteDir()) {

        def msg = "Unable to delete a directory: ${name}"

        throw new IOException(msg)

      }

    ...

01.

02.

03.

04.

05.

06.

07.

08.

41

Page 42: Ninja tricks for groovy system scripting for JavaLand 2016

Extending File II    ...

    } else {

      if (!delete()) {

        def msg = "Unable to delete a file: ${name}"

        throw new IOException(msg)

      }

    }

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09. 42

Page 43: Ninja tricks for groovy system scripting for JavaLand 2016

Extending File IIIFile f = new File('test.txt')

f.safeDelete()

File d = new File('test_dir')

d.safeDelete()

01.

02.

03.

04.

43

Page 44: Ninja tricks for groovy system scripting for JavaLand 2016

Base script44

Page 45: Ninja tricks for groovy system scripting for JavaLand 2016

Base script IBaseScript.groovy :

abstract class BaseScript extends Script {

  static {

    File.metaClass.safeDelete = {

      if (exists()) {

        ...

  }

}

01.

02.

03.

04.

05.

06.

07.

45

Page 46: Ninja tricks for groovy system scripting for JavaLand 2016

Base script IIdelete.groovy :

new File('idonotexist.txt').safeDelete()01.

46

Page 47: Ninja tricks for groovy system scripting for JavaLand 2016

Base script IIIgroovy ‐b BaseScript delete.groovy01.

47

Page 48: Ninja tricks for groovy system scripting for JavaLand 2016

Externalcommands48

Page 49: Ninja tricks for groovy system scripting for JavaLand 2016

External commands Idef exitValue = "ls ‐l".execute().exitValue()

if (!exitValue) {

  println "Command failed with exit code: ${exitValue}"

}

01.

02.

03.

04.

49

Page 50: Ninja tricks for groovy system scripting for JavaLand 2016

External commands IIprintln "ls".execute().text()

println "ls".execute().inputStream.eachLine { println it }

"grep abc".execute().waitForOrKill(1000)

01.

02.

03.

50

Page 51: Ninja tricks for groovy system scripting for JavaLand 2016

External commands IIIProcess process = "command".execute()   

def out = new StringBuffer()

def err = new StringBuffer()

process.waitForProcessOutput(out, err)

01.

02.

03.

04.

51

Page 52: Ninja tricks for groovy system scripting for JavaLand 2016

External commands IV"less temp.txt".execute().pipeTo("grep error".execute()).text

def proc1 = "less temp.txt".execute()

def proc2 = "grep error".execute()

proc1 | proc2

println proc2.text

01.

02.

03.

04.

05.

52

Page 53: Ninja tricks for groovy system scripting for JavaLand 2016

Arguments53

Page 54: Ninja tricks for groovy system scripting for JavaLand 2016

CliBuilderdef cli = new CliBuilder(usage:'ls')

cli.a('display all files')

cli.l('use a long listing format')

cli.t('sort by modification time')

def options = cli.parse(args)

01.

02.

03.

04.

05.

54

Page 55: Ninja tricks for groovy system scripting for JavaLand 2016

Defensivescripting

55

Page 56: Ninja tricks for groovy system scripting for JavaLand 2016

Do you likeNPEs?

56

Page 57: Ninja tricks for groovy system scripting for JavaLand 2016

Even simple things can cause NPEJava:

System.out.println(user.

                     getAddress().

                     getCity())

Groovy:

println user.

          address.

            city

01.

02.

03.

01.

02.

03. 57

Page 58: Ninja tricks for groovy system scripting for JavaLand 2016

Safe navigation operator (?.)println user?.

          address?.

            city 

01.

02.

03.

58

Page 59: Ninja tricks for groovy system scripting for JavaLand 2016

Elvis operator (?:)println user?.

         address?.

           city ?: "No idea"

01.

02.

03.

59

Page 60: Ninja tricks for groovy system scripting for JavaLand 2016

Closures forDSLs

60

Page 61: Ninja tricks for groovy system scripting for JavaLand 2016

Imaginary DSLtransaction {

  request {

    id     = '2L'

    name   = 'PUT'

    amount = 25

  }

  request {

    ...

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.61

Page 62: Ninja tricks for groovy system scripting for JavaLand 2016

DSL: transaction() methoddef transaction(Closure cl) {

  def processor = new RequestProcessor()

  try {

    processor.init()

    cl.delegate = processor

    cl()

    sendRequests()

  } finally {

    processor.cleanup()

}}

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.62

Page 63: Ninja tricks for groovy system scripting for JavaLand 2016

DSL: request() methodclass RequestProcessor {

  def requests = []

  def request(Closure cl) {

    def request = new Request()

    requests << request

    cl.delegate = request

    cl()

  }

  ...

01.

02.

03.

04.

05.

06.

07.

08.

09. 63

Page 64: Ninja tricks for groovy system scripting for JavaLand 2016

DSL: Request structureclass Request {

  String id

  String name

  String amount 

}

01.

02.

03.

04.

05.

64

Page 65: Ninja tricks for groovy system scripting for JavaLand 2016

Datamanipulation

65

Page 66: Ninja tricks for groovy system scripting for JavaLand 2016

XMLimport groovy.util.XmlSlurper

def xmlSource = new File('shakespeare.xml')

def bibliography = new XmlSlurper().parse(xmlSource)

println bibliography.author

bibliography.play

              .findAll { it.year.toInteger() > 1592 }

              .each { println it.title }

01.

02.

03.

04.

05.

06.

07.

66

Page 67: Ninja tricks for groovy system scripting for JavaLand 2016

JSONimport groovy.json.JsonSlurper

def reader = new FileReader('ui.json')

def ui = new JsonSlurper().parse(reader)

ui.items.each { println it.type }

println ui.items[0]

          .axes

          .find {

            it.fields.contains('y')

          }.title

01.

02.

03.

04.

05.

06.

07.

08.

09. 67

Page 68: Ninja tricks for groovy system scripting for JavaLand 2016

Grab yourstuff!

68

Page 69: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: import@Grab('org.apache.httpcomponents:httpclient:4.2.1')

import org.apache.http.impl.client.DefaultHttpClient

import org.apache.http.client.methods.HttpGet

01.

02.

03.

69

Page 70: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: variable@Grab('org.apache.httpcomponents:httpclient:4.2.1')

def httpClient =

  new org.apache.http.impl.client.DefaultHttpClient()

01.

02.

03.

70

Page 71: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: method@Grab('org.apache.httpcomponents:httpclient:4.2.1')

def getHttpClient() {

  new org.apache.http.impl.client.DefaultHttpClient()

}

01.

02.

03.

04.

71

Page 72: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: class@Grab('org.apache.httpcomponents:httpclient:4.2.1')

class Searcher {

  def httpClient

  Searcher() {

    httpClient =

      new org.apache.http.impl.client.DefaultHttpClient()

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

72

Page 73: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: multiple@Grapes([

   @Grab('org.apache.httpcomponents:httpclient:4.2.1'),

   @Grab('org.ccil.cowan.tagsoup:tagsoup:1.2')])

class Searcher { ... }

01.

02.

03.

04.

73

Page 74: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: repository@GrabResolver(name='codehaus',

              root='http://repository.codehaus.org/')

class Searcher { ... }

01.

02.

03.

74

Page 75: Ninja tricks for groovy system scripting for JavaLand 2016

@Grab: exclude@GrabExclude(group='commons‐codec',

             module='commons‐codec')

class Searcher { ... }

01.

02.

03.

75

Page 76: Ninja tricks for groovy system scripting for JavaLand 2016

HTTP76

Page 77: Ninja tricks for groovy system scripting for JavaLand 2016

HTTPBuilder: import@Grab(

  group='org.codehaus.groovy.modules.http‐builder',

  module='http‐builder',

  version='0.6'

)

import groovyx.net.http.*

01.

02.

03.

04.

05.

06.

77

Page 78: Ninja tricks for groovy system scripting for JavaLand 2016

HTTPBuilder: instantiationdef baseUrl = 'http://api.duckduckgo.com'

def queryString = 'q=groovy&format=json&pretty=1'

def http = new HTTPBuilder(baseUrl)

01.

02.

03.

78

Page 79: Ninja tricks for groovy system scripting for JavaLand 2016

HTTPBuilder: requesthttp.request(Method.POST) {

  send ContentType.URLENC, queryString

  response.success = { response, reader ‐>

    println response.statusLine

    println reader.text

  }

  response.failure = { response ‐>

    println response.statusLine

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.79

Page 80: Ninja tricks for groovy system scripting for JavaLand 2016

SQL80

Page 81: Ninja tricks for groovy system scripting for JavaLand 2016

SQL: settingsimport groovy.sql.Sql

def dbSettings = [

  url: 'jdbc:hsqldb:hsql://localhost/cookingdb',

  driver: 'org.hsqldb.jdbcDriver',

  user: 'sa',

  password: ''

]

01.

02.03.

04.

05.

06.

07.

08.

81

Page 82: Ninja tricks for groovy system scripting for JavaLand 2016

SQL: querydef sql = Sql.newInstance(dbSettings)

sql.eachRow('SELECT * FROM COOKBOOK') { cookbook ‐>

  printf '%‐20s%s\n',

         cookbook.id,

         cookbook[1]

}

01.

02.03.

04.

05.

06.

07.

82

Page 83: Ninja tricks for groovy system scripting for JavaLand 2016

Groovy as a server (GaaS?)> groovy ‐l 4444 ‐e "println new Date()" &

> telnet localhost 4444

hey groovy give me the date

Wed Feb 04 10:03:23 EET 2015

01.

02.

03.

04.

83

Page 84: Ninja tricks for groovy system scripting for JavaLand 2016

Ratpack84

Page 85: Ninja tricks for groovy system scripting for JavaLand 2016

Ratpack: import@Grab("io.ratpack:ratpack‐groovy:1.1.1")

import static ratpack.groovy.Groovy.ratpack

01.

02.

85

Page 86: Ninja tricks for groovy system scripting for JavaLand 2016

Ratback: script bodyratpack {

  handlers {

    get {

      response.send "This is the app root (try: /date)"

    }

    get("date") {

      response.send new Date().toString()

    }

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.86

Page 87: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr87

Page 88: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: import@Grab(

  group='com.aestasit.infrastructure.sshoogr',

  module='sshoogr',

  version='0.9.16')

import static com.aestasit.ssh.DefaultSsh.*

01.

02.

03.

04.

05.

88

Page 89: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: defaultsdefaultUser    = 'root'

defaultKeyFile = new File('secret.pem')

execOptions {

  verbose      = true

  showCommand  = true

}

01.

02.

03.

04.

05.

06.

89

Page 90: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: connectionremoteSession {

  url = 'user2:654321@localhost:2222'

  exec 'rm ‐rf /tmp/*'

  exec 'touch /var/lock/my.pid'

  remoteFile('/var/my.conf').text = "enabled=true"

}

01.

02.

03.

04.

05.

06.

90

Page 91: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: multi­line contentremoteFile('/etc/yum.repos.d/puppet.repo').text = '''

  [puppet]

  name=Puppet Labs Packages

  baseurl=http://yum.puppetlabs.com/el/

  enabled=0

  gpgcheck=0

'''

01.

02.

03.

04.

05.

06.

07.

91

Page 92: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: file copyingremoteSession {

  scp {

    from { localDir "$buildDir/application" }

    into { remoteDir '/var/bea/domain/application' }

  }

}

01.

02.

03.

04.

05.

06.

92

Page 93: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: command resultdef result = exec(command: '/usr/bin/mycmd',

  failOnError: false, showOutput: false)

if (result.exitStatus == 1) {

  result.output.eachLine { line ‐>

    if (line.contains('WARNING')) {

      throw new RuntimeException("First warning: ${line}")

    }

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09. 93

Page 94: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: shortcutsif (ok('/usr/bin/mycmd')) {

  ...

}

if (fail('/usr/bin/othercmd')) {

  ...

}

01.

02.

03.

04.

05.

06.

94

Page 95: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: tunnelstunnel('1.2.3.4', 8080) { int localPort ‐>

  def url = "http://localhost:${localPort}/flushCache"

  def result = new URL(url).text

  if (result == 'OK') {

    println "Cache is flushed!"

  } else {

    throw new RuntimeException(result)

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09. 95

Page 96: Ninja tricks for groovy system scripting for JavaLand 2016

Sshoogr: prefix/suffixprefix('sudo ') {

  exec 'rm ‐rf /var/log/abc.log'

  exec 'service abc restart'

}

suffix(' >> output.log') {

  exec 'yum ‐y install nginx'

  exec 'yum ‐y install mc'

  exec 'yum ‐y install links'

}

01.

02.

03.

04.

05.

06.

07.

08.

09. 96

Page 97: Ninja tricks for groovy system scripting for JavaLand 2016

Summary97

Page 98: Ninja tricks for groovy system scripting for JavaLand 2016

Take­awaysGroovy scripts are portable.

Groovy scripts are concise.

Groovy scripts are powerful.

Well, the name is groovy as well!

••••

98

Page 99: Ninja tricks for groovy system scripting for JavaLand 2016

Danke schön!99

Page 100: Ninja tricks for groovy system scripting for JavaLand 2016

Questions?100

Page 101: Ninja tricks for groovy system scripting for JavaLand 2016

Happyscripting!

101