Vert.x based microservices with vxms

Andy Moncsek Senior Consultant

[email protected] Twitter: @AndyAHCP

1 13.03.18 Bezeichnung Präsentation Agenda

1. Introduction

2. Vxms-core

3. Vxms-rest & Vxms-k8s-discovery & Vxms-event

4. Demo

5. Conclusion

2 3/13/18 Vert.x based microservices with vxms Introduction

3 13.03.18 Vert.x based microservices with vxms What Vert.x is...

Vert.x is an unopinionated tool-kit building reactive appications on the JVM

4 13.03.18 Vert.x based microservices with vxms What Vert.x is

scale polyglot

fun general purpose

5 13.03.18 Event-driven microservices with Vxms, Hazelcast and What Vert.x is.... fast

https://www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=db

6 13.03.18 Event-driven microservices with Vxms, Hazelcast and Kubernetes Vert.x (Web) example

public class SimpleRest extends AbstractVerticle {

@Override public void start(Future startFuture) throws Exception {

Router router = Router.router(vertx); router.get("/hello/:name").handler(ctx -> ctx.response().end(("hello world") ); JsonObject config = vertx.getOrCreateContext().config();

vertx.createHttpServer().requestHandler(router::accept) .listen(config.getInteger("port", 9090), config.getString("host", "localhost")); startFuture.complete(); } } 7 13.03.18 Event-driven microservices with Vxms, Hazelcast and Kubernetes What Vxms is...

Vxms is an opinionated framework on top of Vert.x for building reactive services on the JVM

8 13.03.18 Vert.x based microservices with vxms Design goals

No Vert.x 100% Easy of use replacement compatible • other focus • Vert.x • to Vert.x à services concepts are still new*

9 13.03.18 Vert.x based microservices with vxms Design goals

Resilience Modularity

• APIs to build resilient • Vxms-core applications must be • Vxms-rest 1st class citizens • Vxms-event • Vxms-K8s-discovery

10 13.03.18 Vert.x based microservices with vxms Philosophy

Philosophy: Principle of Least Power*

pick the least powerful/easiest to use solution, capable of solving your problem

* http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html

11 13.03.18 Vert.x based microservices with vxms Vxms-core

12 13.03.18 Java 9 und die Konsequenzen Vxms-core

Entry point • to use Vxms • to activate modules Provides default configuration § Creates a http endpoint § Provides reference to io.vertx.ext.web.Route Additional configuration

13 13.03.18 Vert.x based microservices with vxms Vxms-core

@ServiceEndpoint public class SimpleREST extends VxmsEndpoint { Get rid of boilerplate code (creating endpoint & router)

@Override public void postConstruct(Router router, final Future start) { router. get("/hello/:name"). handler(h ->h.response().end("hello World")); start.complete(); }

public static void main(String[] args) { Vertx.vertx().deployVerticle(SimpleREST.class.getName()); } }

14 13.03.18 Vert.x based microservices with vxms Vxms-core

@ServiceEndpoint public class SimpleREST extends AbstractVerticle { Using a «plain» Verticle

public void start(Future start) { VxmsEndpoint.start(start,this); }

public void postConstruct(Router router,final Future start) { router. get("/hello/:name"). handler(h ->h.response().end("hello World")); start.complete(); }

public static void main(String[] args) { Vertx.vertx().deployVerticle(SimpleREST.class.getName()); } } 15 13.03.18 Vert.x based microservices with vxms Vxms-core

@ServiceEndpoint(port =9090, contextRoot ="/", routerConf = CustomRouterConf.class, serverOptions = CustomServerConf.class)

Configuration using annotation

Using Vert.x configuration Same configuration in a all modules

Using environmental variables

16 13.03.18 Vert.x based microservices with vxms Vxms-rest

17 13.03.18 Vert.x based microservices with vxms Vxms-rest

endpoints using jax-rs annotations

fluent API to build the response / handle errors § Chaining via supply / andThen § Non-blocking & blocking API § error handling

18 13.03.18 Vert.x based microservices with vxms Vxms-rest

@Path("/hello/:name") @GET public void simpleREST(RestHandler handler) { String name = handler.request().param("name"); handler. response(). stringResponse((response) ->response.complete("hello World " + name)). execute(); } Non-blocking API

19 13.03.18 Vert.x based microservices with vxms Vxms-rest

@Path("/hello/:name") @GET public void simpleREST(RestHandler handler) { String name = handler.request().param("name"); handler. response(). blocking(). stringResponse(() ->"hello World " + name). execute(); } blocking API

20 13.03.18 Vert.x based microservices with vxms Vxms-rest

@Path("/hello/:name") @GET public void simpleREST(RestHandler handler) { String name = handler.request().param("name"); handler. response(). supply((response) ->response.complete("hello World ")). andThen((value, response) ->response.complete(value+ name)). mapToStringResponse((value, response) ->response.complete(value)). execute(); } Execution chaining

21 13.03.18 Vert.x based microservices with vxms Vxms-rest

@Path("/hello/:name") @GET public void simpleREST(RestHandler handler) { String name = handler.request().param("name"); handler. response(). supply((response) ->response.complete("hello World ")). andThen((value, response) ->response.complete(value+ name)). mapToStringResponse((value, response) ->response.complete(value)). timeout(2000). onFailureRespond((error, future) ->future.complete("error")). httpErrorCode(HttpResponseStatus.BAD_REQUEST). retry(3). closeCircuitBreaker(2000). execute(); } Error handling 22 13.03.18 Vert.x based microservices with vxms Vert.x example with circuitbreaker

CircuitBreaker breaker = CircuitBreaker.create("my-circuit-breaker", vertx, new CircuitBreakerOptions().setMaxFailures(3).setTimeout(2000) ); router.get("/helloEventbus/:name").handler(ctx -> { String name = ctx.request().getParam("name"); breaker.executeWithFallback( future -> { vertx.eventBus() .send("/hello", name, responseHandler -> { if(!responseHandler.fail()) { Message result = responseHandler.result(); future.complete(result.body()); } else { future.fail("error"); } }); }, v -> { // Executed when the circuit is opened return "Hello"; }) .setHandler(ar -> { // Do something with the result ctx.response().end(ar); }); });

23 13.03.18 Vert.x based microservices with vxms Vxms-k8s(Kubernetes)-discovery

24 13.03.18 Vert.x based microservices with vxms Vxms-k8s-discovery Kubernetes namespace

User (REST)

? Products Order v1 (Event) ? Gateway ? (REST)

? ?

Product Order v1 (REST) (Event)

25 13.03.18 Vert.x based microservices with vxms Vxms-k8s-discovery

- Clustering the event bus à Hazelcast or Vert.x plugin

- Discover services by name à built in, for free in k8s

- Discover endpoints / pods à Vxms-k8s-discovery

- Discovery by labels à Vxms-k8s-discovery

26 13.03.18 Vert.x based microservices with vxms Vxms-k8s-discovery

@ServiceEndpoint @K8SDiscovery public class SimpleREST extends VxmsEndpoint {

@ServiceName @WithLabels({ @WithLabel(name="nameLabel", value="${service.property}"), @WithLabel(name="versionLabel", value="${version.property}") }) private String userService;

} • based on fabric8 kubernetes client API

27 13.03.18 Vert.x based microservices with vxms Vxms-k8s-discovery

public static void main(String[] args) { DeploymentOptions options = new DeploymentOptions().setConfig( new JsonObject().put("kube.offline", true) .put("service.property", "vxms-read") .put("version.property", "1.1-SNAPSHOT") .put("name.vxms-read.version.1.1-SNAPSHOT", "localhost:7070")); ... } manual mapping via config } (for local env) supported

28 13.03.18 Vert.x based microservices with vxms Vxms-event

29 13.03.18 Java 9 und die Konsequenzen Vxms-event

same fluent API like rest-module § Chaining via supply / andThen § Non-blocking & blocking API § Error handling

30 13.03.18 Vert.x based microservices with vxms Vxms-event

@Consume("myEventHandler") public void simpleEvent(EventbusHandler reply) { reply .response() .supply((result) -> result.complete("Hello World")) .andThen((value, result) -> result.complete(value + "1")) .mapToStringResponse((value, result) -> result.complete(value + "2")) .timeout(2000) .onError(error -> log.log(Level.WARNING, "ERROR: " + error.getMessage())) .onFailureRespond((failure, future) -> future.complete("error")) .execute(); }

31 13.03.18 Vert.x based microservices with vxms Vxms-rest/event

@ServiceEndpoint Public class Gateway extends VxmsEndpoint{

@Path("/helloEventbus/:name") @GET public void simpleEventbusCall(RestHandler handler) { String name= handler.request().param("name"); handler. eventBusRequest(). send("/hello", name).// send message to eventbus, pass result to REST response mapToStringResponse((message, response)-> response.complete(message.result().body()). timeout(5000). onError(error->LOG(error.getMessage())). execute();// execute non blocking

}

}

32 13.03.18 Event-driven microservices with Vxms, Hazelcast and Kubernetes @ServiceEndpoint Vxms-event Public class Gateway extends VxmsEndpoint{ @Path("/helloEventbus/:name") @GET public void simpleEventbusCall(RestHandlerhandler) { String name= handler.request().param("name"); handler. eventBusRequest(). send("/hello", name).// send message to eventbus, pass result to REST response mapToStringResponse((message, response)-> Event via Eventbus response.complete(message.result().body()). timeout(5000). onError(error->LOG(error.getMessage())). execute();// execute non blocking @ServiceEndpoint } Public class EventbusExample extends VxmsEndpoint{ } @Consume("/hello") public void simpleNonBlocking(EventbusHandlerhandler) { String name= handler.request().body(); handler. response(). stringResponse((response)-> response.complete("hello World "+name)).// complete non-blocking response timeout(2000).// timeout for stringResponse handling onError(error->LOG(error.getMessage())). onFailureRespond((error, future)->future.complete("error:"+error.getMessage())). retry(3). closeCircuitBreaker(2000). execute();// execute non blocking }

} 33 13.03.18 Event-driven microservices with Vxms, Hazelcast and Kubernetes Demo

34 13.03.18 Vert.x based microservices with vxms Demo

35 13.03.18 Vert.x based microservices with vxms Conclusion & outlook

36 13.03.18 Vert.x based microservices with vxms Conclusion

§ Vxms is an easy-to-use entry point to Vert.x

§ Small overhead & no other dependencies (Vert.x core & web)

§ Focuses on service development

§ Started as a spare time

§ Supported by Trivadis

§ Already in use

37 13.03.18 Vert.x based microservices with vxms Outlook

§ Java >= 9 migration (integration test with Jersey )

§ Enhancements with RegEx URL patterns

§ Websocket & SocketJs module

§ images

38 13.03.18 Vert.x based microservices with vxms Thank you Andy Moncsek Senior Consultant [email protected] Twitter: @AndyAHCP

39 13.03.18 Vert.x based microservices with vxms References

- https://github.com/amoAHCP/vxms - http://vertx.io - https://maven.fabric8.io - https://github.com/hazelcast/hazelcast-kubernetes - http://docs.hazelcast.org/docs/latest- development/manual/html/Setting_Up_Clusters/index.html - http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html

40 13.03.18 Event-driven microservices with Vxms, Hazelcast and Kubernetes