Let's say we have a service like this:
@RequestMapping("/hello") public static class MyRestService { @RequestMapping(value = "/world", method = RequestMethod.POST) public String hello(String body) { return body; } }
We want to use a lot of Vertx features, and we decide to embed QBit support inside of a verticle.
Our vertx MyVerticle might look like this:
public class MyVerticle extends AbstractVerticle { private final int port; public MyVerticle(int port) { this.port = port; } public void start() { try { /* Route one call to a vertx handler. */ final Router router = Router.router(vertx); //Vertx router router.route("/svr/rout1/").handler(routingContext -> { HttpServerResponse response = routingContext.response(); response.setStatusCode(202); response.end("route1"); }); /* Route everything under /hello to QBit http server. */ final Route qbitRoute = router.route().path("/hello/*"); /* Vertx HTTP Server. */ final io.vertx.core.http.HttpServer vertxHttpServer = this.getVertx().createHttpServer(); /* * Use the VertxHttpServerBuilder which is a special builder for Vertx/Qbit integration. */ final HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder() .setRoute(qbitRoute) .setHttpServer(vertxHttpServer) .setVertx(getVertx()) .build(); /* * Create a new service endpointServer and add MyRestService to it. * ( You could add a lot more services than just one. ) */ final MyRestService myRestService = new MyRestService(); final ServiceEndpointServer endpointServer = endpointServerBuilder().setUri("/") .addService(myRestService).setHttpServer(httpServer).build(); endpointServer.startServer(); /* * Associate the router as a request handler for the vertxHttpServer. */ vertxHttpServer.requestHandler(router::accept).listen(port); }catch (Exception ex) { ex.printStackTrace(); } } public void stop() { } }
Read the comments to see what is going on. It should make sense.
Next we start up the vertx Verticle (perhaps in a main method).
myVerticle = new MyVerticle(port); vertx = Vertx.vertx(); vertx.deployVerticle(myVerticle, res -> { if (res.succeeded()) { System.out.println("Deployment id is: " + res.result()); } else { System.out.println("Deployment failed!"); res.cause().printStackTrace(); } latch.countDown(); });
final HttpClient client = HttpClientBuilder.httpClientBuilder() .setHost("localhost").setPort(port).buildAndStart(); final HttpTextResponse response = client.postJson("/svr/rout1/", "\"hi\""); assertEquals(202, response.code()); assertEquals("route1", response.body()); final HttpTextResponse response2 = client.postJson("/hello/world", "\"hi\""); assertEquals(200, response2.code()); assertEquals("\"hi\"", response2.body());
The full example is actually one of the integration tests that is part of QBit.
package io.advantageous.qbit.vertx; import io.advantageous.qbit.annotation.RequestMapping; import io.advantageous.qbit.annotation.RequestMethod; import io.advantageous.qbit.http.client.HttpClient; import io.advantageous.qbit.http.client.HttpClientBuilder; import io.advantageous.qbit.http.request.HttpTextResponse; import io.advantageous.qbit.http.server.HttpServer; import io.advantageous.qbit.server.ServiceEndpointServer; import io.advantageous.qbit.util.PortUtils; import io.advantageous.qbit.vertx.http.VertxHttpServerBuilder; import io.vertx.core.AbstractVerticle; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.http.HttpServerResponse; import io.vertx.ext.web.Route; import io.vertx.ext.web.Router; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static io.advantageous.qbit.server.EndpointServerBuilder.endpointServerBuilder; import static org.junit.Assert.assertEquals; /** * Created by rick on 9/29/15. */ public class VertxRESTIntegrationTest { private Vertx vertx; private TestVerticle testVerticle; private int port; @RequestMapping("/hello") public static class TestRestService { @RequestMapping(value = "/world", method = RequestMethod.POST) public String hello(String body) { return body; } } public static class TestVerticle extends AbstractVerticle { private final int port; public TestVerticle(int port) { this.port = port; } public void start() { try { /* Route one call to a vertx handler. */ final Router router = Router.router(vertx); //Vertx router router.route("/svr/rout1/").handler(routingContext -> { HttpServerResponse response = routingContext.response(); response.setStatusCode(202); response.end("route1"); }); /* Route everything under /hello to QBit http server. */ final Route qbitRoute = router.route().path("/hello/*"); /* Vertx HTTP Server. */ final io.vertx.core.http.HttpServer vertxHttpServer = this.getVertx().createHttpServer(); /* * Use the VertxHttpServerBuilder which is a special builder for Vertx/Qbit integration. */ final HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder() .setRoute(qbitRoute) .setHttpServer(vertxHttpServer) .setVertx(getVertx()) .build(); /* * Create a new service endpointServer. */ final ServiceEndpointServer endpointServer = endpointServerBuilder().setUri("/") .addService(new TestRestService()).setHttpServer(httpServer).build(); endpointServer.startServer(); /* * Associate the router as a request handler for the vertxHttpServer. */ vertxHttpServer.requestHandler(router::accept).listen(port); }catch (Exception ex) { ex.printStackTrace(); } } public void stop() { } } @Before public void setup() throws Exception{ final CountDownLatch latch = new CountDownLatch(1); port = PortUtils.findOpenPortStartAt(9000); testVerticle = new TestVerticle(port); vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(5)); vertx.deployVerticle(testVerticle, res -> { if (res.succeeded()) { System.out.println("Deployment id is: " + res.result()); } else { System.out.println("Deployment failed!"); res.cause().printStackTrace(); } latch.countDown(); }); latch.await(5, TimeUnit.SECONDS); } @Test public void test() { final HttpClient client = HttpClientBuilder.httpClientBuilder().setHost("localhost").setPort(port).buildAndStart(); final HttpTextResponse response = client.postJson("/svr/rout1/", "\"hi\""); assertEquals(202, response.code()); assertEquals("route1", response.body()); final HttpTextResponse response2 = client.postJson("/hello/world", "\"hi\""); assertEquals(200, response2.code()); assertEquals("\"hi\"", response2.body()); } @After public void tearDown() throws Exception { final CountDownLatch latch = new CountDownLatch(1); vertx.close(res -> { if (res.succeeded()) { System.out.println("Vertx is closed? " + res.result()); } else { System.out.println("Vertx failed closing"); } latch.countDown(); }); latch.await(5, TimeUnit.SECONDS); vertx = null; testVerticle = null; } }
You can bind direct to the vertxHttpServer, or you can use a router.
public static class MyVerticle extends AbstractVerticle { private final int port; public MyVerticle(int port) { this.port = port; } public void start() { try { HttpServerOptions options = new HttpServerOptions().setMaxWebsocketFrameSize(1000000); options.setPort(port); Router router = Router.router(vertx); //Vertx router router.route("/svr/rout1/").handler(routingContext -> { HttpServerResponse response = routingContext.response(); response.setStatusCode(202); response.end("route1"); }); io.vertx.core.http.HttpServer vertxHttpServer = this.getVertx().createHttpServer(options); HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder() .setRouter(router)//BIND TO THE ROUTER! .setHttpServer(vertxHttpServer) .setVertx(getVertx()) .build(); ...
public static class MyVerticle extends AbstractVerticle { private final int port; public MyVerticle(int port) { this.port = port; } public void start() { try { HttpServerOptions options = new HttpServerOptions().setMaxWebsocketFrameSize(1000000); options.setPort(port); io.vertx.core.http.HttpServer vertxHttpServer = this.getVertx().createHttpServer(options); HttpServer httpServer = VertxHttpServerBuilder.vertxHttpServerBuilder() .setVertx(getVertx()) .setHttpServer(vertxHttpServer) //BIND TO VERTX HTTP SERVER DIRECT .build(); ...
QBit has a health system, and a microservices stats collections system. Vertx 3 provided similar support. QBit has an event bus. Vertx has an event bus. There is no reason why QBit can't provide Vertx implementations of its event bus (this is how the QBit event bus started), or for that matter integrate with Vertx's health system or its stats collection system. QBit has its own service discovery system with implementations that talk to DNS, Consul, or just monitor JSON files to be updated (for Chef Push, or Consul, etcd pull model). There is no reason QBit could not provide an implementation of its Service Discovery that worked with Vertx's clustering support. All of the major internal services that QBit provides are extensible with plugins via interfaces. There is plenty of opportunity for more integration of QBit and Vertx.
QBit and Vertx have both evolved to provide more and more support for microservices and there is a lot of synergy between the two libs.
QBit can also play well with Servlets, Spring MVC, Spring Boot, and other lightweight HTTP libs. QBit comes batteries included.
BACKGROUND
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at http://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/bd25675c-22fc-4b7c-940d-909cdf4aacdf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
compile 'com.github.advantageous:qbit-vertx:0.9.1-RC2'
Nice work, but I do have a question. Which version do I have to use for qbit in order to have the VeertxHttpServerBuilder? I have tried qbit-vertx:0.7.2 and qbit-vertx:0.9.0.RELEASE with no avail.--
Best Regards, Alexandru.
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/feTpRbnQVAQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
Visit this group at http://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/807c2533-18b7-4db3-8f08-4bed58bf6493%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/feTpRbnQVAQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
Visit this group at http://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/560B93E0.5040002%40gmail.com.
For more options, visit https://groups.google.com/d/optout.
Thanks for the tip Rick, I did it so and it worked.
Great work, lots of features, very useful.
If I may, I could make a small remark though.I was a little confused about the route parameter, why does it have to be set into the server, since we already have requestMapping, and why does it have the be the same path described in the requestMapping?
Route is set only once which makes available just one Resource at one time, correct?
Also the event bus migration to origin sounds like a very good idea, as the performance in my tests have greatly decreased using qbit versus using directly vertx bus.
I have 2 implementations of a very simple rest get service, with qbit, and without (using vertx event bus and handlers). The difference is big, could be my configuration, but I doubt. I followed your exact example.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/d43e1185-0940-4aa7-9d29-e104338222eb%40googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/d43e1185-0940-4aa7-9d29-e104338222eb%40googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/10408964-f85e-42f1-b796-789b5a3fa2e4%40googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/97fc1776-c0f9-421b-9a84-0085642e2b1a%40googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/10408964-f85e-42f1-b796-789b5a3fa2e4%40googlegroups.com.
$ wrk -t 4 -d 10 -c 40 http://localhost:9999/services/helloservice/hello
Running 10s test @ http://localhost:9999/services/helloservice/hello
4 threads and 40 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 533.42us 128.77us 2.29ms 88.93%
Req/Sec 18.85k 1.66k 22.28k 60.89%
757677 requests in 10.10s, 83.82MB read
Requests/sec: 75009.08
Transfer/sec: 8.30MB
300 connections
$ wrk -t 4 -d 10 -c 300 http://localhost:9999/services/helloservice/hello
Running 10s test @ http://localhost:9999/services/helloservice/hello
4 threads and 300 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.59ms 783.57us 20.49ms 75.04%
Req/Sec 20.63k 1.95k 22.82k 82.25%
820587 requests in 10.01s, 90.78MB read
Socket errors: connect 0, read 163, write 0, timeout 0
Requests/sec: 82008.93
Transfer/sec: 9.07MB