From b46e320ae134655ceef0a4998ddec976e15b8fb4 Mon Sep 17 00:00:00 2001 From: xstefank Date: Thu, 12 Oct 2023 10:24:41 +0200 Subject: [PATCH 01/29] Unblock SmallRye Health exposed routes (cherry picked from commit 2c21a99aaf8fa61bbd7332f980e222ea1928fa32) --- .../deployment/SmallRyeHealthProcessor.java | 21 ----------- .../runtime/SmallRyeHealthGroupHandler.java | 5 +-- .../health/runtime/SmallRyeHealthHandler.java | 5 +-- .../runtime/SmallRyeHealthHandlerBase.java | 36 +++++++++++-------- .../SmallRyeIndividualHealthGroupHandler.java | 5 +-- .../runtime/SmallRyeLivenessHandler.java | 5 +-- .../runtime/SmallRyeReadinessHandler.java | 5 +-- .../runtime/SmallRyeStartupHandler.java | 5 +-- .../runtime/SmallRyeWellnessHandler.java | 5 +-- 9 files changed, 42 insertions(+), 50 deletions(-) diff --git a/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java b/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java index 3899c03b69169..69d292bd81634 100644 --- a/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java +++ b/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java @@ -5,7 +5,6 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -217,7 +216,6 @@ public void defineHealthRoutes(BuildProducer routes, .routeConfigKey("quarkus.smallrye-health.root-path") .handler(new SmallRyeHealthHandler()) .displayOnNotFoundPage() - .blockingRoute() .build()); // Register the liveness handler @@ -226,7 +224,6 @@ public void defineHealthRoutes(BuildProducer routes, .nestedRoute(healthConfig.rootPath, healthConfig.livenessPath) .handler(new SmallRyeLivenessHandler()) .displayOnNotFoundPage() - .blockingRoute() .build()); // Register the readiness handler @@ -235,29 +232,14 @@ public void defineHealthRoutes(BuildProducer routes, .nestedRoute(healthConfig.rootPath, healthConfig.readinessPath) .handler(new SmallRyeReadinessHandler()) .displayOnNotFoundPage() - .blockingRoute() .build()); - // Find all health groups - Set healthGroups = new HashSet<>(); - // with simple @HealthGroup annotations - for (AnnotationInstance healthGroupAnnotation : index.getAnnotations(HEALTH_GROUP)) { - healthGroups.add(healthGroupAnnotation.value().asString()); - } - // with @HealthGroups repeatable annotations - for (AnnotationInstance healthGroupsAnnotation : index.getAnnotations(HEALTH_GROUPS)) { - for (AnnotationInstance healthGroupAnnotation : healthGroupsAnnotation.value().asNestedArray()) { - healthGroups.add(healthGroupAnnotation.value().asString()); - } - } - // Register the health group handlers routes.produce(nonApplicationRootPathBuildItem.routeBuilder() .management("quarkus.smallrye-health.management.enabled") .nestedRoute(healthConfig.rootPath, healthConfig.groupPath) .handler(new SmallRyeHealthGroupHandler()) .displayOnNotFoundPage() - .blockingRoute() .build()); SmallRyeIndividualHealthGroupHandler handler = new SmallRyeIndividualHealthGroupHandler(); @@ -266,7 +248,6 @@ public void defineHealthRoutes(BuildProducer routes, .nestedRoute(healthConfig.rootPath, healthConfig.groupPath + "/*") .handler(handler) .displayOnNotFoundPage() - .blockingRoute() .build()); // Register the wellness handler @@ -275,7 +256,6 @@ public void defineHealthRoutes(BuildProducer routes, .nestedRoute(healthConfig.rootPath, healthConfig.wellnessPath) .handler(new SmallRyeWellnessHandler()) .displayOnNotFoundPage() - .blockingRoute() .build()); // Register the startup handler @@ -284,7 +264,6 @@ public void defineHealthRoutes(BuildProducer routes, .nestedRoute(healthConfig.rootPath, healthConfig.startupPath) .handler(new SmallRyeStartupHandler()) .displayOnNotFoundPage() - .blockingRoute() .build()); } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthGroupHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthGroupHandler.java index 84c5c6fa62d0c..95b87746c1b08 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthGroupHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthGroupHandler.java @@ -2,12 +2,13 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeHealthGroupHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { - return reporter.getHealthGroups(); + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + return reporter.getHealthGroupsAsync(); } } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandler.java index 6960bb284bce9..6d9d33066e8fb 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandler.java @@ -2,12 +2,13 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeHealthHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { - return reporter.getHealth(); + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + return reporter.getHealthAsync(); } } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java index fff1485398fbc..e999375418769 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthHandlerBase.java @@ -10,7 +10,11 @@ import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser; import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; +import io.smallrye.mutiny.vertx.MutinyHelper; +import io.vertx.core.Context; import io.vertx.core.Handler; +import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpHeaders; import io.vertx.core.http.HttpServerResponse; @@ -18,7 +22,7 @@ abstract class SmallRyeHealthHandlerBase implements Handler { - protected abstract SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext routingContext); + protected abstract Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext routingContext); @Override public void handle(RoutingContext ctx) { @@ -41,19 +45,21 @@ private void doHandle(RoutingContext ctx) { Arc.container().instance(CurrentIdentityAssociation.class).get().setIdentity(user.getSecurityIdentity()); } SmallRyeHealthReporter reporter = Arc.container().instance(SmallRyeHealthReporter.class).get(); - SmallRyeHealth health = getHealth(reporter, ctx); - HttpServerResponse resp = ctx.response(); - if (health.isDown()) { - resp.setStatusCode(503); - } - resp.headers().set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); - Buffer buffer = Buffer.buffer(256); // this size seems to cover the basic health checks - try (BufferOutputStream outputStream = new BufferOutputStream(buffer);) { - reporter.reportHealth(outputStream, health); - resp.end(buffer); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + Context context = Vertx.currentContext(); + getHealth(reporter, ctx).emitOn(MutinyHelper.executor(context)) + .subscribe().with(health -> { + HttpServerResponse resp = ctx.response(); + if (health.isDown()) { + resp.setStatusCode(503); + } + resp.headers().set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); + Buffer buffer = Buffer.buffer(256); // this size seems to cover the basic health checks + try (BufferOutputStream outputStream = new BufferOutputStream(buffer);) { + reporter.reportHealth(outputStream, health); + resp.end(buffer); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); } - } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeIndividualHealthGroupHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeIndividualHealthGroupHandler.java index 66f960791ad8d..e0c7ba3874439 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeIndividualHealthGroupHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeIndividualHealthGroupHandler.java @@ -2,13 +2,14 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeIndividualHealthGroupHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { String group = ctx.normalizedPath().substring(ctx.normalizedPath().lastIndexOf("/") + 1); - return reporter.getHealthGroup(group); + return reporter.getHealthGroupAsync(group); } } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeLivenessHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeLivenessHandler.java index a5cf3dd904cbe..ad33e824ff3d7 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeLivenessHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeLivenessHandler.java @@ -2,12 +2,13 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeLivenessHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { - return reporter.getLiveness(); + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + return reporter.getLivenessAsync(); } } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeReadinessHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeReadinessHandler.java index a23a3e1f9d538..18c652bd673bd 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeReadinessHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeReadinessHandler.java @@ -2,12 +2,13 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeReadinessHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext routingContext) { - return reporter.getReadiness(); + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + return reporter.getReadinessAsync(); } } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeStartupHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeStartupHandler.java index c450430735ecb..cd1ae14846cc9 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeStartupHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeStartupHandler.java @@ -2,12 +2,13 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeStartupHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext routingContext) { - return reporter.getStartup(); + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + return reporter.getStartupAsync(); } } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeWellnessHandler.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeWellnessHandler.java index 84ca3860c1cae..e2131f51de416 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeWellnessHandler.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeWellnessHandler.java @@ -2,12 +2,13 @@ import io.smallrye.health.SmallRyeHealth; import io.smallrye.health.SmallRyeHealthReporter; +import io.smallrye.mutiny.Uni; import io.vertx.ext.web.RoutingContext; public class SmallRyeWellnessHandler extends SmallRyeHealthHandlerBase { @Override - protected SmallRyeHealth getHealth(SmallRyeHealthReporter reporter, RoutingContext routingContext) { - return reporter.getWellness(); + protected Uni getHealth(SmallRyeHealthReporter reporter, RoutingContext ctx) { + return reporter.getWellnessAsync(); } } From cc25791d34fb53cec5beb95b5113fb429f9fcfce Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Fri, 27 Oct 2023 11:44:01 +0200 Subject: [PATCH 02/29] Fix sockjs documentation (cherry picked from commit 7b2efa60de646ffa2e9cf637774a460f33ec3174) --- docs/src/main/asciidoc/vertx-reference.adoc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/src/main/asciidoc/vertx-reference.adoc b/docs/src/main/asciidoc/vertx-reference.adoc index ba0ff5be38f0c..b86f206fd60f0 100644 --- a/docs/src/main/asciidoc/vertx-reference.adoc +++ b/docs/src/main/asciidoc/vertx-reference.adoc @@ -852,7 +852,7 @@ So use SockJS, you need to configure the bridge, especially the addresses that w [source, java] ---- -package org.acme.vertx; +package org.acme; import io.vertx.core.Vertx; import io.vertx.ext.bridge.PermittedOptions; @@ -873,9 +873,13 @@ public class SockJsExample { public void init(@Observes Router router) { SockJSHandler sockJSHandler = SockJSHandler.create(vertx); - sockJSHandler.bridge(new SockJSBridgeOptions() + Router bridge = sockJSHandler.bridge(new SockJSBridgeOptions() .addOutboundPermitted(new PermittedOptions().setAddress("ticks"))); - router.route("/eventbus/*").handler(sockJSHandler); + router.route("/eventbus/*").subRouter(bridge); + + AtomicInteger counter = new AtomicInteger(); + vertx.setPeriodic(1000, + ignored -> vertx.eventBus().publish("ticks", counter.getAndIncrement())); } } From 08002e8e3d4b72e1b2e265c68fabc18292c86133 Mon Sep 17 00:00:00 2001 From: kdnakt Date: Fri, 27 Oct 2023 23:29:36 +0900 Subject: [PATCH 03/29] Fix typo in reactive-event-bus.adoc (cherry picked from commit 998f11368be9997946b86e12cc0d5ebfb955a46d) --- docs/src/main/asciidoc/reactive-event-bus.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/reactive-event-bus.adoc b/docs/src/main/asciidoc/reactive-event-bus.adoc index 8d6197323bab1..b1c03416d0770 100644 --- a/docs/src/main/asciidoc/reactive-event-bus.adoc +++ b/docs/src/main/asciidoc/reactive-event-bus.adoc @@ -26,7 +26,7 @@ However, it is limited to single-event behavior (no stream) and to local message == Installing This mechanism uses the Vert.x EventBus, so you need to enable the `vertx` extension to use this feature. -If you are creating a new project, set the `extensions` parameter are follows: +If you are creating a new project, set the `extensions` parameter as follows: :create-app-artifact-id: vertx-quickstart :create-app-extensions: vertx,resteasy-reactive From 0dae90ec3c4d2bbdb00980b709955b42e7af9ecd Mon Sep 17 00:00:00 2001 From: Alex Martel <13215031+manofthepeace@users.noreply.github.com> Date: Thu, 26 Oct 2023 09:27:14 -0400 Subject: [PATCH 04/29] Remove type from ResolverMapKey (cherry picked from commit ffc8a2a15c8701946d389b8abe0ff663b30e43b5) --- .../jackson/runtime/serialisers/JacksonUtil.java | 4 ++-- .../jackson/runtime/serialisers/ResolverMapKey.java | 13 +++---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java index bb8c217f4ac35..594f4b04a02be 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java @@ -31,11 +31,11 @@ static ObjectMapper getObjectMapperFromContext(Class type, MediaType response } if (contextResolver != null) { var cr = contextResolver; - var key = new ResolverMapKey(type, context.getConfiguration(), context.getInvokedMethod().getDeclaringClass()); + var key = new ResolverMapKey(context.getConfiguration(), context.getInvokedMethod().getDeclaringClass()); return contextResolverMap.computeIfAbsent(key, new Function<>() { @Override public ObjectMapper apply(ResolverMapKey resolverMapKey) { - return cr.getContext(resolverMapKey.getType()); + return cr.getContext(resolverMapKey.getRestClientClass()); } }); } diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ResolverMapKey.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ResolverMapKey.java index 02b8148f06b40..3e4ba6c3dd64c 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ResolverMapKey.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ResolverMapKey.java @@ -10,21 +10,14 @@ */ public final class ResolverMapKey { - private final Class type; private final Configuration configuration; - private final Class restClientClass; - public ResolverMapKey(Class type, Configuration configuration, Class restClientClass) { - this.type = type; + public ResolverMapKey(Configuration configuration, Class restClientClass) { this.configuration = configuration; this.restClientClass = restClientClass; } - public Class getType() { - return type; - } - public Configuration getConfiguration() { return configuration; } @@ -42,12 +35,12 @@ public boolean equals(Object o) { return false; } ResolverMapKey that = (ResolverMapKey) o; - return Objects.equals(type, that.type) && Objects.equals(configuration, that.configuration) + return Objects.equals(configuration, that.configuration) && Objects.equals(restClientClass, that.restClientClass); } @Override public int hashCode() { - return Objects.hash(type, configuration, restClientClass); + return Objects.hash(configuration, restClientClass); } } From 118810bc6a7dfafc19450907750ed8ec340f1106 Mon Sep 17 00:00:00 2001 From: Alex Martel <13215031+manofthepeace@users.noreply.github.com> Date: Fri, 27 Oct 2023 16:12:13 -0400 Subject: [PATCH 05/29] Make contextResolverMap used for both reader and writer (cherry picked from commit 6f5648c1e71887e06cc5bc21dcf869e27562a6b9) --- .../serialisers/ClientJacksonMessageBodyReader.java | 7 +++---- .../serialisers/ClientJacksonMessageBodyWriter.java | 7 +++---- .../reactive/jackson/runtime/serialisers/JacksonUtil.java | 6 ++++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyReader.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyReader.java index 63c4fb8cec20c..6ba0cb7f386c7 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyReader.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyReader.java @@ -33,7 +33,6 @@ public class ClientJacksonMessageBodyReader extends JacksonBasicMessageBodyReade private static final Logger log = Logger.getLogger(ClientJacksonMessageBodyReader.class); - private final ConcurrentMap contextResolverMap = new ConcurrentHashMap<>(); private final ConcurrentMap objectReaderMap = new ConcurrentHashMap<>(); private RestClientRequestContext context; @@ -49,7 +48,7 @@ public Object readFrom(Class type, Type genericType, Annotation[] annota if (entityStream instanceof EmptyInputStream) { return null; } - ObjectReader reader = getEffectiveReader(type, mediaType); + ObjectReader reader = getEffectiveReader(mediaType); return reader.forType(reader.getTypeFactory().constructType(genericType != null ? genericType : type)) .readValue(entityStream); @@ -66,8 +65,8 @@ public void handle(RestClientRequestContext requestContext) { this.context = requestContext; } - private ObjectReader getEffectiveReader(Class type, MediaType responseMediaType) { - ObjectMapper effectiveMapper = getObjectMapperFromContext(type, responseMediaType, context, contextResolverMap); + private ObjectReader getEffectiveReader(MediaType responseMediaType) { + ObjectMapper effectiveMapper = getObjectMapperFromContext(responseMediaType, context); if (effectiveMapper == null) { return getEffectiveReader(); } diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyWriter.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyWriter.java index 9c71047af4a28..bb91ba363f32b 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyWriter.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/ClientJacksonMessageBodyWriter.java @@ -28,7 +28,6 @@ public class ClientJacksonMessageBodyWriter implements MessageBodyWriter protected final ObjectMapper originalMapper; protected final ObjectWriter defaultWriter; - private final ConcurrentMap contextResolverMap = new ConcurrentHashMap<>(); private final ConcurrentMap objectWriterMap = new ConcurrentHashMap<>(); private RestClientRequestContext context; @@ -46,7 +45,7 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotation @Override public void writeTo(Object o, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { - doLegacyWrite(o, annotations, httpHeaders, entityStream, getEffectiveWriter(type, mediaType)); + doLegacyWrite(o, annotations, httpHeaders, entityStream, getEffectiveWriter(mediaType)); } @Override @@ -54,8 +53,8 @@ public void handle(RestClientRequestContext requestContext) throws Exception { this.context = requestContext; } - protected ObjectWriter getEffectiveWriter(Class type, MediaType responseMediaType) { - ObjectMapper objectMapper = getObjectMapperFromContext(type, responseMediaType, context, contextResolverMap); + protected ObjectWriter getEffectiveWriter(MediaType responseMediaType) { + ObjectMapper objectMapper = getObjectMapperFromContext(responseMediaType, context); if (objectMapper == null) { return defaultWriter; } diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java index 594f4b04a02be..e392db2821c6d 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java @@ -1,5 +1,6 @@ package io.quarkus.rest.client.reactive.jackson.runtime.serialisers; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Function; @@ -13,11 +14,12 @@ final class JacksonUtil { + private static final ConcurrentMap contextResolverMap = new ConcurrentHashMap<>(); + private JacksonUtil() { } - static ObjectMapper getObjectMapperFromContext(Class type, MediaType responseMediaType, RestClientRequestContext context, - ConcurrentMap contextResolverMap) { + static ObjectMapper getObjectMapperFromContext(MediaType responseMediaType, RestClientRequestContext context) { Providers providers = getProviders(context); if (providers == null) { return null; From a4967a769a2d36c92665f160435425eaa546a267 Mon Sep 17 00:00:00 2001 From: xstefank Date: Mon, 30 Oct 2023 13:13:06 +0100 Subject: [PATCH 06/29] Exclude resteasy-client from lra-proxy-api in narayana-lra extension (cherry picked from commit 2dcb5107da64d9b9b0e1483b13716e36459bcc54) --- extensions/narayana-lra/runtime/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/extensions/narayana-lra/runtime/pom.xml b/extensions/narayana-lra/runtime/pom.xml index fc9af12c2cd27..d508f17cf3c8e 100644 --- a/extensions/narayana-lra/runtime/pom.xml +++ b/extensions/narayana-lra/runtime/pom.xml @@ -36,6 +36,12 @@ org.jboss.narayana.rts lra-proxy-api + + + org.jboss.resteasy + resteasy-client + + org.jboss.narayana.rts From 88b5ee89073db1dcbac6bb9cc044c680eff100af Mon Sep 17 00:00:00 2001 From: Alexey Loubyansky Date: Tue, 31 Oct 2023 08:47:49 +0100 Subject: [PATCH 07/29] Add jvmArgs option to Quarkus Gradle plugin task quarkusRun (cherry picked from commit 48f901cd4f36ecb3d0c20744e3700d41ccb2a46a) --- .../io/quarkus/gradle/tasks/QuarkusRun.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java index c4fb864085c84..ea37bcb6875d2 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java @@ -14,15 +14,18 @@ import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.PathSensitive; import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskAction; +import org.gradle.api.tasks.options.Option; import io.quarkus.bootstrap.BootstrapException; import io.quarkus.bootstrap.app.AugmentAction; @@ -36,6 +39,7 @@ public abstract class QuarkusRun extends QuarkusBuildTask { private final Property workingDirectory; private final SourceSet mainSourceSet; + private final ListProperty jvmArgs; @Inject public QuarkusRun() { @@ -50,6 +54,8 @@ public QuarkusRun(String description) { workingDirectory = objectFactory.property(File.class); workingDirectory.convention(getProject().provider(() -> QuarkusPluginExtension.getLastFile(getCompilationOutput()))); + + jvmArgs = objectFactory.listProperty(String.class); } /** @@ -75,6 +81,22 @@ public void setWorkingDir(String workingDir) { workingDirectory.set(getProject().file(workingDir)); } + @Input + public ListProperty getJvmArguments() { + return jvmArgs; + } + + @Internal + public List getJvmArgs() { + return jvmArgs.get(); + } + + @SuppressWarnings("unused") + @Option(description = "Set JVM arguments", option = "jvm-args") + public void setJvmArgs(List jvmArgs) { + this.jvmArgs.set(jvmArgs); + } + @TaskAction public void runQuarkus() { ApplicationModel appModel = resolveAppModelForBuild(); @@ -122,6 +144,10 @@ public void accept(Map cmds) { throw new RuntimeException("Should never reach this!"); } List args = (List) cmd.get(0); + if (getJvmArguments().isPresent() && !getJvmArguments().get().isEmpty()) { + args.addAll(1, getJvmArgs()); + } + getProject().getLogger().info("Executing \"" + String.join(" ", args) + "\""); Path wd = (Path) cmd.get(1); File wdir = wd != null ? wd.toFile() : workingDirectory.get(); From 24164ee68facdc8a70ea294bf7fc2166a9372bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Tue, 31 Oct 2023 15:44:45 +0100 Subject: [PATCH 08/29] Fix assertions in Hibernate ORM 5.6 compatibility tests Hibernate ORM 5.6 does not, in fact, preserve information for OffsetTime columns. It just slaps the current JVM timezone on a stored LocalTime. (cherry picked from commit bedb7b1d031aa19cbbdc29f34b3a128d1b2de739) --- .../main/java/io/quarkus/it/hibernate/compatibility/Main.java | 2 +- .../quarkus/it/hibernate/compatibility/CompatibilityTest.java | 3 +-- .../quarkus/it/hibernate/compatibility/CompatibilityTest.java | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/integration-tests/hibernate-orm-compatibility-5.6/database-generator/src/main/java/io/quarkus/it/hibernate/compatibility/Main.java b/integration-tests/hibernate-orm-compatibility-5.6/database-generator/src/main/java/io/quarkus/it/hibernate/compatibility/Main.java index ab7f62e39ff7b..10b01e4b1397e 100644 --- a/integration-tests/hibernate-orm-compatibility-5.6/database-generator/src/main/java/io/quarkus/it/hibernate/compatibility/Main.java +++ b/integration-tests/hibernate-orm-compatibility-5.6/database-generator/src/main/java/io/quarkus/it/hibernate/compatibility/Main.java @@ -72,7 +72,7 @@ public int run(String... args) { checkEqual(createdEntity.duration, loadedEntity.duration); checkEqual(createdEntity.uuid, loadedEntity.uuid); checkEqual(createdEntity.instant, loadedEntity.instant); - checkEqual(createdEntity.offsetTime.withOffsetSameInstant(ZoneId.systemDefault().getRules().getOffset(Instant.now())), + checkEqual(createdEntity.offsetTime.toLocalTime().atOffset(ZoneId.systemDefault().getRules().getOffset(Instant.now())), loadedEntity.offsetTime); checkEqual(createdEntity.offsetDateTime.atZoneSameInstant(ZoneId.systemDefault()).toOffsetDateTime(), loadedEntity.offsetDateTime); diff --git a/integration-tests/hibernate-orm-compatibility-5.6/mariadb/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java b/integration-tests/hibernate-orm-compatibility-5.6/mariadb/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java index ebdf74a1815d0..d326e27317dde 100644 --- a/integration-tests/hibernate-orm-compatibility-5.6/mariadb/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java +++ b/integration-tests/hibernate-orm-compatibility-5.6/mariadb/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java @@ -120,9 +120,8 @@ public void instant() { public void offsetTime() { assertThat(findOld().offsetTime) .isEqualTo(LocalTime.of(12, 58, 30, 0) - .atOffset(ZoneOffset.ofHours(2)) // Hibernate ORM 5 used to normalize these values to the JVM TZ - .withOffsetSameInstant(ZoneId.systemDefault().getRules().getOffset(Instant.now()))); + .atOffset(ZoneId.systemDefault().getRules().getOffset(Instant.now()))); } // https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#timezone-and-offset-storage diff --git a/integration-tests/hibernate-orm-compatibility-5.6/postgresql/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java b/integration-tests/hibernate-orm-compatibility-5.6/postgresql/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java index e6ed294c77e5e..4f5934a6293d3 100644 --- a/integration-tests/hibernate-orm-compatibility-5.6/postgresql/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java +++ b/integration-tests/hibernate-orm-compatibility-5.6/postgresql/src/test/java/io/quarkus/it/hibernate/compatibility/CompatibilityTest.java @@ -120,9 +120,8 @@ public void instant() { public void offsetTime() { assertThat(findOld().offsetTime) .isEqualTo(LocalTime.of(12, 58, 30, 0) - .atOffset(ZoneOffset.ofHours(2)) // Hibernate ORM 5 used to normalize these values to the JVM TZ - .withOffsetSameInstant(ZoneId.systemDefault().getRules().getOffset(Instant.now()))); + .atOffset(ZoneId.systemDefault().getRules().getOffset(Instant.now()))); } // https://github.com/hibernate/hibernate-orm/blob/6.2/migration-guide.adoc#timezone-and-offset-storage From 483dd75728f41602692f212a2c9d5b0b817b2c32 Mon Sep 17 00:00:00 2001 From: Phillip Kruger Date: Fri, 27 Oct 2023 11:03:45 +1100 Subject: [PATCH 09/29] Tests to check content type between Services and OpenAPI Signed-off-by: Phillip Kruger (cherry picked from commit 3dad6f5e55e63d133a3cc88a872c80023c6ee89d) --- bom/application/pom.xml | 2 +- .../deployment/SmallRyeOpenApiProcessor.java | 4 + .../test/jaxrs/DefaultContentTypeTest.java | 2 +- .../java/io/quarkus/it/rest/TestResource.java | 1 + .../io/quarkus/it/main/OpenApiTestCase.java | 11 +- integration-tests/openapi/pom.xml | 171 +++++++++++++ .../java/io/quarkus/it/openapi/Greeting.java | 31 +++ .../it/openapi/jaxrs/BigDecimalResource.java | 98 ++++++++ .../it/openapi/jaxrs/BigIntegerResource.java | 98 ++++++++ .../it/openapi/jaxrs/BooleanResource.java | 136 ++++++++++ .../it/openapi/jaxrs/ByteArrayResource.java | 84 +++++++ .../it/openapi/jaxrs/FileResource.java | 83 +++++++ .../it/openapi/jaxrs/InputStreamResource.java | 85 +++++++ .../it/openapi/jaxrs/IntegerResource.java | 149 +++++++++++ .../it/openapi/jaxrs/LongResource.java | 149 +++++++++++ .../it/openapi/jaxrs/PojoResource.java | 115 +++++++++ .../it/openapi/jaxrs/ReaderResource.java | 85 +++++++ .../it/openapi/jaxrs/ShortResource.java | 136 ++++++++++ .../it/openapi/jaxrs/StringResource.java | 113 +++++++++ .../quarkus/it/openapi/jaxrs/URLResource.java | 123 +++++++++ .../it/openapi/spring/BigDecimalResource.java | 86 +++++++ .../it/openapi/spring/BigIntegerResource.java | 86 +++++++ .../it/openapi/spring/BooleanResource.java | 119 +++++++++ .../it/openapi/spring/ByteArrayResource.java | 76 ++++++ .../it/openapi/spring/FileResource.java | 75 ++++++ .../openapi/spring/InputStreamResource.java | 77 ++++++ .../it/openapi/spring/IntegerResource.java | 130 ++++++++++ .../it/openapi/spring/LongResource.java | 130 ++++++++++ .../it/openapi/spring/PojoResource.java | 101 ++++++++ .../it/openapi/spring/ReaderResource.java | 77 ++++++ .../it/openapi/spring/ShortResource.java | 119 +++++++++ .../it/openapi/spring/StringResource.java | 100 ++++++++ .../it/openapi/spring/URLResource.java | 109 ++++++++ .../it/openapi/AbstractByteArrayTest.java | 59 +++++ .../quarkus/it/openapi/AbstractFileTest.java | 58 +++++ .../it/openapi/AbstractInputStreamTest.java | 58 +++++ .../it/openapi/AbstractReaderTest.java | 58 +++++ .../io/quarkus/it/openapi/AbstractTest.java | 101 ++++++++ .../it/openapi/jaxrs/BigDecimalTest.java | 149 +++++++++++ .../it/openapi/jaxrs/BigIntegerTest.java | 149 +++++++++++ .../quarkus/it/openapi/jaxrs/BooleanTest.java | 213 ++++++++++++++++ .../it/openapi/jaxrs/ByteArrayTest.java | 110 +++++++++ .../io/quarkus/it/openapi/jaxrs/FileTest.java | 110 +++++++++ .../it/openapi/jaxrs/InputStreamTest.java | 110 +++++++++ .../quarkus/it/openapi/jaxrs/IntegerTest.java | 232 +++++++++++++++++ .../io/quarkus/it/openapi/jaxrs/LongTest.java | 232 +++++++++++++++++ .../io/quarkus/it/openapi/jaxrs/PojoTest.java | 172 +++++++++++++ .../quarkus/it/openapi/jaxrs/ReaderTest.java | 110 +++++++++ .../quarkus/it/openapi/jaxrs/ShortTest.java | 211 ++++++++++++++++ .../quarkus/it/openapi/jaxrs/StringTest.java | 169 +++++++++++++ .../io/quarkus/it/openapi/jaxrs/URLTest.java | 169 +++++++++++++ .../it/openapi/spring/BigDecimalTest.java | 149 +++++++++++ .../it/openapi/spring/BigIntegerTest.java | 149 +++++++++++ .../it/openapi/spring/BooleanTest.java | 211 ++++++++++++++++ .../it/openapi/spring/ByteArrayTest.java | 110 +++++++++ .../quarkus/it/openapi/spring/FileTest.java | 110 +++++++++ .../it/openapi/spring/InputStreamTest.java | 110 +++++++++ .../it/openapi/spring/IntegerTest.java | 232 +++++++++++++++++ .../quarkus/it/openapi/spring/LongTest.java | 233 ++++++++++++++++++ .../quarkus/it/openapi/spring/PojoTest.java | 175 +++++++++++++ .../quarkus/it/openapi/spring/ReaderTest.java | 110 +++++++++ .../quarkus/it/openapi/spring/ShortTest.java | 212 ++++++++++++++++ .../quarkus/it/openapi/spring/StringTest.java | 169 +++++++++++++ .../io/quarkus/it/openapi/spring/URLTest.java | 169 +++++++++++++ integration-tests/pom.xml | 1 + 65 files changed, 7564 insertions(+), 7 deletions(-) create mode 100644 integration-tests/openapi/pom.xml create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/Greeting.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigDecimalResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigIntegerResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BooleanResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ByteArrayResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/FileResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/InputStreamResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/IntegerResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/LongResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/PojoResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ReaderResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ShortResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/StringResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/URLResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigDecimalResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigIntegerResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BooleanResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ByteArrayResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/FileResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/InputStreamResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/IntegerResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/LongResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/PojoResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ReaderResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ShortResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/StringResource.java create mode 100644 integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/URLResource.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractByteArrayTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractFileTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractInputStreamTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractReaderTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigDecimalTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigIntegerTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BooleanTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ByteArrayTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/FileTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/InputStreamTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/IntegerTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/LongTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/PojoTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ReaderTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ShortTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/StringTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/URLTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigDecimalTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigIntegerTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BooleanTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ByteArrayTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/FileTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/InputStreamTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/IntegerTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/LongTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/PojoTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ReaderTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ShortTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/StringTest.java create mode 100644 integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/URLTest.java diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 2d72dda5bbd6b..e3986e9959e73 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -54,7 +54,7 @@ 3.4.1 4.0.4 4.0.0 - 3.6.2 + 3.7.0 2.5.1 3.0.3 6.2.6 diff --git a/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java b/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java index 5b1f46f1dd2f5..851e82a60e179 100644 --- a/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java +++ b/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java @@ -162,6 +162,10 @@ public class SmallRyeOpenApiProcessor { private static final String VERT_X = "Vert.x"; static { + System.setProperty(io.smallrye.openapi.api.constants.OpenApiConstants.DEFAULT_PRODUCES_STREAMING, + "application/octet-stream"); + System.setProperty(io.smallrye.openapi.api.constants.OpenApiConstants.DEFAULT_CONSUMES_STREAMING, + "application/octet-stream"); System.setProperty(io.smallrye.openapi.api.constants.OpenApiConstants.DEFAULT_PRODUCES, "application/json"); System.setProperty(io.smallrye.openapi.api.constants.OpenApiConstants.DEFAULT_CONSUMES, "application/json"); System.setProperty(io.smallrye.openapi.api.constants.OpenApiConstants.DEFAULT_PRODUCES_PRIMITIVES, "text/plain"); diff --git a/extensions/smallrye-openapi/deployment/src/test/java/io/quarkus/smallrye/openapi/test/jaxrs/DefaultContentTypeTest.java b/extensions/smallrye-openapi/deployment/src/test/java/io/quarkus/smallrye/openapi/test/jaxrs/DefaultContentTypeTest.java index dc053a88f90de..bd26dca753448 100644 --- a/extensions/smallrye-openapi/deployment/src/test/java/io/quarkus/smallrye/openapi/test/jaxrs/DefaultContentTypeTest.java +++ b/extensions/smallrye-openapi/deployment/src/test/java/io/quarkus/smallrye/openapi/test/jaxrs/DefaultContentTypeTest.java @@ -34,4 +34,4 @@ public void testOpenApiPathAccessResource() { Matchers.containsString("#/components/schemas/Greeting")); } -} +} \ No newline at end of file diff --git a/integration-tests/main/src/main/java/io/quarkus/it/rest/TestResource.java b/integration-tests/main/src/main/java/io/quarkus/it/rest/TestResource.java index 41a282aba4a3d..bb58c4aaf7749 100644 --- a/integration-tests/main/src/main/java/io/quarkus/it/rest/TestResource.java +++ b/integration-tests/main/src/main/java/io/quarkus/it/rest/TestResource.java @@ -150,6 +150,7 @@ public CompletionStage cs() { @GET @Path("/rx") + @Produces("text/plain") public Single rx() { return Single.just("Hello"); } diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/OpenApiTestCase.java b/integration-tests/main/src/test/java/io/quarkus/it/main/OpenApiTestCase.java index 214f452efa1b7..f52a42054287f 100644 --- a/integration-tests/main/src/test/java/io/quarkus/it/main/OpenApiTestCase.java +++ b/integration-tests/main/src/test/java/io/quarkus/it/main/OpenApiTestCase.java @@ -22,7 +22,7 @@ public class OpenApiTestCase { private static final String DEFAULT_MEDIA_TYPE = "application/json"; - private static final String DEFAULT_MEDIA_TYPE_PRIMITAVE = "text/plain"; + private static final String DEFAULT_MEDIA_TYPE_PRIMITIVE = "text/plain"; @TestHTTPResource("q/openapi") URL uri; @@ -64,10 +64,10 @@ public void testOpenAPIJSON() throws Exception { // test RESTEasy extensions JsonObject schemasObj = obj.getJsonObject("components").getJsonObject("schemas"); - String testSchemaType = schemaType("200", DEFAULT_MEDIA_TYPE_PRIMITAVE, + String testSchemaType = schemaType("200", DEFAULT_MEDIA_TYPE_PRIMITIVE, testObj.getJsonObject("get").getJsonObject("responses"), schemasObj); - String rxSchemaType = schemaType("200", DEFAULT_MEDIA_TYPE, + String rxSchemaType = schemaType("200", DEFAULT_MEDIA_TYPE_PRIMITIVE, injectionObj.getJsonObject("get").getJsonObject("responses"), schemasObj); // make sure String, CompletionStage and Single are detected the same @@ -76,7 +76,8 @@ public void testOpenAPIJSON() throws Exception { "Normal and RX/Single have same schema"); JsonObject csObj = paths.getJsonObject("/test/cs"); Assertions.assertEquals(testSchemaType, - schemaType("200", DEFAULT_MEDIA_TYPE, csObj.getJsonObject("get").getJsonObject("responses"), schemasObj), + schemaType("200", DEFAULT_MEDIA_TYPE_PRIMITIVE, csObj.getJsonObject("get").getJsonObject("responses"), + schemasObj), "Normal and RX/CS have same schema"); JsonObject paramsObj = paths.getJsonObject("/test/params/{path}"); @@ -90,7 +91,7 @@ public void testOpenAPIJSON() throws Exception { Assertions.assertEquals(1, keys.size()); Assertions.assertEquals("get", keys.iterator().next()); - String uniSchemaType = schemaType("200", DEFAULT_MEDIA_TYPE_PRIMITAVE, + String uniSchemaType = schemaType("200", DEFAULT_MEDIA_TYPE_PRIMITIVE, uniObj.getJsonObject("get").getJsonObject("responses"), schemasObj); // make sure String, CompletionStage and Uni are detected the same diff --git a/integration-tests/openapi/pom.xml b/integration-tests/openapi/pom.xml new file mode 100644 index 0000000000000..068a587db5118 --- /dev/null +++ b/integration-tests/openapi/pom.xml @@ -0,0 +1,171 @@ + + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-integration-test-openapi + Quarkus - Integration Tests - OpenAPI + The openapi integration tests module + + + + io.quarkus + quarkus-smallrye-openapi + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + io.quarkus + quarkus-reactive-routes + + + io.quarkus + quarkus-spring-web + + + + + io.quarkus + quarkus-junit5 + test + + + io.quarkus + quarkus-junit5-component + test + + + io.rest-assured + rest-assured + test + + + org.assertj + assertj-core + test + + + + + io.quarkus + quarkus-reactive-routes-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-resteasy-reactive-jackson-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-smallrye-openapi-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-spring-web-deployment + ${project.version} + pom + test + + + * + * + + + + + + + + + src/main/resources + true + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + alphabetical + + + + + + + + + native-image + + + native + + + + + true + + + + + no-native + + + !native + + + + + uber-jar + + + + + + diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/Greeting.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/Greeting.java new file mode 100644 index 0000000000000..4312e491c305f --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/Greeting.java @@ -0,0 +1,31 @@ +package io.quarkus.it.openapi; + +public class Greeting { + private int id; + private String salutation; + + public Greeting() { + + } + + public Greeting(int id, String salutation) { + this.id = id; + this.salutation = salutation; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSalutation() { + return salutation; + } + + public void setSalutation(String salutation) { + this.salutation = salutation; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigDecimalResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigDecimalResource.java new file mode 100644 index 0000000000000..a30b2c8759db7 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigDecimalResource.java @@ -0,0 +1,98 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class BigDecimalResource { + @GET + @Path("/justBigDecimal") + public BigDecimal justBigDecimal() { + return new BigDecimal("0"); + } + + @POST + @Path("/justBigDecimal") + public BigDecimal justBigDecimal(BigDecimal body) { + return body; + } + + @GET + @Path("/restResponseBigDecimal") + public RestResponse restResponseBigDecimal() { + return RestResponse.ok(new BigDecimal("0")); + } + + @POST + @Path("/restResponseBigDecimal") + public RestResponse restResponseBigDecimal(BigDecimal body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalBigDecimal") + public Optional optionalBigDecimal() { + return Optional.of(new BigDecimal("0")); + } + + @POST + @Path("/optionalBigDecimal") + public Optional optionalBigDecimal(Optional body) { + return body; + } + + @GET + @Path("/uniBigDecimal") + public Uni uniBigDecimal() { + return Uni.createFrom().item(new BigDecimal("0")); + } + + @GET + @Path("/completionStageBigDecimal") + public CompletionStage completionStageBigDecimal() { + return CompletableFuture.completedStage(new BigDecimal("0")); + } + + @GET + @Path("/completedFutureBigDecimal") + public CompletableFuture completedFutureBigDecimal() { + return CompletableFuture.completedFuture(new BigDecimal("0")); + } + + @GET + @Path("/listBigDecimal") + public List listBigDecimal() { + return Arrays.asList(new BigDecimal[] { new BigDecimal("0") }); + } + + @POST + @Path("/listBigDecimal") + public List listBigDecimal(List body) { + return body; + } + + @GET + @Path("/arrayBigDecimal") + public BigDecimal[] arrayBigDecimal() { + return new BigDecimal[] { new BigDecimal("0") }; + } + + @POST + @Path("/arrayBigDecimal") + public BigDecimal[] arrayBigDecimal(BigDecimal[] body) { + return body; + } + +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigIntegerResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigIntegerResource.java new file mode 100644 index 0000000000000..26c1e6a1fb35d --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BigIntegerResource.java @@ -0,0 +1,98 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class BigIntegerResource { + @GET + @Path("/justBigInteger") + public BigInteger justBigInteger() { + return new BigInteger("0"); + } + + @POST + @Path("/justBigInteger") + public BigInteger justBigInteger(BigInteger body) { + return body; + } + + @GET + @Path("/restResponseBigInteger") + public RestResponse restResponseBigInteger() { + return RestResponse.ok(new BigInteger("0")); + } + + @POST + @Path("/restResponseBigInteger") + public RestResponse restResponseBigInteger(BigInteger body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalBigInteger") + public Optional optionalBigInteger() { + return Optional.of(new BigInteger("0")); + } + + @POST + @Path("/optionalBigInteger") + public Optional optionalBigInteger(Optional body) { + return body; + } + + @GET + @Path("/uniBigInteger") + public Uni uniBigInteger() { + return Uni.createFrom().item(new BigInteger("0")); + } + + @GET + @Path("/completionStageBigInteger") + public CompletionStage completionStageBigInteger() { + return CompletableFuture.completedStage(new BigInteger("0")); + } + + @GET + @Path("/completedFutureBigInteger") + public CompletableFuture completedFutureBigInteger() { + return CompletableFuture.completedFuture(new BigInteger("0")); + } + + @GET + @Path("/listBigInteger") + public List listBigInteger() { + return Arrays.asList(new BigInteger[] { new BigInteger("0") }); + } + + @POST + @Path("/listBigInteger") + public List listBigInteger(List body) { + return body; + } + + @GET + @Path("/arrayBigInteger") + public BigInteger[] arrayBigInteger() { + return new BigInteger[] { new BigInteger("0") }; + } + + @POST + @Path("/arrayBigInteger") + public BigInteger[] arrayBigInteger(BigInteger[] body) { + return body; + } + +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BooleanResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BooleanResource.java new file mode 100644 index 0000000000000..3e3c2aeabd1f1 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/BooleanResource.java @@ -0,0 +1,136 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class BooleanResource { + @GET + @Path("/justBoolean") + public Boolean justBoolean() { + return Boolean.TRUE; + } + + @POST + @Path("/justBoolean") + public Boolean justBoolean(Boolean body) { + return body; + } + + @GET + @Path("/justBool") + public boolean justBool() { + return true; + } + + @POST + @Path("/justBool") + public boolean justBool(boolean body) { + return body; + } + + @GET + @Path("/restResponseBoolean") + public RestResponse restResponseBoolean() { + return RestResponse.ok(Boolean.TRUE); + } + + @POST + @Path("/restResponseBoolean") + public RestResponse restResponseBoolean(Boolean body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalBoolean") + public Optional optionalBoolean() { + return Optional.of(Boolean.TRUE); + } + + @POST + @Path("/optionalBoolean") + public Optional optionalBoolean(Optional body) { + return body; + } + + @GET + @Path("/uniBoolean") + public Uni uniBoolean() { + return Uni.createFrom().item(Boolean.TRUE); + } + + @GET + @Path("/completionStageBoolean") + public CompletionStage completionStageBoolean() { + return CompletableFuture.completedStage(Boolean.TRUE); + } + + @GET + @Path("/completedFutureBoolean") + public CompletableFuture completedFutureBoolean() { + return CompletableFuture.completedFuture(Boolean.TRUE); + } + + @GET + @Path("/listBoolean") + public List listBoolean() { + return Arrays.asList(new Boolean[] { Boolean.TRUE }); + } + + @POST + @Path("/listBoolean") + public List listBoolean(List body) { + return body; + } + + @GET + @Path("/arrayBoolean") + public Boolean[] arrayBoolean() { + return new Boolean[] { Boolean.TRUE }; + } + + @POST + @Path("/arrayBoolean") + public Boolean[] arrayBoolean(Boolean[] body) { + return body; + } + + @GET + @Path("/arrayBool") + public boolean[] arrayBool() { + return new boolean[] { true }; + } + + @POST + @Path("/arrayBool") + public boolean[] arrayBool(boolean[] body) { + return body; + } + + @GET + @Path("/mapBoolean") + public Map mapBoolean() { + Map m = new HashMap<>(); + m.put(true, true); + return m; + } + + @POST + @Path("/mapBoolean") + public Map mapBoolean(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ByteArrayResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ByteArrayResource.java new file mode 100644 index 0000000000000..065f682d808fd --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ByteArrayResource.java @@ -0,0 +1,84 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class ByteArrayResource { + @GET + @Path("/justByteArray/{fileName}") + public byte[] justByteArray(@PathParam("fileName") String filename) { + return toByteArray(filename); + } + + @POST + @Path("/justByteArray") + public byte[] justByteArray(byte[] bs) { + return bs; + } + + @GET + @Path("/restResponseByteArray/{fileName}") + public RestResponse restResponseByteArray(@PathParam("fileName") String filename) { + return RestResponse.ok(toByteArray(filename)); + } + + @POST + @Path("/restResponseByteArray") + public RestResponse restResponseByteArray(byte[] bs) { + return RestResponse.ok(bs); + } + + @GET + @Path("/optionalByteArray/{fileName}") + public Optional optionalByteArray(@PathParam("fileName") String filename) { + return Optional.of(toByteArray(filename)); + } + + @POST + @Path("/optionalByteArray") + public Optional optionalByteArray(Optional inputStream) { + return inputStream; + } + + @GET + @Path("/uniByteArray/{fileName}") + public Uni uniByteArray(@PathParam("fileName") String filename) { + return Uni.createFrom().item(toByteArray(filename)); + } + + @GET + @Path("/completionStageByteArray/{fileName}") + public CompletionStage completionStageByteArray(@PathParam("fileName") String filename) { + return CompletableFuture.completedStage(toByteArray(filename)); + } + + @GET + @Path("/completedFutureByteArray/{fileName}") + public CompletableFuture completedFutureByteArray(@PathParam("fileName") String filename) { + return CompletableFuture.completedFuture(toByteArray(filename)); + } + + private byte[] toByteArray(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return Files.readAllBytes(Paths.get(f)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/FileResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/FileResource.java new file mode 100644 index 0000000000000..9dc4c40567769 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/FileResource.java @@ -0,0 +1,83 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class FileResource { + @GET + @Path("/justFile/{fileName}") + public File justFile(@PathParam("fileName") String filename) { + return toFile(filename); + } + + @POST + @Path("/justFile") + public File justFile(File file) { + return file; + } + + @GET + @Path("/restResponseFile/{fileName}") + public RestResponse restResponseFile(@PathParam("fileName") String filename) { + return RestResponse.ok(toFile(filename)); + } + + @POST + @Path("/restResponseFile") + public RestResponse restResponseFile(File file) { + return RestResponse.ok(file); + } + + @GET + @Path("/optionalFile/{fileName}") + public Optional optionalFile(@PathParam("fileName") String filename) { + return Optional.of(toFile(filename)); + } + + @POST + @Path("/optionalFile") + public Optional optionalFile(Optional file) { + return file; + } + + @GET + @Path("/uniFile/{fileName}") + public Uni uniFile(@PathParam("fileName") String filename) { + return Uni.createFrom().item(toFile(filename)); + } + + @GET + @Path("/completionStageFile/{fileName}") + public CompletionStage completionStageFile(@PathParam("fileName") String filename) { + return CompletableFuture.completedStage(toFile(filename)); + } + + @GET + @Path("/completedFutureFile/{fileName}") + public CompletableFuture completedFutureFile(@PathParam("fileName") String filename) { + return CompletableFuture.completedFuture(toFile(filename)); + } + + private File toFile(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return new File(f); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/InputStreamResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/InputStreamResource.java new file mode 100644 index 0000000000000..d609f152f555c --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/InputStreamResource.java @@ -0,0 +1,85 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class InputStreamResource { + @GET + @Path("/justInputStream/{fileName}") + public InputStream justInputStream(@PathParam("fileName") String filename) { + return toInputStream(filename); + } + + @POST + @Path("/justInputStream") + public InputStream justInputStream(InputStream inputStream) { + return inputStream; + } + + @GET + @Path("/restResponseInputStream/{fileName}") + public RestResponse restResponseInputStream(@PathParam("fileName") String filename) { + return RestResponse.ok(toInputStream(filename)); + } + + @POST + @Path("/restResponseInputStream") + public RestResponse restResponseInputStream(InputStream inputStream) { + return RestResponse.ok(inputStream); + } + + @GET + @Path("/optionalInputStream/{fileName}") + public Optional optionalInputStream(@PathParam("fileName") String filename) { + return Optional.of(toInputStream(filename)); + } + + @POST + @Path("/optionalInputStream") + public Optional optionalInputStream(Optional inputStream) { + return inputStream; + } + + @GET + @Path("/uniInputStream/{fileName}") + public Uni uniInputStream(@PathParam("fileName") String filename) { + return Uni.createFrom().item(toInputStream(filename)); + } + + @GET + @Path("/completionStageInputStream/{fileName}") + public CompletionStage completionStageInputStream(@PathParam("fileName") String filename) { + return CompletableFuture.completedStage(toInputStream(filename)); + } + + @GET + @Path("/completedFutureInputStream/{fileName}") + public CompletableFuture completedFutureInputStream(@PathParam("fileName") String filename) { + return CompletableFuture.completedFuture(toInputStream(filename)); + } + + private InputStream toInputStream(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return Files.newInputStream(Paths.get(f)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/IntegerResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/IntegerResource.java new file mode 100644 index 0000000000000..0187610d2e17c --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/IntegerResource.java @@ -0,0 +1,149 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class IntegerResource { + @GET + @Path("/justInteger") + public Integer justInteger() { + return 0; + } + + @POST + @Path("/justInteger") + public Integer justInteger(Integer body) { + return body; + } + + @GET + @Path("/justInt") + public int justInt() { + return 0; + } + + @POST + @Path("/justInt") + public int justInt(int body) { + return body; + } + + @GET + @Path("/restResponseInteger") + public RestResponse restResponseInteger() { + return RestResponse.ok(0); + } + + @POST + @Path("/restResponseInteger") + public RestResponse restResponseInteger(Integer body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalInteger") + public Optional optionalInteger() { + return Optional.of(0); + } + + @POST + @Path("/optionalInteger") + public Optional optionalInteger(Optional body) { + return body; + } + + @GET + @Path("/optionalInt") + public OptionalInt optionalInt() { + return OptionalInt.of(0); + } + + @POST + @Path("/optionalInt") + public OptionalInt optionalInt(OptionalInt body) { + return body; + } + + @GET + @Path("/uniInteger") + public Uni uniInteger() { + return Uni.createFrom().item(0); + } + + @GET + @Path("/completionStageInteger") + public CompletionStage completionStageInteger() { + return CompletableFuture.completedStage(0); + } + + @GET + @Path("/completedFutureInteger") + public CompletableFuture completedFutureInteger() { + return CompletableFuture.completedFuture(0); + } + + @GET + @Path("/listInteger") + public List listInteger() { + return Arrays.asList(new Integer[] { 0 }); + } + + @POST + @Path("/listInteger") + public List listInteger(List body) { + return body; + } + + @GET + @Path("/arrayInteger") + public Integer[] arrayInteger() { + return new Integer[] { 0 }; + } + + @POST + @Path("/arrayInteger") + public Integer[] arrayInteger(Integer[] body) { + return body; + } + + @GET + @Path("/arrayInt") + public int[] arrayInt() { + return new int[] { 0 }; + } + + @POST + @Path("/arrayInt") + public int[] arrayInt(int[] body) { + return body; + } + + @GET + @Path("/mapInteger") + public Map mapInteger() { + Map m = new HashMap<>(); + m.put(0, 0); + return m; + } + + @POST + @Path("/mapInteger") + public Map mapInteger(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/LongResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/LongResource.java new file mode 100644 index 0000000000000..ee5501f6dd647 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/LongResource.java @@ -0,0 +1,149 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class LongResource { + @GET + @Path("/justLong") + public Long justLong() { + return 0L; + } + + @POST + @Path("/justLong") + public Long justLong(Long body) { + return body; + } + + @GET + @Path("/justPrimitiveLong") + public long justPrimitiveLong() { + return 0L; + } + + @POST + @Path("/justPrimitiveLong") + public long justPrimitiveLong(long body) { + return body; + } + + @GET + @Path("/restResponseLong") + public RestResponse restResponseLong() { + return RestResponse.ok(0L); + } + + @POST + @Path("/restResponseLong") + public RestResponse restResponseLong(Long body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalLong") + public Optional optionalLong() { + return Optional.of(0L); + } + + @POST + @Path("/optionalLong") + public Optional optionalLong(Optional body) { + return body; + } + + @GET + @Path("/optionalPrimitiveLong") + public OptionalLong optionalPrimitiveLong() { + return OptionalLong.of(0L); + } + + @POST + @Path("/optionalPrimitiveLong") + public OptionalLong optionalPrimitiveLong(OptionalLong body) { + return body; + } + + @GET + @Path("/uniLong") + public Uni uniLong() { + return Uni.createFrom().item(0L); + } + + @GET + @Path("/completionStageLong") + public CompletionStage completionStageLong() { + return CompletableFuture.completedStage(0L); + } + + @GET + @Path("/completedFutureLong") + public CompletableFuture completedFutureLong() { + return CompletableFuture.completedFuture(0L); + } + + @GET + @Path("/listLong") + public List listLong() { + return Arrays.asList(new Long[] { 0L }); + } + + @POST + @Path("/listLong") + public List listLong(List body) { + return body; + } + + @GET + @Path("/arrayLong") + public Long[] arrayLong() { + return new Long[] { 0L }; + } + + @POST + @Path("/arrayLong") + public Long[] arrayLong(Long[] body) { + return body; + } + + @GET + @Path("/arrayPrimitiveLong") + public long[] arrayPrimitiveLong() { + return new long[] { 0L }; + } + + @POST + @Path("/arrayPrimitiveLong") + public long[] arrayPrimitiveLong(long[] body) { + return body; + } + + @GET + @Path("/mapLong") + public Map mapLong() { + Map m = new HashMap<>(); + m.put(0L, 0L); + return m; + } + + @POST + @Path("/mapLong") + public Map mapLong(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/PojoResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/PojoResource.java new file mode 100644 index 0000000000000..d325122a7ad79 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/PojoResource.java @@ -0,0 +1,115 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.quarkus.it.openapi.Greeting; +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class PojoResource { + + @GET + @Path("/justPojo") + public Greeting justPojo() { + return new Greeting(0, "justPojo"); + } + + @POST + @Path("/justPojo") + public Greeting justPojo(Greeting greeting) { + return greeting; + } + + @GET + @Path("/restResponsePojo") + public RestResponse restResponsePojo() { + return RestResponse.ok(new Greeting(0, "restResponsePojo")); + } + + @POST + @Path("/restResponsePojo") + public RestResponse restResponsePojo(Greeting greeting) { + return RestResponse.ok(greeting); + } + + @GET + @Path("/optionalPojo") + public Optional optionalPojo() { + return Optional.of(new Greeting(0, "optionalPojo")); + } + + @POST + @Path("/optionalPojo") + public Optional optionalPojo(Optional greeting) { + return greeting; + } + + @GET + @Path("/uniPojo") + public Uni uniPojo() { + return Uni.createFrom().item(new Greeting(0, "uniPojo")); + } + + @GET + @Path("/completionStagePojo") + public CompletionStage completionStagePojo() { + return CompletableFuture.completedStage(new Greeting(0, "completionStagePojo")); + } + + @GET + @Path("/completedFuturePojo") + public CompletableFuture completedFuturePojo() { + return CompletableFuture.completedFuture(new Greeting(0, "completedFuturePojo")); + } + + @GET + @Path("/listPojo") + public List listPojo() { + return Arrays.asList(new Greeting[] { new Greeting(0, "listPojo") }); + } + + @POST + @Path("/listPojo") + public List listPojo(List greeting) { + return greeting; + } + + @GET + @Path("/arrayPojo") + public Greeting[] arrayPojo() { + return new Greeting[] { new Greeting(0, "arrayPojo") }; + } + + @POST + @Path("/arrayPojo") + public Greeting[] arrayPojo(Greeting[] greeting) { + return greeting; + } + + @GET + @Path("/mapPojo") + public Map mapPojo() { + Map m = new HashMap<>(); + Greeting g = new Greeting(0, "mapPojo"); + m.put("mapPojo", g); + return m; + } + + @POST + @Path("/mapPojo") + public Map mapPojo(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ReaderResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ReaderResource.java new file mode 100644 index 0000000000000..0ccfc743b0247 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ReaderResource.java @@ -0,0 +1,85 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; +import java.io.Reader; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class ReaderResource { + @GET + @Path("/justReader/{fileName}") + public Reader justReader(@PathParam("fileName") String filename) { + return toReader(filename); + } + + @POST + @Path("/justReader") + public Reader justReader(Reader inputStream) { + return inputStream; + } + + @GET + @Path("/restResponseReader/{fileName}") + public RestResponse restResponseReader(@PathParam("fileName") String filename) { + return RestResponse.ok(toReader(filename)); + } + + @POST + @Path("/restResponseReader") + public RestResponse restResponseReader(Reader inputStream) { + return RestResponse.ok(inputStream); + } + + @GET + @Path("/optionalReader/{fileName}") + public Optional optionalReader(@PathParam("fileName") String filename) { + return Optional.of(toReader(filename)); + } + + @POST + @Path("/optionalReader") + public Optional optionalReader(Optional inputStream) { + return inputStream; + } + + @GET + @Path("/uniReader/{fileName}") + public Uni uniReader(@PathParam("fileName") String filename) { + return Uni.createFrom().item(toReader(filename)); + } + + @GET + @Path("/completionStageReader/{fileName}") + public CompletionStage completionStageReader(@PathParam("fileName") String filename) { + return CompletableFuture.completedStage(toReader(filename)); + } + + @GET + @Path("/completedFutureReader/{fileName}") + public CompletableFuture completedFutureReader(@PathParam("fileName") String filename) { + return CompletableFuture.completedFuture(toReader(filename)); + } + + private Reader toReader(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return Files.newBufferedReader(Paths.get(f)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ShortResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ShortResource.java new file mode 100644 index 0000000000000..098683380ac01 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/ShortResource.java @@ -0,0 +1,136 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class ShortResource { + @GET + @Path("/justShort") + public Short justShort() { + return 0; + } + + @POST + @Path("/justShort") + public Short justShort(Short body) { + return body; + } + + @GET + @Path("/justPrimitiveShort") + public short justPrimitiveShort() { + return 0; + } + + @POST + @Path("/justPrimitiveShort") + public int justPrimitiveShort(int body) { + return body; + } + + @GET + @Path("/restResponseShort") + public RestResponse restResponseShort() { + return RestResponse.ok((short) 0); + } + + @POST + @Path("/restResponseShort") + public RestResponse restResponseShort(Short body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalShort") + public Optional optionalShort() { + return Optional.of((short) 0); + } + + @POST + @Path("/optionalShort") + public Optional optionalShort(Optional body) { + return body; + } + + @GET + @Path("/uniShort") + public Uni uniShort() { + return Uni.createFrom().item((short) 0); + } + + @GET + @Path("/completionStageShort") + public CompletionStage completionStageShort() { + return CompletableFuture.completedStage((short) 0); + } + + @GET + @Path("/completedFutureShort") + public CompletableFuture completedFutureShort() { + return CompletableFuture.completedFuture((short) 0); + } + + @GET + @Path("/listShort") + public List listShort() { + return Arrays.asList(new Short[] { 0 }); + } + + @POST + @Path("/listShort") + public List listShort(List body) { + return body; + } + + @GET + @Path("/arrayShort") + public Short[] arrayShort() { + return new Short[] { (short) 0 }; + } + + @POST + @Path("/arrayShort") + public Short[] arrayShort(Short[] body) { + return body; + } + + @GET + @Path("/arrayPrimitiveShort") + public short[] arrayPrimitiveShort() { + return new short[] { (short) 0 }; + } + + @POST + @Path("/arrayPrimitiveShort") + public short[] arrayPrimitiveShort(short[] body) { + return body; + } + + @GET + @Path("/mapShort") + public Map mapShort() { + Map m = new HashMap<>(); + m.put((short) 0, (short) 0); + return m; + } + + @POST + @Path("/mapShort") + public Map mapShort(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/StringResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/StringResource.java new file mode 100644 index 0000000000000..1b3bb05320f55 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/StringResource.java @@ -0,0 +1,113 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class StringResource { + + @GET + @Path("/justString") + public String justString() { + return "justString"; + } + + @POST + @Path("/justString") + public String justString(String body) { + return body; + } + + @GET + @Path("/restResponseString") + public RestResponse restResponseString() { + return RestResponse.ok("restResponseString"); + } + + @POST + @Path("/restResponseString") + public RestResponse restResponseString(String body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalString") + public Optional optionalString() { + return Optional.of("optionalString"); + } + + @POST + @Path("/optionalString") + public Optional optionalString(Optional body) { + return body; + } + + @GET + @Path("/uniString") + public Uni uniString() { + return Uni.createFrom().item("uniString"); + } + + @GET + @Path("/completionStageString") + public CompletionStage completionStageString() { + return CompletableFuture.completedStage("completionStageString"); + } + + @GET + @Path("/completedFutureString") + public CompletableFuture completedFutureString() { + return CompletableFuture.completedFuture("completedFutureString"); + } + + @GET + @Path("/listString") + public List listString() { + return Arrays.asList(new String[] { "listString" }); + } + + @POST + @Path("/listString") + public List listString(List body) { + return body; + } + + @GET + @Path("/arrayString") + public String[] arrayString() { + return new String[] { "arrayString" }; + } + + @POST + @Path("/arrayString") + public String[] arrayString(String[] body) { + return body; + } + + @GET + @Path("/mapString") + public Map mapString() { + Map m = new HashMap<>(); + m.put("mapString", "mapString"); + return m; + } + + @POST + @Path("/mapString") + public Map mapString(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/URLResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/URLResource.java new file mode 100644 index 0000000000000..ff852a26c51bd --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/jaxrs/URLResource.java @@ -0,0 +1,123 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; + +import org.jboss.resteasy.reactive.RestResponse; + +import io.smallrye.mutiny.Uni; + +@Path("/jax-rs/defaultContentType") +public class URLResource { + + @GET + @Path("/justURL") + public URL justURL() { + return url(); + } + + @POST + @Path("/justURL") + public URL justURL(URL url) { + return url; + } + + @GET + @Path("/restResponseURL") + public RestResponse restResponseURL() { + return RestResponse.ok(url()); + } + + @POST + @Path("/restResponseURL") + public RestResponse restResponseURL(URL body) { + return RestResponse.ok(body); + } + + @GET + @Path("/optionalURL") + public Optional optionalURL() { + return Optional.of(url()); + } + + @POST + @Path("/optionalURL") + public Optional optionalURL(Optional body) { + return body; + } + + @GET + @Path("/uniURL") + public Uni uniURL() { + return Uni.createFrom().item(url()); + } + + @GET + @Path("/completionStageURL") + public CompletionStage completionStageURL() { + return CompletableFuture.completedStage(url()); + } + + @GET + @Path("/completedFutureURL") + public CompletableFuture completedFutureURL() { + return CompletableFuture.completedFuture(url()); + } + + @GET + @Path("/listURL") + public List listURL() { + return Arrays.asList(new URL[] { url() }); + } + + @POST + @Path("/listURL") + public List listURL(List body) { + return body; + } + + @GET + @Path("/arrayURL") + public URL[] arrayURL() { + return new URL[] { url() }; + } + + @POST + @Path("/arrayURL") + public URL[] arrayURL(URL[] body) { + return body; + } + + @GET + @Path("/mapURL") + public Map mapURL() { + Map m = new HashMap<>(); + m.put("mapURL", url()); + return m; + } + + @POST + @Path("/mapURL") + public Map mapURL(Map body) { + return body; + } + + private URL url() { + try { + return new URL("https://quarkus.io/"); + } catch (MalformedURLException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigDecimalResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigDecimalResource.java new file mode 100644 index 0000000000000..7263e47e60e3d --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigDecimalResource.java @@ -0,0 +1,86 @@ +package io.quarkus.it.openapi.spring; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class BigDecimalResource { + @GetMapping("/justBigDecimal") + public BigDecimal justBigDecimal() { + return new BigDecimal("0"); + } + + @PostMapping("/justBigDecimal") + public BigDecimal justBigDecimal(BigDecimal body) { + return body; + } + + @GetMapping("/responseEntityBigDecimal") + public ResponseEntity responseEntityBigDecimal() { + return ResponseEntity.ok(new BigDecimal("0")); + } + + @PostMapping("/responseEntityBigDecimal") + public ResponseEntity responseEntityBigDecimal(BigDecimal body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalBigDecimal") + public Optional optionalBigDecimal() { + return Optional.of(new BigDecimal("0")); + } + + @PostMapping("/optionalBigDecimal") + public Optional optionalBigDecimal(Optional body) { + return body; + } + + @GetMapping("/uniBigDecimal") + public Uni uniBigDecimal() { + return Uni.createFrom().item(new BigDecimal("0")); + } + + @GetMapping("/completionStageBigDecimal") + public CompletionStage completionStageBigDecimal() { + return CompletableFuture.completedStage(new BigDecimal("0")); + } + + @GetMapping("/completedFutureBigDecimal") + public CompletableFuture completedFutureBigDecimal() { + return CompletableFuture.completedFuture(new BigDecimal("0")); + } + + @GetMapping("/listBigDecimal") + public List listBigDecimal() { + return Arrays.asList(new BigDecimal[] { new BigDecimal("0") }); + } + + @PostMapping("/listBigDecimal") + public List listBigDecimal(List body) { + return body; + } + + @GetMapping("/arrayBigDecimal") + public BigDecimal[] arrayBigDecimal() { + return new BigDecimal[] { new BigDecimal("0") }; + } + + @PostMapping("/arrayBigDecimal") + public BigDecimal[] arrayBigDecimal(BigDecimal[] body) { + return body; + } + +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigIntegerResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigIntegerResource.java new file mode 100644 index 0000000000000..b35860e51beab --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BigIntegerResource.java @@ -0,0 +1,86 @@ +package io.quarkus.it.openapi.spring; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class BigIntegerResource { + @GetMapping("/justBigInteger") + public BigInteger justBigInteger() { + return new BigInteger("0"); + } + + @PostMapping("/justBigInteger") + public BigInteger justBigInteger(BigInteger body) { + return body; + } + + @GetMapping("/responseEntityBigInteger") + public ResponseEntity responseEntityBigInteger() { + return ResponseEntity.ok(new BigInteger("0")); + } + + @PostMapping("/responseEntityBigInteger") + public ResponseEntity responseEntityBigInteger(BigInteger body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalBigInteger") + public Optional optionalBigInteger() { + return Optional.of(new BigInteger("0")); + } + + @PostMapping("/optionalBigInteger") + public Optional optionalBigInteger(Optional body) { + return body; + } + + @GetMapping("/uniBigInteger") + public Uni uniBigInteger() { + return Uni.createFrom().item(new BigInteger("0")); + } + + @GetMapping("/completionStageBigInteger") + public CompletionStage completionStageBigInteger() { + return CompletableFuture.completedStage(new BigInteger("0")); + } + + @GetMapping("/completedFutureBigInteger") + public CompletableFuture completedFutureBigInteger() { + return CompletableFuture.completedFuture(new BigInteger("0")); + } + + @GetMapping("/listBigInteger") + public List listBigInteger() { + return Arrays.asList(new BigInteger[] { new BigInteger("0") }); + } + + @PostMapping("/listBigInteger") + public List listBigInteger(List body) { + return body; + } + + @GetMapping("/arrayBigInteger") + public BigInteger[] arrayBigInteger() { + return new BigInteger[] { new BigInteger("0") }; + } + + @PostMapping("/arrayBigInteger") + public BigInteger[] arrayBigInteger(BigInteger[] body) { + return body; + } + +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BooleanResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BooleanResource.java new file mode 100644 index 0000000000000..e080de6bd9af0 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/BooleanResource.java @@ -0,0 +1,119 @@ +package io.quarkus.it.openapi.spring; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class BooleanResource { + + @GetMapping("/justBoolean") + public Boolean justBoolean() { + return Boolean.TRUE; + } + + @PostMapping("/justBoolean") + public Boolean justBoolean(Boolean body) { + return body; + } + + @GetMapping("/justBool") + public boolean justBool() { + return true; + } + + @PostMapping("/justBool") + public boolean justBool(boolean body) { + return body; + } + + @GetMapping("/responseEntityBoolean") + public ResponseEntity responseEntityBoolean() { + return ResponseEntity.ok(Boolean.TRUE); + } + + @PostMapping("/responseEntityBoolean") + public ResponseEntity responseEntityBoolean(Boolean body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalBoolean") + public Optional optionalBoolean() { + return Optional.of(Boolean.TRUE); + } + + @PostMapping("/optionalBoolean") + public Optional optionalBoolean(Optional body) { + return body; + } + + @GetMapping("/uniBoolean") + public Uni uniBoolean() { + return Uni.createFrom().item(Boolean.TRUE); + } + + @GetMapping("/completionStageBoolean") + public CompletionStage completionStageBoolean() { + return CompletableFuture.completedStage(Boolean.TRUE); + } + + @GetMapping("/completedFutureBoolean") + public CompletableFuture completedFutureBoolean() { + return CompletableFuture.completedFuture(Boolean.TRUE); + } + + @GetMapping("/listBoolean") + public List listBoolean() { + return Arrays.asList(new Boolean[] { Boolean.TRUE }); + } + + @PostMapping("/listBoolean") + public List listBoolean(List body) { + return body; + } + + @GetMapping("/arrayBoolean") + public Boolean[] arrayBoolean() { + return new Boolean[] { Boolean.TRUE }; + } + + @PostMapping("/arrayBoolean") + public Boolean[] arrayBoolean(Boolean[] body) { + return body; + } + + @GetMapping("/arrayBool") + public boolean[] arrayBool() { + return new boolean[] { true }; + } + + @PostMapping("/arrayBool") + public boolean[] arrayBool(boolean[] body) { + return body; + } + + @GetMapping("/mapBoolean") + public Map mapBoolean() { + Map m = new HashMap<>(); + m.put(true, true); + return m; + } + + @PostMapping("/mapBoolean") + public Map mapBoolean(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ByteArrayResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ByteArrayResource.java new file mode 100644 index 0000000000000..5a52f09c4dea2 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ByteArrayResource.java @@ -0,0 +1,76 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class ByteArrayResource { + @GetMapping("/justByteArray/{fileName}") + public byte[] justByteArray(@PathVariable("fileName") String filename) { + return toByteArray(filename); + } + + @PostMapping("/justByteArray") + public byte[] justByteArray(byte[] inputStream) { + return inputStream; + } + + @GetMapping("/responseEntityByteArray/{fileName}") + public ResponseEntity responseEntityByteArray(@PathVariable("fileName") String filename) { + return ResponseEntity.ok(toByteArray(filename)); + } + + @PostMapping("/responseEntityByteArray") + public ResponseEntity responseEntityByteArray(byte[] inputStream) { + return ResponseEntity.ok(inputStream); + } + + @GetMapping("/optionalByteArray/{fileName}") + public Optional optionalByteArray(@PathVariable("fileName") String filename) { + return Optional.of(toByteArray(filename)); + } + + @PostMapping("/optionalByteArray") + public Optional optionalByteArray(Optional inputStream) { + return inputStream; + } + + @GetMapping("/uniByteArray/{fileName}") + public Uni uniByteArray(@PathVariable("fileName") String filename) { + return Uni.createFrom().item(toByteArray(filename)); + } + + @GetMapping("/completionStageByteArray/{fileName}") + public CompletionStage completionStageByteArray(@PathVariable("fileName") String filename) { + return CompletableFuture.completedStage(toByteArray(filename)); + } + + @GetMapping("/completedFutureByteArray/{fileName}") + public CompletableFuture completedFutureByteArray(@PathVariable("fileName") String filename) { + return CompletableFuture.completedFuture(toByteArray(filename)); + } + + private byte[] toByteArray(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return Files.readAllBytes(Paths.get(f)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/FileResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/FileResource.java new file mode 100644 index 0000000000000..538ac8585476c --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/FileResource.java @@ -0,0 +1,75 @@ +package io.quarkus.it.openapi.spring; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class FileResource { + @GetMapping("/justFile/{fileName}") + public File justFile(@PathVariable("fileName") String filename) { + return toFile(filename); + } + + @PostMapping("/justFile") + public File justFile(File file) { + return file; + } + + @GetMapping("/responseEntityFile/{fileName}") + public ResponseEntity restResponseFile(@PathVariable("fileName") String filename) { + return ResponseEntity.ok(toFile(filename)); + } + + @PostMapping("/responseEntityFile") + public ResponseEntity restResponseFile(File file) { + return ResponseEntity.ok(file); + } + + @GetMapping("/optionalFile/{fileName}") + public Optional optionalFile(@PathVariable("fileName") String filename) { + return Optional.of(toFile(filename)); + } + + @PostMapping("/optionalFile") + public Optional optionalFile(Optional file) { + return file; + } + + @GetMapping("/uniFile/{fileName}") + public Uni uniFile(@PathVariable("fileName") String filename) { + return Uni.createFrom().item(toFile(filename)); + } + + @GetMapping("/completionStageFile/{fileName}") + public CompletionStage completionStageFile(@PathVariable("fileName") String filename) { + return CompletableFuture.completedStage(toFile(filename)); + } + + @GetMapping("/completedFutureFile/{fileName}") + public CompletableFuture completedFutureFile(@PathVariable("fileName") String filename) { + return CompletableFuture.completedFuture(toFile(filename)); + } + + private File toFile(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return new File(f); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/InputStreamResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/InputStreamResource.java new file mode 100644 index 0000000000000..1fd68155ac2ac --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/InputStreamResource.java @@ -0,0 +1,77 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class InputStreamResource { + @GetMapping("/justInputStream/{fileName}") + public InputStream justInputStream(@PathVariable("fileName") String filename) { + return toInputStream(filename); + } + + @PostMapping("/justInputStream") + public InputStream justInputStream(InputStream file) { + return file; + } + + @GetMapping("/responseEntityInputStream/{fileName}") + public ResponseEntity restResponseInputStream(@PathVariable("fileName") String filename) { + return ResponseEntity.ok(toInputStream(filename)); + } + + @PostMapping("/responseEntityInputStream") + public ResponseEntity restResponseInputStream(InputStream file) { + return ResponseEntity.ok(file); + } + + @GetMapping("/optionalInputStream/{fileName}") + public Optional optionalInputStream(@PathVariable("fileName") String filename) { + return Optional.of(toInputStream(filename)); + } + + @PostMapping("/optionalInputStream") + public Optional optionalInputStream(Optional file) { + return file; + } + + @GetMapping("/uniInputStream/{fileName}") + public Uni uniInputStream(@PathVariable("fileName") String filename) { + return Uni.createFrom().item(toInputStream(filename)); + } + + @GetMapping("/completionStageInputStream/{fileName}") + public CompletionStage completionStageInputStream(@PathVariable("fileName") String filename) { + return CompletableFuture.completedStage(toInputStream(filename)); + } + + @GetMapping("/completedFutureInputStream/{fileName}") + public CompletableFuture completedFutureInputStream(@PathVariable("fileName") String filename) { + return CompletableFuture.completedFuture(toInputStream(filename)); + } + + private InputStream toInputStream(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return Files.newInputStream(Paths.get(f)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/IntegerResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/IntegerResource.java new file mode 100644 index 0000000000000..97520ab8553a6 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/IntegerResource.java @@ -0,0 +1,130 @@ +package io.quarkus.it.openapi.spring; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class IntegerResource { + + @GetMapping("/justInteger") + public Integer justInteger() { + return 0; + } + + @PostMapping("/justInteger") + public Integer justInteger(Integer body) { + return body; + } + + @GetMapping("/justInt") + public int justInt() { + return 0; + } + + @PostMapping("/justInt") + public int justInt(int body) { + return body; + } + + @GetMapping("/responseEntityInteger") + public ResponseEntity responseEntityInteger() { + return ResponseEntity.ok(0); + } + + @PostMapping("/responseEntityInteger") + public ResponseEntity responseEntityInteger(Integer body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalInteger") + public Optional optionalInteger() { + return Optional.of(0); + } + + @PostMapping("/optionalInteger") + public Optional optionalInteger(Optional body) { + return body; + } + + @GetMapping("/optionalInt") + public OptionalInt optionalInt() { + return OptionalInt.of(0); + } + + @PostMapping("/optionalInt") + public OptionalInt optionalInt(OptionalInt body) { + return body; + } + + @GetMapping("/uniInteger") + public Uni uniInteger() { + return Uni.createFrom().item(0); + } + + @GetMapping("/completionStageInteger") + public CompletionStage completionStageInteger() { + return CompletableFuture.completedStage(0); + } + + @GetMapping("/completedFutureInteger") + public CompletableFuture completedFutureInteger() { + return CompletableFuture.completedFuture(0); + } + + @GetMapping("/listInteger") + public List listInteger() { + return Arrays.asList(new Integer[] { 0 }); + } + + @PostMapping("/listInteger") + public List listInteger(List body) { + return body; + } + + @GetMapping("/arrayInteger") + public Integer[] arrayInteger() { + return new Integer[] { 0 }; + } + + @PostMapping("/arrayInteger") + public Integer[] arrayInteger(Integer[] body) { + return body; + } + + @GetMapping("/arrayInt") + public int[] arrayInt() { + return new int[] { 0 }; + } + + @PostMapping("/arrayInt") + public int[] arrayInt(int[] body) { + return body; + } + + @GetMapping("/mapInteger") + public Map mapInteger() { + Map m = new HashMap<>(); + m.put(0, 0); + return m; + } + + @PostMapping("/mapInteger") + public Map mapInteger(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/LongResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/LongResource.java new file mode 100644 index 0000000000000..8dc69c8763532 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/LongResource.java @@ -0,0 +1,130 @@ +package io.quarkus.it.openapi.spring; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class LongResource { + + @GetMapping("/justLong") + public Long justLong() { + return 0L; + } + + @PostMapping("/justLong") + public Long justLong(Long body) { + return body; + } + + @GetMapping("/justPrimitiveLong") + public long justPrimitiveLong() { + return 0L; + } + + @PostMapping("/justPrimitiveLong") + public long justPrimitiveLong(long body) { + return body; + } + + @GetMapping("/responseEntityLong") + public ResponseEntity responseEntityLong() { + return ResponseEntity.ok(0L); + } + + @PostMapping("/responseEntityLong") + public ResponseEntity responseEntityLong(Long body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalLong") + public Optional optionalLong() { + return Optional.of(0L); + } + + @PostMapping("/optionalLong") + public Optional optionalLong(Optional body) { + return body; + } + + @GetMapping("/optionalPrimitiveLong") + public OptionalLong optionalPrimitiveLong() { + return OptionalLong.of(0L); + } + + @PostMapping("/optionalPrimitiveLong") + public OptionalLong optionalPrimitiveLong(OptionalLong body) { + return body; + } + + @GetMapping("/uniLong") + public Uni uniLong() { + return Uni.createFrom().item(0L); + } + + @GetMapping("/completionStageLong") + public CompletionStage completionStageLong() { + return CompletableFuture.completedStage(0L); + } + + @GetMapping("/completedFutureLong") + public CompletableFuture completedFutureLong() { + return CompletableFuture.completedFuture(0L); + } + + @GetMapping("/listLong") + public List listLong() { + return Arrays.asList(new Long[] { 0L }); + } + + @PostMapping("/listLong") + public List listLong(List body) { + return body; + } + + @GetMapping("/arrayLong") + public Long[] arrayLong() { + return new Long[] { 0L }; + } + + @PostMapping("/arrayLong") + public Long[] arrayLong(Long[] body) { + return body; + } + + @GetMapping("/arrayPrimitiveLong") + public long[] arrayPrimitiveLong() { + return new long[] { 0L }; + } + + @PostMapping("/arrayPrimitiveLong") + public long[] arrayPrimitiveLong(long[] body) { + return body; + } + + @GetMapping("/mapLong") + public Map mapLong() { + Map m = new HashMap<>(); + m.put(0L, 0L); + return m; + } + + @PostMapping("/mapLong") + public Map mapLong(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/PojoResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/PojoResource.java new file mode 100644 index 0000000000000..61a400ce0ab15 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/PojoResource.java @@ -0,0 +1,101 @@ +package io.quarkus.it.openapi.spring; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.quarkus.it.openapi.Greeting; +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class PojoResource { + + @GetMapping("/justPojo") + public Greeting justPojo() { + return new Greeting(0, "justPojo"); + } + + @PostMapping("/justPojo") + public Greeting justPojo(Greeting greeting) { + return greeting; + } + + @GetMapping("/responseEntityPojo") + public ResponseEntity responseEntityPojo() { + return ResponseEntity.ok(new Greeting(0, "responseEntityPojo")); + } + + @PostMapping("/responseEntityPojo") + public ResponseEntity responseEntityPojo(Greeting greeting) { + return ResponseEntity.ok(greeting); + } + + @GetMapping("/optionalPojo") + public Optional optionalPojo() { + return Optional.of(new Greeting(0, "optionalPojo")); + } + + @PostMapping("/optionalPojo") + public Optional optionalPojo(Optional greeting) { + return greeting; + } + + @GetMapping("/uniPojo") + public Uni uniPojo() { + return Uni.createFrom().item(new Greeting(0, "uniPojo")); + } + + @GetMapping("/completionStagePojo") + public CompletionStage completionStagePojo() { + return CompletableFuture.completedStage(new Greeting(0, "completionStagePojo")); + } + + @GetMapping("/completedFuturePojo") + public CompletableFuture completedFuturePojo() { + return CompletableFuture.completedFuture(new Greeting(0, "completedFuturePojo")); + } + + @GetMapping("/listPojo") + public List listPojo() { + return Arrays.asList(new Greeting[] { new Greeting(0, "listPojo") }); + } + + @PostMapping("/listPojo") + public List listPojo(List greeting) { + return greeting; + } + + @GetMapping("/arrayPojo") + public Greeting[] arrayPojo() { + return new Greeting[] { new Greeting(0, "arrayPojo") }; + } + + @PostMapping("/arrayPojo") + public Greeting[] arrayPojo(Greeting[] greeting) { + return greeting; + } + + @GetMapping("/mapPojo") + public Map mapPojo() { + Map m = new HashMap<>(); + Greeting g = new Greeting(0, "mapPojo"); + m.put("mapPojo", g); + return m; + } + + @PostMapping("/mapPojo") + public Map mapPojo(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ReaderResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ReaderResource.java new file mode 100644 index 0000000000000..ccce8056f5940 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ReaderResource.java @@ -0,0 +1,77 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; +import java.io.Reader; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class ReaderResource { + @GetMapping("/justReader/{fileName}") + public Reader justReader(@PathVariable("fileName") String filename) { + return toReader(filename); + } + + @PostMapping("/justReader") + public Reader justReader(Reader file) { + return file; + } + + @GetMapping("/responseEntityReader/{fileName}") + public ResponseEntity restResponseReader(@PathVariable("fileName") String filename) { + return ResponseEntity.ok(toReader(filename)); + } + + @PostMapping("/responseEntityReader") + public ResponseEntity restResponseReader(Reader file) { + return ResponseEntity.ok(file); + } + + @GetMapping("/optionalReader/{fileName}") + public Optional optionalReader(@PathVariable("fileName") String filename) { + return Optional.of(toReader(filename)); + } + + @PostMapping("/optionalReader") + public Optional optionalReader(Optional file) { + return file; + } + + @GetMapping("/uniReader/{fileName}") + public Uni uniReader(@PathVariable("fileName") String filename) { + return Uni.createFrom().item(toReader(filename)); + } + + @GetMapping("/completionStageReader/{fileName}") + public CompletionStage completionStageReader(@PathVariable("fileName") String filename) { + return CompletableFuture.completedStage(toReader(filename)); + } + + @GetMapping("/completedFutureReader/{fileName}") + public CompletableFuture completedFutureReader(@PathVariable("fileName") String filename) { + return CompletableFuture.completedFuture(toReader(filename)); + } + + private Reader toReader(String filename) { + try { + String f = URLDecoder.decode(filename, "UTF-8"); + return Files.newBufferedReader(Paths.get(f)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ShortResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ShortResource.java new file mode 100644 index 0000000000000..103e4b4aa87d8 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/ShortResource.java @@ -0,0 +1,119 @@ +package io.quarkus.it.openapi.spring; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class ShortResource { + + @GetMapping("/justShort") + public Short justShort() { + return (short) 0; + } + + @PostMapping("/justShort") + public Short justShort(Short body) { + return body; + } + + @GetMapping("/justPrimitiveShort") + public short justPrimitiveShort() { + return (short) 0; + } + + @PostMapping("/justPrimitiveShort") + public short justPrimitiveShort(short body) { + return body; + } + + @GetMapping("/responseEntityShort") + public ResponseEntity responseEntityShort() { + return ResponseEntity.ok((short) 0); + } + + @PostMapping("/responseEntityShort") + public ResponseEntity responseEntityShort(Short body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalShort") + public Optional optionalShort() { + return Optional.of((short) 0); + } + + @PostMapping("/optionalShort") + public Optional optionalShort(Optional body) { + return body; + } + + @GetMapping("/uniShort") + public Uni uniShort() { + return Uni.createFrom().item((short) 0); + } + + @GetMapping("/completionStageShort") + public CompletionStage completionStageShort() { + return CompletableFuture.completedStage((short) 0); + } + + @GetMapping("/completedFutureShort") + public CompletableFuture completedFutureShort() { + return CompletableFuture.completedFuture((short) 0); + } + + @GetMapping("/listShort") + public List listShort() { + return Arrays.asList(new Short[] { (short) 0 }); + } + + @PostMapping("/listShort") + public List listShort(List body) { + return body; + } + + @GetMapping("/arrayShort") + public Short[] arrayShort() { + return new Short[] { (short) 0 }; + } + + @PostMapping("/arrayShort") + public Short[] arrayShort(Short[] body) { + return body; + } + + @GetMapping("/arrayPrimitiveShort") + public short[] arrayPrimitiveShort() { + return new short[] { (short) 0 }; + } + + @PostMapping("/arrayPrimitiveShort") + public short[] arrayPrimitiveShort(short[] body) { + return body; + } + + @GetMapping("/mapShort") + public Map mapShort() { + Map m = new HashMap<>(); + m.put((short) 0, (short) 0); + return m; + } + + @PostMapping("/mapShort") + public Map mapShort(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/StringResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/StringResource.java new file mode 100644 index 0000000000000..a8f68604b32c1 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/StringResource.java @@ -0,0 +1,100 @@ +package io.quarkus.it.openapi.spring; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class StringResource { + + @GetMapping("/justString") + public String justString() { + return "justString"; + } + + @PostMapping("/justString") + public String justString(@RequestBody String body) { + return body; + } + + @GetMapping("/responseEntityString") + public ResponseEntity responseEntityString() { + return ResponseEntity.ok("responseEntityString"); + } + + @PostMapping("/responseEntityString") + public ResponseEntity responseEntityString(@RequestBody String body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalString") + public Optional optionalString() { + return Optional.of("optionalString"); + } + + @PostMapping("/optionalString") + public Optional optionalString(@RequestBody Optional body) { + return body; + } + + @GetMapping("/uniString") + public Uni uniString() { + return Uni.createFrom().item("uniString"); + } + + @GetMapping("/completionStageString") + public CompletionStage completionStageString() { + return CompletableFuture.completedStage("completionStageString"); + } + + @GetMapping("/completedFutureString") + public CompletableFuture completedFutureString() { + return CompletableFuture.completedFuture("completedFutureString"); + } + + @GetMapping("/listString") + public List listString() { + return Arrays.asList(new String[] { "listString" }); + } + + @PostMapping("/listString") + public List listString(@RequestBody List body) { + return body; + } + + @GetMapping("/arrayString") + public String[] arrayString() { + return new String[] { "arrayString" }; + } + + @PostMapping("/arrayString") + public String[] arrayString(@RequestBody String[] body) { + return body; + } + + @GetMapping("/mapString") + public Map mapString() { + Map m = new HashMap<>(); + m.put("mapString", "mapString"); + return m; + } + + @PostMapping("/mapString") + public Map mapString(Map body) { + return body; + } +} diff --git a/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/URLResource.java b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/URLResource.java new file mode 100644 index 0000000000000..436ada590afe2 --- /dev/null +++ b/integration-tests/openapi/src/main/java/io/quarkus/it/openapi/spring/URLResource.java @@ -0,0 +1,109 @@ +package io.quarkus.it.openapi.spring; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.smallrye.mutiny.Uni; + +@RestController +@RequestMapping(value = "/spring/defaultContentType") +public class URLResource { + + @GetMapping("/justURL") + public URL justURL() { + return url(); + } + + @PostMapping("/justURL") + public URL justURL(URL url) { + return url; + } + + @GetMapping("/restResponseURL") + public ResponseEntity restResponseURL() { + return ResponseEntity.ok(url()); + } + + @PostMapping("/restResponseURL") + public ResponseEntity restResponseURL(URL body) { + return ResponseEntity.ok(body); + } + + @GetMapping("/optionalURL") + public Optional optionalURL() { + return Optional.of(url()); + } + + @PostMapping("/optionalURL") + public Optional optionalURL(Optional body) { + return body; + } + + @GetMapping("/uniURL") + public Uni uniURL() { + return Uni.createFrom().item(url()); + } + + @GetMapping("/completionStageURL") + public CompletionStage completionStageURL() { + return CompletableFuture.completedStage(url()); + } + + @GetMapping("/completedFutureURL") + public CompletableFuture completedFutureURL() { + return CompletableFuture.completedFuture(url()); + } + + @GetMapping("/listURL") + public List listURL() { + return Arrays.asList(new URL[] { url() }); + } + + @PostMapping("/listURL") + public List listURL(List body) { + return body; + } + + @GetMapping("/arrayURL") + public URL[] arrayURL() { + return new URL[] { url() }; + } + + @PostMapping("/arrayURL") + public URL[] arrayURL(URL[] body) { + return body; + } + + @GetMapping("/mapURL") + public Map mapURL() { + Map m = new HashMap<>(); + m.put("mapURL", url()); + return m; + } + + @PostMapping("/mapURL") + public Map mapURL(Map body) { + return body; + } + + private URL url() { + try { + return new URL("https://quarkus.io/"); + } catch (MalformedURLException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractByteArrayTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractByteArrayTest.java new file mode 100644 index 0000000000000..8fab3d07a34f4 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractByteArrayTest.java @@ -0,0 +1,59 @@ +package io.quarkus.it.openapi; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.file.Files; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; + +import io.restassured.RestAssured; + +public abstract class AbstractByteArrayTest extends AbstractTest { + protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; + + protected void testServiceByteArrayRequest(String path, String expectedContentType) throws IOException { + + byte[] b = Files.readAllBytes(tempFile().toPath()); + byte[] responseFile = RestAssured + .with().body(b) + .and() + .with().contentType(APPLICATION_OCTET_STREAM) + .when() + .post(path) + .then() + .header("Content-Type", Matchers.startsWith(APPLICATION_OCTET_STREAM)) + .extract().asByteArray(); + + Assertions.assertEquals(b.length, responseFile.length); + + } + + protected void testServiceByteArrayResponse(String path, String expectedResponseType) + throws UnsupportedEncodingException, IOException { + // Service + File f = tempFile(); + byte[] b = Files.readAllBytes(f.toPath()); + String filename = URLEncoder.encode(f.getAbsoluteFile().toString(), "UTF-8"); + byte[] responseFile = RestAssured + .when() + .get(path + "/" + filename) + .then() + .header("Content-Type", Matchers.startsWith(expectedResponseType)) + .and() + .extract().asByteArray(); + + Assertions.assertEquals(b.length, responseFile.length); + } + + private File tempFile() { + try { + java.nio.file.Path createTempFile = Files.createTempFile("", ""); + return createTempFile.toFile(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractFileTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractFileTest.java new file mode 100644 index 0000000000000..479f722c3e474 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractFileTest.java @@ -0,0 +1,58 @@ +package io.quarkus.it.openapi; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.file.Files; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; + +import io.restassured.RestAssured; + +public abstract class AbstractFileTest extends AbstractTest { + protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; + + protected void testServiceFileRequest(String path, String expectedContentType) throws IOException { + + File f = tempFile(); + byte[] responseFile = RestAssured + .with().body(f) + .and() + .with().contentType(APPLICATION_OCTET_STREAM) + .when() + .post(path) + .then() + .header("Content-Type", Matchers.startsWith(APPLICATION_OCTET_STREAM)) + .extract().asByteArray(); + + Assertions.assertEquals(Files.readAllBytes(f.toPath()).length, responseFile.length); + + } + + protected void testServiceFileResponse(String path, String expectedResponseType) + throws UnsupportedEncodingException, IOException { + // Service + File f = tempFile(); + String filename = URLEncoder.encode(f.getAbsoluteFile().toString(), "UTF-8"); + byte[] responseFile = RestAssured + .when() + .get(path + "/" + filename) + .then() + .header("Content-Type", Matchers.startsWith(expectedResponseType)) + .and() + .extract().asByteArray(); + + Assertions.assertEquals(Files.readAllBytes(f.toPath()).length, responseFile.length); + } + + private File tempFile() { + try { + java.nio.file.Path createTempFile = Files.createTempFile("", ""); + return createTempFile.toFile(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractInputStreamTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractInputStreamTest.java new file mode 100644 index 0000000000000..6c0aff9418141 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractInputStreamTest.java @@ -0,0 +1,58 @@ +package io.quarkus.it.openapi; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.file.Files; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; + +import io.restassured.RestAssured; + +public abstract class AbstractInputStreamTest extends AbstractTest { + protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; + + protected void testServiceInputStreamRequest(String path, String expectedContentType) throws IOException { + + File f = tempFile(); + byte[] responseFile = RestAssured + .with().body(f) + .and() + .with().contentType(APPLICATION_OCTET_STREAM) + .when() + .post(path) + .then() + .header("Content-Type", Matchers.startsWith(APPLICATION_OCTET_STREAM)) + .extract().asByteArray(); + + Assertions.assertEquals(Files.readAllBytes(f.toPath()).length, responseFile.length); + + } + + protected void testServiceInputStreamResponse(String path, String expectedResponseType) + throws UnsupportedEncodingException, IOException { + // Service + File f = tempFile(); + String filename = URLEncoder.encode(f.getAbsoluteFile().toString(), "UTF-8"); + byte[] responseFile = RestAssured + .when() + .get(path + "/" + filename) + .then() + .header("Content-Type", Matchers.startsWith(expectedResponseType)) + .and() + .extract().asByteArray(); + + Assertions.assertEquals(Files.readAllBytes(f.toPath()).length, responseFile.length); + } + + private File tempFile() { + try { + java.nio.file.Path createTempFile = Files.createTempFile("", ""); + return createTempFile.toFile(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractReaderTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractReaderTest.java new file mode 100644 index 0000000000000..a1cb6cce20c6d --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractReaderTest.java @@ -0,0 +1,58 @@ +package io.quarkus.it.openapi; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.file.Files; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; + +import io.restassured.RestAssured; + +public abstract class AbstractReaderTest extends AbstractTest { + protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; + + protected void testServiceReaderRequest(String path, String expectedContentType) throws IOException { + + File f = tempFile(); + byte[] responseFile = RestAssured + .with().body(f) + .and() + .with().contentType(APPLICATION_OCTET_STREAM) + .when() + .post(path) + .then() + .header("Content-Type", Matchers.startsWith(APPLICATION_OCTET_STREAM)) + .extract().asByteArray(); + + Assertions.assertEquals(Files.readAllBytes(f.toPath()).length, responseFile.length); + + } + + protected void testServiceReaderResponse(String path, String expectedResponseType) + throws UnsupportedEncodingException, IOException { + // Service + File f = tempFile(); + String filename = URLEncoder.encode(f.getAbsoluteFile().toString(), "UTF-8"); + byte[] responseFile = RestAssured + .when() + .get(path + "/" + filename) + .then() + .header("Content-Type", Matchers.startsWith(expectedResponseType)) + .and() + .extract().asByteArray(); + + Assertions.assertEquals(Files.readAllBytes(f.toPath()).length, responseFile.length); + } + + private File tempFile() { + try { + java.nio.file.Path createTempFile = Files.createTempFile("", ""); + return createTempFile.toFile(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractTest.java new file mode 100644 index 0000000000000..b158ea39250f6 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/AbstractTest.java @@ -0,0 +1,101 @@ +package io.quarkus.it.openapi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jakarta.inject.Inject; + +import org.hamcrest.Matchers; +import org.jboss.logging.Logger; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.restassured.RestAssured; + +public abstract class AbstractTest { + private static final Logger LOG = Logger.getLogger(AbstractTest.class); + private static final String OPEN_API_PATH = "/q/openapi"; + + protected static final String TEXT_PLAIN = "text/plain"; + protected static final String APPLICATION_JSON = "application/json"; + + @Inject + protected ObjectMapper om; + + protected void testServiceRequest(String path, String expectedContentType, String expectedValue) { + // Service + RestAssured + .with().body(expectedValue) + .and() + .with().contentType(expectedContentType) + .when() + .post(path) + .then() + .header("Content-Type", Matchers.startsWith(expectedContentType)) + .and() + .body(Matchers.equalTo(expectedValue)); + } + + protected void testServiceResponse(String path, String expectedResponseType, String expectedValue) { + // Service + RestAssured + .when() + .get(path) + .then() + .header("Content-Type", Matchers.startsWith(expectedResponseType)) + .and() + .body(Matchers.equalTo(expectedValue)); + } + + protected void testOpenAPIRequest(String path, String expectedRequestType) { + // OpenAPI + RestAssured.given().queryParam("format", "JSON") + .when().get(OPEN_API_PATH) + .then() + .header("Content-Type", "application/json;charset=UTF-8") + .body("paths.'" + path + "'.post.requestBody.content.'" + expectedRequestType + "'", + Matchers.notNullValue()); + } + + protected void testOpenAPIResponse(String path, String expectedResponseType) { + // OpenAPI + RestAssured.given().queryParam("format", "JSON") + .when().get(OPEN_API_PATH) + .then() + .header("Content-Type", "application/json;charset=UTF-8") + .body("paths.'" + path + "'.get.responses.'200'.content.'" + expectedResponseType + "'", + Matchers.notNullValue()); + } + + protected String createExpected(String message) { + try { + Greeting g = new Greeting(0, message); + return om.writeValueAsString(g); + } catch (JsonProcessingException ex) { + throw new RuntimeException(ex); + } + } + + protected String createExpectedList(String message) { + try { + List l = new ArrayList<>(); + l.add(new Greeting(0, message)); + return om.writeValueAsString(l); + } catch (JsonProcessingException ex) { + throw new RuntimeException(ex); + } + } + + protected String createExpectedMap(String message) { + try { + Map m = new HashMap<>(); + m.put(message, new Greeting(0, message)); + return om.writeValueAsString(m); + } catch (JsonProcessingException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigDecimalTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigDecimalTest.java new file mode 100644 index 0000000000000..cab2e6601fb47 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigDecimalTest.java @@ -0,0 +1,149 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class BigDecimalTest extends AbstractTest { + + // Just BigDecimal + @Test + public void testJustBigDecimalInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigDecimalInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justBigDecimal", TEXT_PLAIN); + } + + @Test + public void testJustBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justBigDecimal", TEXT_PLAIN); + } + + // RestResponse + @Test + public void testRestResponseBigDecimalInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigDecimalInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseBigDecimal", TEXT_PLAIN); + } + + @Test + public void testRestResponseBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseBigDecimal", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalBigDecimalInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalBigDecimal", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalBigDecimalInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalBigDecimal", TEXT_PLAIN); + } + + @Test + public void testOptionalBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalBigDecimal", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testUniBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniBigDecimal", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageBigDecimal", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageBigDecimal", TEXT_PLAIN); + } + + // List + @Test + public void testListBigDecimalInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigDecimalInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listBigDecimal", APPLICATION_JSON); + } + + @Test + public void testListBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listBigDecimal", APPLICATION_JSON); + } + + // BigDecimal[] + @Test + public void testArrayBigDecimalInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigDecimalInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigDecimalInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayBigDecimal", APPLICATION_JSON); + } + + @Test + public void testArrayBigDecimalInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayBigDecimal", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigIntegerTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigIntegerTest.java new file mode 100644 index 0000000000000..89488705d6536 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BigIntegerTest.java @@ -0,0 +1,149 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class BigIntegerTest extends AbstractTest { + + // Just BigInteger + @Test + public void testJustBigIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justBigInteger", TEXT_PLAIN); + } + + @Test + public void testJustBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justBigInteger", TEXT_PLAIN); + } + + // RestResponse + @Test + public void testRestResponseBigIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseBigInteger", TEXT_PLAIN); + } + + @Test + public void testRestResponseBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseBigInteger", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalBigIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalBigInteger", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalBigIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalBigInteger", TEXT_PLAIN); + } + + @Test + public void testOptionalBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalBigInteger", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testUniBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniBigInteger", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageBigInteger", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageBigInteger", TEXT_PLAIN); + } + + // List + @Test + public void testListBigIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listBigInteger", APPLICATION_JSON); + } + + @Test + public void testListBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listBigInteger", APPLICATION_JSON); + } + + // BigInteger[] + @Test + public void testArrayBigIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayBigInteger", APPLICATION_JSON); + } + + @Test + public void testArrayBigIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayBigInteger", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BooleanTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BooleanTest.java new file mode 100644 index 0000000000000..3a327ba0c2cab --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/BooleanTest.java @@ -0,0 +1,213 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class BooleanTest extends AbstractTest { + + // Just Boolean + @Test + public void testJustBooleanInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBooleanInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justBoolean", TEXT_PLAIN); + } + + @Test + public void testJustBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justBoolean", TEXT_PLAIN); + } + + // Just boolean + @Test + public void testJustBoolInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justBool", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBoolInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justBool", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBoolInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justBool", TEXT_PLAIN); + } + + @Test + public void testJustBoolInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justBool", TEXT_PLAIN); + } + + // RestResponse + @Test + public void testRestResponseBooleanInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testRestResponseBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testRestResponseBooleanInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseBoolean", TEXT_PLAIN); + } + + @Test + public void testRestResponseBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseBoolean", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalBooleanInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalBoolean", TEXT_PLAIN, "true"); + } + + //@Test + public void testOptionalBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testOptionalBooleanInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalBoolean", TEXT_PLAIN); + } + + @Test + public void testOptionalBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalBoolean", TEXT_PLAIN); + } + + // Uni + + @Test + public void testUniBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testUniBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniBoolean", TEXT_PLAIN); + } + + // CompletionStage + + @Test + public void testCompletionStageBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testCompletionStageBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageBoolean", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testCompletedFutureBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageBoolean", TEXT_PLAIN); + } + + // List + @Test + public void testListBooleanInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testListBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testListBooleanInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listBoolean", APPLICATION_JSON); + } + + @Test + public void testListBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listBoolean", APPLICATION_JSON); + } + + // Boolean[] + @Test + public void testArrayBooleanInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBooleanInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayBoolean", APPLICATION_JSON); + } + + @Test + public void testArrayBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayBoolean", APPLICATION_JSON); + } + + // boolean[] + @Test + public void testArrayBoolInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayBool", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBoolInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayBool", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBoolInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayBool", APPLICATION_JSON); + } + + @Test + public void testArrayBoolInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayBool", APPLICATION_JSON); + } + + // Map + @Test + public void testMapBooleanInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapBoolean", APPLICATION_JSON, "{\"true\":true}"); + } + + @Test + public void testMapBooleanInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapBoolean", APPLICATION_JSON, "{\"true\":true}"); + } + + @Test + public void testMapBooleanInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapBoolean", APPLICATION_JSON); + } + + @Test + public void testMapBooleanInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapBoolean", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ByteArrayTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ByteArrayTest.java new file mode 100644 index 0000000000000..30d1ec241c67c --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ByteArrayTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractByteArrayTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ByteArrayTest extends AbstractByteArrayTest { + + // Just byte[] + @Test + public void testJustByteArrayInJaxRsServiceRequest() throws IOException { + testServiceByteArrayRequest("/jax-rs/defaultContentType/justByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJusByteArrayInJaxRsServiceResponse() throws IOException { + testServiceByteArrayResponse("/jax-rs/defaultContentType/justByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustByteArrayInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustByteArrayInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // RestResponse + @Test + public void testRestResponseByteArrayInJaxRsServiceRequest() throws IOException { + testServiceByteArrayRequest("/jax-rs/defaultContentType/restResponseByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseByteArrayInJaxRsServiceResponse() throws IOException { + testServiceByteArrayResponse("/jax-rs/defaultContentType/restResponseByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseByteArrayInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseByteArrayInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalByteArrayInJaxRsServiceRequest() throws IOException { + testServiceByteArrayRequest("/jax-rs/defaultContentType/optionalByteArray", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalByteArrayInJaxRsServiceResponse() throws IOException { + testServiceByteArrayResponse("/jax-rs/defaultContentType/optionalByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalByteArrayInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalByteArrayInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniByteArrayInJaxRsServiceResponse() throws IOException { + testServiceByteArrayResponse("/jax-rs/defaultContentType/uniByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniByteArrayInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageByteArrayInJaxRsServiceResponse() throws IOException { + testServiceByteArrayResponse("/jax-rs/defaultContentType/completionStageByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageByteArrayInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureByteArrayInJaxRsServiceResponse() throws IOException { + testServiceByteArrayResponse("/jax-rs/defaultContentType/completedFutureByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureByteArrayInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/FileTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/FileTest.java new file mode 100644 index 0000000000000..9dbefa77babed --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/FileTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractFileTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class FileTest extends AbstractFileTest { + + // Just File + @Test + public void testJustFileInJaxRsServiceRequest() throws IOException { + testServiceFileRequest("/jax-rs/defaultContentType/justFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustFileInJaxRsServiceResponse() throws IOException { + testServiceFileResponse("/jax-rs/defaultContentType/justFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustFileInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustFileInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // RestResponse + @Test + public void testRestResponseFileInJaxRsServiceRequest() throws IOException { + testServiceFileRequest("/jax-rs/defaultContentType/restResponseFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseFileInJaxRsServiceResponse() throws IOException { + testServiceFileResponse("/jax-rs/defaultContentType/restResponseFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseFileInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseFileInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalFileInJaxRsServiceRequest() throws IOException { + testServiceFileRequest("/jax-rs/defaultContentType/optionalFile", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalFileInJaxRsServiceResponse() throws IOException { + testServiceFileResponse("/jax-rs/defaultContentType/optionalFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalFileInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalFileInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniFileInJaxRsServiceResponse() throws IOException { + testServiceFileResponse("/jax-rs/defaultContentType/uniFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniFileInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageFileInJaxRsServiceResponse() throws IOException { + testServiceFileResponse("/jax-rs/defaultContentType/completionStageFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageFileInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureFileInJaxRsServiceResponse() throws IOException { + testServiceFileResponse("/jax-rs/defaultContentType/completedFutureFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureFileInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageFile/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/InputStreamTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/InputStreamTest.java new file mode 100644 index 0000000000000..11c73a3defed5 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/InputStreamTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractInputStreamTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class InputStreamTest extends AbstractInputStreamTest { + + // Just InputStream + @Test + public void testJustInputStreamInJaxRsServiceRequest() throws IOException { + testServiceInputStreamRequest("/jax-rs/defaultContentType/justInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustInputStreamInJaxRsServiceResponse() throws IOException { + testServiceInputStreamResponse("/jax-rs/defaultContentType/justInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustInputStreamInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustInputStreamInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // RestResponse + @Test + public void testRestResponseInputStreamInJaxRsServiceRequest() throws IOException { + testServiceInputStreamRequest("/jax-rs/defaultContentType/restResponseInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseInputStreamInJaxRsServiceResponse() throws IOException { + testServiceInputStreamResponse("/jax-rs/defaultContentType/restResponseInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseInputStreamInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseInputStreamInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalInputStreamInJaxRsServiceRequest() throws IOException { + testServiceInputStreamRequest("/jax-rs/defaultContentType/optionalInputStream", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalInputStreamInJaxRsServiceResponse() throws IOException { + testServiceInputStreamResponse("/jax-rs/defaultContentType/optionalInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalInputStreamInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalInputStreamInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniInputStreamInJaxRsServiceResponse() throws IOException { + testServiceInputStreamResponse("/jax-rs/defaultContentType/uniInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniInputStreamInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageInputStreamInJaxRsServiceResponse() throws IOException { + testServiceInputStreamResponse("/jax-rs/defaultContentType/completionStageInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageInputStreamInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureInputStreamInJaxRsServiceResponse() throws IOException { + testServiceInputStreamResponse("/jax-rs/defaultContentType/completedFutureInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureInputStreamInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/IntegerTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/IntegerTest.java new file mode 100644 index 0000000000000..cd82af12661f7 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/IntegerTest.java @@ -0,0 +1,232 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class IntegerTest extends AbstractTest { + + // Just Integer + @Test + public void testJustIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justInteger", TEXT_PLAIN); + } + + @Test + public void testJustIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justInteger", TEXT_PLAIN); + } + + // Just int + @Test + public void testJustIntInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justInt", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justInt", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justInt", TEXT_PLAIN); + } + + @Test + public void testJustIntInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justInt", TEXT_PLAIN); + } + + // RestResponse + @Test + public void testRestResponseIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseInteger", TEXT_PLAIN); + } + + @Test + public void testRestResponseIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseInteger", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalInteger", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalInteger", TEXT_PLAIN); + } + + @Test + public void testOptionalIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalInteger", TEXT_PLAIN); + } + + // OptionalInt + //@Test + public void testOptionalIntInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalInt", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalIntInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalInt", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalIntInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalInt", TEXT_PLAIN); + } + + @Test + public void testOptionalIntInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalInt", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testUniIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniInteger", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageInteger", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageInteger", TEXT_PLAIN); + } + + // List + @Test + public void testListIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listInteger", APPLICATION_JSON); + } + + @Test + public void testListIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listInteger", APPLICATION_JSON); + } + + // Integer[] + @Test + public void testArrayIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayInteger", APPLICATION_JSON); + } + + @Test + public void testArrayIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayInteger", APPLICATION_JSON); + } + + // int[] + @Test + public void testArrayIntInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayInt", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayInt", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayInt", APPLICATION_JSON); + } + + @Test + public void testArrayIntInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayInt", APPLICATION_JSON); + } + + // Map + @Test + public void testMapIntegerInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapInteger", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapIntegerInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapInteger", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapIntegerInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapInteger", APPLICATION_JSON); + } + + @Test + public void testMapIntegerInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapInteger", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/LongTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/LongTest.java new file mode 100644 index 0000000000000..3a73aff55488c --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/LongTest.java @@ -0,0 +1,232 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class LongTest extends AbstractTest { + + // Just Long + @Test + public void testJustLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justLong", TEXT_PLAIN); + } + + @Test + public void testJustLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justLong", TEXT_PLAIN); + } + + // Just long + @Test + public void testJustPrimitiveLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justPrimitiveLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justPrimitiveLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justPrimitiveLong", TEXT_PLAIN); + } + + @Test + public void testJustPrimitiveLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justPrimitiveLong", TEXT_PLAIN); + } + + // RestResponse + @Test + public void testRestResponseLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseLong", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseLong", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseLong", TEXT_PLAIN); + } + + @Test + public void testRestResponseLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseLong", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalLong", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalLong", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalLong", TEXT_PLAIN); + } + + @Test + public void testOptionalLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalLong", TEXT_PLAIN); + } + + // OptionalLong + //@Test + public void testOptionalPrimitiveLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalPrimitiveLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalPrimitiveLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN); + } + + @Test + public void testOptionalPrimitiveLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniLong", TEXT_PLAIN, "0"); + } + + @Test + public void testUniLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniLong", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageLong", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageLong", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureLong", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageLong", TEXT_PLAIN); + } + + // List + @Test + public void testListLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listLong", APPLICATION_JSON); + } + + @Test + public void testListLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listLong", APPLICATION_JSON); + } + + // Long[] + @Test + public void testArrayLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayLong", APPLICATION_JSON); + } + + @Test + public void testArrayLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayLong", APPLICATION_JSON); + } + + // long[] + @Test + public void testArrayPrimitiveLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON); + } + + @Test + public void testArrayPrimitiveLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON); + } + + // Map + @Test + public void testMapLongInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapLong", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapLongInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapLong", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapLongInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapLong", APPLICATION_JSON); + } + + @Test + public void testMapLongInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapLong", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/PojoTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/PojoTest.java new file mode 100644 index 0000000000000..a50094712b9b0 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/PojoTest.java @@ -0,0 +1,172 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class PojoTest extends AbstractTest { + + // Just Pojo + @Test + public void testJustPojoInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justPojo", APPLICATION_JSON, createExpected("justPojo")); + } + + @Test + public void testJustPojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justPojo", APPLICATION_JSON, createExpected("justPojo")); + } + + @Test + public void testJustPojoInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justPojo", APPLICATION_JSON); + } + + @Test + public void testJustPojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justPojo", APPLICATION_JSON); + } + + // RestResponse + @Test + public void testRestResponsePojoInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponsePojo", APPLICATION_JSON, createExpected("restResponsePojo")); + } + + @Test + public void testRestResponsePojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponsePojo", APPLICATION_JSON, + createExpected("restResponsePojo")); + } + + @Test + public void testRestResponsePojoInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponsePojo", APPLICATION_JSON); + } + + @Test + public void testRestResponsePojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponsePojo", APPLICATION_JSON); + } + + // Optional + @Test + public void testOptionalPojoInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalPojo", APPLICATION_JSON, createExpected("optionalPojo")); + } + + @Test + public void testOptionalPojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalPojo", APPLICATION_JSON, createExpected("optionalPojo")); + } + + @Test + public void testOptionalPojoInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalPojo", APPLICATION_JSON); + } + + @Test + public void testOptionalPojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalPojo", APPLICATION_JSON); + } + + // Uni + @Test + public void testUniPojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniPojo", APPLICATION_JSON, createExpected("uniPojo")); + } + + @Test + public void testUniPojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniPojo", APPLICATION_JSON); + } + + // CompletionStage + @Test + public void testCompletionStagePojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStagePojo", APPLICATION_JSON, + createExpected("completionStagePojo")); + } + + @Test + public void testCompletionStagePojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStagePojo", APPLICATION_JSON); + } + + // CompletedFuture + @Test + public void testCompletedFuturePojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFuturePojo", APPLICATION_JSON, + createExpected("completedFuturePojo")); + } + + @Test + public void testCompletedFuturePojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completedFuturePojo", APPLICATION_JSON); + } + + // List + @Test + public void testListPojoInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listPojo", APPLICATION_JSON, createExpectedList("listPojo")); + } + + @Test + public void testListPojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listPojo", APPLICATION_JSON, createExpectedList("listPojo")); + } + + @Test + public void testListPojoInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listPojo", APPLICATION_JSON); + } + + @Test + public void testListPojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listPojo", APPLICATION_JSON); + } + + // Pojo[] + @Test + public void testArrayPojoInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayPojo", APPLICATION_JSON, createExpectedList("arrayPojo")); + } + + @Test + public void testArrayPojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayPojo", APPLICATION_JSON, createExpectedList("arrayPojo")); + } + + @Test + public void testArrayPojoInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayPojo", APPLICATION_JSON); + } + + @Test + public void testArrayPojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayPojo", APPLICATION_JSON); + } + + // Map + @Test + public void testMapPojoInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapPojo", APPLICATION_JSON, createExpectedMap("mapPojo")); + } + + @Test + public void testMapPojoInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapPojo", APPLICATION_JSON, createExpectedMap("mapPojo")); + } + + @Test + public void testMapPojoInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapPojo", APPLICATION_JSON); + } + + @Test + public void testMapPojoInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapPojo", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ReaderTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ReaderTest.java new file mode 100644 index 0000000000000..53983b630bedf --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ReaderTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.jaxrs; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractReaderTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ReaderTest extends AbstractReaderTest { + + // Just Reader + @Test + public void testJustReaderInJaxRsServiceRequest() throws IOException { + testServiceReaderRequest("/jax-rs/defaultContentType/justReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJusReaderInJaxRsServiceResponse() throws IOException { + testServiceReaderResponse("/jax-rs/defaultContentType/justReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustReaderInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustReaderInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // RestResponse + @Test + public void testRestResponseReaderInJaxRsServiceRequest() throws IOException { + testServiceReaderRequest("/jax-rs/defaultContentType/restResponseReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseReaderInJaxRsServiceResponse() throws IOException { + testServiceReaderResponse("/jax-rs/defaultContentType/restResponseReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseReaderInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseReaderInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalReaderInJaxRsServiceRequest() throws IOException { + testServiceReaderRequest("/jax-rs/defaultContentType/optionalReader", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalReaderInJaxRsServiceResponse() throws IOException { + testServiceReaderResponse("/jax-rs/defaultContentType/optionalReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalReaderInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalReaderInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniReaderInJaxRsServiceResponse() throws IOException { + testServiceReaderResponse("/jax-rs/defaultContentType/uniReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniReaderInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageReaderInJaxRsServiceResponse() throws IOException { + testServiceReaderResponse("/jax-rs/defaultContentType/completionStageReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageReaderInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureReaderInJaxRsServiceResponse() throws IOException { + testServiceReaderResponse("/jax-rs/defaultContentType/completedFutureReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureReaderInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageReader/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ShortTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ShortTest.java new file mode 100644 index 0000000000000..410859d6e40d9 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/ShortTest.java @@ -0,0 +1,211 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ShortTest extends AbstractTest { + + // Just Short + //@Test + public void testJustShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justShort", TEXT_PLAIN); + } + + @Test + public void testJustShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justShort", TEXT_PLAIN); + } + + // Just long + @Test + public void testJustPrimitiveShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justPrimitiveShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justPrimitiveShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justPrimitiveShort", TEXT_PLAIN); + } + + @Test + public void testJustPrimitiveShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justPrimitiveShort", TEXT_PLAIN); + } + + // RestResponse + //@Test + public void testRestResponseShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseShort", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseShort", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseShort", TEXT_PLAIN); + } + + @Test + public void testRestResponseShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseShort", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalShort", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalShort", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalShort", TEXT_PLAIN); + } + + @Test + public void testOptionalShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalShort", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniShort", TEXT_PLAIN, "0"); + } + + @Test + public void testUniShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniShort", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageShort", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageShort", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureShort", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageShort", TEXT_PLAIN); + } + + // List + @Test + public void testListShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listShort", APPLICATION_JSON); + } + + @Test + public void testListShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listShort", APPLICATION_JSON); + } + + // Short[] + @Test + public void testArrayShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayShort", APPLICATION_JSON); + } + + @Test + public void testArrayShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayShort", APPLICATION_JSON); + } + + // long[] + @Test + public void testArrayPrimitiveShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON); + } + + @Test + public void testArrayPrimitiveShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON); + } + + // Map + @Test + public void testMapShortInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapShort", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapShortInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapShort", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapShortInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapShort", APPLICATION_JSON); + } + + @Test + public void testMapShortInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapShort", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/StringTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/StringTest.java new file mode 100644 index 0000000000000..9b3eba2f4df31 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/StringTest.java @@ -0,0 +1,169 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class StringTest extends AbstractTest { + + // Just String + @Test + public void testJustStringInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justString", TEXT_PLAIN, "justString"); + } + + @Test + public void testJustStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justString", TEXT_PLAIN, "justString"); + } + + @Test + public void testJustStringInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justString", TEXT_PLAIN); + } + + @Test + public void testJustStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justString", TEXT_PLAIN); + } + + // RestResponse + @Test + public void testRestResponseStringInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseString", TEXT_PLAIN, "restResponseString"); + } + + @Test + public void testRestResponseStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseString", TEXT_PLAIN, "restResponseString"); + } + + @Test + public void testRestResponseStringInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseString", TEXT_PLAIN); + } + + @Test + public void testRestResponseStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseString", TEXT_PLAIN); + } + + // Optional + // @Test + public void testOptionalStringInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalString", TEXT_PLAIN, "optionalString"); + } + + // @Test + public void testOptionalStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalString", TEXT_PLAIN, "optionalString"); + } + + @Test + public void testOptionalStringInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalString", TEXT_PLAIN); + } + + @Test + public void testOptionalStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalString", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniString", TEXT_PLAIN, "uniString"); + } + + @Test + public void testUniStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniString", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageString", TEXT_PLAIN, "completionStageString"); + } + + @Test + public void testCompletionStageStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageString", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureString", TEXT_PLAIN, "completedFutureString"); + } + + @Test + public void testCompletedFutureStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completedFutureString", TEXT_PLAIN); + } + + // List + @Test + public void testListStringInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listString", APPLICATION_JSON, "[\"listString\"]"); + } + + @Test + public void testListStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listString", APPLICATION_JSON, "[\"listString\"]"); + } + + @Test + public void testListStringInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listString", APPLICATION_JSON); + } + + @Test + public void testListStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listString", APPLICATION_JSON); + } + + // String[] + @Test + public void testArrayStringInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayString", APPLICATION_JSON, "[\"arrayString\"]"); + } + + @Test + public void testArrayStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayString", APPLICATION_JSON, "[\"arrayString\"]"); + } + + @Test + public void testArrayStringInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayString", APPLICATION_JSON); + } + + @Test + public void testArrayStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayString", APPLICATION_JSON); + } + + // Map + @Test + public void testMapStringInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapString", APPLICATION_JSON, "{\"mapString\":\"mapString\"}"); + } + + @Test + public void testMapStringInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapString", APPLICATION_JSON, "{\"mapString\":\"mapString\"}"); + } + + @Test + public void testMapStringInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapString", APPLICATION_JSON); + } + + @Test + public void testMapStringInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapString", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/URLTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/URLTest.java new file mode 100644 index 0000000000000..290f421944004 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/jaxrs/URLTest.java @@ -0,0 +1,169 @@ +package io.quarkus.it.openapi.jaxrs; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class URLTest extends AbstractTest { + + // Just URL + @Test + public void testJustURLInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/justURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testJustURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/justURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testJustURLInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/justURL", APPLICATION_JSON); + } + + @Test + public void testJustURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/justURL", APPLICATION_JSON); + } + + // RestResponse + @Test + public void testRestResponseURLInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/restResponseURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testRestResponseURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/restResponseURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testRestResponseURLInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/restResponseURL", APPLICATION_JSON); + } + + @Test + public void testRestResponseURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/restResponseURL", APPLICATION_JSON); + } + + // Optional + // @Test + public void testOptionalURLInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/optionalURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + // @Test + public void testOptionalURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/optionalURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testOptionalURLInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/optionalURL", APPLICATION_JSON); + } + + @Test + public void testOptionalURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/optionalURL", APPLICATION_JSON); + } + + // Uni + @Test + public void testUniURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/uniURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testUniURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/uniURL", APPLICATION_JSON); + } + + // CompletionStage + @Test + public void testCompletionStageURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completionStageURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testCompletionStageURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completionStageURL", APPLICATION_JSON); + } + + // CompletedFuture + @Test + public void testCompletedFutureURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/completedFutureURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testCompletedFutureURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/completedFutureURL", APPLICATION_JSON); + } + + // List + @Test + public void testListURLInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/listURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testListURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/listURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testListURLInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/listURL", APPLICATION_JSON); + } + + @Test + public void testListURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/listURL", APPLICATION_JSON); + } + + // URL[] + @Test + public void testArrayURLInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/arrayURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testArrayURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/arrayURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testArrayURLInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/arrayURL", APPLICATION_JSON); + } + + @Test + public void testArrayURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/arrayURL", APPLICATION_JSON); + } + + // Map + @Test + public void testMapURLInJaxRsServiceRequest() { + testServiceRequest("/jax-rs/defaultContentType/mapURL", APPLICATION_JSON, "{\"mapURL\":\"https://quarkus.io/\"}"); + } + + @Test + public void testMapURLInJaxRsServiceResponse() { + testServiceResponse("/jax-rs/defaultContentType/mapURL", APPLICATION_JSON, "{\"mapURL\":\"https://quarkus.io/\"}"); + } + + @Test + public void testMapURLInJaxRsOpenAPIRequest() { + testOpenAPIRequest("/jax-rs/defaultContentType/mapURL", APPLICATION_JSON); + } + + @Test + public void testMapURLInJaxRsOpenAPIResponse() { + testOpenAPIResponse("/jax-rs/defaultContentType/mapURL", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigDecimalTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigDecimalTest.java new file mode 100644 index 0000000000000..300b58cb31f14 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigDecimalTest.java @@ -0,0 +1,149 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class BigDecimalTest extends AbstractTest { + + // Just BigDecimal + @Test + public void testJustBigDecimalInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigDecimalInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justBigDecimal", TEXT_PLAIN); + } + + @Test + public void testJustBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justBigDecimal", TEXT_PLAIN); + } + + // ResponseEntity + @Test + public void testRestResponseBigDecimalInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigDecimalInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityBigDecimal", TEXT_PLAIN); + } + + @Test + public void testRestResponseBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityBigDecimal", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalBigDecimalInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalBigDecimal", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalBigDecimalInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalBigDecimal", TEXT_PLAIN); + } + + @Test + public void testOptionalBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalBigDecimal", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testUniBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniBigDecimal", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageBigDecimal", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureBigDecimal", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageBigDecimal", TEXT_PLAIN); + } + + // List + @Test + public void testListBigDecimalInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigDecimalInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listBigDecimal", APPLICATION_JSON); + } + + @Test + public void testListBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listBigDecimal", APPLICATION_JSON); + } + + // BigDecimal[] + @Test + public void testArrayBigDecimalInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigDecimalInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayBigDecimal", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigDecimalInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayBigDecimal", APPLICATION_JSON); + } + + @Test + public void testArrayBigDecimalInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayBigDecimal", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigIntegerTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigIntegerTest.java new file mode 100644 index 0000000000000..6f35621d2c841 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BigIntegerTest.java @@ -0,0 +1,149 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class BigIntegerTest extends AbstractTest { + + // Just BigInteger + @Test + public void testJustBigIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustBigIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justBigInteger", TEXT_PLAIN); + } + + @Test + public void testJustBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justBigInteger", TEXT_PLAIN); + } + + // ResponseEntity + @Test + public void testRestResponseBigIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testRestResponseBigIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityBigInteger", TEXT_PLAIN); + } + + @Test + public void testRestResponseBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityBigInteger", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalBigIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalBigInteger", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalBigIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalBigInteger", TEXT_PLAIN); + } + + @Test + public void testOptionalBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalBigInteger", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testUniBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniBigInteger", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageBigInteger", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureBigInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageBigInteger", TEXT_PLAIN); + } + + // List + @Test + public void testListBigIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListBigIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listBigInteger", APPLICATION_JSON); + } + + @Test + public void testListBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listBigInteger", APPLICATION_JSON); + } + + // BigInteger[] + @Test + public void testArrayBigIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayBigInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayBigIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayBigInteger", APPLICATION_JSON); + } + + @Test + public void testArrayBigIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayBigInteger", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BooleanTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BooleanTest.java new file mode 100644 index 0000000000000..c6c8a1d9e98f6 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/BooleanTest.java @@ -0,0 +1,211 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class BooleanTest extends AbstractTest { + + // Just Boolean + @Test + public void testJustBooleanInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBooleanInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justBoolean", TEXT_PLAIN); + } + + @Test + public void testJustBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justBoolean", TEXT_PLAIN); + } + + // Just boolean + @Test + public void testJustBoolInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justBool", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBoolInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justBool", TEXT_PLAIN, "true"); + } + + @Test + public void testJustBoolInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justBool", TEXT_PLAIN); + } + + @Test + public void testJustBoolInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justBool", TEXT_PLAIN); + } + + // ResponseEntity + @Test + public void testResponseEntityBooleanInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testResponseEntityBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testResponseEntityBooleanInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityBoolean", TEXT_PLAIN); + } + + @Test + public void testResponseEntityBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityBoolean", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalBooleanInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalBoolean", TEXT_PLAIN, "true"); + } + + //@Test + public void testOptionalBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testOptionalBooleanInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalBoolean", TEXT_PLAIN); + } + + @Test + public void testOptionalBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalBoolean", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testUniBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniBoolean", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testCompletionStageBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageBoolean", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureBoolean", TEXT_PLAIN, "true"); + } + + @Test + public void testCompletedFutureBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageBoolean", TEXT_PLAIN); + } + + // List + @Test + public void testListBooleanInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testListBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testListBooleanInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listBoolean", APPLICATION_JSON); + } + + @Test + public void testListBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listBoolean", APPLICATION_JSON); + } + + // Boolean[] + @Test + public void testArrayBooleanInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayBoolean", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBooleanInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayBoolean", APPLICATION_JSON); + } + + @Test + public void testArrayBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayBoolean", APPLICATION_JSON); + } + + // boolean[] + @Test + public void testArrayBoolInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayBool", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBoolInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayBool", APPLICATION_JSON, "[true]"); + } + + @Test + public void testArrayBoolInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayBool", APPLICATION_JSON); + } + + @Test + public void testArrayBoolInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayBool", APPLICATION_JSON); + } + + // Map + @Test + public void testMapBooleanInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapBoolean", APPLICATION_JSON, "{\"true\":true}"); + } + + @Test + public void testMapBooleanInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/mapBoolean", APPLICATION_JSON, "{\"true\":true}"); + } + + @Test + public void testMapBooleanInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapBoolean", APPLICATION_JSON); + } + + @Test + public void testMapBooleanInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapBoolean", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ByteArrayTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ByteArrayTest.java new file mode 100644 index 0000000000000..72a0068dde59e --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ByteArrayTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractByteArrayTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ByteArrayTest extends AbstractByteArrayTest { + + // Just byte[] + @Test + public void testJustByteArrayInSpringServiceRequest() throws IOException { + testServiceByteArrayRequest("/spring/defaultContentType/justByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJusByteArrayInSpringServiceResponse() throws IOException { + testServiceByteArrayResponse("/spring/defaultContentType/justByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustByteArrayInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustByteArrayInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // ResponseEntity + @Test + public void testResponseEntityByteArrayInSpringServiceRequest() throws IOException { + testServiceByteArrayRequest("/spring/defaultContentType/responseEntityByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityByteArrayInSpringServiceResponse() throws IOException { + testServiceByteArrayResponse("/spring/defaultContentType/responseEntityByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseByteArrayInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testRestResponseByteArrayInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalByteArrayInSpringServiceRequest() throws IOException { + testServiceByteArrayRequest("/spring/defaultContentType/optionalByteArray", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalByteArrayInSpringServiceResponse() throws IOException { + testServiceByteArrayResponse("/spring/defaultContentType/optionalByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalByteArrayInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalByteArrayInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniByteArrayInSpringServiceResponse() throws IOException { + testServiceByteArrayResponse("/spring/defaultContentType/uniByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniByteArrayInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageByteArrayInSpringServiceResponse() throws IOException { + testServiceByteArrayResponse("/spring/defaultContentType/completionStageByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageByteArrayInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureByteArrayInSpringServiceResponse() throws IOException { + testServiceByteArrayResponse("/spring/defaultContentType/completedFutureByteArray", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureByteArrayInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageByteArray/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/FileTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/FileTest.java new file mode 100644 index 0000000000000..118562d81df1d --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/FileTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractFileTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class FileTest extends AbstractFileTest { + + // Just File + @Test + public void testJustFileInSpringServiceRequest() throws IOException { + testServiceFileRequest("/spring/defaultContentType/justFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustFileInSpringServiceResponse() throws IOException { + testServiceFileResponse("/spring/defaultContentType/justFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustFileInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustFileInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // ResponseEntity + @Test + public void testResponseEntityFileInSpringServiceRequest() throws IOException { + testServiceFileRequest("/spring/defaultContentType/responseEntityFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityFileInSpringServiceResponse() throws IOException { + testServiceFileResponse("/spring/defaultContentType/responseEntityFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityFileInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityFileInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalFileInSpringServiceRequest() throws IOException { + testServiceFileRequest("/spring/defaultContentType/optionalFile", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalFileInSpringServiceResponse() throws IOException { + testServiceFileResponse("/spring/defaultContentType/optionalFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalFileInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalFileInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniFileInSpringServiceResponse() throws IOException { + testServiceFileResponse("/spring/defaultContentType/uniFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniFileInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageFileInSpringServiceResponse() throws IOException { + testServiceFileResponse("/spring/defaultContentType/completionStageFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageFileInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageFile/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureFileInSpringServiceResponse() throws IOException { + testServiceFileResponse("/spring/defaultContentType/completedFutureFile", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureFileInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageFile/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/InputStreamTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/InputStreamTest.java new file mode 100644 index 0000000000000..b7c03a44ab09c --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/InputStreamTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractInputStreamTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class InputStreamTest extends AbstractInputStreamTest { + + // Just InputStream + @Test + public void testJustInputStreamInSpringServiceRequest() throws IOException { + testServiceInputStreamRequest("/spring/defaultContentType/justInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJusInputStreamInSpringServiceResponse() throws IOException { + testServiceInputStreamResponse("/spring/defaultContentType/justInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustInputStreamInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustInputStreamInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // ResponseEntity + @Test + public void testResponseEntityInputStreamInSpringServiceRequest() throws IOException { + testServiceInputStreamRequest("/spring/defaultContentType/responseEntityInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityInputStreamInSpringServiceResponse() throws IOException { + testServiceInputStreamResponse("/spring/defaultContentType/responseEntityInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityInputStreamInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityInputStreamInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalInputStreamInSpringServiceRequest() throws IOException { + testServiceInputStreamRequest("/spring/defaultContentType/optionalInputStream", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalInputStreamInSpringServiceResponse() throws IOException { + testServiceInputStreamResponse("/spring/defaultContentType/optionalInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalInputStreamInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalInputStreamInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniInputStreamInSpringServiceResponse() throws IOException { + testServiceInputStreamResponse("/spring/defaultContentType/uniInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniInputStreamInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageInputStreamInSpringServiceResponse() throws IOException { + testServiceInputStreamResponse("/spring/defaultContentType/completionStageInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageInputStreamInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureInputStreamInSpringServiceResponse() throws IOException { + testServiceInputStreamResponse("/spring/defaultContentType/completedFutureInputStream", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureInputStreamInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageInputStream/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/IntegerTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/IntegerTest.java new file mode 100644 index 0000000000000..94e7cc9f1b702 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/IntegerTest.java @@ -0,0 +1,232 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class IntegerTest extends AbstractTest { + + // Just Integer + @Test + public void testJustIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justInteger", TEXT_PLAIN); + } + + @Test + public void testJustIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justInteger", TEXT_PLAIN); + } + + // Just int + @Test + public void testJustIntInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justInt", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justInt", TEXT_PLAIN, "0"); + } + + @Test + public void testJustIntInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justInt", TEXT_PLAIN); + } + + @Test + public void testJustIntInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justInt", TEXT_PLAIN); + } + + // ResponseEntity + @Test + public void testResponseEntityIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testResponseEntityIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testResponseEntityIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityInteger", TEXT_PLAIN); + } + + @Test + public void testResponseEntityIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityInteger", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalInteger", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalInteger", TEXT_PLAIN); + } + + @Test + public void testOptionalIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalInteger", TEXT_PLAIN); + } + + // OptionalInt + //@Test + public void testOptionalIntInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalInt", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalIntInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalInt", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalIntInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalInt", TEXT_PLAIN); + } + + @Test + public void testOptionalIntInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalInt", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testUniIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniInteger", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageInteger", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureInteger", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageInteger", TEXT_PLAIN); + } + + // List + @Test + public void testListIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listInteger", APPLICATION_JSON); + } + + @Test + public void testListIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listInteger", APPLICATION_JSON); + } + + // Integer[] + @Test + public void testArrayIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayInteger", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayInteger", APPLICATION_JSON); + } + + @Test + public void testArrayIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayInteger", APPLICATION_JSON); + } + + // int[] + @Test + public void testArrayIntInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayInt", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayInt", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayIntInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayInt", APPLICATION_JSON); + } + + @Test + public void testArrayIntInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayInt", APPLICATION_JSON); + } + + // Map + @Test + public void testMapIntegerInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapInteger", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapIntegerInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/mapInteger", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapIntegerInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapInteger", APPLICATION_JSON); + } + + @Test + public void testMapIntegerInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapInteger", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/LongTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/LongTest.java new file mode 100644 index 0000000000000..046de5dea3f18 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/LongTest.java @@ -0,0 +1,233 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class LongTest extends AbstractTest { + + // Just Long + @Test + public void testJustLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justLong", TEXT_PLAIN); + } + + @Test + public void testJustLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justLong", TEXT_PLAIN); + } + + // Just long + @Test + public void testJustPrimitiveLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justPrimitiveLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justPrimitiveLong", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justPrimitiveLong", TEXT_PLAIN); + } + + @Test + public void testJustPrimitiveLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justPrimitiveLong", TEXT_PLAIN); + } + + // ResponseEntity + @Test + public void testResponseEntityLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityLong", TEXT_PLAIN, "0"); + } + + @Test + public void testResponseEntityLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityLong", TEXT_PLAIN, "0"); + } + + @Test + public void testResponseEntityLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityLong", TEXT_PLAIN); + } + + @Test + public void testResponseEntityLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityLong", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalLong", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalLong", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalLong", TEXT_PLAIN); + } + + @Test + public void testOptionalLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalLong", TEXT_PLAIN); + } + + // OptionalLong + //@Test + public void testOptionalPrimitiveLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalPrimitiveLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalPrimitiveLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN); + } + + @Test + public void testOptionalPrimitiveLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalPrimitiveLong", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniLong", TEXT_PLAIN, "0"); + } + + @Test + public void testUniLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniLong", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageLong", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageLong", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureLong", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageLong", TEXT_PLAIN); + } + + // List + @Test + public void testListLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listLong", APPLICATION_JSON); + } + + @Test + public void testListLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listLong", APPLICATION_JSON); + } + + // Long[] + @Test + public void testArrayLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayLong", APPLICATION_JSON); + } + + @Test + public void testArrayLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayLong", APPLICATION_JSON); + } + + // long[] + @Test + public void testArrayPrimitiveLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON); + } + + @Test + public void testArrayPrimitiveLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayPrimitiveLong", APPLICATION_JSON); + } + + // Map + @Test + public void testMapLongInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapLong", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapLongInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/mapLong", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapLongInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapLong", APPLICATION_JSON); + } + + @Test + public void testMapLongInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapLong", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/PojoTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/PojoTest.java new file mode 100644 index 0000000000000..b94f41fc7ae81 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/PojoTest.java @@ -0,0 +1,175 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class PojoTest extends AbstractTest { + + // Just Pojo + @Test + public void testJustPojoInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justPojo", APPLICATION_JSON, createExpected("justPojo")); + } + + @Test + public void testJustPojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justPojo", APPLICATION_JSON, createExpected("justPojo")); + } + + @Test + public void testJustPojoInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justPojo", APPLICATION_JSON); + } + + @Test + public void testJustPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justPojo", APPLICATION_JSON); + } + + // ResponseEntity + @Test + public void testResponseEntityPojoInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityPojo", APPLICATION_JSON, + createExpected("responseEntityPojo")); + } + + @Test + public void testResponseEntityPojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityPojo", APPLICATION_JSON, + createExpected("responseEntityPojo")); + } + + @Test + public void testResponseEntityPojoInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityPojo", APPLICATION_JSON); + } + + @Test + public void testResponseEntityPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityPojo", APPLICATION_JSON); + } + + // Optional + @Test + public void testOptionalPojoInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalPojo", APPLICATION_JSON, createExpected("optionalPojo")); + } + + @Test + public void testOptionalPojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalPojo", APPLICATION_JSON, createExpected("optionalPojo")); + } + + @Test + public void testOptionalPojoInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalPojo", APPLICATION_JSON); + } + + @Test + public void testOptionalPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalPojo", APPLICATION_JSON); + } + + // Uni + @Test + public void testUniPojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniPojo", APPLICATION_JSON, createExpected("uniPojo")); + } + + @Test + public void testUniPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniPojo", APPLICATION_JSON); + } + + // CompletionStage + @Test + public void testCompletionStagePojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStagePojo", APPLICATION_JSON, + createExpected("completionStagePojo")); + } + + @Test + public void testCompletionStagePojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStagePojo", APPLICATION_JSON); + } + + // CompletedFuture + @Test + public void testCompletedFuturePojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFuturePojo", APPLICATION_JSON, + createExpected("completedFuturePojo")); + } + + @Test + public void testCompletedFuturePojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completedFuturePojo", APPLICATION_JSON); + } + + // List + @Test + public void testListPojoInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listPojo", APPLICATION_JSON, createExpectedList("listPojo")); + } + + @Test + public void testListPojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listPojo", APPLICATION_JSON, createExpectedList("listPojo")); + } + + @Test + public void testListPojoInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listPojo", APPLICATION_JSON); + } + + @Test + public void testListPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listPojo", APPLICATION_JSON); + } + + // Pojo[] + @Test + public void testArrayPojoInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayPojo", APPLICATION_JSON, createExpectedList("arrayPojo")); + } + + @Test + public void testArrayPojoInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayPojo", APPLICATION_JSON, createExpectedList("arrayPojo")); + } + + @Test + public void testArrayPojoInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayPojo", APPLICATION_JSON); + } + + @Test + public void testArrayPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayPojo", APPLICATION_JSON); + } + + // Map + @Test + public void testMapPojoInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapPojo", APPLICATION_JSON, createExpectedMap("mapPojo")); + } + + @Test + public void testMapPojoInSpringServiceResponse() { + + testServiceResponse("/spring/defaultContentType/mapPojo", APPLICATION_JSON, createExpectedMap("mapPojo")); + } + + @Test + public void testMapPojoInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapPojo", APPLICATION_JSON); + } + + @Test + public void testMapPojoInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapPojo", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ReaderTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ReaderTest.java new file mode 100644 index 0000000000000..0a2c7231d8922 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ReaderTest.java @@ -0,0 +1,110 @@ +package io.quarkus.it.openapi.spring; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractReaderTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ReaderTest extends AbstractReaderTest { + + // Just Reader + @Test + public void testJustReaderInSpringServiceRequest() throws IOException { + testServiceReaderRequest("/spring/defaultContentType/justReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJusReaderInSpringServiceResponse() throws IOException { + testServiceReaderResponse("/spring/defaultContentType/justReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustReaderInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testJustReaderInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // ResponseEntity + @Test + public void testResponseEntityReaderInSpringServiceRequest() throws IOException { + testServiceReaderRequest("/spring/defaultContentType/responseEntityReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityReaderInSpringServiceResponse() throws IOException { + testServiceReaderResponse("/spring/defaultContentType/responseEntityReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityReaderInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testResponseEntityReaderInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Optional + //@Test + public void testOptionalReaderInSpringServiceRequest() throws IOException { + testServiceReaderRequest("/spring/defaultContentType/optionalReader", APPLICATION_OCTET_STREAM); + } + + //@Test + public void testOptionalReaderInSpringServiceResponse() throws IOException { + testServiceReaderResponse("/spring/defaultContentType/optionalReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalReaderInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testOptionalReaderInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // Uni + + @Test + public void testUniReaderInSpringServiceResponse() throws IOException { + testServiceReaderResponse("/spring/defaultContentType/uniReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testUniReaderInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletionStage + + @Test + public void testCompletionStageReaderInSpringServiceResponse() throws IOException { + testServiceReaderResponse("/spring/defaultContentType/completionStageReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletionStageReaderInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageReader/{fileName}", APPLICATION_OCTET_STREAM); + } + + // CompletedFuture + @Test + public void testCompletedFutureReaderInSpringServiceResponse() throws IOException { + testServiceReaderResponse("/spring/defaultContentType/completedFutureReader", APPLICATION_OCTET_STREAM); + } + + @Test + public void testCompletedFutureReaderInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageReader/{fileName}", APPLICATION_OCTET_STREAM); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ShortTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ShortTest.java new file mode 100644 index 0000000000000..c7b58ed5e81f9 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/ShortTest.java @@ -0,0 +1,212 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class ShortTest extends AbstractTest { + + // Just Short + //@Test + public void testJustShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justShort", TEXT_PLAIN); + } + + @Test + public void testJustShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justShort", TEXT_PLAIN); + } + + // Just short + @Test + public void testJustPrimitiveShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justPrimitiveShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justPrimitiveShort", TEXT_PLAIN, "0"); + } + + @Test + public void testJustPrimitiveShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justPrimitiveShort", TEXT_PLAIN); + } + + @Test + public void testJustPrimitiveShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justPrimitiveShort", TEXT_PLAIN); + } + + // ResponseEntity + //@Test + public void testResponseEntityShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityShort", TEXT_PLAIN, "0"); + } + + @Test + public void testResponseEntityShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityShort", TEXT_PLAIN, "0"); + } + + @Test + public void testResponseEntityShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityShort", TEXT_PLAIN); + } + + @Test + public void testResponseEntityShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityShort", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalShort", TEXT_PLAIN, "0"); + } + + //@Test + public void testOptionalShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalShort", TEXT_PLAIN, "0"); + } + + @Test + public void testOptionalShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalShort", TEXT_PLAIN); + } + + @Test + public void testOptionalShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalShort", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniShort", TEXT_PLAIN, "0"); + } + + @Test + public void testUniShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniShort", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageShort", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletionStageShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageShort", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureShort", TEXT_PLAIN, "0"); + } + + @Test + public void testCompletedFutureShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageShort", TEXT_PLAIN); + } + + // List + @Test + public void testListShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testListShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listShort", APPLICATION_JSON); + } + + @Test + public void testListShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listShort", APPLICATION_JSON); + } + + // Short[] + @Test + public void testArrayShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayShort", APPLICATION_JSON); + } + + @Test + public void testArrayShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayShort", APPLICATION_JSON); + } + + // long[] + @Test + public void testArrayPrimitiveShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON, "[0]"); + } + + @Test + public void testArrayPrimitiveShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON); + } + + @Test + public void testArrayPrimitiveShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayPrimitiveShort", APPLICATION_JSON); + } + + // Map + @Test + public void testMapShortInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapShort", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapShortInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/mapShort", APPLICATION_JSON, "{\"0\":0}"); + } + + @Test + public void testMapShortInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapShort", APPLICATION_JSON); + } + + @Test + public void testMapShortInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapShort", APPLICATION_JSON); + } + +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/StringTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/StringTest.java new file mode 100644 index 0000000000000..3322e7bda0992 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/StringTest.java @@ -0,0 +1,169 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class StringTest extends AbstractTest { + + // Just String + @Test + public void testJustStringInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justString", TEXT_PLAIN, "justString"); + } + + @Test + public void testJustStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justString", TEXT_PLAIN, "justString"); + } + + @Test + public void testJustStringInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justString", TEXT_PLAIN); + } + + @Test + public void testJustStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justString", TEXT_PLAIN); + } + + // ResponseEntity + @Test + public void testResponseEntityStringInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/responseEntityString", TEXT_PLAIN, "responseEntityString"); + } + + @Test + public void testResponseEntityStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/responseEntityString", TEXT_PLAIN, "responseEntityString"); + } + + @Test + public void testResponseEntityStringInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/responseEntityString", TEXT_PLAIN); + } + + @Test + public void testResponseEntityStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/responseEntityString", TEXT_PLAIN); + } + + // Optional + //@Test + public void testOptionalStringInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalString", TEXT_PLAIN, "optionalString"); + } + + //@Test + public void testOptionalStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalString", TEXT_PLAIN, "optionalString"); + } + + @Test + public void testOptionalStringInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalString", TEXT_PLAIN); + } + + @Test + public void testOptionalStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalString", TEXT_PLAIN); + } + + // Uni + @Test + public void testUniStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniString", TEXT_PLAIN, "uniString"); + } + + @Test + public void testUniStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniString", TEXT_PLAIN); + } + + // CompletionStage + @Test + public void testCompletionStageStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageString", TEXT_PLAIN, "completionStageString"); + } + + @Test + public void testCompletionStageStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageString", TEXT_PLAIN); + } + + // CompletedFuture + @Test + public void testCompletedFutureStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureString", TEXT_PLAIN, "completedFutureString"); + } + + @Test + public void testCompletedFutureStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completedFutureString", TEXT_PLAIN); + } + + // List + @Test + public void testListStringInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listString", APPLICATION_JSON, "[\"listString\"]"); + } + + @Test + public void testListStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listString", APPLICATION_JSON, "[\"listString\"]"); + } + + @Test + public void testListStringInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listString", APPLICATION_JSON); + } + + @Test + public void testListStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listString", APPLICATION_JSON); + } + + // String[] + @Test + public void testArrayStringInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayString", APPLICATION_JSON, "[\"arrayString\"]"); + } + + @Test + public void testArrayStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayString", APPLICATION_JSON, "[\"arrayString\"]"); + } + + @Test + public void testArrayStringInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayString", APPLICATION_JSON); + } + + @Test + public void testArrayStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayString", APPLICATION_JSON); + } + + // Map + @Test + public void testMapStringInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapString", APPLICATION_JSON, "{\"mapString\":\"mapString\"}"); + } + + @Test + public void testMapStringInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/mapString", APPLICATION_JSON, "{\"mapString\":\"mapString\"}"); + } + + @Test + public void testMapStringInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapString", APPLICATION_JSON); + } + + @Test + public void testMapStringInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapString", APPLICATION_JSON); + } +} diff --git a/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/URLTest.java b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/URLTest.java new file mode 100644 index 0000000000000..0e9f1bc07a2e3 --- /dev/null +++ b/integration-tests/openapi/src/test/java/io/quarkus/it/openapi/spring/URLTest.java @@ -0,0 +1,169 @@ +package io.quarkus.it.openapi.spring; + +import org.junit.jupiter.api.Test; + +import io.quarkus.it.openapi.AbstractTest; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class URLTest extends AbstractTest { + + // Just URL + @Test + public void testJustURLInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/justURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testJustURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/justURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testJustURLInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/justURL", APPLICATION_JSON); + } + + @Test + public void testJustURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/justURL", APPLICATION_JSON); + } + + // RestResponse + @Test + public void testRestResponseURLInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/restResponseURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testRestResponseURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/restResponseURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testRestResponseURLInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/restResponseURL", APPLICATION_JSON); + } + + @Test + public void testRestResponseURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/restResponseURL", APPLICATION_JSON); + } + + // Optional + // @Test + public void testOptionalURLInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/optionalURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + // @Test + public void testOptionalURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/optionalURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testOptionalURLInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/optionalURL", APPLICATION_JSON); + } + + @Test + public void testOptionalURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/optionalURL", APPLICATION_JSON); + } + + // Uni + @Test + public void testUniURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/uniURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testUniURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/uniURL", APPLICATION_JSON); + } + + // CompletionStage + @Test + public void testCompletionStageURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completionStageURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testCompletionStageURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completionStageURL", APPLICATION_JSON); + } + + // CompletedFuture + @Test + public void testCompletedFutureURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/completedFutureURL", APPLICATION_JSON, "\"https://quarkus.io/\""); + } + + @Test + public void testCompletedFutureURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/completedFutureURL", APPLICATION_JSON); + } + + // List + @Test + public void testListURLInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/listURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testListURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/listURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testListURLInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/listURL", APPLICATION_JSON); + } + + @Test + public void testListURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/listURL", APPLICATION_JSON); + } + + // URL[] + @Test + public void testArrayURLInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/arrayURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testArrayURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/arrayURL", APPLICATION_JSON, "[\"https://quarkus.io/\"]"); + } + + @Test + public void testArrayURLInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/arrayURL", APPLICATION_JSON); + } + + @Test + public void testArrayURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/arrayURL", APPLICATION_JSON); + } + + // Map + @Test + public void testMapURLInSpringServiceRequest() { + testServiceRequest("/spring/defaultContentType/mapURL", APPLICATION_JSON, "{\"mapURL\":\"https://quarkus.io/\"}"); + } + + @Test + public void testMapURLInSpringServiceResponse() { + testServiceResponse("/spring/defaultContentType/mapURL", APPLICATION_JSON, "{\"mapURL\":\"https://quarkus.io/\"}"); + } + + @Test + public void testMapURLInSpringOpenAPIRequest() { + testOpenAPIRequest("/spring/defaultContentType/mapURL", APPLICATION_JSON); + } + + @Test + public void testMapURLInSpringOpenAPIResponse() { + testOpenAPIResponse("/spring/defaultContentType/mapURL", APPLICATION_JSON); + } +} diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 4ffed18b7049f..b623b32388ee6 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -263,6 +263,7 @@ oidc-client-wiremock oidc-token-propagation oidc-token-propagation-reactive + openapi smallrye-jwt-oidc-webapp smallrye-jwt-token-propagation oidc-code-flow From 1ceacff9b6dc6d270470307b4cadfd358586551b Mon Sep 17 00:00:00 2001 From: Robert Stupp Date: Tue, 31 Oct 2023 16:32:58 +0100 Subject: [PATCH 10/29] Gradle plugin: use full URI for configuration source locations `io.quarkus.gradle.tasks.EffectiveConfig.CombinedConfigSourceProvider` passes only the "file extension" (e.g. `application.properties`) down to `io.smallrye.config.AbstractLocationConfigSourceLoader#loadConfigSources(java.lang.String[], int, java.lang.ClassLoader)`, which may let that function behave wrong and try to for example access an `application.properties` in the wrong location. This can be reproduced by placing an `application.properties` file in the project directory of a Gradle project that uses the Quarkus Gradle plugin. This change fixes this behavior by passing down the correct locations as the `String` representation of the resource URIs, instead of just the "file extensions". Fixes #36767 (cherry picked from commit a1f3057443f341dbc229967c0a3bb806dc974f65) --- .../quarkus/gradle/tasks/EffectiveConfig.java | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/EffectiveConfig.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/EffectiveConfig.java index 3e03f70678474..10bcd6bcabb3f 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/EffectiveConfig.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/EffectiveConfig.java @@ -7,6 +7,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -139,21 +141,26 @@ List applicationPropsSources() { static void configSourcesForApplicationProperties(Set sourceDirectories, Consumer sourceUrls, Consumer configSourceConsumer, int ordinal, String[] fileExtensions) { - URL[] resourceUrls = sourceDirectories.stream().map(File::toURI) - .map(u -> { - try { - return u.toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - }) - .toArray(URL[]::new); - - for (URL resourceUrl : resourceUrls) { - URLClassLoader classLoader = new URLClassLoader(new URL[] { resourceUrl }); - CombinedConfigSourceProvider configSourceProvider = new CombinedConfigSourceProvider(sourceUrls, ordinal, - fileExtensions); - configSourceProvider.getConfigSources(classLoader).forEach(configSourceConsumer); + for (var sourceDir : sourceDirectories) { + var sourceDirPath = sourceDir.toPath(); + var locations = new ArrayList(); + for (String file : fileExtensions) { + Path resolved = sourceDirPath.resolve(file); + if (Files.exists(resolved)) { + locations.add(resolved.toUri().toString()); + } + } + if (!locations.isEmpty()) { + URLClassLoader classLoader; + try { + classLoader = new URLClassLoader(new URL[] { sourceDir.toURI().toURL() }); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + CombinedConfigSourceProvider configSourceProvider = new CombinedConfigSourceProvider(sourceUrls, ordinal, + fileExtensions, locations); + configSourceProvider.getConfigSources(classLoader).forEach(configSourceConsumer); + } } } @@ -204,11 +211,13 @@ static final class CombinedConfigSourceProvider extends AbstractLocationConfigSo private final Consumer sourceUrls; private final int ordinal; private final String[] fileExtensions; + private final List locations; - CombinedConfigSourceProvider(Consumer sourceUrls, int ordinal, String[] fileExtensions) { + CombinedConfigSourceProvider(Consumer sourceUrls, int ordinal, String[] fileExtensions, List locations) { this.sourceUrls = sourceUrls; this.ordinal = ordinal; this.fileExtensions = fileExtensions; + this.locations = locations; } @Override @@ -225,8 +234,7 @@ protected ConfigSource loadConfigSource(final URL url, final int ordinal) throws @Override public List getConfigSources(final ClassLoader classLoader) { - // Note: - return loadConfigSources(getFileExtensions(), ordinal, classLoader); + return loadConfigSources(locations.toArray(new String[0]), ordinal, classLoader); } } } From 981245b85326a43c11c1141e3dbff0c3417322f7 Mon Sep 17 00:00:00 2001 From: brunobat Date: Tue, 17 Oct 2023 17:38:28 +0100 Subject: [PATCH 11/29] OTel flush timeout (cherry picked from commit fb8577140e2d499b8c3c382ce35588cf8314a2b8) --- .../OpenTelemetryDestroyerTest.java | 48 +++++++++++++++++++ .../opentelemetry/OpenTelemetryDestroyer.java | 19 +++++++- .../config/runtime/OTelRuntimeConfig.java | 8 ++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryDestroyerTest.java diff --git a/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryDestroyerTest.java b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryDestroyerTest.java new file mode 100644 index 0000000000000..d0fe61b90b23d --- /dev/null +++ b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryDestroyerTest.java @@ -0,0 +1,48 @@ +package io.quarkus.opentelemetry.deployment; + +import static org.hamcrest.Matchers.is; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; + +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.opentelemetry.OpenTelemetryDestroyer; +import io.quarkus.opentelemetry.deployment.common.TestSpanExporter; +import io.quarkus.opentelemetry.deployment.common.TestSpanExporterProvider; +import io.quarkus.test.QuarkusDevModeTest; +import io.restassured.RestAssured; + +public class OpenTelemetryDestroyerTest { + + @RegisterExtension + final static QuarkusDevModeTest TEST = new QuarkusDevModeTest() + .withApplicationRoot((jar) -> jar + .addClasses(TestSpanExporter.class, + TestSpanExporterProvider.class, + HelloResource.class) + .addAsResource(new StringAsset(TestSpanExporterProvider.class.getCanonicalName()), + "META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider") + .add(new StringAsset( + "quarkus.otel.traces.exporter=test-span-exporter\n" + + "quarkus.otel.experimental.shutdown-wait-time=PT60S\n"), + "application.properties")); + + @Test + void getShutdownWaitTime() { + RestAssured.when() + .get("/hello").then() + .statusCode(200) + .body(is("PT1M")); + } + + @Path("/hello") + public static class HelloResource { + @GET + public String hello() { + return OpenTelemetryDestroyer.getShutdownWaitTime().toString(); + } + } +} diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/OpenTelemetryDestroyer.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/OpenTelemetryDestroyer.java index 67bacb2fc9a0b..b76b36bccfa1d 100644 --- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/OpenTelemetryDestroyer.java +++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/OpenTelemetryDestroyer.java @@ -1,21 +1,36 @@ package io.quarkus.opentelemetry; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.time.Duration; import java.util.Map; import jakarta.enterprise.context.spi.CreationalContext; +import org.eclipse.microprofile.config.ConfigProvider; + import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.quarkus.arc.BeanDestroyer; +import io.smallrye.config.SmallRyeConfig; public class OpenTelemetryDestroyer implements BeanDestroyer { @Override public void destroy(OpenTelemetry openTelemetry, CreationalContext creationalContext, Map params) { if (openTelemetry instanceof OpenTelemetrySdk) { + // between flush and shutdown we will wait shutdown-wait-time, at the most. + var waitTime = getShutdownWaitTime().dividedBy(2); var openTelemetrySdk = ((OpenTelemetrySdk) openTelemetry); - openTelemetrySdk.getSdkTracerProvider().forceFlush(); - openTelemetrySdk.getSdkTracerProvider().shutdown(); + openTelemetrySdk.getSdkTracerProvider().forceFlush().join(waitTime.toMillis(), MILLISECONDS); + openTelemetrySdk.getSdkTracerProvider().shutdown().join(waitTime.toMillis(), MILLISECONDS); } } + + public static Duration getShutdownWaitTime() { + var config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class); + var waitTime = config.getOptionalValue("quarkus.otel.experimental.shutdown-wait-time", Duration.class) + .orElse(Duration.ofSeconds(1)); + return waitTime; + } } diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java index b7eb750b2e36f..d38e1fc83fe7a 100644 --- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java +++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java @@ -1,5 +1,6 @@ package io.quarkus.opentelemetry.runtime.config.runtime; +import java.time.Duration; import java.util.List; import java.util.Optional; @@ -63,4 +64,11 @@ public interface OTelRuntimeConfig { */ @WithName("experimental.resource.disabled-keys") Optional> experimentalResourceDisabledKeys(); + + /** + * The maximum amount of time Quarkus will wait for the OpenTelemetry SDK to flush unsent spans and shutdown. + */ + @WithName("experimental.shutdown-wait-time") + @WithDefault("1s") + Duration experimentalShutdownWaitTime(); } From 3ab5f2ad856462017574ae56aca074c63c9b6235 Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Fri, 20 Oct 2023 15:14:08 +0100 Subject: [PATCH 12/29] [#36582] Fix bug: TransactionalUniAsserter never fails TransactionalUniAsserterTestMethodInvoker is a subclass of RunOnVertxContextTestMethodInvoker. The problem is that there were two separate pointers keeping track of the asserter in the superclass and in the subclass. This lead to only one pointer being initialized and, if the wrong pointer was null-checked, the asserter was ignored causing the test to never fail. This commit fixes the issue by keeping only one reference to the asserter in the superclass. (cherry picked from commit 5ddc8e58ef30991f73c82d0e6f209ffa6f31395e) --- ...sactionalUniAsserterTestMethodInvoker.java | 11 ++------ .../test/vertx/DefaultUniAsserter.java | 5 ++++ .../RunOnVertxContextTestMethodInvoker.java | 27 ++++++++++--------- .../io/quarkus/test/vertx/UniAsserter.java | 5 ++++ .../test/vertx/UniAsserterInterceptor.java | 4 +++ 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserterTestMethodInvoker.java b/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserterTestMethodInvoker.java index 0ff7c21d95427..30808f3c76b07 100644 --- a/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserterTestMethodInvoker.java +++ b/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserterTestMethodInvoker.java @@ -8,21 +8,14 @@ public class TransactionalUniAsserterTestMethodInvoker extends RunOnVertxContextTestMethodInvoker { - private UniAsserter uniAsserter; - @Override public boolean handlesMethodParamType(String paramClassName) { return TransactionalUniAsserter.class.getName().equals(paramClassName); } @Override - public Object methodParamInstance(String paramClassName) { - if (!handlesMethodParamType(paramClassName)) { - throw new IllegalStateException( - "TransactionalUniAsserterTestMethodInvoker does not handle '" + paramClassName + "' method param types"); - } - uniAsserter = new TransactionalUniAsserter(new DefaultUniAsserter()); - return uniAsserter; + protected UniAsserter createUniAsserter() { + return new TransactionalUniAsserter(new DefaultUniAsserter()); } @Override diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java index 43397c98bda64..e5f8ff9ece395 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java @@ -22,6 +22,11 @@ public DefaultUniAsserter() { this.data = new ConcurrentHashMap<>(); } + @Override + public Uni asUni() { + return execution; + } + @SuppressWarnings("unchecked") @Override public UniAsserter assertThat(Supplier> uni, Consumer asserter) { diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java index 12400237b804a..ca55758fd9d46 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java @@ -21,7 +21,7 @@ public class RunOnVertxContextTestMethodInvoker implements TestMethodInvoker { - private DefaultUniAsserter uniAsserter; + private UniAsserter uniAsserter; @Override public boolean handlesMethodParamType(String paramClassName) { @@ -32,12 +32,16 @@ public boolean handlesMethodParamType(String paramClassName) { public Object methodParamInstance(String paramClassName) { if (!handlesMethodParamType(paramClassName)) { throw new IllegalStateException( - "RunOnVertxContextTestMethodInvoker does not handle '" + paramClassName + "' method param types"); + this.getClass().getName() + " does not handle '" + paramClassName + "' method param types"); } - uniAsserter = new DefaultUniAsserter(); + uniAsserter = createUniAsserter(); return uniAsserter; } + protected UniAsserter createUniAsserter() { + return new DefaultUniAsserter(); + } + @Override public boolean supportsMethod(Class originalTestClass, Method originalTestMethod) { return hasSupportedAnnotation(originalTestClass, originalTestMethod) @@ -152,11 +156,11 @@ public void run() { private final Object testInstance; private final Method targetMethod; private final List methodArgs; - private final DefaultUniAsserter uniAsserter; + private final UniAsserter uniAsserter; private final CompletableFuture future; public RunTestMethodOnVertxEventLoopContextHandler(Object testInstance, Method targetMethod, List methodArgs, - DefaultUniAsserter uniAsserter, CompletableFuture future) { + UniAsserter uniAsserter, CompletableFuture future) { this.testInstance = testInstance; this.future = future; this.targetMethod = targetMethod; @@ -184,7 +188,7 @@ private void doRun(Runnable onTerminate) { try { Object testMethodResult = targetMethod.invoke(testInstance, methodArgs.toArray(new Object[0])); if (uniAsserter != null) { - uniAsserter.execution.subscribe().with(new Consumer() { + uniAsserter.asUni().subscribe().with(new Consumer() { @Override public void accept(Object o) { onTerminate.run(); @@ -209,19 +213,16 @@ public void accept(Throwable t) { } public static class RunTestMethodOnVertxBlockingContextHandler implements Handler> { - private static final Runnable DO_NOTHING = new Runnable() { - @Override - public void run() { - } + private static final Runnable DO_NOTHING = () -> { }; private final Object testInstance; private final Method targetMethod; private final List methodArgs; - private final DefaultUniAsserter uniAsserter; + private final UniAsserter uniAsserter; public RunTestMethodOnVertxBlockingContextHandler(Object testInstance, Method targetMethod, List methodArgs, - DefaultUniAsserter uniAsserter) { + UniAsserter uniAsserter) { this.testInstance = testInstance; this.targetMethod = targetMethod; this.methodArgs = methodArgs; @@ -248,7 +249,7 @@ private void doRun(Promise promise, Runnable onTerminate) { try { Object testMethodResult = targetMethod.invoke(testInstance, methodArgs.toArray(new Object[0])); if (uniAsserter != null) { - uniAsserter.execution.subscribe().with(new Consumer() { + uniAsserter.asUni().subscribe().with(new Consumer() { @Override public void accept(Object o) { onTerminate.run(); diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java index 5abe24c09dfd4..803d8725e9a3b 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java @@ -144,4 +144,9 @@ public interface UniAsserter { * Clear the test data. */ void clearData(); + + /** + * @return a {@link Uni} representing the operations pipeline up to this point + */ + Uni asUni(); } diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java index 511aae9c172d6..d622a5459436a 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java @@ -190,4 +190,8 @@ public void clearData() { delegate.clearData(); } + @Override + public Uni asUni() { + return delegate.asUni(); + } } \ No newline at end of file From 4cacc782eac1a17353467d08e9a6c0524502cf08 Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Tue, 31 Oct 2023 11:13:51 +0100 Subject: [PATCH 13/29] [#36582] Minor clean up in TransactionalUniAsserterTest Use method reference where possible (cherry picked from commit b44a56c9f0b3bef26a1103b3ca159ec038ed3487) --- .../it/panache/reactive/TransactionalUniAsserterTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java b/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java index 4f6abb0de637b..e04ce655b113f 100644 --- a/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java +++ b/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java @@ -18,12 +18,12 @@ public class TransactionalUniAsserterTest { @Test public void testTransactionalUniAsserter(TransactionalUniAsserter asserter) { assertNotNull(asserter); - asserter.assertThat(() -> Panache.currentTransaction(), transaction -> { + asserter.assertThat(Panache::currentTransaction, transaction -> { assertNotNull(transaction); assertFalse(transaction.isMarkedForRollback()); asserter.putData("tx", transaction); }); - asserter.assertThat(() -> Panache.currentTransaction(), transaction -> { + asserter.assertThat(Panache::currentTransaction, transaction -> { assertNotNull(transaction); assertFalse(transaction.isMarkedForRollback()); assertNotEquals(transaction, asserter.getData("tx")); From b070b364f421a9f63cebd93f87dd35fc9df79f51 Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Tue, 31 Oct 2023 15:26:24 +0100 Subject: [PATCH 14/29] [#36582] Minor clean up around lambdas (cherry picked from commit a29061e81fba4ad0baf9a481ddd16ee98d504c35) --- .../panache/common/runtime/SessionOperations.java | 14 +++++--------- .../reactive/panache/TransactionalUniAsserter.java | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java index 5f9dcc14f1587..d2345e63cb5f7 100644 --- a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java +++ b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java @@ -85,9 +85,7 @@ static Uni withSessionOnDemand(Supplier> work) { * @return a new {@link Uni} */ public static Uni withTransaction(Supplier> work) { - return withSession(s -> { - return s.withTransaction(t -> work.get()); - }); + return withSession(s -> s.withTransaction(t -> work.get())); } /** @@ -98,9 +96,7 @@ public static Uni withTransaction(Supplier> work) { * @return a new {@link Uni} */ public static Uni withTransaction(Function> work) { - return withSession(s -> { - return s.withTransaction(t -> work.apply(t)); - }); + return withSession(s -> s.withTransaction(work)); } /** @@ -122,8 +118,8 @@ public static Uni withSession(Function> work) { return getSessionFactory() .openSession() .invoke(s -> context.putLocal(key, s)) - .chain(s -> work.apply(s)) - .eventually(() -> closeSession()); + .chain(work::apply) + .eventually(SessionOperations::closeSession); } } @@ -152,7 +148,7 @@ public static Uni getSession() { if (context.getLocal(SESSION_ON_DEMAND_KEY) != null) { if (context.getLocal(SESSION_ON_DEMAND_OPENED_KEY) != null) { // a new reactive session is opened in a previous stage - return Uni.createFrom().item(() -> getCurrentSession()); + return Uni.createFrom().item(SessionOperations::getCurrentSession); } else { // open a new reactive session and store it in the vertx duplicated context // the context was marked as "lazy" which means that the session will be eventually closed diff --git a/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserter.java b/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserter.java index c93868235de1d..9fec68942d232 100644 --- a/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserter.java +++ b/test-framework/hibernate-reactive-panache/src/main/java/io/quarkus/test/hibernate/reactive/panache/TransactionalUniAsserter.java @@ -20,7 +20,7 @@ public final class TransactionalUniAsserter extends UniAsserterInterceptor { @Override protected Supplier> transformUni(Supplier> uniSupplier) { - return () -> SessionOperations.withTransaction(() -> uniSupplier.get()); + return () -> SessionOperations.withTransaction(uniSupplier); } } \ No newline at end of file From 441ee6e820138e27840a359a71207346f28b8aee Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Tue, 31 Oct 2023 15:27:59 +0100 Subject: [PATCH 15/29] [#36582] Add UnwrappableUniAsserter interface The goal is to extract the `asUni()` method from `UniAsserter` (cherry picked from commit c44eab767a1639c80b58b3dd98a279429660548e) --- .../quarkus/test/vertx/DefaultUniAsserter.java | 2 +- .../RunOnVertxContextTestMethodInvoker.java | 8 ++++---- .../java/io/quarkus/test/vertx/UniAsserter.java | 5 ----- .../test/vertx/UniAsserterInterceptor.java | 4 ++-- .../test/vertx/UnwrappableUniAsserter.java | 17 +++++++++++++++++ 5 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 test-framework/vertx/src/main/java/io/quarkus/test/vertx/UnwrappableUniAsserter.java diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java index e5f8ff9ece395..d983369c88704 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/DefaultUniAsserter.java @@ -10,7 +10,7 @@ import io.smallrye.mutiny.Uni; -public final class DefaultUniAsserter implements UniAsserter { +public final class DefaultUniAsserter implements UnwrappableUniAsserter { private final ConcurrentMap data; diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java index ca55758fd9d46..734891926397b 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/RunOnVertxContextTestMethodInvoker.java @@ -156,7 +156,7 @@ public void run() { private final Object testInstance; private final Method targetMethod; private final List methodArgs; - private final UniAsserter uniAsserter; + private final UnwrappableUniAsserter uniAsserter; private final CompletableFuture future; public RunTestMethodOnVertxEventLoopContextHandler(Object testInstance, Method targetMethod, List methodArgs, @@ -165,7 +165,7 @@ public RunTestMethodOnVertxEventLoopContextHandler(Object testInstance, Method t this.future = future; this.targetMethod = targetMethod; this.methodArgs = methodArgs; - this.uniAsserter = uniAsserter; + this.uniAsserter = (UnwrappableUniAsserter) uniAsserter; } @Override @@ -219,14 +219,14 @@ public static class RunTestMethodOnVertxBlockingContextHandler implements Handle private final Object testInstance; private final Method targetMethod; private final List methodArgs; - private final UniAsserter uniAsserter; + private final UnwrappableUniAsserter uniAsserter; public RunTestMethodOnVertxBlockingContextHandler(Object testInstance, Method targetMethod, List methodArgs, UniAsserter uniAsserter) { this.testInstance = testInstance; this.targetMethod = targetMethod; this.methodArgs = methodArgs; - this.uniAsserter = uniAsserter; + this.uniAsserter = (UnwrappableUniAsserter) uniAsserter; } @Override diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java index 803d8725e9a3b..5abe24c09dfd4 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserter.java @@ -144,9 +144,4 @@ public interface UniAsserter { * Clear the test data. */ void clearData(); - - /** - * @return a {@link Uni} representing the operations pipeline up to this point - */ - Uni asUni(); } diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java index d622a5459436a..90a0f713820d7 100644 --- a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UniAsserterInterceptor.java @@ -65,7 +65,7 @@ * * */ -public abstract class UniAsserterInterceptor implements UniAsserter { +public abstract class UniAsserterInterceptor implements UnwrappableUniAsserter { private final UniAsserter delegate; @@ -192,6 +192,6 @@ public void clearData() { @Override public Uni asUni() { - return delegate.asUni(); + return ((UnwrappableUniAsserter) delegate).asUni(); } } \ No newline at end of file diff --git a/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UnwrappableUniAsserter.java b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UnwrappableUniAsserter.java new file mode 100644 index 0000000000000..613b0d3eaafad --- /dev/null +++ b/test-framework/vertx/src/main/java/io/quarkus/test/vertx/UnwrappableUniAsserter.java @@ -0,0 +1,17 @@ +package io.quarkus.test.vertx; + +import io.smallrye.mutiny.Uni; + +/** + * A {@link UniAsserter} that exposes the internal {@link Uni}. + *

+ * We've added this interface so that we don't expose the method {@link #asUni()} to the user + *

+ */ +interface UnwrappableUniAsserter extends UniAsserter { + + /** + * @return a {@link Uni} representing the operations pipeline up to this point + */ + Uni asUni(); +} From 5f3fcbaebcb8507873ab464faaddf3da9a9b6b1a Mon Sep 17 00:00:00 2001 From: sahuefficy <139977482+sahuefficy@users.noreply.github.com> Date: Thu, 2 Nov 2023 14:09:01 +0100 Subject: [PATCH 16/29] Duplicate Authorization Bearer Header Fix (cherry picked from commit 3c880cb8af0ffb78b33bce4ac19ce3df694a97aa) --- .../propagation/reactive/AccessTokenRequestReactiveFilter.java | 2 +- .../token/propagation/runtime/AbstractTokenRequestFilter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/oidc-token-propagation-reactive/runtime/src/main/java/io/quarkus/oidc/token/propagation/reactive/AccessTokenRequestReactiveFilter.java b/extensions/oidc-token-propagation-reactive/runtime/src/main/java/io/quarkus/oidc/token/propagation/reactive/AccessTokenRequestReactiveFilter.java index c965359200950..020ba75a00c7d 100644 --- a/extensions/oidc-token-propagation-reactive/runtime/src/main/java/io/quarkus/oidc/token/propagation/reactive/AccessTokenRequestReactiveFilter.java +++ b/extensions/oidc-token-propagation-reactive/runtime/src/main/java/io/quarkus/oidc/token/propagation/reactive/AccessTokenRequestReactiveFilter.java @@ -124,7 +124,7 @@ protected String getClientName() { public void propagateToken(ResteasyReactiveClientRequestContext requestContext, String accessToken) { if (accessToken != null) { - requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, BEARER_SCHEME_WITH_SPACE + accessToken); + requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, BEARER_SCHEME_WITH_SPACE + accessToken); } else { LOG.debugf("Access token is null, aborting the request with HTTP 401 error"); abortRequest(requestContext); diff --git a/extensions/oidc-token-propagation/runtime/src/main/java/io/quarkus/oidc/token/propagation/runtime/AbstractTokenRequestFilter.java b/extensions/oidc-token-propagation/runtime/src/main/java/io/quarkus/oidc/token/propagation/runtime/AbstractTokenRequestFilter.java index 78026c2ef3856..dd2c5fbdadc78 100644 --- a/extensions/oidc-token-propagation/runtime/src/main/java/io/quarkus/oidc/token/propagation/runtime/AbstractTokenRequestFilter.java +++ b/extensions/oidc-token-propagation/runtime/src/main/java/io/quarkus/oidc/token/propagation/runtime/AbstractTokenRequestFilter.java @@ -23,7 +23,7 @@ public abstract class AbstractTokenRequestFilter implements ClientRequestFilter public void propagateToken(ClientRequestContext requestContext, String token) throws IOException { if (token != null) { - requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, BEARER_SCHEME_WITH_SPACE + token); + requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, BEARER_SCHEME_WITH_SPACE + token); } else { LOG.debugf("Injected access token is null, aborting the request with HTTP 401 error"); abortRequest(requestContext); From acf2faf9209cbfa4e23ab434eb99de3a9b2847b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Thu, 2 Nov 2023 13:35:47 +0100 Subject: [PATCH 17/29] More reliable test setup in integration-tests/hibernate-orm-tenancy/datasource The previous config was relying on FlyWay on a default datasource to create other databases which named datasources pointed at. Which works well, until a named datasource gets initialized before the default datasource; then named datasource initialization fails because the corresponding database doesn't exist yet. This happened on my local laptop, I don't know why it didn't happen on CI. (cherry picked from commit 5da533e91289350c4627ae791a92ff1895750228) --- .../hibernate-orm-tenancy/datasource/README.md | 12 ++++++++---- .../init.sql} | 0 .../hibernate-orm-tenancy/datasource/pom.xml | 4 ++++ .../src/main/resources/application.properties | 14 ++------------ 4 files changed, 14 insertions(+), 16 deletions(-) rename integration-tests/hibernate-orm-tenancy/datasource/{src/main/resources/database/default/V1.0.0__init_databases.sql => custom-mariadbconfig/init.sql} (100%) diff --git a/integration-tests/hibernate-orm-tenancy/datasource/README.md b/integration-tests/hibernate-orm-tenancy/datasource/README.md index 2bca5f5173f79..1f752bfdf5d78 100644 --- a/integration-tests/hibernate-orm-tenancy/datasource/README.md +++ b/integration-tests/hibernate-orm-tenancy/datasource/README.md @@ -19,7 +19,9 @@ Additionally, you can generate a native image and run the tests for this native mvn clean install -Dtest-containers -Dstart-containers -Dnative ``` -If you don't want to run MariaDB as a Docker container, you can start your own MariaDB server. It needs to listen on the default port and have a database called `hibernate_orm_test` and a root user with the password `secret`. +If you don't want to run MariaDB as a Docker container, you can start your own MariaDB server. +It needs to listen on the default port and have a database called `hibernate_orm_test` and a root user with the password `secret`, +and it needs to be initialized with the SQL script found at `custom-mariadbconfig/init.sql`. You can then run the tests as follows (either with `-Dnative` or not): @@ -34,18 +36,20 @@ should not include the database name: check the `application.properties` to see To run the MariaDB server "manually" via command line for testing, the following command line could be useful: ``` -docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name quarkus_test_mariadb -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 mariadb:10.4 +docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name quarkus_test_mariadb -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=secret -p 3308:3306 mariadb:10.4 ``` or if you prefer podman, this won't need root permissions: ``` -podman run --rm=true --net=host --memory-swappiness=0 --tmpfs /var/lib/mysql:rw --tmpfs /var/log:rw --name mariadb_demo -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 mariadb:10.4 +podman run --rm=true --net=host --memory-swappiness=0 --tmpfs /var/lib/mysql:rw --tmpfs /var/log:rw --name mariadb_demo -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=secret -p 3308:3306 mariadb:10.4 ``` N.B. it takes a while for MariaDB to be actually booted and accepting connections. -After it's fully booted, you can run all integration tests via +After it's fully booted you will then need to initialize the database with the SQL script found at `custom-mariadbconfig/init.sql`. + +Once that's done, you can run all integration tests via: ``` mvn clean install -Dtest-containers -Dnative diff --git a/integration-tests/hibernate-orm-tenancy/datasource/src/main/resources/database/default/V1.0.0__init_databases.sql b/integration-tests/hibernate-orm-tenancy/datasource/custom-mariadbconfig/init.sql similarity index 100% rename from integration-tests/hibernate-orm-tenancy/datasource/src/main/resources/database/default/V1.0.0__init_databases.sql rename to integration-tests/hibernate-orm-tenancy/datasource/custom-mariadbconfig/init.sql diff --git a/integration-tests/hibernate-orm-tenancy/datasource/pom.xml b/integration-tests/hibernate-orm-tenancy/datasource/pom.xml index 6827b0e827a3d..c4a24840b1ad3 100644 --- a/integration-tests/hibernate-orm-tenancy/datasource/pom.xml +++ b/integration-tests/hibernate-orm-tenancy/datasource/pom.xml @@ -254,6 +254,10 @@ true + + true + bash -c eval\ ${@} -- mysql -h localhost -uroot -psecret </etc/mysql/conf.d/init.sql + diff --git a/integration-tests/hibernate-orm-tenancy/datasource/src/main/resources/application.properties b/integration-tests/hibernate-orm-tenancy/datasource/src/main/resources/application.properties index 61361b4b3ffcb..2243f12a04de1 100644 --- a/integration-tests/hibernate-orm-tenancy/datasource/src/main/resources/application.properties +++ b/integration-tests/hibernate-orm-tenancy/datasource/src/main/resources/application.properties @@ -1,19 +1,9 @@ # Hibernate ORM settings quarkus.hibernate-orm.database.generation=none quarkus.hibernate-orm.multitenant=database +quarkus.hibernate-orm.datasource=base quarkus.hibernate-orm.packages=io.quarkus.it.hibernate.multitenancy.fruit -# Default DB Configuration -quarkus.datasource.db-kind=mariadb -quarkus.datasource.username=root -quarkus.datasource.password=secret -quarkus.datasource.jdbc.url=${mariadb.base_url}/hibernate_orm_test -quarkus.datasource.jdbc.max-size=1 -quarkus.flyway.migrate-at-start=true -#Reset Flyway metadata at boot, as the database might have been tainted by previous integration tests: -quarkus.flyway.clean-at-start=true -quarkus.flyway.locations=classpath:database/default - # DATABASE Tenant 'base' Configuration quarkus.datasource.base.db-kind=mariadb quarkus.datasource.base.username=jane @@ -37,7 +27,7 @@ quarkus.flyway.mycompany.locations=classpath:database/mycompany # Inventory persistence unit quarkus.hibernate-orm."inventory".database.generation=none quarkus.hibernate-orm."inventory".multitenant=database -quarkus.hibernate-orm."inventory".datasource= +quarkus.hibernate-orm."inventory".datasource=inventory quarkus.hibernate-orm."inventory".packages=io.quarkus.it.hibernate.multitenancy.inventory # DATABASE Tenant 'inventory' / 'base' Configuration From de32f8cdb3bbd9974e3803bb01a4b108cfd1fe09 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 3 Nov 2023 09:50:28 +0200 Subject: [PATCH 18/29] Remove erroneous preview status from cache doc (cherry picked from commit 53474272d71c7ddc98a05be61250519aad8bec46) --- docs/src/main/asciidoc/cache.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/main/asciidoc/cache.adoc b/docs/src/main/asciidoc/cache.adoc index b85ea2babbf30..2b711ed7ff187 100644 --- a/docs/src/main/asciidoc/cache.adoc +++ b/docs/src/main/asciidoc/cache.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Application Data Caching -:extension-status: preview include::_attributes.adoc[] :categories: data :summary: This guide explains how to cache expensive method calls of your CDI beans using simple annotations. From 8d1fee56db7065c13e1905814119fad3513841cd Mon Sep 17 00:00:00 2001 From: Robert Stupp Date: Tue, 31 Oct 2023 15:12:39 +0100 Subject: [PATCH 19/29] Quarkus code-gen (Gradle): Fix behavior to filter unavailable services Java Services (those in `META-INF/services/*` files) that are defined in the (Gradle) project that uses the Quarkus Gradle plugin, are not available when Quarkus code generation runs. This is simply a task-dependency requirement in Gradle, because Java compilation happens after code generation. If a Java service, for example a Smallrye config sources, is present and the (Smallrye) configuration is needed by a Quarkus extension, the build fails during Quarkus code generation with an error message like this: ``` org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':quarkusGenerateCode'. ... Caused by: org.gradle.workers.internal.DefaultWorkerExecutor$WorkExecutionException: A failure occurred while executing io.quarkus.gradle.tasks.worker.CodeGenWorker ... Caused by: java.util.ServiceConfigurationError: io.smallrye.config.ConfigSourceFactory: Provider xyz not found ``` `io.quarkus.deployment.CodeGenerator` has a mechanism to filter out unavailable services via `getUnavailableConfigServices()`. However the callback passed to `io.quarkus.paths.PathTree.apply()` can stop before all roots/trees (`io.quarkus.paths.PathTree.getRoots()`) have been "asked" (`MultiRootPathTree`), because the callback can return a non-`null` value. This "early stop" happens before the root/tree containing the source with the `META-INF/services/*` has been processed. The bug is only triggered, if a Java service is defined in the Gradle project using the Quarkus Gradle plugin and if a Quarkus extension using the configuration is a dependency of that project. This change updates the callback implementation to collect all unavailable services from all `PathTree` roots/trees. An integration test using the Gradle plugin is included as well. Two logging/spelling mistakes have been fixed as well. Fixes #36716 (cherry picked from commit 6c895d0c2dfadb24a74b48e8d4ba4494ecb6a227) --- .../io/quarkus/deployment/CodeGenerator.java | 35 +++++++++---------- .../gradle/tasks/QuarkusGenerateCode.java | 2 +- .../gradle/tasks/worker/CodeGenWorker.java | 3 +- .../custom-config-sources/build.gradle | 23 ++++++++++++ .../custom-config-sources/gradle.properties | 2 ++ .../custom-config-sources/settings.gradle | 15 ++++++++ .../java/org/acme/InMemoryConfigSource.java | 35 +++++++++++++++++++ .../java/org/acme/MyConfigSourceFactory.java | 14 ++++++++ .../io.smallrye.config.ConfigSourceFactory | 1 + ...lipse.microprofile.config.spi.ConfigSource | 1 + .../src/main/resources/application.properties | 1 + .../gradle/CustomConfigSourcesTest.java | 19 ++++++++++ 12 files changed, 130 insertions(+), 21 deletions(-) create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/build.gradle create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/gradle.properties create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/settings.gradle create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/InMemoryConfigSource.java create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/MyConfigSourceFactory.java create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource create mode 100644 integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/application.properties create mode 100644 integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomConfigSourcesTest.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java index 645d64d08a2d8..b93d0b96b25bc 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java @@ -346,39 +346,36 @@ public static T readConfig(ApplicationModel appModel, LaunchMode launchMode, private static Map> getUnavailableConfigServices(ResolvedDependency dep, ClassLoader classLoader) throws CodeGenException { try (OpenPathTree openTree = dep.getContentTree().open()) { - return openTree.apply(META_INF_SERVICES, visit -> { + var unavailableServices = new HashMap>(); + openTree.apply(META_INF_SERVICES, visit -> { if (visit == null) { - // the application module does not include META-INF/services entry - return Map.of(); + // the application module does not include META-INF/services entry. Return `null` here, to let + // MultiRootPathTree.apply() look into all roots. + return null; } - Map> unavailableServices = Map.of(); var servicesDir = visit.getPath(); for (String serviceClass : CONFIG_SERVICES) { var serviceFile = servicesDir.resolve(serviceClass); if (!Files.exists(serviceFile)) { continue; } - final List implList; + var unavailableList = unavailableServices.computeIfAbsent(META_INF_SERVICES + serviceClass, + k -> new ArrayList<>()); try { - implList = Files.readAllLines(serviceFile); + Files.readAllLines(serviceFile).stream() + .map(String::trim) + // skip comments and empty lines + .filter(line -> !line.startsWith("#") && !line.isEmpty()) + .filter(className -> classLoader.getResource(className.replace('.', '/') + ".class") == null) + .forEach(unavailableList::add); } catch (IOException e) { throw new UncheckedIOException("Failed to read " + serviceFile, e); } - final List unavailableList = new ArrayList<>(implList.size()); - for (String impl : implList) { - if (classLoader.getResource(impl.replace('.', '/') + ".class") == null) { - unavailableList.add(impl); - } - } - if (!unavailableList.isEmpty()) { - if (unavailableServices.isEmpty()) { - unavailableServices = new HashMap<>(); - } - unavailableServices.put(META_INF_SERVICES + serviceClass, unavailableList); - } } - return unavailableServices; + // Always return null to let MultiRootPathTree.apply() look into all roots. + return null; }); + return unavailableServices; } catch (IOException e) { throw new CodeGenException("Failed to read " + dep.getResolvedPaths(), e); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java index 3e9c6c02cf304..b01ffdb6732f0 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java @@ -106,7 +106,7 @@ public void generateCode() { File outputPath = getGeneratedOutputDirectory().get().getAsFile(); - getLogger().debug("Will trigger preparing sources for source directory: {} buildDir: {}", + getLogger().debug("Will trigger preparing sources for source directories: {} buildDir: {}", sourcesDirectories, buildDir.getAbsolutePath()); WorkQueue workQueue = workQueue(configMap, () -> extension().codeGenForkOptions); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/worker/CodeGenWorker.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/worker/CodeGenWorker.java index efa9bc1fd7668..fa79bbbe36928 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/worker/CodeGenWorker.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/worker/CodeGenWorker.java @@ -86,7 +86,8 @@ public void execute() { } catch (BootstrapException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { // Gradle "abbreviates" the stacktrace to something human-readable, but here the underlying cause might // get lost in the error output, so add 'e' to the message. - throw new GradleException("Failed to generate sources in the QuarkusPrepare task for " + gav + " due to " + e, e); + throw new GradleException("Failed to generate sources in the QuarkusGenerateCode task for " + gav + " due to " + e, + e); } } } diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/build.gradle b/integration-tests/gradle/src/main/resources/custom-config-sources/build.gradle new file mode 100644 index 0000000000000..2dbbb90a158e7 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/build.gradle @@ -0,0 +1,23 @@ +plugins { + id 'java' + id 'io.quarkus' +} + +repositories { + mavenLocal { + content { + includeGroupByRegex 'io.quarkus.*' + } + } + mavenCentral() +} + +dependencies { + implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") + implementation "io.quarkus:quarkus-grpc" // Need a `CodeGenProvider` on the class path for this test! + compileOnly "io.smallrye.config:smallrye-config-core" +} + +compileJava { + options.compilerArgs << '-parameters' +} diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/gradle.properties b/integration-tests/gradle/src/main/resources/custom-config-sources/gradle.properties new file mode 100644 index 0000000000000..ec2b6ef199c2c --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/gradle.properties @@ -0,0 +1,2 @@ +quarkusPlatformArtifactId=quarkus-bom +quarkusPlatformGroupId=io.quarkus diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/settings.gradle b/integration-tests/gradle/src/main/resources/custom-config-sources/settings.gradle new file mode 100644 index 0000000000000..171b346e0e750 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + mavenLocal { + content { + includeGroupByRegex 'io.quarkus.*' + } + } + mavenCentral() + gradlePluginPortal() + } + plugins { + id 'io.quarkus' version "${quarkusPluginVersion}" + } +} +rootProject.name='custom-config-sources' diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/InMemoryConfigSource.java b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/InMemoryConfigSource.java new file mode 100644 index 0000000000000..b63ec196a074e --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/InMemoryConfigSource.java @@ -0,0 +1,35 @@ +package org.acme; + +import org.eclipse.microprofile.config.spi.ConfigSource; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class InMemoryConfigSource implements ConfigSource { + private static final Map configuration = new HashMap<>(); + + static { + configuration.put("my.prop", "1234"); + } + + @Override + public int getOrdinal() { + return 275; + } + + @Override + public Set getPropertyNames() { + return configuration.keySet(); + } + + @Override + public String getValue(final String propertyName) { + return configuration.get(propertyName); + } + + @Override + public String getName() { + return InMemoryConfigSource.class.getSimpleName(); + } +} diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/MyConfigSourceFactory.java b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/MyConfigSourceFactory.java new file mode 100644 index 0000000000000..e8d1e05f517fe --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/java/org/acme/MyConfigSourceFactory.java @@ -0,0 +1,14 @@ +package org.acme; + +import io.smallrye.config.ConfigSourceContext; +import io.smallrye.config.ConfigSourceFactory; +import org.eclipse.microprofile.config.spi.ConfigSource; + +import java.util.List; + +public class MyConfigSourceFactory implements ConfigSourceFactory { + @Override + public Iterable getConfigSources(ConfigSourceContext context) { + return List.of(new InMemoryConfigSource()); + } +} diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory new file mode 100644 index 0000000000000..d8f8a6fb31a63 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory @@ -0,0 +1 @@ +org.acme.MyConfigSourceFactory \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource new file mode 100644 index 0000000000000..934c1492c8bd5 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource @@ -0,0 +1 @@ +org.acme.InMemoryConfigSource \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/application.properties b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/application.properties new file mode 100644 index 0000000000000..c2480799c946c --- /dev/null +++ b/integration-tests/gradle/src/main/resources/custom-config-sources/src/main/resources/application.properties @@ -0,0 +1 @@ +# Need an empty application.properties to trigger config loading mandatory for CustomConfigSourcesTest \ No newline at end of file diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomConfigSourcesTest.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomConfigSourcesTest.java new file mode 100644 index 0000000000000..74dcd95fa3960 --- /dev/null +++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomConfigSourcesTest.java @@ -0,0 +1,19 @@ +package io.quarkus.gradle; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class CustomConfigSourcesTest extends QuarkusGradleWrapperTestBase { + + @Test + public void testCustomConfigSources() throws Exception { + var projectDir = getProjectDir("custom-config-sources"); + + // The test is successful, if the build works, see https://github.com/quarkusio/quarkus/issues/36716 + runGradleWrapper(projectDir, "clean", "build", "--no-build-cache"); + + var p = projectDir.toPath().resolve("build").resolve("quarkus-app").resolve("quarkus-run.jar"); + assertThat(p).exists(); + } +} From 88085e6dce611c355a23a771ad2d26735129dfc1 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 3 Nov 2023 13:20:30 +0000 Subject: [PATCH 20/29] Fix OIDC key resolver to accept SHA256 certificate thumbprints (cherry picked from commit 96ed6484055be943094ebc8d7e76721088b8c581) --- .../quarkus/oidc/runtime/JsonWebKeySet.java | 12 ++++- .../io/quarkus/oidc/runtime/OidcProvider.java | 26 ++++++++- .../BearerTokenAuthorizationTest.java | 53 +++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/JsonWebKeySet.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/JsonWebKeySet.java index 5fd11a6ed7033..5e80ddfb94b17 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/JsonWebKeySet.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/JsonWebKeySet.java @@ -28,6 +28,7 @@ public class JsonWebKeySet { private Map keysWithKeyId = new HashMap<>(); private Map keysWithThumbprints = new HashMap<>(); + private Map keysWithS256Thumbprints = new HashMap<>(); private Map> keysWithoutKeyIdAndThumbprint = new HashMap<>(); public JsonWebKeySet(String json) { @@ -48,7 +49,12 @@ private void initKeys(String json) { if (x5t != null && jwkKey.getKey() != null) { keysWithThumbprints.put(x5t, jwkKey.getKey()); } - if (jwkKey.getKeyId() == null && x5t == null && jwkKey.getKeyType() != null) { + String x5tS256 = ((PublicJsonWebKey) jwkKey) + .getX509CertificateSha256Thumbprint(calculateThumbprintIfMissing); + if (x5tS256 != null && jwkKey.getKey() != null) { + keysWithS256Thumbprints.put(x5tS256, jwkKey.getKey()); + } + if (jwkKey.getKeyId() == null && x5t == null && x5tS256 == null && jwkKey.getKeyType() != null) { List keys = keysWithoutKeyIdAndThumbprint.get(jwkKey.getKeyType()); if (keys == null) { keys = new ArrayList<>(); @@ -76,6 +82,10 @@ public Key getKeyWithThumbprint(String x5t) { return keysWithThumbprints.get(x5t); } + public Key getKeyWithS256Thumbprint(String x5tS256) { + return keysWithS256Thumbprints.get(x5tS256); + } + public Key getKeyWithoutKeyIdAndThumbprint(JsonWebSignature jws) { try { List keys = keysWithoutKeyIdAndThumbprint.get(jws.getKeyType()); diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java index 1bed63a554926..32bbc806e2d6c 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java @@ -395,7 +395,19 @@ public Key resolveKey(JsonWebSignature jws, List nestingContex if (key == null) { // if only `x5t` was set then the key must exist throw new UnresolvableKeyException( - String.format("JWK with thumbprint '%s' is not available", thumbprint)); + String.format("JWK with the certificate thumbprint '%s' is not available", thumbprint)); + } + } + } + + if (key == null) { + thumbprint = jws.getHeader(HeaderParameterNames.X509_CERTIFICATE_SHA256_THUMBPRINT); + if (thumbprint != null) { + key = getKeyWithS256Thumbprint(jws, thumbprint); + if (key == null) { + // if only `x5tS256` was set then the key must exist + throw new UnresolvableKeyException( + String.format("JWK with the SHA256 certificate thumbprint '%s' is not available", thumbprint)); } } } @@ -406,7 +418,8 @@ public Key resolveKey(JsonWebSignature jws, List nestingContex if (key == null) { throw new UnresolvableKeyException( - String.format("JWK is not available, neither 'kid' nor 'x5t' token headers are set", kid)); + String.format("JWK is not available, neither 'kid' nor 'x5t#S256' nor 'x5t' token headers are set", + kid)); } else { return key; } @@ -430,6 +443,15 @@ private Key getKeyWithThumbprint(JsonWebSignature jws, String thumbprint) { } } + private Key getKeyWithS256Thumbprint(JsonWebSignature jws, String thumbprint) { + if (thumbprint != null) { + return jwks.getKeyWithS256Thumbprint(thumbprint); + } else { + LOG.debug("Token 'x5tS256' header is not set"); + return null; + } + } + public Uni refresh() { final long now = now(); if (now > lastForcedRefreshTime + forcedJwksRefreshIntervalMilliSecs) { diff --git a/integration-tests/oidc-wiremock/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java b/integration-tests/oidc-wiremock/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java index 1eaabbee74ef2..5b014c9b0a5d5 100644 --- a/integration-tests/oidc-wiremock/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java +++ b/integration-tests/oidc-wiremock/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java @@ -12,6 +12,7 @@ import java.util.Set; import org.hamcrest.Matchers; +import org.jose4j.jwx.HeaderParameterNames; import org.junit.jupiter.api.Test; import com.github.tomakehurst.wiremock.WireMockServer; @@ -137,6 +138,31 @@ public void testAccessAdminResourceWithCertThumbprint() { .body(Matchers.containsString("admin")); } + @Test + public void testAccessAdminResourceWithWrongCertThumbprint() { + RestAssured.given().auth().oauth2(getAccessTokenWithWrongThumbprint("admin", Set.of("admin"))) + .when().get("/api/admin/bearer-no-introspection") + .then() + .statusCode(401); + } + + @Test + public void testAccessAdminResourceWithCertS256Thumbprint() { + RestAssured.given().auth().oauth2(getAccessTokenWithS256Thumbprint("admin", Set.of("admin"))) + .when().get("/api/admin/bearer-no-introspection") + .then() + .statusCode(200) + .body(Matchers.containsString("admin")); + } + + @Test + public void testAccessAdminResourceWithWrongCertS256Thumbprint() { + RestAssured.given().auth().oauth2(getAccessTokenWithWrongS256Thumbprint("admin", Set.of("admin"))) + .when().get("/api/admin/bearer-no-introspection") + .then() + .statusCode(401); + } + @Test public void testAccessAdminResourceWithCustomRolePathForbidden() { RestAssured.given().auth().oauth2(getAccessTokenWithCustomRolePath("admin", Set.of("admin"))) @@ -298,6 +324,33 @@ private String getAccessTokenWithThumbprint(String userName, Set groups) .sign("privateKeyWithoutKid.jwk"); } + private String getAccessTokenWithWrongThumbprint(String userName, Set groups) { + return Jwt.preferredUserName(userName) + .groups(groups) + .issuer("https://server.example.com") + .audience("https://service.example.com") + .jws().header(HeaderParameterNames.X509_CERTIFICATE_THUMBPRINT, "123") + .sign("privateKeyWithoutKid.jwk"); + } + + private String getAccessTokenWithS256Thumbprint(String userName, Set groups) { + return Jwt.preferredUserName(userName) + .groups(groups) + .issuer("https://server.example.com") + .audience("https://service.example.com") + .jws().thumbprintS256(OidcWiremockTestResource.getCertificate()) + .sign("privateKeyWithoutKid.jwk"); + } + + private String getAccessTokenWithWrongS256Thumbprint(String userName, Set groups) { + return Jwt.preferredUserName(userName) + .groups(groups) + .issuer("https://server.example.com") + .audience("https://service.example.com") + .jws().header(HeaderParameterNames.X509_CERTIFICATE_SHA256_THUMBPRINT, "123") + .sign("privateKeyWithoutKid.jwk"); + } + private String getAccessTokenWithoutKidAndThumbprint(String userName, Set groups) { return Jwt.preferredUserName(userName) .groups(groups) From e775dadb39e3aee450a8ac5424fa6bea72f18fec Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Sat, 4 Nov 2023 10:06:35 +0100 Subject: [PATCH 21/29] Produce a 503 response when there no more worker threads to handle blocking requests (cherry picked from commit dec72dc2bc255c15488dde2f1b7d83d43d92b68d) --- .../io/quarkus/vertx/http/runtime/QuarkusErrorHandler.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/QuarkusErrorHandler.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/QuarkusErrorHandler.java index 9ae149270aded..a08fa7c6fd26b 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/QuarkusErrorHandler.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/QuarkusErrorHandler.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; @@ -93,6 +94,12 @@ public void accept(Throwable throwable) { event.response().end(); return; } + + if (event.failure() instanceof RejectedExecutionException) { + // No more worker threads - return a 503 + event.response().setStatusCode(HttpResponseStatus.SERVICE_UNAVAILABLE.code()).end(); + return; + } } catch (IllegalStateException e) { //ignore this if the response is already started if (!event.response().ended()) { From 2bfb2c2d1fc3adcd4db739dccc0a01a5a02427f9 Mon Sep 17 00:00:00 2001 From: Yoshikazu Nojima Date: Thu, 2 Nov 2023 20:39:49 +0900 Subject: [PATCH 22/29] Reformat source code block title Without this line break, the sentence is not parsed as title line for the source code block (cherry picked from commit e4268aef0449314030fe18580999ccb49c7216cb) --- docs/src/main/asciidoc/writing-extensions.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/main/asciidoc/writing-extensions.adoc b/docs/src/main/asciidoc/writing-extensions.adoc index 752d918dae8aa..861bfa9fb9578 100644 --- a/docs/src/main/asciidoc/writing-extensions.adoc +++ b/docs/src/main/asciidoc/writing-extensions.adoc @@ -2439,6 +2439,7 @@ One of the main things an extension is likely to do is completely separate the c Frameworks often do parsing/load of configuration on startup that can be done during build time to both reduce the runtime dependencies on frameworks like xml parsers as well as reducing the startup time the parsing incurs. An example of parsing an XML config file using JAXB is shown in the `TestProcessor#parseServiceXmlConfig` method: + .Parsing an XML Configuration into Runtime XmlConfig Instance [source,java] ---- From a49a5caf6b197fc75c3c0c5f4e3585f618d8321b Mon Sep 17 00:00:00 2001 From: Mark Swatosh Date: Wed, 1 Nov 2023 13:03:26 -0500 Subject: [PATCH 23/29] Fixing Db2 Driver typo (cherry picked from commit 875f34ec665bd401517890cc60055660ca2f419b) --- docs/src/main/asciidoc/datasource.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/datasource.adoc b/docs/src/main/asciidoc/datasource.adoc index 164b9e16dff91..b89e0158ad419 100644 --- a/docs/src/main/asciidoc/datasource.adoc +++ b/docs/src/main/asciidoc/datasource.adoc @@ -638,7 +638,7 @@ When using one of the built-in datasource kinds, the JDBC and Reactive drivers a |`db2` |`quarkus-jdbc-db2` -a|* JDBC: `com.ibm.db2.jcc.DBDriver` +a|* JDBC: `com.ibm.db2.jcc.DB2Driver` * XA: `com.ibm.db2.jcc.DB2XADataSource` From cdd91d4386823564c2223718e084a2ffac2a425d Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Thu, 2 Nov 2023 15:59:15 +0100 Subject: [PATCH 24/29] TransactionalUniAsserterTest: test that injected argument is used - UniAsserterTest: add test for UniAsserter#fail() (cherry picked from commit 73e6e456da8698fd351c7ceeaedbc9eaae2a8b1b) --- .../reactive/TransactionalUniAsserterTest.java | 12 ++++++++++++ .../java/io/quarkus/test/vertx/UniAsserterTest.java | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java b/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java index e04ce655b113f..2586929e2143c 100644 --- a/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java +++ b/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/TransactionalUniAsserterTest.java @@ -3,7 +3,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import io.quarkus.hibernate.reactive.panache.Panache; @@ -14,11 +18,14 @@ @QuarkusTest public class TransactionalUniAsserterTest { + private static final AtomicBoolean ASSERTER_USED = new AtomicBoolean(); + @RunOnVertxContext @Test public void testTransactionalUniAsserter(TransactionalUniAsserter asserter) { assertNotNull(asserter); asserter.assertThat(Panache::currentTransaction, transaction -> { + ASSERTER_USED.set(true); assertNotNull(transaction); assertFalse(transaction.isMarkedForRollback()); asserter.putData("tx", transaction); @@ -30,4 +37,9 @@ public void testTransactionalUniAsserter(TransactionalUniAsserter asserter) { }); } + @AfterAll + static void afterAll() { + assertTrue(ASSERTER_USED.get()); + } + } diff --git a/test-framework/vertx/src/test/java/io/quarkus/test/vertx/UniAsserterTest.java b/test-framework/vertx/src/test/java/io/quarkus/test/vertx/UniAsserterTest.java index dd1103d359552..effafa73dbc06 100644 --- a/test-framework/vertx/src/test/java/io/quarkus/test/vertx/UniAsserterTest.java +++ b/test-framework/vertx/src/test/java/io/quarkus/test/vertx/UniAsserterTest.java @@ -12,6 +12,7 @@ import java.util.function.Supplier; import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; import io.smallrye.mutiny.Uni; @@ -94,6 +95,11 @@ public void testAssertThat() { testAsserterFailure(ua -> ua.assertThat(() -> Uni.createFrom().item("foo"), foo -> assertEquals("bar", foo))); } + @Test + public void testFail() { + testAsserterFailure(ua -> ua.fail(), t -> AssertionFailedError.class.isInstance(t)); + } + @Test public void testExecute() throws InterruptedException, ExecutionException { CompletableFuture cf = new CompletableFuture<>(); @@ -238,7 +244,7 @@ private void testAsserterFailure(Consumer assertion, Predicate Date: Mon, 6 Nov 2023 13:24:10 +0200 Subject: [PATCH 25/29] Handle generic types for ParamConverter in REST Client Fixes: #36639 (cherry picked from commit 1aff10f92ca2bb57980983b5da3e7e9f3583868a) --- .../JaxrsClientReactiveProcessor.java | 4 +- .../converter/GenericsConverterTest.java | 127 ++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/converter/GenericsConverterTest.java diff --git a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java index bd86f0b3c6a22..b96c574255bfa 100644 --- a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java +++ b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java @@ -2652,7 +2652,7 @@ private ResultHandle addQueryParam(MethodInfo jandexMethod, BytecodeCreator meth if (isCollection(valueType, index)) { if (valueType.kind() == PARAMETERIZED_TYPE) { Type paramType = valueType.asParameterizedType().arguments().get(0); - if (paramType.kind() == CLASS) { + if ((paramType.kind() == CLASS) || (paramType.kind() == PARAMETERIZED_TYPE)) { componentType = paramType.name().toString(); } } @@ -2679,7 +2679,7 @@ private ResultHandle addQueryParam(MethodInfo jandexMethod, BytecodeCreator meth } else if (isCollection(type, index)) { if (type.kind() == PARAMETERIZED_TYPE) { Type paramType = type.asParameterizedType().arguments().get(0); - if (paramType.kind() == CLASS) { + if ((paramType.kind() == CLASS) || (paramType.kind() == PARAMETERIZED_TYPE)) { componentType = paramType.name().toString(); } } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/converter/GenericsConverterTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/converter/GenericsConverterTest.java new file mode 100644 index 0000000000000..61a8ad069bae6 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/converter/GenericsConverterTest.java @@ -0,0 +1,127 @@ +package io.quarkus.rest.client.reactive.converter; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.net.URI; +import java.util.List; +import java.util.stream.Collectors; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.test.common.http.TestHTTPResource; + +public class GenericsConverterTest { + + @RegisterExtension + static final QuarkusUnitTest TEST = new QuarkusUnitTest(); + + @TestHTTPResource + URI baseUri; + + @Test + void testSingle() { + TestClient client = RestClientBuilder.newBuilder().baseUri(baseUri) + .build(TestClient.class); + var result = client.wrapper(new WrapperClass<>(StatusEnum.ACTIVE)); + assertEquals("ACTIVE", result); + } + + @Test + void testList() { + TestClient client = RestClientBuilder.newBuilder().baseUri(baseUri) + .build(TestClient.class); + var result = client + .wrapperList(List.of(new WrapperClass<>(StatusEnum.ACTIVE), new WrapperClass<>(StatusEnum.INACTIVE))); + assertEquals("ACTIVE,INACTIVE", result); + } + + public enum StatusEnum { + + ACTIVE, + INACTIVE + } + + public static class WrapperClass> { + + private final E value; + + public WrapperClass(final E value) { + this.value = value; + } + + public E getValue() { + return value; + } + } + + public static class WrapperClassParamConverter implements ParamConverter> { + + @Override + public WrapperClass fromString(String value) { + return new WrapperClass<>(Enum.valueOf(StatusEnum.class, value)); + } + + @Override + public String toString(WrapperClass wrapperClass) { + return wrapperClass != null ? wrapperClass.getValue().toString() : null; + } + + } + + @Provider + public static class WrapperClassParamConverterProvider implements ParamConverterProvider { + + @Override + @SuppressWarnings("unchecked") + public ParamConverter getConverter(Class rawType, Type genericType, Annotation[] annotations) { + if (WrapperClass.class.isAssignableFrom(rawType)) { + return (ParamConverter) new WrapperClassParamConverter(); + } + + return null; + } + } + + @Path("/test") + public static class TestResource { + + @GET + @Path("/single") + public String wrapper(@QueryParam("wrapper") final WrapperClass wrapper) { + return wrapper.getValue().toString(); + } + + @GET + @Path("/list") + public String wrapperList(@QueryParam("wrapperList") final List> wrapperList) { + return wrapperList.stream().map(WrapperClass::getValue).map(Enum::name).collect(Collectors.joining(",")); + } + + } + + @Path("/test") + public interface TestClient { + + @GET + @Path("/single") + String wrapper(@QueryParam("wrapper") final WrapperClass wrapper); + + @GET + @Path("/list") + String wrapperList(@QueryParam("wrapperList") final List> wrapperList); + + } + +} From c5bbb18b17db243e01d28e4f1b96f8f87761dcda Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 6 Nov 2023 14:12:15 +0100 Subject: [PATCH 26/29] Build cache - Also exclude .cache for Spotless (cherry picked from commit 63b4239f84bfbd17e1dc7e2a64f1e34afae57764) --- independent-projects/parent/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/independent-projects/parent/pom.xml b/independent-projects/parent/pom.xml index 72740e5cb52e3..8866840ab58d8 100644 --- a/independent-projects/parent/pom.xml +++ b/independent-projects/parent/pom.xml @@ -553,6 +553,7 @@ .idea/* target/* + .cache/* true From 3deb802f0442b0add99c0ee83880119316da6847 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Mon, 6 Nov 2023 14:04:39 +0100 Subject: [PATCH 27/29] Qute: fix validation of array index-based expressions - such as {myArray[1].name} (cherry picked from commit d6fc6051b6144aeaf0e844567f9251391783b4f5) --- .../qute/deployment/QuteProcessor.java | 6 ++++-- .../CheckedTemplateArrayParamTest.java | 20 +++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java index 54a1022511e6b..6cfd2299b1184 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java @@ -1422,7 +1422,8 @@ private static boolean processArray(Info info, MatchResult match) { // myArray[0], myArray.1 try { Integer.parseInt(name); - match.setValues(null, match.type().asArrayType().constituent()); + Type constituent = match.type().asArrayType().constituent(); + match.setValues(match.assignabilityCheck.computingIndex.getClassByName(constituent.name()), constituent); return true; } catch (NumberFormatException e) { // not an integer index @@ -1436,7 +1437,8 @@ private static boolean processArray(Info info, MatchResult match) { Expression param = params.get(0); Object literalValue = param.getLiteral(); if (literalValue == null || literalValue instanceof Integer) { - match.setValues(null, match.type().asArrayType().constituent()); + Type constituent = match.type().asArrayType().constituent(); + match.setValues(match.assignabilityCheck.computingIndex.getClassByName(constituent.name()), constituent); return true; } } else if (name.equals("take") || name.equals("takeLast")) { diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/CheckedTemplateArrayParamTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/CheckedTemplateArrayParamTest.java index a6fd2b8a729f3..1e41d08c99482 100644 --- a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/CheckedTemplateArrayParamTest.java +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/CheckedTemplateArrayParamTest.java @@ -15,14 +15,18 @@ public class CheckedTemplateArrayParamTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(Templates.class) + .addClasses(Templates.class, Color.class) .addAsResource(new StringAsset("Hello {myArray[1]}! ::{myArray.take(1).size}"), - "templates/CheckedTemplateArrayParamTest/arrays.txt")); + "templates/CheckedTemplateArrayParamTest/arrays.txt") + .addAsResource(new StringAsset("{array.0.asStr}"), + "templates/CheckedTemplateArrayParamTest/colors.txt")); @Test public void testBasePath() { assertEquals("Hello 1! ::1", Templates.arrays(new int[] { 0, 1 }).render()); + assertEquals("RED", + Templates.colors(new Color[] { Color.RED, Color.BLUE }).render()); } @CheckedTemplate @@ -30,6 +34,18 @@ public static class Templates { static native TemplateInstance arrays(int[] myArray); + static native TemplateInstance colors(Color[] array); + + } + + public static enum Color { + + RED, + BLUE; + + public String asStr() { + return toString(); + } } } From d070d79f69f7e8752df6efc0b0eb43af7a939fbc Mon Sep 17 00:00:00 2001 From: glefloch Date: Thu, 12 Oct 2023 10:31:17 +0200 Subject: [PATCH 28/29] Bump Gradle version to 8.4 (cherry picked from commit 636c06aae413701760cda3c4ac1a62613e13f4eb) --- build-parent/pom.xml | 2 +- devtools/gradle/gradle/wrapper/gradle-wrapper.properties | 4 ++-- independent-projects/bootstrap/pom.xml | 2 +- .../devtools-testing/src/main/resources/fake-catalog.json | 2 +- independent-projects/tools/pom.xml | 2 +- .../gradle/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build-parent/pom.xml b/build-parent/pom.xml index c40660fe02b22..41e5e2d481f6b 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -64,7 +64,7 @@ 3.9.5 3.2.0 - 8.3 + 8.4 ${project.version} ${project.version} 3.8.1 diff --git a/devtools/gradle/gradle/wrapper/gradle-wrapper.properties b/devtools/gradle/gradle/wrapper/gradle-wrapper.properties index 0cadd3945ae5a..82b3bd91387cb 100644 --- a/devtools/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/devtools/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,8 +1,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists # https://gradle.org/release-checksums/ -distributionSha256Sum=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionSha256Sum=f2b9ed0faf8472cbe469255ae6c86eddb77076c75191741b4a462f33128dd419 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/independent-projects/bootstrap/pom.xml b/independent-projects/bootstrap/pom.xml index f9bb6d38cb2e6..b53b42b3de503 100644 --- a/independent-projects/bootstrap/pom.xml +++ b/independent-projects/bootstrap/pom.xml @@ -78,7 +78,7 @@ 3.5.1 2.1.2 1.3.2 - 8.3 + 8.4 0.0.9 0.1.3 2.23.0 diff --git a/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json b/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json index be03cd57b081a..c8e7e56118368 100644 --- a/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json +++ b/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json @@ -388,7 +388,7 @@ "supported-maven-versions": "[3.6.2,)", "proposed-maven-version": "3.9.5", "maven-wrapper-version": "3.2.0", - "gradle-wrapper-version": "8.3" + "gradle-wrapper-version": "8.4" } }, "codestarts-artifacts": [ diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml index 1300b23de96de..624be6575399f 100644 --- a/independent-projects/tools/pom.xml +++ b/independent-projects/tools/pom.xml @@ -42,7 +42,7 @@ 3.9.5 3.2.0 - 8.3 + 8.4 3.11.0 diff --git a/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties b/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties index 0cadd3945ae5a..82b3bd91387cb 100644 --- a/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,8 +1,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists # https://gradle.org/release-checksums/ -distributionSha256Sum=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionSha256Sum=f2b9ed0faf8472cbe469255ae6c86eddb77076c75191741b4a462f33128dd419 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 17c3e0b673fc938eb56bb271b90510e7be11031d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Sun, 29 Oct 2023 19:03:31 +0100 Subject: [PATCH 29/29] Kc Admin Cl.:Fix typo that allows using customized ObjectMapper (cherry picked from commit 8f9366dba389e88d93baf29c27a2d1ad226ed478) --- .../client/reactive/runtime/ResteasyReactiveClientProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/runtime/ResteasyReactiveClientProvider.java b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/runtime/ResteasyReactiveClientProvider.java index 510b8278e01ea..a8bb66a6d0096 100644 --- a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/runtime/ResteasyReactiveClientProvider.java +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/io/quarkus/keycloak/admin/client/reactive/runtime/ResteasyReactiveClientProvider.java @@ -99,7 +99,7 @@ private boolean canReuseObjectMapper(InstanceHandle objectMapperIn } // if any Jackson properties were configured, disallow reuse - this is done in order to provide forward compatibility with new Jackson configuration options for (String propertyName : ConfigProvider.getConfig().getPropertyNames()) { - if (propertyName.startsWith("io.quarkus.jackson")) { + if (propertyName.startsWith("quarkus.jackson")) { return false; } }