SlideShare une entreprise Scribd logo
1  sur  39
Télécharger pour lire hors ligne
Operating
Microservices
with
Andrés Viedma
@andres_viedma
Andrés ViedmaAndrés Viedma
@andres_viedma@andres_viedma
Andrés ViedmaAndrés Viedma
@andres_viedma@andres_viedma
curl 
-u "jsonrpc:19ffd9709d03ce50675c3a43d1c49c1ac207f4bc45f06c5b2701fbdf8929" 
-d '{"jsonrpc": "2.0", "id": 1, 
"method": "getAllTasks", "params": , {"project_id": 1, "status_id": 1} }' 
http://demo.kanboard.net/jsonrpc.php
01 LET'S PLAY!
(IN THE MUD)
Our weapon: the Groovy shell groovysh
Our basic Groovy Client
class JsonRpcClient {
(...)
def makeCall(String method, Map params = [:]) {
try {
(... json call ...)
return json.result
} catch (HttpResponseException e) {
(...)
}
}
}
class JsonRpcClient {
def methodMissing(String name, args) {
return makeCall(name, args)
}
def makeCall(String method, Map params = [:]) {
(...)
}
(...)
}
Our dynamic Groovy Client
class JsonRpcClient {
def methodMissing(String name, args) {
return makeCall(name, args)
}
def makeCall(String method, Map params = [:]) {
(...)
}
(...)
}
groovy:000> client = new JsonRpcClient(...)
===> jsonrpc.JsonRpcClient@a0a9fa5
groovy:000> client.getAllTasks(project_id: 1, status_id: 2)
Our dynamic Groovy Client
Our dynamic REST Groovy Client
blog.posts.”37”.comments()
blog.posts.”37”.delete()
blog.posts.”37” = [text: 'xxx', ...]
GET
POST
PUT
DELETE
blog.posts.”37”.comments << [text: 'xxx', …]
blog.posts.”37”.comments.add(text: 'xxx', …)
class RestGroovyClient extends RestGroovyClientPath {
String base
(...)
private doGet(String path, params = [:]) { … }
private doPut(String path, params = [:]) { … }
private doPost(String path, params = [:]) { … }
private doDelete(String path, params = [:]) { … }
}
class RestGroovyClientPath {
RestGroovyClient client = null
String path = ''
(...)
}
Our dynamic REST Groovy Client
class RestGroovyClientPath {
def propertyMissing(String name) {
newPath(name)
}
def getAt(name) {
newPath(name.toString())
}
private RestGroovyClientPath newPath(String name) {
return new RestGroovyClientPath(
client: client, path: nextpath(name))
}
(...)
}
Our dynamic REST Groovy Client
blog.posts.”37”.comments()
blog['posts'][37].comments()
class RestGroovyClientPath {
def methodMissing(String name, args) {
return client.doGet(nextpath(name), args)
}
def propertyMissing(String name, value) {
return client.doPut(nextpath(name), args)
}
def leftShift(value) {
return client.doPost(path, value)
}
def delete() {
return client.doDelete(path)
}
}
Our dynamic REST Groovy Client
blog.posts.”37”.comments()
blog.posts.”37” = [...]
blog.posts << [...]
blog.posts.”37”.delete()
02 YOUR LITTLE
BLACK BOOK
What if we create a directory of our services?
Organized as a tree
Grouped by features, by environment...
Register as shell variables
The ConfigSlurper
import dynapiclient.rest.*
jsonrpc {
kanboard = new JsonRpcClient(
base: 'http://demo.kanboard.net/jsonrpc.php',
clientHandler: { it.auth.basic 'demo', 'demo123' } )
}
rest {
(...)
marvel = new RestDynClient(
base: 'http://gateway.marvel.com/', path: '/v1/public',
paramsHandler: this.&marvelAuthenticate)
}
void marvelAuthenticate(Map callParams, String method) {
(...)
}
jsonrpc.kanboard.getMyProjects()
The ConfigSlurper
import dynapiclient.rest.*
jsonrpc {
kanboard = new JsonRpcClient(
base: 'http://demo.kanboard.net/jsonrpc.php',
clientHandler: { it.auth.basic 'demo', 'demo123' } )
}
rest {
(...)
marvel = new RestDynClient(
base: 'http://gateway.marvel.com/', path: '/v1/public',
paramsHandler: this.&marvelAuthenticate)
}
void marvelAuthenticate(Map callParams, String method) {
(...)
}
Available on startup: ~/.groovy/groovysh.profile
groovyUserHome = new File(System.getProperty('user.home'), '.groovy')
file = new File(groovyUserHome, 'assets.groovy')
binding.variables <<
new ConfigSlurper().parse(file.toURI().toURL())
Teamwork: share the directory
@Grab(group='org.springframework',
module='spring-orm',
version='3.2.5.RELEASE')
Teamwork: share the directory
Fast release cycle
@Grab(group='org.springframework',
module='spring-orm',
version='3.2.5.RELEASE')
@SourceGrab(
'https://github.com/andresviedma/
groovy-assets-directory-example.git')
AST transformation
Source Grapes Available in
Classpath
@SourceGrab('<url>')
public class myscript extends Script {
static {
SourceGrape.grab("<url>");
}
(...)
}
TRICK Add the sources directory to the classpath
in runtime and... it just works!
Merge directory parts (ConfigSlurper)
1. Passwords (local)
2. The main directory (git)
3. Personal / dev assets (local)
TRICK Merge config files: append all the files
and then parse them
03 I NEVER FORGET
A FACE
(BUT IN YOUR CASE, I'LL MAKE
AN EXCEPTION)
Asking for help
marvel.characters(doc)
groovy:000> rest.marvel.characters
===> **** /v1/public/characters
** GET: Fetches lists of characters.
Params: name, nameStartsWith, modifiedSince, comics, series, events,
stories, orderBy, limit, offset
Next: {characterId}
groovy:000>
marvel.characters()GET
marvel.characters.help()(doc)
Asking for help
groovy:000> rest.marvel.characters."1010354"
===> **** /v1/public/characters/{characterId}
** GET: Fetches a single character by id.
[characterId(*)]
Next: comics, events, series, stories
groovy:000>
Replaceable URL path sections
What about Autocomplete?
We have the ExpandoMetaClass!
groovy:000> x = 2
===> 2
groovy:000> x.metaClass.sayHello = { args -> println 'hello' }
===> groovysh_evaluate$_run_closure1@57adfab0
groovy:000> x.sayHello()
hello
===> null
groovy:000> x.
abs() byteValue() compareTo( doubleValue() downto(
floatValue()
intValue() longValue() power( shortValue() times(
upto(
groovy:000>
What about Autocomplete?
We have the ExpandoMetaClass!
groovy:000> x = 2
===> 2
groovy:000> x.metaClass.sayHello = { args -> println 'hello' }
===> groovysh_evaluate$_run_closure1@57adfab0
groovy:000> x.sayHello()
hello
===> null
groovy:000> x.
abs() byteValue() compareTo( doubleValue() downto(
floatValue()
intValue() longValue() power( shortValue() times(
upto(
groovy:000>
What about Autocomplete?
The shell wraps the Expando In a HandleMetaClass
groovy:000> x.metaClass
===> HandleMetaClass[MetaClassImpl[class java.lang.String]]
groovy:000> x.metaClass."hello" = { name -> "Hello ${name}" }
===> groovysh_evaluate$_run_closure1@feba70e
groovy:000> x.metaClass
===> HandleMetaClass[ExpandoMetaClass[class java.lang.String]]
groovy:000> x.metaClass.getMetaMethods()*.name.findAll { it.startsWith('h') }
===> [hasProperty]
TRICK Use InvokerHelper.getMetaClass(x)
instead of x.metaClass
class AutocompleteMetaClass extends DelegatingMetaClass {
static void addFakeMethodsToObject(Object object, methods, properties) {
def autocomplete = configureMetaClass(object)
def innerMeta = autocomplete.originalMetaClass
addFakeMethodsToExpando(innerMeta, object, methods, properties)
}
private static MetaClass configureMetaClass(Object object) {
def metaOld = InvokerHelper.getMetaClass(object)
if (metaOld.getClass().name != AutocompleteMetaClass.class.name) {
object.metaClass = new AutocompleteMetaClass(metaOld)
}
return InvokerHelper.getMetaClass(object)
}
(...)
}
Create your own brand AutocompleteMetaClass
class AutocompleteMetaClass extends DelegatingMetaClass {
(...)
final MetaClass expando
AutocompleteMetaClass(MetaClass originalMetaClass) {
super(originalMetaClass)
this.expando = originalMetaClass
}
List<MetaMethod> getMetaMethods() {
return expando.getExpandoMethods()
}
List<MetaBeanProperty> getProperties() {
return expando.getExpandoProperties()
}
}
Create your own brand AutocompleteMetaClass
Let's demo!!!
04 So...?
(JUST ENDING, I PROMISE...)
Give me the code!!!
https://github.com/andresviedma/sourcegrape
https://github.com/andresviedma/dynapiclient-groovy
https://github.com/andresviedma/groovy-assets-directory-example
Where did all this led us?
Shared microservices directory
Dynamic service calls
Autocomplete
Integrated help
A powerful shell
But, in the way there, mostly...
Learning about Groovy scripting black magic
Having fun!
Andrés ViedmaAndrés Viedma
@andres_viedma@andres_viedma
Questions?

Contenu connexe

En vedette

Groovy - Grails as a modern scripting language for Web applications
Groovy - Grails as a modern scripting language for Web applicationsGroovy - Grails as a modern scripting language for Web applications
Groovy - Grails as a modern scripting language for Web applicationsIndicThreads
 
Madrid GUG - Grails Plugins: Exporter
Madrid GUG - Grails Plugins: ExporterMadrid GUG - Grails Plugins: Exporter
Madrid GUG - Grails Plugins: ExporterIván López Martín
 
Hacking the Grails Spring Security Plugins
Hacking the Grails Spring Security PluginsHacking the Grails Spring Security Plugins
Hacking the Grails Spring Security PluginsGR8Conf
 
Greach 2014 - Metaprogramming with groovy
Greach 2014 - Metaprogramming with groovyGreach 2014 - Metaprogramming with groovy
Greach 2014 - Metaprogramming with groovyIván López Martín
 
Hacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 PluginHacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 PluginBurt Beckwith
 
T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!
T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!
T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!Iván López Martín
 
Advanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and MonitoringAdvanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and MonitoringBurt Beckwith
 
Little Did He Know ...
Little Did He Know ...Little Did He Know ...
Little Did He Know ...Burt Beckwith
 
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayerCodemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayerIván López Martín
 
Fun With Spring Security
Fun With Spring SecurityFun With Spring Security
Fun With Spring SecurityBurt Beckwith
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovytomaslin
 
Reactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and GrailsReactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and GrailsSteve Pember
 
Building Micro-Services with Scala
Building Micro-Services with ScalaBuilding Micro-Services with Scala
Building Micro-Services with ScalaYardena Meymann
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyGR8Conf
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean CodeGR8Conf
 
Groovy in the Cloud
Groovy in the CloudGroovy in the Cloud
Groovy in the CloudDaniel Woods
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyAli Tanwir
 

En vedette (18)

Groovy - Grails as a modern scripting language for Web applications
Groovy - Grails as a modern scripting language for Web applicationsGroovy - Grails as a modern scripting language for Web applications
Groovy - Grails as a modern scripting language for Web applications
 
Madrid GUG - Grails Plugins: Exporter
Madrid GUG - Grails Plugins: ExporterMadrid GUG - Grails Plugins: Exporter
Madrid GUG - Grails Plugins: Exporter
 
Hacking the Grails Spring Security Plugins
Hacking the Grails Spring Security PluginsHacking the Grails Spring Security Plugins
Hacking the Grails Spring Security Plugins
 
Greach 2014 - Metaprogramming with groovy
Greach 2014 - Metaprogramming with groovyGreach 2014 - Metaprogramming with groovy
Greach 2014 - Metaprogramming with groovy
 
Hacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 PluginHacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 Plugin
 
T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!
T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!
T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!
 
Advanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and MonitoringAdvanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and Monitoring
 
Little Did He Know ...
Little Did He Know ...Little Did He Know ...
Little Did He Know ...
 
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayerCodemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
 
Fun With Spring Security
Fun With Spring SecurityFun With Spring Security
Fun With Spring Security
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovy
 
Reactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and GrailsReactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and Grails
 
Building Micro-Services with Scala
Building Micro-Services with ScalaBuilding Micro-Services with Scala
Building Micro-Services with Scala
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Groovy on Android
Groovy on AndroidGroovy on Android
Groovy on Android
 
Groovy in the Cloud
Groovy in the CloudGroovy in the Cloud
Groovy in the Cloud
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 

Dernier

Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Dernier (20)

Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

Operating Microservices with Groovy

  • 4.
  • 5. curl -u "jsonrpc:19ffd9709d03ce50675c3a43d1c49c1ac207f4bc45f06c5b2701fbdf8929" -d '{"jsonrpc": "2.0", "id": 1, "method": "getAllTasks", "params": , {"project_id": 1, "status_id": 1} }' http://demo.kanboard.net/jsonrpc.php
  • 7. Our weapon: the Groovy shell groovysh
  • 8. Our basic Groovy Client class JsonRpcClient { (...) def makeCall(String method, Map params = [:]) { try { (... json call ...) return json.result } catch (HttpResponseException e) { (...) } } }
  • 9. class JsonRpcClient { def methodMissing(String name, args) { return makeCall(name, args) } def makeCall(String method, Map params = [:]) { (...) } (...) } Our dynamic Groovy Client
  • 10. class JsonRpcClient { def methodMissing(String name, args) { return makeCall(name, args) } def makeCall(String method, Map params = [:]) { (...) } (...) } groovy:000> client = new JsonRpcClient(...) ===> jsonrpc.JsonRpcClient@a0a9fa5 groovy:000> client.getAllTasks(project_id: 1, status_id: 2) Our dynamic Groovy Client
  • 11. Our dynamic REST Groovy Client blog.posts.”37”.comments() blog.posts.”37”.delete() blog.posts.”37” = [text: 'xxx', ...] GET POST PUT DELETE blog.posts.”37”.comments << [text: 'xxx', …] blog.posts.”37”.comments.add(text: 'xxx', …)
  • 12. class RestGroovyClient extends RestGroovyClientPath { String base (...) private doGet(String path, params = [:]) { … } private doPut(String path, params = [:]) { … } private doPost(String path, params = [:]) { … } private doDelete(String path, params = [:]) { … } } class RestGroovyClientPath { RestGroovyClient client = null String path = '' (...) } Our dynamic REST Groovy Client
  • 13. class RestGroovyClientPath { def propertyMissing(String name) { newPath(name) } def getAt(name) { newPath(name.toString()) } private RestGroovyClientPath newPath(String name) { return new RestGroovyClientPath( client: client, path: nextpath(name)) } (...) } Our dynamic REST Groovy Client blog.posts.”37”.comments() blog['posts'][37].comments()
  • 14. class RestGroovyClientPath { def methodMissing(String name, args) { return client.doGet(nextpath(name), args) } def propertyMissing(String name, value) { return client.doPut(nextpath(name), args) } def leftShift(value) { return client.doPost(path, value) } def delete() { return client.doDelete(path) } } Our dynamic REST Groovy Client blog.posts.”37”.comments() blog.posts.”37” = [...] blog.posts << [...] blog.posts.”37”.delete()
  • 16.
  • 17. What if we create a directory of our services? Organized as a tree Grouped by features, by environment... Register as shell variables
  • 18. The ConfigSlurper import dynapiclient.rest.* jsonrpc { kanboard = new JsonRpcClient( base: 'http://demo.kanboard.net/jsonrpc.php', clientHandler: { it.auth.basic 'demo', 'demo123' } ) } rest { (...) marvel = new RestDynClient( base: 'http://gateway.marvel.com/', path: '/v1/public', paramsHandler: this.&marvelAuthenticate) } void marvelAuthenticate(Map callParams, String method) { (...) } jsonrpc.kanboard.getMyProjects()
  • 19. The ConfigSlurper import dynapiclient.rest.* jsonrpc { kanboard = new JsonRpcClient( base: 'http://demo.kanboard.net/jsonrpc.php', clientHandler: { it.auth.basic 'demo', 'demo123' } ) } rest { (...) marvel = new RestDynClient( base: 'http://gateway.marvel.com/', path: '/v1/public', paramsHandler: this.&marvelAuthenticate) } void marvelAuthenticate(Map callParams, String method) { (...) }
  • 20. Available on startup: ~/.groovy/groovysh.profile groovyUserHome = new File(System.getProperty('user.home'), '.groovy') file = new File(groovyUserHome, 'assets.groovy') binding.variables << new ConfigSlurper().parse(file.toURI().toURL())
  • 21. Teamwork: share the directory @Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')
  • 22. Teamwork: share the directory Fast release cycle @Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE') @SourceGrab( 'https://github.com/andresviedma/ groovy-assets-directory-example.git')
  • 23. AST transformation Source Grapes Available in Classpath @SourceGrab('<url>') public class myscript extends Script { static { SourceGrape.grab("<url>"); } (...) } TRICK Add the sources directory to the classpath in runtime and... it just works!
  • 24. Merge directory parts (ConfigSlurper) 1. Passwords (local) 2. The main directory (git) 3. Personal / dev assets (local) TRICK Merge config files: append all the files and then parse them
  • 25. 03 I NEVER FORGET A FACE (BUT IN YOUR CASE, I'LL MAKE AN EXCEPTION)
  • 26.
  • 27.
  • 28. Asking for help marvel.characters(doc) groovy:000> rest.marvel.characters ===> **** /v1/public/characters ** GET: Fetches lists of characters. Params: name, nameStartsWith, modifiedSince, comics, series, events, stories, orderBy, limit, offset Next: {characterId} groovy:000> marvel.characters()GET marvel.characters.help()(doc)
  • 29. Asking for help groovy:000> rest.marvel.characters."1010354" ===> **** /v1/public/characters/{characterId} ** GET: Fetches a single character by id. [characterId(*)] Next: comics, events, series, stories groovy:000> Replaceable URL path sections
  • 30. What about Autocomplete? We have the ExpandoMetaClass! groovy:000> x = 2 ===> 2 groovy:000> x.metaClass.sayHello = { args -> println 'hello' } ===> groovysh_evaluate$_run_closure1@57adfab0 groovy:000> x.sayHello() hello ===> null groovy:000> x. abs() byteValue() compareTo( doubleValue() downto( floatValue() intValue() longValue() power( shortValue() times( upto( groovy:000>
  • 31. What about Autocomplete? We have the ExpandoMetaClass! groovy:000> x = 2 ===> 2 groovy:000> x.metaClass.sayHello = { args -> println 'hello' } ===> groovysh_evaluate$_run_closure1@57adfab0 groovy:000> x.sayHello() hello ===> null groovy:000> x. abs() byteValue() compareTo( doubleValue() downto( floatValue() intValue() longValue() power( shortValue() times( upto( groovy:000>
  • 32. What about Autocomplete? The shell wraps the Expando In a HandleMetaClass groovy:000> x.metaClass ===> HandleMetaClass[MetaClassImpl[class java.lang.String]] groovy:000> x.metaClass."hello" = { name -> "Hello ${name}" } ===> groovysh_evaluate$_run_closure1@feba70e groovy:000> x.metaClass ===> HandleMetaClass[ExpandoMetaClass[class java.lang.String]] groovy:000> x.metaClass.getMetaMethods()*.name.findAll { it.startsWith('h') } ===> [hasProperty] TRICK Use InvokerHelper.getMetaClass(x) instead of x.metaClass
  • 33. class AutocompleteMetaClass extends DelegatingMetaClass { static void addFakeMethodsToObject(Object object, methods, properties) { def autocomplete = configureMetaClass(object) def innerMeta = autocomplete.originalMetaClass addFakeMethodsToExpando(innerMeta, object, methods, properties) } private static MetaClass configureMetaClass(Object object) { def metaOld = InvokerHelper.getMetaClass(object) if (metaOld.getClass().name != AutocompleteMetaClass.class.name) { object.metaClass = new AutocompleteMetaClass(metaOld) } return InvokerHelper.getMetaClass(object) } (...) } Create your own brand AutocompleteMetaClass
  • 34. class AutocompleteMetaClass extends DelegatingMetaClass { (...) final MetaClass expando AutocompleteMetaClass(MetaClass originalMetaClass) { super(originalMetaClass) this.expando = originalMetaClass } List<MetaMethod> getMetaMethods() { return expando.getExpandoMethods() } List<MetaBeanProperty> getProperties() { return expando.getExpandoProperties() } } Create your own brand AutocompleteMetaClass
  • 36. 04 So...? (JUST ENDING, I PROMISE...)
  • 37. Give me the code!!! https://github.com/andresviedma/sourcegrape https://github.com/andresviedma/dynapiclient-groovy https://github.com/andresviedma/groovy-assets-directory-example
  • 38. Where did all this led us? Shared microservices directory Dynamic service calls Autocomplete Integrated help A powerful shell
  • 39. But, in the way there, mostly... Learning about Groovy scripting black magic Having fun! Andrés ViedmaAndrés Viedma @andres_viedma@andres_viedma Questions?