diff --git a/.github/workflows/ci-actions-incremental.yml b/.github/workflows/ci-actions-incremental.yml index a34518ee35d89..0e12da17fbdec 100644 --- a/.github/workflows/ci-actions-incremental.yml +++ b/.github/workflows/ci-actions-incremental.yml @@ -832,8 +832,7 @@ jobs: env: CAPTURE_BUILD_SCAN: true run: | - git clone https://github.com/quarkusio/quarkus-quickstarts.git && cd quarkus-quickstarts - git checkout development + git clone -b 3.9 https://github.com/quarkusio/quarkus-quickstarts.git && cd quarkus-quickstarts export LANG=en_US && ./mvnw -e -B -fae --settings .github/mvn-settings.xml clean verify -DskipTests - name: Prepare build reports archive if: always() diff --git a/.gitignore b/.gitignore index cf125852ce54b..2cb8e2e551695 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ nb-configuration.xml .envrc .jekyll-cache .mvn/.gradle-enterprise +.mvn/.develocity .quarkus diff --git a/bom/application/pom.xml b/bom/application/pom.xml index fc8c1151de642..c7649f78fd629 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -55,7 +55,7 @@ 4.1.0 4.0.0 3.10.0 - 2.8.1 + 2.8.2 6.2.6 4.5.0 2.1.0 @@ -92,7 +92,7 @@ 23.1.2 1.8.0 - 2.16.1 + 2.17.0 1.0.0.Final 3.14.0 1.16.1 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 4f3655320912b..0214c541a0941 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -54,7 +54,7 @@ ${maven.compiler.release} - 17 + 21 org.graalvm.polyglot:js-community org.graalvm.js:js-language + org.graalvm.js:js-scriptengine org.graalvm.polyglot:js org.graalvm.polyglot:polyglot org.graalvm.regex:regex @@ -170,6 +171,7 @@ org.graalvm.shadowed:icu4j org.graalvm.sdk:jniutils org.graalvm.sdk:word + org.graalvm.sdk:collections org.graalvm.sdk:native-bridge io.quarkus:quarkus-bootstrap-core @@ -220,6 +222,7 @@ org.graalvm.polyglot:js-community org.graalvm.js:js-language + org.graalvm.js:js-scriptengine org.graalvm.polyglot:js org.graalvm.polyglot:polyglot org.graalvm.regex:regex @@ -230,6 +233,7 @@ org.graalvm.shadowed:icu4j org.graalvm.sdk:jniutils org.graalvm.sdk:word + org.graalvm.sdk:collections org.graalvm.sdk:native-bridge io.quarkus:quarkus-bootstrap-runner diff --git a/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java index 4bc790ec24f7f..2812fc1be4db7 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java @@ -42,7 +42,7 @@ public class UpdateMojo extends QuarkusProjectStateMojoBase { /** * Version of the target platform (e.g: 2.0.0.Final) - * You may instead use streamId to target the latest version of a specific platform stream. + * You may instead use stream to target the latest version of a specific platform stream. */ @Parameter(property = "platformVersion", required = false) private String platformVersion; diff --git a/docs/src/main/asciidoc/config-reference.adoc b/docs/src/main/asciidoc/config-reference.adoc index 870980d16646f..d5a700efeb22c 100644 --- a/docs/src/main/asciidoc/config-reference.adoc +++ b/docs/src/main/asciidoc/config-reference.adoc @@ -341,6 +341,7 @@ With the `dev` profile enabled, the property `bar` has the value `hallo`, but th `bonjour`. If the `prod` profile is enabled, `bar` has the value `hello` (as there is no specific value for the `prod` profile), and `baz` the value `bonjour`. +[[default-profiles]] === Default Profiles By default, Quarkus provides three profiles, that activate automatically in certain conditions: diff --git a/docs/src/main/asciidoc/dev-services.adoc b/docs/src/main/asciidoc/dev-services.adoc index f8aea5e5c5f14..01fd6fdf4e77b 100644 --- a/docs/src/main/asciidoc/dev-services.adoc +++ b/docs/src/main/asciidoc/dev-services.adoc @@ -6,27 +6,56 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Dev Services Overview include::_attributes.adoc[] :categories: core -:summary: A list of all extensions that support Dev Services and their configuration options. +:summary: An introduction to dev services and a list of all extensions that support Dev Services and their configuration options. :topics: dev-services,dev-mode,testing +== What Are Dev Services? + Quarkus supports the automatic provisioning of unconfigured services in development and test mode. We refer to this capability -as Dev Services. From a developer's perspective this means that if you include an extension and don't configure it then +as Dev Services. If you include an extension and don't configure it then Quarkus will automatically start the relevant service (usually using https://www.testcontainers.org/[Testcontainers] behind the scenes) and wire up your application to use this service. +For a tutorial showing how to get started writing an application with persistence and Dev Services, see xref:getting-started-dev-services.adoc[Your Second Quarkus Application]. + + +== Using Dev Services + +Dev Services are designed to be frictionless, so they will be automatically started any time you include an extension which supports +Dev Services, as long as you don't configure a connection to an external service. + +NOTE: In order to use most Dev Services you will need a working container environment (remote environments are supported). +If you don't have a container environment, such as Docker or Podman, installed you will need to configure your services normally. + +The default startup timeout for Dev Services is 60s, if this is not enough you can increase it with the `quarkus.devservices.timeout` property. + +To configure a production service but continue to use Dev Services in development and test modes, use xref:config-reference.adoc#default-profiles[configuration profiles]. + +For example, + +[source, properties] +---- +# configure your datasource +%prod.quarkus.datasource.db-kind = postgresql +%prod.quarkus.datasource.username = prod-admin +%prod.quarkus.datasource.password = super-secret +%prod.quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/mydatabase +---- + +== Disabling Dev Services + All this functionality is part of the Quarkus `deployment` modules, so does not affect the production application in any way. If you want to disable all Dev Services you can use the `quarkus.devservices.enabled=false` config property, although in most cases this is not necessary as simply configuring the service will result in the Dev Service being disabled automatically. -Note that the default startup timeout is 60s, if this is not enough you can increase it with the `quarkus.devservices.timeout` property. -This page lists all the Dev Services that Quarkus supports. +== Platform Dev Services + +This section lists all the Dev Services available in the Quarkus Platform. -NOTE: In order to use Dev Services you will generally need a working Docker environment (remote environments are supported). -If you don't have Docker installed you will need to configure your services normally. -== AMQP +=== AMQP The AMQP Dev Service will be enabled when the `quarkus-messaging-amqp` extension is present in your application, and the broker address has not been explicitly configured. More information can be found in the @@ -34,7 +63,7 @@ xref:amqp-dev-services.adoc[AMQP Dev Services Guide]. include::{generated-dir}/config/quarkus-smallrye-reactivemessaging-amqp-config-group-amqp-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== Apicurio Registry +=== Apicurio Registry The Apicurio Dev Service will be enabled when the `quarkus-apicurio-registry-avro` extension is present in your application, and it's address has not been explicitly configured. More information can be found in the @@ -42,7 +71,7 @@ xref:apicurio-registry-dev-services.adoc[Apicurio Registry Dev Services Guide]. include::{generated-dir}/config/quarkus-apicurio-registry-devservices-apicurio-registry-devservice-apicurio-registry-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== Databases +=== Databases The database Dev Services will be enabled when a reactive or JDBC datasource extension is present in the application, and the database URL has not been configured. More information can be found in the @@ -60,7 +89,7 @@ N.B. if you opt in for this feature, Quarkus will not reset the state of the dat include::{generated-dir}/config/quarkus-datasource-config-group-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== Kafka +=== Kafka The Kafka Dev Service will be enabled when the `quarkus-kafka-client` extension is present in your application, and the broker address has not been explicitly configured. More information can be found in the @@ -68,7 +97,7 @@ xref:kafka-dev-services.adoc[Kafka Dev Services Guide]. include::{generated-dir}/config/quarkus-kafka-client-config-group-kafka-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== Keycloak +=== Keycloak The Keycloak Dev Service will be enabled when the `quarkus-oidc` extension is present in your application, and the server address has not been explicitly configured. More information can be found in the @@ -76,7 +105,7 @@ xref:security-openid-connect-dev-services.adoc[OIDC Dev Services Guide]. include::{generated-dir}/config/quarkus-keycloak-devservices-keycloak-keycloak-build-time-config.adoc[opts=optional, leveloffset=+1] -== Kubernetes +=== Kubernetes The Kubernetes Dev Service will be enabled when `kubernetes-client` extension is present in your application, and the API server address has not been explicitly configured. More information can be found in the @@ -84,7 +113,7 @@ xref:kubernetes-dev-services.adoc[Kubernetes Dev Services Guide]. include::{generated-dir}/config/quarkus-kubernetes-client-config-group-kubernetes-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== MongoDB +=== MongoDB The MongoDB Dev Service will be enabled when the `quarkus-mongodb-client` extension is present in your application, and the server address has not been explicitly configured. More information can be found in the @@ -92,7 +121,7 @@ xref:mongodb.adoc#dev-services[MongoDB Guide]. include::{generated-dir}/config/quarkus-mongodb-config-group-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== RabbitMQ +=== RabbitMQ The RabbitMQ Dev Service will be enabled when the `quarkus-messaging-rabbitmq` extension is present in your application, and the broker address has not been explicitly configured. More information can be found in the @@ -100,13 +129,13 @@ xref:rabbitmq-dev-services.adoc[RabbitMQ Dev Services Guide]. include::{generated-dir}/config/quarkus-smallrye-reactivemessaging-rabbitmq-config-group-rabbit-mq-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] -== Pulsar +=== Pulsar The Pulsar Dev Service will be enabled when the `quarkus-messaging-pulsar` extension is present in your application, and the broker address has not been explicitly configured. More information can be found in the xref:pulsar-dev-services.adoc[Pulsar Dev Services Guide]. -== Redis +=== Redis The Redis Dev Service will be enabled when the `quarkus-redis-client` extension is present in your application, and the server address has not been explicitly configured. More information can be found in the @@ -114,19 +143,13 @@ xref:redis-dev-services.adoc[Redis Dev Services Guide]. include::{generated-dir}/config/quarkus-redis-config-group-client-dev-services-config.adoc[opts=optional, leveloffset=+1] -== Vault +=== Vault The Vault Dev Service will be enabled when the `quarkus-vault` extension is present in your application, and the server address has not been explicitly configured. More information can be found in the link:{vault-guide}#dev-services[Vault Guide]. -== Neo4j - -The Neo4j Dev Service will be enabled when the `quarkus-neo4j` extension is present in your application, and -the server address has not been explicitly configured. More information can be found in the -link:{neo4j-guide}#dev-services[Neo4j Guide]. - -== Infinispan +=== Infinispan The Infinispan Dev Service will be enabled when the `quarkus-infinispan-client` extension is present in your application, and the server address has not been explicitly configured. More information can be found in the @@ -134,10 +157,32 @@ xref:infinispan-dev-services.adoc[Infinispan Dev Services Guide]. include::{generated-dir}/config/quarkus-infinispan-client-config-group-infinispan-client-build-time-config-dev-service-configuration.adoc[opts=optional, leveloffset=+1] -== Elasticsearch +=== Elasticsearch The Elasticsearch Dev Service will be enabled when one of the Elasticsearch based extensions (Elasticsearch client or Hibernate Search ORM Elasticsearch) is present in your application, and the server address has not been explicitly configured. More information can be found in the xref:elasticsearch-dev-services.adoc[Elasticsearch Dev Services Guide]. include::{generated-dir}/config/quarkus-elasticsearch-devservices-elasticsearch-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1] + +== Dev Services beyond the Quarkus Platform + +Many Quarkiverse extensions which are not in the Quarkus Platform also offer Dev Services. + +Here are some highlights. + +=== Neo4j + +The Neo4j Dev Service will be enabled when the `quarkus-neo4j` extension is present in your application, and +the server address has not been explicitly configured. More information can be found in the +link:{neo4j-guide}#dev-services[Neo4j Guide]. + +=== WireMock + +The WireMock extension starts WireMock as a Dev Service. It is a test-focussed extension, designed to run in dev and test mode only. +More information can be found in the https://docs.quarkiverse.io/quarkus-wiremock/dev/index.html[WireMock Guide]. + +=== Microcks + +The Microcks Quarkus extension includes a Microcks Dev Service. The Dev Service manages mocks for dependencies and contract-testing your API endpoints. +See the extension https://github.com/microcks/microcks-quarkus[README.md] for more information. \ No newline at end of file diff --git a/docs/src/main/asciidoc/hibernate-orm-panache.adoc b/docs/src/main/asciidoc/hibernate-orm-panache.adoc index 3e15bd753e261..12d76c52dd4f2 100644 --- a/docs/src/main/asciidoc/hibernate-orm-panache.adoc +++ b/docs/src/main/asciidoc/hibernate-orm-panache.adoc @@ -75,37 +75,6 @@ Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {q The solution is located in the `hibernate-orm-panache-quickstart` link:{quickstarts-tree-url}/hibernate-orm-panache-quickstart[directory]. -[NOTE] -==== -If your project is already configured to use other annotation processors, you will need to additionally add the Panache annotation processor: - -[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] -.pom.xml ----- - - maven-compiler-plugin - ${compiler-plugin.version} - - ${maven.compiler.parameters} - - - - io.quarkus - quarkus-panache-common - ${quarkus.platform.version} - - - - ----- - -[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] -.build.gradle ----- -annotationProcessor("io.quarkus:quarkus-panache-common") ----- -==== - == Setting up and configuring Hibernate ORM with Panache To get started: diff --git a/docs/src/main/asciidoc/hibernate-reactive-panache.adoc b/docs/src/main/asciidoc/hibernate-reactive-panache.adoc index 846a09c177b9b..8b6d16a9ad2f4 100644 --- a/docs/src/main/asciidoc/hibernate-reactive-panache.adoc +++ b/docs/src/main/asciidoc/hibernate-reactive-panache.adoc @@ -71,37 +71,6 @@ Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {q The solution is located in the `hibernate-reactive-panache-quickstart` link:{quickstarts-tree-url}/hibernate-reactive-panache-quickstart[directory]. -[NOTE] -==== -If your project is already configured to use other annotation processors, you will need to additionally add the Panache annotation processor: - -[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] -.pom.xml ----- - - maven-compiler-plugin - ${compiler-plugin.version} - - ${maven.compiler.parameters} - - - - io.quarkus - quarkus-panache-common - ${quarkus.platform.version} - - - - ----- - -[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] -.build.gradle ----- -annotationProcessor("io.quarkus:quarkus-panache-common") ----- -==== - == Setting up and configuring Hibernate Reactive with Panache To get started: diff --git a/docs/src/main/asciidoc/rest.adoc b/docs/src/main/asciidoc/rest.adoc index 15469f285e738..968213774a87b 100644 --- a/docs/src/main/asciidoc/rest.adoc +++ b/docs/src/main/asciidoc/rest.adoc @@ -2608,7 +2608,7 @@ public class CheeseBodyHandler implements MessageBodyReader, } ---- -If you want to get the most performance our of your writer, you can extend the +If you want to get the most performance out of your writer, you can extend the link:{resteasy-reactive-api}/org/jboss/resteasy/reactive/server/spi/ServerMessageBodyWriter.html[`ServerMessageBodyWriter`] instead of link:{jaxrsapi}/jakarta/ws/rs/ext/MessageBodyWriter.html[`MessageBodyWriter`] where you will be able to use less reflection and bypass the blocking IO layer: diff --git a/docs/src/main/asciidoc/scheduler-reference.adoc b/docs/src/main/asciidoc/scheduler-reference.adoc index b2374725ae3a1..ebfa3a4f34540 100644 --- a/docs/src/main/asciidoc/scheduler-reference.adoc +++ b/docs/src/main/asciidoc/scheduler-reference.adoc @@ -438,6 +438,23 @@ NOTE: By default, the scheduler is not started unless a `@Scheduled` business me NOTE: If the xref:quartz.adoc[Quartz extension] is present and the DB store type is used then it's not possible to pass a task instance to the job definition and a task class must be used instead. The Quartz API can be also used to schedule a job programmatically. +In certain cases, a more fine-grained approach might be needed which is why Quarkus also exposes `java.util.concurrent.ScheduledExecutorService` and `java.util.concurrent.ExecutorService` that can be injected as CDI beans. +However, these executors are used by other Quarkus extensions and therefore should be approached with caution. Furthermore, users are never allowed to shut these executors down manually. + +[source,java] +---- +class JobScheduler { + + @Inject + ScheduledExecutorService executor; + + void everySecondWithDelay() { + Runnable myRunnable = createMyRunnable(); + executor.scheduleAtFixedRate(myRunnable, 3, 1, TimeUnit.SECONDS); + } +} +---- + == Scheduled Methods and Testing It is often desirable to disable the scheduler when running the tests. diff --git a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc index 9584b86abb792..caf601b1cec70 100644 --- a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc +++ b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc @@ -269,10 +269,41 @@ CertificateCredential credential = identity.getCredential(CertificateCredential. X509Certificate certificate = credential.getCertificate(); ---- -==== Authorization +[[map-certificate-attributes-to-roles]] +==== Mapping certificate attributes to roles + +The information from the client certificate can be used to add roles to Quarkus `SecurityIdentity`. + +You can add new roles to `SecurityIdentity` after checking a client certificate's common name (CN) attribute. +The easiest way to add new roles is to use a certificate attribute to role mapping feature. + +For example, you can update the properties shown in the section which introduces <> as follows: + +[source,properties] +---- +quarkus.http.ssl.certificate.key-store-file=server-keystore.jks +quarkus.http.ssl.certificate.key-store-password=the_key_store_secret +quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks +quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret +quarkus.http.ssl.client-auth=required +quarkus.http.insecure-requests=disabled + +quarkus.http.auth.certificate-role-properties=cert-role-mappings.properties <1> + +quarkus.http.auth.permission.certauthenticated.paths=/* <2> +quarkus.http.auth.permission.certauthenticated.policy=role-policy-cert <2> +quarkus.http.auth.policy.role-policy-cert.roles-allowed=user,admin <2> +---- +<1> The `cert-role-mappings.properties` classpath resource contains a map of certificate's CN values to roles in the form `CN=role` or `CN=role1,role2`, etc. Let's assume it contains three entries: `alice=user,admin`, `bob=user` and `jdoe=tester`. +<2> Use HTTP security policy to require that `SecurityIdentity` must have either `user` or `admin` roles for the requests to be authorized. + +Given the preceeding configuration, the request is authorized if the client certificate's CN attribute is equal to `alice` or `bob` and forbidden if it is equal to `jdoe`. + +==== Using certificate attributes to augment SecurityIdentity + +You can always register `SecurityIdentityAugmentor` if the automatic <> option does not suit. +Custom `SecurityIdentityAugmentor` can check the values of different client certificate attributes and augment the `SecurityIdentity` accordingly. -The information from the client certificate can be used to enhance Quarkus `SecurityIdentity`. -For example, you can add new roles after checking a client certificate subject name, and so on. For more information about customizing `SecurityIdentity`, see the xref:security-customization.adoc#security-identity-customization[Security identity customization] section in the Quarkus "Security tips and tricks" guide. [[other-supported-authentication-mechanisms]] diff --git a/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc b/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc index 02b723f77e488..48a482d4b2091 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc @@ -410,7 +410,7 @@ import io.quarkus.oidc.client.runtime.TokensHelper; public class OidcClientResource { @Inject - OidcClientCreator clients; + OidcClientCreator oidcClientCreator; TokensHelper tokenHelper = new TokensHelper(); @Inject diff --git a/extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java b/extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java new file mode 100644 index 0000000000000..715f9d62ff3ba --- /dev/null +++ b/extensions/jackson/deployment/src/test/java/io/quarkus/jackson/deployment/JacksonDefaultPoolTest.java @@ -0,0 +1,14 @@ +package io.quarkus.jackson.deployment; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.util.JsonRecyclerPools; + +public class JacksonDefaultPoolTest { + + @Test + public void validateDefaultJacksonPool() { + Assertions.assertThat(JsonRecyclerPools.defaultPool()).isInstanceOf(JsonRecyclerPools.LockFreePool.class); + } +} diff --git a/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java b/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java index 6f7bbe0cd3851..3254837f6e54d 100644 --- a/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java +++ b/extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/VertxHybridPoolObjectMapperCustomizer.java @@ -10,7 +10,9 @@ public class VertxHybridPoolObjectMapperCustomizer implements ObjectMapperCustom @Override public void customize(ObjectMapper objectMapper) { - if (objectMapper.getFactory()._getRecyclerPool() == JsonRecyclerPools.defaultPool()) { + var existingMapperPool = objectMapper.getFactory()._getRecyclerPool(); + // JsonRecyclerPools.defaultPool() by default should create a LockFreePool + if (existingMapperPool instanceof JsonRecyclerPools.LockFreePool) { objectMapper.getFactory().setRecyclerPool(HybridJacksonPool.getInstance()); } } diff --git a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java index a7d5ae3e2c2a5..4c2741d2092ed 100644 --- a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java +++ b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java @@ -105,6 +105,8 @@ NativeImageConfigBuildItem build( .addRuntimeInitializedClass("io.netty.handler.ssl.ReferenceCountedOpenSslEngine") .addRuntimeInitializedClass("io.netty.handler.ssl.ReferenceCountedOpenSslContext") .addRuntimeInitializedClass("io.netty.handler.ssl.ReferenceCountedOpenSslClientContext") + .addRuntimeInitializedClass("io.netty.handler.ssl.JdkSslServerContext") + .addRuntimeInitializedClass("io.netty.handler.ssl.JdkSslClientContext") .addRuntimeInitializedClass("io.netty.handler.ssl.util.ThreadLocalInsecureRandom") .addRuntimeInitializedClass("io.netty.buffer.ByteBufUtil$HexUtil") .addRuntimeInitializedClass("io.netty.buffer.PooledByteBufAllocator") diff --git a/extensions/resteasy-reactive/rest-client-jaxrs/kotlin/pom.xml b/extensions/resteasy-reactive/rest-client-jaxrs/kotlin/pom.xml index d26c7918ee8e5..b7a7ce82ce837 100644 --- a/extensions/resteasy-reactive/rest-client-jaxrs/kotlin/pom.xml +++ b/extensions/resteasy-reactive/rest-client-jaxrs/kotlin/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-client-jaxrs-kotlin Quarkus - REST - Kotlin - Provides Kotlin support for RESTEasy Reactive + Provides Kotlin support for Quarkus REST diff --git a/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java b/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java index daa221114c341..f5c68a2a5d4c8 100644 --- a/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java +++ b/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java @@ -203,7 +203,7 @@ public RestClientBuilderImpl userAgent(String userAgent) { @Override public RestClientBuilderImpl executorService(ExecutorService executor) { throw new IllegalArgumentException("Specifying executor service is not supported. " + - "The underlying call in RestEasy Reactive is non-blocking, " + + "The underlying call is non-blocking, " + "there is no reason to offload the call to a separate thread pool."); } diff --git a/extensions/resteasy-reactive/rest-common/runtime/pom.xml b/extensions/resteasy-reactive/rest-common/runtime/pom.xml index beae4962c358c..68c5bf066f308 100644 --- a/extensions/resteasy-reactive/rest-common/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-common/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-common Quarkus - REST - Common - Runtime - Common runtime parts of Quarkus RESTEasy Reactive + Common runtime parts of Quarkus REST diff --git a/extensions/resteasy-reactive/rest-jackson-common/runtime/pom.xml b/extensions/resteasy-reactive/rest-jackson-common/runtime/pom.xml index 33eb3ae141aa7..23aac235818da 100644 --- a/extensions/resteasy-reactive/rest-jackson-common/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-jackson-common/runtime/pom.xml @@ -10,7 +10,7 @@ quarkus-rest-jackson-common Quarkus - REST - Jackson Common Bits - Runtime - Common classes for Jackson serialization support for RESTEasy Reactive + Common classes for Jackson serialization support for Quarkus REST diff --git a/extensions/resteasy-reactive/rest-jackson/runtime/pom.xml b/extensions/resteasy-reactive/rest-jackson/runtime/pom.xml index e68d4979923eb..1afb96cef2987 100644 --- a/extensions/resteasy-reactive/rest-jackson/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-jackson/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-jackson Quarkus - REST - Jackson - Runtime - Jackson serialization support for RESTEasy Reactive. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it + Jackson serialization support for Quarkus REST. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it diff --git a/extensions/resteasy-reactive/rest-jaxb/runtime/pom.xml b/extensions/resteasy-reactive/rest-jaxb/runtime/pom.xml index ba0ac4db7fa59..f5dd192a153c8 100644 --- a/extensions/resteasy-reactive/rest-jaxb/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-jaxb/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-jaxb Quarkus - REST - JAXB - Runtime - JAXB serialization support for RESTEasy Reactive. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. + JAXB serialization support for Quarkus REST. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. diff --git a/extensions/resteasy-reactive/rest-jsonb-common/runtime/pom.xml b/extensions/resteasy-reactive/rest-jsonb-common/runtime/pom.xml index d6b533f0c4485..edfb5996b4747 100644 --- a/extensions/resteasy-reactive/rest-jsonb-common/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-jsonb-common/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-jsonb-common Quarkus - REST - JSON-B Common Bits - Runtime - Common classes for JSON-B serialization support for RESTEasy Reactive + Common classes for JSON-B serialization support for Quarkus REST diff --git a/extensions/resteasy-reactive/rest-jsonb/runtime/pom.xml b/extensions/resteasy-reactive/rest-jsonb/runtime/pom.xml index 54cab04e8a631..3ee70588046e5 100644 --- a/extensions/resteasy-reactive/rest-jsonb/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-jsonb/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-jsonb Quarkus - REST - JSON-B - Runtime - JSON-B serialization support for RESTEasy Reactive. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. + JSON-B serialization support for Quarkus REST. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. diff --git a/extensions/resteasy-reactive/rest-kotlin-serialization/runtime/pom.xml b/extensions/resteasy-reactive/rest-kotlin-serialization/runtime/pom.xml index 32039114e3033..0a8e4172b1737 100644 --- a/extensions/resteasy-reactive/rest-kotlin-serialization/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-kotlin-serialization/runtime/pom.xml @@ -12,7 +12,7 @@ quarkus-rest-kotlin-serialization Quarkus - REST - Kotlin Serialization - Runtime - Kotlin Serialization support for RESTEasy Reactive. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. + Kotlin Serialization support for Quarkus REST. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. diff --git a/extensions/resteasy-reactive/rest-kotlin/runtime/pom.xml b/extensions/resteasy-reactive/rest-kotlin/runtime/pom.xml index 2d82c14aa260a..1e5b9c11486dd 100644 --- a/extensions/resteasy-reactive/rest-kotlin/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-kotlin/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-kotlin Quarkus - REST - Kotlin - Runtime - Provides Kotlin support for RESTEasy Reactive + Provides Kotlin support for Quarkus REST diff --git a/extensions/resteasy-reactive/rest-links/runtime/pom.xml b/extensions/resteasy-reactive/rest-links/runtime/pom.xml index df85370552d28..6e75b222e6590 100644 --- a/extensions/resteasy-reactive/rest-links/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-links/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-links Quarkus - REST - Links - Runtime - Web Links support for RESTEasy Reactive. Inject web links into response HTTP headers by annotating your endpoint resources. + Web Links support for Quarkus REST. Inject web links into response HTTP headers by annotating your endpoint resources. diff --git a/extensions/resteasy-reactive/rest-qute/runtime/pom.xml b/extensions/resteasy-reactive/rest-qute/runtime/pom.xml index 93be27f7c66de..74f6acd3b62bd 100644 --- a/extensions/resteasy-reactive/rest-qute/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-qute/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-qute Quarkus - REST - Qute - Runtime - Qute integration for RESTEasy Reactive. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. + Qute integration for Quarkus REST. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. diff --git a/extensions/resteasy-reactive/rest-servlet/runtime/pom.xml b/extensions/resteasy-reactive/rest-servlet/runtime/pom.xml index 0019722bc48dc..b5e15d17a14d9 100644 --- a/extensions/resteasy-reactive/rest-servlet/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-servlet/runtime/pom.xml @@ -11,7 +11,7 @@ quarkus-rest-servlet Quarkus - REST Servlet - Runtime - Servlet support for Quarkus RESTEasy Reactive + Servlet support for Quarkus REST diff --git a/extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java b/extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java index 49026dc2197d4..85b881798f12c 100644 --- a/extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java +++ b/extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java @@ -1280,7 +1280,7 @@ public void setupDeployment(BeanContainerBuildItem beanContainerBuildItem, RuntimeValue deployment = recorder.createDeployment(deploymentInfo, beanContainerBuildItem.getValue(), shutdownContext, vertxConfig, requestContextFactoryBuildItem.map(RequestContextFactoryBuildItem::getFactory).orElse(null), - initClassFactory, launchModeBuildItem.getLaunchMode()); + initClassFactory, launchModeBuildItem.getLaunchMode(), servletPresent); quarkusRestDeploymentBuildItemBuildProducer .produce(new ResteasyReactiveDeploymentBuildItem(deployment, deploymentPath)); diff --git a/extensions/resteasy-reactive/rest/deployment/src/main/resources/dev-ui/qwc-resteasy-reactive-endpoint-scores.js b/extensions/resteasy-reactive/rest/deployment/src/main/resources/dev-ui/qwc-resteasy-reactive-endpoint-scores.js index 01f7caddbc1b5..758bd983acace 100644 --- a/extensions/resteasy-reactive/rest/deployment/src/main/resources/dev-ui/qwc-resteasy-reactive-endpoint-scores.js +++ b/extensions/resteasy-reactive/rest/deployment/src/main/resources/dev-ui/qwc-resteasy-reactive-endpoint-scores.js @@ -1,5 +1,5 @@ -import { QwcHotReloadElement, html, css} from 'qwc-hot-reload-element'; -import { JsonRpc } from 'jsonrpc'; +import {css, html, QwcHotReloadElement} from 'qwc-hot-reload-element'; +import {JsonRpc} from 'jsonrpc'; import '@vaadin/details'; import '@vaadin/horizontal-layout'; @@ -103,7 +103,7 @@ export class QwcResteasyReactiveEndpointScores extends QwcHotReloadElement { } return html` + linkText="Learn how to write REST Services with Quarkus REST"> `; } diff --git a/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java b/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java index ca41be791fcd8..e54d35e3229ec 100644 --- a/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java +++ b/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRecorder.java @@ -107,7 +107,10 @@ public RuntimeValue createDeployment(DeploymentInfo info, ShutdownContext shutdownContext, HttpBuildTimeConfig vertxConfig, RequestContextFactory contextFactory, BeanFactory initClassFactory, - LaunchMode launchMode) { + LaunchMode launchMode, + boolean servletPresent) { + + info.setServletPresent(servletPresent); CurrentRequestManager .setCurrentRequestInstance(new QuarkusCurrentRequest(beanContainer.beanInstance(CurrentVertxRequest.class))); diff --git a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java index 7bfd1f68aea4c..f61dcbbf2d5d9 100644 --- a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java +++ b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java @@ -12,6 +12,7 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Singleton; +import org.eclipse.microprofile.graphql.Input; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; @@ -236,6 +237,7 @@ void setAdditionalClassesToIndex(BuildProducer jar - .addClasses(TestingGraphQLApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("people-client/mp-graphql/url=" + url + "\n" + "people-client/mp-graphql/header/My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java index 2bbc1133d4083..abf35039193ec 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientInjectionWithQuarkusConfigTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.test.QuarkusUnitTest; import io.smallrye.graphql.client.GraphQLClient; @@ -32,7 +33,7 @@ public class DynamicGraphQLClientInjectionWithQuarkusConfigTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("quarkus.smallrye-graphql-client.people.url=" + url + "\n" + "quarkus.smallrye-graphql-client.people.header.My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java index 908efe65ca79b..c6b9590ccd3cb 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/DynamicGraphQLClientProgrammaticUsageTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.http.TestHTTPResource; @@ -26,7 +27,7 @@ public class DynamicGraphQLClientProgrammaticUsageTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, Person.class, PersonDto.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @TestHTTPResource diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java index bde9d888ddaec..344599fa07e29 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/StorkAndGraphQLClientTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -21,7 +22,7 @@ public class StorkAndGraphQLClientTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset( "quarkus.smallrye-graphql-client.typesafeclient.url=stork://foo-service/graphql\n" + "quarkus.stork.foo-service.service-discovery.type=static\n" + diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypeSafeGraphQLParameterInputNameWithClientModelTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypeSafeGraphQLParameterInputNameWithClientModelTest.java new file mode 100644 index 0000000000000..0f59d6016d20a --- /dev/null +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypeSafeGraphQLParameterInputNameWithClientModelTest.java @@ -0,0 +1,34 @@ +package io.quarkus.smallrye.graphql.client.deployment; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import jakarta.inject.Inject; + +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; +import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; +import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; +import io.quarkus.test.QuarkusUnitTest; + +public class TypeSafeGraphQLParameterInputNameWithClientModelTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); + + @Inject + TestingGraphQLClientApi client; + + @Test + public void performQuery() { + final String expectedName = "Mark"; + String actualPerson = client.getNameOfThePerson(new PersonDto(expectedName)); + assertEquals(expectedName, actualPerson); + } +} diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java index d3b1033ce74e4..88c881bbc2ee4 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientFQNameTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApiWithNoConfigKey; import io.quarkus.test.QuarkusUnitTest; @@ -27,7 +28,8 @@ public class TypesafeGraphQLClientFQNameTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class, + PersonDto.class) .addAsResource( new StringAsset( "quarkus.smallrye-graphql-client.\"io.quarkus.smallrye.graphql." + diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java index c75b3fb652109..07c8e796380d0 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -24,7 +25,7 @@ public class TypesafeGraphQLClientInjectionTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("typesafeclient/mp-graphql/url=" + url + "\n" + "typesafeclient/mp-graphql/header/My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java index 1b066b01ab7ac..03d7197993851 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -24,7 +25,7 @@ public class TypesafeGraphQLClientInjectionWithQuarkusConfigTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsResource(new StringAsset("quarkus.smallrye-graphql-client.typesafeclient.url=" + url + "\n" + "quarkus.smallrye-graphql-client.typesafeclient.header.My-Header=My-Value"), "application.properties") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java index c06279e6eb031..b3fc7caa0bb13 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -21,7 +22,7 @@ public class TypesafeGraphQLClientProgrammaticUsageTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @TestHTTPResource diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java index ec091a6a82cad..768e5dafe143c 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientProgrammaticUsageWithClientModelTest.java @@ -6,12 +6,14 @@ import java.net.URL; import java.util.List; +import org.eclipse.microprofile.graphql.Input; import org.jboss.jandex.Index; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApi; import io.quarkus.test.QuarkusUnitTest; @@ -26,7 +28,7 @@ public class TypesafeGraphQLClientProgrammaticUsageWithClientModelTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @TestHTTPResource @@ -34,7 +36,8 @@ public class TypesafeGraphQLClientProgrammaticUsageWithClientModelTest { @Test public void performQuery() throws IOException { - Index index = Index.of(GraphQLClientApi.class, TestingGraphQLClientApi.class, Person.class); + Index index = Index.of(GraphQLClientApi.class, TestingGraphQLClientApi.class, Person.class, PersonDto.class, + Input.class); TestingGraphQLClientApi client = ((VertxTypesafeGraphQLClientBuilder) TypesafeGraphQLClientBuilder.newBuilder()) .clientModels(ClientModelBuilder.build(index)) .endpoint(url.toString() + "/graphql") diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java index 84840596fe0a9..8e66221907ec9 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientShortcutTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.smallrye.graphql.client.deployment.model.Person; +import io.quarkus.smallrye.graphql.client.deployment.model.PersonDto; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLApi; import io.quarkus.smallrye.graphql.client.deployment.model.TestingGraphQLClientApiWithNoConfigKey; import io.quarkus.test.QuarkusUnitTest; @@ -28,7 +29,8 @@ public class TypesafeGraphQLClientShortcutTest { @RegisterExtension static QuarkusUnitTest test = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class) + .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApiWithNoConfigKey.class, Person.class, + PersonDto.class) .addAsResource( new StringAsset( "quarkus.smallrye-graphql-client.TestingGraphQLClientApiWithNoConfigKey.url=" + url), diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java new file mode 100644 index 0000000000000..c0b6129225c29 --- /dev/null +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/PersonDto.java @@ -0,0 +1,23 @@ +package io.quarkus.smallrye.graphql.client.deployment.model; + +import org.eclipse.microprofile.graphql.Input; + +@Input("PersonInput") +public class PersonDto { + private String name; + + public PersonDto() { + } + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java index f6f73aed7485e..df3b331195ded 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLApi.java @@ -8,6 +8,7 @@ import org.eclipse.microprofile.graphql.Query; import io.quarkus.vertx.http.runtime.CurrentVertxRequest; +import io.smallrye.graphql.execution.context.SmallRyeContext; @GraphQLApi public class TestingGraphQLApi { @@ -15,6 +16,9 @@ public class TestingGraphQLApi { @Inject CurrentVertxRequest request; + @Inject + SmallRyeContext ctx; + @Query public List people() { Person person1 = new Person(); @@ -36,4 +40,14 @@ public String returnHeader(String key) { return request.getCurrent().request().getHeader(key); } + private final String EXPECTED_QUERY_FOR_NAME_OF_THE_PERSON = "query nameOfThePerson($personDto: PersonInput) { nameOfThePerson(personDto: $personDto) }"; + + @Query + public String getNameOfThePerson(PersonDto personDto) { + if (!ctx.getQuery().equals(EXPECTED_QUERY_FOR_NAME_OF_THE_PERSON)) + throw new RuntimeException( + String.format("Wrong Query - expected: %s\n actual: %s", EXPECTED_QUERY_FOR_NAME_OF_THE_PERSON, + ctx.getQuery())); + return personDto.getName(); + } } diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java index f28ccc571feb6..e456c86bd6396 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/model/TestingGraphQLClientApi.java @@ -15,4 +15,7 @@ public interface TestingGraphQLClientApi { @Query public String returnHeader(String key); + @Query + public String getNameOfThePerson(PersonDto personDto); + } diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/CompletionStageTest.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/CompletionStageTest.java index ea4a4b78b6c89..2a1c7912ac44d 100644 --- a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/CompletionStageTest.java +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/CompletionStageTest.java @@ -45,7 +45,7 @@ public void testSourcePost() { " title\n" + " published\n" + " buyLink\n" + - " authors {\n" + + " asyncAuthors {\n" + " name\n" + " bornName\n" + " }\n" + @@ -87,7 +87,7 @@ public CompletionStage getBuyLink(@Source Book book) { return CompletableFuture.supplyAsync(() -> String.format(AMAZON_SEARCH_FORMAT, title)); } - public CompletionStage>> getAuthors(@Source List books) { + public CompletionStage>> getAsyncAuthors(@Source List books) { List> authorsOfAllBooks = new ArrayList<>(); for (Book book : books) { List authors = new ArrayList<>(); diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/UniTest.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/UniTest.java index 6375602409431..3685c05c51f1a 100644 --- a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/UniTest.java +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/UniTest.java @@ -44,7 +44,7 @@ public void testSourcePost() { " title\n" + " published\n" + " buyLink\n" + - " authors {\n" + + " asyncAuthors {\n" + " name\n" + " bornName\n" + " }\n" + @@ -81,7 +81,7 @@ public Uni getBuyLink(@Source Book book) { return Uni.createFrom().item(() -> String.format(AMAZON_SEARCH_FORMAT, title)); } - public Uni>> getAuthors(@Source List books) { + public Uni>> getAsyncAuthors(@Source List books) { List> authorsOfAllBooks = new ArrayList<>(); for (Book book : books) { List authors = new ArrayList<>(); diff --git a/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java b/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java index 4233aa75967f1..0b3921302320d 100644 --- a/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java +++ b/extensions/smallrye-health/deployment/src/test/java/io/quarkus/smallrye/health/test/HealthCheckProducerDefaultScopeTest.java @@ -31,10 +31,12 @@ void testHealth() { try { RestAssured.defaultParser = Parser.JSON; when().get("/q/health/ready").then() + .header("cache-control", "no-store") .body("status", is("UP"), "checks.status", hasItems("UP", "UP"), "checks.name", hasItems("alpha1", "bravo1")); when().get("/q/health/ready").then() + .header("cache-control", "no-store") .body("status", is("UP"), "checks.status", hasItems("UP", "UP"), "checks.name", hasItems("alpha1", "bravo2")); 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 30dd03d3ca973..cc0bb85cce758 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 @@ -59,7 +59,9 @@ private void doHandle(RoutingContext ctx, ManagedContext requestContext) { if (health.isDown()) { resp.setStatusCode(503); } - resp.headers().set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); + resp.headers() + .set(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8") + .set(HttpHeaders.CACHE_CONTROL, "no-store"); Buffer buffer = Buffer.buffer(256); // this size seems to cover the basic health checks try (BufferOutputStream outputStream = new BufferOutputStream(buffer);) { reporter.reportHealth(outputStream, health); diff --git a/extensions/spring-web/resteasy-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/spring-web/resteasy-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml index 2ecdd23b44ad4..1db221c7f1981 100644 --- a/extensions/spring-web/resteasy-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/spring-web/resteasy-reactive/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -1,5 +1,5 @@ --- artifact: ${project.groupId}:${project.artifactId}:${project.version} -name: "Spring Web RESTEasy Reactive" +name: "Spring Web REST" metadata: unlisted: true diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java index d80af2bca4b0e..11bcd0d08eaf8 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java @@ -66,7 +66,7 @@ public void runtimeInit(Optional staticResources, Stat @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class) public void nativeImageResource(Optional staticResources, - BuildProducer producer) { + BuildProducer producer) throws IOException { if (staticResources.isPresent()) { Set entries = staticResources.get().getEntries(); List metaInfResources = new ArrayList<>(entries.size()); @@ -75,10 +75,34 @@ public void nativeImageResource(Optional staticResourc // TODO: do we perhaps want to register the whole directory? continue; } + String metaInfResourcesPath = StaticResourcesRecorder.META_INF_RESOURCES + entry.getPath(); metaInfResources.add(metaInfResourcesPath); } producer.produce(new NativeImageResourceBuildItem(metaInfResources)); + + // register all directories under META-INF/resources for reflection in order to enable + // the serving of index.html in arbitrarily nested directories + ClassPathUtils.consumeAsPaths(StaticResourcesRecorder.META_INF_RESOURCES, resource -> { + try { + Files.walkFileTree(resource, new SimpleFileVisitor<>() { + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { + if (e != null) { + throw e; + } + int index = dir.toString().indexOf(StaticResourcesRecorder.META_INF_RESOURCES); + if (index > 0) { + producer.produce(new NativeImageResourceBuildItem(dir.toString().substring(index))); + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } } @@ -89,7 +113,8 @@ public void nativeImageResource(Optional staticResourc * @return the set of static resources * @throws Exception */ - private Set getClasspathResources(ApplicationArchivesBuildItem applicationArchivesBuildItem) + private Set getClasspathResources( + ApplicationArchivesBuildItem applicationArchivesBuildItem) throws Exception { Set knownPaths = new HashSet<>(); diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js index cc259a7f67065..a70a2a0efd2e9 100644 --- a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js +++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js @@ -200,12 +200,47 @@ export class RouterController { RouterController.router.addRoutes(routes); - if(currentSelection === path){ + var currentSelection = window.location.pathname; + const search = this.getQueryParamsWithoutFrom(); + + var relocationRequest = this.getQueryParameter("from"); + if (relocationRequest) { + // We know and already loaded the requested location + if (relocationRequest === path) { + Router.go({pathname: path, search}); + } + } else if(currentSelection === path){ Router.go({pathname: path, search}); - }else if(!RouterController.router.location.route && currentSelection.endsWith('/dev-ui/') && defaultRoute) { + } else if(!RouterController.router.location.route && currentSelection.endsWith('/dev-ui/') && defaultRoute) { Router.go({pathname: path, search}); + // We do not know and have not yet loaded the requested location + } else if (!RouterController.router.location.route && defaultRoute) { + // pass original query param + const currentQueryString = window.location.search; + const origSearch = currentQueryString?.length > 0 ? '&' + currentQueryString : ''; + + Router.go({ + pathname: path, + search: '?from=' + currentSelection + origSearch, + }); + } + } + } + + getQueryParamsWithoutFrom() { + const params = new URLSearchParams(window.location.search); + if (params) { + const paramsWithoutFrom = []; + params.forEach((value, key) => { + if (key !== 'from') { + paramsWithoutFrom.push(key + '=' + value) + } + }); + if (paramsWithoutFrom.length > 0) { + return paramsWithoutFrom.join('&'); } } + return ''; } getQueryParameters() { diff --git a/independent-projects/extension-maven-plugin/pom.xml b/independent-projects/extension-maven-plugin/pom.xml index 512b1e0453f97..421090a13c0fa 100644 --- a/independent-projects/extension-maven-plugin/pom.xml +++ b/independent-projects/extension-maven-plugin/pom.xml @@ -41,7 +41,7 @@ 3.12.1 3.2.1 3.2.5 - 2.16.1 + 2.17.0 1.4.0 5.10.2 diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java index 60990009a9d88..92ec1af83341f 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/StorkClientRequestFilter.java @@ -15,9 +15,7 @@ import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestFilter; import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.Uni; import io.smallrye.stork.Stork; -import io.smallrye.stork.api.ServiceInstance; @Priority(Priorities.AUTHENTICATION) @Provider @@ -34,67 +32,64 @@ public void filter(ResteasyReactiveClientRequestContext requestContext) { } requestContext.suspend(); - Uni serviceInstance; boolean measureTime = shouldMeasureTime(requestContext.getResponseType()); try { - serviceInstance = Stork.getInstance() + Stork.getInstance() .getService(serviceName) - .selectInstanceAndRecordStart(measureTime); - } catch (Throwable e) { - log.error("Error selecting service instance for serviceName: " + serviceName, e); - requestContext.resume(e); - return; - } - - serviceInstance.subscribe() - .with(instance -> { - boolean isHttps = instance.isSecure() || "storks".equals(uri.getScheme()); - String scheme = isHttps ? "https" : "http"; - try { - // In the case the service instance does not set the host and/or port - String host = instance.getHost() == null ? "localhost" : instance.getHost(); - int port = instance.getPort(); - if (instance.getPort() == 0) { - if (isHttps) { - port = 433; - } else { - port = 80; - } - } - // Service instance can also contain an optional path. - Optional path = instance.getPath(); - String actualPath = uri.getRawPath(); - if (path.isPresent()) { - var p = path.get(); - if (!p.startsWith("/")) { - p = "/" + p; + .selectInstanceAndRecordStart(measureTime) + .subscribe() + .with(instance -> { + boolean isHttps = instance.isSecure() || "storks".equals(uri.getScheme()); + String scheme = isHttps ? "https" : "http"; + try { + // In the case the service instance does not set the host and/or port + String host = instance.getHost() == null ? "localhost" : instance.getHost(); + int port = instance.getPort(); + if (instance.getPort() == 0) { + if (isHttps) { + port = 433; + } else { + port = 80; + } } - if (actualPath == null) { - actualPath = p; - } else { - // Append both. - if (actualPath.startsWith("/") || p.endsWith("/")) { - actualPath = p + actualPath; + // Service instance can also contain an optional path. + Optional path = instance.getPath(); + String actualPath = uri.getRawPath(); + if (path.isPresent()) { + var p = path.get(); + if (!p.startsWith("/")) { + p = "/" + p; + } + if (actualPath == null) { + actualPath = p; } else { - actualPath = p + "/" + actualPath; + // Append both. + if (actualPath.startsWith("/") || p.endsWith("/")) { + actualPath = p + actualPath; + } else { + actualPath = p + "/" + actualPath; + } } } + //To avoid the path double encoding we create uri with path=null and set the path after + URI newUri = new URI(scheme, + uri.getUserInfo(), host, port, + null, uri.getQuery(), uri.getFragment()); + URI build = UriBuilder.fromUri(newUri).path(actualPath).build(); + requestContext.setUri(build); + if (measureTime && instance.gatherStatistics()) { + requestContext.setCallStatsCollector(instance); + } + requestContext.resume(); + } catch (URISyntaxException e) { + requestContext.resume(new IllegalArgumentException("Invalid URI", e)); } - //To avoid the path double encoding we create uri with path=null and set the path after - URI newUri = new URI(scheme, - uri.getUserInfo(), host, port, - null, uri.getQuery(), uri.getFragment()); - URI build = UriBuilder.fromUri(newUri).path(actualPath).build(); - requestContext.setUri(build); - if (measureTime && instance.gatherStatistics()) { - requestContext.setCallStatsCollector(instance); - } - requestContext.resume(); - } catch (URISyntaxException e) { - requestContext.resume(new IllegalArgumentException("Invalid URI", e)); - } - }, - requestContext::resume); + }, + requestContext::resume); + } catch (Throwable e) { + log.error("Error selecting service instance for serviceName: " + serviceName, e); + requestContext.resume(e); + } } } diff --git a/independent-projects/resteasy-reactive/pom.xml b/independent-projects/resteasy-reactive/pom.xml index 1bd5c8e1dd860..e9186770ab69f 100644 --- a/independent-projects/resteasy-reactive/pom.xml +++ b/independent-projects/resteasy-reactive/pom.xml @@ -64,7 +64,7 @@ 4.5.7 5.4.0 1.0.0.Final - 2.16.1 + 2.17.0 2.6.0 3.0.2 3.0.3 diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/Deployment.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/Deployment.java index be49b103a3a77..09d35ca9800a8 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/Deployment.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/Deployment.java @@ -47,12 +47,14 @@ public class Deployment { private final ArrayList> classMappers; private final List> runtimeConfigurableServerRestHandlers; private final RuntimeExceptionMapper exceptionMapper; + private final boolean servletPresent; private final ResteasyReactiveConfig resteasyReactiveConfig; private final Map> disabledEndpoints; //this is not final, as it is set after startup private RuntimeConfiguration runtimeConfiguration; - public Deployment(ExceptionMapping exceptionMapping, ContextResolvers contextResolvers, + public Deployment(ExceptionMapping exceptionMapping, + ContextResolvers contextResolvers, ServerSerialisers serialisers, ServerRestHandler[] abortHandlerChain, EntityWriter dynamicEntityWriter, String prefix, ParamConverterProviders paramConverterProviders, @@ -62,6 +64,7 @@ public Deployment(ExceptionMapping exceptionMapping, ContextResolvers contextRes ArrayList> classMappers, List> runtimeConfigurableServerRestHandlers, RuntimeExceptionMapper exceptionMapper, + boolean servletPresent, ResteasyReactiveConfig resteasyReactiveConfig, Map> disabledEndpoints) { this.exceptionMapping = exceptionMapping; @@ -79,6 +82,7 @@ public Deployment(ExceptionMapping exceptionMapping, ContextResolvers contextRes this.classMappers = classMappers; this.runtimeConfigurableServerRestHandlers = runtimeConfigurableServerRestHandlers; this.exceptionMapper = exceptionMapper; + this.servletPresent = servletPresent; this.resteasyReactiveConfig = resteasyReactiveConfig; this.disabledEndpoints = disabledEndpoints; } @@ -103,6 +107,10 @@ public ExceptionMapping getExceptionMapping() { return exceptionMapping; } + public boolean isServletPresent() { + return servletPresent; + } + public ContextResolvers getContextResolvers() { return contextResolvers; } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/DeploymentInfo.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/DeploymentInfo.java index 6234b51970142..374ec3aa254e9 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/DeploymentInfo.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/DeploymentInfo.java @@ -38,6 +38,7 @@ public class DeploymentInfo { private String applicationPath; private List globalHandlerCustomizers = new ArrayList<>(); private boolean developmentMode; + private boolean servletPresent = false; public ResourceInterceptors getInterceptors() { return interceptors; @@ -191,4 +192,13 @@ public DeploymentInfo setDevelopmentMode(boolean developmentMode) { this.developmentMode = developmentMode; return this; } + + public boolean isServletPresent() { + return servletPresent; + } + + public DeploymentInfo setServletPresent(boolean servletPresent) { + this.servletPresent = servletPresent; + return this; + } } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeDeploymentManager.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeDeploymentManager.java index 3e00d096a614d..b5734722de63a 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeDeploymentManager.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeDeploymentManager.java @@ -234,7 +234,8 @@ public BeanFactory.BeanInstance apply(Class aClass) { abortHandlingChain.toArray(EMPTY_REST_HANDLER_ARRAY), dynamicEntityWriter, prefix, paramConverterProviders, configurationImpl, applicationSupplier, threadSetupAction, requestContextFactory, preMatchHandlers, classMappers, - runtimeConfigurableServerRestHandlers, exceptionMapper, info.getResteasyReactiveConfig(), + runtimeConfigurableServerRestHandlers, exceptionMapper, info.isServletPresent(), + info.getResteasyReactiveConfig(), disabledEndpoints); } @@ -243,7 +244,7 @@ private void forEachMapperEntry(MappersKey key, int classTemplateNameCount = key.path.countPathParamNames(); RuntimeMappingDeployment runtimeMappingDeployment = new RuntimeMappingDeployment(classTemplates); ClassRoutingHandler classRoutingHandler = new ClassRoutingHandler(runtimeMappingDeployment.buildClassMapper(), - classTemplateNameCount); + classTemplateNameCount, info.isServletPresent()); classMappers.add(new RequestMapper.RequestPath<>(true, key.path, new RestInitialHandler.InitialMatch(new ServerRestHandler[] { classRoutingHandler }, runtimeMappingDeployment.getMaxMethodTemplateNameCount() + classTemplateNameCount))); diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/ClassRoutingHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/ClassRoutingHandler.java index b4f34f25d944f..efbd79da49c24 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/ClassRoutingHandler.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/ClassRoutingHandler.java @@ -33,10 +33,13 @@ public class ClassRoutingHandler implements ServerRestHandler { private final Map> mappers; private final int parameterOffset; + final boolean servletPresent; - public ClassRoutingHandler(Map> mappers, int parameterOffset) { + public ClassRoutingHandler(Map> mappers, int parameterOffset, + boolean servletPresent) { this.mappers = mappers; this.parameterOffset = parameterOffset; + this.servletPresent = servletPresent; } @Override @@ -226,7 +229,7 @@ private void throwNotFound(ResteasyReactiveRequestContext requestContext) { ProvidersImpl providers = requestContext.getProviders(); ExceptionMapper exceptionMapper = providers.getExceptionMapper(NotFoundException.class); - if (exceptionMapper == null) { + if (exceptionMapper == null || servletPresent) { if (requestContext.resumeExternalProcessing()) { return; } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RestInitialHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RestInitialHandler.java index 558ba876af1cf..6afebf58c4fe9 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RestInitialHandler.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RestInitialHandler.java @@ -63,7 +63,10 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti ProvidersImpl providers = requestContext.getProviders(); ExceptionMapper exceptionMapper = providers.getExceptionMapper(NotFoundException.class); - if (exceptionMapper != null) { + if (exceptionMapper != null && !deployment.isServletPresent()) { + // the NotFoundExceptionMapper needs access to the headers so we need to activate the scope + requestContext.requireCDIRequestScope(); + // we want to engage the NotFoundExceptionMapper when nothing is found requestContext.handleException(new NotFoundException()); return; } else if (requestContext.resumeExternalProcessing()) { diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateRecipe.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateRecipe.java index 2d6339b98ae9d..2881032b0fd5d 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateRecipe.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateRecipe.java @@ -51,6 +51,10 @@ public QuarkusUpdateRecipe addRecipe(Map recipe) { if (!recipe.containsKey("name") || !(recipe.get("name") instanceof String)) { throw new IllegalArgumentException("Recipe name is required"); } + // some YAML documents might not be recipes. For instance, they could be categories. + if (!recipe.containsKey("type") || !recipe.get("type").toString().endsWith("/recipe")) { + return this; + } this.recipes.add(recipe); return this; } diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml index f96f2eeda0bfc..9c17353f85dd9 100644 --- a/independent-projects/tools/pom.xml +++ b/independent-projects/tools/pom.xml @@ -49,7 +49,7 @@ 3.25.3 - 2.16.1 + 2.17.0 4.0.1 5.10.2 1.26.1 diff --git a/integration-tests/amazon-lambda-http-resteasy-reactive/pom.xml b/integration-tests/amazon-lambda-http-resteasy-reactive/pom.xml index 121ac2b9b2806..1037b6d3d9329 100644 --- a/integration-tests/amazon-lambda-http-resteasy-reactive/pom.xml +++ b/integration-tests/amazon-lambda-http-resteasy-reactive/pom.xml @@ -11,7 +11,7 @@ quarkus-integration-test-amazon-lambda-http-resteasy-reactive Quarkus - Integration Tests - Amazon Lambda HTTP RESTEasy Reactive - Test with Resteasy Reactive and Amazon Lambda HTTP + Test with Quarkus REST and Amazon Lambda HTTP io.quarkus diff --git a/integration-tests/amazon-lambda-rest-resteasy-reactive/pom.xml b/integration-tests/amazon-lambda-rest-resteasy-reactive/pom.xml index 4a71a8d3cbb2a..d6842b9c53217 100644 --- a/integration-tests/amazon-lambda-rest-resteasy-reactive/pom.xml +++ b/integration-tests/amazon-lambda-rest-resteasy-reactive/pom.xml @@ -11,7 +11,7 @@ quarkus-integration-test-amazon-lambda-rest-resteasy-reactive Quarkus - Integration Tests - Amazon Lambda AWS Gateway REST API - Module that contains Amazon Lambda related tests for RESTEasy Reactive + Module that contains Amazon Lambda related tests for Quarkus REST io.quarkus diff --git a/integration-tests/hibernate-validator-resteasy-reactive/pom.xml b/integration-tests/hibernate-validator-resteasy-reactive/pom.xml index 530f503282a58..e97d2598faa5d 100644 --- a/integration-tests/hibernate-validator-resteasy-reactive/pom.xml +++ b/integration-tests/hibernate-validator-resteasy-reactive/pom.xml @@ -11,7 +11,7 @@ quarkus-integration-test-hibernate-validator-resteasy-reactive Quarkus - Integration Tests - Hibernate Validator - Module that contains Hibernate Validator/Bean Validation related tests using RESTEasy Reactive + Module that contains Hibernate Validator/Bean Validation related tests using Quarkus REST diff --git a/integration-tests/oidc-client-reactive/pom.xml b/integration-tests/oidc-client-reactive/pom.xml index b753e79946d43..35cb2616b04d7 100644 --- a/integration-tests/oidc-client-reactive/pom.xml +++ b/integration-tests/oidc-client-reactive/pom.xml @@ -12,7 +12,7 @@ quarkus-integration-test-oidc-client-reactive Quarkus - Integration Tests - OpenID Connect Client Reactive - Module that contains OpenID Connect Client tests using RESTEasy Reactive + Module that contains OpenID Connect Client tests using Quarkus REST http://localhost:8180/auth diff --git a/integration-tests/resteasy-reactive-kotlin/pom.xml b/integration-tests/resteasy-reactive-kotlin/pom.xml index 92515457261da..a2858bbd856e1 100644 --- a/integration-tests/resteasy-reactive-kotlin/pom.xml +++ b/integration-tests/resteasy-reactive-kotlin/pom.xml @@ -11,7 +11,7 @@ quarkus-integration-test-resteasy-reactive-kotlin-parent - Quarkus - Integration Tests - RESTEasy Reactive Kotlin - Parent + Quarkus - Integration Tests - Quarkus REST Kotlin - Parent pom diff --git a/integration-tests/vertx-http/src/main/resources/META-INF/resources/dummy/index.html b/integration-tests/vertx-http/src/main/resources/META-INF/resources/dummy/index.html new file mode 100644 index 0000000000000..6cb29f572ede2 --- /dev/null +++ b/integration-tests/vertx-http/src/main/resources/META-INF/resources/dummy/index.html @@ -0,0 +1,7 @@ + + + Hello world + +Hello World + + diff --git a/integration-tests/vertx-http/src/main/resources/META-INF/resources/dummy2/test.html b/integration-tests/vertx-http/src/main/resources/META-INF/resources/dummy2/test.html new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/integration-tests/vertx-http/src/main/resources/META-INF/resources/l1/l2/index.html b/integration-tests/vertx-http/src/main/resources/META-INF/resources/l1/l2/index.html new file mode 100644 index 0000000000000..6cb29f572ede2 --- /dev/null +++ b/integration-tests/vertx-http/src/main/resources/META-INF/resources/l1/l2/index.html @@ -0,0 +1,7 @@ + + + Hello world + +Hello World + + diff --git a/integration-tests/vertx-http/src/main/resources/META-INF/resources/test.txt b/integration-tests/vertx-http/src/main/resources/META-INF/resources/test.txt new file mode 100644 index 0000000000000..9daeafb9864cf --- /dev/null +++ b/integration-tests/vertx-http/src/main/resources/META-INF/resources/test.txt @@ -0,0 +1 @@ +test diff --git a/integration-tests/vertx-http/src/test/java/io/quarkus/it/vertx/StaticResourcesIT.java b/integration-tests/vertx-http/src/test/java/io/quarkus/it/vertx/StaticResourcesIT.java new file mode 100644 index 0000000000000..d20e98d4a2c53 --- /dev/null +++ b/integration-tests/vertx-http/src/test/java/io/quarkus/it/vertx/StaticResourcesIT.java @@ -0,0 +1,7 @@ +package io.quarkus.it.vertx; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +public class StaticResourcesIT extends StaticResourcesTest { +} diff --git a/integration-tests/vertx-http/src/test/java/io/quarkus/it/vertx/StaticResourcesTest.java b/integration-tests/vertx-http/src/test/java/io/quarkus/it/vertx/StaticResourcesTest.java new file mode 100644 index 0000000000000..028044c2feda7 --- /dev/null +++ b/integration-tests/vertx-http/src/test/java/io/quarkus/it/vertx/StaticResourcesTest.java @@ -0,0 +1,41 @@ +package io.quarkus.it.vertx; + +import static io.restassured.RestAssured.when; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class StaticResourcesTest { + + @Test + public void testExisting() { + when().get("/test.txt").then().statusCode(200); + } + + @Test + public void testNonExisting() { + when().get("/test2.txt").then().statusCode(404); + } + + @Test + public void testIndexInDirectory() { + when().get("/dummy/").then().statusCode(200); + } + + @Test + public void testIndexInNestedDirectory() { + when().get("/l1/l2/").then().statusCode(200); + } + + @Test + public void testNonIndexInDirectory() { + when().get("/dummy2/").then().statusCode(404); + } + + @Test + public void testIndexInNonExistingDirectory() { + when().get("/dummy3/").then().statusCode(404); + } +}