Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Dynamically assembled REST Microservices using JAX-RS and... Microservices? - Neil Bartlett

1,166 views

Published on

OSGi Community Event 2016 Presentation by Neil Bartlett (Paremus)

REST microservices are a powerful tool for composing large-scale systems, and the standalone nature of a microservice helps to avoid it becoming part of a “big ball of mud” application. Given the power and success of microservices as inter-process modules, why stop there? OSGi has offered in-process microservices for nearly two decades, and uses them to great effect in modular applications.

The new OSGi JAX-RS whiteboard service allows dynamic OSGi services to be automatically exported as JAX-RS Resources, Filters or Applications. These “Microservice modules” can be easily shared or moved between frameworks, allowing you to benefit from a microservice structure that goes all the way down.

Background
Over the last decade there has been a significant shift in the way that many computer programs are written. The focus has changed from building larger, more monolithic applications that provide a single high-level function, to composing these high-level behaviours from groups of smaller, distributed services. This is generally known as a “microservice” architecture, indicating that the services are smaller and lighter weight than typical web services.

The standard for REST microservices in Java is known as JAX-RS. JAX-RS provides a simple annotation-based model in which POJOs can have their methods mapped to RESTful service invocations. There is automatic mapping of HTTP parameters, and of the HTTP response, based on the annotations, and the incoming HTTP Headers. JAX-RS also includes support for grouping these POJOs into a single Application artifact. This allows the POJOs to interact with one another, as well as to share configuration and runtime state. When used in JAX-RS these POJOs are known as JAX-RS resources.

Ideal JAX-RS resources are stateless, and are usually instantiated by the container. JAX-RS resources share many features with OSGi services, in that they provide a way for machines (or processes within a machine) to interact with one another through a defined contract. This synergy between JAX-RS resources and OSGi services is the driver for the OSGi JAX-RS whiteboard service, allowing OSGi services to be transparently exposed using JAX-RS.

Published in: Technology
  • Be the first to comment

Dynamically assembled REST Microservices using JAX-RS and... Microservices? - Neil Bartlett

  1. 1. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 OSGi Community Event 2016 co-located at EclipseCon Europe 2016 Dynamically assembled REST microservices using JAX-RS and... microservices? Neil Bartlett http://www.paremus.com info@paremus.com
  2. 2. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Introduction
  3. 3. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 What are Microservices?
  4. 4. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 What are Microservices? • Ignoring the “OSGi Services are microservices” argument for now! • Microservices are commonly understood to be: • Small, independently deployable units of functionality; • Decoupled from internal details; • Resilient to failure; • Potentially implemented in heterogeneous languages.
  5. 5. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 The Isolation Curve Monolithic Method Classes OSGi Isolation Cost Process VM Physical Server Regional Datacentre Datacentre on Mars Container “Microservices”
  6. 6. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Process/Container Level Isolation • Communication implies networking. • Serialisation, deserialisation, addressing, etc. • Many approaches taken over the years! • CORBA • RMI • COM • SOAP • DDS • Thrift, Avro, Protobuf …
  7. 7. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 RESTful Microservices
  8. 8. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 What is REST • REpresentational State Transfer – from Roy Fielding’s dissertation. • An architectural style that focuses on: • Resources vs Procedures • Limited set of operations (e.g. CRUD) • Flexibility and adaptability • Compliance with web and internet structures. • “It’s how the Web works”. • Bonus: plays nicely with caches and proxies. • Does not dictate message formats. Clients can request preferred format.
  9. 9. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Advantages of REST vs RPC • Excellent cross-language support compatibility. • Well defined behaviour, e.g. idempotency. • Adaptable — easier for client and server to evolve and deploy independently. • In theory unversioned, self-documenting APIs. • Clients can navigate links and “discover” the shape of the API.
  10. 10. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Disadvantages of REST vs RPC • Impedance mismatch with mainstream languages. • RPC is easier for quick-and-dirty jobs. • In practice, REST APIs are versioned… much to Fielding’s disgust! • See Docker, GitHub, etc. • In practice, clients do expect specific versions, and break on mismatch. • Coding a fully flexible, adaptive client is a lot of work!
  11. 11. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS
  12. 12. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS • Java API for RESTful Web Services. • Eases the impedance mismatch for writing REST resources in Java. • Java EE specification. • JSR 311 defined JAX-RS 1.1 in 2009. • JSR 339 defined JAX-RS 2.0 in 2013. • Added client API, async HTTP on server side, filters and interceptors.
  13. 13. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Resource Classes • JAX-RS allows us to define Resources as plain Java classes. • Annotations control how the resource responds to web requests: • @Path – specifies a relative path for the resource or a method • @GET, @PUT, @POST, @DELETE, @HEAD, @OPTIONS specify the HTTP request type for a resource method • @Produces – specifies the media type a method will produce • @Consumes – specifies the media type a method can accept
  14. 14. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Simple Example @Path(“foo”) public class Foo { @GET @Path(“test”) @Produces(TEXT_PLAIN) public String getFoo() { return “hello”; } @GET @Path(“test”) @Produces(APPLICATION_JSON) public String getFooJson() { return “{‘hello’:’’}”; } } • The JAX-RS engine chooses which method to call based on the client’s Accept header. E.g. Accept: application/json
  15. 15. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Parameterised Paths @GET @Path(“test/{name}”) public String getFoo(@PathParam(“name”) String name) { return “hello ” + name; } • The JAX-RS engine chooses which method to call based on the client’s Accept header. E.g. Accept: application/json
  16. 16. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Field Injection @Path(“foo”) public class Foo { @Context HttpHeaders headers; @Context UriInfo uriInfo; @GET @Path(“test”) public String getFoo(String name) { headers.getRequestHeaders() .getFirst(“Last-Event-ID”); … } }
  17. 17. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Automatic Transformation • Use JAXB to define mapping to JSON or XML. • Saves complicated manual serialisation. • NB: Requires JAXB annotations on the Product class. @Path(“foo”) public class Foo { @GET @Produces({ APPLICATION_JSON, APPLICATION_XML }) public Product getProduct(String id) { Product p = // … return p; } }
  18. 18. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS in OSGi
  19. 19. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS in OSGi • Using JAX-RS directly in OSGi is tricky. • Resources configured by class name… not ideal in a modular world. • Could use the Web Application spec (WABs) but then we lose a lot of OSGi goodness like Declarative Services.
  20. 20. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS in OSGi • Mapping OSGi Services to JAX-RS is fairly obvious idea. • Whiteboard style: to provide a Resource, simply provide a Service. • Several open source implementations. • Most notably osgi-jaxrs-connector from EclipseSource. • Time to standardise! • Apply latest techniques and lessons from enRoute. • RFC 217 under development.
  21. 21. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS in OSGi • JAX-RS Resources are similar to Servlets. • We already have the Http Whiteboard… • Why not reuse it?
  22. 22. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS Resource Service • Publish a service of any type. • Attach marker property osgi.jaxrs.resource.base. • Marks the property as a JAX-RS resource, and defines the base URI. osgi.jaxrs.resource.base=example
  23. 23. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS Resource Component • Publish a service of any type. • Attach marker property osgi.jaxrs.resource.base. • Marks the property as a JAX-RS resource, and defines the base URI. @Component( service=Object.class, property=“osgi.jaxrs.resource.base=jaxrs") @Path(“foo”) public class Foo { @GET public String getFoo() { … } }
  24. 24. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS Resource Component • Note: service=Object.class • The component must be published as a service of some type. • The component does not implement an interface… • therefore bnd would not normally declare a service element. • The service attribute forces bnd to declare a service element.
  25. 25. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 What’s the Path? @Component( service=Object.class, property=“osgi.jaxrs.resource.base=example") @Path(“foo”) public class Foo { @GET @Path(“test”) public String getFoo() { … } } • http://<host>:<port>/example/foo/test
  26. 26. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Scopes • In “plain” JAX-RS, resources objects are created and destroyed on each request. • This doesn’t match the normal OSGi service lifecycle. • The previous example runs as a “singleton” in JAX-RS terms. • We can switch to prototype scope by specifying: scope=ServiceScope.PROTOTYPE
  27. 27. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Scopes • NB: don’t use injected @Context fields in a singleton! • Use as method parameters instead. • Or use prototype scope if the component is cheap to create. @GET @Path(“{name}”) public String getFoo( @PathParam(“name”) String name, @Context HttpHeaders headers) { // … }
  28. 28. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 JAX-RS Applications • Sometimes we cluster related Resources into an Application. • Applications are provided in the same way. • Note slightly different property declaration. @Component( service=Object.class, property=“osgi.jaxrs.application.base=example") @Path(“myapp”) public class MyApplication extends Application { @Override public Set<Class<?>> getClasses() { return Stream.of(MyResource1.class, MyResource2.class, …) .collect(toSet()); } }
  29. 29. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Endpoint Advertisement
  30. 30. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Problem • You are writing a microservices client… • Where is the back-end service?? • Choices: • Hard code URL; • Manually configure URL; • DNS tricks.
  31. 31. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 OSGi Remote Services • Remote Services is a specification for publishing and invoking services across a network. Provider Consumer Remote Services Provider Remote Services Provider ???
  32. 32. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Consuming REST Resources • But a REST resource cannot be invoked like a normal service! • We don’t use Remote Services this way. • The JAX-RS whiteboard provides an Endpoint service with no methods. • That service carries a property named osgi.jaxrs.uri • … the URI that can be used to access the JAX-RS resource.
  33. 33. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Consuming REST Resources REST Resource HTTP Server Endpoint URI=http://.../rest REST Client http
  34. 34. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Consuming REST Resources • Declarative Services code snippet. • Note: our component depends on the remote REST resource! • Can depend on multiple resources, using different target filters. • This component could be another JAX-RS resource! @Reference(target = “(osgi.jaxrs.name=MyResource)”) void setEndpoint(Endpoint ep, Map<String,Object> props) { this.uri = converter .convert(props.get(“osgi.jaxrs.uri”)) .to(String.class); } // Later… client.target(uri).request();
  35. 35. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Dynamically Connecting/Reconnecting, Self- Assembling Distributed Applications • If a part crashes, just restart anywhere else.
  36. 36. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Coding Clients • Use the JAX-RS 2.0 Client API. ClientBuilder is available as a service. • Integrated with OSGi Promises for async invocation. PromiseHandler<String> handler = new PromiseHandler<>(); clientBuilder.build() .target(uri) .path(“/foo”).path(“/{name}”) .resolveTemplate(“name”, getNameParam()) .request().async().get(handler); Promise<String> result = handler.getPromise();
  37. 37. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Reminder: Promises are Cool • Promises can be used to chain together a series of async REST calls. requestMapCoords(postcode) .flatMap(c -> findNearestSchool(c)) .flatMap(s -> requestExamRanking(s)) …
  38. 38. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Implementation & Demo
  39. 39. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Specification Status • RFC 217 • View on GitHub: github.com/osgi/design → rfcs/rfc0217 • Expected in OSGi Release 7, around Q2-Q3 2017. • Not yet a chapter in the Early Draft compendium. • RFC Author: Tim Ward, Paremus. • RI will be developed by Liferay. • Based on CXF JAX-RS. • Ongoing implementation work in Apache Aries.
  40. 40. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 DEMO
  41. 41. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 Want to See More? • Go to Tim Ward’s talk tomorrow at 10:15 in Schubartsaal. • “Transaction Control – A functional approach to modular transaction management” • Demo includes a CRUD microservice implemented with this spec.
  42. 42. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 www.paremus.com @Paremus info@paremus.com
  43. 43. Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016

×