33import com .fizzed .rocker .ContentType ;
44import com .fizzed .rocker .RockerOutputFactory ;
55import io .netty .util .concurrent .MultithreadEventExecutorGroup ;
6- import io .vertx .core .impl .VertxInternal ;
6+ import io .vertx .core .impl .SysProps ;
7+ import io .vertx .core .internal .VertxInternal ;
8+ import io .vertx .core .internal .logging .Logger ;
9+ import io .vertx .core .internal .logging .LoggerFactory ;
710import io .vertx .pgclient .*;
811import io .vertx .core .*;
912import io .vertx .core .buffer .Buffer ;
1316import io .vertx .core .http .HttpServerRequest ;
1417import io .vertx .core .http .HttpServerResponse ;
1518import io .vertx .core .json .JsonObject ;
16- import io .vertx .core .logging .Logger ;
17- import io .vertx .core .logging .LoggerFactory ;
1819import io .vertx .sqlclient .*;
1920import io .vertx .sqlclient .impl .SqlClientInternal ;
2021import vertx .model .*;
@@ -73,21 +74,20 @@ static int getQueries(HttpServerRequest request) {
7374 private static final String PATH_FORTUNES = "/fortunes" ;
7475 private static final String PATH_CACHING = "/cached-queries" ;
7576
76- private static final Handler <AsyncResult <Void >> NULL_HANDLER = null ;
77-
7877 private static final CharSequence RESPONSE_TYPE_PLAIN = HttpHeaders .createOptimized ("text/plain" );
7978 private static final CharSequence RESPONSE_TYPE_HTML = HttpHeaders .createOptimized ("text/html; charset=UTF-8" );
80- static final CharSequence RESPONSE_TYPE_JSON = HttpHeaders .createOptimized ("application/json" );
79+ private static final CharSequence RESPONSE_TYPE_JSON = HttpHeaders .createOptimized ("application/json" );
8180
8281 private static final String HELLO_WORLD = "Hello, world!" ;
8382 private static final Buffer HELLO_WORLD_BUFFER = Buffer .buffer (HELLO_WORLD , "UTF-8" );
8483
85- private static final CharSequence HEADER_SERVER = HttpHeaders .createOptimized ( "server" ) ;
86- private static final CharSequence HEADER_DATE = HttpHeaders .createOptimized ( "date" ) ;
87- private static final CharSequence HEADER_CONTENT_TYPE = HttpHeaders .createOptimized ( "content-type" ) ;
88- private static final CharSequence HEADER_CONTENT_LENGTH = HttpHeaders .createOptimized ( "content-length" ) ;
84+ private static final CharSequence HEADER_SERVER = HttpHeaders .SERVER ;
85+ private static final CharSequence HEADER_DATE = HttpHeaders .DATE ;
86+ private static final CharSequence HEADER_CONTENT_TYPE = HttpHeaders .CONTENT_TYPE ;
87+ private static final CharSequence HEADER_CONTENT_LENGTH = HttpHeaders .CONTENT_LENGTH ;
8988
9089 private static final CharSequence HELLO_WORLD_LENGTH = HttpHeaders .createOptimized ("" + HELLO_WORLD .length ());
90+ private static final CharSequence JSON_LENGTH = HttpHeaders .createOptimized ("" + new Message ("Hello, World!" ).toJson ().length ());
9191 private static final CharSequence SERVER = HttpHeaders .createOptimized ("vert.x" );
9292
9393 private static final String SELECT_WORLD = "SELECT id, randomnumber from WORLD where id=$1" ;
@@ -114,7 +114,8 @@ static Integer boxedRandomWorldNumber() {
114114 private HttpServer server ;
115115 private SqlClientInternal client ;
116116 private CharSequence dateString ;
117- private CharSequence [] plaintextHeaders ;
117+ private MultiMap plaintextHeaders ;
118+ private MultiMap jsonHeaders ;
118119
119120 private final RockerOutputFactory <BufferRockerOutput > factory = BufferRockerOutput .factory (ContentType .RAW );
120121
@@ -125,19 +126,43 @@ static Integer boxedRandomWorldNumber() {
125126 private PreparedQuery <RowSet <Row >>[] AGGREGATED_UPDATE_WORLD_QUERY = new PreparedQuery [500 ];
126127 private WorldCache WORLD_CACHE ;
127128
129+ private MultiMap plaintextHeaders () {
130+ return HttpHeaders
131+ .headers ()
132+ .add (HEADER_CONTENT_TYPE , RESPONSE_TYPE_PLAIN )
133+ .add (HEADER_SERVER , SERVER )
134+ .add (HEADER_DATE , dateString )
135+ .add (HEADER_CONTENT_LENGTH , HELLO_WORLD_LENGTH )
136+ .copy (false );
137+ }
138+
139+ private MultiMap jsonHeaders () {
140+ return HttpHeaders
141+ .headers ()
142+ .add (HEADER_CONTENT_TYPE , RESPONSE_TYPE_JSON )
143+ .add (HEADER_SERVER , SERVER )
144+ .add (HEADER_DATE , dateString )
145+ .add (HEADER_CONTENT_LENGTH , JSON_LENGTH )
146+ .copy (false );
147+ }
148+
128149 @ Override
129150 public void start (Promise <Void > startPromise ) throws Exception {
130151 int port = 8080 ;
131- server = vertx .createHttpServer (new HttpServerOptions ())
152+ server = vertx
153+ .createHttpServer (new HttpServerOptions ()
154+ .setHttp2ClearTextEnabled (false )
155+ .setStrictThreadMode (true ))
132156 .requestHandler (App .this );
133157 dateString = createDateHeader ();
134- plaintextHeaders = new CharSequence [] {
135- HEADER_CONTENT_TYPE , RESPONSE_TYPE_PLAIN ,
136- HEADER_SERVER , SERVER ,
137- HEADER_DATE , dateString ,
138- HEADER_CONTENT_LENGTH , HELLO_WORLD_LENGTH };
158+ plaintextHeaders = plaintextHeaders ();
159+ jsonHeaders = jsonHeaders ();
139160 JsonObject config = config ();
140- vertx .setPeriodic (1000 , id -> plaintextHeaders [5 ] = dateString = createDateHeader ());
161+ vertx .setPeriodic (1000 , id -> {
162+ dateString = createDateHeader ();
163+ plaintextHeaders = plaintextHeaders ();
164+ jsonHeaders = jsonHeaders ();
165+ });
141166 PgConnectOptions options = new PgConnectOptions ();
142167 options .setDatabase (config .getString ("database" , "hello_world" ));
143168 options .setHost (config .getString ("host" , "tfb-database" ));
@@ -261,26 +286,19 @@ private void sendError(HttpServerRequest req, Throwable cause) {
261286
262287 private void handlePlainText (HttpServerRequest request ) {
263288 HttpServerResponse response = request .response ();
264- MultiMap headers = response .headers ();
265- for (int i = 0 ;i < plaintextHeaders .length ; i += 2 ) {
266- headers .add (plaintextHeaders [i ], plaintextHeaders [i + 1 ]);
267- }
268- response .end (HELLO_WORLD_BUFFER , NULL_HANDLER );
289+ response .headers ().setAll (plaintextHeaders );
290+ response .end (HELLO_WORLD_BUFFER );
269291 }
270292
271293 private void handleJson (HttpServerRequest request ) {
272294 HttpServerResponse response = request .response ();
273- MultiMap headers = response .headers ();
274- headers
275- .add (HEADER_CONTENT_TYPE , RESPONSE_TYPE_JSON )
276- .add (HEADER_SERVER , SERVER )
277- .add (HEADER_DATE , dateString );
278- response .end (new Message ("Hello, World!" ).toJson (), NULL_HANDLER );
295+ response .headers ().setAll (jsonHeaders );
296+ response .end (new Message ("Hello, World!" ).toJson ());
279297 }
280298
281299 private void handleDb (HttpServerRequest req ) {
282300 HttpServerResponse resp = req .response ();
283- SELECT_WORLD_QUERY .execute (Tuple .of (boxedRandomWorldNumber ()), res -> {
301+ SELECT_WORLD_QUERY .execute (Tuple .of (boxedRandomWorldNumber ())). onComplete ( res -> {
284302 if (res .succeeded ()) {
285303 RowIterator <Row > resultSet = res .result ().iterator ();
286304 if (!resultSet .hasNext ()) {
@@ -293,7 +311,7 @@ private void handleDb(HttpServerRequest req) {
293311 headers .add (HttpHeaders .SERVER , SERVER );
294312 headers .add (HttpHeaders .DATE , dateString );
295313 headers .add (HttpHeaders .CONTENT_TYPE , RESPONSE_TYPE_JSON );
296- resp .end (word .toJson (), NULL_HANDLER );
314+ resp .end (word .toJson ());
297315 } else {
298316 sendError (req , res .cause ());
299317 }
@@ -322,7 +340,9 @@ public Queries(HttpServerRequest req) {
322340 private void handle () {
323341 client .group (c -> {
324342 for (int i = 0 ; i < queries ; i ++) {
325- c .preparedQuery (SELECT_WORLD ).execute (Tuple .of (boxedRandomWorldNumber ()), this );
343+ c .preparedQuery (SELECT_WORLD )
344+ .execute (Tuple .of (boxedRandomWorldNumber ()))
345+ .onComplete (this );
326346 }
327347 });
328348 }
@@ -346,7 +366,7 @@ public void handle(AsyncResult<RowSet<Row>> ar) {
346366 headers .add (HttpHeaders .SERVER , SERVER );
347367 headers .add (HttpHeaders .DATE , dateString );
348368 headers .add (HttpHeaders .CONTENT_TYPE , RESPONSE_TYPE_JSON );
349- resp .end (World .toJson (worlds ), NULL_HANDLER );
369+ resp .end (World .toJson (worlds ));
350370 }
351371 }
352372 }
@@ -370,7 +390,7 @@ public void handle() {
370390 for (int i = 0 ; i < worldsToUpdate .length ; i ++) {
371391 final Integer id = boxedRandomWorldNumber ();
372392 final int index = i ;
373- preparedQuery .execute (Tuple .of (id ), res -> {
393+ preparedQuery .execute (Tuple .of (id )). onComplete ( res -> {
374394 if (!failed ) {
375395 if (res .failed ()) {
376396 failed = true ;
@@ -395,7 +415,9 @@ private void randomWorldsQueryCompleted() {
395415 params .add (world .getId ());
396416 params .add (world .getRandomNumber ());
397417 }
398- AGGREGATED_UPDATE_WORLD_QUERY [worldsToUpdate .length - 1 ].execute (Tuple .wrap (params ), updateResult -> {
418+ AGGREGATED_UPDATE_WORLD_QUERY [worldsToUpdate .length - 1 ]
419+ .execute (Tuple .wrap (params ))
420+ .onComplete (updateResult -> {
399421 if (updateResult .failed ()) {
400422 sendError (request , updateResult .cause ());
401423 return ;
@@ -411,12 +433,14 @@ private void sendResponse() {
411433 headers .add (HttpHeaders .DATE , dateString );
412434 headers .add (HttpHeaders .CONTENT_TYPE , RESPONSE_TYPE_JSON );
413435 Buffer buff = WorldJsonSerializer .toJsonBuffer (worldsToUpdate );
414- res .end (buff , null );
436+ res .end (buff );
415437 }
416438 }
417439
418440 private void handleFortunes (HttpServerRequest req ) {
419- SELECT_FORTUNE_QUERY .execute (ar -> {
441+ SELECT_FORTUNE_QUERY
442+ .execute ()
443+ .onComplete (ar -> {
420444 HttpServerResponse response = req .response ();
421445 if (ar .succeeded ()) {
422446 SqlResult <List <Fortune >> result = ar .result ();
@@ -432,7 +456,7 @@ private void handleFortunes(HttpServerRequest req) {
432456 headers .add (HttpHeaders .DATE , dateString );
433457 headers .add (HttpHeaders .CONTENT_TYPE , RESPONSE_TYPE_HTML );
434458 FortunesTemplate template = FortunesTemplate .template (fortunes );
435- response .end (template .render (factory ).buffer (), NULL_HANDLER );
459+ response .end (template .render (factory ).buffer ());
436460 } else {
437461 sendError (req , ar .cause ());
438462 }
@@ -457,7 +481,7 @@ private void handleCaching(HttpServerRequest req) {
457481 .add (HEADER_CONTENT_TYPE , RESPONSE_TYPE_JSON )
458482 .add (HEADER_SERVER , SERVER )
459483 .add (HEADER_DATE , dateString );
460- response .end (CachedWorld .toJson (worlds ), NULL_HANDLER );
484+ response .end (CachedWorld .toJson (worlds ));
461485 }
462486
463487 public static void main (String [] args ) throws Exception {
@@ -471,24 +495,30 @@ public static void main(String[] args) throws Exception {
471495 }
472496 }
473497 JsonObject config = new JsonObject (new String (Files .readAllBytes (new File (args [0 ]).toPath ())));
474- Vertx vertx = Vertx .vertx (new VertxOptions ().setEventLoopPoolSize (eventLoopPoolSize ).setPreferNativeTransport (true ));
498+ Vertx vertx = Vertx .vertx (new VertxOptions ()
499+ .setEventLoopPoolSize (eventLoopPoolSize )
500+ .setPreferNativeTransport (true )
501+ .setDisableTCCL (true )
502+ );
475503 vertx .exceptionHandler (err -> {
476504 err .printStackTrace ();
477505 });
478- printConfig (vertx );
479- vertx .deployVerticle (App .class .getName (),
480- new DeploymentOptions ().setInstances (eventLoopPoolSize ).setConfig (config ), event -> {
481- if (event .succeeded ()) {
482- logger .info ("Server listening on port " + 8080 );
483- } else {
484- logger .error ("Unable to start your application" , event .cause ());
485- }
486- });
506+ printConfig ((VertxInternal ) vertx );
507+ vertx .deployVerticle (
508+ App .class .getName (),
509+ new DeploymentOptions ().setInstances (eventLoopPoolSize ).setConfig (config ))
510+ .onComplete (event -> {
511+ if (event .succeeded ()) {
512+ logger .info ("Server listening on port " + 8080 );
513+ } else {
514+ logger .error ("Unable to start your application" , event .cause ());
515+ }
516+ });
487517 }
488518
489- private static void printConfig (Vertx vertx ) {
519+ private static void printConfig (VertxInternal vertx ) {
490520 boolean nativeTransport = vertx .isNativeTransportEnabled ();
491- String transport = (( VertxInternal ) vertx ) .transport ().getClass ().getSimpleName ();
521+ String transport = vertx .transport ().getClass ().getSimpleName ();
492522 String version = "unknown" ;
493523 try {
494524 InputStream in = Vertx .class .getClassLoader ().getResourceAsStream ("META-INF/vertx/vertx-version.txt" );
@@ -513,5 +543,10 @@ private static void printConfig(Vertx vertx) {
513543 logger .info ("Event Loop Size: " + ((MultithreadEventExecutorGroup )vertx .nettyEventLoopGroup ()).executorCount ());
514544 logger .info ("Native transport : " + nativeTransport );
515545 logger .info ("Transport : " + transport );
546+ logger .info ("Netty buffer bound check : " + System .getProperty ("io.netty.buffer.checkBounds" ));
547+ logger .info ("Netty buffer accessibility check : " + System .getProperty ("io.netty.buffer.checkAccessible" ));
548+ for (SysProps sysProp : SysProps .values ()) {
549+ logger .info (sysProp .name + " : " + sysProp .get ());
550+ }
516551 }
517552}
0 commit comments