From 50810260533f1e6aad0db139b1433f7506f36da6 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Mon, 20 Nov 2023 15:22:35 +0100 Subject: [PATCH 01/48] Qute: dev mode - no-restart-templates - fix javadoc in QuteDevModeConfig - improve NoRestartTemplatesDevModeTest (cherry picked from commit 2ff97152d6c07d8b3b4a7effaa98e37f6c2e79f0) --- .../deployment/devmode/NoRestartRoute.java | 13 +++++++-- .../NoRestartTemplatesDevModeTest.java | 28 ++++++++++++++----- .../qute/runtime/QuteDevModeConfig.java | 4 +-- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartRoute.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartRoute.java index 454868cd93d71..43f088655cfda 100644 --- a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartRoute.java +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartRoute.java @@ -6,6 +6,7 @@ import jakarta.inject.Inject; import jakarta.inject.Singleton; +import io.quarkus.qute.Location; import io.quarkus.qute.Template; import io.quarkus.vertx.web.Route; import io.vertx.ext.web.RoutingContext; @@ -15,12 +16,20 @@ public class NoRestartRoute { private String id; - @Inject + @Location("foo/norestart") Template norestart; + @Inject + Template bar; + @Route(path = "norestart") public void test(RoutingContext ctx) { - ctx.end(norestart.data("foo", id).render()); + ctx.end(norestart.data("id", id).render()); + } + + @Route(path = "bar") + public void testBar(RoutingContext ctx) { + ctx.end(bar.data("id", id).render()); } @PostConstruct diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartTemplatesDevModeTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartTemplatesDevModeTest.java index c7d9dca8e6717..5636fa2b77782 100644 --- a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartTemplatesDevModeTest.java +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/devmode/NoRestartTemplatesDevModeTest.java @@ -18,10 +18,13 @@ public class NoRestartTemplatesDevModeTest { .withApplicationRoot(root -> root .addClass(NoRestartRoute.class) .addAsResource(new StringAsset( - "Hello {foo}!"), - "templates/norestart.html") + "Hello {id}!"), + "templates/foo/norestart.html") .addAsResource(new StringAsset( - "quarkus.qute.dev-mode.no-restart-templates=templates/norestart.html"), + "Hi {id}!"), + "templates/bar.html") + .addAsResource(new StringAsset( + "quarkus.qute.dev-mode.no-restart-templates=templates/.+"), "application.properties")); @Test @@ -29,14 +32,25 @@ public void testNoRestartTemplates() { Response resp = given().get("norestart"); resp.then() .statusCode(200); - String val = resp.getBody().asString(); - assertTrue(val.startsWith("Hello ")); + String val1 = resp.getBody().asString(); + assertTrue(val1.startsWith("Hello ")); + + resp = given().get("bar"); + resp.then() + .statusCode(200); + String val2 = resp.getBody().asString(); + assertTrue(val2.startsWith("Hi ")); - config.modifyResourceFile("templates/norestart.html", t -> t.concat("!!")); + config.modifyResourceFile("templates/foo/norestart.html", t -> t.concat("!!")); + config.modifyResourceFile("templates/bar.html", t -> t.concat("!!")); resp = given().get("norestart"); resp.then().statusCode(200); - assertEquals(val + "!!", resp.getBody().asString()); + assertEquals(val1 + "!!", resp.getBody().asString()); + + resp = given().get("bar"); + resp.then().statusCode(200); + assertEquals(val2 + "!!", resp.getBody().asString()); } } diff --git a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/QuteDevModeConfig.java b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/QuteDevModeConfig.java index be0787fc88113..843a08b3eadcf 100644 --- a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/QuteDevModeConfig.java +++ b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/QuteDevModeConfig.java @@ -15,8 +15,8 @@ public class QuteDevModeConfig { * This regular expression can be used to specify the templates for which the application is not restarted. * I.e. the templates are reloaded and only runtime validations are performed. *

- * The matched input is the template path relative from the {@code templates} directory and the - * {@code /} is used as a path separator. For example, {@code templates/foo.html}. + * The matched input is the template path that starts with a template root, and the {@code /} is used as a path separator. + * For example, {@code templates/foo.html}. */ @ConfigItem public Optional noRestartTemplates; From 738f27fcd724a92b86e34453bf5d250505ac4d49 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Tue, 21 Nov 2023 11:27:38 +0100 Subject: [PATCH 02/48] Dev mode: RuntimeUpdatesProcessor - never watch directories (cherry picked from commit f90ca79c153fb444384e057e123ef24a6411ae59) --- .../io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java index 0a92c1909a8fe..24a1c175a3059 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java @@ -1128,7 +1128,9 @@ private RuntimeUpdatesProcessor setWatchedFilePathsInternal(Map // First find all matching paths from all roots try (final Stream walk = Files.walk(root)) { walk.forEach(path -> { - if (path.equals(root)) { + if (path.equals(root) + // Never watch directories + || Files.isDirectory(path)) { return; } // Use the relative path to match the watched file From 927a5e7cf2f69356a926f5643bc4bea3c03682cf Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Mon, 20 Nov 2023 18:55:12 +0100 Subject: [PATCH 03/48] Add classes from additional JPA model build items to pre-generate proxies (cherry picked from commit c48339d0f9d84bd0770ad942a20448ed543bf388) --- .../hibernate/orm/deployment/HibernateOrmProcessor.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java index 8a45d4ceca3c5..7d0101630b26a 100644 --- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java +++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java @@ -416,6 +416,7 @@ public BytecodeRecorderConstantDefinitionBuildItem pregenProxies( JpaModelIndexBuildItem indexBuildItem, TransformedClassesBuildItem transformedClassesBuildItem, List persistenceUnitDescriptorBuildItems, + List additionalJpaModelBuildItems, BuildProducer generatedClassBuildItemBuildProducer, LiveReloadBuildItem liveReloadBuildItem) { Set managedClassAndPackageNames = new HashSet<>(jpaModel.getEntityClassNames()); @@ -426,6 +427,11 @@ public BytecodeRecorderConstantDefinitionBuildItem pregenProxies( // is used for packages too, and it relies (indirectly) on getManagedClassNames(). managedClassAndPackageNames.addAll(pud.getManagedClassNames()); } + + for (AdditionalJpaModelBuildItem additionalJpaModelBuildItem : additionalJpaModelBuildItems) { + managedClassAndPackageNames.add(additionalJpaModelBuildItem.getClassName()); + } + PreGeneratedProxies proxyDefinitions = generatedProxies(managedClassAndPackageNames, indexBuildItem.getIndex(), transformedClassesBuildItem, generatedClassBuildItemBuildProducer, liveReloadBuildItem); From 01e8d18d3196f33598d38b72e3311654a2c8fa9a Mon Sep 17 00:00:00 2001 From: Jonathan Kolberg Date: Tue, 21 Nov 2023 13:51:10 +0100 Subject: [PATCH 04/48] Update kindcontainer to 1.4.4 (cherry picked from commit 8596fc96deb8a043f0465e0fc740b250f1375cdd) --- bom/application/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 055ec2d25c619..0b50b2d09ee88 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -210,7 +210,7 @@ 3.3.3 2.0.0 - 1.3.0 + 1.4.4 2.7 2.4 2.4.0 From ad8ebe7391ab78ad8b86fdc27fc44f648e774a28 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 21 Nov 2023 12:28:56 +0000 Subject: [PATCH 05/48] Always execute a JPA password action (cherry picked from commit 2c29d55a7cadc4fcd4d792aeee9e160f54961ab9) --- .../common/deployment/JpaSecurityIdentityUtil.java | 13 ++++++++++--- .../jpa/common/runtime/JpaIdentityProviderUtil.java | 12 ++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java b/extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java index 5501ea4444353..054fcb33d6e69 100644 --- a/extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java +++ b/extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java @@ -45,18 +45,21 @@ public static void buildIdentity(Index index, JpaSecurityDefinition jpaSecurityD PanacheEntityPredicateBuildItem panacheEntityPredicate, FieldDescriptor passwordProviderField, MethodCreator outerMethod, ResultHandle userVar, BytecodeCreator innerMethod) { // if(user == null) throw new AuthenticationFailedException(); + + PasswordType passwordType = passwordTypeValue != null ? PasswordType.valueOf(passwordTypeValue.asEnum()) + : PasswordType.MCF; + try (BytecodeCreator trueBranch = innerMethod.ifNull(userVar).trueBranch()) { + ResultHandle exceptionInstance = trueBranch .newInstance(MethodDescriptor.ofConstructor(AuthenticationFailedException.class)); + trueBranch.invokeStaticMethod(passwordActionMethod(), trueBranch.load(passwordType)); trueBranch.throwException(exceptionInstance); } // :pass = user.pass | user.getPass() ResultHandle pass = jpaSecurityDefinition.password.readValue(innerMethod, userVar); - PasswordType passwordType = passwordTypeValue != null ? PasswordType.valueOf(passwordTypeValue.asEnum()) - : PasswordType.MCF; - if (passwordType == PasswordType.CUSTOM && passwordProviderValue == null) { throw new RuntimeException("Missing password provider for password type: " + passwordType); } @@ -245,4 +248,8 @@ private static MethodDescriptor getUtilMethod(String passwordProviderMethod) { return MethodDescriptor.ofMethod(JpaIdentityProviderUtil.class, passwordProviderMethod, org.wildfly.security.password.Password.class, String.class); } + + private static MethodDescriptor passwordActionMethod() { + return MethodDescriptor.ofMethod(JpaIdentityProviderUtil.class, "passwordAction", void.class, PasswordType.class); + } } diff --git a/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/common/runtime/JpaIdentityProviderUtil.java b/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/common/runtime/JpaIdentityProviderUtil.java index a65f771596a5d..15a3c4710d1c8 100644 --- a/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/common/runtime/JpaIdentityProviderUtil.java +++ b/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/common/runtime/JpaIdentityProviderUtil.java @@ -2,6 +2,7 @@ import java.security.spec.InvalidKeySpecException; import java.util.List; +import java.util.UUID; import org.wildfly.security.credential.PasswordCredential; import org.wildfly.security.evidence.PasswordGuessEvidence; @@ -10,9 +11,11 @@ import org.wildfly.security.password.util.ModularCrypt; import org.wildfly.security.provider.util.ProviderUtil; +import io.quarkus.elytron.security.common.BcryptUtil; import io.quarkus.security.AuthenticationFailedException; import io.quarkus.security.identity.request.TrustedAuthenticationRequest; import io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest; +import io.quarkus.security.jpa.PasswordType; import io.quarkus.security.runtime.QuarkusPrincipal; import io.quarkus.security.runtime.QuarkusSecurityIdentity; @@ -70,4 +73,13 @@ public static Password getMcfPassword(String pass) { throw new RuntimeException(e); } } + + public static void passwordAction(PasswordType type) { + String uuid = UUID.randomUUID().toString(); + if (type == PasswordType.CLEAR) { + ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR, uuid.toCharArray()); + } else { + BcryptUtil.bcryptHash(uuid); + } + } } From db8054a3232711b75d9576265c8619aa88bf66f0 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 22 Nov 2023 17:41:18 +0100 Subject: [PATCH 06/48] Docs: add keywords to Vert.x guides - so that it's possible to filter guides via "vertx" instead of "vert.x" (cherry picked from commit 470d96fa8de36b360b389565bb2fdd4ec292a261) --- docs/src/main/asciidoc/reactive-event-bus.adoc | 1 + docs/src/main/asciidoc/vertx-reference.adoc | 1 + docs/src/main/asciidoc/vertx.adoc | 1 + 3 files changed, 3 insertions(+) diff --git a/docs/src/main/asciidoc/reactive-event-bus.adoc b/docs/src/main/asciidoc/reactive-event-bus.adoc index b1c03416d0770..d0c2f3bc2ab52 100644 --- a/docs/src/main/asciidoc/reactive-event-bus.adoc +++ b/docs/src/main/asciidoc/reactive-event-bus.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using the event bus include::_attributes.adoc[] :categories: messaging +:keywords: vertx vert.x :summary: This guide explains how different beans can interact using the event bus. :topics: messaging,event-bus,vert.x :extensions: io.quarkus:quarkus-vertx diff --git a/docs/src/main/asciidoc/vertx-reference.adoc b/docs/src/main/asciidoc/vertx-reference.adoc index eed2eadb4d316..a069688101698 100644 --- a/docs/src/main/asciidoc/vertx-reference.adoc +++ b/docs/src/main/asciidoc/vertx-reference.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Vert.x Reference Guide include::_attributes.adoc[] :categories: miscellaneous +:keywords: vertx event verticle :summary: This reference guide provides advanced details about the usage and the configuration of the Vert.x instance used by Quarkus. https://vertx.io[Vert.x] is a toolkit for building reactive applications. diff --git a/docs/src/main/asciidoc/vertx.adoc b/docs/src/main/asciidoc/vertx.adoc index 09fb4a2a4b706..c5bbb73681ebd 100644 --- a/docs/src/main/asciidoc/vertx.adoc +++ b/docs/src/main/asciidoc/vertx.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using Eclipse Vert.x API from a Quarkus Application include::_attributes.adoc[] :categories: miscellaneous +:keywords: vertx event verticle :summary: This guide explains how to use Vert.x in Quarkus to build reactive applications. https://vertx.io[Vert.x] is a toolkit for building reactive applications. From 60933cecc0ea6d17f449586b151dee560f8a8793 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 22 Nov 2023 17:20:42 +0100 Subject: [PATCH 07/48] Vert.x: report exception for blocking message consumer methods - fixes #37222 (cherry picked from commit 9917e6bfe277c5d777e9d29ef0a6f36fcf2668f3) --- .../vertx/deployment/MessageConsumerFailureTest.java | 12 +++++++++--- .../vertx/runtime/VertxEventBusConsumerRecorder.java | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/deployment/MessageConsumerFailureTest.java b/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/deployment/MessageConsumerFailureTest.java index c282c6c1bb49a..888acb58d3d07 100644 --- a/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/deployment/MessageConsumerFailureTest.java +++ b/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/deployment/MessageConsumerFailureTest.java @@ -58,6 +58,12 @@ public void testFailure() throws InterruptedException { @Test public void testFailureNoReplyHandler() throws InterruptedException { + verifyFailureNoReply("foo", "Foo is dead", IllegalStateException.class); + verifyFailureNoReply("foo-blocking", "Red is dead", IllegalStateException.class); + } + + void verifyFailureNoReply(String address, String expectedMessage, Class expectedException) + throws InterruptedException { Handler oldHandler = vertx.exceptionHandler(); try { BlockingQueue synchronizer = new LinkedBlockingQueue<>(); @@ -71,10 +77,10 @@ public void handle(Throwable event) { } } }); - eventBus.send("foo", "bar"); + eventBus.send(address, "hello"); Object ret = synchronizer.poll(2, TimeUnit.SECONDS); - assertTrue(ret instanceof IllegalStateException); - assertEquals("Foo is dead", ((IllegalStateException) ret).getMessage()); + assertTrue(expectedException.isAssignableFrom(ret.getClass())); + assertEquals(expectedMessage, ((Throwable) ret).getMessage()); } finally { vertx.exceptionHandler(oldHandler); } diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/VertxEventBusConsumerRecorder.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/VertxEventBusConsumerRecorder.java index 7a3edda524766..b5f60a42f2246 100644 --- a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/VertxEventBusConsumerRecorder.java +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/VertxEventBusConsumerRecorder.java @@ -28,6 +28,7 @@ import io.smallrye.common.vertx.VertxContext; import io.vertx.core.AsyncResult; import io.vertx.core.Context; +import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.eventbus.EventBus; @@ -138,7 +139,7 @@ public void run() { } }); } else { - dup.executeBlocking(new Callable() { + Future future = dup.executeBlocking(new Callable() { @Override public Void call() { try { @@ -154,6 +155,7 @@ public Void call() { return null; } }, invoker.isOrdered()); + future.onFailure(context::reportException); } } else { // Will run on the context used for the consumer registration. From 0aa55d575badfe99d19467f6cfb233feeafc3d79 Mon Sep 17 00:00:00 2001 From: Falko Modler Date: Thu, 23 Nov 2023 18:51:56 +0100 Subject: [PATCH 08/48] Bump testcontainers to 1.19.3 and use docker-java-bom (cherry picked from commit 12c2bbe539c67be36a9416cac29885c2c02b4411) --- bom/application/pom.xml | 48 +++++------------------------------------ 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 0b50b2d09ee88..ce0740f2a0634 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -206,8 +206,8 @@ 1.11.3 2.4.14.Final 0.1.18.Final - 1.19.1 - 3.3.3 + 1.19.3 + 3.3.4 2.0.0 1.4.4 @@ -3304,48 +3304,10 @@ com.github.docker-java - docker-java - ${docker-java.version} - - - com.github.docker-java - docker-java-api - ${docker-java.version} - - - com.github.docker-java - docker-java-core - ${docker-java.version} - - - com.github.docker-java - docker-java-transport - ${docker-java.version} - - - com.github.docker-java - docker-java-transport-httpclient5 - ${docker-java.version} - - - com.github.docker-java - docker-java-transport-jersey - ${docker-java.version} - - - com.github.docker-java - docker-java-transport-netty - ${docker-java.version} - - - com.github.docker-java - docker-java-transport-okhttp - ${docker-java.version} - - - com.github.docker-java - docker-java-transport-zerodep + docker-java-bom ${docker-java.version} + pom + import com.google.cloud.functions From b546555f29ab4f0591057043ae10e2d62ce7438c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:22:59 +0000 Subject: [PATCH 09/48] Bump org.jetbrains.kotlin:kotlin-gradle-plugin-api in /devtools/gradle Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin-api](https://github.com/JetBrains/kotlin) from 1.9.20 to 1.9.21. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.20...v1.9.21) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] (cherry picked from commit 463e0c6d8f1f904af95043bc7f8b596d1686106d) --- devtools/gradle/gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/gradle/gradle/libs.versions.toml b/devtools/gradle/gradle/libs.versions.toml index 9902875d78e44..5bb10bc0b84fc 100644 --- a/devtools/gradle/gradle/libs.versions.toml +++ b/devtools/gradle/gradle/libs.versions.toml @@ -2,7 +2,7 @@ plugin-publish = "1.2.1" # updating Kotlin here makes QuarkusPluginTest > shouldNotFailOnProjectDependenciesWithoutMain(Path) fail -kotlin = "1.9.20" +kotlin = "1.9.21" smallrye-config = "3.4.4" junit5 = "5.10.1" From d88f2643c4731b3dbcd285137f57b61490fd9f79 Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Fri, 24 Nov 2023 07:55:34 +0100 Subject: [PATCH 10/48] Fix the major version of Java 21. 66 is Java 22. 65 is Java 21. (cherry picked from commit 3d815e7f09e4d1f2bdad4b86fc4c6ad6fd20964d) --- .../deployment/pkg/builditem/CompiledJavaVersionBuildItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CompiledJavaVersionBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CompiledJavaVersionBuildItem.java index 88dadbcc63dd4..ee2ab28b42d4d 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CompiledJavaVersionBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CompiledJavaVersionBuildItem.java @@ -76,7 +76,7 @@ final class Known implements JavaVersion { private static final int JAVA_11_MAJOR = 55; private static final int JAVA_17_MAJOR = 61; private static final int JAVA_19_MAJOR = 63; - private static final int JAVA_21_MAJOR = 66; + private static final int JAVA_21_MAJOR = 65; private final int determinedMajor; From ad0525f4ff56d36028f3afa1f16ff29817a37114 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 21 Nov 2023 14:34:17 +0000 Subject: [PATCH 11/48] Add a test showing how OIDC ID token can be propagated (cherry picked from commit 1e8c767ea5e8776d34947a1f964c429018eee6cb) --- .../quarkus/it/keycloak/FrontendResource.java | 12 ++++++++++ .../keycloak/IdTokenPropagationService.java | 20 ++++++++++++++++ .../IdTokenRequestReactiveFilter.java | 23 +++++++++++++++++++ .../it/keycloak/ProtectedResource.java | 8 +++---- .../src/main/resources/application.properties | 1 + .../OidcTokenReactivePropagationTest.java | 5 +++- 6 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenPropagationService.java create mode 100644 integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenRequestReactiveFilter.java diff --git a/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/FrontendResource.java b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/FrontendResource.java index 64d9d13c35a6e..58690fa283fd1 100644 --- a/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/FrontendResource.java +++ b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/FrontendResource.java @@ -16,6 +16,10 @@ public class FrontendResource { @RestClient AccessTokenPropagationService accessTokenPropagationService; + @Inject + @RestClient + IdTokenPropagationService idTokenPropagationService; + @Inject @RestClient ServiceWithoutToken serviceWithoutToken; @@ -28,6 +32,14 @@ public Uni userNameAccessTokenPropagation() { return accessTokenPropagationService.getUserName(); } + @GET + @Path("id-token-propagation") + @Produces("text/plain") + @RolesAllowed("user") + public Uni userNameIdTokenPropagation() { + return idTokenPropagationService.getUserName(); + } + @GET @Path("service-without-token") @Produces("text/plain") diff --git a/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenPropagationService.java b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenPropagationService.java new file mode 100644 index 0000000000000..8fe9e0e928cdd --- /dev/null +++ b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenPropagationService.java @@ -0,0 +1,20 @@ +package io.quarkus.it.keycloak; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; + +import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +import io.smallrye.mutiny.Uni; + +@RegisterRestClient +@RegisterProvider(IdTokenRequestReactiveFilter.class) +@Path("/") +public interface IdTokenPropagationService { + + @GET + @Produces("text/plain") + Uni getUserName(); +} diff --git a/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenRequestReactiveFilter.java b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenRequestReactiveFilter.java new file mode 100644 index 0000000000000..82186e45db0c6 --- /dev/null +++ b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/IdTokenRequestReactiveFilter.java @@ -0,0 +1,23 @@ +package io.quarkus.it.keycloak; + +import jakarta.annotation.Priority; +import jakarta.inject.Inject; +import jakarta.ws.rs.Priorities; +import jakarta.ws.rs.core.HttpHeaders; + +import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestContext; +import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestFilter; + +import io.quarkus.oidc.IdTokenCredential; + +@Priority(Priorities.AUTHENTICATION) +public class IdTokenRequestReactiveFilter implements ResteasyReactiveClientRequestFilter { + + @Inject + IdTokenCredential idToken; + + @Override + public void filter(ResteasyReactiveClientRequestContext requestContext) { + requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, "Bearer " + idToken.getToken()); + } +} diff --git a/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/ProtectedResource.java b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/ProtectedResource.java index c4cf5320e129a..3b3a2a78883e2 100644 --- a/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/ProtectedResource.java +++ b/integration-tests/oidc-token-propagation-reactive/src/main/java/io/quarkus/it/keycloak/ProtectedResource.java @@ -1,13 +1,13 @@ package io.quarkus.it.keycloak; -import java.security.Principal; - import jakarta.annotation.security.RolesAllowed; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; +import org.eclipse.microprofile.jwt.JsonWebToken; + import io.quarkus.security.Authenticated; import io.smallrye.mutiny.Uni; @@ -16,12 +16,12 @@ public class ProtectedResource { @Inject - Principal principal; + JsonWebToken jwt; @GET @Produces("text/plain") @RolesAllowed("user") public Uni principalName() { - return Uni.createFrom().item(principal.getName()); + return Uni.createFrom().item(jwt.getClaim("typ") + ":" + jwt.getName()); } } diff --git a/integration-tests/oidc-token-propagation-reactive/src/main/resources/application.properties b/integration-tests/oidc-token-propagation-reactive/src/main/resources/application.properties index 321847db72236..36253fa1c4c16 100644 --- a/integration-tests/oidc-token-propagation-reactive/src/main/resources/application.properties +++ b/integration-tests/oidc-token-propagation-reactive/src/main/resources/application.properties @@ -1,4 +1,5 @@ io.quarkus.it.keycloak.AccessTokenPropagationService/mp-rest/uri=http://localhost:8081/protected +io.quarkus.it.keycloak.IdTokenPropagationService/mp-rest/uri=http://localhost:8081/protected io.quarkus.it.keycloak.ServiceWithoutToken/mp-rest/uri=http://localhost:8081/protected quarkus.oidc.application-type=web-app diff --git a/integration-tests/oidc-token-propagation-reactive/src/test/java/io/quarkus/it/keycloak/OidcTokenReactivePropagationTest.java b/integration-tests/oidc-token-propagation-reactive/src/test/java/io/quarkus/it/keycloak/OidcTokenReactivePropagationTest.java index df2184d15568a..7a4cb646a36f0 100644 --- a/integration-tests/oidc-token-propagation-reactive/src/test/java/io/quarkus/it/keycloak/OidcTokenReactivePropagationTest.java +++ b/integration-tests/oidc-token-propagation-reactive/src/test/java/io/quarkus/it/keycloak/OidcTokenReactivePropagationTest.java @@ -29,8 +29,11 @@ public void testGetUserNameWithAccessTokenPropagation() throws Exception { loginForm.getInputByName("password").setValueAttribute("alice"); TextPage textPage = loginForm.getInputByName("login").click(); + assertEquals("Bearer:alice", textPage.getContent()); + + textPage = webClient.getPage("http://localhost:8081/frontend/id-token-propagation"); + assertEquals("ID:alice", textPage.getContent()); - assertEquals("alice", textPage.getContent()); webClient.getCookieManager().clearCookies(); } } From 82db5e6083e894b6821a9abb844e1aa05ef57b75 Mon Sep 17 00:00:00 2001 From: Martin Kofoed Date: Wed, 22 Nov 2023 15:15:42 +0100 Subject: [PATCH 12/48] When skipping @Provider auto-discovery for REST clients, take client filters into consideration (cherry picked from commit 42f23d8767b18329394f2bafbe648391a8297d47) --- .../RestClientReactiveProcessor.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java index 22a4b76f9b69e..5f5a7c34939f2 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java @@ -9,6 +9,8 @@ import static io.quarkus.rest.client.reactive.deployment.DotNames.CLIENT_QUERY_PARAM; import static io.quarkus.rest.client.reactive.deployment.DotNames.CLIENT_QUERY_PARAMS; import static io.quarkus.rest.client.reactive.deployment.DotNames.CLIENT_REDIRECT_HANDLER; +import static io.quarkus.rest.client.reactive.deployment.DotNames.CLIENT_REQUEST_FILTER; +import static io.quarkus.rest.client.reactive.deployment.DotNames.CLIENT_RESPONSE_FILTER; import static io.quarkus.rest.client.reactive.deployment.DotNames.REGISTER_CLIENT_HEADERS; import static io.quarkus.rest.client.reactive.deployment.DotNames.REGISTER_PROVIDER; import static io.quarkus.rest.client.reactive.deployment.DotNames.REGISTER_PROVIDERS; @@ -297,18 +299,10 @@ void registerProvidersFromAnnotations(CombinedIndexBuildItem indexBuildItem, } } - List providerInterfaceNames = providerClass.interfaceNames(); - // don't register server specific types - if (providerInterfaceNames.contains(ResteasyReactiveDotNames.CONTAINER_REQUEST_FILTER) - || providerInterfaceNames.contains(ResteasyReactiveDotNames.CONTAINER_RESPONSE_FILTER) - || providerInterfaceNames.contains(ResteasyReactiveDotNames.EXCEPTION_MAPPER)) { + if (skipAutoDiscoveredProvider(providerClass.interfaceNames())) { continue; } - if (providerInterfaceNames.contains(ResteasyReactiveDotNames.FEATURE)) { - continue; // features should not be automatically registered for the client, see javadoc for Feature - } - DotName providerDotName = providerClass.name(); int priority = getAnnotatedPriority(index, providerDotName.toString(), Priorities.USER); @@ -580,6 +574,29 @@ && isImplementorOf(index, target.asClass(), RESPONSE_EXCEPTION_MAPPER, Set.of(AP } } + /** + * Based on a list of interfaces implemented by @Provider class, determine if registration + * should be skipped or not. Server-specific types should be omitted unless implementation + * of a ClientRequestFilter exists on the same class explicitly. + * Features should always be omitted. + */ + private boolean skipAutoDiscoveredProvider(List providerInterfaceNames) { + if (providerInterfaceNames.contains(ResteasyReactiveDotNames.FEATURE)) { + return true; + } + if (providerInterfaceNames.contains(ResteasyReactiveDotNames.CONTAINER_REQUEST_FILTER) + || providerInterfaceNames.contains(ResteasyReactiveDotNames.CONTAINER_RESPONSE_FILTER) + || providerInterfaceNames.contains(ResteasyReactiveDotNames.EXCEPTION_MAPPER)) { + if (providerInterfaceNames.contains(CLIENT_REQUEST_FILTER) + || providerInterfaceNames.contains(CLIENT_RESPONSE_FILTER)) { + return false; + } else { + return true; + } + } + return false; + } + private Map populateClientExceptionMapperFromAnnotations( BuildProducer generatedClasses, BuildProducer reflectiveClasses, IndexView index) { From ecc0b51594e5631bcdbb3927fb14b6ff70f55bb8 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 24 Nov 2023 13:53:49 +0100 Subject: [PATCH 13/48] Prepare docs/sync-web-site.sh for automated releases (cherry picked from commit 37fefb380dd1a537fdc2905d8f828cf72358c5cd) --- docs/sync-web-site.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/sync-web-site.sh b/docs/sync-web-site.sh index 1041831b12477..353e45c2c58e0 100755 --- a/docs/sync-web-site.sh +++ b/docs/sync-web-site.sh @@ -36,7 +36,11 @@ if [ -z $TARGET_DIR ]; then if [[ "$QUARKUS_WEB_SITE_PUSH" != "true" ]]; then GIT_OPTIONS="--depth=1" fi - git clone -b develop --single-branch $GIT_OPTIONS git@github.com:quarkusio/quarkusio.github.io.git ${TARGET_DIR} + if [ -n "${RELEASE_GITHUB_TOKEN}" ]; then + git clone -b develop --single-branch $GIT_OPTIONS https://${RELEASE_GITHUB_TOKEN}:@github.com/quarkusio/quarkusio.github.io.git ${TARGET_DIR} + else + git clone -b develop --single-branch $GIT_OPTIONS git@github.com:quarkusio/quarkusio.github.io.git ${TARGET_DIR} + fi fi if [ $BRANCH == "main" ] && [ "$QUARKUS_RELEASE" == "true" ]; then From 396da834e1da8873de37239b9529ba15f388e8d0 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Thu, 16 Nov 2023 15:53:26 +0000 Subject: [PATCH 14/48] Use the default tenant resolver if the custom one does not resolve a tenant (cherry picked from commit 21fbe9dc129a4fac3dd998d95bd4e6ac58ed7153) --- .../security-openid-connect-multitenancy.adoc | 83 ++++++++++--------- .../runtime/DefaultTenantConfigResolver.java | 5 +- .../it/keycloak/CustomTenantResolver.java | 46 +--------- 3 files changed, 49 insertions(+), 85 deletions(-) diff --git a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc index 9622829047e1a..7c9bb2dd06daf 100644 --- a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc @@ -586,48 +586,12 @@ user `alice` exists in both tenants, for the application they are distinct users When you set multiple tenant configurations in the `application.properties` file, you only need to specify how the tenant identifier gets resolved. To configure the resolution of the tenant identifier, use one of the following options: -* <> * <> +* <> * <> -[[default-tenant-resolver]] -=== Default resolution - -The default resolution for a tenant identifier is convention based, whereby the authentication request must include the tenant identifier in the last segment of the request path. - -The following `application.properties` example shows how you can configure two tenants named `google` and `github`: - -[source,properties] ----- -# Tenant 'google' configuration -quarkus.oidc.google.provider=google -quarkus.oidc.google.client-id=${google-client-id} -quarkus.oidc.google.credentials.secret=${google-client-secret} -quarkus.oidc.google.authentication.redirect-path=/signed-in - -# Tenant 'github' configuration -quarkus.oidc.github.provider=google -quarkus.oidc.github.client-id=${github-client-id} -quarkus.oidc.github.credentials.secret=${github-client-secret} -quarkus.oidc.github.authentication.redirect-path=/signed-in ----- - -In this example, both tenants configure OIDC `web-app` applications to use an authorization code flow to authenticate users and also require session cookies to get generated after the authentication has taken place. -After either Google or GitHub authenticates the current user, the user gets returned to the `/signed-in` area for authenticated users, for example, a secured resource path on the JAX-RS endpoint. - -Finally, to complete the default tenant resolution, set the following configuration property: - -[source,properties] ----- -quarkus.http.auth.permission.login.paths=/google,/github -quarkus.http.auth.permission.login.policy=authenticated ----- - -If the endpoint is running on `http://localhost:8080`, you can also provide UI options for users to log in to either `http://localhost:8080/google` or `http://localhost:8080/github`, without having to add specific`/google` or `/github` JAX-RS resource paths. -Tenant identifiers are also recorded in the session cookie names after the authentication is completed. -Therefore, authenticated users can access the secured application area without requiring either the `google` or `github` path values to be included in the secured URL. - -Default resolution can also work for Bearer token authentication but it might be less practical in this case because a tenant identifier will always need to be set as the last path segment value. +These tenant resolution options will be tried in turn, in the order they are listed, until the tenant id gets resolved. +If the tenant id remains unresolved (`null`) in the end then the default (unnamed) tenant configuration will be selected. [[tenant-resolver]] === Resolve with `TenantResolver` @@ -672,6 +636,45 @@ public class CustomTenantResolver implements TenantResolver { In this example, the value of the last request path segment is a tenant ID, but if required, you can implement a more complex tenant identifier resolution logic. +[[default-tenant-resolver]] +=== Default resolution + +The default resolution for a tenant identifier is convention based, whereby the authentication request must include the tenant identifier in the last segment of the request path. + +The following `application.properties` example shows how you can configure two tenants named `google` and `github`: + +[source,properties] +---- +# Tenant 'google' configuration +quarkus.oidc.google.provider=google +quarkus.oidc.google.client-id=${google-client-id} +quarkus.oidc.google.credentials.secret=${google-client-secret} +quarkus.oidc.google.authentication.redirect-path=/signed-in + +# Tenant 'github' configuration +quarkus.oidc.github.provider=google +quarkus.oidc.github.client-id=${github-client-id} +quarkus.oidc.github.credentials.secret=${github-client-secret} +quarkus.oidc.github.authentication.redirect-path=/signed-in +---- + +In this example, both tenants configure OIDC `web-app` applications to use an authorization code flow to authenticate users and also require session cookies to get generated after the authentication has taken place. +After either Google or GitHub authenticates the current user, the user gets returned to the `/signed-in` area for authenticated users, for example, a secured resource path on the JAX-RS endpoint. + +Finally, to complete the default tenant resolution, set the following configuration property: + +[source,properties] +---- +quarkus.http.auth.permission.login.paths=/google,/github +quarkus.http.auth.permission.login.policy=authenticated +---- + +If the endpoint is running on `http://localhost:8080`, you can also provide UI options for users to log in to either `http://localhost:8080/google` or `http://localhost:8080/github`, without having to add specific`/google` or `/github` JAX-RS resource paths. +Tenant identifiers are also recorded in the session cookie names after the authentication is completed. +Therefore, authenticated users can access the secured application area without requiring either the `google` or `github` path values to be included in the secured URL. + +Default resolution can also work for Bearer token authentication but it might be less practical in this case because a tenant identifier will always need to be set as the last path segment value. + [[annotations-tenant-resolver]] === Resolve with annotations @@ -775,6 +778,8 @@ public class CustomTenantConfigResolver implements TenantConfigResolver { The `OidcTenantConfig` returned from this method is the same used to parse the `oidc` namespace configuration from the `application.properties`. You can populate it using any of the settings supported by the `quarkus-oidc` extension. +If the dynamic tenant resolver returns `null` then a <> will be attempted next. + === Tenant resolution for OIDC `web-app` applications The simplest option for resolving OIDC `web-app` application configuration is to follow the steps described in the <> section. diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java index 1448c112aa928..ef07097a85bbc 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java @@ -152,9 +152,12 @@ private TenantConfigContext getStaticTenantContext(RoutingContext context) { if (tenantId == null && context.get(CURRENT_STATIC_TENANT_ID_NULL) == null) { if (tenantResolver.isResolvable()) { tenantId = tenantResolver.get().resolve(context); - } else if (tenantConfigBean.getStaticTenantsConfig().size() > 0) { + } + + if (tenantId == null && tenantConfigBean.getStaticTenantsConfig().size() > 0) { tenantId = defaultStaticTenantResolver.resolve(context); } + if (tenantId == null) { tenantId = context.get(OidcUtils.TENANT_ID_ATTRIBUTE); } diff --git a/integration-tests/oidc-wiremock/src/main/java/io/quarkus/it/keycloak/CustomTenantResolver.java b/integration-tests/oidc-wiremock/src/main/java/io/quarkus/it/keycloak/CustomTenantResolver.java index 34ffd429732e1..2fe6cca9790dc 100644 --- a/integration-tests/oidc-wiremock/src/main/java/io/quarkus/it/keycloak/CustomTenantResolver.java +++ b/integration-tests/oidc-wiremock/src/main/java/io/quarkus/it/keycloak/CustomTenantResolver.java @@ -17,54 +17,10 @@ public String resolve(RoutingContext context) { if (path.endsWith("code-flow") || path.endsWith("code-flow/logout")) { return "code-flow"; } - if (path.endsWith("code-flow-encrypted-id-token-jwk")) { - return "code-flow-encrypted-id-token-jwk"; - } - if (path.endsWith("code-flow-encrypted-id-token-pem")) { - return "code-flow-encrypted-id-token-pem"; - } if (path.endsWith("code-flow-form-post") || path.endsWith("code-flow-form-post/front-channel-logout")) { return "code-flow-form-post"; } - if (path.endsWith("code-flow-user-info-only")) { - return "code-flow-user-info-only"; - } - if (path.endsWith("code-flow-user-info-github")) { - return "code-flow-user-info-github"; - } - if (path.endsWith("bearer-user-info-github-service")) { - return "bearer-user-info-github-service"; - } - if (path.endsWith("code-flow-user-info-github-cached-in-idtoken")) { - return "code-flow-user-info-github-cached-in-idtoken"; - } - if (path.endsWith("code-flow-token-introspection")) { - return "code-flow-token-introspection"; - } - if (path.endsWith("bearer")) { - return "bearer"; - } - if (path.endsWith("bearer-id")) { - return "bearer-id"; - } - if (path.endsWith("bearer-required-algorithm")) { - return "bearer-required-algorithm"; - } - if (path.endsWith("bearer-azure")) { - return "bearer-azure"; - } - if (path.endsWith("bearer-no-introspection")) { - return "bearer-no-introspection"; - } - if (path.endsWith("bearer-role-claim-path")) { - return "bearer-role-claim-path"; - } - if (path.endsWith("bearer-key-without-kid-thumbprint")) { - return "bearer-key-without-kid-thumbprint"; - } - if (path.endsWith("bearer-wrong-role-path")) { - return "bearer-wrong-role-path"; - } + return null; } } From 7ec0c0a302943e4de50e1ea41ee2072b2b38af86 Mon Sep 17 00:00:00 2001 From: Andreas Eberle Date: Mon, 6 Nov 2023 15:38:30 +0100 Subject: [PATCH 15/48] Update Kotlin to version 1.9.21, Mockito to 5.7.0 (cherry picked from commit b206484ff53f565671067172671439783bd2ad5e) --- bom/application/pom.xml | 2 +- build-parent/pom.xml | 4 ++-- .../src/test/java/io/quarkus/gradle/QuarkusPluginTest.java | 2 +- independent-projects/arc/pom.xml | 6 +++--- .../conditional-dependencies-kotlin/build.gradle.kts | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index ce0740f2a0634..2ff092d816b04 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -157,7 +157,7 @@ 2.14.0 2.2.0 1.0.0 - 1.9.10 + 1.9.21 1.7.3 0.27.0 1.6.0 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index cfe5555cab915..ebbd89b7700dd 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -20,8 +20,8 @@ 3.11.0 - 1.9.10 - 1.9.0 + 1.9.21 + 1.9.10 2.13.8 4.8.1 diff --git a/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/QuarkusPluginTest.java b/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/QuarkusPluginTest.java index 580777c029f6d..862ad0a62abb6 100644 --- a/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/QuarkusPluginTest.java +++ b/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/QuarkusPluginTest.java @@ -105,7 +105,7 @@ public void shouldReturnMultipleOutputSourceDirectories() { @Test public void shouldNotFailOnProjectDependenciesWithoutMain(@TempDir Path testProjectDir) throws IOException { - var kotlinVersion = System.getProperty("kotlin_version", "1.9.10"); + var kotlinVersion = System.getProperty("kotlin_version", "1.9.21"); var settingFile = testProjectDir.resolve("settings.gradle.kts"); var mppProjectDir = testProjectDir.resolve("mpp"); var quarkusProjectDir = testProjectDir.resolve("quarkus"); diff --git a/independent-projects/arc/pom.xml b/independent-projects/arc/pom.xml index 5219daa4e1bce..0bc692b18aed0 100644 --- a/independent-projects/arc/pom.xml +++ b/independent-projects/arc/pom.xml @@ -55,9 +55,9 @@ 3.24.2 5.10.0 - 1.9.10 - 1.7.1 - 5.4.0 + 1.9.21 + 1.7.3 + 5.7.0 1.7.0.Final 2.0.1 diff --git a/integration-tests/gradle/src/main/resources/conditional-dependencies-kotlin/build.gradle.kts b/integration-tests/gradle/src/main/resources/conditional-dependencies-kotlin/build.gradle.kts index e5d23bacc50de..5e3808937ce3e 100644 --- a/integration-tests/gradle/src/main/resources/conditional-dependencies-kotlin/build.gradle.kts +++ b/integration-tests/gradle/src/main/resources/conditional-dependencies-kotlin/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - kotlin("jvm") version "1.9.10" - kotlin("plugin.allopen") version "1.9.10" + kotlin("jvm") version "1.9.21" + kotlin("plugin.allopen") version "1.9.21" id("io.quarkus") } From 58fc317ef6fcec3e2de553321b4554da3c3669af Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sat, 25 Nov 2023 11:58:13 +0100 Subject: [PATCH 16/48] Use batch mode for update-version.sh (cherry picked from commit 0685076e9a835c4eb29b52daa3ef2e1db773e923) --- update-version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update-version.sh b/update-version.sh index 3eb07d975cbd4..1ebbaf2382826 100755 --- a/update-version.sh +++ b/update-version.sh @@ -9,7 +9,7 @@ if [ $# -eq 0 ]; then fi VERSION=$1 -./mvnw -Dscan=false -Dgradle.cache.local.enabled=false versions:set -Dtcks -DnewVersion="${VERSION}" -DgenerateBackupPoms=false -DprocessAllModules -Prelocations +./mvnw -e -B -Dscan=false -Dgradle.cache.local.enabled=false versions:set -Dtcks -DnewVersion="${VERSION}" -DgenerateBackupPoms=false -DprocessAllModules -Prelocations if [ -f devtools/gradle/gradle.properties ]; then sed -i -r "s/^version( ?= ?).*$/version\1${VERSION}/" devtools/gradle/gradle.properties From ae706c3d2e4b66dcfdda299884332ae6c8996e7c Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sat, 25 Nov 2023 11:49:18 +0100 Subject: [PATCH 17/48] Avoid asking for GPG passphrase on CI (cherry picked from commit 86673f962548e140636261add0490c03553334ba) --- independent-projects/parent/pom.xml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/independent-projects/parent/pom.xml b/independent-projects/parent/pom.xml index be3075bf1548b..33c243cd1c009 100644 --- a/independent-projects/parent/pom.xml +++ b/independent-projects/parent/pom.xml @@ -831,5 +831,30 @@ + + ci + + + env.CI + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + + --pinentry-mode + loopback + + + + + + + From 45f1a67172c85e34303070d6dd15d7fd2bdc9916 Mon Sep 17 00:00:00 2001 From: Sebastian Schuster Date: Thu, 23 Nov 2023 08:48:36 +0100 Subject: [PATCH 18/48] 37279 bump mssql jdbc driver to 12.4.2 (cherry picked from commit 306c8733b4e6ea0c5735d1d2cdc83d7e4c4eacd4) --- bom/application/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 2ff092d816b04..c4bd155f1bbbb 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -128,7 +128,7 @@ 42.6.0 3.2.0 8.0.33 - 12.4.0.jre11 + 12.4.2.jre11 1.6.7 23.3.0.23.09 10.14.2.0 From 80321f67e96ab2bb5ccef1b3327fee1379cf9768 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 28 Nov 2023 09:58:48 +0200 Subject: [PATCH 19/48] Runtime (re)initialize Netty's PlatformDependent classes Closes https://github.com/quarkusio/quarkus/issues/17839 (cherry picked from commit 76c02780328546fb5e60088e7a7447f35a0ef48a) --- .../main/java/io/quarkus/netty/deployment/NettyProcessor.java | 3 +++ 1 file changed, 3 insertions(+) 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 766d2f8c00800..5de637d124c8c 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 @@ -162,6 +162,9 @@ NativeImageConfigBuildItem build( log.debug("Not registering Netty native kqueue classes as they were not found"); } + builder.addRuntimeReinitializedClass("io.netty.util.internal.PlatformDependent"); + builder.addRuntimeReinitializedClass("io.netty.util.internal.PlatformDependent0"); + return builder //TODO: make configurable .build(); } From 8bf1f64e5d905350a39606e120c02493460cb4be Mon Sep 17 00:00:00 2001 From: Andy Damevin Date: Tue, 28 Nov 2023 10:56:23 +0100 Subject: [PATCH 20/48] Unlist quarkus-resteasy-qute and quarkus-resteasy-reactive-qute (cherry picked from commit 5e8e7e6db2b9707b33a401a450acc0fa75712b3f) --- .../runtime/src/main/resources/META-INF/quarkus-extension.yaml | 1 + .../runtime/src/main/resources/META-INF/quarkus-extension.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/extensions/resteasy-classic/resteasy-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/resteasy-classic/resteasy-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml index d0391e67d3f8b..0da36a3fd354e 100644 --- a/extensions/resteasy-classic/resteasy-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/resteasy-classic/resteasy-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -2,6 +2,7 @@ artifact: ${project.groupId}:${project.artifactId}:${project.version} name: "RESTEasy Classic Qute" metadata: + unlisted: true keywords: - "templating" - "templates" diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/resteasy-reactive/quarkus-resteasy-reactive-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml index 9f0006b6bf2fa..eec8b27d0eb38 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -1,6 +1,7 @@ name: "RESTEasy Reactive Qute" artifact: ${project.groupId}:${project.artifactId}:${project.version} metadata: + unlisted: true keywords: - "templating" - "templates" From c5727582c19d1c10e96704b0af4768cba79726eb Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Tue, 28 Nov 2023 10:32:09 -0600 Subject: [PATCH 21/48] Fix incorrect log dependency (cherry picked from commit 8e22ed9f2e9914885b1a620219422404840e037f) --- test-framework/junit5-component/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-framework/junit5-component/pom.xml b/test-framework/junit5-component/pom.xml index fafa7e91c4d8b..8d6bb92298438 100644 --- a/test-framework/junit5-component/pom.xml +++ b/test-framework/junit5-component/pom.xml @@ -61,7 +61,7 @@ org.jboss.logmanager - jboss-logmanager-embedded + jboss-logmanager test From 8910702a00f229e75c8d540be9887071fae7897a Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 28 Nov 2023 13:38:37 +0100 Subject: [PATCH 22/48] Update Boucycastle to 1.77 and Boucycastle FIPS to 1.0.2.4 (cherry picked from commit bf0829f31ed7e00afaf371631770c2895d714f0b) --- bom/application/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index c4bd155f1bbbb..07102cf90be9a 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -15,8 +15,8 @@ 2.0.1 - 1.76 - 1.0.2.3 + 1.77 + 1.0.2.4 1.0.17 5.0.0 3.0.2 From d6935c948a4c57be6d3e57fa84149e434e489e96 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 28 Nov 2023 17:01:05 +0000 Subject: [PATCH 23/48] Remove SecureRandom providerDefaultRandom from BouncyCastleFipsProvider substitution (cherry picked from commit e9da9c8b630c5b523068bbe9a61f50dccd562eca) --- .../security/runtime/graal/BouncyCastleSubstitutions.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/graal/BouncyCastleSubstitutions.java b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/graal/BouncyCastleSubstitutions.java index b647e93b36ccc..7fad7acc4698d 100644 --- a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/graal/BouncyCastleSubstitutions.java +++ b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/graal/BouncyCastleSubstitutions.java @@ -95,10 +95,6 @@ final class Target_org_bouncycastle_jcajce_provider_BouncyCastleFipsProvider { @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) // private SecureRandom entropySource; - - @Alias - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) // - private SecureRandom providerDefaultRandom; } @com.oracle.svm.core.annotate.TargetClass(className = "org.bouncycastle.math.ec.ECPoint", onlyWith = BouncyCastleCryptoFips.class) From 6cbe4f2589a13b19fa5e2b828483d2d45e66fd4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Tue, 28 Nov 2023 22:32:22 +0100 Subject: [PATCH 24/48] Docs: list runtime form auth properties (cherry picked from commit de807d8666ffa77f47febbb07842c9fab0d6835a) --- docs/src/main/asciidoc/security-authentication-mechanisms.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc index 108657ce55dc0..fe736a13f3146 100644 --- a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc +++ b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc @@ -173,6 +173,7 @@ public Response logout() { The following properties can be used to configure form-based authentication: include::{generated-dir}/config/quarkus-vertx-http-config-group-form-auth-config.adoc[opts=optional, leveloffset=+1] +include::{generated-dir}/config/quarkus-vertx-http-config-group-auth-runtime-config.adoc[opts=optional, leveloffset=+1] [[mutual-tls]] === Mutual TLS authentication From 7d5ec9e0c1ce501dc3d7115164c88afa1c30180b Mon Sep 17 00:00:00 2001 From: mert18 Date: Tue, 28 Nov 2023 06:09:50 +0300 Subject: [PATCH 25/48] dev-v1 deprecated url changed to dev-ui in documentation (cherry picked from commit 1d85a445c4408569105ed55f69e17ab3889f1751) --- .../src/main/resources/META-INF/resources/index.entry.qute.html | 2 +- docs/src/main/asciidoc/dev-mode-differences.adoc | 2 +- docs/src/main/asciidoc/grpc-service-implementation.adoc | 2 +- docs/src/main/asciidoc/security-keycloak-authorization.adoc | 2 +- .../security-oidc-bearer-token-authentication-tutorial.adoc | 2 +- docs/src/main/asciidoc/security-openid-connect-client.adoc | 2 +- .../src/main/asciidoc/security-openid-connect-dev-services.adoc | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts/grpc-codestart/base/src/main/resources/META-INF/resources/index.entry.qute.html b/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts/grpc-codestart/base/src/main/resources/META-INF/resources/index.entry.qute.html index 4f3acc377dc7f..07f8b05dacbc2 100644 --- a/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts/grpc-codestart/base/src/main/resources/META-INF/resources/index.entry.qute.html +++ b/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts/grpc-codestart/base/src/main/resources/META-INF/resources/index.entry.qute.html @@ -1,3 +1,3 @@ {#include index-entry} -{#body}
› It can be tested in the Dev UI (available in dev mode only). +{#body}
› It can be tested in the Dev UI (available in dev mode only). {/include} \ No newline at end of file diff --git a/docs/src/main/asciidoc/dev-mode-differences.adoc b/docs/src/main/asciidoc/dev-mode-differences.adoc index b49ee27d3ca6b..30db2b5d0323c 100644 --- a/docs/src/main/asciidoc/dev-mode-differences.adoc +++ b/docs/src/main/asciidoc/dev-mode-differences.adoc @@ -50,7 +50,7 @@ Examples of such operations are: ==== A new Dev UI has been implemented in Quarkus 3.x. Not all the features are available yet. -You can still access the previous version of the Dev UI using: http://localhost:8080/q/dev-v1/. +You can still access the previous version of the Dev UI using: http://localhost:8080/q/dev-ui/. ==== === Error pages diff --git a/docs/src/main/asciidoc/grpc-service-implementation.adoc b/docs/src/main/asciidoc/grpc-service-implementation.adoc index 2d870aed2c917..8878d03c29b28 100644 --- a/docs/src/main/asciidoc/grpc-service-implementation.adoc +++ b/docs/src/main/asciidoc/grpc-service-implementation.adoc @@ -359,7 +359,7 @@ public class HelloServiceTest implements Greeter { == Trying out your services manually In the dev mode, you can try out your gRPC services in the Quarkus Dev UI. -Just go to http://localhost:8080/q/dev-v1 and click on _Services_ under the gRPC tile. +Just go to http://localhost:8080/q/dev-ui and click on _Services_ under the gRPC tile. Please note that your application needs to expose the "normal" HTTP port for the Dev UI to be accessible. If your application does not expose any HTTP endpoints, you can create a dedicated profile with a dependency on `quarkus-vertx-http`: [source,xml] diff --git a/docs/src/main/asciidoc/security-keycloak-authorization.adoc b/docs/src/main/asciidoc/security-keycloak-authorization.adoc index 6f58b3c0681c1..8d6c6a063ac92 100644 --- a/docs/src/main/asciidoc/security-keycloak-authorization.adoc +++ b/docs/src/main/asciidoc/security-keycloak-authorization.adoc @@ -235,7 +235,7 @@ include::{includes}/devtools/dev.adoc[] xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] will launch a Keycloak container and import a `quarkus-realm.json`. -Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev-v1[/q/dev-v1] and click on a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. +Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev-ui[/q/dev-ui] and click on a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. You will be asked to log in into a `Single Page Application` provided by `OpenID Connect Dev UI`: diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc index 79b64542b456d..1be0d80000013 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc @@ -263,7 +263,7 @@ For more information, see the link:{url-quarkusio-guides}security-keycloak-admin include::{includes}/devtools/dev.adoc[] ==== * link:{quarkusio-guides}/security-openid-connect-dev-services[Dev Services for Keycloak] will start a Keycloak container and import a `quarkus-realm.json`. -. Open a link:{url-quarkusio-guides}dev-ui[Dev UI], which you can find at http://localhost:8080/q/dev-v1[/q/dev-v1], then click a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. +. Open a link:{url-quarkusio-guides}dev-ui[Dev UI], which you can find at http://localhost:8080/q/dev-ui[/q/dev-ui], then click a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. . When prompted to log in to a `Single Page Application` provided by `OpenID Connect Dev UI`, do the following steps: * Log in as `alice` (password: `alice`), who has a `user` role. diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index 62a63de2f71a4..bcce8989a88da 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -363,7 +363,7 @@ include::{includes}/devtools/dev.adoc[] xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] will launch a Keycloak container and import a `quarkus-realm.json`. -Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev-v1[/q/dev-v1] and click on a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. +Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev-ui[/q/dev-ui] and click on a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. You will be asked to log in into a `Single Page Application` provided by `OpenID Connect Dev UI`: diff --git a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc index 3e4f7fc20672e..ee38209a69427 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -419,7 +419,7 @@ Please follow the xref:dev-ui.adoc[Dev UI] tutorial as well as check the `extens == Non Application Root Path Considerations -This document refers to the `http://localhost:8080/q/dev-v1` Dev UI URL in several places where `q` is a default non application root path. If you customize `quarkus.http.root-path` and/or `quarkus.http.non-application-root-path` properties then replace `q` accordingly, please see https://quarkus.io/blog/path-resolution-in-quarkus/[Path Resolution in Quarkus] for more information. +This document refers to the `http://localhost:8080/q/dev-ui` Dev UI URL in several places where `q` is a default non application root path. If you customize `quarkus.http.root-path` and/or `quarkus.http.non-application-root-path` properties then replace `q` accordingly, please see https://quarkus.io/blog/path-resolution-in-quarkus/[Path Resolution in Quarkus] for more information. == References From 36421ae188f6fc2a6b85f63e6bf6096527a97653 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 28 Nov 2023 22:19:25 +0200 Subject: [PATCH 26/48] Improve Docker Desktop detection During some experiments I noticed that when setting DOCKER_HOST, `docker info` no longer reports the context as `desktop-linux`. Looking for "Docker Desktop" as the docker server operating system seems more reliable. I am keeping the `desktop-linux` filter as a fallback nevertheless. Improves https://github.com/quarkusio/quarkus/pull/37242 (cherry picked from commit 5336193a00f08f7a787a4ec6fc46ae66b4d2cf5b) --- .../java/io/quarkus/runtime/util/ContainerRuntimeUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/runtime/src/main/java/io/quarkus/runtime/util/ContainerRuntimeUtil.java b/core/runtime/src/main/java/io/quarkus/runtime/util/ContainerRuntimeUtil.java index 607ead4f24980..42cc489ec9988 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/util/ContainerRuntimeUtil.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/util/ContainerRuntimeUtil.java @@ -194,7 +194,8 @@ private static boolean getRootlessStateFor(ContainerRuntime containerRuntime) { // We also treat Docker Desktop as "rootless" since the way it binds mounts does not // transparently map the host user ID and GID // see https://docs.docker.com/desktop/faqs/linuxfaqs/#how-do-i-enable-file-sharing - stringPredicate = line -> line.trim().equals("rootless") || line.contains("desktop-linux"); + stringPredicate = line -> line.trim().equals("rootless") || line.contains("Docker Desktop") + || line.contains("desktop-linux"); } else { stringPredicate = line -> line.trim().equals("rootless: true"); } From e164f6f8ba84e9049923c4f80a695f8189c6a78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Tue, 28 Nov 2023 23:20:12 +0100 Subject: [PATCH 27/48] Docs: fix OIDC credentials reference to secret key (cherry picked from commit d7d6fef9b569579c8d5ff152a5afdb3dbbc793f6) --- .../java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java b/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java index 45b1923d5d805..f3810d610a001 100644 --- a/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java +++ b/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java @@ -180,7 +180,7 @@ public static enum Method { } /** - * The client secret value - it will be ignored if 'secret.key' is set + * The client secret value - it will be ignored if 'credentials.secret' is set */ @ConfigItem public Optional value = Optional.empty(); From 3b6724ddcbf2e2d1c31a2e9d718365db6d9cf4d8 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 28 Nov 2023 19:05:16 +0000 Subject: [PATCH 28/48] Do not fail the request in OidcClient filters if OidcClient is disabled (cherry picked from commit ec9c312fb8d04576de1890d14d01443d34df3d30) --- .../filter/runtime/AbstractOidcClientRequestFilter.java | 4 ++-- .../runtime/AbstractOidcClientRequestReactiveFilter.java | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java b/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java index 5b2a0f25f67ac..458fa15740778 100644 --- a/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java +++ b/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java @@ -25,8 +25,8 @@ public void filter(ClientRequestContext requestContext) throws IOException { final String accessToken = getAccessToken(); requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, BEARER_SCHEME_WITH_SPACE + accessToken); } catch (DisabledOidcClientException ex) { - LOG.debug("Client is disabled, aborting the request"); - throw ex; + LOG.debug("Client is disabled, acquiring and propagating the token is not necessary"); + return; } catch (Exception ex) { LOG.debugf("Access token is not available, cause: %s, aborting the request", ex.getMessage()); throw (ex instanceof RuntimeException) ? (RuntimeException) ex : new RuntimeException(ex); diff --git a/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java b/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java index 9c266fb892baf..5bff7d719403d 100644 --- a/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java +++ b/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java @@ -39,11 +39,12 @@ public void accept(Tokens tokens) { @Override public void accept(Throwable t) { if (t instanceof DisabledOidcClientException) { - LOG.debug("Client is disabled, aborting the request"); + LOG.debug("Client is disabled, acquiring and propagating the token is not necessary"); + requestContext.resume(); } else { LOG.debugf("Access token is not available, cause: %s, aborting the request", t.getMessage()); + requestContext.resume((t instanceof RuntimeException) ? t : new RuntimeException(t)); } - requestContext.resume((t instanceof RuntimeException) ? t : new RuntimeException(t)); } }); } From 08f5751dbe0e9075fb8f9f7600f53541ce4d8bbb Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Tue, 28 Nov 2023 09:43:26 +0100 Subject: [PATCH 29/48] Upgrade to Jandex 3.1.6 (cherry picked from commit 6986f8076b2ecf1a95188f8c05e938f76c2c8fef) --- bom/application/pom.xml | 2 +- build-parent/pom.xml | 2 +- independent-projects/arc/pom.xml | 2 +- independent-projects/bootstrap/pom.xml | 2 +- independent-projects/junit5-virtual-threads/pom.xml | 2 +- independent-projects/qute/pom.xml | 2 +- independent-projects/resteasy-reactive/pom.xml | 2 +- independent-projects/tools/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 07102cf90be9a..3c37f3131f632 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -20,7 +20,7 @@ 1.0.17 5.0.0 3.0.2 - 3.1.5 + 3.1.6 1.3.2 1 1.1.5 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index ebbd89b7700dd..ac589a8b8e299 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -33,7 +33,7 @@ ${version.surefire.plugin} - 3.1.5 + 3.1.6 1.0.0 2.5.10 diff --git a/independent-projects/arc/pom.xml b/independent-projects/arc/pom.xml index 0bc692b18aed0..9fcf219e160dd 100644 --- a/independent-projects/arc/pom.xml +++ b/independent-projects/arc/pom.xml @@ -48,7 +48,7 @@ 2.0.1 1.7.0 - 3.1.5 + 3.1.6 3.5.3.Final 2.5.1 1.6.Final diff --git a/independent-projects/bootstrap/pom.xml b/independent-projects/bootstrap/pom.xml index 0db20683a71fe..766e2e9e5d7ad 100644 --- a/independent-projects/bootstrap/pom.xml +++ b/independent-projects/bootstrap/pom.xml @@ -40,7 +40,7 @@ 3.11.0 3.2.1 3.1.2 - 3.1.5 + 3.1.6 3.24.2 diff --git a/independent-projects/junit5-virtual-threads/pom.xml b/independent-projects/junit5-virtual-threads/pom.xml index 4b35067e4ac1e..d30d68dcb74ef 100644 --- a/independent-projects/junit5-virtual-threads/pom.xml +++ b/independent-projects/junit5-virtual-threads/pom.xml @@ -44,7 +44,7 @@ 3.11.0 3.2.1 3.1.2 - 3.1.5 + 3.1.6 2.23.0 1.9.0 diff --git a/independent-projects/qute/pom.xml b/independent-projects/qute/pom.xml index af92986637614..ca6c9c5db9f07 100644 --- a/independent-projects/qute/pom.xml +++ b/independent-projects/qute/pom.xml @@ -43,7 +43,7 @@ 11 5.10.0 3.24.2 - 3.1.5 + 3.1.6 1.7.0 3.5.3.Final 3.11.0 diff --git a/independent-projects/resteasy-reactive/pom.xml b/independent-projects/resteasy-reactive/pom.xml index 0b5bf88744fa0..4b60545273467 100644 --- a/independent-projects/resteasy-reactive/pom.xml +++ b/independent-projects/resteasy-reactive/pom.xml @@ -48,7 +48,7 @@ 11 4.0.1 - 3.1.5 + 3.1.6 1.12.12 5.10.0 3.9.5 diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml index 48814923bfe7a..ac055703db66e 100644 --- a/independent-projects/tools/pom.xml +++ b/independent-projects/tools/pom.xml @@ -62,7 +62,7 @@ 3.1.2 ${project.version} 25 - 3.1.5 + 3.1.6 2.0.2 4.2.0
From 4690f4eea2dc3be4d56e77f697e43d910d1b7968 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Wed, 29 Nov 2023 14:42:08 +0200 Subject: [PATCH 30/48] Stop disabling unsafe in netty at native-executable runtime Resolves issues unveiled with https://github.com/quarkusio/quarkus/pull/37347 (cherry picked from commit de181ea16dad09e4f74d298895db7d1dfda63dbf) --- .../infinispan/client/deployment/InfinispanClientProcessor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java b/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java index 58201a89f0b4f..7e11774606f90 100644 --- a/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java +++ b/extensions/infinispan-client/deployment/src/main/java/io/quarkus/infinispan/client/deployment/InfinispanClientProcessor.java @@ -205,7 +205,6 @@ InfinispanPropertiesBuildItem setup(ApplicationArchivesBuildItem applicationArch additionalBeans.produce(AdditionalBeanBuildItem.builder().addBeanClass(InfinispanClientName.class).build()); additionalBeans.produce(AdditionalBeanBuildItem.builder().addBeanClass(Remote.class).build()); - systemProperties.produce(new SystemPropertyBuildItem("io.netty.noUnsafe", "true")); hotDeployment .produce(new HotDeploymentWatchedFileBuildItem(META_INF + File.separator + DEFAULT_HOTROD_CLIENT_PROPERTIES)); From a13fa0161fcb7c74cbbf6e9ac046aaceeaca0eed Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 29 Nov 2023 11:38:26 +0100 Subject: [PATCH 31/48] Update MAX_LTS_SUPPORTED_BY_KOTLIN to 21 Kotlin 1.9.20 supports Java 21. (cherry picked from commit 01505b4840be56ac7f43d1ad17f2cdf5f3e73bf5) --- .../src/main/java/io/quarkus/devtools/project/JavaVersion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/JavaVersion.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/JavaVersion.java index ffa49e92acafb..109133f72a509 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/JavaVersion.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/JavaVersion.java @@ -64,7 +64,7 @@ public String toString() { // ordering is important here, so let's keep them ordered public static final SortedSet JAVA_VERSIONS_LTS = new TreeSet<>(List.of(11, 17, 21)); public static final int DEFAULT_JAVA_VERSION = 11; - public static final int MAX_LTS_SUPPORTED_BY_KOTLIN = 17; + public static final int MAX_LTS_SUPPORTED_BY_KOTLIN = 21; public static final String DETECT_JAVA_RUNTIME_VERSION = "<>"; public static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("(\\d+)(?:\\..*)?"); From d948b487dd27e189938a7a720a0435ba9998d5ca Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 29 Nov 2023 16:07:24 +0100 Subject: [PATCH 32/48] Disable new Http2RSTFloodProtectionConfigTest on Windows We already disabled Http2RSTFloodProtectionTest on Windows and this new tests suffers from the same issues. (cherry picked from commit 041a3cb57354b244fa4a42042a161f78007ef5f3) --- .../vertx/http/http2/Http2RSTFloodProtectionConfigTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/http2/Http2RSTFloodProtectionConfigTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/http2/Http2RSTFloodProtectionConfigTest.java index 5f4091a2b7097..c3abccb5d5512 100644 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/http2/Http2RSTFloodProtectionConfigTest.java +++ b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/http2/Http2RSTFloodProtectionConfigTest.java @@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.test.QuarkusUnitTest; @@ -29,6 +31,7 @@ /** * Configuration of the RST flood protection (CVE-2023-44487) */ +@DisabledOnOs(OS.WINDOWS) public class Http2RSTFloodProtectionConfigTest { @TestHTTPResource(value = "/ping", ssl = true) From 41544630e9ebd29221c18338a691e196ef2e2343 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 29 Nov 2023 18:26:04 +0100 Subject: [PATCH 33/48] Revert "Build cache - Upload quarkus-ide-launcher-999-SNAPSHOT.jar" This reverts commit b259b9a468bfab3fdcfe0cfd6d3584a98396b4cc. (cherry picked from commit c4e6eb753a943a1cff6021f968f19065277330e7) --- .github/workflows/ci-actions-incremental.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ci-actions-incremental.yml b/.github/workflows/ci-actions-incremental.yml index 92b758f0d09ef..c4e8f1af7e5a2 100644 --- a/.github/workflows/ci-actions-incremental.yml +++ b/.github/workflows/ci-actions-incremental.yml @@ -398,12 +398,6 @@ jobs: uses: gradle/github-actions/maven-build-scan/save@v1-beta with: job-name: "JVM Tests - JDK ${{matrix.java.name}}" - - name: Upload quarkus-ide-launcher jar - uses: actions/upload-artifact@v3 - with: - name: "quarkus-ide-launcher-999-SNAPSHOT.jar - JDK ${{matrix.java.name}}" - path: | - core/launcher/target/quarkus-ide-launcher-999-SNAPSHOT.jar maven-tests: name: Maven Tests - JDK ${{matrix.java.name}} From 27370c66ff488d5b53ea4b97e81c8d37841fe617 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 29 Nov 2023 19:03:29 +0100 Subject: [PATCH 34/48] Only download the builder image once for a given CI job We don't cache the images from job to job so we can download it once at the beginning using a `missing` policy and then avoid downloading it. (cherry picked from commit 92b51f35ca75497a891d5889e386c53831c0a98f) --- integration-tests/pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 8e027683779b5..1ad49073f3b20 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -470,6 +470,17 @@ + + native-ci + + + env.CI + + + + missing + + From a6baf92fa1f212a4010500af169510bb399526e7 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 29 Nov 2023 19:04:26 +0100 Subject: [PATCH 35/48] Retry downloading the builder image once after 5 seconds Might help with the current Quay.io reliability that we have, be it due to GitHub Actions or Quay.io network issues. (cherry picked from commit 4be6bb26494c5f8bfa453ab7d82c91ff6789e4d8) --- .../NativeImageBuildContainerRunner.java | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java index d826c15c68113..61a93dd0e55c2 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java @@ -49,8 +49,8 @@ public void setup(boolean processInheritIODisabled) { // will appear to block and no output will be shown String effectiveBuilderImage = nativeConfig.builderImage().getEffectiveImage(); var builderImagePull = nativeConfig.builderImage().pull(); - log.infof("Checking status of builder image '%s'", effectiveBuilderImage); if (builderImagePull != NativeConfig.ImagePullStrategy.ALWAYS) { + log.infof("Checking status of builder image '%s'", effectiveBuilderImage); Process imageInspectProcess = null; try { final ProcessBuilder pb = new ProcessBuilder( @@ -82,20 +82,37 @@ public void setup(boolean processInheritIODisabled) { } } } - Process pullProcess = null; + try { - final ProcessBuilder pb = new ProcessBuilder( - Arrays.asList(containerRuntime.getExecutableName(), "pull", effectiveBuilderImage)); - pullProcess = ProcessUtil.launchProcess(pb, processInheritIODisabled); - if (pullProcess.waitFor() != 0) { - throw new RuntimeException("Failed to pull builder image '" + effectiveBuilderImage + "'"); - } - } catch (IOException | InterruptedException e) { - throw new RuntimeException("Failed to pull builder image '" + effectiveBuilderImage + "'", e); - } finally { - if (pullProcess != null) { - pullProcess.destroy(); + log.infof("Pulling builder image '%s'", effectiveBuilderImage); + pull(effectiveBuilderImage, processInheritIODisabled); + } catch (Exception e) { + log.infof("Retrying in 5 seconds"); + try { + Thread.sleep(5_000L); + } catch (InterruptedException e1) { + throw new RuntimeException(e1); } + log.infof("Pulling builder image '%s' (take 2)", effectiveBuilderImage); + pull(effectiveBuilderImage, processInheritIODisabled); + } + } + } + + private void pull(String effectiveBuilderImage, boolean processInheritIODisabled) { + Process pullProcess = null; + try { + final ProcessBuilder pb = new ProcessBuilder( + Arrays.asList(containerRuntime.getExecutableName(), "pull", effectiveBuilderImage)); + pullProcess = ProcessUtil.launchProcess(pb, processInheritIODisabled); + if (pullProcess.waitFor() != 0) { + throw new RuntimeException("Failed to pull builder image '" + effectiveBuilderImage + "'"); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException("Failed to pull builder image '" + effectiveBuilderImage + "'"); + } finally { + if (pullProcess != null) { + pullProcess.destroy(); } } } From 39fcc661f592edb47658008e61f2f5d94fd7ece2 Mon Sep 17 00:00:00 2001 From: "alexey.kovynev" Date: Wed, 29 Nov 2023 18:24:58 +0200 Subject: [PATCH 36/48] Update Gradle to 8.5 (cherry picked from commit fa96ddba9d5d46423b6c7cc1d7b578b599b116b6) --- 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 ac589a8b8e299..1866362b5538f 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -64,7 +64,7 @@ 3.9.5 3.2.0 - 8.4 + 8.5 ${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 82b3bd91387cb..80f3d5675f491 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=f2b9ed0faf8472cbe469255ae6c86eddb77076c75191741b4a462f33128dd419 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip +distributionSha256Sum=c16d517b50dd28b3f5838f0e844b7520b8f1eb610f2f29de7e4e04a1b7c9c79b +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-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 766e2e9e5d7ad..d966792760d95 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.4 + 8.5 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 3b970eaec4e5a..281043c650de9 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 @@ -390,7 +390,7 @@ "recommended-java-version": "17", "proposed-maven-version": "3.9.5", "maven-wrapper-version": "3.2.0", - "gradle-wrapper-version": "8.4" + "gradle-wrapper-version": "8.5" } }, "codestarts-artifacts": [ diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml index ac055703db66e..e991dd082c987 100644 --- a/independent-projects/tools/pom.xml +++ b/independent-projects/tools/pom.xml @@ -42,7 +42,7 @@ 3.9.5 3.2.0 - 8.4 + 8.5 3.11.0 diff --git a/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties b/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties index 82b3bd91387cb..80f3d5675f491 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=f2b9ed0faf8472cbe469255ae6c86eddb77076c75191741b4a462f33128dd419 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip +distributionSha256Sum=c16d517b50dd28b3f5838f0e844b7520b8f1eb610f2f29de7e4e04a1b7c9c79b +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 2e0ca065a243651851792c7b8da09b3a1f6196fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gro=C3=9Fewinkelmann?= Date: Thu, 30 Nov 2023 11:49:12 +0100 Subject: [PATCH 37/48] Fix typo configMapRefKey -> configMapKeyRef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Großewinkelmann (cherry picked from commit 4787a8a012d87fccea25ca37387a9eb5282dea10) --- docs/src/main/asciidoc/deploying-to-kubernetes.adoc | 2 +- docs/src/main/asciidoc/deploying-to-openshift.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/deploying-to-kubernetes.adoc b/docs/src/main/asciidoc/deploying-to-kubernetes.adoc index 2b85072b421e2..b634f56f08b47 100644 --- a/docs/src/main/asciidoc/deploying-to-kubernetes.adoc +++ b/docs/src/main/asciidoc/deploying-to-kubernetes.adoc @@ -506,7 +506,7 @@ This would generate the following in the `env` section of your container: - env: - name: FOO valueFrom: - configMapRefKey: + configMapKeyRef: key: keyName name: my-configmap optional: false diff --git a/docs/src/main/asciidoc/deploying-to-openshift.adoc b/docs/src/main/asciidoc/deploying-to-openshift.adoc index 268d699a4b74a..93496d901bb5e 100644 --- a/docs/src/main/asciidoc/deploying-to-openshift.adoc +++ b/docs/src/main/asciidoc/deploying-to-openshift.adoc @@ -367,7 +367,7 @@ This would generate the following in the `env` section of your container: - env: - name: FOO valueFrom: - configMapRefKey: + configMapKeyRef: key: keyName name: my-configmap optional: false From fe6f3dfd7dca838c92666a76b55cd265eaf5d79e Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 30 Nov 2023 12:12:42 +0100 Subject: [PATCH 38/48] quarkus-update - Improve cleanup of log lines (cherry picked from commit 30e10ff9f9bbcdd9c64aab08e504b3679fbc9c9a) --- .../project/update/rewrite/QuarkusUpdateCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java index b7ea74069b464..9c2bea126433f 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java @@ -351,13 +351,13 @@ private String clean(String line) { return line; } - String pattern = "[" + name() + "]"; + String pattern = "[" + name() + "] "; - if (line.length() < pattern.length()) { + if (!line.startsWith(pattern)) { return line; } - return line.substring(pattern.length()).trim(); + return line.substring(pattern.length()); } private boolean matches(String line) { From 81c217f28b1c1c79bd4b68b5e4a47455d5ab9640 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 30 Nov 2023 12:13:11 +0100 Subject: [PATCH 39/48] quarkus update - Remove two unused methods (cherry picked from commit 397ca66e6aca443a950ed97f047bdaef24f816d2) --- .../project/update/rewrite/QuarkusUpdateCommand.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java index 9c2bea126433f..0fafb6b0adcaa 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java @@ -311,14 +311,6 @@ public static boolean isWindows() { return OS.contains("win"); } - static boolean hasGradle(Path dir) { - return Files.exists(dir.resolve("build.gradle")); - } - - private static boolean hasMaven(Path dir) { - return Files.exists(dir.resolve("pom.xml")); - } - private enum LogLevel { ERROR, From f5347f78cf6a4b67a84270e4bb0582ab69bf9a38 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 30 Nov 2023 12:15:53 +0100 Subject: [PATCH 40/48] quarkus update - Fix Windows detection (cherry picked from commit e3ba23c573222508462679b72cf5939fe992b0f6) --- independent-projects/tools/devtools-common/pom.xml | 4 ++++ .../project/update/rewrite/QuarkusUpdateCommand.java | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/independent-projects/tools/devtools-common/pom.xml b/independent-projects/tools/devtools-common/pom.xml index a8dfd837041f7..2e5832fddb6af 100644 --- a/independent-projects/tools/devtools-common/pom.xml +++ b/independent-projects/tools/devtools-common/pom.xml @@ -50,6 +50,10 @@ io.smallrye.common smallrye-common-version
+ + io.smallrye.common + smallrye-common-os + io.fabric8 maven-model-helper diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java index 0fafb6b0adcaa..c8a5ae63fb8f1 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java @@ -24,6 +24,7 @@ import io.quarkus.devtools.messagewriter.MessageWriter; import io.quarkus.devtools.project.BuildTool; import io.quarkus.qute.Qute; +import io.smallrye.common.os.OS; public class QuarkusUpdateCommand { @@ -305,10 +306,8 @@ private static boolean isExecutable(Path file) { return false; } - private static String OS = System.getProperty("os.name").toLowerCase(); - public static boolean isWindows() { - return OS.contains("win"); + return OS.WINDOWS.isCurrent(); } private enum LogLevel { From f96b56d015e9633421f5a5e36848eaf07898b9ce Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 30 Nov 2023 12:17:30 +0100 Subject: [PATCH 41/48] quarkus update - Add a clean in mvn process-sources We need to clean the project before the next compilation as things have changed a lot (e.g. in the case of a Quarkus 2.x -> 3.x update). (cherry picked from commit c6ad1fb15c51da32e9ccf242c5628c65ba05221c) --- .../update/rewrite/QuarkusUpdateCommand.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java index c8a5ae63fb8f1..cde516b239d60 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java @@ -58,6 +58,16 @@ public static void handle(MessageWriter log, BuildTool buildTool, Path baseDir, } } + private static void runMavenUpdate(MessageWriter log, Path baseDir, String rewritePluginVersion, String recipesGAV, + Path recipe, + boolean dryRun) { + final String mvnBinary = findMvnBinary(baseDir); + executeCommand(baseDir, getMavenUpdateCommand(mvnBinary, rewritePluginVersion, recipesGAV, recipe, dryRun), log); + + // format the sources + executeCommand(baseDir, getMavenProcessSourcesCommand(mvnBinary), log); + } + private static void runGradleUpdate(MessageWriter log, Path baseDir, String rewritePluginVersion, String recipesGAV, Path recipe, boolean dryRun) { Path tempInit = null; @@ -120,19 +130,10 @@ private static void propagateSystemPropertyIfSet(String name, List comma } } - private static void runMavenUpdate(MessageWriter log, Path baseDir, String rewritePluginVersion, String recipesGAV, - Path recipe, - boolean dryRun) { - final String mvnBinary = findMvnBinary(baseDir); - executeCommand(baseDir, getMavenUpdateCommand(mvnBinary, rewritePluginVersion, recipesGAV, recipe, dryRun), log); - - // format the sources - executeCommand(baseDir, getMavenProcessSourcesCommand(mvnBinary), log); - } - private static List getMavenProcessSourcesCommand(String mvnBinary) { List command = new ArrayList<>(); command.add(mvnBinary); + command.add("clean"); command.add("process-sources"); final String mavenSettings = getMavenSettingsArg(); if (mavenSettings != null) { From 04c784fe2955475997577035ebe86627fba986dd Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 30 Nov 2023 14:41:29 +0100 Subject: [PATCH 42/48] quarkus update - Execute Maven commands in batch mode (cherry picked from commit 553c361aa8559f3aca563ff6c2bee8bfa1b4dd11) --- .../devtools/project/update/rewrite/QuarkusUpdateCommand.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java index cde516b239d60..f53c3def02dd4 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java @@ -133,6 +133,7 @@ private static void propagateSystemPropertyIfSet(String name, List comma private static List getMavenProcessSourcesCommand(String mvnBinary) { List command = new ArrayList<>(); command.add(mvnBinary); + command.add("-B"); command.add("clean"); command.add("process-sources"); final String mavenSettings = getMavenSettingsArg(); @@ -148,6 +149,7 @@ private static List getMavenUpdateCommand(String mvnBinary, String rewri boolean dryRun) { final List command = new ArrayList<>(); command.add(mvnBinary); + command.add("-B"); command.add("-e"); command.add( String.format("%s:%s:%s:%s", MAVEN_REWRITE_PLUGIN_GROUP, MAVEN_REWRITE_PLUGIN_ARTIFACT, rewritePluginVersion, From 092fb9c8137b37acbc9d0a8b9ded620a08a426cf Mon Sep 17 00:00:00 2001 From: Alexei Bratuhin Date: Wed, 29 Nov 2023 15:33:15 +0100 Subject: [PATCH 43/48] #37390 = respect comma in property value for @RolesAllowed using double-escape (cherry picked from commit b045e662139dd8a1281763091aa2e29e725ec271) --- .../rolesallowed/RolesAllowedExpressionTest.java | 12 +++++++++++- .../security/runtime/SecurityCheckRecorder.java | 12 +++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/extensions/security/deployment/src/test/java/io/quarkus/security/test/rolesallowed/RolesAllowedExpressionTest.java b/extensions/security/deployment/src/test/java/io/quarkus/security/test/rolesallowed/RolesAllowedExpressionTest.java index 7af69cfa4c78e..f29bc1f0c6f4e 100644 --- a/extensions/security/deployment/src/test/java/io/quarkus/security/test/rolesallowed/RolesAllowedExpressionTest.java +++ b/extensions/security/deployment/src/test/java/io/quarkus/security/test/rolesallowed/RolesAllowedExpressionTest.java @@ -40,7 +40,8 @@ public class RolesAllowedExpressionTest { "%test.test-profile-admin=admin\n" + "missing-profile-profile-admin=superman\n" + "%missing-profile.missing-profile-profile-admin=admin\n" + - "all-roles=Administrator,Software,Tester,User\n"; + "all-roles=Administrator,Software,Tester,User\n" + + "ldap-roles=cn=Administrator\\\\,ou=Software\\\\,dc=Tester\\\\,dc=User\n"; @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() @@ -90,6 +91,10 @@ public void shouldRestrictAccessToSpecificRole() { assertSuccess(() -> bean.list(), "list", new AuthData(Set.of("Administrator", "Software", "Tester", "User"), false, "list")); assertFailureFor(() -> bean.list(), ForbiddenException.class, ADMIN); + + // property expression with escaped collection separator should not be treated as list + assertSuccess(() -> bean.ldap(), "ldap", + new AuthData(Set.of("cn=Administrator,ou=Software,dc=Tester,dc=User"), false, "ldap")); } @Singleton @@ -141,6 +146,11 @@ public final String list() { return "list"; } + @RolesAllowed("${ldap-roles}") + public final String ldap() { + return "ldap"; + } + } } diff --git a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java index ee6639d2ef495..8661d06f3f4bd 100644 --- a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java +++ b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java @@ -98,15 +98,17 @@ public String[] get() { // @RolesAllowed({"${my.roles}"}) => my.roles=one,two <=> @RolesAllowed({"one", "two"}) if (strVal != null && strVal.contains(",")) { var strArr = StringUtil.split(strVal); - if (strArr.length > 1) { + if (strArr.length >= 1) { // role order is irrelevant as logical operator between them is OR - // first role will go to the original place + // first role will go to the original place, double escaped comma will be parsed correctly strVal = strArr[0]; - // the rest of the roles will be appended at the end - for (int i1 = 1; i1 < strArr.length; i1++) { - roles.add(strArr[i1]); + if (strArr.length > 1) { + // the rest of the roles will be appended at the end + for (int i1 = 1; i1 < strArr.length; i1++) { + roles.add(strArr[i1]); + } } } } From b9964f513eea74baaf129c7a785137cde0dc8b9c Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Thu, 30 Nov 2023 10:44:12 +0100 Subject: [PATCH 44/48] Scheduler: register ApplicationNotRunning as bean even if quartz is used - fixes #37417 (cherry picked from commit 3b44cde7a3ab5136115ca13eeb00a71cf69dd2bf) --- .../ApplicationNotRunningPredicateTest.java | 57 +++++++++++++++++++ .../deployment/SchedulerProcessor.java | 3 +- .../ApplicationNotRunningPredicateTest.java | 10 ++-- 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/ApplicationNotRunningPredicateTest.java diff --git a/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/ApplicationNotRunningPredicateTest.java b/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/ApplicationNotRunningPredicateTest.java new file mode 100644 index 0000000000000..8cb4bcda0915d --- /dev/null +++ b/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/ApplicationNotRunningPredicateTest.java @@ -0,0 +1,57 @@ +package io.quarkus.quartz.test; + +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import jakarta.enterprise.event.Observes; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.runtime.StartupEvent; +import io.quarkus.scheduler.FailedExecution; +import io.quarkus.scheduler.Scheduled; +import io.quarkus.scheduler.SuccessfulExecution; +import io.quarkus.test.QuarkusUnitTest; + +public class ApplicationNotRunningPredicateTest { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest().withApplicationRoot((jar) -> jar.addClasses(Jobs.class)); + + static final CountDownLatch SUCCESS_LATCH = new CountDownLatch(1); + static volatile FailedExecution failedExecution; + + @Test + public void testTriggerErrorStatus() throws InterruptedException { + assertTrue(SUCCESS_LATCH.await(5, TimeUnit.SECONDS)); + assertNull(failedExecution); + } + + void observeSuccessfulExecution(@Observes SuccessfulExecution successfulExecution) { + SUCCESS_LATCH.countDown(); + } + + void observeFailedExecution(@Observes FailedExecution failedExecution) { + ApplicationNotRunningPredicateTest.failedExecution = failedExecution; + } + + static class Jobs { + + volatile boolean started; + + void started(@Observes StartupEvent event) { + started = true; + } + + @Scheduled(every = "0.2s", skipExecutionIf = Scheduled.ApplicationNotRunning.class) + void scheduleAfterStarted() { + if (!started) { + throw new IllegalStateException(); + } + } + } +} diff --git a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java index 60196c55e4190..ad9c8176b9ca3 100644 --- a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java +++ b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java @@ -98,8 +98,9 @@ public class SchedulerProcessor { @BuildStep void beans(Capabilities capabilities, BuildProducer additionalBeans) { + additionalBeans.produce(new AdditionalBeanBuildItem(Scheduled.ApplicationNotRunning.class)); if (capabilities.isMissing(Capability.QUARTZ)) { - additionalBeans.produce(new AdditionalBeanBuildItem(SimpleScheduler.class, Scheduled.ApplicationNotRunning.class)); + additionalBeans.produce(new AdditionalBeanBuildItem(SimpleScheduler.class)); } } diff --git a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/ApplicationNotRunningPredicateTest.java b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/ApplicationNotRunningPredicateTest.java index 6318d8ecb0d31..c7b246ebe2b0b 100644 --- a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/ApplicationNotRunningPredicateTest.java +++ b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/ApplicationNotRunningPredicateTest.java @@ -6,9 +6,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import jakarta.annotation.Priority; import jakarta.enterprise.event.Observes; -import jakarta.interceptor.Interceptor; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -43,15 +41,15 @@ void observeFailedExecution(@Observes FailedExecution failedExecution) { static class Jobs { - volatile boolean preStart; + volatile boolean started; - void started(@Observes @Priority(Interceptor.Priority.PLATFORM_BEFORE) StartupEvent event) { - preStart = true; + void started(@Observes StartupEvent event) { + started = true; } @Scheduled(every = "0.2s", skipExecutionIf = Scheduled.ApplicationNotRunning.class) void scheduleAfterStarted() { - if (!preStart) { + if (!started) { throw new IllegalStateException(); } } From 703c9f8b735873c1454db885ba8840aaf1f8c0ba Mon Sep 17 00:00:00 2001 From: Michael Rasmussen Date: Fri, 1 Dec 2023 05:02:28 +0200 Subject: [PATCH 45/48] Add Content-Range header to 206 Partial Content file response (cherry picked from commit 1a9e2e7d321ed6f62a8648d2ec98b96412f0936b) --- .../server/test/providers/FileTestCase.java | 20 ++++++++++++++++ .../serialisers/ServerFileBodyHandler.java | 23 +++++++++++++------ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/providers/FileTestCase.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/providers/FileTestCase.java index 80f99ddf1105d..a7feae8824879 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/providers/FileTestCase.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/providers/FileTestCase.java @@ -45,17 +45,37 @@ public void testFiles() throws Exception { .then() .statusCode(206) .header(HttpHeaders.CONTENT_LENGTH, "10") + .header("Content-Range", "bytes 0-9/" + contentLength) .body(Matchers.equalTo(content.substring(0, 10))); RestAssured.given().header("Range", "bytes=10-19").get("/providers/file/file") .then() .statusCode(206) .header(HttpHeaders.CONTENT_LENGTH, "10") + .header("Content-Range", "bytes 10-19/" + contentLength) .body(Matchers.equalTo(content.substring(10, 20))); RestAssured.given().header("Range", "bytes=10-").get("/providers/file/file") .then() .statusCode(206) .header(HttpHeaders.CONTENT_LENGTH, String.valueOf(content.length() - 10)) + .header("Content-Range", "bytes 10-" + (content.length() - 1) + "/" + contentLength) .body(Matchers.equalTo(content.substring(10))); + RestAssured.given().header("Range", "bytes=-10").get("/providers/file/file") + .then() + .statusCode(206) + .header(HttpHeaders.CONTENT_LENGTH, "10") + .header("Content-Range", + "bytes " + (content.length() - 10) + "-" + (content.length() - 1) + "/" + contentLength) + .body(Matchers.equalTo(content.substring((content.length() - 10)))); + RestAssured.given().header("Range", "bytes=" + (content.length() + 1) + "-").get("/providers/file/file") + .then() + .statusCode(200) + .header(HttpHeaders.CONTENT_LENGTH, contentLength) + .body(Matchers.equalTo(content)); + RestAssured.given().header("Range", "bytes=0-1, 3-4").get("/providers/file/file") + .then() + .statusCode(200) + .header(HttpHeaders.CONTENT_LENGTH, contentLength) + .body(Matchers.equalTo(content)); RestAssured.get("/providers/file/file-partial") .then() .statusCode(200) diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerFileBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerFileBodyHandler.java index bd33ed659fda6..31158a025c3b4 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerFileBodyHandler.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerFileBodyHandler.java @@ -42,16 +42,25 @@ static void sendFile(File file, ServerRequestContext context) { ResteasyReactiveRequestContext ctx = ((ResteasyReactiveRequestContext) context); Object rangeObj = ctx.getHeader("Range", true); ByteRange byteRange = rangeObj == null ? null : ByteRange.parse(rangeObj.toString()); + long fileLength = file.length(); if ((byteRange != null) && (byteRange.ranges.size() == 1)) { ByteRange.Range range = byteRange.ranges.get(0); - long length = range.getEnd() == -1 ? Long.MAX_VALUE : range.getEnd() - range.getStart() + 1; - context.serverResponse() - .setStatusCode(Response.Status.PARTIAL_CONTENT.getStatusCode()) - .sendFile(file.getAbsolutePath(), range.getStart(), length); - } else { - context.serverResponse().sendFile(file.getAbsolutePath(), 0, file.length()); + ByteRange.Range fileRange = (range.getStart() == -1) + ? new ByteRange.Range(fileLength - range.getEnd(), fileLength - 1) + : new ByteRange.Range(range.getStart(), Math.min(fileLength - 1, range.getEnd())); + + if ((fileRange.getStart() >= 0) && (fileRange.getStart() <= fileRange.getEnd())) { + String contentRange = "bytes " + fileRange.getStart() + "-" + fileRange.getEnd() + "/" + fileLength; + long length = fileRange.getEnd() - fileRange.getStart() + 1; + context.serverResponse() + .setStatusCode(Response.Status.PARTIAL_CONTENT.getStatusCode()) + .setResponseHeader("Content-Range", contentRange) + .sendFile(file.getAbsolutePath(), fileRange.getStart(), length); + return; + } } + context.serverResponse().sendFile(file.getAbsolutePath(), 0, fileLength); } /** @@ -138,7 +147,7 @@ public static ByteRange parse(String rangeHeader) { if (index + 1 < part.length()) { end = Long.parseLong(part.substring(index + 1)); } else { - end = -1; + end = Long.MAX_VALUE; } ranges.add(new Range(start, end)); } From cdbc6d66d8df1abe0e244406fdde0daad0c53175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Fri, 1 Dec 2023 14:32:12 +0100 Subject: [PATCH 46/48] Test access to fields of @Immutable embeddables (cherry picked from commit 79e3b19ec13360b305fa6941516559e325faa3dd) --- .../ImmutableEmbeddableFieldAccessTest.java | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 extensions/hibernate-orm/deployment/src/test/java/io/quarkus/hibernate/orm/applicationfieldaccess/ImmutableEmbeddableFieldAccessTest.java diff --git a/extensions/hibernate-orm/deployment/src/test/java/io/quarkus/hibernate/orm/applicationfieldaccess/ImmutableEmbeddableFieldAccessTest.java b/extensions/hibernate-orm/deployment/src/test/java/io/quarkus/hibernate/orm/applicationfieldaccess/ImmutableEmbeddableFieldAccessTest.java new file mode 100644 index 0000000000000..123a97aa63ef5 --- /dev/null +++ b/extensions/hibernate-orm/deployment/src/test/java/io/quarkus/hibernate/orm/applicationfieldaccess/ImmutableEmbeddableFieldAccessTest.java @@ -0,0 +1,193 @@ +package io.quarkus.hibernate.orm.applicationfieldaccess; + +import static org.assertj.core.api.Assertions.assertThat; + +import jakarta.inject.Inject; +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityManager; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +import org.hibernate.Hibernate; +import org.hibernate.annotations.Immutable; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.narayana.jta.QuarkusTransaction; +import io.quarkus.test.QuarkusUnitTest; + +/** + * Checks that access to record fields or record getters by the application works correctly. + */ +public class ImmutableEmbeddableFieldAccessTest { + + @RegisterExtension + static QuarkusUnitTest runner = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(MyEntity.class) + .addClasses(MyImmutableEmbeddableWithFieldAccess.class) + .addClasses(MyImmutableEmbeddableWithAccessors.class) + .addClass(AccessDelegate.class)) + .withConfigurationResource("application.properties"); + + @Inject + EntityManager em; + + @Test + public void immutableEmbeddableWithoutAdditionalGetters_field() { + doTestFieldAccess(new AccessDelegate() { + @Override + public void setValue(MyEntity entity, Long value) { + var embedded = new MyImmutableEmbeddableWithFieldAccess(); + embedded.value = value; + entity.embeddedWithoutAccessors = embedded; + } + + @Override + public Long getValue(MyEntity entity) { + return entity.embeddedWithoutAccessors == null ? null : entity.embeddedWithoutAccessors.value; + } + }); + } + + @Test + public void immutableEmbeddableWithAdditionalGetters_field() { + doTestFieldAccess(new AccessDelegate() { + @Override + public void setValue(MyEntity entity, Long value) { + var embedded = new MyImmutableEmbeddableWithAccessors(); + // Assuming this is changed only once on initialization, + // which is the only way the @Immutable annotation would make sense. + embedded.value = value; + entity.embeddedWithFieldAccess = embedded; + } + + @Override + public Long getValue(MyEntity entity) { + return entity.embeddedWithFieldAccess == null ? null : entity.embeddedWithFieldAccess.value; + } + }); + } + + @Test + public void immutableEmbeddableWithAccessors() { + doTestFieldAccess(new AccessDelegate() { + @Override + public void setValue(MyEntity entity, Long value) { + var embedded = new MyImmutableEmbeddableWithAccessors(); + // Assuming this is changed only once on initialization, + // which is the only way the @Immutable annotation would make sense. + embedded.setValue(value); + entity.embeddedWithFieldAccess = embedded; + } + + @Override + public Long getValue(MyEntity entity) { + return entity.embeddedWithFieldAccess == null ? null : entity.embeddedWithFieldAccess.getValue(); + } + }); + } + + // Ideally we'd make this a @ParameterizedTest and pass the access delegate as parameter, + // but we cannot do that due to JUnit using a different classloader than the test. + private void doTestFieldAccess(AccessDelegate delegate) { + Long id = QuarkusTransaction.disallowingExisting().call(() -> { + var entity = new MyEntity(); + em.persist(entity); + return entity.id; + }); + + QuarkusTransaction.disallowingExisting().run(() -> { + var entity = em.find(MyEntity.class, id); + assertThat(delegate.getValue(entity)) + .as("Loaded value before update") + .isNull(); + }); + + QuarkusTransaction.disallowingExisting().run(() -> { + var entity = em.getReference(MyEntity.class, id); + // Since field access is replaced with accessor calls, + // we expect this change to be detected by dirty tracking and persisted. + delegate.setValue(entity, 42L); + }); + + QuarkusTransaction.disallowingExisting().run(() -> { + var entity = em.find(MyEntity.class, id); + // We're working on an initialized entity. + assertThat(entity) + .as("find() should return uninitialized entity") + .returns(true, Hibernate::isInitialized); + // The above should have persisted a value that passes the assertion. + assertThat(delegate.getValue(entity)) + .as("Loaded value after update") + .isEqualTo(42L); + }); + + QuarkusTransaction.disallowingExisting().run(() -> { + var entity = em.getReference(MyEntity.class, id); + // We're working on an uninitialized entity. + assertThat(entity) + .as("getReference() should return uninitialized entity") + .returns(false, Hibernate::isInitialized); + // The above should have persisted a value that passes the assertion. + assertThat(delegate.getValue(entity)) + .as("Lazily loaded value after update") + .isEqualTo(42L); + // Accessing the value should trigger initialization of the entity. + assertThat(entity) + .as("Getting the value should initialize the entity") + .returns(true, Hibernate::isInitialized); + }); + } + + @Entity(name = "myentity") + public static class MyEntity { + @Id + @GeneratedValue + public long id; + @Embedded + @AttributeOverride(name = "value", column = @Column(name = "value1")) + public MyImmutableEmbeddableWithAccessors embeddedWithFieldAccess; + @Embedded + @AttributeOverride(name = "value", column = @Column(name = "value2")) + public MyImmutableEmbeddableWithFieldAccess embeddedWithoutAccessors; + } + + @Immutable + @Embeddable + public static class MyImmutableEmbeddableWithFieldAccess { + public Long value; + + public MyImmutableEmbeddableWithFieldAccess() { + } + } + + @Immutable + @Embeddable + public static class MyImmutableEmbeddableWithAccessors { + private Long value; + + // For Hibernate ORM instantiation + protected MyImmutableEmbeddableWithAccessors() { + } + + public Long getValue() { + return value; + } + + // For Hibernate ORM instantiation + protected void setValue(Long value) { + this.value = value; + } + } + + private interface AccessDelegate { + void setValue(MyEntity entity, Long value); + + Long getValue(MyEntity entity); + } +} From 78a823c441bb23c46f0e2b84de1e4732b743eebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Fri, 1 Dec 2023 14:41:10 +0100 Subject: [PATCH 47/48] Fix Panache bytecode enhancement for @Embeddable records (cherry picked from commit 1b426fc415832a026d0f3806f685f50034bf6359) --- .../deployment/PanacheHibernateCommonResourceProcessor.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extensions/panache/panache-hibernate-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheHibernateCommonResourceProcessor.java b/extensions/panache/panache-hibernate-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheHibernateCommonResourceProcessor.java index 93037abea56c9..6127afcc2955b 100644 --- a/extensions/panache/panache-hibernate-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheHibernateCommonResourceProcessor.java +++ b/extensions/panache/panache-hibernate-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheHibernateCommonResourceProcessor.java @@ -157,9 +157,12 @@ private EntityModel createEntityModel(ClassInfo classInfo) { // so we need to be careful when we enhance private fields, // because the corresponding `$_hibernate_{read/write}_*()` methods // will only be generated for classes mapped through *annotations*. - boolean willBeEnhancedByHibernateOrm = classInfo.hasAnnotation(DOTNAME_ENTITY) + boolean isManaged = classInfo.hasAnnotation(DOTNAME_ENTITY) || classInfo.hasAnnotation(DOTNAME_MAPPED_SUPERCLASS) || classInfo.hasAnnotation(DOTNAME_EMBEDDABLE); + boolean willBeEnhancedByHibernateOrm = isManaged + // Records are immutable, thus never enhanced + && !classInfo.isRecord(); for (FieldInfo fieldInfo : classInfo.fields()) { String name = fieldInfo.name(); if (!Modifier.isStatic(fieldInfo.flags()) From 83a3e5110ff153b8c7e03392f34ea95d6dc78231 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 11 Oct 2023 15:07:28 +0300 Subject: [PATCH 48/48] Make Truffle from GraalVM 23.1 work in all Quarkus modes Fixes: #36242 (cherry picked from commit 738a24d70ed9e7ec3cdeddc3cb8fb7a2d589b75d) --- .../SetClassPathSystemPropBuildItem.java | 12 +++++ .../steps/ClassPathSystemPropBuildStep.java | 53 +++++++++++++++++++ .../ClassPathSystemPropertyRecorder.java | 11 ++++ 3 files changed, 76 insertions(+) create mode 100644 core/deployment/src/main/java/io/quarkus/deployment/builditem/SetClassPathSystemPropBuildItem.java create mode 100644 core/deployment/src/main/java/io/quarkus/deployment/steps/ClassPathSystemPropBuildStep.java create mode 100644 core/runtime/src/main/java/io/quarkus/runtime/ClassPathSystemPropertyRecorder.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/SetClassPathSystemPropBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/SetClassPathSystemPropBuildItem.java new file mode 100644 index 0000000000000..7461e22f7a73f --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/SetClassPathSystemPropBuildItem.java @@ -0,0 +1,12 @@ +package io.quarkus.deployment.builditem; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * A marker build item to make Quarkus set the {@code java.class.path} system property. + * This system property is used in rare by libraries (Truffle for example) to create their own ClassLoaders. + * The value of the system property is simply best effort, as there is no way to faithfully represent + * the Quarkus ClassLoader hierarchies in a system property value. + */ +public final class SetClassPathSystemPropBuildItem extends MultiBuildItem { +} diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassPathSystemPropBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassPathSystemPropBuildStep.java new file mode 100644 index 0000000000000..feda25cbade14 --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassPathSystemPropBuildStep.java @@ -0,0 +1,53 @@ +package io.quarkus.deployment.steps; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.SetClassPathSystemPropBuildItem; +import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.runtime.ClassPathSystemPropertyRecorder; + +public class ClassPathSystemPropBuildStep { + + @BuildStep + public void produce(BuildProducer producer, CurateOutcomeBuildItem curateOutcome) { + boolean truffleUsed = curateOutcome.getApplicationModel().getDependencies().stream() + .anyMatch(d -> d.getGroupId().equals("org.graalvm.polyglot")); + if (truffleUsed) { + producer.produce(new SetClassPathSystemPropBuildItem()); + } + } + + @BuildStep + @Record(ExecutionTime.STATIC_INIT) + public void set(List setCPItems, + CurateOutcomeBuildItem curateOutcome, + ClassPathSystemPropertyRecorder recorder) { + if (setCPItems.isEmpty()) { + return; + } + Collection runtimeDependencies = curateOutcome.getApplicationModel().getRuntimeDependencies(); + List parentFirst = new ArrayList<>(); + List regular = new ArrayList<>(); + for (ResolvedDependency dependency : runtimeDependencies) { + if (dependency.isClassLoaderParentFirst()) { + parentFirst.addAll(dependency.getContentTree().getRoots()); + } else { + regular.addAll(dependency.getContentTree().getRoots()); + + } + } + String classPathValue = Stream.concat(parentFirst.stream(), regular.stream()).map(p -> p.toAbsolutePath().toString()) + .collect(Collectors.joining(":")); + recorder.set(classPathValue); + } +} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/ClassPathSystemPropertyRecorder.java b/core/runtime/src/main/java/io/quarkus/runtime/ClassPathSystemPropertyRecorder.java new file mode 100644 index 0000000000000..fdca4fcb0cb65 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/ClassPathSystemPropertyRecorder.java @@ -0,0 +1,11 @@ +package io.quarkus.runtime; + +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class ClassPathSystemPropertyRecorder { + + public void set(String value) { + System.setProperty("java.class.path", value); + } +}