Using Grails to power your electric car

  • 1,319 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,319
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
4
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Using Grails to poweryour Electric Car
  • 2. 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
  • 3. Agenda● What the heck am I trying to solve!!● How on earth did we solve it?● What are our plans for the future?
  • 4. Disclaimer....
  • 5. Electric Cars vs Electric Vehicles
  • 6. 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)
  • 7. Not kidding... !!Range Anxiety Reducer :)
  • 8. 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
  • 9. EV Chargers in the wild
  • 10. Charging ProcessBack OfficeValidation / Verification● Is the card valid?● Electricity pricing?● How much can I charge?● Who is the customer?● Did you make a reservation?● ….
  • 11. Stakeholders involved in EV Charging
  • 12. How to manageall those(different kind of)Chargers?Stakeholders?Processes?
  • 13. 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)
  • 14. Schematic overview of a Charge Point
  • 15. 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!
  • 16. Agenda● What the heck am I trying to solve!!● How on earth did we solve it?● What are our plans for the future?
  • 17. Release 1.0!! SOAP ~ Contract First with Grails was not that easy, so we moved to a pure JAVA/Spring OCPP application
  • 18. 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);}}
  • 19. 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)
  • 20. 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"/>
  • 21. Chargepoint Overview
  • 22. Pool Overview
  • 23. Nokia Maps – Heat Map
  • 24. 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!
  • 25. Release 2.0● Guidelines:› Focus on creating a modular platform› Test Driven Development› Use Grails for everything!!› Minimize the use of plugins!!!
  • 26. Grails CXF Plugin● WSDL› Contract First & Code First● Wire Interceptors› Logging, Security● Support for versioning@GrailsCxfEndpoint(address=/myCustomSoapService/v2/)
  • 27. 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}
  • 28. 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
  • 29. AMQP - Advanced Message Queuing Protocol● Asynchronous and synchronous message exchange› Enables modular platform architecture
  • 30. 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!}}
  • 31. 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}}
  • 32. 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
  • 33. Testing● Functional & Unit Testing› Build-Test-Data› Spock● Load & Performane Testing› BadBoy / Apache JMeter
  • 34. Some stuff we have used● Grails Plugins› Spring Security› Export› RabbitMQ› CXF› Fixture› Spock› Build-Test-Data● Non-Plugins› Twitter BootStrap› Jackson JSON
  • 35. Agenda● What the heck am I trying to solve!!● How on earth did we solve it?● What are our plans for the future?
  • 36. 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>
  • 37. Release 3.0● Using WebSockets for full-duplex communication
  • 38. 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
  • 39. 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
  • 40. WebSocket API Hooks
  • 41. 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
  • 42. Thank you!!http://twitter.com/marcopasmarco.pas@ihomer.nlhttp://www.linkedin.com/in/marcopas