63
© 2013 Amadeus IT Group SA © 2012 Amadeus IT Group SA Polyglot alchemy: JSR 223 in action Fabrice Matrat Marc Campora

Polyglot Alchemy : JSR 223 In Action

Embed Size (px)

DESCRIPTION

Today your customers want to tailor applications to their specific needs, in terms of both business logic and user interface. In short, they want to inject custom code to transform a mainstream system into a platform as a service (PaaS). To support this vision, Amadeus built an extensibility framework relying on the JVM and JSR 223 to turn its business-critical solutions into a PaaS. Attend this session to hear how it dealt with JSR 223 limitations, why it picked Groovy as its favorite language, and the challenges it faced with sandboxing and hot swap on multitenant systems. The presentation also shares what Amadeus expects from invokedynamic and the coming support of JavaScript on the JVM.

Citation preview

Page 1: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

©

20

12 A

mad

eu

s IT

Gro

up

SA

Polyglot alchemy: JSR 223 in action

Fabrice MatratMarc Campora

Page 2: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Marc Campora Sr Manager Java Middleware [email protected] @mcampora

Page 3: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Fabrice Matrat System Architect Technical Evangelist [email protected] @fabricematrat

Page 4: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Context & Pb Statement

Key design decisions

Looking forward & Conclusion

Page 5: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Context & Pb Statement

Key design decisions

Looking forward & Conclusion

Page 6: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Amadeus

Leading provider of IT solutions for the travel industry Connect Providers (ex. airlines) and Resellers

(ex. TAs)

Provide IT solutions (ex. check-in or inventory system)

Page 7: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

System Constraints

3.7MBookings/day

1.6BTransactions/day

100+IT changes/day

<0.5sResponse time

99.99%Availability

600kTerminals

Page 8: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Our products

Inventory Departure

control Self Booking

Tools Point-of-sale e-Commerce Mobile

companions

Page 9: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Technical platform

A clear technical strategy RIA even for the mobile

Community products

SaaS, multi-tenants infrastructure

Web-based

Common hardware

Common code

Java, JEE, JavaScript

Page 10: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Problem statement

Community versus specific

Page 11: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

From SaaS to PaaS

Application logic

Middleware & Framework

Application UI

Page 12: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

From SaaS to PaaS

Application logic

Middleware & Framework

Script execution environment

API

Application UI

Custom logic

Custom UICustom UI

Page 13: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Features and ambition

Dev. Env.• Distributed version control• Self service loads and fallbacks• Access control and traceability• Life cycle management

UI• Custom dialogs• UI extensions

API• Call reservation systems• Call any external Web services• Store and retrieve custom data• Send emails• …

Runtime• Hotswap• Sandboxing• Isolation• Usage monitoring

Page 14: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Context & Pb Statement

Key design decisions

Looking forward & Conclusion

Page 15: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

JSR 223 Sandbox Integration

Page 16: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Scripting on JVM

Application logic

Middleware & Framework

Script execution environment

API

Application UI

Script Script

Script

Page 17: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Scripting for Amadeus PaaS

PaaS

JVM

Performance

Memory

WSTemplating

StrongCommunity

Dev. Productivit

y

Page 18: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Language Choice (2010)

Language

• Java 1.6• Groovy 1.6• Jython 2.5• JRuby 1.4• Rhino 1.7

Methodology

• Popularity• Documentation• Depth-first

search• Fibonacci• Templating• WebService

Page 19: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Groovy

0 200 400 600 800 1000 1200 14000

50

100

150

200

250

300

350

400

450

500

Java

Rhino

Groovy

JRuby

Jython

Time

Memory

Page 20: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Embed Groovy

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");

Page 21: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Embed Groovy

ClassLoader parent = getClass().getClassLoader(); GroovyClassLoader loader = new GroovyClassLoader(parent); File script = new File("HelloWorld.groovy")Class<GroovyObject> groovyClass = loader.parseClass(script); GroovyObject groovyObject = groovyClass.newInstance(); groovyObject.invokeMethod("run", new Object[0]);

Page 22: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Embed Groovy

String[] roots = new String[] { "/my/groovy/script/path" }; GroovyScriptEngine gse = new GroovyScriptEngine(roots); Binding binding = new Binding(); binding.setVariable("input", "world"); gse.run("hello.groovy", binding); System.out.println(binding.getVariable("output"));

Page 23: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Groovy

Plug to Amadeus PaaS

What about JavaScript ?

Page 24: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

JSR 223

Standard to embed scripting in JVM

Independent from language

Part of JDK 6+

One entry point: javax.script

Page 25: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Groovy vs. JSR 223

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 engine= mgr.getEngineByName("groovy"); Bindigs bindings = engine.createBindings();bindings.put("foo", new Integer(2)); engine.eval("println 'Hello World!'; x = 123; return foo * 10", bindings);

Page 26: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

JSR 223 in and out

In Out

Performance

Security

Engine Wrapper

Multiple script technologies

Common API

Page 27: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

In Out

Page 28: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Multiple script technology

Freemarker

Groovy

ScriptEngineManager mgr = new ScriptEngineManager();

ScriptEngine engine = mgr.getEngineByName( "groovy");

engine.eval("println 'Hello World!'");

ScriptEngineManager mgr = new ScriptEngineManager();

ScriptEngine engine =

mgr.getEngineByName( "freemarker"); engine.eval("Hello ${who}!");

Page 29: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Common APIInterface Description

ScriptEngine Main wrapper

ScriptEngineFactory Factory for ScriptEngine

Compilable ScriptEngine which contains methods to compile script

Invocable ScriptEngine whose methods allow scripts to be executed.

Bindings A mapping of key/value pairs, all of whose keys are Strings.

ScriptContext Context

Classes Description

ScriptEngineManager Discovery and instantiation mechanism for ScriptEngine

AbstractScriptEngine Super Class

CompiledScript Store results of compilations.

SimpleBindings HashMap bindings

SimpleScriptContext Simple ScriptContext.

Page 30: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

In Out

Page 31: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Availability 800 languages on JVM

Around 60 are maintained

20 have JSR 223 Implementation

Language Availability

Groovy Yes

Scala Yes

Jython Yes

JRuby Yes

Clojure Yes

Ceylon No

Golo No

… ..

Page 32: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Performance

Compilation Result JSR 223 No Access

Storage

Script Compilation Result

Script Script

Script

Page 33: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Cache

Performance

Byte

Code

Custom classloader

Cache

Page 34: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Hot swapping Groovy

Run 2 versions of the same script

Passport.groovygot changed

Passport.class

new code1110000011

new hash

new code1110000011

new hash

Custom classloader

Page 35: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

JSR 223 Sandbox Integration

Page 36: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Script in JVM sharing platform and resources

Sandbox

Page 37: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Bad things can happen Consume resources (CPU, disk, threads)

Java and Amadeus API is available

Sandbox

java.lang.System.exit(1)

Page 38: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Access control

Compile Runtime

Page 39: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Compile : How ?

Check every node in AST @ compile time

org.codehaus.groovy.control.customizers.CompilationCustomizerorg.codehaus.groovy.ast.GroovyCodeVisitor

Page 40: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Compile : Design

Deny/Allow/Deny Blacklist Everything

Whitelist

BlacklistMethods granularity in whitelisted classes

java.lang.System

java.lang.System.exit java.lang.System.currentTimeMillis

Page 41: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Compile : Implementation

class SecureCodeCustomizer extends CompilationCustomizer { public SecureCodeCustomizer() { super(CompilePhase.CANONICALIZATION); } public void call(…) { final ModuleNode ast = source.getAST(); ast.getStatementBlock().visit(new SecureCodeVisitor()); … }}class SecureCodeVisitor implements GroovyCodeVisitor { public void visitMethodCallExpression(MethodCallExpression call) { checkMethodAuthorized(call); … } public void visitStaticMethodCallExpression (…) {…} public void visitClassExpression (…) {…} …}

Page 42: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Access control

Compile Runtime

Page 43: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Runtime

Java Security leverage the JVM's Security Managers

Wrap Primitive/Method

Add Wrapping

((Object)"ls").execute()

def obj = ((Object)"ls")// Throw an exception if necessaryauthorizeStatement(obj, "execute")obj.execute();

Page 44: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Resource Sharing

Stability Isolation

Page 45: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Sandbox code (for stability)

Timeout enforcement Protection against infinite loops and other

patterns

Injected @ compile time via AST transformation

@groovy.transform.TimedInterrupt( value = 10L, unit = TimeUnit.SECONDS)

def config = new CompilerConfiguration() def customizer = new ASTTransformationCustomizer( [value:10L, unit:TimeUnit.SECONDS], TimedInterrupt)config.addCompilationCustomizers(customizer)

Page 46: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

We are not alone

Oracle Application Developer Framework https://github.com/sjurgemeyer/

GR8ConfUS2013/tree/master/JimDriscoll Jenkins

http://kohsuke.org/2012/04/27/groovy-secureastcustomizer-is-harmful/

Call to the community for improvement !

Page 47: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Resource Sharing

Stability Isolation

Page 48: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Remoting

AST can optimize the Contextual information sent to the Execution Farm.

Applicationfarm

Scriptingfarm(s)

REST/Jsonwith applicationcontext

Page 49: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Remoting

Isolation SandBox Failure

Memory or IO contentions

No Resources Impact on Main application Farm

Customers or staging isolation

On demand provisioning Fine grain usage reports

Billing Model

Page 50: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

JSR 223 Sandbox Integration

Page 51: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Developer experience

Production

Preview

Page 52: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Groovy productivity

Java

XML appears as objects TripPlan<extends XMLNode> tp = TripPlanFactory.tripplan

tp.AIR.ITINERARIES.each {itinerary -> Logger.info itinerary.text()

}

Untyped language Actually you have the choice

def unknown = "we’re @ J1 2013"

String message = "we’re @ J1 2013"

Page 53: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

A practical case study…

Page 54: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

A practical case study…

Page 55: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

A practical case study…

UI

Hook

Action

Server

Placeholder import amadeus.pnr.tripplan

// get PNR in-memory representation (a.k.a. TripPlan)def tripplan = TripPlan.getTripPlan()

// defining a list of eligible countriesdef COUNTRY_LIST=["US", "PR", "AS", "VI", "MP", "GU"]// defining a list of eligible carriersdef CARRIER_LIST=["UA","AA"]

// business condition if one goes to or comes from US,// or if carrier is UA or AAdef eligibleTrip = !tripplan.AIR.LIST_ITINERARY.LIST_SEGMENT.findAll { ((it.E_LOCATION.COUNTRY_CODE in COUNTRY_LIST) || (it.B_LOCATION.COUNTRY_CODE in COUNTRY_LIST)) || (it.AIRLINE.CODE in CARRIER_LIST)}.isEmpty()

// if trip eligible, trigger the UI enrichmentbean.with { if (eligibleTrip) { // the id of the product UI placeholder in which to display. placeholder = "customTSAPlaceholder"

// the script to be called during the next step to // process the user inputs. actionId = "CustomTSAProcess" }}

{Template} {macro init()} <div style="padding-left: 20px;"> {@aria:TextField { label: 'Maiden name', labelWidth: 210, block: true, bind: to("pspt") } /} {@aria:TextField { label: 'Redress number', block: true, labelWidth: 210, bind: to("redn") } /} {@aria:TextField { label: 'Known traveler id', block: true, labelWidth: 210, bind: to("knwt") } /} </div> {/macro}{/Template}

Page 56: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

A practical case study…

Page 57: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Context & Pb Statement

Key design decisions

Looking forward & Conclusion

Page 58: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Remaining challenges

A productive development environment

Page 59: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Remaining challenges

A productive development environment Success leads to Elasticity

Page 60: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Remaining challenges

A productive development environment Success leads to Elasticity Add new languages to enlarge the user

base

Page 61: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Take home messages

Groovy is great to customize applications

The JVM and JSR223 give you access to other languages

Sandboxing and isolation are a must

Unfortunately sandboxing and isolation are specific to the language

Page 62: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Some more…

Special thanks to the team!

UI produced using AriaTemplates ™ (github.com/ariatemplates)To know more about Amadeus: http://www.amadeus.com

JavaOne Polyglot Enterprise Development on the JVM [CON2382]

Mark Little – VP Red Hat Inc The JVM Is Over: The Polyglot Virtual Machine Is Here

[CON5344]Marcus Lagergren - Runtime Futurist, Oracle

Liftoff with Groovy 2.1 [CON2591]Guillaume Laforge - Pivotal

Embedded DSL: Groovy and Scala Fair Duel [TUT4524]Corinne Krych - RedHat and Pascal Cohen - Amadeus

Page 63: Polyglot Alchemy : JSR 223 In Action

© 2

01

3 A

mad

eu

s IT

Gro

up

SA

Q&A