developing modular, polyglot applications with spring (springone india 2012)

88
Developing modular, polyglot applications with Spring Chris Richardson Author of POJOs in Action, Founder of the original CloudFoundry.com @crichardson [email protected] http://plainoldobjects.com/

Upload: chris-richardson

Post on 10-May-2015

2.491 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Developing modular, polyglot applications with Spring

Chris Richardson

Author of POJOs in Action, Founder of the original CloudFoundry.com

@crichardson [email protected]

http://plainoldobjects.com/

Page 2: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Presentation goal

Modular, polyglot applications:

what, why and how?

Why Spring is the ideal technology

for building these applications

Page 3: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris

Page 4: Developing modular, polyglot applications with Spring (SpringOne India 2012)

(About Chris)

Page 5: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris - 1999

WebLogic Server

CORBA

Enterprise JavaBeans

Page 6: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris - 2004

Page 7: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring programming model

POJO

Dependency Injection

Aspect-Oriented

Programming

Portable Service

Abstractions

Page 8: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Transformed how I developed software!

Page 9: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris()

Page 10: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris - 2006

Cloud Computing

Oakland JUG

Page 11: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Transformed how I deployed software!

Page 12: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris

Page 13: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Chris

http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/

Page 14: Developing modular, polyglot applications with Spring (SpringOne India 2012)

vmc push About-Chris

Signup at http://cloudfoundry.com

Developer Advocate for CloudFoundry.com

Page 15: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Presentation layer design

• Using NoSQL databases

• Inter-service communication options

Page 16: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Let’s imagine you are building an e-commerce application

Page 17: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Traditional web application architecture

Tomcat

Browser

WAR

MySQL Database

ShippingService

AccountingService

InventoryService

StoreFrontUI

developtestdeploy

Simple to

Apache

scale

Page 18: Developing modular, polyglot applications with Spring (SpringOne India 2012)

But there are problems

Page 19: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Users expect a rich, dynamic and interactive experience

Java Web ApplicationBrowser

HTTP Request

HTML/Javascript

Old style UI architecture isn’t good enough

HTML5/JavaScript browser applicationsReal-time web ≅ NodeJS

Page 20: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Limitations of relational databases

• Scalability

•Distribution

• Schema updates

•O/R impedance mismatch

• Handling semi-structured data

Page 21: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Intimidates developers

Page 22: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Scalability issues

•Different components have different scalability needs ⇔ but

you can only scale the entire system

• Some components might not be scalable ⇒ can’t scale system

Page 23: Developing modular, polyglot applications with Spring (SpringOne India 2012)

• Need to redeploy everything to change one component

• Increases risk of failure, e.g. interrupts background jobs

Fear of change

• Extensive test cycle

• Updates will happen less often, e.g. Makes A/B testing UI really difficult

Obstacle to frequent deployments

Page 24: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Overloads your IDE and container

Slows down development

Page 25: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Lots of coordination and communication required

Obstacle to scaling developmentI want to update

the UI

But the backend is not working yet!

Page 26: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Requires long-term commitment to a technology stack

Page 27: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Presentation layer design

• Using NoSQL databases

• Inter-service communication options

Page 28: Developing modular, polyglot applications with Spring (SpringOne India 2012)
Page 29: Developing modular, polyglot applications with Spring (SpringOne India 2012)

The scale cube

X axis - horizontal duplication

Z axis

- data

parti

tionin

g

Y axis - functionaldecomposition

Scale

by sp

litting

similar

thing

s

Scale by splitting different things

Page 30: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Y-axis scaling - application level

WAR

ShippingService

AccountingService

InventoryService

StoreFrontUI

Page 31: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Y-axis scaling - application level

Store front web application

shipping application

inventory application

Apply X axis cloning and/or Z axis partitioning to each service

ShippingService

AccountingService

InventoryServiceStoreFrontUI

accounting application

Page 32: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Real world examples

http://highscalability.com/amazon-architecture

Between 100-150 services are accessed to build a page.

http://techblog.netflix.com/

http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

http://queue.acm.org/detail.cfm?id=1394128

Page 33: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Drawbacks of Y-axis splits

• Complexity

• Partitioned databases and transaction management

•Deciding when to use this approach

Page 34: Developing modular, polyglot applications with Spring (SpringOne India 2012)

But there are many benefits

• Scales development: develop, deploy and scale each service independently

• Enables frequent deployments

• Less for each developer to learn

• Doesn’t overload IDE or container

• Improves fault isolation

• Easily adopt new technologies

Page 35: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Two levels of architecture

System-level

ServicesInter-service glue: interfaces and communication mechanismsSlow changing

Service-level

Internal architecture of each serviceEach service can use a different technology stackRapidly evolving - regularly rewritePick the best tool for the job

Page 36: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Modular, polyglot, applications

Page 37: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Lots of languages and frameworks to choose from

And many more...

Page 38: Developing modular, polyglot applications with Spring (SpringOne India 2012)

But there are lots of awesome, and mature Spring projects

• Spring Framework

• Spring Security

• Spring Mobile

• Spring Data

• Spring Web Services

• Spring Batch

• Spring Integration

• Spring AMQP

• Spring Social

• Spring Shell

• ...

Page 39: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring works with Scala@Controllerclass TwilioController {

@Autowired var surveyManagementService: SurveyManagementService = _

@RequestMapping(value = Array("/begincall.html")) @ResponseBody def beginCall(@RequestParam("From") callerId: String) = { surveyManagementService.findSurveyByCallerId(callerId) match { case None => <Response> <Say>Sorry don't recognize your number</Say> <Hangup/> </Response> case Some(survey) => <Response> <Say>{ survey.prompt }</Say> <Gather action="handleresponse.html" method="POST" numDigits="1"> { for ((choice, index) <- survey.choices zipWithIndex) yield <Say>Press { index } for { choice }</Say> } </Gather> <Say>We are sorry you could not decide</Say> <Hangup/> </Response> } }

Page 40: Developing modular, polyglot applications with Spring (SpringOne India 2012)

The Spring Scala project

• Scala-style “setters/getters”

• Bean configuration DSL

• Scala-style template classes

https://github.com/SpringSource/spring-scala

class  PersonConfiguration                            extends  FunctionalConfiguration  {        val  jack  =  bean()  {                new  Person("Jack",  "Doe")        }

       val  jane  =  bean()  {                new  Person("Jane",  "Doe")        }

       val  john  =  bean()  {                val  john  =  new  Person("John",  "Doe")                john.father  =  jack()                john.mother  =  jane()                john        }}

Page 41: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Coming in 2013Java 8 closures = concise code!

http://cr.openjdk.java.net/~briangoetz/lambda/sotc3.html

List<Album> albums = ...List<Album> sortedFavorites = albums.stream() .filter(a -> a.tracks.anyMatch(t -> (t.rating >= 4))) .sorted(comparing(a -> a.name)) .into(new ArrayList<>());

Predicate

int sum = shapes.parallel() .filter(s -> s.getColor() == BLUE) .map(s -> s.getWeight()) .sum();

Parallelism

Page 42: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Modularity

Productivity

Portability

Testability

Key benefits of Spring are still

Page 43: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Presentation layer design

• Using NoSQL databases

• Inter-service communication options

Page 44: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Browser

WAR

StoreFrontUI

Model

View Controller

Presentation layer evolution....

HTML / HTTP

Page 45: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Browser Web application

RESTfulEndpoints

Model

View Controller

...Presentation layer evolution

JSON-REST

HTML 5 - JavaScript

No elaborate, server-side web framework required

Event publisher

Events

Static content

Page 46: Developing modular, polyglot applications with Spring (SpringOne India 2012)

How to publish events to browser?

Page 47: Developing modular, polyglot applications with Spring (SpringOne India 2012)

NodeJS is the fashionable technology

Page 48: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Why NodeJS?• Familiar JavaScript

• High-performance, scalable event-driven, non-blocking I/O model

• Compact runtime, e.g. 64M

•Over 13,000 17,000 modules developed by the community

•Many JavaScript client frameworks have a NodeJS counterpart, e.g. socket.io and SockJS

Page 49: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Why not NodeJS?

a.k.a. callback hell

Page 50: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Dealing with JavaScript

“...Still the consequence of this is that we must take javascript

seriously as a first-class language and concentrate on how to limit the

damage its flaws cause....”

http://martinfowler.com/bliki/gotoAarhus2012.html

Page 51: Developing modular, polyglot applications with Spring (SpringOne India 2012)

NodeJS as a mediator...

BrowserService 1

Service 2

...

HTML 5ApplicationSocket.io

client

Events

REST

Server app

Socket.ioserver

Node JS

Static content

Page 52: Developing modular, polyglot applications with Spring (SpringOne India 2012)

...NodeJS as a mediator

Node JS

Service

RabbitMQ Service

REST

AMQP AMQP

REST

Events

socket.io

Page 53: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Example NodeJS applicationvar express = require('express') , http = require('http') , amqp = require(‘amqp’) , server = http.createServer(app) , io = require('socket.io').listen(server) ....;

server.listen(8081);...var amqpCon = amqp.createConnection(...);

io.sockets.on('connection', function (socket) { function amqpMessageHandler(message, headers, deliveryInfo) { var m = JSON.parse(message.data.toString()); socket.emit(‘tick’, m); }; amqpCon.queue(“”, {}, function(queue) { queue.bind(“myExchange”, “myBindingKey”); queue.subscribe(amqpMessageHandler); });});

Handle socket.io connection

Subscribe to AMQP queue

Republish as socket.io event

Page 54: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Example browser application

var socket = io.connect(location.hostname);

function ClockModel() { self.ticker = ko.observable(1); socket.on('tick', function (data) { self.ticker(data); });};

ko.applyBindings(new ClockModel());

<html><body>

The event is <span data-bind="text: ticker"></span>

<script src="/socket.io/socket.io.js"></script><script src="/knockout-2.0.0.js"></script><script src="/clock.js"></script>

</body></html>

clock.js

Connect to socket.io server

Subscribe to tick event

Bind to model

Update model

Page 55: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Cujojs & s2js

JavaScript

Dependency Injection

Aspect-Oriented

Programming

Portable Service

Abstractions

www.cujojs.com github.com/s2js

Page 56: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Presentation layer design

• Using NoSQL databases

• Inter-service communication options

Page 57: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Why NoSQL?

Benefits

• Higher performance

• Higher scalability

• Richer data-model

• Schema-less

Drawbacks

• Limited transactions

• Limited querying

• Relaxed consistency

• Unconstrained data

Page 58: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Example NoSQL Databases

Database Key features

Cassandra Extensible column store, very scalable, distributed

Neo4j Graph database

MongoDB Document-oriented, fast, scalable

Redis Key-value store, very fast

http://nosql-database.org/ lists 122+ NoSQL databases

Page 59: Developing modular, polyglot applications with Spring (SpringOne India 2012)

NoSQL and the scale cube

MongoDB replica setsCassandra replication

Mongo

DB sha

rding

Cassan

dra

parti

tionin

g

Page 60: Developing modular, polyglot applications with Spring (SpringOne India 2012)

The future is polyglot

IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg

Page 61: Developing modular, polyglot applications with Spring (SpringOne India 2012)

StoreFrontUI

storefront web application

AccountingService

accounting application

InventoryService

inventory application

ShippingService

shipping application

MySQL

Polyglot persistence architecture

Redis

Mongo

Page 62: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring Data = simplifying data access

http://www.springsource.org/spring-data

•Redis

•MongoDB

•Neo4j

• JPA

• REST

• Apache Hadoop

• Gemfire

Page 63: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Agenda

• The (sometimes evil) monolith

• Refactoring to a modular, polyglot architecture

• Presentation layer design

• Using NoSQL databases

• Inter-service communication options

Page 64: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Inter-service communication options

• Synchronous HTTP ⇔ asynchronous AMQP

• Formats: JSON, XML, Protocol Buffers, Thrift, ...

• JSON is fashionable and easier to debug

• Binary format is more efficient

Page 65: Developing modular, polyglot applications with Spring (SpringOne India 2012)

StoreFrontUI

wgrus-store.war

AccountingService

wgrus-billing.war

InventoryService

wgrus-inventory.war

ShippingService

wgrus-shipping.war

MySQL

RabbitMQ(Message Broker)

Asynchronous message-based communication

Page 66: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Benefits

•Decouples caller from server

• Caller unaware of server’s coordinates (URL)

•Message broker buffers message when server is down/slow

• Supports a variety of communication patterns

Page 67: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Drawbacks

• Additional complexity of message broker

• Request/reply using messaging is more complex

• Firewall unfriendly

Page 68: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring AMQP

• Encapsulates low-level details

• Simplifies sending and receiving of messages

Producer

Spring AMQP

AMQP

AmqpTemplate

Consumer

ListenerContainer

Page 69: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring Integration• Provides the building blocks for a pipes and

filters architecture

• Enables development of application components that are

• loosely coupled

• insulated from messaging infrastructure

• Messaging defined declaratively

Page 70: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Order Service

Messaging Gateway

Channel Service Activator

Shipping service

Development time: same JVM@Servicepublic class OrderServiceImpl {

@Autowiredprivate ShippingService shippingService;

public void placeOrder() { String orderId = generateOrderId(); … shippingService.shipOrder(orderId);}

}

@Servicepublic class ShippingServiceImpl {

public void shipOrder(String orderId) { ....}

}

shipOrder()

Page 71: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Order Service

Messaging Gateway

Channel Service Activator

Shipping service

AMQP

RabbitMQ

AMQP Channel

Test and production: distributed

Application code is unchanged

Page 72: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Synchronous REST

ShippingService

StoreFrontUI

wgrus-store.war

AccountingService

wgrus-billing.war

wgrus-shipping.war

InventoryService

wgrus-inventory.war

MySQL

REST

...

Page 73: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Pros and cons of REST

• Pros

• Simple and familiar

• Request/reply is easy

• Firewall friendly

•No intermediate broker

• Cons

•Only supports request/reply

• Server must be available

• Client needs to know URL(s) of server(s)

Page 74: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring MVC makes REST easy@Controllerpublic class AccountController {

@Autowired private MoneyTransferService moneyTransferService; @RequestMapping(value = "/accounts/{accountId}", method = RequestMethod.GET) @ResponseBody public AccountInfo getAccount(@PathVariable String accountId) { Account account = moneyTransferService.findAccountByid(accountId); return makeAccountInfo(account); }

@RequestMapping(value = "/accounts", method = RequestMethod.POST) @ResponseStatus( HttpStatus.CREATED ) public void createAccount(@RequestBody AccountInfo accountInfo, UriComponentsBuilder builder, HttpServletResponse response) { ... }

URL matching &

destructuringobject ⇒XML/JSON

XML/JSON ⇒

object

Page 75: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Not all APIs are RESTful

From http://martinfowler.com/articles/richardsonMaturityModel.html

Page 76: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About Hypertext As The Engine Of Application State

• Single well known URL

• Entity representation has typed relationship links

• Client discovers what it can do to an entity via those links

See http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Page 77: Developing modular, polyglot applications with Spring (SpringOne India 2012)

About HATEOAS

$ curl http://cf-auto-scaler.cloudfoundry.com{"links": [ {"rel":"autoscaledapps", "href":"http://cf-auto-scaler.cloudfoundry.com/autoscaledapps"}]}

The well known URL

Linklink type

$ curl http://cf-auto-scaler.cloudfoundry.com/autoscaledapps{"content":[ {"name":"vertx-clock", "links":[ {"rel":"self","href":"http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock"}, {"rel":"rules","href":"http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules"} ] }],...}

Links to act on this app

Page 78: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring HATEOAS@Controller@RequestMapping(value = "/autoscaledapps")public class AutoscaledAppController {

@RequestMapping(value = "/{appName}", method = RequestMethod.GET) public HttpEntity<AutoscaledAppResource> get(@PathVariable String appName) { AutoscaledAppResource ar = new AutoscaledAppResource(appName); ar.add(linkTo(AutoscaledAppController.class)

.slash(appName).withSelfRel()); ar.add(linkTo(AutoscaledAppController.class)

.slash(appName).slash("rules").withRel("rules")); return new HttpEntity<AutoscaledAppResource>(ar); } ...}

https://github.com/SpringSource/spring-hateoas

public class AutoscaledAppResource extends ResourceSupport {

private String name;

Page 79: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Consuming RESTful WS

RestTemplate restTemplate = new RestTemplate();

AccountInfo accountInfo = new AccountInfo(...);URI accountUrl = restTemplate.postForLocation("http://localhost/accounts", accountInfo);

ResponseEntity<AccountInfo> accountInfoResponse = restTemplate.getForEntity(accountUrl, AccountInfo.class);

Assert.assertEquals(HttpStatus.SC_OK, accountInfoResponse.getStatusCode());AccountInfo accountInfo2 = accountInfoResponse.getBody();...

Page 80: Developing modular, polyglot applications with Spring (SpringOne India 2012)

The Spring REST shell$ rest-shellhttp://localhost:8080:> baseUri http://cf-auto-scaler.cloudfoundry.comhttp://cf-auto-scaler.cloudfoundry.com:> discoverrel href =======================================================================autoscaledapps http://cf-auto-scaler.cloudfoundry.com/autoscaledapps

http://cf-auto-scaler.cloudfoundry.com:> follow --rel autoscaledapps

http://cf-auto-scaler.cloudfoundry.com/autoscaledapps:> post --from src/test/resources/examplejson/createapp1.json --follow true

1 files uploaded to the server using POSThttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock:> discoverrel href ================================================================================self http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock rules http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/ruleshttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock:> follow --rel rules http://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules:> post

--from src/test/resources/examplejson/createrule1.json --follow true1 files uploaded to the server using POSThttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules/idle:> uphttp://cf-auto-scaler.cloudfoundry.com/autoscaledapps/vertx-clock/rules:> up

Page 81: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Original architecture

Tomcat

Browser

WAR

MySQL Database

ShippingService

AccountingService

InventoryService

StoreFrontUI

developtestdeploy

Simple to

Apache

scale

Page 82: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Inventory Service Shipping

NodeJS

Modular, polyglot architecture

RabbitMQ

NodeJS

Inventory Service Shipping Service

Billing Service Redis Inventory Database

Mongo Order Database

Standalone“headless”

Spring Integration/Java

applications

Spring/Scala web application

MySQL Customer Database

Desktop Browser Native Mobile application HTML5 mobile application

StoreUI StoreUI StoreUI

StoreUIJavascriptAsynchronous,

scalable communication

How

do w

e dep

loy

this!

?!

Page 83: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Applica'on  Service  Interface

OSS community

Private  Clouds  

PublicClouds

MicroClouds

Data Services

Other Services

Msg Services

vFabric Postgres

vFabric RabbitMQTM

Additional partners services …

Page 84: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Cloud Foundry simplifies the deployment of modular, polyglot

applications

Page 85: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Spring makes it easy to consume Cloud Foundry services

Page 86: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Many Spring applications run on Cloud Foundry unchanged

Page 87: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Summary

•Modern applications have a modular, polyglot architecture

•Spring is the ideal technology for building these applications

•Cloud Foundry is the ideal way to deploy these applications

Page 88: Developing modular, polyglot applications with Spring (SpringOne India 2012)

Thank you!

@crichardson [email protected]://plainoldobjects.com

www.cloudfoundry.com @cloudfoundry