Spring one 2012 Groovy as a weapon of maas PaaSification
- 6. ©2012AmadeusITGroupSA
Travel ecosystem
Airlines
Hotels
Cruises/ Ferries
Tour Operators
Car Rentals
Rail
Airlines own distribution
Airports, ticket offices,
web sites, call centers
Providers
Travel Agencies
TMCs
Traditional agencies
Online agencies
• Travel
Shopping
• Reservation
• Ticketing
• Post Sales
• Customer
Profiles
• Destination
Content
• …
Global
Distribution
System
Leisure
Business
End
consumers
- 11. ©2012AmadeusITGroupSA
Amadeus System Constraints
• 600+ millions bookings, 1 billion billable
transactions per year.
Huge Volumes
• 24x7 99.99%
• 4:20 minute coffee pause per month
High Availability
• 20 000 transaction per second - average < 200ms
• 65 000 external messages per second
Fast Performance
- 20. ©2012AmadeusITGroupSA
Three types of developers
Corporate (airlines, travel agency chains)
Observe “rules and regulations”
IT Services (small-medium shops)
Agile, know their tools, hack
Travel Agents
Non-technical, read a book or two
Karin Dalziel, Michael Lokner , Creative Commons
- 31. ©2012AmadeusITGroupSA
Some code examples
def keyboard = new Scanner(System.in)
def number = new Random().nextInt(10) + 1
def guess = 0
while (number != guess) {
println "Guess the number which is between 1 and 10: "
guess = keyboard.nextInt()
}
println"Hurray! You guessed correctly!"
function guessNumber() {
// Get a random integer from 1 to 10 inclusive
var num = Math.ceil(Math.random() * 10);
var guess;
while (guess != num) {
guess = prompt('Guess the number between 1 and
10 inclusive');
}
alert('Congratulations!nThe number was ' + num);
}
guessNumber();
import random
target, guess = random.randint(1, 10), 0
while target != guess:
guess = int(input('Guess my number between 1 and 10 until you get it right: '))
print('Thats right!')
n = rand( 10 ) + 1
puts 'Guess the number: '
puts 'Wrong! Guess again: ' until gets.to_i == n
puts 'Well guessed!'
source: http://rosettacode.com
- 37. ©2012AmadeusITGroupSA
JSR 223 Services
Script Execution: executing stream of characters in script language
• ScriptEngine
Binding: exposing Java objects to script programs as named
variables
• Bindings, ScriptContext
Compilation: generating intermediate code from script source
• Compilable, CompiledScript
Invocation: reusing intermediate code
• Invocable
- 38. ©2012AmadeusITGroupSA
Groovy vs. JSR
GroovyShell shell = new GroovyShell();
shell.evaluate(
"println 'Hello World!'; x = 123; return foo * 10");
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine groovyEngine = mgr.getEngineByName(“groovy");
try {
groovyEngine.eval(
"println 'Hello World!'; x = 123; return foo * 10");
} catch (ScriptException ex) {
ex.printStackTrace();
}
- 39. ©2012AmadeusITGroupSA
Groovy vs. JSR
Binding binding = new Binding();
binding.setVariable("foo", new Integer(2));
GroovyShell shell = new GroovyShell(binding);
shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine groovyEngine = mgr.getEngineByName(“groovy");
Bindigs bindings = groovyEngine.createBindings();
bindings.put("foo", new Integer(2));
try {
groovyEngine.eval(
"println 'Hello World!'; x = 123; return foo * 10 “, bindings);
} catch (ScriptException ex) {
ex.printStackTrace();
}
- 40. ©2012AmadeusITGroupSA
JSR 223 Interfacing with Java
Invocable
groovyEngine.eval(
"def hello(s) { println 'Hello ${s}!';}");
Invocable obj = (Invocable) groovyEngine;
inv.invokeMethod(obj, "hello", "Groovy!!" );
Invocable with interface
groovyEngine.eval(
"def hello(s) { println 'Hello ${s}!';}");
Invocable inv = (Invocable) groovyEngine;
Runnable r = inv.getInterface(Runnable.class);
r.run();
- 41. ©2012AmadeusITGroupSA
JSR 223 Interfacing with Java
Invocable
jsEngine.eval(
"function hello(s) { log('Hello ' + s); }");
Invocable obj = (Invocable) groovyEngine;
inv.invokeMethod(obj, "hello", "JavaScript!!" );
Invocable with interface
jsEngine.eval(
"function hello(s) { log('Hello ' + s); }");
Invocable inv = (Invocable) groovyEngine;
Runnable r = inv.getInterface(Runnable.class);
r.run();
- 47. ©2012AmadeusITGroupSA
Pacification
We are executing in JVM, sharing the platform
and resources
What can you do in JVM?
Consume resources (CPU, disk, threads)
Spy around:
Amadeus code,
Other customers’ code
Even worse, other customers’ data
- 49. ©2012AmadeusITGroupSA
AST visiting
Check every node in AST at compile time
org.codehaus.groovy.control.customizers.CompilationCustomizer
org.codehaus.groovy.ast.GroovyCodeVisitor
Sandbox API
Whitelist
API that you can call
Blacklist
java.lang.Object, java.lang.reflect
Methods in whitelisted classes
- 50. ©2012AmadeusITGroupSA
AST modification (for stability)
Timeout scripts
groovy.transform.TimedInterrupt
@TimedInterrupt(value = 10L, unit = TimeUnit.SECONDS)
Allow interrupting script thread
groovy.transform.ThreadInterrupt
Allow custom interrupting
groovy.transform.ConditionalInterrupt
@ConditionalInterrupt({++counter<10})
- 54. ©2012AmadeusITGroupSA
DOM-like object
SaaS services communicate using
DOM-like object with Map interface
groovy.util.Node
Adding support for groovy
constructs (e.g. closures)
groovy.lang.DelegatingMetaClass
Marshall
object on
java side
Unmarshall
(parse) on
groovy
- 59. ©2012AmadeusITGroupSA
DSL for macros
Simple
Send terminal command
Prompt user
Variable
Loops?
Conditions?
ask “Customer phone?" assign to phone
send “AP ${phone}"
ask “Customer account?" assign to account
send "RM ACC-${account}"
- 62. ©2012AmadeusITGroupSA
What kind of IDE
DSL
• For end users
• Integrated in application itself
UI templating
• Text editor or Web based
• Ace, Eclipse Orion
• Graphical
Groovy
• For professionals only
• Eclipse today
- 65. ©2012AmadeusITGroupSA
How to test
Develop locally, execute on remotely hosted
platform
Install platform locally
Works for Google App Engine,
Azure, Cloud Foundry
Mock platform locally
- 69. ©2012AmadeusITGroupSA
Open Source
We know the value is in community
We have contributed to groovy,
We will keep contributing
http://www.amadeus.com/blog/17/09/open-for-
business/
Open sourcing UI http://ariatemplates.com/
- 70. ©2012AmadeusITGroupSA
THE END
Special thanks
SSE Team
Vincent Bersin, Tiago Fernandez, Mathieu Bruyen,
Sebastien Blanc, Guillaume Cernier (@cernier,
http://linkedin.com/in/cernierg), Vincent Malley, Marco Funaro, Pascal
Cohen, Vincent Gerard, Nicola Rondelle, Bruno Bongiovanni,
Francesco Uliana, Emanuel Dore, Geoffrey Van Staen
Architecture group
Marc Campora, Christophe Allexandre, Fabrice Matrat
Amadeus e-Travel Management and Selling Platform Connect
teams for creating products that are shown here
Wikipedia for images of French Riviera
rosetta.org for code examples
Smartflow DSL slides inspired by
http://dslprez.cloudfoundry.com/DSLPresentation.html by
Corinne Krych, Sebastien Blanc