diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java index 4601e1caf..280438731 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/IndexScannerTestBase.java @@ -1,7 +1,5 @@ package io.smallrye.openapi.runtime.scanner; -import static io.smallrye.openapi.api.constants.OpenApiConstants.DUPLICATE_OPERATION_ID_BEHAVIOR; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -21,23 +19,18 @@ import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.openapi.OASFactory; import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.eclipse.microprofile.openapi.models.Operation; -import org.eclipse.microprofile.openapi.models.PathItem; import org.eclipse.microprofile.openapi.models.media.Schema; -import org.eclipse.microprofile.openapi.models.parameters.Parameter; import org.jboss.jandex.DotName; import org.jboss.jandex.Index; import org.jboss.jandex.Indexer; import org.jboss.logging.Logger; import org.json.JSONException; -import org.junit.jupiter.api.Assertions; import org.skyscreamer.jsonassert.JSONAssert; import io.smallrye.config.PropertiesConfigSource; import io.smallrye.config.SmallRyeConfigBuilder; import io.smallrye.openapi.api.OpenApiConfig; import io.smallrye.openapi.api.SmallRyeOpenAPI; -import io.smallrye.openapi.model.Extensions; public class IndexScannerTestBase { @@ -133,40 +126,6 @@ public static String toJSON(OpenAPI oai) { .toJSON(); } - public static void verifyMethodAndParamRefsPresent(OpenAPI oai) { - if (oai.getPaths() != null && oai.getPaths().getPathItems() != null) { - for (Map.Entry pathItemEntry : oai.getPaths().getPathItems().entrySet()) { - final PathItem pathItem = pathItemEntry.getValue(); - if (pathItem.getOperations() != null) { - for (Map.Entry operationEntry : pathItem.getOperations().entrySet()) { - final Operation operation = operationEntry.getValue(); - String opRef = operationEntry.getKey() + " " + pathItemEntry.getKey(); - Assertions.assertNotNull(Extensions.getMethodRef(operation), "methodRef: " + opRef); - if (operation.getParameters() != null) { - for (Parameter parameter : operation.getParameters()) { - /* - * if @Parameter style=matrix was not specified at the same @Path segment - * a synthetic parameter is created which cannot be mapped to a field or method parameter - */ - if (!isPathMatrixObject(parameter)) { - // in all other cases paramRef should be set - String pRef = opRef + ", " + parameter.getIn() + ": " + parameter.getName(); - Assertions.assertNotNull(Extensions.getParamRef(parameter), "paramRef: " + pRef); - } - } - } - } - } - } - } - } - - private static boolean isPathMatrixObject(Parameter parameter) { - return parameter.getIn() == Parameter.In.PATH && parameter.getStyle() == Parameter.Style.MATRIX - && parameter.getSchema() != null && parameter.getSchema().getType() != null - && parameter.getSchema().getType().equals(Collections.singletonList(Schema.SchemaType.OBJECT)); - } - public static String schemaToString(String entityName, Schema schema) { return toJSON(OASFactory.createOpenAPI() .components(OASFactory.createComponents() @@ -254,10 +213,6 @@ public static OpenApiConfig dynamicConfig(String key, Object value) { return dynamicConfig(config); } - public static OpenApiConfig failOnDuplicateOperationIdsConfig() { - return dynamicConfig(DUPLICATE_OPERATION_ID_BEHAVIOR, OpenApiConfig.DuplicateOperationIdBehavior.FAIL.name()); - } - public static OpenApiConfig dynamicConfig(Map properties) { return OpenApiConfig.fromConfig(config(properties)); } diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ParameterScanTests.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ParameterScanTests.java index 135dc78ef..f90541f77 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ParameterScanTests.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/ParameterScanTests.java @@ -1,5 +1,6 @@ package io.smallrye.openapi.runtime.scanner; +import static io.smallrye.openapi.api.constants.OpenApiConstants.DUPLICATE_OPERATION_ID_BEHAVIOR; import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.ByteArrayInputStream; @@ -11,7 +12,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.OptionalDouble; import java.util.OptionalLong; @@ -24,6 +27,7 @@ import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.PathItem; import org.jboss.jandex.Index; import org.jboss.jandex.IndexReader; import org.jboss.jandex.IndexWriter; @@ -32,6 +36,7 @@ import org.junit.jupiter.api.Test; import io.smallrye.openapi.api.OpenApiConfig; +import io.smallrye.openapi.model.Extensions; import test.io.smallrye.openapi.runtime.scanner.Widget; import test.io.smallrye.openapi.runtime.scanner.jakarta.MultipleContentTypesWithFormParamsTestResource; @@ -40,6 +45,42 @@ */ class ParameterScanTests extends IndexScannerTestBase { + public static void verifyMethodAndParamRefsPresent(OpenAPI oai) { + if (oai.getPaths() != null && oai.getPaths().getPathItems() != null) { + for (Map.Entry pathItemEntry : oai.getPaths().getPathItems().entrySet()) { + final PathItem pathItem = pathItemEntry.getValue(); + if (pathItem.getOperations() != null) { + for (var operationEntry : pathItem.getOperations().entrySet()) { + var operation = operationEntry.getValue(); + String opRef = operationEntry.getKey() + " " + pathItemEntry.getKey(); + Assertions.assertNotNull(Extensions.getMethodRef(operation), "methodRef: " + opRef); + if (operation.getParameters() != null) { + for (var parameter : operation.getParameters()) { + /* + * if @Parameter style=matrix was not specified at the same @Path segment + * a synthetic parameter is created which cannot be mapped to a field or method parameter + */ + if (!isPathMatrixObject(parameter)) { + // in all other cases paramRef should be set + String pRef = opRef + ", " + parameter.getIn() + ": " + parameter.getName(); + Assertions.assertNotNull(Extensions.getParamRef(parameter), "paramRef: " + pRef); + } + } + } + } + } + } + } + } + + private static boolean isPathMatrixObject(org.eclipse.microprofile.openapi.models.parameters.Parameter parameter) { + return parameter.getIn() == org.eclipse.microprofile.openapi.models.parameters.Parameter.In.PATH + && parameter.getStyle() == org.eclipse.microprofile.openapi.models.parameters.Parameter.Style.MATRIX + && parameter.getSchema() != null && parameter.getSchema().getType() != null + && parameter.getSchema().getType().equals( + Collections.singletonList(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.OBJECT)); + } + private static void test(String expectedResource, Class... classes) throws IOException, JSONException { Index index = indexOf(classes); OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); @@ -163,10 +204,12 @@ void testJakartaMultipleContentTypesWithFormParams() throws IOException, JSONExc @Test void testFailOnDuplicateOperationIds() { - final OpenApiConfig config = failOnDuplicateOperationIdsConfig(); final IllegalStateException exception = assertThrows(IllegalStateException.class, - () -> test(config, "params.multiple-content-types-with-form-params.json", - MultipleContentTypesWithFormParamsTestResource.class, Widget.class)); + () -> test( + dynamicConfig(DUPLICATE_OPERATION_ID_BEHAVIOR, OpenApiConfig.DuplicateOperationIdBehavior.FAIL.name()), + "params.multiple-content-types-with-form-params.json", + MultipleContentTypesWithFormParamsTestResource.class, + Widget.class)); assertStartsWith(exception.getMessage(), "SROAP07950: Duplicate operationId:", "Exception message"); } 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 991a66f73..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; @@ -63,6 +64,7 @@ public boolean isDeleteMethod(final MethodInfo method) { } @Override + @SuppressWarnings("deprecation") public boolean containsScannerAnnotations(List instances, List extensions) { for (AnnotationInstance instance : instances) { @@ -149,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); @@ -312,8 +311,7 @@ private ResourceParameters getResourceParameters(final ClassInfo resourceClass, final MethodInfo method) { Function reader = t -> context.io().parameterIO().read(t); return VertxParameterProcessor.process(context, currentAppPath, resourceClass, - method, reader, - context.getExtensions()); + method, reader); } /** diff --git a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxLogging.java b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxLogging.java index b4c8a7a17..55cc3fb09 100644 --- a/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxLogging.java +++ b/extension-vertx/src/main/java/io/smallrye/openapi/vertx/VertxLogging.java @@ -1,5 +1,7 @@ package io.smallrye.openapi.vertx; +import static java.lang.invoke.MethodHandles.lookup; + import org.jboss.logging.Logger; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; @@ -7,7 +9,7 @@ @MessageLogger(projectCode = "SROAP", length = 5) interface VertxLogging { - VertxLogging log = Logger.getMessageLogger(VertxLogging.class, VertxLogging.class.getPackage().getName()); + VertxLogging log = Logger.getMessageLogger(lookup(), VertxLogging.class, VertxLogging.class.getPackage().getName()); @LogMessage(level = Logger.Level.WARN) @Message(id = 14000, value = "Ignoring %s annotation that is not on a method") 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 2526405af..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,15 +15,12 @@ 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; import org.jboss.jandex.Type; import io.smallrye.openapi.runtime.io.Names; -import io.smallrye.openapi.runtime.scanner.AnnotationScannerExtension; import io.smallrye.openapi.runtime.scanner.ResourceParameters; import io.smallrye.openapi.runtime.scanner.spi.AbstractParameterProcessor; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; @@ -45,9 +43,8 @@ public class VertxParameterProcessor extends AbstractParameterProcessor { private VertxParameterProcessor(AnnotationScannerContext scannerContext, String contextPath, - Function reader, - List extensions) { - super(scannerContext, contextPath, reader, extensions); + Function reader) { + super(scannerContext, contextPath, reader, scannerContext.getExtensions()); } /** @@ -63,7 +60,6 @@ private VertxParameterProcessor(AnnotationScannerContext scannerContext, * Vert.x HTTP annotations * @param reader callback method for a function producing {@link Parameter} from a * {@link org.eclipse.microprofile.openapi.annotations.parameters.Parameter} - * @param extensions scanner extensions * @return scanned parameters and modified path contained in a {@link ResourceParameters} * object */ @@ -71,10 +67,9 @@ public static ResourceParameters process(AnnotationScannerContext context, String contextPath, ClassInfo resourceClass, MethodInfo resourceMethod, - Function reader, - List extensions) { + Function reader) { - VertxParameterProcessor processor = new VertxParameterProcessor(context, contextPath, reader, extensions); + VertxParameterProcessor processor = new VertxParameterProcessor(context, contextPath, reader); return processor.process(resourceClass, resourceMethod); } @@ -96,39 +91,27 @@ 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 = 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(); - } - } - - 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 void readAnnotatedType(FrameworkParameter frameworkParam, AnnotationInstance annotation, @@ -149,15 +132,6 @@ private void readAnnotatedType(FrameworkParameter frameworkParam, AnnotationInst matrixParams.computeIfAbsent(pathSegment, k -> new HashMap<>()) .put(paramName(annotation), annotation); - - // Do this in Vert.x ? - //}else if (frameworkParam.location == In.PATH && targetType != null - // && VertxConstants.REQUEST_MAPPING.equals(targetType.name())) { - // String pathSegment = JandexUtil.value(annotation, ParameterConstant.PROP_VALUE); - - // if (!matrixParams.containsKey(pathSegment)) { - // matrixParams.put(pathSegment, new HashMap<>()); - // } } else if (frameworkParam.location != null) { readFrameworkParameter(annotation, frameworkParam, overriddenParametersOnly); } else if (target != null) { @@ -175,65 +149,47 @@ 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; - AnnotationInstance methodAnnotation = target.asMethod().annotation(possiblePath); - if (methodAnnotation != null) { - path = methodAnnotation; - } + pathValue = scannerContext.annotations().getAnnotationValue( + target, + Collections.singletonList(VertxConstants.ROUTE), + "path", + target.asMethod().name()); } - if (path != null) { - String pathValue = routePathValuesToPath(path, defaultPathValue); - if (pathValue != null) { - if (pathValue.startsWith("/")) { - pathValue = pathValue.substring(1); - } + if (pathValue == null) { + return ""; + } - if (pathValue.endsWith("/")) { - pathValue = pathValue.substring(0, pathValue.length() - 1); - } + if (pathValue.startsWith("/")) { + pathValue = pathValue.substring(1); + } + + if (pathValue.endsWith("/")) { + pathValue = pathValue.substring(0, pathValue.length() - 1); + } - // Replace :var with {var} - if (pathValue.contains(":")) { - List parts = Arrays.asList(pathValue.split("/")); - List partsConverted = new ArrayList<>(); - for (String part : parts) { - if (part.startsWith(":")) { - part = "{" + part.substring(1) + "}"; - } - partsConverted.add(part); - } - pathValue = String.join("/", partsConverted.toArray(new String[] {})); + // Replace :var with {var} - NOSONAR + if (pathValue.contains(":")) { + List parts = Arrays.asList(pathValue.split("/")); + List partsConverted = new ArrayList<>(); + for (String part : parts) { + if (part.startsWith(":")) { + part = "{" + part.substring(1) + "}"; } - return pathValue; + partsConverted.add(part); } + pathValue = String.join("/", partsConverted.toArray(new String[] {})); } - return ""; - } - - /** - * 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; + return pathValue; } @Override diff --git a/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/DeprecatedAnnotationTest.java b/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/DeprecatedAnnotationTest.java index bc2026711..1f9f51d87 100644 --- a/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/DeprecatedAnnotationTest.java +++ b/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/DeprecatedAnnotationTest.java @@ -3,11 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.io.IOException; - import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.jboss.jandex.Index; -import org.json.JSONException; import org.junit.jupiter.api.Test; import io.quarkus.vertx.web.Param; @@ -39,10 +35,8 @@ public String getD2() { } @Test - void testDeprecatedClassSetsOperationsDeprecated() throws IOException, JSONException { - Index index = Index.of(DeprecatedResource.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); - OpenAPI result = scanner.scan(); + void testDeprecatedClassSetsOperationsDeprecated() { + OpenAPI result = scan(DeprecatedResource.class); // NOSONAR assertTrue(result.getPaths().getPathItem("/deprecated/d1").getGET().getDeprecated()); assertTrue(result.getPaths().getPathItem("/deprecated/d2").getGET().getDeprecated()); } @@ -66,10 +60,8 @@ public String getD1() { } @Test - void testDeprecatedMethodSetsOperationsDeprecated() throws IOException, JSONException { - Index index = Index.of(MixedDeprecationResource.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); - OpenAPI result = scanner.scan(); + void testDeprecatedMethodSetsOperationsDeprecated() { + OpenAPI result = scan(MixedDeprecationResource.class); assertNull(result.getPaths().getPathItem("/mixed/m1").getGET().getDeprecated()); assertTrue(result.getPaths().getPathItem("/mixed/d1").getGET().getDeprecated()); } @@ -87,12 +79,9 @@ public String getO1(@Param("p1") @Deprecated String p1, @Param("p2") String p2) } @Test - void testDeprecatedParametersSetDeprecated() throws IOException, JSONException { - Index index = Index.of(DeprecatedParamResource.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); - OpenAPI result = scanner.scan(); + void testDeprecatedParametersSetDeprecated() { + OpenAPI result = scan(DeprecatedParamResource.class); printToConsole(result); - assertTrue(result.getPaths().getPathItem("/params/o1").getGET().getParameters().get(0).getDeprecated()); assertNull(result.getPaths().getPathItem("/params/o1").getGET().getParameters().get(1).getDeprecated()); diff --git a/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxAnnotationScannerTest.java b/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxAnnotationScannerTest.java index d51b7e768..71a537a0a 100644 --- a/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxAnnotationScannerTest.java +++ b/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxAnnotationScannerTest.java @@ -3,7 +3,6 @@ import java.io.IOException; import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.jboss.jandex.Index; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -18,7 +17,13 @@ * * @author Phillip Kruger (phillip.kruger@redhat.com) */ -class VertxAnnotationScannerTest extends VertxDataObjectScannerTestBase { +class VertxAnnotationScannerTest extends IndexScannerTestBase { + + void test(String expectedResource, Class... classes) throws IOException, JSONException { + OpenAPI result = scan(classes); + printToConsole(result); + assertJsonEquals(expectedResource, result); + } /** * This test a basic, no OpenApi annotations, hello world service @@ -28,13 +33,7 @@ class VertxAnnotationScannerTest extends VertxDataObjectScannerTestBase { */ @Test void testBasicGetRouteDefinitionScanning() throws IOException, JSONException { - Index i = indexOf(GreetingGetRoute.class, Greeting.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(failOnDuplicateOperationIdsConfig(), i); - - OpenAPI result = scanner.scan(); - - printToConsole(result); - assertJsonEquals("resource.testBasicRouteGetDefinitionScanning.json", result); + test("resource.testBasicRouteGetDefinitionScanning.json", GreetingGetRoute.class, Greeting.class); } /** @@ -45,13 +44,7 @@ void testBasicGetRouteDefinitionScanning() throws IOException, JSONException { */ @Test void testBasicPostRouteDefinitionScanning() throws IOException, JSONException { - Index i = indexOf(GreetingPostRoute.class, Greeting.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(failOnDuplicateOperationIdsConfig(), i); - - OpenAPI result = scanner.scan(); - - printToConsole(result); - assertJsonEquals("resource.testBasicRoutePostDefinitionScanning.json", result); + test("resource.testBasicRoutePostDefinitionScanning.json", GreetingPostRoute.class, Greeting.class); } /** @@ -62,13 +55,7 @@ void testBasicPostRouteDefinitionScanning() throws IOException, JSONException { */ @Test void testBasicPutRouteDefinitionScanning() throws IOException, JSONException { - Index i = indexOf(GreetingPutRoute.class, Greeting.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(failOnDuplicateOperationIdsConfig(), i); - - OpenAPI result = scanner.scan(); - - printToConsole(result); - assertJsonEquals("resource.testBasicRoutePutDefinitionScanning.json", result); + test("resource.testBasicRoutePutDefinitionScanning.json", GreetingPutRoute.class, Greeting.class); } /** @@ -79,13 +66,7 @@ void testBasicPutRouteDefinitionScanning() throws IOException, JSONException { */ @Test void testBasicDeleteRouteDefinitionScanning() throws IOException, JSONException { - Index i = indexOf(GreetingDeleteRoute.class, Greeting.class); - OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(failOnDuplicateOperationIdsConfig(), i); - - OpenAPI result = scanner.scan(); - - printToConsole(result); - assertJsonEquals("resource.testBasicRouteDeleteDefinitionScanning.json", result); + test("resource.testBasicRouteDeleteDefinitionScanning.json", GreetingDeleteRoute.class, Greeting.class); } } diff --git a/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxDataObjectScannerTestBase.java b/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxDataObjectScannerTestBase.java deleted file mode 100644 index a78515538..000000000 --- a/extension-vertx/src/test/java/io/smallrye/openapi/runtime/scanner/VertxDataObjectScannerTestBase.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.smallrye.openapi.runtime.scanner; - -import org.jboss.jandex.Index; -import org.jboss.jandex.Indexer; -import org.junit.jupiter.api.BeforeAll; - -/** - * Base for Vert.x tests. Index the test classes - * - * @author Phillip Kruger (phillip.kruger@redhat.com) - */ -public class VertxDataObjectScannerTestBase extends IndexScannerTestBase { - - protected static Index index; - - @BeforeAll - public static void createIndex() { - Indexer indexer = new Indexer(); - - // Test samples - indexDirectory(indexer, "test/io/smallrye/openapi/runtime/scanner/entities/"); - - index = indexer.complete(); - } - -} diff --git a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingDeleteRoute.java b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingDeleteRoute.java index 3b1034352..0dae397e0 100644 --- a/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingDeleteRoute.java +++ b/extension-vertx/src/test/java/test/io/smallrye/openapi/runtime/scanner/resources/GreetingDeleteRoute.java @@ -21,7 +21,7 @@ public class GreetingDeleteRoute { // 1) Basic path var test @Route(path = "/greet/:id", methods = HttpMethod.DELETE) public void greet(@Param("id") String id) { - + // No-op } } 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": {