Skip to content

Commit 5e23897

Browse files
committed
server/module: vertx support #3778
- documentation - bug fixing and API improvements
1 parent 3164993 commit 5e23897

File tree

48 files changed

+1272
-383
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1272
-383
lines changed

docs/asciidoc/index.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ Latest Release: https://github.com/jooby-project/jooby/releases/tag/v{joobyVersi
6262
6363
Looking for a previous version?
6464
65-
* Access to link:v3[3.x] documentation. See link:/migration/4.x[migrating from 3.x to 4.x]
66-
* Access to link:v2[2.x] documentation. See link:/migration/3.x[migrating from 2.x to 3.x]
65+
* Access to link:v3[3.x] documentation. link:/migration/4.x[Migrating from 3.x to 4.x]
66+
* Access to link:v2[2.x] documentation. link:/migration/3.x[Migrating from 2.x to 3.x]
6767
* Access to link:v1[1.x] documentation.
6868
====
6969

@@ -76,7 +76,7 @@ Looking for a previous version?
7676
* link:modules/openapi[OpenAPI 3] support
7777
* <<execution-model, Event Loop and blocking execution modes>>
7878
* <<responses, Reactive responses>> (Completable Futures, RxJava, Reactor, SmallRye types and Kotlin Coroutines)
79-
* <<server, Multi-server>> including https://www.eclipse.org/jetty[Jetty], https://netty.io[Netty] and http://undertow.io[Undertow]
79+
* <<server, Multi-server>> including https://www.eclipse.org/jetty[Jetty], https://netty.io[Netty], https://vertx.io[Vertx] and http://undertow.io[Undertow]
8080
* Make the jump to full-stack framework with the extension/plugin mechanism and a variety of link:modules[]
8181

8282
=== Script API

docs/asciidoc/modules/modules.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Available modules are listed next.
2626
* link:/modules/jdbi[Jdbi]: Jdbi module.
2727
* link:/modules/kafka[Kafka]: Kafka module.
2828
* link:/modules/redis[Redis]: Redis module.
29+
* link:/modules/vertx-mysql-client[Vertx mySQL client]: Vertx reactive mySQL client module.
30+
* link:/modules/vertx-pg-client[Vertx Postgres client]: Vertx reactive Postgres client module.
2931

3032
=== Validation
3133
* link:/modules/avaje-validator[Avaje Validator]: Avaje Validator module.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
== Sql Client
2+
3+
A https://github.com/eclipse-vertx/vertx-sql-client[reactive SQL Client]. Supported databases:
4+
5+
- MySQL
6+
7+
These modules require a Vertx instance available in the service registry.
8+
9+
include::vertx-sql-client.template[artifactId="jooby-vertx-mysql-client" sqlClient="MySQL" moduleName="VertxMySQLModule" builderName="MySQLBuilder"]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
== Sql Client
2+
3+
A https://github.com/eclipse-vertx/vertx-sql-client[reactive SQL Client]. Supported databases:
4+
5+
- PostgreSQL
6+
7+
These modules require a Vertx instance available in the service registry.
8+
9+
include::vertx-sql-client.template[artifactId="jooby-vertx-pg-client" sqlClient="Postgres" moduleName="VertxPgModule" builderName="PgBuilder"]

docs/asciidoc/modules/vertx-sql-client.adoc

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,65 +7,6 @@ A https://github.com/eclipse-vertx/vertx-sql-client[reactive SQL Client]. Suppor
77
88
These modules require a Vertx instance available in the service registry.
99

10-
=== MySQL client
11-
12-
1) Add the dependency:
13-
14-
[dependency, artifactId="jooby-vertx-mysql-client"]
15-
.
16-
17-
2) Install
18-
19-
.Java
20-
[source, java, role="primary"]
21-
----
22-
import io.jooby.vertx.VertxModule;
23-
import io.jooby.vertx.VertxMySQLModule;
24-
import static io.jooby.vertx.VertxHandler.vertx;
25-
26-
{
27-
install(new VertxModule()); <1>
28-
29-
use(vertx()); <2>
30-
31-
get("/{id}", ctx -> {
32-
var db = require(SqlClient.class); <3>
33-
return db.preparedQuery("SELECT id, randomnumber from WORLD where id=$1") <4>
34-
.execute(Tuple.of(ctx.path("id").longValue()))
35-
.map(result -> {
36-
var row = result.iterator().next();
37-
return new World(row.getInteger(0), row.getInteger(1));
38-
});
39-
});
40-
}
41-
----
42-
43-
.Kotlin
44-
[source, kt, role="secondary"]
45-
----
46-
import io.jooby.vertx.VertxModule
47-
import io.jooby.vertx.VertxMySQLModule
48-
import static io.jooby.vertx.VertxHandler.vertx
49-
50-
{
51-
install(VertxModule()) <1>
52-
53-
use(vertx()) <2>
54-
55-
get("/{id}") {
56-
val db = require(SqlClient::class) <3>
57-
db.preparedQuery("SELECT id, randomnumber from WORLD where id=$1") <4>
58-
.execute(Tuple.of(ctx.path("id").longValue()))
59-
.map({ result ->
60-
val row = result.iterator().next()
61-
World(row.getInteger(0), row.getInteger(1))
62-
})
63-
}
64-
}
65-
----
66-
67-
<1> Install Vertx
68-
<2> Install vertx handler. Render future, promise and buffer.
69-
<3> Get SQL client instance
70-
<4> Run a database query
10+
include::vertx-sql-client.template[artifactId="jooby-vertx-mysql-client" sqlClient="mysql" moduleName="VertxMySQLModule" builderName="MySQLBuilder" port=3306]
7111

12+
include::vertx-sql-client.template[artifactId="jooby-vertx-pg-client" sqlClient="postgresql" moduleName="VertxPgModule" builderName="PgBuilder" port=5432]

docs/asciidoc/modules/vertx.adoc

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
https://vertx.io/[Vertx] Reactive applications on the JVM.
44

5+
This module export the following services:
6+
7+
- io.vertx.core.Vertx
8+
- io.vertx.core.eventbus.EventBus
9+
- io.vertx.core.file.FileSystem
10+
511
=== Usage
612

713
1) Add the dependency:
@@ -120,4 +126,132 @@ import io.jooby.vertx.VertxModule;
120126
}
121127
----
122128

123-
include::vertx-sql-client.adoc[]
129+
include::modules/vertx-sql-client.adoc[]
130+
131+
== Vertx Server (Advanced)
132+
133+
The javadoc:vertx.VertxServer[] allow you to share the Vertx acceptor and event loop groups within
134+
the javadoc:netty.NettyServer[], so both vertx and netty web server implementation share the same
135+
resources. See https://vertx.io/docs/guides/advanced-vertx-guide/#integrating-netty[for more information].
136+
137+
The vertx server must be manually provided at boot time (there is no service loader support for it):
138+
139+
.Java
140+
[source, java, role="primary"]
141+
----
142+
import io.jooby.vertx.VertxServer;
143+
144+
{
145+
get("/vertx", ctx -> {
146+
return "Running from vertx event loop";
147+
});
148+
}
149+
150+
public static void main(String[] args) {
151+
runApp(args, new VertxServer(), EVENT_LOOP, App::new);
152+
}
153+
----
154+
155+
.Kotlin
156+
[source, kt, role="secondary"]
157+
----
158+
import io.jooby.vertx.VertxServer
159+
160+
import io.jooby.vertx.VertxServer;
161+
162+
{
163+
get("/vertx") {
164+
"Running from vertx event loop"
165+
}
166+
}
167+
168+
un main(args: Array<String>) {
169+
runApp(args, VertxServer(), EVENT_LOOP, ::App)
170+
}
171+
----
172+
173+
If you run multiple applications, they all share a single Vertx instance.
174+
175+
[IMPORTANT]
176+
====
177+
*VertxModule must NOT be installed while running on VertxServer*
178+
====
179+
180+
One of the main benefits of running on the VertxServer is to share/reuse the event loop threads.
181+
You can run non-blocking code on the Vertx event loop thread without context switch. A good example
182+
of this is to run within
183+
184+
=== Sql Connection
185+
186+
These modules exist as part of the performance tests required by https://www.techempower.com/benchmarks[Techempower].
187+
188+
You are free to use them, but keep in mind they are for very specific kind of application.
189+
190+
include::vertx-sql-connection.template[artifactId="jooby-vertx-mysql-client" sqlClient="MySQL" moduleName="VertxMySQLConnectionModule"]
191+
192+
include::vertx-sql-connection.template[artifactId="jooby-vertx-pg-client" sqlClient="Postgres" moduleName="VertxPgConnectionModule"]
193+
194+
195+
==== How it works?
196+
197+
There is an internal Verticle (one per IO threads) with a dedicated https://vertx.io/docs/apidocs/io/vertx/sqlclient/SqlConnection.html[SqlConnection]. This connection is only
198+
accessible from a Vertx thread any attempt to access to the connection from a non Vertx thread
199+
will result in exception.
200+
201+
Same applies for the https://vertx.io/docs/apidocs/io/vertx/sqlclient/PreparedStatement.html[PreparedStatement] / https://vertx.io/docs/apidocs/io/vertx/sqlclient/PreparedQuery.html[PreparedQuery] instances.
202+
203+
.PreparedStatement example:
204+
[source,java]
205+
----
206+
import io.jooby.Reified;
207+
208+
String SELECT_WORLD = "SELECT id, randomnumber from WORLD where id=$1";
209+
210+
Reified<PreparedQuery<RowSet<Row>>> PreparedQueryType =
211+
getParameterized(PreparedQuery.class, getParameterized(RowSet.class, Row.class));
212+
213+
{
214+
install(new VertxPgConnectionModule()
215+
.preparedStatement(Map.of("selectWorld", List.of(SELECT_WORLD))) <1>
216+
);
217+
218+
use(vertx()); <2>
219+
220+
var selectWorldQuery = ctx.require(PreparedQueryType, "selectWorld"); <3>
221+
get("/world/{id}", ctx -> {
222+
return selectWorldQuery.execute(Tuple.of(ctx.path("id").longValue()))
223+
.map(
224+
result -> {
225+
var row = result.iterator().next();
226+
return new World(row.getInteger(0), row.getInteger(1));
227+
});
228+
});
229+
}
230+
231+
public static void main(String[] args) {
232+
runApp(args, new VertxServer(), EVENT_LOOP, App::new);
233+
}
234+
----
235+
236+
<1> Created a prepared statement. This is done when Verticle is deployed
237+
<2> Add Vertx handler, so it can render Future and Promise.
238+
<3> Get a reference to the prepared statement
239+
240+
The line:
241+
242+
var selectWorldQuery = ctx.require(PreparedQueryType, "selectWorld");
243+
244+
Allow you to get a reference/proxy to the prepared statement/query. The proxy will thrown an exception
245+
if you try to use from a non Vertx thread. The prepared statement is compiled when the Verticle
246+
is deployed (at application startup time).
247+
248+
If you work with any of the dependency injection supported framework, you can inject the prepared
249+
statement like:
250+
251+
[source,java]
252+
----
253+
@Inject
254+
public WorldRepository(@Named("selectWorld") PreparedQuery<RowSet<Row>> selectWorld) {
255+
this.selectWorld = selectWorld;
256+
}
257+
----

docs/asciidoc/servers.adoc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ There are three server implementations:
44

55
- javadoc:jetty.JettyServer[artifact=jooby-jetty]
66
- javadoc:netty.NettyServer[artifact=jooby-netty]
7+
- javadoc:vertx.VertxServer[artifact=jooby-vertx]
78
- javadoc:undertow.UndertowServer[artifact=jooby-undertow]
89
910
Servers are automatically registered based on their presence on the project classpath.
@@ -23,6 +24,14 @@ To use Undertow, add the dependency:
2324
[dependency, artifactId="jooby-undertow"]
2425
.
2526

27+
To use Vertx, add the dependency:
28+
29+
[dependency, artifactId="jooby-vertx"]
30+
31+
.
32+
33+
The javadoc:vertx.VertxServer[] setup is fully described link:/modules/vertx#vertx-server-advanced[here].
34+
2635
[IMPORTANT]
2736
====
2837
Only one server dependency must be available on classpath.
@@ -62,7 +71,7 @@ first setup wins.
6271

6372
=== Manual setup
6473

65-
Servers are automatically loaded using `ServiceLoader` API. If you need to add it manually:
74+
Servers are automatically loaded using `ServiceLoader` API:
6675

6776
.Server
6877
[source,java,role="primary"]
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
=== {{sqlClient}}
2+
3+
1) Add the dependency:
4+
5+
[dependency, artifactId="{{artifactId}}"]
6+
.
7+
8+
2) Define connection string or key/value pairs details:
9+
10+
.application.conf
11+
[source, properties]
12+
----
13+
db = {{sqlClient}}//dbuser:secretpassword@localhost:{{port}}/mydb
14+
----
15+
16+
.application.conf
17+
[source, properties]
18+
----
19+
db.host = localhost
20+
db.port = {{port}}
21+
db.database = mydb
22+
db.user = dbuser
23+
db.password = secretpassword
24+
----
25+
26+
3) Install
27+
28+
.Java
29+
[source, java, role="primary"]
30+
----
31+
import io.jooby.vertx.VertxModule;
32+
import io.jooby.vertx.{{moduleName}};
33+
import static io.jooby.vertx.VertxHandler.vertx;
34+
35+
{
36+
install(new VertxModule()); <1>
37+
38+
install(new {{moduleName}}()); <2>
39+
40+
use(vertx()); <3>
41+
42+
get("/{id}", ctx -> {
43+
var db = require(SqlClient.class); <4>
44+
return db.preparedQuery("SELECT id, name from World where id=$1") <5>
45+
.execute(Tuple.of(ctx.path("id").longValue()))
46+
.map(result -> {
47+
var row = result.iterator().next();
48+
return new World(row.getInteger(0), row.getInteger(1));
49+
});
50+
});
51+
}
52+
----
53+
54+
.Kotlin
55+
[source, kt, role="secondary"]
56+
----
57+
import io.jooby.vertx.VertxModule
58+
import io.jooby.vertx.{{moduleName}}
59+
import static io.jooby.vertx.VertxHandler.vertx
60+
61+
{
62+
install(VertxModule()) <1>
63+
64+
install({{moduleName}}()); <2>
65+
66+
use(vertx()) <3>
67+
68+
get("/{id}") {
69+
val db = require(SqlClient::class) <4>
70+
db.preparedQuery("SELECT id, name from World where id=$1") <5>
71+
.execute(Tuple.of(ctx.path("id").longValue()))
72+
.map({ result ->
73+
val row = result.iterator().next()
74+
World(row.getInteger(0), row.getInteger(1))
75+
})
76+
}
77+
}
78+
----
79+
80+
<1> Install Vertx
81+
<2> Install Sql Client: {{sqlClient}
82+
<3> Install vertx handler. Render future, promise and buffer
83+
<4> Get SQL client instance
84+
<5> Run a database query
85+
86+
To use the client version of the driver:
87+
88+
.Client
89+
[source, java]
90+
----
91+
92+
{
93+
...
94+
install(new {{moduleName}}({{builderName}}::client));
95+
...
96+
}
97+
----

0 commit comments

Comments
 (0)