SlideShare une entreprise Scribd logo
1  sur  86
DEVELOPING WITH CLOUD
SERVICES
Chris Richardson
Author of POJOs in Action
Founder of the original CloudFoundry.com
@crichardson
chris.richardson@springsource.com
http://plainoldobjects.com
@crichardson
Presentation goal
How to build robust,
scalable applications with
Cloud Services
@crichardson
About Chris
@crichardson
(About Chris)
@crichardson
About Chris()
@crichardson
About Chris
@crichardson
About Chris
http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/
@crichardson
vmc push About-Chris
Developer Advocate for
CloudFoundry.com
@crichardson
Agenda
• Why use cloud services?
• Developing location-based applications
• Building SMS and telephony enabled applications
• Developing robust, fault tolerant applications
@crichardson
Three phases of every galactic
civilization
Survival
Inquiry
Sophistication
@crichardson
Three phases of every galactic
civilization
How
Why
Where
can we eat?
do we eat?
Where shall we have lunch?
@crichardson
Where shall we
have lunch?
@crichardson
Solved byVoteMeetEat.com
•What restaurants are nearby?
•Which friends are close by?
•Where do your friends prefer to eat?
To sign up text
"register" to 510-
XXX-YYYY
@crichardson
VoteMeetEat.com
Friend and restaurant location databases
+
SMS
+
Voice calls
To sign up text
"register" to 510-
XXX-YYYY
@crichardson
Key story: registration
5
551212
@crichardson
Key story: registration
+5105551212
@crichardson
Key story: voting
555 1212
@crichardson
Key story: announce location
VOTEMEETEAT.COM
To sign up text
"register" to 510-
XXX-YYYY
@crichardson
High-level architecture
VoteMeet
Eat
Telephony
Integration
Friend Geo
Database
Restaurant
Database
Mobile
Phone
Do we really want to
build all this?
DIY = DIFFICULT
@crichardson
Use cloud-based services
• Highly scalable services
• Someone else’s headache to develop and maintain
• Provided by IaaS/PaaS
• Provided by 3rd party
@crichardson
Cloud Foundry services
@crichardson
Thousands of 3rd party services
http://www.programmableweb.com/apis/directory
http://www.slideshare.net/jmusser/j-musser-apishotnotgluecon2012
@crichardson
• Predominantly REST
• Predominantly JSON
• > billion API calls/day:Twitter, Google, Facebook, Netflix,
Accuweather, ...
• Increasing number of API-only companies
http://www.slideshare.net/jmusser/j-musser-apishotnotgluecon2012
Cloud service trends
@crichardson
Diverse
@crichardson
Benefits of cloud services
• Someone else’s headache to develop and operate
• Focus on your core business problem
• Get up and running quickly
• Elasticity
• Capex Opex
@crichardson
Drawbacks of cloud services
• Complexity and drawbacks of a distributed system
• You are dependent on service provider
@crichardson
Risks of cloud services
Urban Airship’s Strategic Partnership With
SimpleGeoTurns Into An Acquisition
@crichardson
Cloud Services-based
architecture
VoteMeetEat
Twilio
MongoDB
Factual.Com
Mobile
Phone
@crichardson
DEMO
@crichardson
Agenda
• Why use cloud services?
• Developing location-based applications
• Building SMS and telephony enabled applications
• Developing robust, fault tolerant applications
@crichardson
Location-based services are hot!
@crichardson
Client-side APIs for finding
location
W3C Geolocation API
@crichardson
BUT what about the server-side?
@crichardson
Lots of really difficult problems
•Scalable, spatial database – CRUD records, find nearby
•Data management – database of places, street information
•Forward geo-coding: address lat/lon
•Reverse geo-coding: lat/lon address
•Maps
•Directions
Easier to use Geo-aaS
@crichardson
Examples of Geo-aaS
Beware the terms of
service
• Maps
• Forward and reverse geocoding
• Directions
• Elevation
• Places
• Freely available geographic
database
• Various APIs including
reverse geocoding
• Business+review database
• Neighborhood database
• Places database
• Reverse geocoding
@crichardson
VoteMeetEat.com & Geo
trait FriendService {
def addOrUpdate(request : AddOrUpdateUserRequest)
def findNearbyFriends(request : NearbyFriendsRequest) :
FindNearbyFriendsResponse
}
trait RestaurantService {
def findNearbyRestaurants(location: Location) :
FindNearbyRestaurantResponse
}
@crichardson
trait FriendService {
def addOrUpdate(request : AddOrUpdateUserRequest)
def findNearbyFriends(request : NearbyFriendsRequest) :
FindNearbyFriendsResponse
}
Implementing the friends
database
@crichardson
MongoDB
• Document-oriented database
• Very fast, highly scalable and available
• Rich query language that supports location-
based queries
• Provided by CloudFoundry.com
@crichardson
MongoDB server
Database: VoteMeetEat
Collection: friendRecord
Storing friends in MongoDB
{
"_id": "+15105551212",
"name": "Chris R.",
"location": {
"x": -122.25206103187264,
"y": 37.847427441773796
}
}
@crichardson
Spring Data for MongoDB
• Provides MongoTemplate
• Analogous to JdbcTemplate
• Hides boilerplate code
• Domain object Document mapping
@crichardson
Using Spring data: creating an
index on location attribute
@Component
class MongoFriendService extends FriendService {
@Autowired
var mongoTemplate: MongoTemplate = _
@PostConstruct
def createGeoIndex {
val dbo = new BasicDBObject
dbo.put("location", "2d")
mongoTemplate.getCollection("friendRecord").ensureIndex(dbo)
}
Create geospatial 2d index
Collection name
Attribute and
index type
@crichardson
Using Spring Data: adding record
@Component
class MongoFriendService extends FriendService {
override def addOrUpdate(request: AddOrUpdateUserRequest) = {
val name = request.name
val phoneNumber = request.phoneNumber
val fr = new FriendRecord(phoneNumber, name,
new Point(request.longitude, request.latitude))
mongoTemplate.save(fr)
}
case class FriendRecord(id : String,
name : String,
location : Point)
@crichardson
Using Spring Data: finding nearby
friends
@Component
class MongoFriendService extends FriendService {
override def findNearbyFriends(request: NearbyFriendsRequest) = {
val location = new Point(request.longitude, request.latitude)
val distance = new Distance(3, Metrics.MILES)
val query = NearQuery.near(location).maxDistance(distance)
val result = mongoTemplate.geoNear(query, classOf[FriendRecord])
val nearby = result.getContent.map(_.getContent)
FindNearbyFriendsResponse(nearby.map(f => FriendInfo(f.name, f.id)))
}
@crichardson
MongoDB and Cloud Foundry
$ vmc create-service mongodb vme-mongo
@crichardson
$ vmc push vme-user --path web/target/
Application Deployed URL [cer-spring.cloudfoundry.com]:
Detected a Java SpringSource Spring Application, is this correct? [Yn]:
Memory Reservation (64M, 128M, 256M, 512M, 1G) [512M]:
Creating Application: OK
Would you like to bind any services to 'vme-user'? [yN]: y
Would you like to use an existing provisioned service? [yN]: y
The following provisioned services are available
1: vme-mongo
2: mysql-135e0
Please select one you wish to use: 1
Binding Service [vme-mongo]: OK
Uploading Application:
Checking for available resources: OK
Processing resources: OK
Packing application: OK
Uploading (12K): OK
Push Status: OK
Binding a service to an application
Would you like to bind any services to 'vme-user'? [yN]: y
Would you like to use an existing provisioned service? [yN]: y
The following provisioned services are available
1: vme-mongo
2: mysql-135e0
Please select one you wish to use: 1
Binding Service [vme-mongo]: OK
@crichardson
Connecting to MongoDB
	 <bean id="mongoTemplate"
class="org.springframework.data.mongodb.core.MongoTemplate">
	 	 <constructor-arg ref="mongoFactory" />
	 </bean>
	 <beans profile="default">
	 	 <mongo:db-factory id="mongoFactory" dbname="surveygeo" />
	 </beans>
	 <beans profile="cloud">
	 	 <cloud:mongo-db-factory id="mongoFactory" />
	 </beans>
Outside of Cloud Foundry
Inside Cloud Foundry
@crichardson
Implementing the restaurant
database
trait RestaurantService {
def findNearbyRestaurants(location: Location) :
FindNearbyRestaurantResponse
}
@crichardson
Using Factual
• Geographic database as a Service
• Including 1.2M restaurants in the US
• Pricing: 10K calls day free, pay per use
@crichardson
Factual API
• RESTful/JSON interface
• Uses 2-legged OAuth 1.0.
• Geo and text filters
• Pagination
• Libraries for various languages
@crichardson
Restaurant Service
@Service
class FactualRestaurantService extends RestaurantService {
@Value("${factual_consumer_key}") var consumerKey: String = _
@Value("${factual_consumer_secret}") var consumerSecret: String = _
var factual: Factual = _
@PostConstruct
def initialize {
factual = new Factual(consumerKey, consumerSecret, true)
}
override def findNearbyRestaurants(location: Location) = {
...
val restaurants = factual.get.fetch("restaurants-us",
new Query().within(new Circle(location.lat, location.lon, 1000)).limit(5))
val rs = restaurants.getData.map { map =>
RestaurantInfo(map.get("name").asInstanceOf[String])
}
FindNearbyRestaurantResponse(rs.toList)
}
...
5 restaurants within 1km
@crichardson
Agenda
• Why use cloud services?
• Developing location-based applications
• Building SMS and telephony enabled applications
• Developing robust, fault tolerant applications
@crichardson
The telephony and SMS are
important
http://blog.nielsen.com/nielsenwire/online_mobile/new-mobile-obsession-
u-s-teens-triple-data-usage/
7/ waking hr !
Nielsen
@crichardson
Reporting traffic light problems in London
@crichardson
Google 2-Factor authentication
@crichardson
VoteMeetEat.com &Telephony
• Handling registration SMS
• Sending SMS notifying users to vote
• Handling incoming voice call from voters:
• Text-to-speech of restaurants options
• Collecting digits entered via keypad
• Sending SMS/Voice notifications of voting results
@crichardson
DIY telephony = Difficult
• Difficult to setup and operate
• Expensive
• Complex SMS protocols
• …
Better to use SMS/Telephony-aaS:
@crichardson
Telephony/SMS - aaS
• SMS
• Inbound and outgoing calls
• Recording and transcription
• SMS
• Inbound and outgoing calls
• Recording and transcription
• Twitter
• IM
@crichardson
Twilio -Telephony and SMS as a
service
• REST API
• Allocate phone numbers
• Make and receive phone calls
• Send and receive SMS messages
• Pay per use:
• Phone calls - per-minute
• SMS – per SMS sent or received
• Phone number – per month
• Examples
• OpenVBX is a web-based, open source phone system
• StubHub – notifies sellers of a pending sale via phone
• SurveyMonkey – interactive polling
• Salesforce – SMS-based voting for 19,000 conference attendees
@crichardson
UsingTwilio
Twilio Your
Application
TwiML doc
HTTP GET/
POST
REST API
Manage resources
Send SMS
Initiate voice calls
Handle incoming SMS and voice calls
Respond to user input
Voice
SMS
Phone number
SMS URL +VOICE URL
@crichardson
Handling SMS registration
5
551212
User
texts
‘register’
System
replies
@crichardson
Handling SMS registration
Twilio
SMS
REGISTRATION
HTTP POST
http://≪smsUrl≫?From=≪PhoneNumber≫&
Body=≪Message≫&...
<Response>
<Sms>To complete registration please
go to http://...
</Sms>
</Response>
SMS
@crichardson
Handling SMS registration
TwiML document
describing the
response
@crichardson
Inviting users to vote
5551212555121255512125551212
System sends
text
@crichardson
Inviting users to vote
POST /2010-04-01/Accounts/≪AccountSID≫/SMS/Messages
From=+15105551212
&To=+14155551212
&Body=≪MESSAGE≫
Authorization: Basic ....
Basic auth usingTwilio
AccountSid+AuthToken
@crichardson
Sending SMS using the Spring
RestTemplate
@Component
class TwilioService {
	 def sendSms(recipient : String, message : String) = {
	 	 val response = postToTwilio("SMS/Messages",
	 	 Map("From" -> twilioPhoneNumber, "To" -> recipient, "Body" -> message))
	 	 (response  "SMSMessage"  "Sid").text
	 }
@crichardson
Sending SMS using the Spring
RestTemplate
@Component
class TwilioService {
def postToTwilio(resourcePath : String, requestParams : Map[String, String]) = {
	
	 val entity = makeEntity(requestParams)
	 try {
	 val response = restTemplate.postForObject(twilioUrl +
"/Accounts/{accountSid}/{resource}",
	 entity, classOf[String],
accountSid, resourcePath)
	 XML.loadString(response)
	 } catch {
	 case e : HttpClientErrorException if e.getStatusCode == HttpStatus.BAD_REQUEST =>
	 val body = e.getResponseBodyAsString()
	 val xmlBody = XML.loadString(body)
	 val code = Integer.parseInt((xmlBody  "Code").text)
	 val message = (xmlBody  "Message").text
	 throw new TwilioRestException(message, code)
	 }
}
@crichardson
Voting: user calls number
555 1212
@crichardson
Voting
Twilio
Survey Management
<Response>
<Say> Chris would like to meet and eat. </Say>
<Gather action="handleresponse.html"
method="POST" numDigits="1">
<Say>Press 1 for ....</Say>
<Say>Press 2 for ....</Say>
</Gather>
</Response>
HTTP POST
http://≪voiceUrl≫?From=≪PhoneNumber≫
Call
@crichardson
Voting
Twilio
Survey Management
<Response>
<Say>Thank you for choosing.
The most popular place so far is ...
</Say>
<Pause/>
<Say>You will hear from us soon. Good bye</Say>
<Hangup/>
</Response>
HTTP POST
http://....handleresponse.html?
From=≪PhoneNumber≫&Digits=≪...≫
Digits
@crichardson
Voting code 1
@Controller
class 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>
}
}
@crichardson
Voting code 2
class TwilioController {
...
@RequestMapping(value = Array("/handleresponse.html"))
@ResponseBody
def handleUserResponse(@RequestParam("From") callerId: String,
@RequestParam("Digits") digits: Int) = {
val survey = surveyManagementService.recordVote(callerId, digits)
<Response>
<Say>Thank you for choosing. The most popular place so far is
{ survey.map(_.mostPopularChoice) getOrElse "oops" }
</Say>
<Pause/>
<Say>You will hear from us soon. Good bye</Say>
<Hangup/>
</Response>
}
}
@crichardson
Agenda
• Why use cloud services?
• Developing location-based applications
• Building SMS and telephony enabled applications
• Developing robust, fault tolerant applications
@crichardson
The need for parallelism
Service A
Service B
Service C
Service D
b = serviceB()
c = serviceC()
d = serviceD(b, c)
Call in parallel
@crichardson
Futures are a great concurrency
abstraction
• Object that will contain the result of a concurrent computation -
http://en.wikipedia.org/wiki/Futures_and_promises
• Various implementations
• Java 7 Futures = ok
• Guava ListenableFutures = better
• Scala’s composable Futures = really good
• Java 8 CompletableFuture = great
Future<Integer> result =
executorService.submit(new Callable<Integer>() {... });
@crichardson
Using futures to parallelize requests
trait FriendService {
def findNearbyFriends(request : NearbyFriendsRequest) :
Future[FindNearbyFriendsResponse]
}
trait RestaurantService {
def findNearbyRestaurants(location: Location) :
Future[FindNearbyRestaurantResponse]
}
val f1 = friendsService.findNearbyFriends(NearbyFriendsRequest.fromLocation(vmeRecord.location))
val f2 = restaurantService.findNearbyRestaurants(vmeRecord.location)
val nearbyFriends = f1.get(2, TimeUnit.SECONDS)
val nearbyRestaurants = f2.get(2, TimeUnit.SECONDS)
Two calls execute concurrently
Client
Side
Proxies
@crichardson
Using external web services =
Distributed system
VoteMeetEat
Twilio
MongoDB
Factual.Com
Mobile
Phone
@crichardson
Internally = Distributed System
Survey
management
VME
management
Registration
SMS
Registration
web app
VME
web app
User
management
Rabbit
MQ
@crichardson
Handling failure
Service A Service B
Errors happen
in distributed systems
@crichardson
About Netflix
http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
> 1B API calls/day
1 API call average 6 service calls
Fault tolerance is essential
@crichardson
How to run out of threads
Tomcat
Execute thread
pool
HTTP Request
Thread 1
Thread 2
Thread 3
Thread n
Service A Service B
If service B is down
then thread will be
blocked
XX
X
X
X
Eventually all threads
will be blocked
@crichardson
Their approach
• Network timeouts and retries
• Invoke remote services via a bounded thread pool
• Use the Circuit Breaker pattern
• On failure:
• return default/cached data
• return error to caller
• https://github.com/Netflix/Hystrix
http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
@crichardson
@Service
class FactualRestaurantService extends RestaurantService {
@Autowired
@Qualifier("factualHystrixConfig")
var factualHystrixConfig: HystrixCommand.Setter = _
override def findNearbyRestaurants(location: Location) = {
class FindRestaurantsCommand
extends HystrixCommand[FindNearbyRestaurantResponse]
(factualHystrixConfig
.andCommandKey(HystrixCommandKey.Factory.asKey("FindRestaurantsCommand"))) {
override def run() = {
val restaurants = factual.fetch("restaurants",
new Query().within(new Circle(location.lat, location.lon, 1000)).limit(5))
val rs = for (map <- restaurants.getData) yield {
RestaurantInfo(map.get("name").asInstanceOf[String])
}
FindNearbyRestaurantResponse(rs.toList)
}
}
new FindRestaurantsCommand().queue()
}
}
Using Hystrix
@crichardson
Summary
Cloud services are highly scalable services developed and
operated by a 3rd party
Let’s you focus on your core business problem
Risk: provider is acquired and stops offering service
Developing an application that reliably consumes cloud
services requires careful design
@crichardson
Questions?
@crichardson chris.richardson@springsource.com
http://plainoldobjects.com - code and slides
Sign up for CloudFoundry.com

Contenu connexe

Similaire à Developing applications with Cloud Services (jax jax2013)

Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)Chris Richardson
 
Polyglot persistence for Java developers: time to move out of the relational ...
Polyglot persistence for Java developers: time to move out of the relational ...Polyglot persistence for Java developers: time to move out of the relational ...
Polyglot persistence for Java developers: time to move out of the relational ...Chris Richardson
 
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)Chuck Greb
 
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...Docker, Inc.
 
Develop a native application that uses GPS location.pptx
Develop a native application that uses GPS location.pptxDevelop a native application that uses GPS location.pptx
Develop a native application that uses GPS location.pptxvishal choudhary
 
Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Chris Richardson
 
The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?Chris Richardson
 
Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...
Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...
Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...MSDEVMTL
 
Multi-Cloud Micro-Services with CloudFoundry
Multi-Cloud Micro-Services with CloudFoundryMulti-Cloud Micro-Services with CloudFoundry
Multi-Cloud Micro-Services with CloudFoundrygeekclub888
 
Spring Days NYC - A pattern language for microservices
Spring Days NYC - A pattern language for microservicesSpring Days NYC - A pattern language for microservices
Spring Days NYC - A pattern language for microservicesChris Richardson
 
Kong Summit 2018 - Microservices: decomposing applications for testability an...
Kong Summit 2018 - Microservices: decomposing applications for testability an...Kong Summit 2018 - Microservices: decomposing applications for testability an...
Kong Summit 2018 - Microservices: decomposing applications for testability an...Chris Richardson
 
(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud
(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud
(MBL203) Drones to Cars: Connecting the Devices in Motion to the CloudAmazon Web Services
 
Real-time Microservices and In-Memory Data Grids
Real-time Microservices and In-Memory Data GridsReal-time Microservices and In-Memory Data Grids
Real-time Microservices and In-Memory Data GridsAli Hodroj
 
Multi cloud appcustomscale-appgroups-slideshare
Multi cloud appcustomscale-appgroups-slideshareMulti cloud appcustomscale-appgroups-slideshare
Multi cloud appcustomscale-appgroups-slideshareE Ting
 
Decompose your monolith: strategies for migrating to microservices (Tide)
Decompose your monolith: strategies for migrating to microservices (Tide)Decompose your monolith: strategies for migrating to microservices (Tide)
Decompose your monolith: strategies for migrating to microservices (Tide)Chris Richardson
 
Reaching out from ADF Mobile (ODTUG KScope 2014)
Reaching out from ADF Mobile (ODTUG KScope 2014)Reaching out from ADF Mobile (ODTUG KScope 2014)
Reaching out from ADF Mobile (ODTUG KScope 2014)Luc Bors
 
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...Chris Richardson
 
A pattern language for microservices - Chris Richardson
A pattern language for microservices - Chris RichardsonA pattern language for microservices - Chris Richardson
A pattern language for microservices - Chris RichardsonJAXLondon_Conference
 

Similaire à Developing applications with Cloud Services (jax jax2013) (20)

Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)
 
Polyglot persistence for Java developers: time to move out of the relational ...
Polyglot persistence for Java developers: time to move out of the relational ...Polyglot persistence for Java developers: time to move out of the relational ...
Polyglot persistence for Java developers: time to move out of the relational ...
 
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
Building Location-Aware Apps using Open Source (AnDevCon SF 2014)
 
Location based services
Location based servicesLocation based services
Location based services
 
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
 
Develop a native application that uses GPS location.pptx
Develop a native application that uses GPS location.pptxDevelop a native application that uses GPS location.pptx
Develop a native application that uses GPS location.pptx
 
Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)
 
The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?
 
Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...
Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...
Stephane Lapointe, Frank Boucher & Alexandre Brisebois: Les micro-services et...
 
Multi-Cloud Micro-Services with CloudFoundry
Multi-Cloud Micro-Services with CloudFoundryMulti-Cloud Micro-Services with CloudFoundry
Multi-Cloud Micro-Services with CloudFoundry
 
Spring Days NYC - A pattern language for microservices
Spring Days NYC - A pattern language for microservicesSpring Days NYC - A pattern language for microservices
Spring Days NYC - A pattern language for microservices
 
Kong Summit 2018 - Microservices: decomposing applications for testability an...
Kong Summit 2018 - Microservices: decomposing applications for testability an...Kong Summit 2018 - Microservices: decomposing applications for testability an...
Kong Summit 2018 - Microservices: decomposing applications for testability an...
 
(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud
(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud
(MBL203) Drones to Cars: Connecting the Devices in Motion to the Cloud
 
Real-time Microservices and In-Memory Data Grids
Real-time Microservices and In-Memory Data GridsReal-time Microservices and In-Memory Data Grids
Real-time Microservices and In-Memory Data Grids
 
Multi cloud appcustomscale-appgroups-slideshare
Multi cloud appcustomscale-appgroups-slideshareMulti cloud appcustomscale-appgroups-slideshare
Multi cloud appcustomscale-appgroups-slideshare
 
Decompose your monolith: strategies for migrating to microservices (Tide)
Decompose your monolith: strategies for migrating to microservices (Tide)Decompose your monolith: strategies for migrating to microservices (Tide)
Decompose your monolith: strategies for migrating to microservices (Tide)
 
Reaching out from ADF Mobile (ODTUG KScope 2014)
Reaching out from ADF Mobile (ODTUG KScope 2014)Reaching out from ADF Mobile (ODTUG KScope 2014)
Reaching out from ADF Mobile (ODTUG KScope 2014)
 
Core Location in iOS
Core Location in iOSCore Location in iOS
Core Location in iOS
 
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
 
A pattern language for microservices - Chris Richardson
A pattern language for microservices - Chris RichardsonA pattern language for microservices - Chris Richardson
A pattern language for microservices - Chris Richardson
 

Plus de Chris Richardson

More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternChris Richardson
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...Chris Richardson
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Chris Richardson
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsChris Richardson
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfChris Richardson
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Chris Richardson
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...Chris Richardson
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Chris Richardson
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 Chris Richardson
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureChris Richardson
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Chris Richardson
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled servicesChris Richardson
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Chris Richardson
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...Chris Richardson
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Chris Richardson
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...Chris Richardson
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationChris Richardson
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate PlatformChris Richardson
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolithChris Richardson
 
JFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
JFokus: Cubes, Hexagons, Triangles, and More: Understanding MicroservicesJFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
JFokus: Cubes, Hexagons, Triangles, and More: Understanding MicroservicesChris Richardson
 

Plus de Chris Richardson (20)

More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-pattern
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patterns
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled services
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders application
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate Platform
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith
 
JFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
JFokus: Cubes, Hexagons, Triangles, and More: Understanding MicroservicesJFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
JFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
 

Developing applications with Cloud Services (jax jax2013)

  • 1. DEVELOPING WITH CLOUD SERVICES Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson chris.richardson@springsource.com http://plainoldobjects.com
  • 2. @crichardson Presentation goal How to build robust, scalable applications with Cloud Services
  • 8. @crichardson vmc push About-Chris Developer Advocate for CloudFoundry.com
  • 9. @crichardson Agenda • Why use cloud services? • Developing location-based applications • Building SMS and telephony enabled applications • Developing robust, fault tolerant applications
  • 10. @crichardson Three phases of every galactic civilization Survival Inquiry Sophistication
  • 11. @crichardson Three phases of every galactic civilization How Why Where can we eat? do we eat? Where shall we have lunch?
  • 13. @crichardson Solved byVoteMeetEat.com •What restaurants are nearby? •Which friends are close by? •Where do your friends prefer to eat? To sign up text "register" to 510- XXX-YYYY
  • 14. @crichardson VoteMeetEat.com Friend and restaurant location databases + SMS + Voice calls To sign up text "register" to 510- XXX-YYYY
  • 19. VOTEMEETEAT.COM To sign up text "register" to 510- XXX-YYYY
  • 21. @crichardson Use cloud-based services • Highly scalable services • Someone else’s headache to develop and maintain • Provided by IaaS/PaaS • Provided by 3rd party
  • 23. @crichardson Thousands of 3rd party services http://www.programmableweb.com/apis/directory http://www.slideshare.net/jmusser/j-musser-apishotnotgluecon2012
  • 24. @crichardson • Predominantly REST • Predominantly JSON • > billion API calls/day:Twitter, Google, Facebook, Netflix, Accuweather, ... • Increasing number of API-only companies http://www.slideshare.net/jmusser/j-musser-apishotnotgluecon2012 Cloud service trends
  • 26. @crichardson Benefits of cloud services • Someone else’s headache to develop and operate • Focus on your core business problem • Get up and running quickly • Elasticity • Capex Opex
  • 27. @crichardson Drawbacks of cloud services • Complexity and drawbacks of a distributed system • You are dependent on service provider
  • 28. @crichardson Risks of cloud services Urban Airship’s Strategic Partnership With SimpleGeoTurns Into An Acquisition
  • 31. @crichardson Agenda • Why use cloud services? • Developing location-based applications • Building SMS and telephony enabled applications • Developing robust, fault tolerant applications
  • 33.
  • 34. @crichardson Client-side APIs for finding location W3C Geolocation API
  • 35. @crichardson BUT what about the server-side?
  • 36. @crichardson Lots of really difficult problems •Scalable, spatial database – CRUD records, find nearby •Data management – database of places, street information •Forward geo-coding: address lat/lon •Reverse geo-coding: lat/lon address •Maps •Directions Easier to use Geo-aaS
  • 37. @crichardson Examples of Geo-aaS Beware the terms of service • Maps • Forward and reverse geocoding • Directions • Elevation • Places • Freely available geographic database • Various APIs including reverse geocoding • Business+review database • Neighborhood database • Places database • Reverse geocoding
  • 38. @crichardson VoteMeetEat.com & Geo trait FriendService { def addOrUpdate(request : AddOrUpdateUserRequest) def findNearbyFriends(request : NearbyFriendsRequest) : FindNearbyFriendsResponse } trait RestaurantService { def findNearbyRestaurants(location: Location) : FindNearbyRestaurantResponse }
  • 39. @crichardson trait FriendService { def addOrUpdate(request : AddOrUpdateUserRequest) def findNearbyFriends(request : NearbyFriendsRequest) : FindNearbyFriendsResponse } Implementing the friends database
  • 40. @crichardson MongoDB • Document-oriented database • Very fast, highly scalable and available • Rich query language that supports location- based queries • Provided by CloudFoundry.com
  • 41. @crichardson MongoDB server Database: VoteMeetEat Collection: friendRecord Storing friends in MongoDB { "_id": "+15105551212", "name": "Chris R.", "location": { "x": -122.25206103187264, "y": 37.847427441773796 } }
  • 42. @crichardson Spring Data for MongoDB • Provides MongoTemplate • Analogous to JdbcTemplate • Hides boilerplate code • Domain object Document mapping
  • 43. @crichardson Using Spring data: creating an index on location attribute @Component class MongoFriendService extends FriendService { @Autowired var mongoTemplate: MongoTemplate = _ @PostConstruct def createGeoIndex { val dbo = new BasicDBObject dbo.put("location", "2d") mongoTemplate.getCollection("friendRecord").ensureIndex(dbo) } Create geospatial 2d index Collection name Attribute and index type
  • 44. @crichardson Using Spring Data: adding record @Component class MongoFriendService extends FriendService { override def addOrUpdate(request: AddOrUpdateUserRequest) = { val name = request.name val phoneNumber = request.phoneNumber val fr = new FriendRecord(phoneNumber, name, new Point(request.longitude, request.latitude)) mongoTemplate.save(fr) } case class FriendRecord(id : String, name : String, location : Point)
  • 45. @crichardson Using Spring Data: finding nearby friends @Component class MongoFriendService extends FriendService { override def findNearbyFriends(request: NearbyFriendsRequest) = { val location = new Point(request.longitude, request.latitude) val distance = new Distance(3, Metrics.MILES) val query = NearQuery.near(location).maxDistance(distance) val result = mongoTemplate.geoNear(query, classOf[FriendRecord]) val nearby = result.getContent.map(_.getContent) FindNearbyFriendsResponse(nearby.map(f => FriendInfo(f.name, f.id))) }
  • 46. @crichardson MongoDB and Cloud Foundry $ vmc create-service mongodb vme-mongo
  • 47. @crichardson $ vmc push vme-user --path web/target/ Application Deployed URL [cer-spring.cloudfoundry.com]: Detected a Java SpringSource Spring Application, is this correct? [Yn]: Memory Reservation (64M, 128M, 256M, 512M, 1G) [512M]: Creating Application: OK Would you like to bind any services to 'vme-user'? [yN]: y Would you like to use an existing provisioned service? [yN]: y The following provisioned services are available 1: vme-mongo 2: mysql-135e0 Please select one you wish to use: 1 Binding Service [vme-mongo]: OK Uploading Application: Checking for available resources: OK Processing resources: OK Packing application: OK Uploading (12K): OK Push Status: OK Binding a service to an application Would you like to bind any services to 'vme-user'? [yN]: y Would you like to use an existing provisioned service? [yN]: y The following provisioned services are available 1: vme-mongo 2: mysql-135e0 Please select one you wish to use: 1 Binding Service [vme-mongo]: OK
  • 48. @crichardson Connecting to MongoDB <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg ref="mongoFactory" /> </bean> <beans profile="default"> <mongo:db-factory id="mongoFactory" dbname="surveygeo" /> </beans> <beans profile="cloud"> <cloud:mongo-db-factory id="mongoFactory" /> </beans> Outside of Cloud Foundry Inside Cloud Foundry
  • 49. @crichardson Implementing the restaurant database trait RestaurantService { def findNearbyRestaurants(location: Location) : FindNearbyRestaurantResponse }
  • 50. @crichardson Using Factual • Geographic database as a Service • Including 1.2M restaurants in the US • Pricing: 10K calls day free, pay per use
  • 51. @crichardson Factual API • RESTful/JSON interface • Uses 2-legged OAuth 1.0. • Geo and text filters • Pagination • Libraries for various languages
  • 52. @crichardson Restaurant Service @Service class FactualRestaurantService extends RestaurantService { @Value("${factual_consumer_key}") var consumerKey: String = _ @Value("${factual_consumer_secret}") var consumerSecret: String = _ var factual: Factual = _ @PostConstruct def initialize { factual = new Factual(consumerKey, consumerSecret, true) } override def findNearbyRestaurants(location: Location) = { ... val restaurants = factual.get.fetch("restaurants-us", new Query().within(new Circle(location.lat, location.lon, 1000)).limit(5)) val rs = restaurants.getData.map { map => RestaurantInfo(map.get("name").asInstanceOf[String]) } FindNearbyRestaurantResponse(rs.toList) } ... 5 restaurants within 1km
  • 53. @crichardson Agenda • Why use cloud services? • Developing location-based applications • Building SMS and telephony enabled applications • Developing robust, fault tolerant applications
  • 54. @crichardson The telephony and SMS are important http://blog.nielsen.com/nielsenwire/online_mobile/new-mobile-obsession- u-s-teens-triple-data-usage/ 7/ waking hr ! Nielsen
  • 57. @crichardson VoteMeetEat.com &Telephony • Handling registration SMS • Sending SMS notifying users to vote • Handling incoming voice call from voters: • Text-to-speech of restaurants options • Collecting digits entered via keypad • Sending SMS/Voice notifications of voting results
  • 58. @crichardson DIY telephony = Difficult • Difficult to setup and operate • Expensive • Complex SMS protocols • … Better to use SMS/Telephony-aaS:
  • 59. @crichardson Telephony/SMS - aaS • SMS • Inbound and outgoing calls • Recording and transcription • SMS • Inbound and outgoing calls • Recording and transcription • Twitter • IM
  • 60. @crichardson Twilio -Telephony and SMS as a service • REST API • Allocate phone numbers • Make and receive phone calls • Send and receive SMS messages • Pay per use: • Phone calls - per-minute • SMS – per SMS sent or received • Phone number – per month • Examples • OpenVBX is a web-based, open source phone system • StubHub – notifies sellers of a pending sale via phone • SurveyMonkey – interactive polling • Salesforce – SMS-based voting for 19,000 conference attendees
  • 61. @crichardson UsingTwilio Twilio Your Application TwiML doc HTTP GET/ POST REST API Manage resources Send SMS Initiate voice calls Handle incoming SMS and voice calls Respond to user input Voice SMS Phone number SMS URL +VOICE URL
  • 63. @crichardson Handling SMS registration Twilio SMS REGISTRATION HTTP POST http://≪smsUrl≫?From=≪PhoneNumber≫& Body=≪Message≫&... <Response> <Sms>To complete registration please go to http://... </Sms> </Response> SMS
  • 64. @crichardson Handling SMS registration TwiML document describing the response
  • 65. @crichardson Inviting users to vote 5551212555121255512125551212 System sends text
  • 66. @crichardson Inviting users to vote POST /2010-04-01/Accounts/≪AccountSID≫/SMS/Messages From=+15105551212 &To=+14155551212 &Body=≪MESSAGE≫ Authorization: Basic .... Basic auth usingTwilio AccountSid+AuthToken
  • 67. @crichardson Sending SMS using the Spring RestTemplate @Component class TwilioService { def sendSms(recipient : String, message : String) = { val response = postToTwilio("SMS/Messages", Map("From" -> twilioPhoneNumber, "To" -> recipient, "Body" -> message)) (response "SMSMessage" "Sid").text }
  • 68. @crichardson Sending SMS using the Spring RestTemplate @Component class TwilioService { def postToTwilio(resourcePath : String, requestParams : Map[String, String]) = { val entity = makeEntity(requestParams) try { val response = restTemplate.postForObject(twilioUrl + "/Accounts/{accountSid}/{resource}", entity, classOf[String], accountSid, resourcePath) XML.loadString(response) } catch { case e : HttpClientErrorException if e.getStatusCode == HttpStatus.BAD_REQUEST => val body = e.getResponseBodyAsString() val xmlBody = XML.loadString(body) val code = Integer.parseInt((xmlBody "Code").text) val message = (xmlBody "Message").text throw new TwilioRestException(message, code) } }
  • 70. @crichardson Voting Twilio Survey Management <Response> <Say> Chris would like to meet and eat. </Say> <Gather action="handleresponse.html" method="POST" numDigits="1"> <Say>Press 1 for ....</Say> <Say>Press 2 for ....</Say> </Gather> </Response> HTTP POST http://≪voiceUrl≫?From=≪PhoneNumber≫ Call
  • 71. @crichardson Voting Twilio Survey Management <Response> <Say>Thank you for choosing. The most popular place so far is ... </Say> <Pause/> <Say>You will hear from us soon. Good bye</Say> <Hangup/> </Response> HTTP POST http://....handleresponse.html? From=≪PhoneNumber≫&Digits=≪...≫ Digits
  • 72. @crichardson Voting code 1 @Controller class 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> } }
  • 73. @crichardson Voting code 2 class TwilioController { ... @RequestMapping(value = Array("/handleresponse.html")) @ResponseBody def handleUserResponse(@RequestParam("From") callerId: String, @RequestParam("Digits") digits: Int) = { val survey = surveyManagementService.recordVote(callerId, digits) <Response> <Say>Thank you for choosing. The most popular place so far is { survey.map(_.mostPopularChoice) getOrElse "oops" } </Say> <Pause/> <Say>You will hear from us soon. Good bye</Say> <Hangup/> </Response> } }
  • 74. @crichardson Agenda • Why use cloud services? • Developing location-based applications • Building SMS and telephony enabled applications • Developing robust, fault tolerant applications
  • 75. @crichardson The need for parallelism Service A Service B Service C Service D b = serviceB() c = serviceC() d = serviceD(b, c) Call in parallel
  • 76. @crichardson Futures are a great concurrency abstraction • Object that will contain the result of a concurrent computation - http://en.wikipedia.org/wiki/Futures_and_promises • Various implementations • Java 7 Futures = ok • Guava ListenableFutures = better • Scala’s composable Futures = really good • Java 8 CompletableFuture = great Future<Integer> result = executorService.submit(new Callable<Integer>() {... });
  • 77. @crichardson Using futures to parallelize requests trait FriendService { def findNearbyFriends(request : NearbyFriendsRequest) : Future[FindNearbyFriendsResponse] } trait RestaurantService { def findNearbyRestaurants(location: Location) : Future[FindNearbyRestaurantResponse] } val f1 = friendsService.findNearbyFriends(NearbyFriendsRequest.fromLocation(vmeRecord.location)) val f2 = restaurantService.findNearbyRestaurants(vmeRecord.location) val nearbyFriends = f1.get(2, TimeUnit.SECONDS) val nearbyRestaurants = f2.get(2, TimeUnit.SECONDS) Two calls execute concurrently Client Side Proxies
  • 78. @crichardson Using external web services = Distributed system VoteMeetEat Twilio MongoDB Factual.Com Mobile Phone
  • 79. @crichardson Internally = Distributed System Survey management VME management Registration SMS Registration web app VME web app User management Rabbit MQ
  • 80. @crichardson Handling failure Service A Service B Errors happen in distributed systems
  • 81. @crichardson About Netflix http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html > 1B API calls/day 1 API call average 6 service calls Fault tolerance is essential
  • 82. @crichardson How to run out of threads Tomcat Execute thread pool HTTP Request Thread 1 Thread 2 Thread 3 Thread n Service A Service B If service B is down then thread will be blocked XX X X X Eventually all threads will be blocked
  • 83. @crichardson Their approach • Network timeouts and retries • Invoke remote services via a bounded thread pool • Use the Circuit Breaker pattern • On failure: • return default/cached data • return error to caller • https://github.com/Netflix/Hystrix http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
  • 84. @crichardson @Service class FactualRestaurantService extends RestaurantService { @Autowired @Qualifier("factualHystrixConfig") var factualHystrixConfig: HystrixCommand.Setter = _ override def findNearbyRestaurants(location: Location) = { class FindRestaurantsCommand extends HystrixCommand[FindNearbyRestaurantResponse] (factualHystrixConfig .andCommandKey(HystrixCommandKey.Factory.asKey("FindRestaurantsCommand"))) { override def run() = { val restaurants = factual.fetch("restaurants", new Query().within(new Circle(location.lat, location.lon, 1000)).limit(5)) val rs = for (map <- restaurants.getData) yield { RestaurantInfo(map.get("name").asInstanceOf[String]) } FindNearbyRestaurantResponse(rs.toList) } } new FindRestaurantsCommand().queue() } } Using Hystrix
  • 85. @crichardson Summary Cloud services are highly scalable services developed and operated by a 3rd party Let’s you focus on your core business problem Risk: provider is acquired and stops offering service Developing an application that reliably consumes cloud services requires careful design