From b1091af7f1e3dfb4b31a50218871786935b25855 Mon Sep 17 00:00:00 2001 From: Michael Edgar Date: Fri, 20 Dec 2024 12:14:03 -0500 Subject: [PATCH] refactor: additional Vert.x clean up and increase scenario coverage Signed-off-by: Michael Edgar --- .../openapi/vertx/VertxAnnotationScanner.java | 14 ++-- .../vertx/VertxParameterProcessor.java | 84 +++++-------------- .../scanner/resources/GreetingGetRoute.java | 8 +- .../scanner/resources/GreetingPostRoute.java | 8 +- .../scanner/resources/GreetingPutRoute.java | 7 +- ...e.testBasicRouteGetDefinitionScanning.json | 3 +- ....testBasicRoutePostDefinitionScanning.json | 33 ++++++++ 7 files changed, 80 insertions(+), 77 deletions(-) diff --git a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java index a2bdf5257..04533fa73 100644 --- a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java +++ b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxAnnotationScanner.java @@ -2,6 +2,7 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; @@ -150,14 +151,11 @@ private OpenAPI processRouteClass(ClassInfo routeClass) { context.getResolverStack().push(resolver); // Get the @RouteBase info and save it for later - AnnotationInstance routeBaseAnnotation = context.annotations().getAnnotation(routeClass, - VertxConstants.ROUTE_BASE); - - if (routeBaseAnnotation != null) { - this.currentAppPath = routeBaseAnnotation.value("path").asString(); // TODO: Check if there and check for : - } else { - this.currentAppPath = "/"; - } + this.currentAppPath = context.annotations().getAnnotationValue( + routeClass, + Collections.singletonList(VertxConstants.ROUTE_BASE), + "path", + "/"); // Process @OpenAPIDefinition annotation OpenAPI openApi = processDefinitionAnnotation(context, routeClass); diff --git a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxParameterProcessor.java b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxParameterProcessor.java index 30f7df18b..8cd7ba89f 100644 --- a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxParameterProcessor.java +++ b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxParameterProcessor.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.function.Function; @@ -14,8 +15,6 @@ import org.eclipse.microprofile.openapi.models.parameters.Parameter.Style; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; -import org.jboss.jandex.AnnotationTarget.Kind; -import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.MethodInfo; @@ -92,46 +91,29 @@ protected void readAnnotatedType(AnnotationInstance annotation, AnnotationInstan if (isReadableParameterAnnotation(name)) { readParameterAnnotation(annotation, overriddenParametersOnly); - } else if (VertxConstants.PARAM.equals(name) && annotation.value() != null) { - String parameterName = annotation.value().asString(); - String path = getMethodRoutePath(annotation); - - if (path != null && path.contains(":" + parameterName)) { + } else if (VertxConstants.PARAM.equals(name)) { + // @Param only targets method parameters + MethodInfo resourceMethod = annotation.target().asMethodParameter().method(); + String parameterName = paramName(annotation); + String path = scannerContext.annotations().getAnnotationValue( + resourceMethod, + Collections.singletonList(VertxConstants.ROUTE), + "path", + resourceMethod.name()); + + if (path.contains(":" + parameterName)) { FrameworkParameter vertxParameter = VertxParameter.PATH_PARAM.parameter; readAnnotatedType(vertxParameter, annotation, beanParamAnnotation, overriddenParametersOnly); } else { FrameworkParameter vertxParameter = VertxParameter.QUERY_PARAM.parameter; readAnnotatedType(vertxParameter, annotation, beanParamAnnotation, overriddenParametersOnly); } - } else if (VertxConstants.HEADER_PARAM.equals(name) && annotation.value() != null) { + } else if (VertxConstants.HEADER_PARAM.equals(name)) { FrameworkParameter vertxParameter = VertxParameter.HEADER_PARAM.parameter; readAnnotatedType(vertxParameter, annotation, beanParamAnnotation, overriddenParametersOnly); } } - private String getMethodRoutePath(AnnotationInstance annotation) { - String path = null; - MethodInfo resourceMethod = null; - - if (annotation.target().kind() == METHOD) { - resourceMethod = annotation.target().asMethod(); - } else if (annotation.target().kind() == Kind.METHOD_PARAMETER) { - resourceMethod = annotation.target().asMethodParameter().method(); - } - - if (resourceMethod != null) { - AnnotationInstance routeAnnotation = resourceMethod.annotation(VertxConstants.ROUTE); - AnnotationValue pathValue = routeAnnotation.value("path"); - path = resourceMethod.name(); // default to methodName - - if (pathValue != null) { - path = pathValue.asString(); - } - } - - return path; - } - private void readAnnotatedType(FrameworkParameter frameworkParam, AnnotationInstance annotation, AnnotationInstance beanParamAnnotation, boolean overriddenParametersOnly) { if (frameworkParam != null) { @@ -167,27 +149,21 @@ private void readAnnotatedType(FrameworkParameter frameworkParam, AnnotationInst @Override protected String pathOf(AnnotationTarget target) { - AnnotationInstance path = null; - String defaultPathValue = null; + String pathValue = null; if (target.kind().equals(CLASS)) { - DotName possiblePath = VertxConstants.ROUTE_BASE; - AnnotationInstance classAnnotation = scannerContext.annotations().getAnnotation(target, possiblePath); - if (classAnnotation != null && classAnnotation.value("path") != null) { - path = classAnnotation; - } + pathValue = scannerContext.annotations().getAnnotationValue( + target, + Collections.singletonList(VertxConstants.ROUTE_BASE), + "path"); } else if (target.kind().equals(METHOD)) { - defaultPathValue = target.asMethod().name(); - DotName possiblePath = VertxConstants.ROUTE; - path = target.asMethod().annotation(possiblePath); + pathValue = scannerContext.annotations().getAnnotationValue( + target, + Collections.singletonList(VertxConstants.ROUTE), + "path", + target.asMethod().name()); } - if (path == null) { - return ""; - } - - String pathValue = routePathValuesToPath(path, defaultPathValue); - if (pathValue == null) { return ""; } @@ -216,20 +192,6 @@ protected String pathOf(AnnotationTarget target) { return pathValue; } - /** - * Creates a String path from the Route path value - * - * @param routeAnnotation - * @return - */ - static String routePathValuesToPath(AnnotationInstance routeAnnotation, String defaultValue) { - AnnotationValue value = routeAnnotation.value("path"); - if (value != null) { - return value.asString(); - } - return defaultValue; - } - @Override protected boolean isSubResourceLocator(MethodInfo method) { return false; diff --git a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingGetRoute.java b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingGetRoute.java index f5054c6f7..8694d6fd1 100644 --- a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingGetRoute.java +++ b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingGetRoute.java @@ -9,6 +9,7 @@ import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import io.quarkus.vertx.web.Param; @@ -44,15 +45,16 @@ public List hellosPathVariable(RoutingExchange routingExchange, @Param return Arrays.asList(new Greeting("Hello " + name)); } - // 3) Basic path var with Optional test + // 3) Basic path var with Optional test, name of parameter taken from argument name @Route(path = "/helloOptional/:name", methods = HttpMethod.GET) - public Optional helloOptional(HttpServerRequest httpServerRequest, @Param("name") String name) { + public Optional helloOptional(HttpServerRequest httpServerRequest, @Param String name) { return Optional.of(new Greeting("Hello " + name)); } // 4) Basic request param test @Route(path = "/helloRequestParam", methods = HttpMethod.GET) - public Greeting helloRequestParam(HttpServerResponse httpServerResponse, @Param("name") String name) { + public Greeting helloRequestParam(HttpServerResponse httpServerResponse, + @Parameter(description = "The name") @Param("name") String name) { return new Greeting("Hello " + name); } diff --git a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPostRoute.java b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPostRoute.java index 57baf87c3..2b701fef9 100644 --- a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPostRoute.java +++ b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPostRoute.java @@ -7,6 +7,7 @@ import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import io.quarkus.vertx.web.Body; +import io.quarkus.vertx.web.Header; import io.quarkus.vertx.web.Route; import io.quarkus.vertx.web.Route.HttpMethod; import io.quarkus.vertx.web.RouteBase; @@ -20,7 +21,7 @@ * @author Phillip Kruger (phillip.kruger@redhat.com) */ @ApplicationScoped -@RouteBase(path = "greeting", consumes = "application/json", produces = "application/json") +@RouteBase(path = "greeting/", consumes = "application/json", produces = "application/json") public class GreetingPostRoute { // 1) Basic path var test @@ -36,4 +37,9 @@ public void greetWithResponse(@Body Greeting greeting) { // } + // 3) Header parameter + @Route(path = "/greetWithHeader", methods = HttpMethod.POST) + public Greeting greetWithResponse(@Body Greeting greeting, @Header String language) { + return greeting; + } } diff --git a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPutRoute.java b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPutRoute.java index 8fd725497..33e2c4b60 100644 --- a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPutRoute.java +++ b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingPutRoute.java @@ -21,17 +21,18 @@ * @author Phillip Kruger (phillip.kruger@redhat.com) */ @ApplicationScoped -@RouteBase(path = "greeting", consumes = "application/json", produces = "application/json") +// `path` not specified on @RouteBase +@RouteBase(consumes = "application/json", produces = "application/json") public class GreetingPutRoute { // 1) Basic path var test - @Route(path = "/greet/:id", methods = HttpMethod.PUT) + @Route(path = "/greeting/greet/:id", methods = HttpMethod.PUT) public Greeting greet(@Body Greeting greeting, @Param("id") String id) { return greeting; } // 2) Void, so without a type specified - @Route(path = "/greetWithResponse/:id", methods = HttpMethod.PUT) + @Route(path = "/greeting/greetWithResponse/:id", methods = HttpMethod.PUT) @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(ref = "#/components/schemas/Greeting"))) public void greetWithResponse(@Body Greeting greeting, @Param("id") String id) { // diff --git a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json index fe2bb36d0..efbbd14c3 100644 --- a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json +++ b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRouteGetDefinitionScanning.json @@ -452,7 +452,8 @@ "in" : "query", "schema" : { "type" : "string" - } + }, + "description" : "The name" } ], "responses" : { "200" : { diff --git a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json index de70ce66d..25521f3d3 100644 --- a/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json +++ b/extension-vertx/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.testBasicRoutePostDefinitionScanning.json @@ -52,6 +52,39 @@ } } } + }, + "/greeting/greetWithHeader": { + "post": { + "parameters": [{ + "name": "language", + "in": "header", + "schema": { + "type": "string" + } + }], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Greeting" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Greeting" + } + } + } + } + } + } } }, "components": {