Using Grails to power your electric car
Upcoming SlideShare
Loading in...5
×
 

Using Grails to power your electric car

on

  • 1,655 views

 

Statistics

Views

Total Views
1,655
Views on SlideShare
1,522
Embed Views
133

Actions

Likes
1
Downloads
3
Comments
0

1 Embed 133

https://twitter.com 133

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Using Grails to power your electric car Using Grails to power your electric car Presentation Transcript

  • Using Grails to poweryour Electric Car
  • Small Intro● Marco Pas (1973)› Education in Chemistry and thenmoved to Transportation & Logisticsto finally IT.. what is next?● Software Engineer● Burgundian lifestyleWikipedia tells us :enjoyment of life, good food,and extravagant spectacle
  • Agenda● What the heck am I trying to solve!!● How on earth did we solve it?● What are our plans for the future? View slide
  • Disclaimer.... View slide
  • Electric Cars vs Electric Vehicles
  • Convention Fueling != Electric Vehicle Charging● EV Charging Challenges:› Impossible to store & forward electricity› Charge often (Limited Range)› Time to charge (from minutes to hours)› Compatibility (plugs, charging cables)
  • Not kidding... !!Range Anxiety Reducer :)
  • Public EV Chargers in numbers● 2011: EU 12.000● 2020: EU 660.0002011 2020Denmark 280 5.000Germany 1.900 150.000Italy 1.300 125.000Netherlands 1.700 32.000United Kingdom 703 122.000
  • EV Chargers in the wild
  • Charging ProcessBack OfficeValidation / Verification● Is the card valid?● Electricity pricing?● How much can I charge?● Who is the customer?● Did you make a reservation?● ….
  • Stakeholders involved in EV Charging
  • How to manageall those(different kind of)Chargers?Stakeholders?Processes?
  • Requirements● Implement a platform that enables EV Infra management:› To monitor a Charge Point (CP) network› Supports remote management› Track charging sessions● Including charge authorization &transaction storage› Multi-tenancy› 3rdparty integration using Web Services (SOAP / REST)
  • Schematic overview of a Charge Point
  • Open Charge Point Protocol (OCPP)● Open protocol between charging stations and a managing centralsystem aka back office› Asynchronous› Based on SOAP (v1.2)› Working group with support from all manufacturers!
  • Agenda● What the heck am I trying to solve!!● How on earth did we solve it?● What are our plans for the future?
  • Release 1.0!! SOAP ~ Contract First with Grails was not that easy, so we moved to a pure JAVA/Spring OCPP application
  • Jackson JSON Mapperpublic class JsonMapper extends ObjectMapper {public JsonMapper() {super();/*** De-Serialization options JSON -> OBJECT*/// - ignore unknown fields - otherwise the construction of the object will fail!this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// - make it possible to also construct empty objectsthis.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);/*** Serialization options OBJECT -> JSON*/// properties with non-null values are to be included in the resulting JSONthis.setSerializationInclusion(JsonInclude.Include.NON_NULL);}}
  • Jackson JSON Mapper● JSON → Object● Object → JSONresources.groovybeans = {// a preconfigured Jackson JSON mapper with defaultsjsonMapper(JsonMapper){}}def jsonContent = “{name: John Doe}”Person person = jsonMapper.readValue(jsonContent, Person.class)Person person = new Person(name: John Doe)def jsonContent = jsonMapper.valueToTree(person)
  • Theming support● Login-Logout & user configurable themes● Using Spring Security Core PluginConfig.groovy// make sure we can act on security eventsgrails.plugins.springsecurity.useSecurityEventListener = true// executed when a user succesfully authenticates into the applicationgrails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx →// .. code intentionally emitted .. //session.theme = “MyNameOfTheTheme”}page.gsp<g:if test="${session?.theme == null}"><% session.theme="${grailsApplication.config.default.theme}"%></g:if><r:require module="${session?.theme}"/><g:external uri="/css/themes/${session?.theme - "theme_"}/images/favicon.ico"/>
  • Chargepoint Overview
  • Pool Overview
  • Nokia Maps – Heat Map
  • Technical Debt● Client was very happy but.... shame on us:› Tightly coupled› Poor test coverage› Spring project & Grails project› Adding functional value is just to much fun!● But... ready for round 2..› Thanks to Grails we could refactor with great ease and speed!
  • Release 2.0● Guidelines:› Focus on creating a modular platform› Test Driven Development› Use Grails for everything!!› Minimize the use of plugins!!!
  • Grails CXF Plugin● WSDL› Contract First & Code First● Wire Interceptors› Logging, Security● Support for versioning@GrailsCxfEndpoint(address=/myCustomSoapService/v2/)
  • Annotated example@GrailsCxfEndpoint(address=/centralsystem/ocpp/v1/5,wsdl = wsdl/ocpp_15_centralsystem.wsdl,expose = EndpointType.JAX_WS_WSDL,soap12 = true,inInterceptors = ["logSoapInboundInterceptor", "setReplyToSOAPHeaderInInterceptor"],outInterceptors = ["logSoapOutboundInterceptor"])@WebService(name = "CentralSystemService",targetNamespace = "urn://Ocpp/Cs/2012/06/",serviceName = "CentralSystemService",portName = "CentralSystemServiceSoap12")@GZIPclass CentralSystemOcpp15Service implements CentralSystemService {// ... code intentionally omitted// ... contains the methods that needs to be implemented due to the implements}
  • Demo● Create a contract first webservice using Grails CXF plugin› Source WSDL: CustomerService.wsdl› Steps:● Create grails project● Install CXF plugin● Use WSDL2JAVA to generate web service implementation● Create Grails service that implements the web service interface● Test using SOAPUI
  • AMQP - Advanced Message Queuing Protocol● Asynchronous and synchronous message exchange› Enables modular platform architecture
  • RabbitMQ – an AMQP implementation● Grails RabbitMQ Plugin› High-level abstraction for sending and receiving messages› Fallback to Spring Templateclass MessageReceiveService {static rabbitQueue = helloQvoid handleMessage(message) {// handle message…}}class MessageSendController {def sendMessage = {rabbitSend helloQ, Hello!}}
  • RabbitMQ Synchronousclass MessageSendController {def rabbitTemplate // use the Spring rabbitTemplate directlydef sendMessage = {def response = rabbitTemplate.convertSendAndReceive helloQ, Hello Worldprintln response}}class MessageReceiveService {static rabbitQueue = [queues: helloQ, messageConverterBean: ]void handleMessage(Message message) {// determine the reply queuedef returnQueue = message.messageProperties.replyTo// return the response to temporary return queue..rabbitSend returnQueue, Hello there}}
  • Demo● Send and Consume a message via RabbitMQ› Steps:● Install RabbitMQ plugin● Configure Grails app to use RabbitMQ● Create code to publish and consume a message
  • Testing● Functional & Unit Testing› Build-Test-Data› Spock● Load & Performane Testing› BadBoy / Apache JMeter
  • Some stuff we have used● Grails Plugins› Spring Security› Export› RabbitMQ› CXF› Fixture› Spock› Build-Test-Data● Non-Plugins› Twitter BootStrap› Jackson JSON
  • Agenda● What the heck am I trying to solve!!● How on earth did we solve it?● What are our plans for the future?
  • Release 3.0● Additional protocol implementation in JSON› Eliminating the verbosity of SOAP!› To ([<MessageTypeId>, “<UniqueId>”, “<Action>”, {<Payload>}])<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:cp="urn://Ocpp/Cp/2012/06/" xmlns:cs="urn://Ocpp/Cs/2012/06/"xmlns:imp="urn://iMOVE/Cp/2011/09/" xmlns:ims="urn://iMOVE/Cs/2011/09/"><SOAP-ENV:Header><wsa5:MessageID>940</wsa5:MessageID><wsa5:From><wsa5:Address>http://127.0.0.1:1234</wsa5:Address></wsa5:From><wsa5:ReplyTo SOAP-ENV:mustUnderstand="true"><wsa5:Address>http://127.0.0.1:1234</wsa5:Address></wsa5:ReplyTo><wsa5:To SOAP-ENV:mustUnderstand="true">http://www.starwarsrules.com/services/centralsystem/ocpp/v1/5</wsa5:To><wsa5:Action SOAP-ENV:mustUnderstand="true">/Heartbeat</wsa5:Action><cs:chargeBoxIdentity SOAP-ENV:mustUnderstand="true">CHARGER_001_1234</cs:chargeBoxIdentity></SOAP-ENV:Header><SOAP-ENV:Body><cs:heartbeatRequest /></SOAP-ENV:Body></SOAP-ENV:Envelope>[2, “19223201”, “HeartBeat”, {“”}]<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:cp="urn://Ocpp/Cp/2012/06/" xmlns:cs="urn://Ocpp/Cs/2012/06/"xmlns:imp="urn://iMOVE/Cp/2011/09/" xmlns:ims="urn://iMOVE/Cs/2011/09/"><SOAP-ENV:Header><wsa5:MessageID>940</wsa5:MessageID><wsa5:From><wsa5:Address>http://127.0.0.1:1234</wsa5:Address></wsa5:From><wsa5:ReplyTo SOAP-ENV:mustUnderstand="true"><wsa5:Address>http://127.0.0.1:1234</wsa5:Address></wsa5:ReplyTo><wsa5:To SOAP-ENV:mustUnderstand="true">http://www.starwarsrules.com/services/centralsystem/ocpp/v1/5</wsa5:To><wsa5:Action SOAP-ENV:mustUnderstand="true">/Heartbeat</wsa5:Action><cs:chargeBoxIdentity SOAP-ENV:mustUnderstand="true">CHARGER_001_1234</cs:chargeBoxIdentity></SOAP-ENV:Header><SOAP-ENV:Body><cs:heartbeatRequest /></SOAP-ENV:Body></SOAP-ENV:Envelope>
  • Release 3.0● Using WebSockets for full-duplex communication
  • WebSockets● Defines an API establishing a "socket" connections between aclient and a server› Providing full-duplex communicationchannel over a single TCPconnection› HTTP upgrade byProtocol Negotiation› Firewall friendly! (port 80)› No reconnect handling or guaranteedmessage delivery
  • WebSocket handshake● Client Request● Server ResponseGET /mychat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chatSec-WebSocket-Version: 13Origin: http://example.comHTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat
  • WebSocket API Hooks
  • Vertx.io● Asynchronous Application Development› Polyglot, Simplicity, Scalability, Concurrency› Distributed Event Bus› WebSocket support● VerticlesServer.groovyvertx.createHttpServer().requestHandler { req ->req.response.headers().put("Content-Type", "text/html; charset-UTF-8");req.response.end("<html><body><h1>Hello from vert.x!</h1></body></html>");}.listen(8080)vertx run Server.groovyvertx run Server.groovy -instances 4
  • Thank you!!http://twitter.com/marcopasmarco.pas@ihomer.nlhttp://www.linkedin.com/in/marcopas