Quantcast
Channel: Vert.x
Viewing all 158 articles
Browse latest View live

Vert.x 2.1.6 released !

$
0
0

The Vert.x team is pleased to announce the release of Vert.x 2.1.6.

This is a maintenance release on the 2.x branch that fixes a few bugs and is designed for Vert.x 2 production users who cannot upgrade to 3.0 immediately.

For the latest production version for new projects please see Vert.x 3.0.

Fixes in this release include:

  • runZip - fix bugs in unpacking zips
  • HttpClient - make sure writeHead is set to true before connect
  • Upgrade to Hazelcast 3.5 to fix bug in Multimap state.
  • Workaround for Hazelcast bug which could result in inconsistent cluster state if multiple nodes shutdown concurrently
  • Clustering fixes related to clearing up state in case of event bus connections closing and on close of event bus.
  • Fix message replies to nodes other than the node the SockJS bridge is deployed on.

The artifacts has been deployed to Maven Central, and you can get the distribution on Bintray.


Vert.x3 Web easy as Pi

$
0
0

Vert.x Web distinguishes itself from traditional application servers like JavaEE by just
being a simple extension toolkit to Vert.x, which makes it quite lightweight and small but
nevertheless very powerful.

One can create simple applications targeting small devices such as Raspberry Pi without having to write much code but
still very fast as it is expected from any Vert.x application.

Lets for example think of making a realtime cpu load visualization web app.
For this example we need a few things:

To bootstrap this project we start by creating the pom.xml
file. A good start is always to consult the examples,
and you should end up with something like:

...
<groupId>io.vertx.bloggroupId><artifactId>rpiartifactId><version>1.0version><dependencies><dependency><groupId>io.vertxgroupId><artifactId>vertx-coreartifactId><version>3.0.0version>dependency><dependency><groupId>io.vertxgroupId><artifactId>vertx-webartifactId><version>3.0.0version>dependency>dependencies>
...

At this moment you can start coding the application using the standard maven source src/main/java and resource
src/main/resouces locations. And add a the class io.vertx.blog.RpiVerticle
to the project:

publicclassRPiVerticleextendsAbstractVerticle{

  privatestaticfinal OperatingSystemMXBean osMBean;

  static {
    try {
      osMBean = ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),
          ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);
    } catch (IOException e) {
      thrownew RuntimeException(e);
    }
  }

  @Overridepublicvoidstart(){

    Router router = Router.router(vertx);

    router.route("/eventbus/*").handler(SockJSHandler.create(vertx)
        .bridge(new BridgeOptions().addOutboundPermitted(new PermittedOptions().setAddress("load"))));

    router.route().handler(StaticHandler.create());

    vertx.createHttpServer().requestHandler(router::accept).listen(8080);

    vertx.setPeriodic(1000, t -> vertx.eventBus().publish("load",
        new JsonObject()
            .put("creatTime", System.currentTimeMillis())
            .put("cpuTime", osMBean.getSystemLoadAverage())));
  }
}

So lets go through the code, first in the static constructor we initialize the MXBean that will allow us to collect
the current System Load Average, then on the start method we create a Vert.x Web Router and define that for all
requests starting with /eventbus should be handled by the SockJS server, which we then bridge to the Vert.x
EventBus and allow outbound messages addressed to the load address.

Since our application is a web application we will also server some static content with the StaticHandler and we
finally start a HTTP server listening on port 8080.

So now all we are missing is a way to push real time data to the client so we end up creating a Periodic task that
repeats every 1000 milliseconds and sends some JSON payload to the address "load".

If you run this application right now you won’t see much since there is no frontend yet, so lets build a very basic
index.html:

...
var eb = new vertx.EventBus(window.location + "eventbus");

eb.onopen = function(){
  eb.registerHandler("load", function(msg){
    if (data.length === 25) {
      // when length of data equal 25 then pop data[0]
      data.shift();
    }
    data.push({
      "creatTime": newDate(msg.creatTime),
      "cpuTime": msg.cpuTime
    });
    render();
  });
};
...

Lets walk again the code, we start by opening a EventBus bridge over SockJS and register a handler data to consume
messages sent to that address. Once such a message arrives we do some house keeping to avoid filling our browser memory
and then add the incoming message to the data queue and triger a rendering of the data. There is however one interesting
issue here, since the message payload is JSON there is no native support for Date objects so we need to do some
parsing from what arrives from the server. In this case the server sends a simple time since epoch number, but one can
choose any format he likes.

At this moment you can build and package your app like mvn clean package, then deploy it to your raspberrypi like:
scp target/rpi-1.0-fat.jar pi@raspberrypi:~/ and finally run it: java -jar rpi-1.0-fat.jar.

Open a browser to see the realtime graph!

screeshot

Vert.x 3 init.d Script

$
0
0

Let’s say you have a Vert.x 3 application you want to install on a Linux server. But you want the old school way (I meant not the docker way ☺). So, in other words, you need an init.d script. This post proposes an init.d script that you can use to start / stop / restart a Vert.x 3 application.

Prerequisites

The proposed script assumes your application is packaged as a fat jar. So, your application is going to be launched using java -jar your-fat-jar ....

The script

The init.d scripts have to reply to a set of commands:

  • start : starts the application (if not yet started)
  • stop : stops the application (if started)
  • status : let you know if the application is started or not
  • restart : restart the application

These commands are invoked using:

service my-service-script startservice my-service-script stopservice my-service-script statusservice my-service-script restart

In general, service scripts are hooked in the boot and shutdown sequences to start and stop automatically during the system starts and stops.

So, enough talks, let’s look at the script:

Using the script

First download the script from the here.

You need to set a couple of variables located at the beginning of the file:

# The directory in which your application is installedAPPLICATION_DIR="/opt/my-vertx-app"# The fat jar containing your applicationAPPLICATION_JAR="maven-verticle-3.0.0-fat.jar"# The application argument such as -cluster -cluster-host ...APPLICATION_ARGS=""# vert.x options and system properties (-Dfoo=bar).VERTX_OPTS=""# The path to the Java command to use to launch the application (must be java 8+)JAVA=/opt/java/java/bin/java

The rest of the script can stay as it is, but feel free to adapt it to your needs. Once you have set these variables based on your environment, move the file to /etc/init.d and set it as executable:

sudo mv my-vertx-application /etc/init.d
sudo chmod +x my-vertx-application

Then, you should be able to start your application using:

sudo service my-vertx-application start

Depending to your operating system, adding the hooks to the boot and shutdown sequence differs. For instance on Ubuntu you need to use the update-rc.d command while on CentOS chkconfig is used

That’s all, enjoy !

Vert.x3 and PostgreSQL JSON type

$
0
0

One of the interesting features of NoSQL databases is their schema-less mode of operation. This feature is very useful
during project prototyping and early development since at early the stages of development of projects all data
structures are not clear or have been defined yet. The reason of this post is not to discuss about that subject, but to
show that sometimes you can also use NoSQL with a more traditional database engine like PostgreSQL.

Since version 9.3 there is support for JSON however with
version 9.4 there is even better support with the new type
JSONB. I will now show how to use the basic JSON type in a simple REST application written with Vert.x3:

Now all you need to do is play with this REST service, for this you can use curl to create a sale:

$ curl \
    -i \
    -H"Content-Type: application/json" \
    -XPOST \
    -d '{"id": 1, "customer_name": "John", "items": {"description": "milk", "quantity": 4}}' \
    http://localhost:8080/sales

HTTP/1.1 201 Created
Content-Length: 0
$

And if you want to read that new document:

$ curl -i -H "Accept: application/json" -X GET http://localhost:8080/sales/1
HTTP/1.1200 OK
content-type: application/json
Content-Length:75

{"id":1,"customer_name":"John","items":{"description":"milk","quantity":4}}
$

Checklist for Migrating from Vert.x 2.1.x to Vert.x 3 - Part One

$
0
0

This blog post presents feedbacks from a project migration using Vert.x 2 to Vert.x 3.

We are in the process of converting our Vert.x 2.1.5 application to Vert.x 3.0.

So while upgrading our application, I thought I should note down all the changes that we had to do in the process. Since Vert.x 3 is a major upgrade from the previous version, with so many changes.

It requires re-thinking your current 2.x Vert.x application. There are new classes, new apis, and a new package structure that has greatly simplified things that we used to have to work around. Therefore in our upgrade it required us to refactor and remove any unnecessary “hacks” that weren’t available in 2 that are now a part of Vert.x 3 that you really want and need to take advantage of. (I don’t mean there are hacks in 3.x, just that we had in our application with Vert.x 2.x)

There are Metrics, and Clustered shared data, with locking and many more features that are amazing new additions. These are things we had to hack into our application with Vert.x 2.x. We added our own MetricsRegistry from DropWizard which meant making our own Main class that called Vert.x’s Starter class after starting up the registry, but only in our Devops server deploys, not our developer machines. And we had to build our own distributed locked of clustered data that also required writing a comprehensive distributed timers. (The timers got fixed with a better actor model). But now we can use what Vert.x gives us internally for those use cases.

This blog post is part one, as I am sure there will be some new changes that we need to do that we haven’t gotten to yet. Which as we go, will post in part two. Also that this post is a work in progress in that whenever you are upgrading and refactoring your code, it doesn’t leave much time for taking detailed notes, or writing beautiful prose. I am a terrible writer even when I can fully concentrate on it. So the first draft will just be a list of my notes. These notes are not in any particular order, but some things like tests you might want to save for last. (Just DON’T delete your tests, tests are very important)

One of the first things that Vert.x has changed is the whole classloader setup. Read the Vert.x Docs for more information but basically, we have a flat classloader system now. YAY! And one of the first things I noticed that is gone is the Platform module.

Changes we have made.

Dependency changes

  1. So the first thing we did was to remove the vert.x-platform dependency from our pom file (Build dependency file of whatever build system you use) This also means that you will be removing any import statements from your code that has .platform. Which leads us to the next point.

  2. Change all the imports for Vertx. from org.vertx to io.vertx. This could be a lot of work, as it is in every class you use Vert.x in. We had at least 250 locations to change here. Some classes have moved packages and “jars” that have them, so there will be some new jars to include as dependencies and different import statements for them.

  3. If using a language other than Java, change the dependency to vertx-lang-<>

  4. Remove any modules references that are using Vert.x 2.x stuff. You can get an odd error like
    The type org.vertx.java.core.json.JsonObject cannot be resolved. It is indirectly referenced from required .class files.

  5. testtools dependency is gone. There is now Vertx-unit. So all your previous tests need to be completely re-written in the new style. This can be really difficult and time consuming as the tests you already have written really do need to be re-written from scratch. But these tests are also the backbone in knowing if your code is working. So this could take months if you have a really full set of test suites already. Also note the list below is to convert your JUnit Integration tests. as vertx-unit first and foremost provides its own testing framework/suite but it also works in JUnit, and if you are using JUnit you need to do the following

    • Remove all the imports to TestTools, including VertxAssert. I would do a find/replace to replace all the VertxAssert to testContext for when you have to add TestContext to all your @Test methods. I recommend naming the parameter testContext, just to put more context, into your context. Because if you just have context as your parameter name, how do you know what context the context is? Sorry, that was too much fun. Basically, what I am saying is if you have say Spring ApplicationContext in with your integration tests with Vert.x what does context represent? Spring or Vert.x test context.
    • Add @RunWith(VertxUnitRunner.class) above your test class
    • Remove any VertxAssert.testComplete() those are gone. It needs TestContext.async().complete(). It is also important to understand what async() means. When to call it, when to complete it. It also allows you to do multiple async() calls and nested ones. I think I needed that when I had a test that was a longer use case of many messages being sent, but only after responses to other ones occurred. For instance, to do chat in our app, you have to connect, subscribe, friend someone, then you can send a chat message. So that is 4 total Vert.x Messages sent from the Test client. And you can subscribe until connect completed, and you can send or receive messages unless you are subscribed and have a friend. So we need to have a few async() calls in that scenario.
    • What is in your start method override. Make that an @Before.
    • What is in your stop method override. Make that an @After.
    • If you have your assertions have custom message strings to log out when they fail, that parameter is now at the end of the assert method call. Yes, this one can be painful.

Build Changes

  1. Remove all vertx maven plugin code to generate modules, instead create fat jars, which requires adding the Shade maven plugin to put all jar files into a big fat jar. The vertx-examples project has simplest-maven which has the stuff to create the fat jar. simplest-gradle is the gradle equivalent.

  2. If you were running your application with runMod or something like that then you need to create a fat jar, changing the build file as in this one and create a Main class like here this one.

Class/Code Changes

  1. Verticle is now an interface and not a class to extend, so using Groovy as an example you now extend GroovyVerticle. In Java extend AbstractVerticle instead.

  2. There is no registerHandler on the eventBus anymore. So everywhere you do that has to change to create/call consumer() and to unregister that handler, you have to have a reference to the MessageConsumer that consumer() call returns and call its unregister method.

  3. JsonObject.toMap() changed to JsonObject.getMap()

  4. JsonObject also removed all the putXXX methods with just one put method with overloaded versions for different types.

  5. JsonObjectMessage no longer exists. What replaces depends on what you are doing. Meaning, if it is an async callback to a deploy, you will get a Message instance back that has succeeded() or failed() methods as well as body() to check any results. If it is a Consumer, it is typically a straight forward
    JsonObject. If you are in Groovy it is also a JsonObject, but the body() is a Map which you can use directly now, instead of having to convert from JsonObject to Map.

  6. There isn’t a container variable in Verticles anymore for deploying verticles and also a config file. You need to use vertx.getOrCreateContext().config() to get to it. I used that in the SockJS Example code below.

  7. SharedData no longer has shared sets. It has a Map of SharedData, so an entry in that Map of shared data could be the name of the set as the key, and a Set as the value. It actually gives you more flexibility of what you put into Shared data, so this is actually a big win for us.

  8. Getting the writeHandlerID from a Socket type, is now a method call instead of .writeHandlerID, so .writeHandlerID()

  9. SockJSSocket is in vertx-web package now, so include it to get the class.

  10. There isn’t a SockJSServer class anymore either. So you will create a WebServer, a Router
    and set SSL (if you are using SSL on the WebServer) then create a SockJSHandler to assign to the router via the route() method and handler() methods in the Router api.
    Here is an example of our code. Although I haven’t tested it yet. ;)

publicclassMyVerticleextendsGroovyVerticle {
  Router router

  @Overridevoid start() throws Exception {
     router = Router.router(vertx)
     (Map) sslConfig =
        (Map)vertx.getOrCreateContext()
          .config().get('ssl')

     HttpServer sslHttpServer = vertx.createHttpServer(
         SSL:true,
         keyStorePath: sslConfig.get("keystore"),
         keyStorePassword: sslConfig.get("password"))

     startWebApiServer(sslHttpServer)
  }

  privatevoid startWebApiServer(final HttpServer httpServer) {
    def sockHandler = SockJSHandler.create(vertx, [:])
    sockHandler.socketHandler {
      SockJSSocket ws -> sockJSConnectHandler(ws)
    }
    router.route("/hdpoker").handler(sockHandler)
    httpServer.requestHandler(router.&accept)
    httpServer.listen()
  }

}

More testing change

Testing messages in Integration Tests. To tell the test method that this has async calls put
Async async = testContext.async() as the first line in the test method. Yes, this is a little redundant from above, but I always forgot to put async() calls in my integration tests and they would pass so quickly, without sending anything out, because it wasn’t waiting anymore

Runtime changes

If you don’t use Vert.x built-in Logging and need to use slf4j, then remember that you should set a system property called vertx.logger-delegate-factory-class-name with the name of a Java class which implements the interface LoggerFactory. Vert.x provides pre-built implementations for Log4J and SLF4J with the class names io.vertx.core.logging.Log4jLogDelegateFactory and io.vertx.core.logging.SLF4JLogDelegateFactory.

Still working

Well, that is all I have for you folks so far. We are still not done, as we haven’t gotten our application running with real clients just yet. But we do have all our integration tests from before completely passing
so, if something does come up, it should be a small one (KNOCK ON WOOD)

Please feel free to post on the Vert.x Google Group with any comments or suggestions on what to add to this blog post or for Part Two.

Thanks

Mark S

Vert.x3 says "hello" to NPM users

$
0
0

In programming literature it has become the standard to create a hello world program as the first example. In this
article I’ll be demonstrating how NPM users can quickly get started with vert.x. You will see that it is not
that different and in fact it can be done using the tools you’re used to. Note that although we are using NPM we are
not relying on node.js, all javascript code runs on the JVM.

Hello World Examples

Here are four simple hello world examples. The comments in the code explain how the code works and the text around it
explain what it does and how to test it.

Hello Console

This example is about as plain as it can get. It prints the words “Hello World“ to the terminal. If you’re a
javascript developer you should be already used to npm and know that you always start a project with the file
package.json:

{
  "name": "vertx3-hello-console",
  "private": true,
  "dependencies": {
    "vertx3-min": "3.0.0-1"
  },
  "scripts": {
    "start": "./node_modules/.bin/vertx run server.js"
  }
}

Note that we have a dependency wich is obvious vert.x now note that there are 3 flavours of this dependency:

According to your needs you can pick a different flavour, since for a simple hello world we only need the minimal that
is the one we add to the dependency property.

Now we need to do a simple hello app, we will call this file “server.js“:

// Call the console.log function.console.log("Hello World");

You can run this by executing:

npm install
npm start

The first command retrieve the vert.x stack while the seconds starts your program.

Hello HTTP

I’d guess that while it’s not the only use case for vert.x, most people are using it as a web application platform. So
the next example will be a simple HTTP server that responds to every request with the plain text message “Hello World
server.js:

vertx.createHttpServer()
  .requestHandler(function (req) {
    req.response()
      .putHeader("content-type", "text/plain")
      .end("Hello World!");
}).listen(8080);

Now you can reuse the same package.json we’ve just defined in the previous section and start the server with
npm start. Once the server starts you can open a browser to http://localhost:8080 and enjoy the message.

Hello TCP

Vert.x also makes an excellent TCP server, and here is an example that responds to all TCP connections with the
message “Hello World” and then closes the connection server.js:

var server = vertx.createNetServer();
server.connectHandler(function (socket) {
  socket.write("Hello World!\n");
  socket.close();
});

server.listen(7000, "localhost");

Again reuse the previous package.json and test it by doing telnet localhost 7000.

Hello Web

Often you won’t be using vert.x built-in libraries because they are designed to be very low level. This makes vert.x
quick, nimble, and easy to maintain, but if you are planning to build a complex application you want some productivity
and rely on a simple web framework. For this specific case there is vert.x web,
a simple, yet productive framework, to build fast web application with routing, template
rendering, lots of middleware etc…usually not enough to get started on a real world application. This example shows an
HTTP server that responds with “Hello World” to all requests to “/“ and responds with a 404 error to everything else
server.js:

var Router = require("vertx-web-js/router");
var server = vertx.createHttpServer();

var router = Router.router(vertx);

router.get("/").handler(function(ctx){
  // This handler will be called for "/" requestsvar response = ctx.response();
  response.putHeader("content-type", "text/plain");

  // Write to the response and end it
  response.end("Hello World!");
});

server.requestHandler(router.accept).listen(8080);

In order to test this, you will need to install the vertx3-full stack. There are two ways to do this. You can either
install it globally npm install -g vertx3-full or add it as a dependency to our package.json as we have done before,
for example package.json:

{
  "name": "vertx3-hello-web",
  "private": true,
  "dependencies": {
    "vertx3-full": "3.0.0-1"
  },
  "scripts": {
    "start": "./node_modules/.bin/vertx run server.js"
  }
}

That’s it for now, Hopefully this will help you get started working with vert.x!

My first Vert.x 3 Application

$
0
0

Let’s say, you heard someone saying that Vert.x is awesome. Ok great, but you may want to try it by yourself. Well, the next natural question is “where do I start ?”. This post is a good starting point. It shows how is built a very simple vert.x application (nothing fancy), how it is tested and how it is packaged and executed. So, everything you need to know before building your own groundbreaking application.

The code developed in this post is available on github. This post is part of the Introduction to Vert.x series. The code of this post in in the post-1 branch.

Let’s start !

First, let’s create a project. In this post, we use Apache Maven, but you can use Gradle or the build process tool you prefer. You could use the Maven jar archetype to create the structure, but basically, you just need a directory with:

  1. a src/main/java directory
  2. a src/main/test directory
  3. a pom.xml file

So, you would get something like:

.
├── pom.xml├── src
│   ├── main
│   │   └── java
│   └── test
│       └── java

Let’s create the pom.xml file with the following content:

<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0modelVersion><groupId>io.vertx.bloggroupId><artifactId>my-first-appartifactId><version>1.0-SNAPSHOTversion><dependencies><dependency><groupId>io.vertxgroupId><artifactId>vertx-coreartifactId><version>3.0.0version>dependency>dependencies><build><plugins><plugin><artifactId>maven-compiler-pluginartifactId><version>3.3version><configuration><source>1.8source><target>1.8target>configuration>plugin>plugins>build>project>

This pom.xml file is pretty straightforward:

  • it declares a dependency on vertx-core
  • it configures the maven-compiler-plugin to use Java 8.

This second point is important, Vert.x applications require Java 8.

Let’s code !

Ok, now we have made the pom.xml file. Let’s do some real coding… Create the src/main/java/io/vertx/blog/first/MyFirstVerticle.java file with the following content:

package io.vertx.blog.first;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;

publicclassMyFirstVerticleextendsAbstractVerticle{

  @Overridepublicvoidstart(Future fut){
    vertx
        .createHttpServer()
        .requestHandler(r -> {
          r.response().end("

Hello from my first "

+ "Vert.x 3 application"); }) .listen(8080, result -> { if (result.succeeded()) { fut.complete(); } else { fut.fail(result.cause()); } }); } }

This is actually our not fancy application. The class extends AbstractVerticle. In the Vert.x world, a verticle is a component. By extending AbstractVerticle, our class gets access to the vertx field.

The start method is called when the verticle is deployed. We could also implement a stop method, but in this case Vert.x takes care of the garbage for us. The start method receives a Future object that will let us inform Vert.x when our start sequence is completed or report an error. One of the particularity of Vert.x is its asynchronous / non-blocking aspect. When our verticle is going to be deployed it won’t wait until the start method has been completed. So, the Future parameter is important to notify of the completion.

The start method creates a HTTP server and attaches a request handler to it. The request handler is a lambda, passed in the requestHandler method, called every time the server receives a request. Here, we just reply Hello ... (nothing fancy I told you). Finally, the server is bound to the 8080 port. As this may fails (because the port may already be used), we pass another lambda expression checking whether or not the connection has succeeded. As mentioned above it calls either fut.complete in case of success or fut.fail to report an error.

Let’s try to compile the application using:

mvn clean compile

Fortunately, it should succeed.

That’s all for the application.

Let’s test

Well, that’s good to have developed an application, but we can never be too careful, so let’s test it. The test uses JUnit and vertx-unit - a framework delivered with vert.x to make the testing of vert.x application more natural.

Open the pom.xml file to add the two following dependencies:

<dependency><groupId>junitgroupId><artifactId>junitartifactId><version>4.12version><scope>testscope>dependency><dependency><groupId>io.vertxgroupId><artifactId>vertx-unitartifactId><version>3.0.0version><scope>testscope>dependency>

Now create the src/test/java/io/vertx/blog/first/MyFirstVerticleTest.java with the following content:

package io.vertx.blog.first;

import io.vertx.core.Vertx;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(VertxUnitRunner.class)
publicclassMyFirstVerticleTest{

  private Vertx vertx;

  @BeforepublicvoidsetUp(TestContext context){
    vertx = Vertx.vertx();
    vertx.deployVerticle(MyFirstVerticle.class.getName(),
        context.asyncAssertSuccess());
  }

  @AfterpublicvoidtearDown(TestContext context){
    vertx.close(context.asyncAssertSuccess());
  }

  @TestpublicvoidtestMyApplication(TestContext context){
    final Async async = context.async();

    vertx.createHttpClient().getNow(8080, "localhost", "/",
     response -> {
      response.handler(body -> {
        context.assertTrue(body.toString().contains("Hello"));
        async.complete();
      });
    });
  }
}

This is a JUnit test for our verticle. The test uses vertx-unit, so we use a custom runner. vert.x-unit makes easy to test asynchronous interactions, which are the basis of vert.x applications.

In the setUp method, we creates an instance of Vertx and deploy our verticle. You may have noticed that unlike the traditional JUnit @Before method, it receives a TestContext. This object lets us control the asynchronous aspect of our test. For instance, when we deploy our verticle, it starts asynchronously, as most Vert.x interactions. We cannot check anything until it gets started correctly. So, as second argument of the deployVerticle method, we pass a result handler: context.asyncAssertSuccess(). It fails the test if the verticle does not start correctly. In addition it waits until the verticle has completed its start sequence. Remember, in our verticle, we call fut.complete(). So it waits until this method is called, and in the case of a failures, fails the test.

Well, the tearDown method is straightforward, and just terminates the vertx instance we created.

Let’s now have a look to the test of our application: the testMyApplication method. The test emits a request to our application and checks the result. Emitting the request and receiving the response is asynchronous. So we need a way to control this. As the setUp and tearDown methods, the test method receives a TestContext. From this object we creates an async handle (async) that lets us notify the test framework when the test has completed (using async.complete()).

So, once the async handle is created, we create a HTTP client and emits a HTTP request handled by our application with the getNow() method (getNow is just a shortcut for get(...).end()). The response is handled by a lambda. In this lambda we retrieves the response body by passing another lambda to the handler method. The body argument is the response body (as a buffer object). We check that the body contains the "Hello" String and declare the test complete.

Let’s take a minute to mention the assertions. Unlike in traditional JUnit tests, it uses context.assert.... Indeed, if the assertion fails, it will interrupt the test immediately. So it’s pretty important to always uses these assertion methods because of the asynchronous aspect of the Vert.x application and so tests.

Our test can be run from an IDE, or using Maven:

mvn clean test

Packaging

So, let’s sum up. We have an application and a test. Well, let’s now package the application. In this post we package the application in a fat jar. A fat jar is a standalone executable Jar file containing all the dependencies required to run the application. This is a very convenient way to package Vert.x applications as it’s only one file. It also make them easy to execute.

To create a fat jar, edit the pom.xml file and add the following snippet just before :

<plugin><groupId>org.apache.maven.pluginsgroupId><artifactId>maven-shade-pluginartifactId><version>2.3version><executions><execution><phase>packagephase><goals><goal>shadegoal>goals><configuration><transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><manifestEntries><Main-Class>io.vertx.core.StarterMain-Class><Main-Verticle>io.vertx.blog.first.MyFirstVerticleMain-Verticle>manifestEntries>transformer>transformers><artifactSet/><outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jaroutputFile>configuration>execution>executions>plugin>

It uses the maven-shade-plugin to create the fat jar. In the manifestEntries it indicates the name of our verticle. You may wonder from where comes the Starter class. It’s actually a class from vert.x, that is going to create the vertx instance and deploy our verticle.

So, with this plugin configured, let’s launch:

mvn clean package

This is going to create target/my-first-app-1.0-SNAPSHOT-fat.jar embedding our application along with all the dependencies (including vert.x itself).

Executing our application

Well, it’s nice to have a fat jar, but we want to see our application running! As said above, thanks to the fat jar packaging, running Vert.x application is easy as:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

Then, open a browser to http://localhost:8080.

To stop the application, hit CTRL+C.

Conclusion

This Vert.x 3 crash class has presented how you can develop a simple application using Vert.x 3, how to test it, package it and run it. So, you now know everything you need to build amazing system on top of Vert.x 3. Next time we will see how to configure our application.

Happy coding & Stay tuned !

Vert.x Application Configuration

$
0
0

Previously in ‘Introduction to Vert.x’

In this post, we developed a very simple Vert.x 3 application, and saw how this application can be tested, packaged and executed. That was nice, isn’t it ? Well, ok, that was only the beginning. In this post, we are going to enhance our application to support external configuration.

So just to remind you, we have an application starting a HTTP server on the port 8080 and replying a polite “Hello” message to all HTTP requests. The previous code is available here. The code developed in this post is in the post-2 branch.

So, why do we need configuration?

That’s a good question. The application works right now, but well, let’s say you want to deploy it on a machine where the port 8080 is already taken. We would need to change the port in the application code and in the test, just for this machine. That would be sad. Fortunately, Vert.x applications are configurable.

Vert.x configurations are using the JSON format, so don’t expect anything complicated. They can be passed to verticle either from the command line, or using an API. Let’s have a look.

No ‘8080’ anymore

The first step is to modify the io.vertx.blog.first.MyFirstVerticle class to not bind to the port 8080, but to read it from the configuration:

publicvoidstart(Future fut){
  vertx
      .createHttpServer()
      .requestHandler(r -> {
        r.response().end("

Hello from my first "

+ "Vert.x 3 application"); }) .listen( // Retrieve the port from the configuration,// default to 8080. config().getInteger("http.port", 8080), result -> { if (result.succeeded()) { fut.complete(); } else { fut.fail(result.cause()); } } ); }

So, the only difference with the previous version is config().getInteger("http.port", 8080). Here, our code is now requesting the configuration and check whether the http.port property is set. If not, the port 8080 is used as fall-back. The retrieved configuration is a JsonObject.

As we are using the port 8080 by default, you can still package our application and run it as before:

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

Simple right ?

API-based configuration - Random port for the tests

Now that the application is configurable, let’s try to provide a configuration. In our test, we are going to configure our application to use the port 8081. So, previously we were deploying our verticle with:

vertx.deployVerticle(MyFirstVerticle.class.getName(), context.asyncAssertSuccess());

Let’s now pass some deployment options:

port = 8081;
DeploymentOptions options = new DeploymentOptions()
    .setConfig(new JsonObject().put("http.port", port)
);
vertx.deployVerticle(MyFirstVerticle.class.getName(), options, context.asyncAssertSuccess());

The DeploymentOptions object lets us customize various parameters. In particular, it lets us inject the JsonObject retrieved by the verticle when using the config() method.

Obviously, the test connecting to the server needs to be slightly modified to use the right port (port is a field):

vertx.createHttpClient().getNow(port, "localhost", "/", response -> {
  response.handler(body -> {
    context.assertTrue(body.toString().contains("Hello"));
    async.complete();
  });
});

Ok, well, this does not really fix our issue. What happens when the port 8081 is used too. Let’s now pick a random port:

ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();

DeploymentOptions options = new DeploymentOptions()
    .setConfig(new JsonObject().put("http.port", port)
    );

vertx.deployVerticle(MyFirstVerticle.class.getName(), options, context.asyncAssertSuccess());

So, the idea is very simple. We open a server socket that would pick a random port (that’s why we put 0 as parameter). We retrieve the used port and close the socket. Be aware that this method is not perfect and may fail if the picked port becomes used between the close method and the start of our HTTP server. However, it would work fine in the very high majority of the case.

With this in place, our test is now using a random port. Execute them with:

mvn clean test

External configuration - Let’s run on another port

Ok, well random port is not what we want in production. Could you imagine the face of your production team if you tell them that your application is picking a random port. It can actually be funny, but we should never mess with the production team.

So for the actual execution of your application, let’s pass the configuration in an external file. The configuration is stored in a json file.

Create the src/main/conf/my-application-conf.json with the following content:

{
  "http.port" : 8082
}

And now, to use this configuration just launch your application with:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar -conf src/main/conf/my-application-conf.json

Open a browser on http://localhost:8082, here it is !

How does that work ? Remember, our fat jar is using the Starter class (provided by Vert.x) to launch our application. This class is reading the -conf parameter and create the corresponding deployment options when deploying our verticle.

Conclusion

After having developed your first Vert.x application, we have seen how this application is configurable, and this without adding any complexity to our application. In the next post, we are going to see how we can use vertx-web to develop a small application serving static pages and a REST API. A bit more fancy, but still very simple.

Happy Coding and & Stay Tuned!


Some Rest with Vert.x

$
0
0

Previously in this blog series

This post is part of the Introduction to Vert.x series. So, let’s have a quick look about the content of the previous posts. In the first post, we developed a very simple Vert.x 3 application, and saw how this application can be tested, packaged and executed. In the last post, we saw how this application became configurable and how we can use a random port in test.

Well, nothing fancy… Let’s go a bit further this time and develop a CRUD-ish application. So an application exposing an HTML page interacting with the backend using a REST API. The level of RESTfullness of the API is not the topic of this post, I let you decide as it’s a very slippery topic.

So, in other words we are going to see:

  • Vert.x Web - a framework that let you create Web applications easily using Vert.x
  • How to expose static resources
  • How to develop a REST API

The code developed in this post is available on the post-3 branch of this Github project. We are going to start from the post-2 codebase.

So, let’s start.

Vert.x Web

As you may have notices in the previous posts, dealing with complex HTTP application using only Vert.x Core would be kind of cumbersome. That’s the main reason behind Vert.x Web. It makes the development of Vert.x base web applications really easy, without changing the philosophy.

To use Vert.x Web, you need to update the pom.xml file to add the following dependency:

<dependency><groupId>io.vertxgroupId><artifactId>vertx-webartifactId><version>3.0.0version>dependency>

That’s the only thing you need to use Vert.x Web. Sweet, no ?

Let’s now use it. Remember, in the previous post, when we requested http://localhost:8080, we reply a nice Hello World message. Let’s do the same with Vert.x Web. Open the io.vertx.blog.first.MyFirstVerticle class and change the start method to be:

@Overridepublicvoidstart(Future fut){
 // Create a router object.
 Router router = Router.router(vertx);

 // Bind "/" to our hello message - so we are still compatible.
 router.route("/").handler(routingContext -> {
   HttpServerResponse response = routingContext.response();
   response
       .putHeader("content-type", "text/html")
       .end("

Hello from my first Vert.x 3 application

"
); }); // Create the HTTP server and pass the "accept" method to the request handler. vertx .createHttpServer() .requestHandler(router::accept) .listen( // Retrieve the port from the configuration,// default to 8080. config().getInteger("http.port", 8080), result -> { if (result.succeeded()) { fut.complete(); } else { fut.fail(result.cause()); } } ); }

You may be surprise by the length of this snippet (in comparison to the previous code). But as we are going to see, it will make our app on steroids, just be patient.

As you can see, we start by creating a Router object. The router is the cornerstone of Vert.x Web. This object is responsible for dispatching the HTTP requests to the right handler. Two other concepts are very important in Vert.x Web:

  • Routes - which let you define how request are dispatched
  • Handlers - which are the actual action processing the requests and writing the result. Handlers can be chained.

If you understand these 3 concepts, you have understood everything in Vert.x Web.

Let’s focus on this code first:

router.route("/").handler(routingContext -> {
  HttpServerResponse response = routingContext.response();
  response
      .putHeader("content-type", "text/html")
      .end("

Hello from my first Vert.x 3 application

"
); });

It routes requests arriving on “/“ to the given handler. Handlers receive a RoutingContext object. This handler is quite similar to the code we had before, and it’s quite normal as it manipulates the same type of object: HttpServerResponse.

Let’s now have a look to the rest of the code:

vertx
    .createHttpServer()
    .requestHandler(router::accept)
    .listen(
        // Retrieve the port from the configuration,// default to 8080.
        config().getInteger("http.port", 8080),
        result -> {
          if (result.succeeded()) {
            fut.complete();
          } else {
            fut.fail(result.cause());
          }
        }
    );
}

It’s basically the same code as before, except that we change the request handler. We pass router::accept to the handler. You may not be familiar with this notation. It’s a reference to a method (here the method accept from the router object). In other worlds, it instructs vert.x to call the accept method of the router when it receives a request.

Let’s try to see if this work:

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

By opening http://localhost:8080 in your browser you should see the Hello message. As we didn’t change the behavior of the application, our tests are still valid.

Exposing static resources

Ok, so we have a first application using vert.x web. Let’s see some of the benefits. Let’s start with serving static resources, such as an index.html page. Before we go further, I should start with a disclaimer: “the HTML page we are going to see here is ugly like hell : I’m not a UI guy”. I should also add that there are probably plenty of better ways to implement this and a myriad of frameworks I should try, but that’s not the point. I tried to keep things simple and just relying on JQuery and Twitter Bootstrap, so if you know a bit of JavaScript you can understand and edit the page.

Let’s create the HTML page that will be the entry point of our application. Create an index.html page in src/main/resources/assets with the content from here. As it’s just a HTML page with a bit of JavaScript, we won’t detail the file here. If you have questions, just post comments.

Basically, the page is a simple CRUD UI to manage my collection of not-yet-finished bottles of Whisky. It was made in a generic way, so you can transpose it to your own collection. The list of product is displayed in the main table. You can create a new product, edit one or delete one. These actions are relying on a REST API (that we are going to implement) through AJAX calls. That’s all.

Once this page is created, edit the io.vertx.blog.first.MyFirstVerticle class and change the start method to be:

@Overridepublicvoidstart(Future fut){
 Router router = Router.router(vertx);
 router.route("/").handler(routingContext -> {
   HttpServerResponse response = routingContext.response();
   response
       .putHeader("content-type", "text/html")
       .end("

Hello from my first Vert.x 3 application

"
); }); // Serve static resources from the /assets directory router.route("/assets/*").handler(StaticHandler.create("assets")); vertx .createHttpServer() .requestHandler(router::accept) .listen( // Retrieve the port from the configuration,// default to 8080. config().getInteger("http.port", 8080), result -> { if (result.succeeded()) { fut.complete(); } else { fut.fail(result.cause()); } } ); }

The only difference with the previous code is the router.route("/assets/*").handler(StaticHandler.create("assets")); line. So, what does this line mean? It’s actually quite simple. It routes requests on “/assets/*” to resources stored in the “assets” directory. So our index.html page is going to be served using http://localhost:8080/assets/index.html.

Before testing this, let’s take a few seconds on the handler creation. All processing actions in Vert.x web are implemented as handler. To create a handler you always call the create method.

So, I’m sure you are impatient to see our beautiful HTML page. Let’s build and run the application:

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

Now, open your browser to http://localhost:8080/assets/index.html. Here it is… Ugly right? I told you.

As you may notice too… the table is empty, this is because we didn’t implement the REST API yet. Let’s do that now.

REST API with Vert.x Web

Vert.x Web makes the implementation of REST API really easy, as it basically routes your URL to the right handler. The API is very simple, and will be structured as follows:

  • GET /api/whiskies => get all bottles (getAll)
  • GET /api/whiskies/:id => get the bottle with the corresponding id (getOne)
  • POST /api/whiskies => add a new bottle (addOne)
  • PUT /api/whiskies/:id => update a bottle (updateOne)
  • DELETE /api/whiskies/id => delete a bottle (deleteOne)

We need some data…

But before going further, let’s create our data object. Create the src/main/java/io/vertx/blog/first/Whisky.java with the following content:

package io.vertx.blog.first;

import java.util.concurrent.atomic.AtomicInteger;

publicclassWhisky{

  privatestaticfinal AtomicInteger COUNTER = new AtomicInteger();

  privatefinalint id;

  private String name;

  private String origin;

  publicWhisky(String name, String origin){
    this.id = COUNTER.getAndIncrement();
    this.name = name;
    this.origin = origin;
  }

  publicWhisky(){
    this.id = COUNTER.getAndIncrement();
  }

  public String getName(){
    return name;
  }

  public String getOrigin(){
    return origin;
  }

  publicintgetId(){
    return id;
  }

  publicvoidsetName(String name){
    this.name = name;
  }

  publicvoidsetOrigin(String origin){
    this.origin = origin;
  }
}

It’s a very simple bean class (so with getters and setters). We choose this format because Vert.x is relying on Jackson to handle the JSON format. Jackson automates the serialization and deserialization of bean classes, making our code much simpler.

Now, let’s create a couple of bottles. In the MyFirstVerticle class, add the following code:

// Store our productprivate Map products = new LinkedHashMap<>();
// Create some productprivatevoidcreateSomeData(){
  Whisky bowmore = new Whisky("Bowmore 15 Years Laimrig", "Scotland, Islay");
  products.put(bowmore.getId(), bowmore);
  Whisky talisker = new Whisky("Talisker 57° North", "Scotland, Island");
  products.put(talisker.getId(), talisker);
}

Then, in the start method, call the createSomeData method:

@Overridepublicvoidstart(Future fut){

  createSomeData();

  // Create a router object.
  Router router = Router.router(vertx);

  // Rest of the method
}

As you have noticed, we don’t really have a backend here, it’s just a (in-memory) map. Adding a backend will be covered by another post.

Get our products

Enough decoration, let’s implement the REST API. We are going to start with GET /api/whiskies. It returns the list of bottles in a JSON Array.

In the start method, add this line just below the static handler line:

router.get("/api/whiskies").handler(this::getAll);

This line instructs the router to handle the GET requests on “/api/whiskies” by calling the getAll method. We could have inlined the handler code, but for clarity reasons let’s create another method:

privatevoidgetAll(RoutingContext routingContext){
  routingContext.response()
      .putHeader("content-type", "application/json; charset=utf-8")
      .end(Json.encodePrettily(products.values()));
}

As every handler our method receives a RoutingContext. It populates the response by setting the content-type and the actual content. Because our content may contain weird characters, we force the charset to UTF-8. To create the actual content, no need to compute the JSON string ourself. Vert.x lets us use the Json API. So Json.encodePrettily(products.values()) computes the JSON string representing the set of bottles.

We could have used Json.encodePrettily(products), but to make the JavaScript code simpler, we just return the set of bottles and not an object containing ID => Bottle entries.

With this in place, we should be able to retrieve the set of bottle from our HTML page. Let’s try it:

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

Then open the HTML page in your browser (http://localhost:8080/assets/index.html), and should should see:

Alt text

I’m sure you are curious, and want to actually see what is returned by our REST API. Let’s open a browser to http://localhost:8080/api/whiskies. You should get:

[ {
  "id" : 0,
  "name" : "Bowmore 15 Years Laimrig",
  "origin" : "Scotland, Islay"}, {
  "id" : 1,
  "name" : "Talisker 57° North",
  "origin" : "Scotland, Island"} ]

Create a product

Now we can retrieve the set of bottles, let’s create a new one. Unlike the previous REST API endpoint, this one need to read the request’s body. For performance reason, it should be explicitly enabled. Don’t be scared… it’s just a handler.

In the start method, add these lines just below the line ending by getAll:

router.route("/api/whiskies*").handler(BodyHandler.create());
router.post("/api/whiskies").handler(this::addOne);

The first line enables the reading of the request body for all routes under “/api/whiskies”. We could have enabled it globally with router.route().handler(BodyHandler.create()).

The second line maps POST requests on /api/whiskies to the addOne method. Let’s create this method:

privatevoidaddOne(RoutingContext routingContext){
  final Whisky whisky = Json.decodeValue(routingContext.getBodyAsString(),
      Whisky.class);
  products.put(whisky.getId(), whisky);
  routingContext.response()
      .setStatusCode(201)
      .putHeader("content-type", "application/json; charset=utf-8")
      .end(Json.encodePrettily(whisky));
}

The method starts by retrieving the Whisky object from the request body. It just reads the body into a String and passes it to the Json.decodeValue method. Once created it adds it to the backend map and returns the created bottle as JSON.

Let’s try this. Rebuild and restart the application with:

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

Then, refresh the HTML page and click on the Add a new bottle button. Enter the data such as: “Jameson” as name and “Ireland” as origin (purists would have noticed that this is actually a Whiskey and not a Whisky). The bottle should be added to the table.

Status 201 ?
As you can see, we have set the response status to 201. It means CREATED, and is the generally used in REST API that create an entity. By default vert.x web is setting the status to 200 meaning OK.

Finishing a bottle

Well, bottles do not last forever, so we should be able to delete a bottle. In the start method, add this line:

router.delete("/api/whiskies/:id").handler(this::deleteOne);

In the URL, we define a path parameter:id. So, when handling a matching request, Vert.x extracts the path segment corresponding to the parameter and let us access it in the handler method. For instance, /api/whiskies/0 maps id to 0.

Let’s see how the parameter can be used in the handler method. Create the deleteOne method as follows:

privatevoiddeleteOne(RoutingContext routingContext){
  String id = routingContext.request().getParam("id");
  if (id == null) {
    routingContext.response().setStatusCode(400).end();
  } else {
    Integer idAsInteger = Integer.valueOf(id);
    products.remove(idAsInteger);
  }
  routingContext.response().setStatusCode(204).end();
}

The path parameter is retrieved using routingContext.request().getParam("id"). It checks whether it’s null (not set), and in this case returns a Bad Request response (status code 400). Otherwise, it removes it from the backend map.

Status 204 ?
As you can see, we have set the response status to 204 - NO CONTENT. Response to the HTTP Verb delete have generally no content.

The other methods

We won’t detail getOne and updateOne as the implementations are straightforward and very similar. Their implementations are available on Github.

Cheers !

It’s time to conclude this post. We have seen how Vert.x Web lets you implement a REST API easily and how it can serve static resources. A bit more fancy than before, but still pretty easy.

In the next post, we are going to improve our tests to cover the REST API.

Say Tuned & Happy Coding !

Unit and Integration Tests

$
0
0

Previously in “introduction to vert.x”

Let’s refresh our mind about what we developed so far in the introduction to vert.x series. In the first post, we developed a very simple Vert.x 3 application, and saw how this application can be tested, packaged and executed. In the second post, we saw how this application became configurable and how we can use a random port in test, and use another configurable port in production. Finally, the previous post has shown how to use vertx-web and how to implement a small REST API. However, we forgot an important task. We didn’t test the API. In this post we will increase the confidence we have on this application by implementing unit and integration tests.

The code of this post is available in the post-4 branch of the project. The starting post, however is the code available in the post-3 branch.

Tests, Tests, Tests…

This post is mainly about tests. We distinguish two types of tests: unit tests and integration tests. Both are equally important, but have different focus. Unit tests ensure that one component of your application, generally a class in the Java world, behaves as expected. The application is not tested as a whole, but pieces by pieces. Integration tests are more black box in the sense that the application is started and tested generally externally.

In this post we are going to start with some more unit tests as a warm up session and then focus on integration tests. If you already implemented integration tests, you may be a bit scared, and it makes sense. But don’t worry, with Vert.x there are no hidden surprises.

Warmup : Some more unit tests

Let’s start slowly. Remember in the first post we have implemented a unit test with vertx-unit. The test we did is dead simple:

  1. we started the application before the test
  2. we checks that it replies “Hello”

Just to refresh your mind, let’s have a look to the code

@BeforepublicvoidsetUp(TestContext context)throws IOException {
    vertx = Vertx.vertx();
    ServerSocket socket = new ServerSocket(0);
    port = socket.getLocalPort();
    socket.close();
    DeploymentOptions options = new DeploymentOptions()
        .setConfig(new JsonObject().put("http.port", port)
        );
    vertx.deployVerticle(MyFirstVerticle.class.getName(), options, context.asyncAssertSuccess());
  }

The setUp method is invoked before each test (as instructed by the @Before annotation). It, first, creates a new instance of Vert.x. Then, it gets a free port and then deploys our verticle with the right configuration. Thanks to the context.asyncAssertSuccess() it waits until the successful deployment of the verticle.

The tearDown is straightforward and just closes the Vert.x instance. It automatically un-deploys the verticles:

@AfterpublicvoidtearDown(TestContext context){
    vertx.close(context.asyncAssertSuccess());
  }

Finally, our single test is:

@TestpublicvoidtestMyApplication(TestContext context){
    final Async async = context.async();
    vertx.createHttpClient().getNow(port, "localhost", "/", response -> {
      response.handler(body -> {
        context.assertTrue(body.toString().contains("Hello"));
        async.complete();
      });
    });
   }
It is only checking that the application replies "Hello" when we emit a HTTP request on `/`. Let's now try to implement some unit tests checkin that our web application and the REST API behave as expected. Let's start by checking that the `index.html` page is correctly served. This test is very similar to the previous one:
@TestpublicvoidcheckThatTheIndexPageIsServed(TestContext context){
    Async async = context.async();
    vertx.createHttpClient().getNow(port, "localhost", "/assets/index.html", response -> {
      context.assertEquals(response.statusCode(), 200);
      context.assertEquals(response.headers().get("content-type"), "text/html");
      response.bodyHandler(body -> {
        context.assertTrue(body.toString().contains("My Whisky Collection"));
        async.complete();
      });
    });
  }
We retrieve the `index.html` page and check: 1. it's there (status code 200) 2. it's a HTML page (content type set to "text/html") 3. it has the right title ("My Whisky Collection")
Retrieving content
As you can see, we can test the status code and the headers directly on the HTTP response, but ensure that the body is right, we need to retrieve it. This is done with a body handler that receives the complete body as parameter. Once the last check is made, we release the `async` by calling `complete`.
Ok, great, but this actually does not test our REST API. Let's ensure that we can add a bottle to the collection. Unlike the previous tests, this one is using `post` to _post_ data to the server:
@TestpublicvoidcheckThatWeCanAdd(TestContext context){
    Async async = context.async();
    final String json = Json.encodePrettily(new Whisky("Jameson", "Ireland"));
    final String length = Integer.toString(json.length());
    vertx.createHttpClient().post(port, "localhost", "/api/whiskies")
        .putHeader("content-type", "application/json")
        .putHeader("content-length", length)
        .handler(response -> {
          context.assertEquals(response.statusCode(), 201);
          context.assertTrue(response.headers().get("content-type").contains("application/json"));
          response.bodyHandler(body -> {
            final Whisky whisky = Json.decodeValue(body.toString(), Whisky.class);
            context.assertEquals(whisky.getName(), "Jameson");
            context.assertEquals(whisky.getOrigin(), "Ireland");
            context.assertNotNull(whisky.getId());
            async.complete();
          });
        })
        .write(json)
        .end();
  }

First we create the content we want to add. The server consumes JSON data, so we need a JSON string. You can either write your JSON document manually, or use the Vert.x method (Json.encodePrettily) as done here. Once we have the content, we create a post request. We need to configure some headers to be correctly read by the server. First, we say that we are sending JSON data and we also set the content length. We also attach a response handler very close to the checks made in the previous test. Notice that we can rebuild our object from the JSON document send by the server using the JSON.decodeValue method. It’s very convenient as it avoids lots of boilerplate code. At this point the request is not emitted, we need to write the data and call the end() method. This is made using .write(json).end();.

The order of the methods is important. You cannot write data if you don’t have a response handler configured. Finally don’t forget to call end.

So, let’s try this. You can run the test using:

mvn clean test

We could continue writing more unit test like that, but it could become quite complex. Let’s see how we could continue our tests using integration tests.

IT hurts

Well, I think we need to make that clear, integration testing hurts. If you have experience in this area, can you remember how long did it take to setup everything correctly? I get new white hairs by just thinking about it. Why are integration tests more complicated? It’s basically because of the setup:

  1. We must start the application in a close to production way
  2. We must then run the tests (and configure them to hit the right application instance)
  3. We must stop the application

That does not sound unconquerable like that, but if you need Linux, MacOS X and Windows support, it quickly get messy. There are plenty of great frameworks easing this such as Arquillian, but let’s do it without any framework to understand how it works.

We need a battle plan

Before rushing into the complex configuration, let’s think a minute about the tasks:

Step 1 - Reserve a free port
We need to get a free port on which the application can listen, and we need to inject this port in our integration tests.

Step 2 - Generate the application configuration
Once we have the free port, we need to write a JSON file configuring the application HTTP Port to this port.

Step 3 - Start the application
Sounds easy right? Well it’s not that simple as we need to launch our application in a background process.

Step 4 - Execute the integration tests
Finally, the central part, run the tests. But before that we should implement some integration tests. Let’s come to that later.

Step 5 - Stop the application
Once the tests have been executed, regardless if there are failures or errors in the tests, we need to stop the application.

There are multiple way to implement this plan. We are going to use a generic way. It’s not necessarily the better, but can be applied almost everywhere. The approach is tight to Apache Maven. If you want to propose an alternative using Gradle or a different tool, I will be happy to add your way to the post.

Implement the plan

As said above, this section is Maven-centric, and most of the code goes in the pom.xml file. If you never used the different Maven lifecycle phases, I recommend you to look at the introduction to the Maven lifecycle.

We need to add and configure a couple of plugins. Open the pom.xml file and in the section add:

<plugin><groupId>org.codehaus.mojogroupId><artifactId>build-helper-maven-pluginartifactId><version>1.9.1version><executions><execution><id>reserve-network-portid><goals><goal>reserve-network-portgoal>goals><phase>process-sourcesphase><configuration><portNames><portName>http.portportName>portNames>configuration>execution>executions>plugin>

We use the build-helper-maven-plugin (a plugin to know if you are often using Maven) to pick up a free port. Once found, the plugin assigns the http.port variable to the picked port. We execute this plugin early in the build (during the process-sources phase), so we can use the http.port variable in the other plugin. This was for the first step.

Two actions are required for the second step. First, in the pom.xml file, just below the opening tag, add:

<testResources><testResource><directory>src/test/resourcesdirectory><filtering>truefiltering>testResource>testResources>

This instructs Maven to filter resources from the src/test/resources directory. Filter means replacing placeholders by actual values. That’s exactly what we need as we now have the http.port variable. So create the src/test/resources/my-it-config.json file with the following content:

{
  "http.port": ${http.port}
}

This configuration file is similar to the one we did in previous posts. The only difference is the ${http.port} which is the (default) Maven syntax for filtering. So, when Maven is going to process or file it will replace ${http.port} by the selected port. That’s all for the second step.

The step 3 and 5 are a bit more tricky. We should start and stop the application. We are going to use the maven-antrun-plugin to achieve this. In the pom.xml file, below the build-helper-maven-plugin, add:

<plugin><artifactId>maven-antrun-pluginartifactId><version>1.8version><executions><execution><id>start-vertx-appid><phase>pre-integration-testphase><goals><goal>rungoal>goals><configuration><target><execexecutable="${java.home}/bin/java"dir="${project.build.directory}"spawn="true"><argvalue="-jar"/><argvalue="${project.artifactId}-${project.version}-fat.jar"/><argvalue="-conf"/><argvalue="${project.build.directory}/test-classes/my-it-config.json"/>exec>target>configuration>execution><execution><id>stop-vertx-appid><phase>post-integration-testphase><goals><goal>rungoal>goals><configuration><target><execexecutable="bash"dir="${project.build.directory}"spawn="false"><argvalue="-c"/><argvalue="ps ax | grep -i '${project.artifactId}' | awk 'NR==1{print $1}' | xargs kill -SIGTERM"/>exec>target>configuration>execution>executions>plugin>

That’s a huge piece of XML, isn’t it ? We configure two executions of the plugin. The first one, happening in the pre-integration-test phase, executes a set of bash command to start the application. It basically executes:

java -jar my-first-app-1.0-SNAPSHOT-fat.jar -conf .../my-it-config.json

Is the fatjar created ?
The fat jar embedding our application is created in the package phase, preceding the pre-integration-test, so yes, the fat jar is created.

As mentioned above, we launch the application as we would in a production environment.

Once, the integration tests are executed (step 4 we didn’t look at it yet), we need to stop the application (so in the the post-integration-test phase). To close the application, we are going to invoke some shell magic command to find our process in with the ps command and send the SIGTERM signal. It is equivalent to:

ps
.... -> find your process id
kill your_process_id -SIGTERM

And Windows ?
I mentioned it above, we want Windows to be supported and these commands are not going to work on Windows. Don’t worry, Windows configuration is below….

We should now do the fourth step we (silently) skipped. To execute our integration tests, we use the maven-failsafe-plugin. Add the following plugin configuration to your pom.xml file:

<plugin><groupId>org.apache.maven.pluginsgroupId><artifactId>maven-failsafe-pluginartifactId><version>2.18.1version><executions><execution><goals><goal>integration-testgoal><goal>verifygoal>goals><configuration><systemProperties><http.port>${http.port}http.port>systemProperties>configuration>execution>executions>plugin>

As you can see, we pass the http.port property as a system variable, so our tests are able to connect on the right port.

That’s all ! Wow…. Let’s try this (for windows users, you will need to be patient or to jump to the last section).

mvn clean verify

We should not use mvn integration-test because the application would still be running. The verify phase is after the post-integration-test phase and will analyse the integration-tests results. Build failures because of integration tests failed assertions are reported in this phase.

Hey, we don’t have integration tests !

And that’s right, we set up everything, but we don’t have a single integration test. To ease the implementation, let’s use two libraries: AssertJ and Rest-Assured.

AssertJ proposes a set of assertions that you can chain and use fluently. Rest Assured is a framework to test REST API.

In the pom.xml file, add the two following dependencies just before :

<dependency><groupId>com.jayway.restassuredgroupId><artifactId>rest-assuredartifactId><version>2.4.0version><scope>testscope>dependency><dependency><groupId>org.assertjgroupId><artifactId>assertj-coreartifactId><version>2.0.0version><scope>testscope>dependency>

Then, create the src/test/java/io/vertx/blog/first/MyRestIT.java file. Unlike unit test, integration test ends with IT. It’s a convention from the Failsafe plugin to distinguish unit (starting or ending with Test) from integration tests (starting or ending with IT). In the created file add:

package io.vertx.blog.first;

import com.jayway.restassured.RestAssured;
import org.junit.AfterClass;
import org.junit.BeforeClass;

publicclassMyRestIT{

  @BeforeClasspublicstaticvoidconfigureRestAssured(){
    RestAssured.baseURI = "http://localhost";
    RestAssured.port = Integer.getInteger("http.port", 8080);
  }

  @AfterClasspublicstaticvoidunconfigureRestAssured(){
    RestAssured.reset();
  }
}

The methods annotated with @BeforeClass and @AfterClass are invoked once before / after all tests of the class. Here, we just retrieve the http port (passed as a system property) and we configure REST Assured.

It’s now time to implement a real test. Let’s check we can retrieve an individual product:

@TestpublicvoidcheckThatWeCanRetrieveIndividualProduct(){
// Get the list of bottles, ensure it's a success and extract the first id.finalint id = get("/api/whiskies").then()
    .assertThat()
    .statusCode(200)
    .extract()
    .jsonPath().getInt("find { it.name=='Bowmore 15 Years Laimrig' }.id");
// Now get the individual resource and check the content
get("/api/whiskies/" + id).then()
    .assertThat()
    .statusCode(200)
    .body("name", equalTo("Bowmore 15 Years Laimrig"))
    .body("origin", equalTo("Scotland, Islay"))
    .body("id", equalTo(id));
}

Here you can appreciate the power and expressiveness of Rest Assured. We retrieve the list of product, ensure the response is correct, and extract the id of a specific bottle using a JSON (Groovy) Path expression.

Then, we try to retrieve the metadata of this individual product, and check the result.

Let’s now implement a more sophisticated scenario. Let’s add and delete a product:

@TestpublicvoidcheckWeCanAddAndDeleteAProduct(){
  // Create a new bottle and retrieve the result (as a Whisky instance).
  Whisky whisky = given()
      .body("{\"name\":\"Jameson\", \"origin\":\"Ireland\"}").request().post("/api/whiskies").thenReturn().as(Whisky.class);
  assertThat(whisky.getName()).isEqualToIgnoringCase("Jameson");
  assertThat(whisky.getOrigin()).isEqualToIgnoringCase("Ireland");
  assertThat(whisky.getId()).isNotZero();
  // Check that it has created an individual resource, and check the content.
  get("/api/whiskies/" + whisky.getId()).then()
      .assertThat()
      .statusCode(200)
      .body("name", equalTo("Jameson"))
      .body("origin", equalTo("Ireland"))
      .body("id", equalTo(whisky.getId()));
  // Delete the bottle
  delete("/api/whiskies/" + whisky.getId()).then().assertThat().statusCode(200);
  // Check that the resrouce is not available anymore
  get("/api/whiskies/" + whisky.getId()).then()
      .assertThat()
      .statusCode(404);
}
So, now we have integration tests let's try:
mvn clean verify

Simple no ? Well, simple once the setup is done right…. You can continue implementing other integration tests to be sure that everything behave as you expect.

Dear Windows users…

This section is the bonus part for Windows user, or people wanting to run their integration tests on Windows machine too. The command we execute to stop the application is not going to work on Windows. Luckily, it’s possible to extend the pom.xml with a profile executed on Windows.

In your pom.xml, just after , add:

<profiles><profile><id>windowsid><activation><os><family>windowsfamily>os>activation><build><plugins><plugin><artifactId>maven-antrun-pluginartifactId><version>1.8version><executions><execution><id>stop-vertx-appid><phase>post-integration-testphase><goals><goal>rungoal>goals><configuration><target><execexecutable="wmic"dir="${project.build.directory}"spawn="false"><argvalue="process"/><argvalue="where"/><argvalue="CommandLine like '%${project.artifactId}%' and not name='wmic.exe'"/><argvalue="delete"/>exec>target>configuration>execution>executions>plugin>plugins>build>profile>profiles>

This profile replaces the actions described above to stop the application with a version working on windows. The profile is automatically enabled on Windows. As on others operating systems, execute with:

mvn clean verify

Conclusion

Wow, what a trip ! We are done… In this post we have seen how we can gain confidence in Vert.x applications by implementing both unit and integration tests. Unit tests, thanks to vert.x unit, are able to check the asynchronous aspect of Vert.x application, but could be complex for large scenarios. Thanks to Rest Assured and AssertJ, integration tests are dead simple to write… but the setup is not straightforward. This post have shown how it can be configured easily. Obviously, you could also use AssertJ and Rest Assured in your unit tests.

Next time, we are going to replace the in memory backend with a database, and use asynchronous integration with this database.

Stay Tuned & Happy Coding !

Vert.x3 real time web apps

$
0
0

One of the interesting features of Vert.x is the SockJS event bus bridge. This piece of software
allows external applications to communicate with Vert.x event bus using Websockets and if your browser does not
support it then it gracefully degrades to pooling AJAX calls.

WebSockets bring a new level of interaction to the web, they really bring real time to web applications due to the
fact that its communication model is bi-directional in contrast to the traditional HTTP model where a client can
initiate a data request to a server but not the other way around.

In this small post I will demonstrate how you can create a simple collaborative drawing app. The idea is simple, all
users that open the app will be be presented with a empty canvas and what they draw or is drawn on other canvas is
shared in real time on their screen.

For the sake of simplicity and making this post light there is no security involved so, everyone is free to listen to
what is being drawn, however the external application has limited read write access to a single address on Vert.x
event bus, ensuring that other services running on the cluster will not be exposed.

This is what you should expect to see:

screecast

Bootstrap a project

If you followed the previous series on Vert.x development, you saw
that Java and Maven were the main topic, since Vert.x is polyglot I will focus on JavaScript and
NPM as my programming language and package management tool.

With NPM start by creating a package.json, in order to do this we should run:

npm init

This will present a selection of questions and in the end you should have a basic package.json file. This
configuration is very basic so you need to add a dependency to Vert.x so
you can run the application. You can add it to the dependencies property and it should look more or less like this:

{
  "name": "draw",
  "private": true,
  "dependencies": {
  "vertx3-full": "3.0.0-1"
  },
  "scripts": {
  "start": "vertx run server.js"
  },
  "version": "1.0.0",
  "main": "server.js",
  "devDependencies": {},
  "author": "",
  "license": "ISC",
  "description": "A Real Time Drawing App"
}

If you do not know why there is the dependency on vertx3-full or why the added scripts property please check the
older blog post about it.

Project Structure

This post has no preference over project structure, so if you do not agree with the structure used here feel free to
use what you feel best. For this example I will keep it to:

├── package.json├── server.js└── webroot
  ├── assets
  │   └── js
  │     ├── script.js│     └── vertxbus.js└── index.html3 directories, 5 files

As you can imagine server.js will be our Vert.x application and everything under webroot will be the client
application.

The client application is not really Vert.x specific and could in theory be used by any other framework so I will go
lightly over its code.

Client Application

Our application main entry point is as one can expect index.html. In the index file define the following HTML:

<html><head><metacharset="utf-8"/><title>Real time drawing Apptitle>head><body><canvasid="paper"width="1900"height="1000">
  Your browser needs to support canvas for this to work!
canvas><scriptsrc="http://code.jquery.com/jquery-1.8.0.min.js">script><scriptsrc="//cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js">script><scriptsrc='assets/js/vertxbus.js'>script><scriptsrc="assets/js/script.js">script>body>html>

As I previously wrote, the idea is to keep it as simple as possible so it is all about having a canvas element and a
application main script script.js. All the rest are files served by CDNs that provide common web application
libraries such as jQuery, HTML5 shim for older browsers, SockJS client and vertxbus bridge.

The main code is on script.js file:

$(function(){

  // This demo depends on the canvas elementif (!('getContext'indocument.createElement('canvas'))) {
    alert('Sorry, it looks like your browser does not support canvas!');
    returnfalse;
  }

  var doc = $(document),
    canvas = $('#paper'),
    ctx = canvas[0].getContext('2d');

  // Generate an unique IDvar id = Math.round($.now() * Math.random());

  // A flag for drawing activityvar drawing = false;

  var clients = {};
  // create a event bus bridge to the server that served this filevar eb = new vertx.EventBus(
      window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/eventbus');

  eb.onopen = function(){
    // listen to draw events
    eb.registerHandler('draw', function(data){
      // Is the user drawing?if (data.drawing && clients[data.id]) {

        // Draw a line on the canvas. clients[data.id] holds// the previous position of this user's mouse pointer

        drawLine(clients[data.id].x, clients[data.id].y, data.x, data.y);
      }

      // Saving the current client state
      clients[data.id] = data;
      clients[data.id].updated = $.now();
    });
  };

  var prev = {};

  canvas.on('mousedown', function(e){
    e.preventDefault();
    drawing = true;
    prev.x = e.pageX;
    prev.y = e.pageY;
  });

  doc.bind('mouseup mouseleave', function(){
    drawing = false;
  });

  var lastEmit = $.now();

  doc.on('mousemove', function(e){
    if ($.now() - lastEmit >30) {
      eb.publish('draw', {
        'x': e.pageX,
        'y': e.pageY,
        'drawing': drawing,
        'id': id
      });
      lastEmit = $.now();
    }

    // Draw a line for the current user's movement, as it is// not received in the eventbusif (drawing) {

      drawLine(prev.x, prev.y, e.pageX, e.pageY);

      prev.x = e.pageX;
      prev.y = e.pageY;
    }
  });

  // Remove inactive clients after 10 seconds of inactivity
  setInterval(function(){

    for (var ident in clients) {
      if (clients.hasOwnProperty(ident)) {
        if ($.now() - clients[ident].updated >10000) {
          // Last update was more than 10 seconds ago.// This user has probably closed the pagedelete clients[ident];
        }
      }
    }

  }, 10000);

  functiondrawLine(fromx, fromy, tox, toy){
    ctx.moveTo(fromx, fromy);
    ctx.lineTo(tox, toy);
    ctx.stroke();
  }

});

The most important part in this code is all the code related to eb. The variable eb is our bridge to the event
bus, Start by creating a bridge using the vertx.EventBus object and define where to connect, using the details
of the current window location.

Then add a onopen listener that will subscribe to the address draw on the event bus so it can listen to all
messages regarding drawing and perform the drawing actions. Since listening is not enough I also add a mouse listener
to the document so when it moves it publishes events to the draw address.

Note that I am using publish and not send, the reason should be obvious, I want everyone to know this users mouse
movements, I am not interested on sending the events to just a single user. You can see now that if you want to have
a drawing app in a one on one user basis then instead of publish() you should use send().

Server Application

The server code is quite straight forward, all you need is:

var Router = require("vertx-web-js/router");
var SockJSHandler = require("vertx-web-js/sock_js_handler");
var StaticHandler = require("vertx-web-js/static_handler");

var router = Router.router(vertx);

// Allow outbound traffic to the draw addressvar options = {
  "outboundPermitteds" : [{"address" : "draw"}],
  "inboundPermitteds" :  [{"address" : "draw"}]
};

router.route("/eventbus/*").handler(SockJSHandler.create(vertx).bridge(options).handle);

// Serve the static resources
router.route().handler(StaticHandler.create().handle);

vertx.createHttpServer().requestHandler(router.accept).listen(8080);

We start with the usual imports, we import a reference to the Router object and a couple of helper handlers
SockJSHandler and StaticHandler. As their names should tell you one handler will be responsible to handle all
SockJS data and the other all HTTP file serving requests.

We then add then to a router and start a HTTP server that will handle all incoming request using the handler accept
function. Finally we listen on port 8080 and we are ready.

Note that there is a options object where a couple of properties are defined outbound/inbound permitted addresses.
Without this configuration the external application will not be allowed to connect to the vert.x bus, in fact the
default configuration of the SockJSHandler is deny all. So you must specify explicitly which address are allowed to
receive messages from SockJS and which ones are allowed to send/publish to SockJS.

Now you can start your application, don’t forget to install the dependencies for the first time:

npm install

And then run the application:

npm start

If you now open 2 browser windows you will be able to draw nice pictures and see the drawing showing in “real time”
on the other window, if you then draw on the second you should get the mirror effect on the first window.

Have fun!

Writing secure Vert.x Web apps

$
0
0

This is a starting guide for securing vert.x web applications. It is by no means a comprehensive guide on web application security such as OWASP. Standard rules and practices apply to vert.x apps as if they would to any other web framework.

The post will cover the items that always seem to come up on forums.

Don’t run as root

It is a common practise that your devops team member will constantly say, one shall run a service with the least amount of privileges necessary and no more. Although this might sound like folklore to less experienced developers that hit an issue when trying to run on privileged ports 80, 443, running as root solves it quickly but open a door to bigger problems. Lets look at this code:

publicclassAppextendsAbstractVerticle{
  @Overridepublicvoidstart(){

    Router router = Router.router(vertx);

    router.route().handler(StaticHandler.create(""));

    vertx.createHttpServer().requestHandler(router::accept).listen(80);
  }
}

When started with the CWD set to / (java -Dvertx.cwd=/ ...) you just created a simple file server for all your server storage. Now imagine that you want to start this application you will hit the error:

Aug 26, 20152:02:18 PM io.vertx.core.http.impl.HttpServerImpl
SEVERE: java.net.SocketException: Permission denied

So if you do now run as root it will start, however in your browser now try to navigate to: http://localhost/etc/shadow congratulations you just exposed your server loginsandpasswords!

There are several ways to run as a under privileged user, you can use iptables to forward requests to higher ports, use authbind, run behind a proxy like ngnix, etc…

Sessions

Many applications are going to deal with user sessions at some point.

Session cookies should have the SECURE and HTTPOnly flags set. This ensures that they can only be sent over HTTPS (you are using HTTPS right?) and there is no script access to the cookie client side:

Router router = Router.router(vertx);

    router.route().handler(CookieHandler.create());
    router.route().handler(SessionHandler
        .create(LocalSessionStore.create(vertx))
        .setCookieHttpOnlyFlag(true)
        .setCookieSecureFlag(true)
    );

    router.route().handler(routingContext -> {

      Session session = routingContext.session();

      Integer cnt = session.get("hitcount");
      cnt = (cnt == null ? 0 : cnt) + 1;

      session.put("hitcount", cnt);

      routingContext.response().end("Hitcount: " + cnt);
    });

    vertx.createHttpServer().requestHandler(router::accept).listen(8080);

And in this case when inspecting your browser you should see:

nocookie

Of course if you do not do that any script on your browser has the capability of reading, sniffing hijacking or tampering your sessions.

Security Headers

There are plenty of security headers that help improve security with just a couple of lines of code. There is no need to explain them here since there are good articles online that will probably do it better than me.

Here is how one could implement a couple of them:

publicclassAppextendsAbstractVerticle{

  @Overridepublicvoidstart(){

    Router router = Router.router(vertx);
    router.route().handler(ctx -> {
      ctx.response()
          // do not allow proxies to cache the data
          .putHeader("Cache-Control", "no-store, no-cache")
          // prevents Internet Explorer from MIME - sniffing a// response away from the declared content-type
          .putHeader("X-Content-Type-Options", "nosniff")
          // Strict HTTPS (for about ~6Months)
          .putHeader("Strict-Transport-Security", "max-age=" + 15768000)
          // IE8+ do not allow opening of attachments in the context of this resource
          .putHeader("X-Download-Options", "noopen")
          // enable XSS for IE
          .putHeader("X-XSS-Protection", "1; mode=block")
          // deny frames
          .putHeader("X-FRAME-OPTIONS", "DENY");
    });

    vertx.createHttpServer().requestHandler(router::accept).listen(8080);
  }
}

Cross-Site Request Forgery (CSRF) Protection

Vert.x web provides CSRF protection using an included handler. To enable CSRF protections you need to add it to your router as you would add any other handler:

publicclassAppextendsAbstractVerticle{

  @Overridepublicvoidstart(){

    Router router = Router.router(vertx);

    router.route().handler(CookieHandler.create());
    router.route().handler(SessionHandler
        .create(LocalSessionStore.create(vertx))
        .setCookieHttpOnlyFlag(true)
        .setCookieSecureFlag(true)
    );
    router.route().handler(CSRFHandler.create("not a good secret"));

    router.route().handler(ctx -> {
      ...
    });

The handler adds a CSRF token to requests which mutate state. In order change the state a (XSRF-TOKEN) cookie is set with a unique token, that is expected to be sent back in a (X-XSRF-TOKEN) header.

Limit uploads

When dealing with uploads always define a upper bound, otherwise you will be vulnerable to DDoS attacks. For example lets say that you have the following code:

publicclassAppextendsAbstractVerticle{

  @Overridepublicvoidstart(){

    Router router = Router.router(vertx);

    router.route().handler(BodyHandler.create());

    router.route().handler(ctx -> {
      ...

Now a bad intentioned person could generate a random file with 1GB of trash:

dd if=/dev/urandom of=ddos bs=1G count=1

And then upload it to your server:

curl --data-binary "@ddos" -H "Content-Type: application/octet-stream" -X POST http://localhost:8080/

Your application will happily try to handle this until one of 2 things happens, it will run out of disk space or memory. In order to mitigate these kind of attacks always specify the maximum allowed upload size:

publicclassAppextendsAbstractVerticle{

  privatestaticfinalint KB = 1024;
  privatestaticfinalint MB = 1024 * KB;

  @Overridepublicvoidstart(){

    Router router = Router.router(vertx);
    router.route().handler(BodyHandler.create().setBodyLimit(50 * MB));

Final Words

Although this is just a small list of things you should remember when implementing your application there are more comprehensive checklists to check:

Contract Driven REST Services with Vert.x3

$
0
0

We see a new trend in development where we are shifting from developing applications to develop APIs. More and more we see services being offered as REST APIs that we are allowed to consume and we already see this trend from the big names in the industry, e.g.: Facebook, Wikipedia, Amazon, Twitter, Google and Reddit they all offer APIs.

Of course making an REST API using Vert.x is quite simple, just use Vert.x Web and you can start writing your API in seconds, however an API without documentation is not an API since no developer will know how to use it. However this is one of the most sensitive issues to tackle in software development, nobody likes to write documentation. However, in the REST age where REST-based web-services are ubiquitous, documentation for public web-services is a necessity. There are a lot of tools out there, two of the most popular are without a doubt:

Both frameworks have a large ecosystem of tools and tooling around but they tackle the documentation from two different perspectives. While Swagger is purely a documentation tool it tackles the problem from bottom up and RAML does document top down. They both rely on a document (JSON for Swagger, YAML for RAML).

I’ll now go over building a simple Hello World API, document it and test it. For this example I’ll choose RAML since it feels more natural to the way we code with Vert.x Web.

Define the Hello World API

We need a contract and as with any other development we need some specification, You can learn about RAML in its website and quickly see how easy it is to get started. So we start with the following specification:

#%RAML 0.8

title: Hello world REST API
baseUri:http://localhost:8080/
version: v1

/hello:
get:
responses:
200:
body:
application/json:
schema: |
{ “$schema”: http://json-schema.org/schema,
“type”: “object”,
“description”: “Hello World Greeting”,
“properties”: {
“greeting”: { “type”: “string” }
},
“required”: [ “greeting” ]
}

So if you didn’t understood why I named RAML as a top down documentation tool, I think it becomes clear now. So there are some basic definition on the top of the file like, title, baseUri and version which should be self explanatory.

And then we start with the API documentation, so we specify that at the URL/hello using the HTTP verb GET you are expected to get a response with status code 200 and the body of the response should have content type application/json. This is a very minimal document, one could go over and specify the json schema for the response, input values, etc…, however lets just keep it simple for this example.

IDE ?
if you do not like to write yaml in your editor you can always use the API Designer which gives you instant feedback on your API document and provides a testing platform
.

Implement the API

So you got your contract, time to implement it, this is a very simple API so I’ll jump to the code immediately:

publicclassAppextendsAbstractVerticle{
  @Overridepublicvoidstart(){
    Router router = Router.router(vertx);

    router.get("/hello").handler(rc -> {
      rc.response()
          .putHeader("content-type", "application/json")
          .end(new JsonObject().put("greeting", "Hello World!").encode());
    });

    vertx.createHttpServer().requestHandler(router::accept).listen(8080);
  }
}

As you can see the code resembles the contract document, when there is a GET request to /hello we send to the client a empty JSON document {}.

Are we done?

The answer is NO!!! how can we be sure that our implementation does comply to the contract? We need to test. As I wrote before there is no specific support for Vert.x from RAML or other tools however in this case it is not a problem we can still test our code without having the need to implement a test framework from the ground up.

Testing our contract

The initial step is to setup a test, this should be trivial we are using Java (although we could test any of Vert.x
supported languages using the same technique). We create a JUnit unit test.

JUnit ? ! For this example I will be using JUnit instead of Vert.x Test mostly to let you know that Vert.x isn’t an opinionated framework, so you are free to choose the tool that best fits you.
publicclassAPITest{

  @BeforeClasspublicstaticvoidbootApp(){
    Runner.run(App.class);
  }

  @TestpublicvoidtestHelloEndpoint(){
  }
}

So at this moment you have a simple test, I’ll share the code of the runner class (basically it just instantiates a
Vertx instance and load the verticle we just implemented above) and has a empty test testHelloEndpoint.

Load the API definition into the test

publicclassAPITest{

  privatestaticfinal RamlDefinition api = RamlLoaders.fromClasspath()
        .load("/api/hello.raml")
        .assumingBaseUri("http://localhost:8080/");

  private CheckingWebTarget checking;

  ...
}

So the first step is to load the API definition into our test and have a reference to a CheckingWebTarget object. The checking object is where you can perform assertions, but to do this we need some client make REST calls in order to test.

Create a REST client

There are many options for this, you could use JAX-RS, RestAssured, RestEasy, etc… so I’ll pick RestEasy for now:

publicclassAPITest{

  privatestaticfinal RamlDefinition api = RamlLoaders.fromClasspath()
      .load("/api/hello.raml")
      .assumingBaseUri("http://localhost:8080/");

  private ResteasyClient client = new ResteasyClientBuilder().build();
  private CheckingWebTarget checking;

  @BeforeClasspublicstaticvoidbootApp(){
    Runner.run(App.class);
  }

  @BeforepublicvoidcreateTarget(){
    checking = api.createWebTarget(client.target("http://localhost:8080"));
  }

  ...
}

Implement the test

All of the boilerplate code is in place and if you look at the previous section you will see that it wasn’t that bad, just a few lines and you loaded the RAML contract, created a REST client and started up your application and all this under ~10 lines of code.

So lets finish and implement the verification of the contract:

publicclassAPITest{
  ...

  @TestpublicvoidtestHelloEndpoint(){
    checking.path("/hello").request().get();
    Assert.assertThat(checking.getLastReport(), RamlMatchers.hasNoViolations());
  }
}

Once you run your tests, you will see:

13:09:28.200 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Sending request: GET /hello HTTP/1.1
13:09:28.201 [main] DEBUG org.apache.http.wire -  >>"GET /hello HTTP/1.1[\r][\n]"
13:09:28.202 [main] DEBUG org.apache.http.wire -  >>"Accept-Encoding: gzip, deflate[\r][\n]"
13:09:28.202 [main] DEBUG org.apache.http.wire -  >>"Host: localhost:8080[\r][\n]"
13:09:28.202 [main] DEBUG org.apache.http.wire -  >>"Connection: Keep-Alive[\r][\n]"
13:09:28.202 [main] DEBUG org.apache.http.wire -  >>"[\r][\n]"
13:09:28.202 [main] DEBUG org.apache.http.headers - >> GET /hello HTTP/1.1
13:09:28.202 [main] DEBUG org.apache.http.headers - >> Accept-Encoding: gzip, deflate
13:09:28.203 [main] DEBUG org.apache.http.headers - >> Host: localhost:8080
13:09:28.203 [main] DEBUG org.apache.http.headers - >> Connection: Keep-Alive
13:09:28.412 [main] DEBUG org.apache.http.wire -  <<"HTTP/1.1200OK[\r][\n]"13:09:28.413 [main] DEBUGorg.apache.http.wire-<<"content-type:application/json[\r][\n]"13:09:28.413 [main] DEBUGorg.apache.http.wire-<<"Content-Length:2[\r][\n]"13:09:28.413 [main] DEBUGorg.apache.http.wire-<<"[\r][\n]"13:09:28.414 [main] DEBUGo.a.h.i.conn.DefaultClientConnection-Receivingresponse:HTTP/1.1200OK13:09:28.414 [main] DEBUGorg.apache.http.headers-<<HTTP/1.1200OK13:09:28.415 [main] DEBUGorg.apache.http.headers-<<content-type:application/json13:09:28.415 [main] DEBUGorg.apache.http.headers-<<Content-Length:213:09:28.429 [main] DEBUGorg.apache.http.wire-<<"{}"Testsrun:1, Failures:0, Errors:0, Skipped:0, Timeelapsed:1.076secResults:Testsrun:1, Failures:0, Errors:0, Skipped:0

And we are done, we now have a API that follow the contract, you can now keep developing your API and implementation and have a test driven approach to be sure that the contract is not broken.

Next steps

Until now you have learn how to integrate RAML into Vert.x and CI, however the users of your API will not be able to know much about the API yet since its documentation is not publicly available. So lets publish online the documentation of your API, of course if your API is private you do not need to follow these steps.

In order to do this all we need it to include in our application the RAML console, the fastest way to do this is just download a release to src/main/resouces/webroot and in the original application [Vert.x Router] we add a Static Content Handler to serve the console files. Your application source code should look like this:

publicclassAppextendsAbstractVerticle{
  @Overridepublicvoidstart(){
    Router router = Router.router(vertx);

    router.get("/hello").handler(rc -> {
      rc.response()
          .putHeader("content-type", "application/json")
          .end(new JsonObject().put("greeting", "Hello World!").encode());
    });

    // optionally enable the web console so users can play with your API// online from their web browsers
    router.route().handler(StaticHandler.create());

    vertx.createHttpServer().requestHandler(router::accept).listen(8080);
  }
}

Once you start you application open a browser pointing at the console. Once you do that you should be presented with something similar to this:

apiconsole

Article source code

You can get the full source code for this article here.

Vert.x 3.1.0 is released !

$
0
0

I’m pleased to announce the release of Vert.x 3.1!

Some of the highlights of this release include:

  • Vertx-sync is a set of utilities that allow you to perform asynchronous operations and receive events in a synchronous way, but without blocking kernel threads.

  • Vertx-stomp is an implementation of a STOMP server and client. You can use the STOMP server with other clients and use the STOMP client with other servers. The server and the client supports the version 1.0, 1.1 and 1.2 of the STOMP protocol. The STOMP server can also be used as a bridge with the vert.x event bus.

  • Vertx-shell is a command line interface for the Vert.x runtime available from regular terminals using different protocols.

  • Re-implementation of the Starter class and related functionality. And now redeploy is back!

Full release notes can be found here:

https://github.com/vert-x3/wiki/wiki/3.1-Release-Notes

Breaking changes here:

https://github.com/vert-x3/wiki/wiki/3.1.0---Breaking-changes

NPM for the event-bus client here:

https://www.npmjs.com/package/vertx3-eventbus-client

Many thanks to all the committers and community whose contributions made this possible.

A special thanks to the full-time team - Clement, Julien and Paulo who put in a lot of work to get this out :)

Next stop is Vert.x 3.2 which we hope to have out before Christmas.

The artifacts have been deployed to Maven Central and you can get the distribution on Bintray.

Using the asynchronous SQL client

$
0
0

Finally, back… This post is the fifth post of the introduction to vert.x blog series, after a not-that-small break. In this post we are going to see how we can use JDBC in a vert.x application, and this, using the asynchronous API provided by the vertx-jdbc-client.

Previously in the introduction to vert.x series

As it was quite some time since the last post, let’s start by refreshing our mind about the four previous posts:

  1. The first post has described how to build a vert.x application with Maven and execute unit tests.
  2. The second post has described how this application can become configurable.
  3. The third post has introduced vertx-web, and a small collection management application has been developed. This application offers a REST API used by a HTML/JavaScript frontend.
  4. The previous post has presented how you can run integration tests to ensure the behavior of your application.

In this post, back to code. The current application uses an in-memory map to store the products. It’s time to use a database. In this post we are going to use HSQL, but you can use any database providing a JDBC driver. Interactions with the database will be asynchronous and made using the vertx-jdbc-client.

The code of this post are available on this Github project, in the post-5 branch branch.

Asynchronous?

One of the vert.x characteristics is being asynchronous. With an asynchronous API, you don’t wait for a result, but you are notified when this result is ready. Just to illustrate this, let’s take a very simple example.

Let’s imagine an add method. Traditionally, you would use it like this: int r = add(1, 1). This is a synchronous API as you are waiting for the result. An asynchronous version of this API would be: add(1, 1, r -> { /* do something with the result */ }). In this version, you pass a Handler called when the result has been computed. The method does not return anything, and could be implemented as:

publicvoidadd(int a, int b, Handler resultHandler){
    int r = a + b;
    resultHandler.handle(r);
}

Just to avoid misconceptions, asynchronous API are not about threads. As we can see in the add example, there are no threads involved.

JDBC yes, but asynchronous

So, now that we have seen some basics about asynchronous API, let’s have a look to the vertx-jdbc-client. This component lets us interact with a database through a JDBC driver. These interactions are asynchronous, so when you were doing:

String sql ="SELECT * FROM Products";
ResultSet rs = stmt.executeQuery(sql);

it will be:

connection.query("SELECT * FROM Products", result -> {
        // do something with the result
});

This model is more efficient as it avoids waiting for the result. You are notified when the result is available.

Let’s now modify our application to use a database to store our products.

Some maven dependencies

The first things we need to do it to declare two new Maven dependencies in our pom.xml file:

<dependency><groupId>io.vertxgroupId><artifactId>vertx-jdbc-clientartifactId><version>3.1.0version>dependency><dependency><groupId>org.hsqldbgroupId><artifactId>hsqldbartifactId><version>2.3.3version>dependency>

The first dependency provides the vertx-jdbc-client, while the second one provide the HSQL JDBC driver. If you want to use another database, change this dependency. You will also need to change the JDBC url and JDBC driver class name later.

Initializing the JDBC client

Now that we have added these dependencies, it’s time to create our JDBC client:

In the MyFirstVerticle class, declare a new field JDBCClient jdbc;, and add the following line at the beginning of the start method:

jdbc = JDBCClient.createShared(vertx, config(), "My-Whisky-Collection");

This creates an instance of JDBC client, configured with the configuration provided to the verticle. To work correctly this configuration needs to provide:

  • url - the JDBC url such as jdbc:hsqldb:mem:db?shutdown=true
  • driver_class - the JDBC driver class such as org.hsqldb.jdbcDriver

Ok, we have the client, we need a connection to the database. This is achieved using the jdbc.getConnection that take a Handler> as parameter. Let’s have a deeper look to this type. It’s a Handler, so it is called when the result is ready. This result is an instance of AsyncResult. AsyncResult is a structure provided by vert.x that lets us know if the operation was completed successfully or failed. In case of success, it provides the result, here an instance of SQLConnection.

When you receive an instance of AsyncResult, your code generally looks like:

if (ar.failed()) {
  System.err.println("The operation has failed...: "
      + ar.cause().getMessage());
} else {
  // Use the result:
  result = ar.result();
 }

So, let’s go back to our SQLConnection. We need to retrieve it, and then start the rest of the application. This changes how we start the application, as it will become asynchronous. So, if we divide our startup sequence into small chunks it would be something like:

startBackend(
 (connection) -> createSomeData(connection,
     (nothing) -> startWebApp(
         (http) -> completeStartup(http, fut)
     ), fut
 ), fut);

with:

  1. startBackend - retrieves a SQLConnection and then calls the next step
  2. createSomeData - initializes the database and inserts some data. When done, it calls the next step
  3. startWebApp - starts our web application
  4. completeStartup - finalizes our start sequence

fut is the completion future passed by vert.x that let us report when we are started, or if an issue has been encountered while starting.

Let’s have a look to startBackend:

private void startBackend(Handler<AsyncResult<SQLConnection>> next, Future<Void> fut) {
    jdbc.getConnection(ar -> {
      if (ar.failed()) {
        fut.fail(ar.cause());
      } else {
        next.handle(Future.succeededFuture(ar.result()));
      }
    });
  }

This method retrieves a SQLConnection, check whether this operation succeeded. If so, it calls the next step. In case of failure, it reports it.

The other methods follow the same pattern: 1) check if the last operation has succeeded, 2) do the task, 3) call the next step.

A bit of SQL…

Our client is ready, let’s now write some SQL statements. Let’s start by the createSomeData method that is part of the startup sequence:

private void createSomeData(AsyncResult<SQLConnection>result,
    Handler<AsyncResult<Void>> next, Future<Void> fut) {
    if (result.failed()) {
      fut.fail(result.cause());
    } else {
      SQLConnection connection = result.result();
      connection.execute(
          "CREATE TABLE IF NOT EXISTS Whisky (id INTEGER IDENTITY, name varchar(100), " +
          "origin varchar(100))",
          ar -> {
            if (ar.failed()) {
              fut.fail(ar.cause());
              return;
            }
            connection.query("SELECT * FROM Whisky", select -> {
              if (select.failed()) {
                fut.fail(ar.cause());
                return;
              }
              if (select.result().getNumRows() == 0) {
                insert(
                    new Whisky("Bowmore 15 Years Laimrig", "Scotland, Islay"),
                    connection,
                    (v) -> insert(new Whisky("Talisker 57° North", "Scotland, Island"),
                        connection,
                        (r) -> next.handle(Future.<Void>succeededFuture())));
              } else {
                next.handle(Future.<Void>succeededFuture());
              }
            });
          });
    }
  }
This method checks that the `SQLConnection` is available and then start executing some SQL statements. First, it creates the tables if there are not there yet. As you can see, the method called is structured as follows:
connection.execute(
    SQL statement,
    handler called when the statement has been executed
)

The handler receives an AsyncResult, i.e. a notification of the completion without an actual result.

In the code of this handler, we check whether or not the statement has been executed correctly, and if so we check to see if the table already contains some data, if not, it inserts data using the insert method:

private void insert(Whisky whisky, SQLConnection connection, Handler<AsyncResult<Whisky>> next) {
  String sql = "INSERT INTO Whisky (name, origin) VALUES ?, ?";
  connection.updateWithParams(sql,
      new JsonArray().add(whisky.getName()).add(whisky.getOrigin()),
      (ar) -> {
        if (ar.failed()) {
          next.handle(Future.failedFuture(ar.cause()));
          return;
        }
        UpdateResultresult = ar.result();
        // Build a new whisky instance with the generated id.
        Whisky w = new Whisky(result.getKeys().getInteger(0), whisky.getName(), whisky.getOrigin());
        next.handle(Future.succeededFuture(w));
      });
}

This method uses the updateWithParams method with an INSERT statement, and pass values. This approach avoids SQL injection. Once the the statement has been executed, we creates a new Whisky object with the created (auto-generated) id.

Some REST with a pinch of SQL

The method described above is part of our start sequence. But what about the method invoked by our REST API. Let’s have a look to the getAll method. This method is called by the web frontend to retrieve all stored products:

private void getAll(RoutingContext routingContext) {
    jdbc.getConnection(ar -> {
      SQLConnection connection = ar.result();
      connection.query("SELECT * FROM Whisky", result -> {
        List<Whisky> whiskies = result.result().getRows().stream().map(Whisky::new).collect(Collectors.toList());
        routingContext.response()
            .putHeader("content-type", "application/json; charset=utf-8")
            .end(Json.encodePrettily(whiskies));
      });
    });
  }

This method gets a SQLConnection, and then issue a query. Once the result has been retrieved it writes the HTTP response as before. The getOne, deleteOne, updateOne and addOne methods follow the same pattern.

Let’s have a look to the result provided to the handler passed to the query method. It gets a ResultSet, which contains the query result. Each row is a JsonObject, so if your data object has a constructor taking a JsonObject as unique argument, creating there objects is straightforward.

Test, test, and test again

We need to slightly update our tests to configure the JDBCClient. In the MyFirstVertilceTest class, change the DeploymentOption object created in the setUp method to be:

DeploymentOptions options = new DeploymentOptions()
        .setConfig(new JsonObject()
            .put("http.port", port)
            .put("url", "jdbc:hsqldb:mem:test?shutdown=true")
            .put("driver_class", "org.hsqldb.jdbcDriver")
        );

In addition to the http.port, we also put the JDBC url and the class of the JDBC driver. We use an in-memory database for tests.

The same modification needs to be done in the src/test/resources/my-it-config.json file:

{
  "http.port": ${http.port},
  "url": "jdbc:hsqldb:mem:it-test?shutdown=true",
  "driver_class": "org.hsqldb.jdbcDriver"
}

The src/main/conf/my-application-conf.json file also needs to be updated, not for the tests, but to run the application:

{
  "http.port" : 8082,
  "url": "jdbc:hsqldb:file:db/whiskies",
  "driver_class": "org.hsqldb.jdbcDriver"}

The JDBC url is a bit different in this last file, as we store the database on the file system.

Show time!

Let’s now build our application:

mvn clean package

As we didn’t change the API (neither the public java one nor the REST), test should run smoothly.

Then launch the application with:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar -conf src/main/conf/my-application-conf.json

Open your browser to http://localhost:8082/assets/index.html, and you should see the application using the database. This time the products are stored in a database persisted on the file system. So, if we stop and restart the application, the data is restored.

Conclusion

In this post, we saw how you can use JDBC database with vert.x, and thus without too much burden. You may have been surprised by the asynchronous development model, but once you start using it, it’s hard to come back.

Next time, let’s see how the same application can use mongoDB instead of HSQL.

Stay tuned, and happy coding !


Vert.x ES6 back to the future

$
0
0

On October 21th, 2015 we all rejoiced with the return from the past of Marty McFly with his flying car and so on, however in the Vert.x world we were quite sad that the JavaScript support we have was still using a technology released in December 2009. The support for ES5 is not something that we Vert.x team controls but something that is inherited from running on top of Nashorn.

With all these nostalgic thoughts on my mind I’ve decided to bring us back to the future and by future I mean, lets start using a modern JavaScript, or more correctly, lets start using ECMAScript 6.

It turned out to be quite simple to achieve this so I’ll pick the hello world example and write it in ES6 just to show how you can port your code to ES6 and still use the current Vert.x APIs. Note that Vert.x internals still are ES5 and have not been touched or modified to support any of ES6 features.

main

Traditionally your main.js file would reside in the root of your module (this is where NPM will look for it by default); however as we are going to transpile to ES5 you’ll want to put your index file in /src/main.js.

However, because we are transpiling to ES5, your package.json‘s main block should point to the transpiled index.js file in the /lib directory.

{
  "name": "vertx-es6",
  "version": "0.0.1",
  "private": true,

  "main": "lib/main.js",

  "scripts": {
    "build": "rm -Rf lib && ./node_modules/.bin/babel --out-dir lib src",
    "start": "./node_modules/.bin/vertx run lib/main.js"},

  "dependencies": {
    "vertx3-full": "3.1.0",
    "babel-cli": "6.2.0",
    "babel-preset-es2015": "6.1.18"}
}

As you can see, the main idea is to invoke the transpiler (Babel) when we are building our project, and run it using the generated files. This is slightly equivalent to a compilation process you would have using compiled language.

.npmignore

If you’re planning to deploy your package to npm either local or private you should be aware that npm will exclude anything listed on your .gitignore since we should ignore the generated code from git it need to inform npm to ignore that rule and keep the lib directory. The .gitignore should be something like:

/lib
/node_modules

And the .npmignore:

/.gitignore

Hello fat arrows and let keywords

So all the heavy work has been done, in order to create our hello world we just need to code some ES6 in our src/main.js file:

var Router = require("vertx-web-js/router");
var server = vertx.createHttpServer();

var router = Router.router(vertx);

router.get("/").handler((ctx) => {

    let response = ctx.response();
    response.putHeader("content-type", "text/plain");

    response.end("Hello ES6 World!");
});

server.requestHandler(router.accept).listen(8080);

As you can see we’re using fat arrows instead of writing a function closure and scoped variables using let keyword. If you now compile your project:

npm run build

And then start it:

npm start

You have your first back to the future ES6 verticle!

Combine vert.x and mongo to build a giant

$
0
0

This blog post is part of the introduction to vert.x series. Last time, we have seen how we can use the vertx-jdbc-client to connect to a database using a JDBC driver. In this post, we are going to replace this JDBC client by the vertx-mongo-client, and thus connect to a Mongo database.

You don’t understand the title, check the mongoDB website.

But before going further, let’s recap.

Previously in ‘introduction to vert.x’

  1. The first post has described how to build a vert.x application with Maven and execute unit tests.
  2. The second post has described how this application can become configurable.
  3. The third post has introduced vertx-web, and a small collection management application has been developed. This application offers a REST API used by a HTML/JavaScript frontend.
  4. The fourth post has presented how you can run integration tests to ensure the behavior of your application.
  5. The last post has presented how you can interact with a JDBC database using the vertx-jdbc-client.

This post shows another client that lets you use MongoDB in a vert.x application. This client provides an vert.x API to access asynchronously to the Mongo database. We won’t compare whether or not JDBC is superior to Mongo, they have both pros and cons, and you should use the one that meet your requirements. Vert.x lets you choose, that’s the point.

The vertx-mongo-client documentation is available here.

The code developed in this blog post is available in the branch post-6. Our starting point is the code from the post-5 branch.

Asynchronous data access

One of the vert.x characteristics is being asynchronous. With an asynchronous API, you don’t wait for a result, but you are notified when this result is ready. Thanks to vert.x, this notification happens in the same thread (understand event loop) as the initial request:

Asynchronous data access

Your code (on the left) is going to invoke the mongo client and pass a callback that will be invoked when the result is available. The invocation to the mongo client is non blocking and returns immediately. The client is dealing with the mongo database and when the result has been computed / retrieved, it invokes the callback in the same event loop as the request.

This model is particularly powerful as it avoids the synchronization pitfalls. Indeed, your code is only called by a single thread, no need to synchronize anything.

As with every Maven project….

… we need to update the pom.xml file first.

In the pom.xml file, replace the vertx-jdbc-client by the vertx-mongo-client:

<dependency><groupId>io.vertxgroupId><artifactId>vertx-mongo-clientartifactId><version>3.1.0version>dependency>

Unlike JDBC where we were instantiating a database on the fly, here we need to explicitly starts a MongoDB server. In order to launch a Mongo server in our test, we are going to add another dependency:

<dependency><groupId>de.flapdoodle.embedgroupId><artifactId>de.flapdoodle.embed.mongoartifactId><version>1.50.0version><scope>testscope>dependency>

This dependency will be used in our unit tests, as it lets us start a mongo server programmatically. For our integration tests, we are going to use a Maven plugin starting and stopping the mongo server before and after our integration tests. Add this plugin to the section of your pom.xml file.

<plugin><groupId>com.github.joelittlejohn.embedmongogroupId><artifactId>embedmongo-maven-pluginartifactId><version>0.2.0version><executions><execution><id>startid><goals><goal>startgoal>goals><configuration><port>37017port>configuration>execution><execution><id>stopid><goals><goal>stopgoal>goals>execution>executions>plugin>

Notice the port we use here (37017), we will use this port later.

Enough XML for today

Now that we have updated our pom.xml file, it’s time to change our verticle. The first thing to do is to replace the jdbc client by the mongo client:

mongo = MongoClient.createShared(vertx, config());

This client is configured with the configuration given to the verticle (more on this below).

Once done, we need to change how we start the application. With the mongo client, no need to acquire a connection, it handles this internally. So our startup sequence is a bit more simple:

createSomeData(
        (nothing) -> startWebApp(
            (http) -> completeStartup(http, fut)
        ), fut);

As in the previous post, we need to insert some predefined data if the database is empty:

privatevoidcreateSomeData(Handler> next, Future fut){
    Whisky bowmore = new Whisky("Bowmore 15 Years Laimrig", "Scotland, Islay");
    Whisky talisker = new Whisky("Talisker 57° North", "Scotland, Island");
    System.out.println(bowmore.toJson());
    // Do we have data in the collection ?
    mongo.count(COLLECTION, new JsonObject(), count -> {
      if (count.succeeded()) {
        if (count.result() == 0) {
          // no whiskies, insert data
          mongo.insert(COLLECTION, bowmore.toJson(), ar -> {
            if (ar.failed()) {
              fut.fail(ar.cause());
            } else {
              mongo.insert(COLLECTION, talisker.toJson(), ar2 -> {
                if (ar2.failed()) {
                  fut.failed();
                } else {
                  next.handle(Future.succeededFuture());
                }
              });
            }
          });
        } else {
          next.handle(Future.succeededFuture());
        }
      } else {
        // report the error
        fut.fail(count.cause());
      }
    });
}

To detect whether or not the database already contains some data, we retrieve the number of documents from the whiskies collection. This is done with : mongo.count(COLLECTION, new JsonObject(), count -> {}). The second parameter is the query. In our case, we want to count all documents. This is done using new JsonObject() that would create a query accepting all documents from the collection (it’s equivalent to a SELECT * FROM ...).

Also notice the insert calls. Documents are passed as JSON object, so to insert an object, just serialize it to JSON and use mongo.insert(COLLECTION, json, completion handler).

Mongo-ize the REST handlers

Now that the application boot sequence has been migrated to mongo, it’s time to update the code handling the REST requests.

Let’s start by the getAll method that returns all stored products. To implement this, we use the find method. As we saw for the count method, we pass an empty json object to describe a query accepting all documents:

privatevoidgetAll(RoutingContext routingContext){
    mongo.find(COLLECTION, new JsonObject(), results -> {
      List objects = results.result();
      List whiskies = objects.stream().map(Whisky::new).collect(Collectors.toList());
      routingContext.response()
          .putHeader("content-type", "application/json; charset=utf-8")
          .end(Json.encodePrettily(whiskies));
    });
}

The query results are passed as a list of JSON objects. From this list we can create our product instances, and fill the HTTP response with this set.

To delete a specific document we need to select the document using its id:

privatevoiddeleteOne(RoutingContext routingContext){
    String id = routingContext.request().getParam("id");
    if (id == null) {
      routingContext.response().setStatusCode(400).end();
    } else {
      mongo.removeOne(COLLECTION, new JsonObject().put("_id", id),
          ar -> routingContext.response().setStatusCode(204).end());
    }
}

The new JsonObject().put("_id", id) describes a query selecting a single document (selected by its unique id, so it’s the equivalent to SELECT * WHERE id=...). Notice the _id which is a mongo trick to select a document by id.

Updating a document is a less trivial:

privatevoidupdateOne(RoutingContext routingContext){
    final String id = routingContext.request().getParam("id");
    JsonObject json = routingContext.getBodyAsJson();
    if (id == null || json == null) {
      routingContext.response().setStatusCode(400).end();
    } else {
      mongo.update(COLLECTION,
          new JsonObject().put("_id", id), // Select a unique document// The update syntax: {$set, the json object containing the fields to update}new JsonObject()
              .put("$set", json),
          v -> {
            if (v.failed()) {
              routingContext.response().setStatusCode(404).end();
            } else {
              routingContext.response()
                  .putHeader("content-type", "application/json; charset=utf-8")
                  .end(Json.encodePrettily(
                  new Whisky(id, json.getString("name"),
                    json.getString("origin"))));
            }
          });
    }
}

As we can see, the update method takes two JSON objects as parameter:

  1. The first one denotes the query (here we select a single document using its id).
  2. The second object expresses the change to apply to the selected document. It uses a mongo syntax. In our case, we update the document using the $set operator.

Replace document
In this code we update the document and replace only a set of fields. You can also replace the whole document using mongo.replace(...).

I definitely recommend to have a look to the MongoDB documentation, especially:

Time for configuration

Well, the code is migrated, but we still need to update the configuration. With JDBC we passed the JDBC url and the driver class in the configuration. With mongo, we need to configure the connection_string - the mongo:// url on which the application is connected, and db_name - a name for the data source.

Let’s start by the unit test. Edit the MyFirstVerticleTest file and add the following code:

privatestatic MongodProcess MONGO;
    privatestaticint MONGO_PORT = 12345;
    @BeforeClasspublicstaticvoidinitialize()throws IOException {
      MongodStarter starter = MongodStarter.getDefaultInstance();
      IMongodConfig mongodConfig = new MongodConfigBuilder()
          .version(Version.Main.PRODUCTION)
          .net(new Net(MONGO_PORT, Network.localhostIsIPv6()))
          .build();
      MongodExecutable mongodExecutable =
            starter.prepare(mongodConfig);
     MONGO = mongodExecutable.start();
    }

    @AfterClasspublicstaticvoidshutdown(){  MONGO.stop(); }

Before our tests, we start (programmatically) a mongo database on the port 12345. When all our tests have been executed, we shutdown the database.

So now that the mongo server is managed, we need to to give the right configuration to our verticle. Update the DeploymentOption instance with:

DeploymentOptions options = new DeploymentOptions()
        .setConfig(new JsonObject()
            .put("http.port", port)
            .put("db_name", "whiskies-test")
            .put("connection_string",
                "mongodb://localhost:" + MONGO_PORT)
    );

That’s all for the unit tests.

For the integration-test, we are using an externalized json file. Edit the src/test/resources/my-it-config.json with the following content:

{
      "http.port": ${http.port},
      "db_name": "whiskies-it",
      "connection_string": "mongodb://localhost:37017"
    }

Notice the port we are using for the mongo server. This port was configured in the pom.xml file.

Last but not least, we still have a configuration file to edit: the configuration you use to launch the application in production:

{
      "http.port": 8082,
      "db_name": "whiskies",
      "connection_string": "mongodb://localhost:27017"}

Here you would need to edit the localhost:27017 with the right url for your mongo server.

Some changes in the integration tests
Because mongo document id are String and not integer, we have to slightly change document selection in the integration test.

Time for a run

It’s time to package and run the application and check that everything works as expected. Let’s package the application using:

mvn clean verify

And then to launch it, start your mongo server and launch:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar \
  -conf src/main/conf/my-application-conf.json

If you are, like me, using docker / docker-machine for almost everything, edit the configuration file to refer to the right host (localhost for docker, the docker-machine ip if you use docker-machine) and then launch:

docker run -d -p 27017:27017 mongo
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar \
  -conf src/main/conf/my-application-conf.json
# or
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar \
  -conf src/main/conf/my-application-conf-docker-machine.json

The application live and running

That’s all folks !

We are reaching the end of this post. We saw how you can use the vert-mongo-client to access asynchronously data stored inside a mongo database as well as inserting/updating this data. Now you have the choice between JDBC or Mongo. In addition, vert.x provides a client for Redis.

Next time, we will see how the verticle class can be split in two verticles in order to better organize your code. The interaction between the two verticles will uses services.

Stay tuned & Happy coding !

Vert.x 3.2.0 is released !

$
0
0

We are pleased to announce the release of Vert.x 3.2.0!

Some of the highlights of this release include:

The release also contains many bug fixes and a ton of improvements. Full release notes can be found here:

https://github.com/vert-x3/wiki/wiki/3.2.0---Release-Notes

Breaking changes are here:

https://github.com/vert-x3/wiki/wiki/3.2.0-Breaking-changes

The event bus client using the SockJS bridge are available from NPM, Bower and as a WebJar:

Dockers images are also available on the Docker Hub The vert.x distribution is also available from SDKMan.

Many thanks to all the committers and community whose contributions made this possible.

Next stop is Vert.x 3.3.0 which we hope to have out in March 2016.

The artifacts have been deployed to Maven Central and you can get the distribution on Bintray.

Automatic redeployment in Eclipse IDE

$
0
0

Vert.x 3.1 has (re-) introduced the redeploy feature. This blog post explains how to use this feature in the Eclipse IDE. However, you can easily adapt the content to your IDE.

How does redeploy work

How is implemented the redeploy is not as you may expect. First, the redeploy does not rely on a build tool, but is integrated in vert.x. However you can plug your build tools with the redeploy feature. This feature is offered by the io.vertx.core.Launcher class. The redeployment process is actually very simple:

  1. the application is launched in redeploy mode.
  2. it listens for file changes
  3. when a matching file is changed, it stops the application
  4. it executes the on-redeploy actions if any
  5. it restarts the application
  6. back to (2)

Initially the application is launched in redeploy mode. The application is actually launched in background, in a separated process. Vert.x listens for file changes. You give it a set of (Ant-style) patterns and every time a matching file changes, Vert.x stops the whole application and restarts it. Optionally you can configure a on-redeploy action to plug in your build tools.

To integrate this process in Eclipse (or in your IDE), you just need to configure the set of listened files, and let the Launcher class starts and stops your application.

Redeploy in Eclipse

The following screencast explains how you configure a vert.x application to be run in Eclipse and how to configure the redeploy:

To summarize the last configuration:

  • it’s a Java application configuration
  • it’s uses io.vertx.core.Launcher as main class
  • In the Program arguments (Arguments tab), write: run --redeploy="src/**/*.java" --launcher-class=org.acme.vertx.Main

Redeploy with your own Main class

Let’s now imagine that you have your own Main class, starting your application. For instance, it can be something like:

package org.acme.vertx;

import io.vertx.core.Vertx;

publicclassMain{

    publicstaticvoidmain(String[] args){
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(MyMainVerticle.class.getName());
    }

}

The redeploy feature from vert.x lets you use your own Main class:

  1. Create another Run configuration
  2. Set the Main-Class to io.vertx.core.Launcher (yes, the one from vert.x not yours)
  3. In the application parameter add: run --redeploy="src/**/*.java" --launcher-class=org.acme.vertx.Main

With this configuration, the application is launched in background using your own Main class, and will restart the application every time you change your source code (you can even change the source code of your Main class).

ECMAScript 6/7 on the JVM with TypeScript and Vert.x

$
0
0

Following the latest releases of Vert.x 3.2 and vertx-lang-typescript 1.1.0 I figured it would be a good idea to give you a couple of examples how teaming Vert.x and TypeScript helps you use ECMAScript 6 and 7 features on the JVM today.

The vertx-lang-typescript library adds TypeScript support to Vert.x 3. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. It supports the ECMAScript 6 (ECMAScript 2015, ES6) standard and also a few parts of ECMAScript 7 (ES7) already.

The library automatically compiles Vert.x verticles written in TypeScript to JavaScript and executes them on the JVM. vertx-lang-typescript also provides type definitions for the Vert.x JavaScript API. Use them in your favourite TypeScript editor/IDE to get auto-completion, API documentation and meaningful error messages. See the following screencast:

ECMAScript 6/7 and Vert.x

Below you find an example verticle written in TypeScript. Well, I left all the TypeScript-specific parts out. In fact the verticle is valid ECMAScript 6 (except for the last snippet [9] which is ECMAScript 7).

First, follow the vertx-lang-typescript README to install the library and to enable TypeScript in Vert.x. Then extract the type definitions (vertx-lang-typescript-1.1.0-typings.zip) into a new directory. Create a new file named es7verticle.ts in this directory and copy the code below into it. Finally, open your command prompt and execute

vertx run es7verticle.ts

This will run a small HTTP server that listens to requests on port 8080. If you open your browser and go to http://localhost:8080 you will see the following:

So far so good. Now let’s have a look at the code. I numbered the individual ECMAScript features used. Here’s a complete list:

  1. Use an arrow function to create a request handler (ES6)
  2. Block-scoped variables do not pollute your global namespace (ES6)
  3. Specify a default value for a function parameter (ES6)
  4. Use rest parameters to collect multiple parameters in an array (ES6)
  5. Spread the contents of an array to function parameters (ES6)
  6. Iterate over array contents using the for…of loop (ES6)
  7. template strings enable string interpolation and multi-line strings (ES6)
  8. Use classes and inheritance (ES6)
  9. Use the new exponentiation operator as a shortcut for Math.pow() (ES7)

Conclusion

The example demonstrates very well how you can use ECMAScript 6 (and parts of 7) on the JVM today. In fact, there are a lot more cool ES6 features not included in the example such as constants (const), the property shorthand or method properties.

TypeScript is so much more than just ES6. It actually has a very good static type system that allows you to make compile-time type checks. This is makes it much easier to write large Vert.x applications with many verticles. Personally I really like the support that I get from my IDE when programming TypeScript. Since vertx-lang-typescript comes with type definitions for the Vert.x JavaScript API I get auto-completion and access to the documentation right in the editor. I mostly use Sublime by the way, but I have tested it successfully with Visual Studio Code, Eclipse and Atom.

Unfortunately, the only ES7 feature that you can use at the moment with vertx-lang-typescript is the exponentiation operator. TypeScript 1.7 also supports decorators but this feature is disabled at the moment in vertx-lang-typescript because it is experimental and subject to change. I’ll keep you up to date when new features are introduced.

Alternatives

We’ve recently published a post on how to use ECMAScript 6 with Vert.x here on this blog. We used Babel, a compiler that translates ES6 to ES5.

Although this approach works well it is a bit harder to set up and use than the one presented here. First, you need to wrap your Vert.x application in a NPM package. Second, in order to run your application, you need to execute two commands. You have to compile it with npm run build and then then call npm start. With vertx-lang-typescript you only need one command. vertx-lang-typescript also allows you to embed the TypeScript verticle in a larger Vert.x application and also mix multiple languages in one project. This is not possible if you wrap everything in a NPM package.

Finally, the approach based on Babel only supports ECMAScript 6 (2015), although more features from ES7 will surely be introduced in Babel in the future. TypeScript on the other hand gives you much more features such as static typing that you will certainly find useful for any larger project.

Viewing all 158 articles
Browse latest View live