Eclipse Vert.x 3.5.0 released !
The Vert.x team is pleased to announce the release of Eclipse Vert.x 3.5.0.
As usual it delivers an impressive number of high quality features.
Let’s go RxJava2
First and foremost this release delivers the RxJava2 API with support of its full range of types.
In addition of Single
, Rxified APIs also expose theCompletable
and Maybe
types:
// expose Handler<AsyncResult<Void>>
Completable completable = server.rxClose();
completable.subscribe(() -> System.out.println("closed"));
// expose Handler<AsyncResult<String>> where the result can be null
Maybe<String> ipAddress = dnsClient.rxLookup("www.google.com");
ipAddress.subscribe(
value -> System.out.println("resolved to " + value),
err -> err.printStackTrace(),
() -> System.out.println("does not resolve"));
RxJava augments Vert.x streams with a toObservable()
method, likewise RxJava2 adds the toFlowable()
method:
// Flowable<Buffer> maps to a ReadStream<Buffer>
// back-pressured stream
Flowable<Buffer> flowable = asyncFile.toFlowable();
// but we still can get an Observable<Buffer>
// non back-pressured stream
Observable<Buffer> flowable = asyncFile.toObservable();
What’s so different between Flowable
and Observable
? the former handles back-pressure, i.e the subscriber can control the flow of items and the later can not!!!
You can read the documentation in the section of the docs or go straight to the examples
Kotlin coroutines
Support for Kotlin Coroutines is one of my favourite 3.5 features (by the way I’ll present a talk about Vert.x and coroutines at KotlinConf).
Coroutines allows you to reason about asynchronous flow the same way you do with traditional sequential flow with the extra bonus to use try
/catch
/finally
super combo:
val movie = ctx.pathParam("id")
val rating = Integer.parseInt(ctx.queryParam("getRating")[0])
val connection = awaitResult<SQLConnection> { client.getConnection(it) }
try {
val result = awaitResult<ResultSet> { connection.queryWithParams("SELECT TITLE FROM MOVIE WHERE ID=?", json { array(movie) }, it) }
if (result.rows.size == 1) {
awaitResult<UpdateResult> { connection.updateWithParams("INSERT INTO RATING (VALUE, MOVIE_ID) VALUES ?, ?", json { array(rating, movie) }, it) }
ctx.response().setStatusCode(200).end()
} else {
ctx.response().setStatusCode(404).end()
}
} finally {
connection.close()
}
This example is borrowed from our examples.
NOTE: I’ve used try
/finally
purposely instead of Kotlin’s use
extension method
MQTT Client
In Vert.x 3.4 we added the MQTT server, 3.5 completes the MQTT story with the MQTT client:
MqttClient mqttClient = MqttClient.create(vertx,
new MqttClientOptions()
.setPort(BROKER_PORT)
.setHost(BROKER_HOST)).connect(ar ->
if (ar.succeeded()) {
System.out.println("Connected to a server");
mqttClient.publish(
MQTT_TOPIC,
Buffer.buffer(MQTT_MESSAGE),
MqttQoS.AT_MOST_ONCE,
false,
false,
s -> mqttClient.disconnect(d -> System.out.println("Disconnected from server")));
} else {
System.out.println("Failed to connect to a server");
ar.cause().printStackTrace();
}
});
You can find MQTT client and server examples here
Web API contracts
With the new OpenAPI router factory we can focus on the API implementation and not on the validation of the input. The usage is quite simple:
OpenAPI3RouterFactory.createRouterFactoryFromFile(vertx, "petstore.yaml", ar -> {
if (ar.succeeded()) {
// Spec loaded with success
OpenAPI3RouterFactory routerFactory = ar.result();
// add your API and security handlers to the factory
// add it to a server
vertx.createHttpServer()
.requestHandler(routerFactory.getRouter()::accept)
.listen();
} else {
// Something went wrong during router factory initialization
}
});
Now as a developer you only need to care about the API and not on the validation. The OpenAPI router will ensure that a request to an API will first to the contract before your handler is invoked.
Java 9 support
Java 9 was released a few days ago and the Vert.x stack has been carefully tested on Java 9 and most of our components run on Java 9 (Groovy does not run well on Java 9, please see the support matrix)
As a bonus you can now use HTTP/2 out of the box with JDK SSL!
You can also use Vert.x jars as anonymous modules.
Event driven JSON Parsing
We provide now an event driven JSON Parser emitting parse events that is very handy when you need to handle very large JSON structures and you don’t want to buffer it which introduce extra latency and increase the memory consumption.
The parser allows you to switch between fine grained JSON parse events or full structures, for instance you can parse an array of object very efficiently:
JsonParser parser = JsonParser.newParser();
// The parser will handle JSON objects as values
parser.objectValueMode();
parser.handler(event -> {
switch (event.type()) {
case START_ARRAY:
// Start the array
break;
case END_ARRAY:
// End the array
break;
case VALUE:
// Handle each object
break;
}
});
Single SQL operations
Single SQL operations (aka one-shot) have been drastically simplified: most of the SQLOperations
operations can now be performed directly on the SQLClient
:
client.queryWithParams("SELECT AVG(VALUE) AS VALUE FROM RATING WHERE MOVIE_ID=?", new JsonArray().add(id), ar2 -> {
if (ar.succeeded()) {
int value = ar.result().get(0).getInteger("VALUE");
// Continue
}
});
Under the hood, the client takes care of the pool acquire/release interaction for you.
Native transport and domain sockets
We now support native transports on Linux (Epoll) and MacOS (KQueue), as well as UNIX domain sockets for NetServer/NetClient
(HttpServer
/HttpClient
should support UNIX domain sockets soon).
Auth handler chaining
There are times when you want to support multiple authN/authZ mechanisms in a single application.
Vert.x Web supports auth handlers chaining
Vert.x config improvements
Vert.x Config allows configuring your application by assembling config chunks from different locations such as file, http, zookeeper…
In this version, we have added the support for Consul and Vault.
With the Consul config store, you can retrieve your configuration from a Consul server - so in other words, distribute the configuration from your orchestration infrastructure.
The Vault config store lets you retrieve secrets avoiding hard coding secrets or distributing credentials using an insecure way. Vault enforces the security of your secrets and only allowed applications can retrieve them. In other words, now you can keep your secrets secret.
ACKs
I want on behalf of the team to thank all the contributors for this release including the Google Summer of Code students (Pavel Drankov, Francesco Guardiani and Yunyu Lin) that delivered an impressive work.
Finally
The release notes
Docker images are also available on the Docker Hub. The Vert.x distribution is also available from SDKMan and HomeBrew.
The event bus client using the SockJS bridge are available from NPM, Bower and as a WebJar:
- https://www.npmjs.com/package/vertx3-eventbus-client
- https://github.com/vert-x3/vertx-bus-bower
- http://www.webjars.org/
The artifacts have been deployed to Maven Central and you can get the distribution on Bintray.