From c4308a59c5f413b89dcd73ee254cc643aa60f90a Mon Sep 17 00:00:00 2001 From: joshua bauer Date: Wed, 3 Oct 2018 09:58:58 -0700 Subject: [PATCH] Blocking and Debug Support Support isBlocking when more than one consume type specified. Added @Debug annotation. --- pom.xml | 2 +- .../sinistral/proteus/annotations/Debug.java | 23 ++++++++++++ .../server/handlers/HandlerGenerator.java | 36 ++++++++++++++----- .../proteus/test/controllers/Tests.java | 36 +++++++++++++++++++ .../test/server/TestControllerEndpoints.java | 13 +++++++ 5 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 src/main/java/io/sinistral/proteus/annotations/Debug.java diff --git a/pom.xml b/pom.xml index 28a54fa..a0e4bc6 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.sinistral proteus-core - 0.3.3-SNAPSHOT + 0.3.4-SNAPSHOT proteus core Proteus is an extremely light, fast, and flexible Java REST API framework built atop Undertow. http://github.com/noboomu/proteus diff --git a/src/main/java/io/sinistral/proteus/annotations/Debug.java b/src/main/java/io/sinistral/proteus/annotations/Debug.java new file mode 100644 index 0000000..7e772b3 --- /dev/null +++ b/src/main/java/io/sinistral/proteus/annotations/Debug.java @@ -0,0 +1,23 @@ +/** + * + */ +package io.sinistral.proteus.annotations; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that this route should use a RequestDumpingHandler + */ +@Retention(RUNTIME) +@Target({ TYPE, METHOD }) +public @interface Debug +{ + boolean value() default true; +} + + \ No newline at end of file diff --git a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java index 0c2e194..41b9fc7 100644 --- a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java +++ b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java @@ -30,17 +30,15 @@ import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; - - import org.apache.commons.lang3.StringUtils; import org.reflections.Reflections; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.type.TypeReference; import com.google.inject.Inject; import com.google.inject.name.Named; -import com.fasterxml.jackson.core.type.TypeReference; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; @@ -53,6 +51,7 @@ import com.squareup.javapoet.TypeSpec; import io.sinistral.proteus.annotations.Blocking; +import io.sinistral.proteus.annotations.Debug; import io.sinistral.proteus.server.Extractors; import io.sinistral.proteus.server.ServerRequest; import io.sinistral.proteus.server.ServerResponse; @@ -63,7 +62,8 @@ import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; import io.undertow.server.RoutingHandler; -import io.undertow.server.handlers.RequestBufferingHandler; +import io.undertow.server.handlers.form.FormEncodedDataDefinition; +import io.undertow.server.handlers.form.MultiPartParserDefinition; import io.undertow.util.Headers; import io.undertow.util.HttpString; import net.openhft.compiler.CompilerUtils; @@ -393,6 +393,7 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class)) String consumesContentType = "*/*"; Boolean isBlocking = false; + Boolean isDebug = false; Optional blockingAnnotation = Optional.ofNullable(m.getAnnotation(Blocking.class)); @@ -400,6 +401,13 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class)) { isBlocking = blockingAnnotation.get().value(); } + + Optional debugAnnotation = Optional.ofNullable(m.getAnnotation(Debug.class)); + + if (debugAnnotation.isPresent()) + { + isDebug = debugAnnotation.get().value(); + } Optional producesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Produces.class)); @@ -467,8 +475,8 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class)) endpointInfo.setConsumes(consumesContentType); //The handler for these two inputs types is blocking, so we set the flag - if (endpointInfo.getConsumes().equals("application/x-www-form-urlencoded") - || endpointInfo.getConsumes().equals("multipart/form-data")) { + if (endpointInfo.getConsumes().contains(FormEncodedDataDefinition.APPLICATION_X_WWW_FORM_URLENCODED) + || endpointInfo.getConsumes().contains(MultiPartParserDefinition.MULTIPART_FORM_DATA)) { isBlocking = true; } @@ -768,7 +776,7 @@ else if (producesContentType.contains(MediaType.TEXT_HTML)) } else { - methodBuilder.addStatement("exchange.getResponseSender().send(com.jsoniter.output.JsonStream.serialize($L))", "response"); + methodBuilder.addStatement("exchange.getResponseSender().send($L.toString())", "response"); } } @@ -827,9 +835,19 @@ else if (producesContentType.contains(MediaType.TEXT_HTML)) securityDefinitions.addAll(typeLevelSecurityDefinitions); } - if (isBlocking) + if (isBlocking && isDebug) { - handlerName = "new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(1).wrap(" + handlerName + "))"; + handlerName = "new io.undertow.server.handlers.RequestDumpingHandler(new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(8).wrap(" + handlerName + ")))"; + } + else if( isBlocking ) + { + handlerName = "new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(8).wrap(" + handlerName + "))"; + + } + else if( isDebug ) + { + handlerName = "new io.undertow.server.handlers.RequestDumpingHandler(" + handlerName + ")"; + } if (wrapAnnotation.isPresent() || typeLevelHandlerWrapperMap.size() > 0 || securityDefinitions.size() > 0) diff --git a/src/test/java/io/sinistral/proteus/test/controllers/Tests.java b/src/test/java/io/sinistral/proteus/test/controllers/Tests.java index f468cb7..174a44e 100644 --- a/src/test/java/io/sinistral/proteus/test/controllers/Tests.java +++ b/src/test/java/io/sinistral/proteus/test/controllers/Tests.java @@ -34,6 +34,7 @@ import com.google.inject.Singleton; import io.sinistral.proteus.annotations.Blocking; +import io.sinistral.proteus.annotations.Debug; import io.sinistral.proteus.server.ServerRequest; import io.sinistral.proteus.server.ServerResponse; import io.sinistral.proteus.test.models.User; @@ -269,6 +270,41 @@ public ServerResponse responseUploadByteBuffer(ServerRequest request } + @GET + @Path("/response/debug") + @Debug + @ApiOperation(value = "Debug endpoint", httpMethod = "GET" ) + public ServerResponse> debugEndpoint(ServerRequest request) + { + try + { + Map map = ImmutableMap.of("message", "Hello, World!"); + + return response( map ).applicationJson(); + } catch(Exception e) + { + return response().badRequest(e); + } + } + + + @GET + @Path("/response/debug/blocking") + @Debug + @Blocking + @ApiOperation(value = "Debug blocking endpoint", httpMethod = "GET" ) + public ServerResponse> debugBlockingEndpoint(ServerRequest request) + { + try + { + Map map = ImmutableMap.of("message", "Hello, World!"); + + return response( map ).applicationJson(); + } catch(Exception e) + { + return response().badRequest(e); + } + } @GET @Path("/response/future/user") diff --git a/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java b/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java index 88c985a..6a7a1fb 100644 --- a/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java +++ b/src/test/java/io/sinistral/proteus/test/server/TestControllerEndpoints.java @@ -77,7 +77,20 @@ public void testSwaggerDocs() { given().accept(ContentType.JSON).log().uri().when().get("swagger.json").then().statusCode(200).and().body("basePath", is("/v1")); } + + @Test + public void testDebugEndpoint() + { + given().accept(ContentType.JSON).log().uri().when().get("tests/response/debug").then().statusCode(200); + } + @Test + public void testDebugBlockingEndpoint() + { + given().accept(ContentType.JSON).log().uri().when().get("tests/response/debug/blocking").then().statusCode(200); + } + + @Test public void exchangeUserJson() {