From e29e2d5fcdb80fd138385dcc6a5611cbc65e7e96 Mon Sep 17 00:00:00 2001 From: Brian Setz Date: Wed, 22 Jan 2025 21:39:50 +0100 Subject: [PATCH] Add support for managed JAX-RS subresource locators (#2169) * Add support for managed JAX-RS subresource locators * Resolve the return type first * Add tests for managed JAX-RS sub resource --------- Co-authored-by: Brian Setz <6406348-briansetz@users.noreply.gitlab.com> Co-authored-by: Michael Edgar --- .../openapi/jaxrs/JaxRsAnnotationScanner.java | 8 +- .../runtime/scanner/SubresourceScanTests.java | 2 + .../scanner/jakarta/Sub1TestResource.java | 4 + .../scanner/jakarta/Sub3TestResource.java | 16 ++++ .../scanner/javax/Sub1TestResource.java | 4 + .../scanner/javax/Sub3TestResource.java | 16 ++++ .../resource.subresources-with-params.json | 87 +++++++++++++++++++ 7 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub3TestResource.java create mode 100644 extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub3TestResource.java diff --git a/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java b/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java index 845754652..f3d4bb3d0 100644 --- a/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java +++ b/extension-jaxrs/src/main/java/io/smallrye/openapi/jaxrs/JaxRsAnnotationScanner.java @@ -402,7 +402,13 @@ private void processSubResource(final ClassInfo resourceClass, OpenAPI openApi, List locatorPathParameters, Set tagRefs) { - final Type methodReturnType = context.getResourceTypeResolver().resolve(method.returnType()); + + // Extract the method return type, if the method return type is Class then extract the type parameter. + Type methodReturnType = context.getResourceTypeResolver().resolve(method.returnType()); + if (methodReturnType.kind() == Type.Kind.PARAMETERIZED_TYPE + && methodReturnType.asParameterizedType().name().equals(DotName.createSimple(Class.class))) { + methodReturnType = methodReturnType.asParameterizedType().arguments().get(0); + } if (Type.Kind.VOID.equals(methodReturnType.kind())) { // Can sub-resource locators return a CompletionStage? diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/SubresourceScanTests.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/SubresourceScanTests.java index c311178c4..959e9d4d9 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/SubresourceScanTests.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/SubresourceScanTests.java @@ -33,6 +33,7 @@ void testJavaxResteasyMultipartInput() throws IOException, JSONException { test.io.smallrye.openapi.runtime.scanner.javax.MainTestResource.class, test.io.smallrye.openapi.runtime.scanner.javax.Sub1TestResource.class, test.io.smallrye.openapi.runtime.scanner.javax.Sub2TestResource.class, + test.io.smallrye.openapi.runtime.scanner.javax.Sub3TestResource.class, test.io.smallrye.openapi.runtime.scanner.javax.RecursiveLocatorResource.class); } @@ -42,6 +43,7 @@ void testJakartaResteasyMultipartInput() throws IOException, JSONException { test.io.smallrye.openapi.runtime.scanner.jakarta.MainTestResource.class, test.io.smallrye.openapi.runtime.scanner.jakarta.Sub1TestResource.class, test.io.smallrye.openapi.runtime.scanner.jakarta.Sub2TestResource.class, + test.io.smallrye.openapi.runtime.scanner.jakarta.Sub3TestResource.class, test.io.smallrye.openapi.runtime.scanner.jakarta.RecursiveLocatorResource.class); } diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub1TestResource.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub1TestResource.java index 94d8b3191..c26a0cc5e 100644 --- a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub1TestResource.java +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub1TestResource.java @@ -39,4 +39,8 @@ public Sub2TestResource getSub2(@PathParam("sub2-id") String sub2Id) { return new Sub2TestResource(); } + @Path(value = "/sub3/{sub3-id}") + public Class getSub3(@PathParam("sub3-id") String sub3Id) { + return Sub3TestResource.class; + } } diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub3TestResource.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub3TestResource.java new file mode 100644 index 000000000..c600fdd16 --- /dev/null +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/Sub3TestResource.java @@ -0,0 +1,16 @@ +package test.io.smallrye.openapi.runtime.scanner.jakarta; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; + +@SuppressWarnings(value = "unused") +public class Sub3TestResource { + + @GET + @Path(value = "{subsubid}") + public String getSub3(@PathParam("sub3-id") String sub3Id, @PathParam(value = "subsubid") String subsubid) { + return "Sub3TestResource"; + } + +} diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub1TestResource.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub1TestResource.java index e35c4fd80..d3d3e38b3 100644 --- a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub1TestResource.java +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub1TestResource.java @@ -39,4 +39,8 @@ public Sub2TestResource getSub2(@PathParam("sub2-id") String sub2Id) { return new Sub2TestResource(); } + @Path(value = "/sub3/{sub3-id}") + public Class getSub3(@PathParam("sub3-id") String sub3Id) { + return Sub3TestResource.class; + } } diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub3TestResource.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub3TestResource.java new file mode 100644 index 000000000..2067df35a --- /dev/null +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/Sub3TestResource.java @@ -0,0 +1,16 @@ +package test.io.smallrye.openapi.runtime.scanner.javax; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +@SuppressWarnings(value = "unused") +public class Sub3TestResource { + + @GET + @Path(value = "{subsubid}") + public String getSub3(@PathParam("sub3-id") String sub3Id, @PathParam(value = "subsubid") String subsubid) { + return "Sub3TestResource"; + } + +} diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json index 440598f28..85cabb58c 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/resource.subresources-with-params.json @@ -301,6 +301,93 @@ } ] }, + "/resource{resource}/sub/{id}{idMatrix}/sub3/{sub3-id}/{subsubid}" : { + "parameters" : [ { + "style" : "matrix", + "explode" : true, + "schema" : { + "type" : "object", + "properties" : { + "r0m0" : { + "$ref" : "#/components/schemas/LocalDateTime" + }, + "r0m1" : { + "$ref" : "#/components/schemas/LocalDateTime" + } + } + }, + "name" : "resource", + "in" : "path", + "required" : true + }, { + "description" : "Resource Identifier", + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "style" : "matrix", + "explode" : true, + "schema" : { + "type" : "object", + "properties" : { + "m1" : { + "type" : "string" + }, + "m2" : { + "type" : "integer", + "format" : "int32" + } + } + }, + "name" : "idMatrix", + "in" : "path", + "required" : true + }, { + "name" : "q1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "q2", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "get" : { + "parameters" : [ { + "name" : "sub3-id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "subsubid", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/resource{resource}/sub0": { "get": { "parameters": [