From c1d33658f64d93623d4ab08a0acef3f5bb647421 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 24 Aug 2023 16:08:23 +0200 Subject: [PATCH 01/32] Update to Kotlin 1.9.10 (cherry picked from commit ff6a81dcc5c4b381a4d4f216d1fccdc039838166) --- bom/application/pom.xml | 6 +++--- build-parent/pom.xml | 2 +- .../src/test/java/io/quarkus/gradle/QuarkusPluginTest.java | 2 +- .../kotlin/serialization/common/runtime/JsonConfig.java | 7 +++++++ .../kotlin/serialization/common/runtime/JsonProducer.kt | 1 + independent-projects/arc/pom.xml | 2 +- .../conditional-dependencies-kotlin/build.gradle.kts | 4 ++-- 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 8386a7eb51c00..4e4e8b76b3179 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -158,10 +158,10 @@ 2.14.0 2.2.0 1.0.0 - 1.9.0 - 1.7.2 + 1.9.10 + 1.7.3 0.27.0 - 1.5.1 + 1.6.0 3.7.0 3.2.0 4.2.0 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 265f81d6e1445..80c16c35ccd4f 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -20,7 +20,7 @@ 3.11.0 - 1.9.0 + 1.9.10 1.8.20 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 aaeb75459ec1e..580777c029f6d 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.0"); + var kotlinVersion = System.getProperty("kotlin_version", "1.9.10"); var settingFile = testProjectDir.resolve("settings.gradle.kts"); var mppProjectDir = testProjectDir.resolve("mpp"); var quarkusProjectDir = testProjectDir.resolve("quarkus"); diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/java/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonConfig.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/java/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonConfig.java index 4655bd1b1da86..df47f1c32e7c0 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/java/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonConfig.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/java/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonConfig.java @@ -123,6 +123,12 @@ public class JsonConfig { @ConfigItem(name = "naming-strategy") public Optional namingStrategy; + /** + * Specifies if the enum values should be decoded case insensitively. + */ + @ConfigItem(defaultValue = "false") + public boolean decodeEnumsCaseInsensitive = false; + @Override public String toString() { return new StringJoiner(", ", JsonConfig.class.getSimpleName() + "[", "]") @@ -137,6 +143,7 @@ public String toString() { .add("classDiscriminator='" + classDiscriminator + "'") .add("allowSpecialFloatingPointValues=" + allowSpecialFloatingPointValues) .add("useAlternativeNames=" + useAlternativeNames) + .add("decodeEnumsCaseInsensitive=" + decodeEnumsCaseInsensitive) .toString(); } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/kotlin/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonProducer.kt b/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/kotlin/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonProducer.kt index 63f83f4168a3b..45ea46cde67a8 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/kotlin/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonProducer.kt +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-kotlin-serialization-common/runtime/src/main/kotlin/io/quarkus/resteasy/reactive/kotlin/serialization/common/runtime/JsonProducer.kt @@ -37,6 +37,7 @@ class JsonProducer { prettyPrintIndent = configuration.json.prettyPrintIndent useAlternativeNames = configuration.json.useAlternativeNames useArrayPolymorphism = configuration.json.useArrayPolymorphism + decodeEnumsCaseInsensitive = configuration.json.decodeEnumsCaseInsensitive configuration.json.namingStrategy.ifPresent { strategy -> loadStrategy(this, strategy, this@JsonProducer) diff --git a/independent-projects/arc/pom.xml b/independent-projects/arc/pom.xml index a9de9e1d56369..945a1764650c5 100644 --- a/independent-projects/arc/pom.xml +++ b/independent-projects/arc/pom.xml @@ -54,7 +54,7 @@ 3.24.2 5.9.3 - 1.9.0 + 1.9.10 1.7.1 5.4.0 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 a4b08923c3a60..87ca016cb890d 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.0" - kotlin("plugin.allopen") version "1.9.0" + kotlin("jvm") version "1.9.10" + kotlin("plugin.allopen") version "1.9.10" id("io.quarkus") } From 28b3010e770c2febfc1184e3915ba96922afe0e6 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Mon, 28 Aug 2023 13:42:12 +0200 Subject: [PATCH 02/32] QuarkusComponentTest docs: remove the incorrect note - related to https://github.com/quarkusio/quarkus/issues/35591 (cherry picked from commit ac7ccc4e457e8ae858547a828a1e52229e589131) --- docs/src/main/asciidoc/getting-started-testing.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/src/main/asciidoc/getting-started-testing.adoc b/docs/src/main/asciidoc/getting-started-testing.adoc index 1bf75d33779c6..244714a058e15 100644 --- a/docs/src/main/asciidoc/getting-started-testing.adoc +++ b/docs/src/main/asciidoc/getting-started-testing.adoc @@ -1626,8 +1626,6 @@ The container is stopped and the config is released during the `after all` test The fields annotated with `@Inject` and `@InjectMock` are injected after a test instance is created and unset before a test instance is destroyed. Finally, the CDI request context is activated and terminated per each test method. -NOTE: By default, a new test instance is created for each test method. Therefore, a new CDI container is started for each test method. However, if the test class is annotated with `@org.junit.jupiter.api.TestInstance` and the test instance lifecycle is set to `org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS` then the CDI container will be shared across all test method executions of a given test class. - === Auto Mocking Unsatisfied Dependencies Unlike in regular CDI environments the test does not fail if a component injects an unsatisfied dependency. From a15f3864a1f792fb9ca287efea2993ae109dcef3 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 28 Aug 2023 12:55:25 +0300 Subject: [PATCH 03/32] Fix Jakarta Cookie serialization in native Fixes: #35582 (cherry picked from commit a9aa2f798419bfa990d9bc24c460bb7725157c6c) --- .../processor/ResteasyReactiveJacksonProcessor.java | 6 ++++++ .../jsonb/deployment/ResteasyReactiveJsonbProcessor.java | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java index 5294839c8816a..564b1ed477e7a 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java @@ -13,6 +13,7 @@ import jakarta.ws.rs.Priorities; import jakarta.ws.rs.RuntimeType; +import jakarta.ws.rs.core.Cookie; import jakarta.ws.rs.core.MediaType; import org.jboss.jandex.AnnotationInstance; @@ -205,6 +206,11 @@ private String getJacksonMessageBodyReader(boolean needsFullFeatureSet) { : ServerJacksonMessageBodyReader.class.getName(); } + @BuildStep + void reflection(BuildProducer producer) { + producer.produce(ReflectiveClassBuildItem.builder(Cookie.class).methods().build()); + } + @Record(ExecutionTime.STATIC_INIT) @BuildStep void handleJsonAnnotations(Optional resourceScanningResultBuildItem, diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/main/java/io/quarkus/resteasy/reactive/jsonb/deployment/ResteasyReactiveJsonbProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/main/java/io/quarkus/resteasy/reactive/jsonb/deployment/ResteasyReactiveJsonbProcessor.java index fcaed58b07e6c..b17c7163f3da4 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/main/java/io/quarkus/resteasy/reactive/jsonb/deployment/ResteasyReactiveJsonbProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/main/java/io/quarkus/resteasy/reactive/jsonb/deployment/ResteasyReactiveJsonbProcessor.java @@ -1,11 +1,13 @@ package io.quarkus.resteasy.reactive.jsonb.deployment; import jakarta.ws.rs.RuntimeType; +import jakarta.ws.rs.core.Cookie; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.resteasy.reactive.common.deployment.ServerDefaultProducesHandlerBuildItem; import io.quarkus.resteasy.reactive.jsonb.common.deployment.ResteasyReactiveJsonbCommonProcessor; import io.quarkus.resteasy.reactive.spi.MessageBodyReaderBuildItem; @@ -29,4 +31,9 @@ void additionalProviders(BuildProducer additionalRea ResteasyReactiveJsonbCommonProcessor.additionalProviders(additionalReaders, additionalWriters, RuntimeType.SERVER); } + + @BuildStep + void reflection(BuildProducer producer) { + producer.produce(ReflectiveClassBuildItem.builder(Cookie.class).methods().build()); + } } From 826e852b30e1c779101a5b438d7fb2e2c75a6ccf Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 25 Aug 2023 19:18:29 +0100 Subject: [PATCH 04/32] Get DevUI include openid scope if it is not configured (cherry picked from commit 043a327107e44001b206c3510ba0d8a039dae157) --- .../io/quarkus/oidc/runtime/OidcConfigPropertySupplier.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcConfigPropertySupplier.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcConfigPropertySupplier.java index 0b05277f48b4f..68b586664872f 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcConfigPropertySupplier.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcConfigPropertySupplier.java @@ -111,7 +111,11 @@ public String get(Config config) { scopes = providerConfig.authentication.scopes; } if (scopes.isPresent()) { - return OidcCommonUtils.urlEncode(String.join(" ", scopes.get())); + String scopesString = String.join(" ", scopes.get()); + if (!scopes.get().contains(OidcConstants.OPENID_SCOPE)) { + scopesString += (" " + OidcConstants.OPENID_SCOPE); + } + return OidcCommonUtils.urlEncode(scopesString); } else { return OidcConstants.OPENID_SCOPE; } From 668e5515471a32c92b2ca63ecb2f7be149f06223 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 25 Aug 2023 19:26:51 +0100 Subject: [PATCH 05/32] Fix DevUI callback URL references in the docs (cherry picked from commit 52fe14f4ce978c9922a00abd6ad6daf86763251b) --- .../main/asciidoc/security-openid-connect-dev-services.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 67a51a1b768ec..331ccb5b3f43f 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -133,7 +133,7 @@ You may need to register a redirect URI for the authorization code flow initiate If Keycloak does enforce it then you will see an authentication error informing you that the `redirect_uri` value is wrong. -In this case select the `Keycloak Admin` option in the right top corner, login as `admin:admin`, select the test realm and the client which Dev UI for Keycloak is configured with and add `http://localhost:8080/q/dev/io.quarkus.quarkus-oidc/provider` to `Valid Redirect URIs`. If you used `-Dquarkus.http.port` when starting Quarkus then change `8080` to the value of `quarkus.http.port` +In this case select the `Keycloak Admin` option in the right top corner, login as `admin:admin`, select the test realm and the client which Dev UI for Keycloak is configured with and add `http://localhost:8080/q/dev-ui/io.quarkus.quarkus-oidc/keycloak-provider` to `Valid Redirect URIs`. If you used `-Dquarkus.http.port` when starting Quarkus then change `8080` to the value of `quarkus.http.port` If the container is shared between multiple applications running on different ports then you will need to register `redirect_uri` values for each of these applications. @@ -318,7 +318,7 @@ image::dev-ui-oidc-devconsole-card.png[alt=Generic Dev UI OpenID Connect Card,ro Follow the link, and you will be able to log in to your provider, get the tokens and test the application. The experience will be the same as described in the <> section, where `Dev Services for Keycloak` container has been started, especially if you work with Keycloak. -You will most likely need to configure your OpenId Connect provider to support redirecting back to the `Dev Console`. Add `http://localhost:8080/q/dev-v1/io.quarkus.quarkus-oidc/provider` as one of the supported redirect and logout URLs. one of the supported redirect and logout URLs. +You will most likely need to configure your OpenId Connect provider to support redirecting back to the `Dev Console`. Add `http://localhost:8080/q/dev-ui/io.quarkus.quarkus-oidc/`providerName`-provider` as one of the supported redirect and logout URLs, where `providerName` will need to be replaced by the name of the provider shown in DevUI, for example, `auth0`. If you work with other providers then a Dev UI experience described in the <> section might differ slightly. For example, an access token may not be in a JWT format, so it won't be possible to show its internal content, though all providers should return an ID Token as JWT. From 5411c18179fcaad3c890a52bbf8ee9b981ddf531 Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Mon, 28 Aug 2023 10:17:43 +0200 Subject: [PATCH 06/32] Release the virtual thread executor Thus, the next test/dev execution would recreate a new executor. Fix #35575 (cherry picked from commit 1e6d12135902633081c50a4b92269f7e15c25afe) --- .../java/io/quarkus/virtual/threads/VirtualThreadsRecorder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/virtual-threads/runtime/src/main/java/io/quarkus/virtual/threads/VirtualThreadsRecorder.java b/extensions/virtual-threads/runtime/src/main/java/io/quarkus/virtual/threads/VirtualThreadsRecorder.java index c326cd433d1b2..8d6a8c3fcca29 100644 --- a/extensions/virtual-threads/runtime/src/main/java/io/quarkus/virtual/threads/VirtualThreadsRecorder.java +++ b/extensions/virtual-threads/runtime/src/main/java/io/quarkus/virtual/threads/VirtualThreadsRecorder.java @@ -47,6 +47,7 @@ public void run() { @Override public void run() { Executor executor = current; + current = null; if (executor instanceof ExecutorService) { ExecutorService service = (ExecutorService) executor; service.shutdown(); From 5b84809c6e3a7310e8b1035dc28c0a07e87a0717 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 29 Aug 2023 16:14:46 +0200 Subject: [PATCH 07/32] Config doc - Avoid processing methods if not @ConfigMapping Fixes #35594 (cherry picked from commit 469697790acadf34326f37a35f7bdd59c3baac1a) --- .../annotation/processor/Constants.java | 2 +- .../ExtensionAnnotationProcessor.java | 5 ++- .../generate_doc/ConfigDocItemFinder.java | 35 ++++++++++++------- .../generate_doc/ConfigDocItemScanner.java | 4 +-- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java b/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java index 743c1bbf00aa1..d6251ece2eb60 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/Constants.java @@ -70,7 +70,7 @@ final public class Constants { public static final String ANNOTATION_CONFIG_WITH_UNNAMED_KEY = "io.smallrye.config.WithUnnamedKey"; public static final Set SUPPORTED_ANNOTATIONS_TYPES = Set.of(ANNOTATION_BUILD_STEP, ANNOTATION_CONFIG_GROUP, - ANNOTATION_CONFIG_ROOT, ANNOTATION_RECORDER); + ANNOTATION_CONFIG_ROOT, ANNOTATION_RECORDER, ANNOTATION_CONFIG_MAPPING); public static final Map ALIASED_TYPES = Map.of( OptionalLong.class.getName(), Long.class.getName(), diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java b/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java index f6a585cd0bef0..ddd722a0e3254 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java @@ -145,6 +145,9 @@ public void doProcess(Set annotations, RoundEnvironment r trackAnnotationUsed(Constants.ANNOTATION_RECORDER); processRecorder(roundEnv, annotation); break; + case Constants.ANNOTATION_CONFIG_MAPPING: + trackAnnotationUsed(Constants.ANNOTATION_CONFIG_MAPPING); + break; } } } @@ -257,7 +260,7 @@ public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) try { if (generateDocs) { final Set outputs = configDocItemScanner - .scanExtensionsConfigurationItems(javaDocProperties); + .scanExtensionsConfigurationItems(javaDocProperties, isAnnotationUsed(ANNOTATION_CONFIG_MAPPING)); for (ConfigDocGeneratedOutput output : outputs) { DocGeneratorUtil.sort(output.getConfigDocItems()); // sort before writing configDocWriter.writeAllExtensionConfigDocumentation(output); diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java b/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java index 589085573f4d5..004ecae8dfbaa 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemFinder.java @@ -75,15 +75,18 @@ class ConfigDocItemFinder { private final Map configGroupQualifiedNameToTypeElementMap; private final FsMap allConfigurationGroups; private final FsMap allConfigurationRoots; + private final boolean configMapping; public ConfigDocItemFinder(Set configRoots, Map configGroupQualifiedNameToTypeElementMap, - Properties javaDocProperties, FsMap allConfigurationGroups, FsMap allConfigurationRoots) { + Properties javaDocProperties, FsMap allConfigurationGroups, FsMap allConfigurationRoots, + boolean configMapping) { this.configRoots = configRoots; this.configGroupQualifiedNameToTypeElementMap = configGroupQualifiedNameToTypeElementMap; this.javaDocProperties = javaDocProperties; this.allConfigurationGroups = allConfigurationGroups; this.allConfigurationRoots = allConfigurationRoots; + this.configMapping = configMapping; } /** @@ -97,7 +100,7 @@ ScannedConfigDocsItemHolder findInMemoryConfigurationItems() throws IOException ConfigPhase buildTime = ConfigPhase.BUILD_TIME; final List configDocItems = recursivelyFindConfigItems(entry.getValue(), EMPTY, EMPTY, buildTime, false, 1, - false); + false, configMapping); allConfigurationGroups.put(entry.getKey(), OBJECT_MAPPER.writeValueAsString(configDocItems)); } @@ -107,7 +110,7 @@ ScannedConfigDocsItemHolder findInMemoryConfigurationItems() throws IOException String rootName = configRootInfo.getName(); ConfigPhase configPhase = configRootInfo.getConfigPhase(); final List configDocItems = recursivelyFindConfigItems(element, rootName, rootName, configPhase, - false, sectionLevel, true); + false, sectionLevel, true, configMapping); holder.addConfigRootItems(configRootInfo, configDocItems); allConfigurationRoots.put(configRootInfo.getClazz().toString(), OBJECT_MAPPER.writeValueAsString(configDocItems)); } @@ -119,7 +122,8 @@ ScannedConfigDocsItemHolder findInMemoryConfigurationItems() throws IOException * Recursively find config item found in a config root or config group given as {@link Element} */ private List recursivelyFindConfigItems(Element element, String rootName, String parentName, - ConfigPhase configPhase, boolean withinAMap, int sectionLevel, boolean generateSeparateConfigGroupDocsFiles) + ConfigPhase configPhase, boolean withinAMap, int sectionLevel, boolean generateSeparateConfigGroupDocsFiles, + boolean configMapping) throws JsonProcessingException { List configDocItems = new ArrayList<>(); TypeElement asTypeElement = (TypeElement) element; @@ -138,7 +142,8 @@ private List recursivelyFindConfigItems(Element element, String r if (rawConfigItems == null) { // element not yet scanned Element superElement = ((DeclaredType) superType).asElement(); superTypeConfigItems = recursivelyFindConfigItems(superElement, rootName, parentName, - configPhase, withinAMap, sectionLevel, generateSeparateConfigGroupDocsFiles); + configPhase, withinAMap, sectionLevel, generateSeparateConfigGroupDocsFiles, + configMapping); } else { superTypeConfigItems = OBJECT_MAPPER.readValue(rawConfigItems, LIST_OF_CONFIG_ITEMS_TYPE_REF); } @@ -148,7 +153,7 @@ private List recursivelyFindConfigItems(Element element, String r } for (Element enclosedElement : element.getEnclosedElements()) { - if (!shouldProcessElement(enclosedElement)) { + if (!shouldProcessElement(enclosedElement, configMapping)) { continue; } @@ -262,7 +267,7 @@ private List recursivelyFindConfigItems(Element element, String r if (isConfigGroup(type)) { List groupConfigItems = readConfigGroupItems(configPhase, rootName, name, emptyList(), type, - configSection, withinAMap, generateSeparateConfigGroupDocsFiles); + configSection, withinAMap, generateSeparateConfigGroupDocsFiles, configMapping); DocGeneratorUtil.appendConfigItemsIntoExistingOnes(configDocItems, groupConfigItems); } else { final ConfigDocKey configDocKey = new ConfigDocKey(); @@ -293,7 +298,8 @@ private List recursivelyFindConfigItems(Element element, String r additionalNames = emptyList(); } List groupConfigItems = readConfigGroupItems(configPhase, rootName, name, - additionalNames, type, configSection, true, generateSeparateConfigGroupDocsFiles); + additionalNames, type, configSection, true, generateSeparateConfigGroupDocsFiles, + configMapping); DocGeneratorUtil.appendConfigItemsIntoExistingOnes(configDocItems, groupConfigItems); continue; } else { @@ -320,7 +326,7 @@ private List recursivelyFindConfigItems(Element element, String r configSection.setOptional(true); List groupConfigItems = readConfigGroupItems(configPhase, rootName, name, emptyList(), typeInString, configSection, withinAMap, - generateSeparateConfigGroupDocsFiles); + generateSeparateConfigGroupDocsFiles, configMapping); DocGeneratorUtil.appendConfigItemsIntoExistingOnes(configDocItems, groupConfigItems); continue; } else if ((typeInString.startsWith(List.class.getName()) @@ -424,11 +430,15 @@ private boolean isConfigGroup(String type) { return configGroupQualifiedNameToTypeElementMap.containsKey(type) || allConfigurationGroups.hasKey(type); } - private boolean shouldProcessElement(final Element enclosedElement) { + private boolean shouldProcessElement(final Element enclosedElement, final boolean configMapping) { if (enclosedElement.getKind().isField()) { return true; } + if (!configMapping && enclosedElement.getKind() == ElementKind.METHOD) { + return false; + } + // A ConfigMapping method if (enclosedElement.getKind().equals(ElementKind.METHOD)) { ExecutableElement method = (ExecutableElement) enclosedElement; @@ -537,7 +547,8 @@ private List readConfigGroupItems( String configGroup, ConfigDocSection configSection, boolean withinAMap, - boolean generateSeparateConfigGroupDocs) + boolean generateSeparateConfigGroupDocs, + boolean configMapping) throws JsonProcessingException { configSection.setConfigGroupType(configGroup); @@ -557,7 +568,7 @@ private List readConfigGroupItems( } else { TypeElement configGroupTypeElement = configGroupQualifiedNameToTypeElementMap.get(configGroup); groupConfigItems = recursivelyFindConfigItems(configGroupTypeElement, EMPTY, EMPTY, configPhase, - false, 1, generateSeparateConfigGroupDocs); + false, 1, generateSeparateConfigGroupDocs, configMapping); allConfigurationGroups.put(configGroup, OBJECT_MAPPER.writeValueAsString(groupConfigItems)); } diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemScanner.java b/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemScanner.java index 317b7767864fc..4881cf3e87478 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemScanner.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/generate_doc/ConfigDocItemScanner.java @@ -118,12 +118,12 @@ public void addConfigRoot(final PackageElement pkg, TypeElement clazz) { } } - public Set scanExtensionsConfigurationItems(Properties javaDocProperties) + public Set scanExtensionsConfigurationItems(Properties javaDocProperties, boolean configMapping) throws IOException { Set configDocGeneratedOutputs = new HashSet<>(); final ConfigDocItemFinder configDocItemFinder = new ConfigDocItemFinder(configRoots, configGroupsToTypeElement, - javaDocProperties, allConfigGroupGeneratedDocs, allExtensionGeneratedDocs); + javaDocProperties, allConfigGroupGeneratedDocs, allExtensionGeneratedDocs, configMapping); final ScannedConfigDocsItemHolder inMemoryScannedItemsHolder = configDocItemFinder.findInMemoryConfigurationItems(); if (!inMemoryScannedItemsHolder.isEmpty()) { From c79064408c6e448bb309ded0103503028a1301ea Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 29 Aug 2023 16:18:11 +0200 Subject: [PATCH 08/32] Add some missing @ConfigItem annotations Noticed while working on another approach to fix #35594. (cherry picked from commit 8dc17544fd2f7ad640976bc2464aad9e48fa90bf) --- .../azure/functions/deployment/AzureFunctionsConfig.java | 5 +++++ .../container/image/docker/deployment/DockerConfig.java | 1 + .../openshift/deployment/ContainerImageOpenshiftConfig.java | 1 + .../orm/deployment/HibernateOrmConfigPersistenceUnit.java | 3 +++ .../io/quarkus/kubernetes/deployment/AutoScalingConfig.java | 6 ++++++ .../kubernetes/deployment/GlobalAutoScalingConfig.java | 5 +++++ .../io/quarkus/kubernetes/deployment/KnativeConfig.java | 2 ++ .../openapi/common/deployment/SmallRyeOpenApiConfig.java | 1 + 8 files changed, 24 insertions(+) diff --git a/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsConfig.java b/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsConfig.java index 049684836a21d..7e324cbee2d0b 100644 --- a/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsConfig.java +++ b/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsConfig.java @@ -70,6 +70,7 @@ public class AzureFunctionsConfig { /** * Specifies the instrumentation key of application insights which will bind to your function app */ + @ConfigItem public Optional appInsightsKey; public RuntimeConfig runtime; @@ -85,15 +86,18 @@ public class AzureFunctionsConfig { /** * */ + @ConfigItem public Optional appServicePlanResourceGroup; /** * Azure subscription id. Required only if there are more than one subscription in your account */ + @ConfigItem public Optional subscriptionId; /** * */ + @ConfigItem public Optional pricingTier; /** @@ -233,6 +237,7 @@ public static class AuthConfig { /** * Filesystem path to properties file if using file type */ + @ConfigItem public Optional path; /** diff --git a/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerConfig.java b/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerConfig.java index fa13ce661509e..cf06381a8aca5 100644 --- a/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerConfig.java +++ b/extensions/container-image/container-image-docker/deployment/src/main/java/io/quarkus/container/image/docker/deployment/DockerConfig.java @@ -49,6 +49,7 @@ public class DockerConfig { /** * The networking mode for the RUN instructions during build */ + @ConfigItem public Optional network; /** diff --git a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/ContainerImageOpenshiftConfig.java b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/ContainerImageOpenshiftConfig.java index d2adf4fe379ff..bf92f1a9d4451 100644 --- a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/ContainerImageOpenshiftConfig.java +++ b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/ContainerImageOpenshiftConfig.java @@ -132,6 +132,7 @@ public static String getDefaultJvmImage(CompiledJavaVersionBuildItem.JavaVersion * The image push secret to use for pushing to external registries. * (see: https://cloud.redhat.com/blog/pushing-application-images-to-an-external-registry) **/ + @ConfigItem public Optional imagePushSecret; /** diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java index 7462c4b1308c9..be2da22d14f81 100644 --- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java +++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java @@ -28,12 +28,14 @@ public class HibernateOrmConfigPersistenceUnit { *

* If undefined, it will use the default datasource. */ + @ConfigItem @ConvertWith(TrimmedStringConverter.class) public Optional datasource; /** * The packages in which the entities affected to this persistence unit are located. */ + @ConfigItem @ConvertWith(TrimmedStringConverter.class) public Optional> packages; @@ -195,6 +197,7 @@ public class HibernateOrmConfigPersistenceUnit { /** * Caching configuration */ + @ConfigItem @ConfigDocSection public Map cache; diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AutoScalingConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AutoScalingConfig.java index 303eb62c0a330..00ca52ebb69c1 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AutoScalingConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AutoScalingConfig.java @@ -4,6 +4,7 @@ import java.util.Optional; import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; @ConfigGroup public class AutoScalingConfig { @@ -16,6 +17,7 @@ public class AutoScalingConfig { * * @return The autoscaler class. */ + @ConfigItem Optional autoScalerClass; /** @@ -24,6 +26,7 @@ public class AutoScalingConfig { * * @return The cpu metric or NONE if no metric has been selected. */ + @ConfigItem Optional metric; /** @@ -31,6 +34,7 @@ public class AutoScalingConfig { * * @return the selected target or zero if no target is selected. */ + @ConfigItem Optional target; /** @@ -39,10 +43,12 @@ public class AutoScalingConfig { * * @return the container concurrency, or zero if it is not bound. */ + @ConfigItem Optional containerConcurrency; /** * This value specifies a percentage of the target to actually be targeted by the autoscaler. */ + @ConfigItem Optional targetUtilizationPercentage; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/GlobalAutoScalingConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/GlobalAutoScalingConfig.java index 1ad74874d6a0b..766b8cf83e596 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/GlobalAutoScalingConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/GlobalAutoScalingConfig.java @@ -3,6 +3,7 @@ import java.util.Optional; import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; @ConfigGroup public class GlobalAutoScalingConfig { @@ -15,6 +16,7 @@ public class GlobalAutoScalingConfig { * * @return The autoscaler class. */ + @ConfigItem Optional autoScalerClass; /** @@ -25,16 +27,19 @@ public class GlobalAutoScalingConfig { * concurrency: Hard Limit * @return the container concurrency, or zero if it is not bound. */ + @ConfigItem Optional containerConcurrency; /** * This value specifies a percentage of the target to actually be targeted by the autoscaler. */ + @ConfigItem Optional targetUtilizationPercentage; /** * The requests per second per replica. */ + @ConfigItem Optional requestsPerSecond; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java index 1b5d5e135ff74..ed5c47c786952 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeConfig.java @@ -484,11 +484,13 @@ public EnvVarsConfig getEnv() { /** * The name of the revision. */ + @ConfigItem Optional revisionName; /** * Traffic configuration. */ + @ConfigItem Map traffic; /** diff --git a/extensions/smallrye-openapi-common/deployment/src/main/java/io/quarkus/smallrye/openapi/common/deployment/SmallRyeOpenApiConfig.java b/extensions/smallrye-openapi-common/deployment/src/main/java/io/quarkus/smallrye/openapi/common/deployment/SmallRyeOpenApiConfig.java index 59c333fc96e20..087b9dc7cf1cf 100644 --- a/extensions/smallrye-openapi-common/deployment/src/main/java/io/quarkus/smallrye/openapi/common/deployment/SmallRyeOpenApiConfig.java +++ b/extensions/smallrye-openapi-common/deployment/src/main/java/io/quarkus/smallrye/openapi/common/deployment/SmallRyeOpenApiConfig.java @@ -54,6 +54,7 @@ public final class SmallRyeOpenApiConfig { /** * Add a certain SecurityScheme with config */ + @ConfigItem public Optional securityScheme; /** From a5aaca495d9cb5316f5937bf106ab470c393bba4 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 29 Aug 2023 17:43:27 +0100 Subject: [PATCH 09/32] Show JWE encrypted token parts in DevUI (cherry picked from commit 446e61b811a640cbc93f0a14b69c5c0f994666ee) --- .../resources/dev-ui/qwc-oidc-provider.js | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js index de8ab3e90fb6b..94068863faa89 100644 --- a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js +++ b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js @@ -208,13 +208,16 @@ export class QwcOidcProvider extends QwcHotReloadElement { .decoded-token pre { white-space: break-spaces; } - .token-success { + .token-payload { color: var(--lumo-success-color); } - .token-danger { + .token-headers { color: var(--lumo-error-color); } - .token-primary { + .token-signature { + color: var(--quarkus-blue); + } + .token-encryption { color: var(--quarkus-blue); } .margin-top-space-m { @@ -1150,8 +1153,21 @@ export class QwcOidcProvider extends QwcHotReloadElement { const signature = parts[2]?.trim(); return html` - ${headers}.${payload}.${signature} + ${headers}.${payload}.${signature} + `; + } else if (parts.length === 5) { + const headers = parts[0]?.trim(); + const encryptedKey = parts[1]?.trim(); + const initVector = parts[2]?.trim(); + const ciphertext = parts[3]?.trim(); + const authTag = parts[4]?.trim(); + + return html` + ${headers}.${encryptedKey}.${initVector}.${ciphertext}.${authTag} `; } else { return html`${token}`; @@ -1169,10 +1185,24 @@ export class QwcOidcProvider extends QwcHotReloadElement { const signature = parts[2]; const jsonPayload = JSON.parse(payload); return html` -

${JSON.stringify(JSON.parse(headers), null, 4)?.trim()}
-
${JSON.stringify(jsonPayload,null,4)?.trim()}
- ${signature?.trim()} +
${JSON.stringify(JSON.parse(headers), null, 4)?.trim()}
+
${JSON.stringify(jsonPayload,null,4)?.trim()}
+- ${signature?.trim()} `; + } else if (parts.length === 5) { + const headers = window.atob(parts[0]?.trim()); + const encryptedKey = parts[1]?.trim(); + const initVector = parts[2]?.trim(); + const ciphertext = parts[3]?.trim(); + const authTag = parts[4]?.trim(); + + return html` +
${JSON.stringify(JSON.parse(headers), null, 4)?.trim()}
+
${encryptedKey}
+
${initVector}
+
${ciphertext}
+ ${authTag} + `; } else { return html`${token}`; } From e1194feb81174ed0b7471bc0d07ef789959da55e Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 29 Aug 2023 18:10:06 +0100 Subject: [PATCH 10/32] Pass client_id in Dev UI logout request (cherry picked from commit 0e1af3d78625bb3c33b2c92cf9b2e554fb223b70) --- .../deployment/src/main/resources/dev-ui/qwc-oidc-provider.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js index 94068863faa89..d1fbd800b7880 100644 --- a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js +++ b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js @@ -1131,6 +1131,7 @@ export class QwcOidcProvider extends QwcHotReloadElement { _logout() { localStorage.removeItem('authorized'); + const clientId = this._getClientId(); let address; if (propertiesState.keycloakAdminUrl && this._selectedRealm) { @@ -1141,7 +1142,8 @@ export class QwcOidcProvider extends QwcHotReloadElement { window.location.assign(address + '?' + (propertiesState.postLogoutUriParam ?? '') + '=' + this._getEncodedPath() - + '&id_token_hint=' + propertiesState.idToken); + + '&id_token_hint=' + propertiesState.idToken + + "&client_id=" + clientId); } static _prettyToken(token){ From 5479432d1e44101d22ce5d2099f9879898762fe1 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Tue, 29 Aug 2023 11:30:20 +0300 Subject: [PATCH 11/32] Add support for Podman auth file in Jib Fixes: #35609 (cherry picked from commit b3b27d8b559cab8e44068457c734de0c40764323) --- .../container/image/jib/deployment/JibProcessor.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java b/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java index 2d79781a403c1..e3c35da63d1cd 100644 --- a/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java +++ b/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java @@ -362,6 +362,17 @@ private RegistryImage toRegistryImage(ImageReference imageReference, Optional Date: Mon, 28 Aug 2023 14:03:25 +0200 Subject: [PATCH 12/32] Bump Gradle to 8.3 (cherry picked from commit 07921656398aae0c4efe1f116f5624590dea5ec4) --- 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 80c16c35ccd4f..65d157702b346 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -64,7 +64,7 @@ 3.9.3 3.2.0 - 8.1.1 + 8.3 ${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 733c0c7955fdb..0cadd3945ae5a 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=5625a0ae20fe000d9225d000b36909c7a0e0e8dda61c19b12da769add847c975 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip +distributionSha256Sum=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-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 7af9276785053..37f1c47dec6f6 100644 --- a/independent-projects/bootstrap/pom.xml +++ b/independent-projects/bootstrap/pom.xml @@ -77,7 +77,7 @@ 3.5.1 2.1.0 1.3.2 - 8.1.1 + 8.3 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 f9c1fa44b1eda..d5a6bf64cd3a3 100644 --- a/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json +++ b/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json @@ -388,7 +388,7 @@ "supported-maven-versions": "[3.6.2,)", "proposed-maven-version": "3.8.8", "maven-wrapper-version": "3.2.0", - "gradle-wrapper-version": "8.1.1" + "gradle-wrapper-version": "8.3" } }, "codestarts-artifacts": [ diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml index aae4bd09b0cee..c0929488b8451 100644 --- a/independent-projects/tools/pom.xml +++ b/independent-projects/tools/pom.xml @@ -42,7 +42,7 @@ 3.9.3 3.2.0 - 8.1.1 + 8.3 3.11.0 diff --git a/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties b/integration-tests/gradle/gradle/wrapper/gradle-wrapper.properties index 733c0c7955fdb..0cadd3945ae5a 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=5625a0ae20fe000d9225d000b36909c7a0e0e8dda61c19b12da769add847c975 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip +distributionSha256Sum=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From f23f04826db7ed0a1bf9b096e4e9a860a63ecb35 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 30 Aug 2023 08:29:11 +0200 Subject: [PATCH 13/32] Hibernate Reactive Panache: fix WithSessionOnDemand implementation - fixes #35568 (cherry picked from commit 0d1ae5ead98312ea602c2b536e5ad451e44f7664) --- .../common/runtime/SessionOperations.java | 14 ++++-- .../deployment/pom.xml | 5 ++ .../panache/test/WithSessionOnDemandTest.java | 46 +++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 extensions/panache/hibernate-reactive-panache/deployment/src/test/java/io/quarkus/hibernate/reactive/panache/test/WithSessionOnDemandTest.java diff --git a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java index 99c15a8691d11..6c18c85066417 100644 --- a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java +++ b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java @@ -49,6 +49,7 @@ public Key get() { // This key is used to indicate that a reactive session should be opened lazily (when needed) in the current vertx context private static final String SESSION_ON_DEMAND_KEY = "hibernate.reactive.panache.sessionOnDemand"; + private static final String SESSION_ON_DEMAND_OPENED_KEY = "hibernate.reactive.panache.sessionOnDemandOpened"; /** * Marks the current vertx duplicated context as "lazy" which indicates that a reactive session should be opened lazily if @@ -70,6 +71,7 @@ static Uni withSessionOnDemand(Supplier> work) { // perform the work and eventually close the session and remove the key return work.get().eventually(() -> { context.removeLocal(SESSION_ON_DEMAND_KEY); + context.removeLocal(SESSION_ON_DEMAND_OPENED_KEY); return closeSession(); }); } @@ -148,9 +150,15 @@ public static Uni getSession() { return Uni.createFrom().item(current); } else { if (context.getLocal(SESSION_ON_DEMAND_KEY) != null) { - // open a new reactive session and store it in the vertx duplicated context - // the context was marked as "lazy" which means that the session will be eventually closed - return getSessionFactory().openSession().invoke(s -> context.putLocal(key, s)); + if (context.getLocal(SESSION_ON_DEMAND_OPENED_KEY) != null) { + // a new reactive session is opened in a previous stage + return Uni.createFrom().item(() -> getCurrentSession()); + } else { + // open a new reactive session and store it in the vertx duplicated context + // the context was marked as "lazy" which means that the session will be eventually closed + context.putLocal(SESSION_ON_DEMAND_OPENED_KEY, true); + return getSessionFactory().openSession().invoke(s -> context.putLocal(key, s)); + } } else { throw new IllegalStateException("No current Mutiny.Session found" + "\n\t- no reactive session was found in the context and the context was not marked to open a new session lazily" diff --git a/extensions/panache/hibernate-reactive-panache/deployment/pom.xml b/extensions/panache/hibernate-reactive-panache/deployment/pom.xml index 6e7f2b66cb6c2..0282b59e06f11 100644 --- a/extensions/panache/hibernate-reactive-panache/deployment/pom.xml +++ b/extensions/panache/hibernate-reactive-panache/deployment/pom.xml @@ -35,6 +35,11 @@ quarkus-junit5-internal test + + io.quarkus + quarkus-test-hibernate-reactive-panache + test + io.quarkus quarkus-reactive-pg-client-deployment diff --git a/extensions/panache/hibernate-reactive-panache/deployment/src/test/java/io/quarkus/hibernate/reactive/panache/test/WithSessionOnDemandTest.java b/extensions/panache/hibernate-reactive-panache/deployment/src/test/java/io/quarkus/hibernate/reactive/panache/test/WithSessionOnDemandTest.java new file mode 100644 index 0000000000000..e86ae99de555e --- /dev/null +++ b/extensions/panache/hibernate-reactive-panache/deployment/src/test/java/io/quarkus/hibernate/reactive/panache/test/WithSessionOnDemandTest.java @@ -0,0 +1,46 @@ +package io.quarkus.hibernate.reactive.panache.test; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import org.hibernate.reactive.mutiny.Mutiny.Session; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.Unremovable; +import io.quarkus.hibernate.reactive.panache.Panache; +import io.quarkus.hibernate.reactive.panache.common.WithSessionOnDemand; +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.test.vertx.RunOnVertxContext; +import io.quarkus.test.vertx.UniAsserter; +import io.smallrye.mutiny.Uni; + +public class WithSessionOnDemandTest { + + @RegisterExtension + static QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot(root -> root.addClasses(MrBean.class, MyEntity.class)); + + @Inject + MrBean bean; + + @RunOnVertxContext + @Test + public void testSharedSession(UniAsserter asserter) { + asserter.assertEquals(() -> bean.ping(), "true"); + } + + @Unremovable + @ApplicationScoped + static class MrBean { + + @WithSessionOnDemand + Uni ping() { + Uni s1 = Panache.getSession(); + Uni s2 = Panache.getSession(); + // Test that both unis receive the same session + return s1.chain(s1Val -> s2.map(s2Val -> "" + (s1Val == s2Val))); + } + + } +} From d2b337b00b92004a0def8913a08b197439d59030 Mon Sep 17 00:00:00 2001 From: Phillip Kruger Date: Wed, 30 Aug 2023 12:25:29 +1000 Subject: [PATCH 14/32] Fix dev ui css Signed-off-by: Phillip Kruger (cherry picked from commit 7f8e6124f9968bcfa81daebdf95538c0b07704e8) --- .../src/main/resources/dev-ui-templates/build-time/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui-templates/build-time/index.html b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui-templates/build-time/index.html index d4535e3ddd931..8116f44ae7912 100644 --- a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui-templates/build-time/index.html +++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui-templates/build-time/index.html @@ -28,7 +28,7 @@ height: 100vh; font-family: var(--lumo-font-family); font-size: var(--lumo-font-size-m); - line-height: var(--lumo-line-height-m): + line-height: var(--lumo-line-height-m); overflow: hidden; display: flex; flex-direction: column; From 9c75237b4054fbc1dddc4cf02ae89ee2fda2c741 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Tue, 29 Aug 2023 12:54:38 +0200 Subject: [PATCH 15/32] ArC: fix binary compatibility problem with ManagedContext - follow-up to #34310 (cherry picked from commit 335651b2f741c8f65ef181b0e0fde9db5fa6fde4) --- independent-projects/arc/pom.xml | 1 + independent-projects/arc/runtime/pom.xml | 19 +++++++++++++++++++ .../java/io/quarkus/arc/ManagedContext.java | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/independent-projects/arc/pom.xml b/independent-projects/arc/pom.xml index 945a1764650c5..eb2d5310fe24a 100644 --- a/independent-projects/arc/pom.xml +++ b/independent-projects/arc/pom.xml @@ -51,6 +51,7 @@ 3.1.2 3.5.1.Final 2.2.0 + 1.6.Final 3.24.2 5.9.3 diff --git a/independent-projects/arc/runtime/pom.xml b/independent-projects/arc/runtime/pom.xml index c8e62a8ab7ec4..91061affda06c 100644 --- a/independent-projects/arc/runtime/pom.xml +++ b/independent-projects/arc/runtime/pom.xml @@ -47,5 +47,24 @@ + + + + + org.jboss.bridger + bridger + ${version.bridger} + + + weave + process-classes + + transform + + + + + + diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ManagedContext.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ManagedContext.java index 4e7037255e73f..69e7d09cbc08c 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ManagedContext.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/ManagedContext.java @@ -17,6 +17,11 @@ default ContextState activate() { return activate(null); } + // Maintain binary compatibility with Quarkus 3.2 + default void activate$$bridge() { + activate(null); + } + /** * Activate the context. *

@@ -28,6 +33,11 @@ default ContextState activate() { */ ContextState activate(ContextState initialState); + // Maintain binary compatibility with Quarkus 3.2 + default void activate$$bridge(ContextState initialState) { + activate(initialState); + } + /** * Deactivate the context - do not destoy existing contextual instances. */ From 0c63069d9f13bc6b1da83ebcad5e0066dd2991cb Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Wed, 30 Aug 2023 09:39:41 -0500 Subject: [PATCH 16/32] Preserve format style when adding after-shutdown message (cherry picked from commit 46d460d3177855bdf5d8dfd1f0fbf17e05de5b28) --- .../java/io/quarkus/runtime/logging/LogCleanupFilter.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/runtime/src/main/java/io/quarkus/runtime/logging/LogCleanupFilter.java b/core/runtime/src/main/java/io/quarkus/runtime/logging/LogCleanupFilter.java index 7f60c667dc50d..8d94f2a78160c 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/logging/LogCleanupFilter.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/logging/LogCleanupFilter.java @@ -8,6 +8,7 @@ import java.util.logging.LogRecord; import org.jboss.logging.Logger; +import org.jboss.logmanager.ExtLogRecord; public class LogCleanupFilter implements Filter { @@ -30,7 +31,12 @@ public boolean isLoggable(LogRecord record) { //we also use this filter to add a warning about errors generated after shutdown if (record.getLevel().intValue() >= org.jboss.logmanager.Level.ERROR.intValue() && shutdownNotifier.shutdown) { if (!record.getMessage().endsWith(SHUTDOWN_MESSAGE)) { - record.setMessage(record.getMessage() + SHUTDOWN_MESSAGE); + if (record instanceof ExtLogRecord) { + ExtLogRecord elr = (ExtLogRecord) record; + elr.setMessage(record.getMessage() + SHUTDOWN_MESSAGE, elr.getFormatStyle()); + } else { + record.setMessage(record.getMessage() + SHUTDOWN_MESSAGE); + } } } // Only allow filtering messages of warning level and lower From 3517d9b71b78770806251fa34cfa1420c267663c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 30 Aug 2023 12:53:04 +0200 Subject: [PATCH 17/32] Refactor Hibernate config mapping to use groups instead of dotted names (take 2) Follows up on commit ad94afb (cherry picked from commit 651d391d6925e778c9800d767d556e7c5f271549) --- .../orm/deployment/HibernateOrmConfig.java | 22 +++++++++--- .../HibernateOrmConfigPersistenceUnit.java | 36 +++++++++++++------ .../orm/deployment/HibernateOrmProcessor.java | 10 +++--- .../metrics/HibernateOrmMetricsProcessor.java | 2 +- .../HibernateReactiveProcessor.java | 10 +++--- 5 files changed, 55 insertions(+), 25 deletions(-) diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java index a342c1a770ffa..e2be11c863d71 100644 --- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java +++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java @@ -79,10 +79,10 @@ public class HibernateOrmConfig { public Optional logSessionMetrics; /** - * Whether metrics are published if a metrics extension is enabled. + * Configuration related to metrics. */ - @ConfigItem(name = "metrics.enabled") - public boolean metricsEnabled; + @ConfigItem + public HibernateOrmConfigMetric metrics; public boolean isAnyNonPersistenceXmlPropertySet() { // Do NOT include persistenceXml in here. @@ -91,7 +91,7 @@ public boolean isAnyNonPersistenceXmlPropertySet() { log.isAnyPropertySet() || statistics.isPresent() || logSessionMetrics.isPresent() || - metricsEnabled; + metrics.isAnyPropertySet(); } public Map getAllPersistenceUnitConfigsAsMap() { @@ -170,4 +170,18 @@ public static class HibernateOrmConfigDatabase { public DatabaseOrmCompatibilityVersion ormCompatibilityVersion; } + @ConfigGroup + public static class HibernateOrmConfigMetric { + + /** + * Whether metrics are published if a metrics extension is enabled. + */ + @ConfigItem + public boolean enabled; + + public boolean isAnyPropertySet() { + return enabled; + } + } + } diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java index be2da22d14f81..f87622b5957a0 100644 --- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java +++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java @@ -209,15 +209,10 @@ public class HibernateOrmConfigPersistenceUnit { public HibernateOrmConfigPersistenceUnitDiscriminator discriminator; /** - * Identifiers can be quoted using one of the available strategies. - *

- * Set to {@code none} by default, meaning no identifiers will be quoted. If set to {@code all}, all identifiers and column - * definitions will be quoted. Additionally, setting it to {@code all-except-column-definitions} will skip the column - * definitions, which can usually be required when they exist, or else use the option {@code only-keywords} to quote only - * identifiers deemed SQL keywords by the Hibernate ORM dialect. + * Config related to identifier quoting. */ - @ConfigItem(defaultValue = "none", name = "quote-identifiers.strategy") - public IdentifierQuotingStrategy identifierQuotingStrategy; + @ConfigItem(defaultValue = "none") + public HibernateOrmConfigPersistenceUnitQuoteIdentifiers quoteIdentifiers; /** * The default in Quarkus is for 2nd level caching to be enabled, @@ -288,7 +283,7 @@ public boolean isAnyPropertySet() { multitenantSchemaDatasource.isPresent() || fetch.isAnyPropertySet() || discriminator.isAnyPropertySet() || - identifierQuotingStrategy != IdentifierQuotingStrategy.NONE || + quoteIdentifiers.isAnyPropertySet() || !unsupportedProperties.isEmpty(); } @@ -550,7 +545,7 @@ public static class HibernateOrmConfigPersistenceUnitDatabase { /** * Whether Hibernate should quote all identifiers. * - * @deprecated {@link #identifierQuotingStrategy} should be used to configure quoting strategy. + * @deprecated {@link #quoteIdentifiers} should be used to configure quoting strategy. */ @ConfigItem @Deprecated @@ -652,6 +647,27 @@ public boolean isAnyPropertySet() { } + @ConfigGroup + public static class HibernateOrmConfigPersistenceUnitQuoteIdentifiers { + + /** + * Identifiers can be quoted using one of the available strategies. + *

+ * Set to {@code none} by default, meaning no identifiers will be quoted. If set to {@code all}, all identifiers and + * column + * definitions will be quoted. Additionally, setting it to {@code all-except-column-definitions} will skip the column + * definitions, which can usually be required when they exist, or else use the option {@code only-keywords} to quote + * only + * identifiers deemed SQL keywords by the Hibernate ORM dialect. + */ + @ConfigItem(defaultValue = "none") + public IdentifierQuotingStrategy strategy; + + public boolean isAnyPropertySet() { + return strategy != IdentifierQuotingStrategy.NONE; + } + } + /** * Discriminator configuration. * 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 a2117baab9210..cd4fa7da36329 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 @@ -966,15 +966,15 @@ private static void producePersistenceUnitDescriptorFromConfig( persistenceUnitConfig.database.charset.name()); // Quoting strategy - if (persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ALL - || persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS + if (persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ALL + || persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS || persistenceUnitConfig.database.globallyQuotedIdentifiers) { descriptor.getProperties().setProperty(AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, "true"); } - if (persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS) { + if (persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS) { descriptor.getProperties().setProperty( AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS_SKIP_COLUMN_DEFINITIONS, "true"); - } else if (persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ONLY_KEYWORDS) { + } else if (persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ONLY_KEYWORDS) { descriptor.getProperties().setProperty(AvailableSettings.KEYWORD_AUTO_QUOTING_ENABLED, "true"); } @@ -1019,7 +1019,7 @@ private static void producePersistenceUnitDescriptorFromConfig( String.valueOf(fetchSize))); // Statistics - if (hibernateOrmConfig.metricsEnabled + if (hibernateOrmConfig.metrics.enabled || (hibernateOrmConfig.statistics.isPresent() && hibernateOrmConfig.statistics.get())) { descriptor.getProperties().setProperty(AvailableSettings.GENERATE_STATISTICS, "true"); //When statistics are enabled, the default in Hibernate ORM is to also log them after each diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/metrics/HibernateOrmMetricsProcessor.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/metrics/HibernateOrmMetricsProcessor.java index de04d1dc662a4..155c09b7e3957 100644 --- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/metrics/HibernateOrmMetricsProcessor.java +++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/metrics/HibernateOrmMetricsProcessor.java @@ -33,7 +33,7 @@ public void metrics(HibernateOrmConfig config, // IF Hibernate metrics and Hibernate statistics are enabled // then define a consumer. It will only be invoked if metrics is enabled - if (config.metricsEnabled && config.statistics.orElse(true) && metricsConfiguration.isPresent()) { + if (config.metrics.enabled && config.statistics.orElse(true) && metricsConfiguration.isPresent()) { datasourceMetrics.produce(new MetricsFactoryConsumerBuildItem(metricsRecorder.consumeMetricsFactory())); } } diff --git a/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java b/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java index a6ac9c7e45224..9dff2f96a0122 100644 --- a/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java +++ b/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java @@ -303,14 +303,14 @@ private static ParsedPersistenceXmlDescriptor generateReactivePersistenceUnit( persistenceUnitConfig.database.charset.name()); // Quoting strategy - if (persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ALL - || persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS + if (persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ALL + || persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS || persistenceUnitConfig.database.globallyQuotedIdentifiers) { desc.getProperties().setProperty(AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, "true"); } - if (persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS) { + if (persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ALL_EXCEPT_COLUMN_DEFINITIONS) { desc.getProperties().setProperty(AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS_SKIP_COLUMN_DEFINITIONS, "true"); - } else if (persistenceUnitConfig.identifierQuotingStrategy == IdentifierQuotingStrategy.ONLY_KEYWORDS) { + } else if (persistenceUnitConfig.quoteIdentifiers.strategy == IdentifierQuotingStrategy.ONLY_KEYWORDS) { desc.getProperties().setProperty(AvailableSettings.KEYWORD_AUTO_QUOTING_ENABLED, "true"); } @@ -353,7 +353,7 @@ private static ParsedPersistenceXmlDescriptor generateReactivePersistenceUnit( String.valueOf(statementBatchSize))); // Statistics - if (hibernateOrmConfig.metricsEnabled + if (hibernateOrmConfig.metrics.enabled || (hibernateOrmConfig.statistics.isPresent() && hibernateOrmConfig.statistics.get())) { desc.getProperties().setProperty(AvailableSettings.GENERATE_STATISTICS, "true"); } From 5d29120e5af368a2e3b78c10d486f2b27c578bdb Mon Sep 17 00:00:00 2001 From: Romain LE BARO Date: Wed, 30 Aug 2023 17:03:13 +0200 Subject: [PATCH 18/32] Allow using a servicePath with capital letters when testing with the OIDC provider test Service (cherry picked from commit e4113aa63ea04171ed4c978779945f3f52bacf73) --- .../deployment/src/main/resources/dev-ui/qwc-oidc-provider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js index d1fbd800b7880..6ecb76ad16901 100644 --- a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js +++ b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js @@ -780,7 +780,7 @@ export class QwcOidcProvider extends QwcHotReloadElement { > customSerializationMap = new HashMap<>(); private static final Map> customDeserializationMap = new HashMap<>(); - public void recordJsonView(String methodId, String className) { - jsonViewMap.put(methodId, loadClass(className)); + public void recordJsonView(String targetId, String className) { + jsonViewMap.put(targetId, loadClass(className)); } public void recordCustomSerialization(String target, String className) { @@ -42,6 +42,10 @@ public void run() { }); } + public static Class jsonViewForClass(Class clazz) { + return jsonViewMap.get(clazz.getName()); + } + public static Class jsonViewForMethod(String methodId) { return jsonViewMap.get(methodId); } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java index dab95f4f402be..89dbe47c6d36a 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java @@ -175,6 +175,13 @@ public ObjectReader apply(ObjectMapper objectMapper) { Class jsonViewValue = ResteasyReactiveServerJacksonRecorder.jsonViewForMethod(resourceInfo.getMethodId()); if (jsonViewValue != null) { return effectiveReader.withView(jsonViewValue); + } else { + jsonViewValue = ResteasyReactiveServerJacksonRecorder + .jsonViewForClass(resourceInfo.getResourceClass()); + if (jsonViewValue != null) { + return effectiveReader.withView(jsonViewValue); + } + } } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java index abe3896f9a33d..171b6843fa62d 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java @@ -66,6 +66,13 @@ public void writeResponse(Object o, Type genericType, ServerRequestContext conte Class jsonViewValue = ResteasyReactiveServerJacksonRecorder.jsonViewForMethod(resourceInfo.getMethodId()); if (jsonViewValue != null) { effectiveWriter = effectiveWriter.withView(jsonViewValue); + } else { + jsonViewValue = ResteasyReactiveServerJacksonRecorder + .jsonViewForClass(resourceInfo.getResourceClass()); + if (jsonViewValue != null) { + effectiveWriter = effectiveWriter.withView(jsonViewValue); + } + } } effectiveWriter.writeValue(stream, o); From 6a167ed5e6af618dc6982e56b69c5fd6ec715fab Mon Sep 17 00:00:00 2001 From: Michelle Purcell Date: Wed, 30 Aug 2023 10:56:58 +0100 Subject: [PATCH 20/32] Fix doc link asciidoc change link to xref where applicable (cherry picked from commit a9ddd130bfec9d029d3ab8378a502a7f69cb6051) --- docs/src/main/asciidoc/security-architecture.adoc | 4 ++-- .../src/main/asciidoc/security-authentication-mechanisms.adoc | 4 ++-- .../main/asciidoc/security-basic-authentication-howto.adoc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/main/asciidoc/security-architecture.adoc b/docs/src/main/asciidoc/security-architecture.adoc index f74b2e68a47a2..ef3bcebd2dffa 100644 --- a/docs/src/main/asciidoc/security-architecture.adoc +++ b/docs/src/main/asciidoc/security-architecture.adoc @@ -73,11 +73,11 @@ You can customize the following core security components of Quarkus: * `IdentityProvider` * `SecurityidentityAugmentor` -For more information about customizing Quarkus Security, including reactive security and how to register a security provider, see the Quarkus link:{url-quarkusio-guides}security-customization[Security tips and tricks] guide. +For more information about customizing Quarkus Security, including reactive security and how to register a security provider, see the Quarkus xref:security-customization.adoc[Security tips and tricks] guide. == References * xref:security-overview.adoc[Quarkus Security overview] * xref:security-authentication-mechanisms.adoc#other-supported-authentication-mechanisms[Other supported authentication mechanisms] * xref:security-identity-providers.adoc[Identity providers] -* xref:security-authorize-web-endpoints-reference.adoc[Authorization of web endpoints] \ No newline at end of file +* xref:security-authorize-web-endpoints-reference.adoc[Authorization of web endpoints] diff --git a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc index 5f10459eb9091..0ccbb5e426867 100644 --- a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc +++ b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc @@ -150,7 +150,7 @@ X509Certificate certificate = credential.getCertificate(); The information from the client certificate can be used to enhance Quarkus `SecurityIdentity`. For example, you can add new roles after checking a client certificate subject name, and so on. -For more information about customizing `SecurityIdentity`, see the link:{url-quarkusio-guides}security-customization#security-identity-customization[Security identity customization] section in the Quarkus "Security tips and tricks" guide. +For more information about customizing `SecurityIdentity`, see the xref:security-customization.adoc#security-identity-customization[Security identity customization] section in the Quarkus "Security tips and tricks" guide. [[other-supported-authentication-mechanisms]] == Other supported authentication mechanisms @@ -209,7 +209,7 @@ For more information about OIDC authentication and authorization methods that yo To enable the Quarkus OIDC extension at runtime, set `quarkus.oidc.tenant-enabled=false` at build time. Then re-enable it at runtime by using a system property. -For more information about managing the individual tenant configurations in multitenant OIDC deployments, see the link:{url-quarkusio-guides}security-openid-connect-multitenancy#disable-tenant[Disabling tenant configurations] section in the "Using OpenID Connect (OIDC) multi-tenancy" guide. +For more information about managing the individual tenant configurations in multitenant OIDC deployments, see the xref:security-openid-connect-multitenancy.adoc#disable-tenant[Disabling tenant configurations] section in the "Using OpenID Connect (OIDC) multi-tenancy" guide. ==== ==== OpenID Connect client and filters diff --git a/docs/src/main/asciidoc/security-basic-authentication-howto.adoc b/docs/src/main/asciidoc/security-basic-authentication-howto.adoc index b58298fa1a9f2..2f620a217c871 100644 --- a/docs/src/main/asciidoc/security-basic-authentication-howto.adoc +++ b/docs/src/main/asciidoc/security-basic-authentication-howto.adoc @@ -8,7 +8,7 @@ Enable xref:security-basic-authentication.adoc[Basic authentication] for your Qu == Prerequisites -* You have installed at least one extension that provides an `IdentityProvider` based on username and password, such as link:{url-quarkusio-guides}security-jdbc[Elytron JDBC]. +* You have installed at least one extension that provides an `IdentityProvider` based on username and password, such as xref:security-jdbc.adoc[Elytron JDBC]. == Procedure From 3c7ef7b2590349da1fe9b987a3fe1ca3aea60d4f Mon Sep 17 00:00:00 2001 From: Alexey Loubyansky Date: Wed, 30 Aug 2023 18:58:47 +0200 Subject: [PATCH 21/32] Add plexus version constraints to the bootstrap BOM (cherry picked from commit 98425368e501d7630da4f8f01441a50e8eb75131) --- independent-projects/bootstrap/bom/pom.xml | 12 +++++++++++- independent-projects/bootstrap/pom.xml | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/independent-projects/bootstrap/bom/pom.xml b/independent-projects/bootstrap/bom/pom.xml index 131ccd81e8ff4..b92825c14c595 100644 --- a/independent-projects/bootstrap/bom/pom.xml +++ b/independent-projects/bootstrap/bom/pom.xml @@ -395,10 +395,20 @@ - org.sonatype.plexus + org.codehaus.plexus plexus-cipher ${plexus-cipher.version} + + org.codehaus.plexus + plexus-interpolation + ${plexus-interpolation.version} + + + org.codehaus.plexus + plexus-sec-dispatcher + ${plexus-sec-dispatcher.version} + org.codehaus.plexus plexus-utils diff --git a/independent-projects/bootstrap/pom.xml b/independent-projects/bootstrap/pom.xml index 37f1c47dec6f6..69078422da081 100644 --- a/independent-projects/bootstrap/pom.xml +++ b/independent-projects/bootstrap/pom.xml @@ -73,7 +73,9 @@ 1.7.36 23.0.1 2.6.0 - 1.7 + 2.0 + 1.26 + 2.0 3.5.1 2.1.0 1.3.2 From 3a1b8be85b38f6e512770f711fbe925d297f8c19 Mon Sep 17 00:00:00 2001 From: Roberto Cortez Date: Wed, 30 Aug 2023 18:10:15 +0100 Subject: [PATCH 22/32] Update SmallRye Config to 3.3.4 (cherry picked from commit cea51e42dd7e78f76071b3e1cea59438b1073406) --- 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 4e4e8b76b3179..bed2105755608 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -51,7 +51,7 @@ 2.0 3.1.1 2.1.0 - 3.3.3 + 3.3.4 4.0.4 4.0.0 3.5.1 From 18c2a60934f58310accf4a99affcdc4046df855f Mon Sep 17 00:00:00 2001 From: domkun <1139208+domkun@users.noreply.github.com> Date: Fri, 1 Sep 2023 08:07:37 +0200 Subject: [PATCH 23/32] Fix custom codec registration for more than one codec (cherry picked from commit a6c87e906e7c1b485af665e77631fd32cff9e034) --- .../client/datasource/CustomCodecTest.java | 90 ++++++++++++++----- .../runtime/client/RedisClientRecorder.java | 5 +- 2 files changed, 72 insertions(+), 23 deletions(-) diff --git a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/deployment/client/datasource/CustomCodecTest.java b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/deployment/client/datasource/CustomCodecTest.java index cc5e86c6d0c8b..39b9bd89e77de 100644 --- a/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/deployment/client/datasource/CustomCodecTest.java +++ b/extensions/redis-client/deployment/src/test/java/io/quarkus/redis/deployment/client/datasource/CustomCodecTest.java @@ -28,7 +28,8 @@ public class CustomCodecTest { @RegisterExtension static final QuarkusUnitTest unitTest = new QuarkusUnitTest() .setArchiveProducer( - () -> ShrinkWrap.create(JavaArchive.class).addClass(Jedi.class).addClass(MyCustomCodec.class)) + () -> ShrinkWrap.create(JavaArchive.class).addClass(Jedi.class).addClass(Sith.class) + .addClass(CustomJediCodec.class).addClass(CustomSithCodec.class)) .overrideConfigKey("quarkus.redis.hosts", "${quarkus.redis.tr}"); @Inject @@ -37,28 +38,45 @@ public class CustomCodecTest { @Test void testCustomCodecs() { String key1 = UUID.randomUUID().toString(); - // Check that the codec is registered - assertThat(Codecs.getDefaultCodecFor(Jedi.class)).isInstanceOf(MyCustomCodec.class); - - HashCommands hash1 = ds.hash(Jedi.class); - hash1.hset(key1, "test", new Jedi("luke", "skywalker")); - var retrieved = hash1.hget(key1, "test"); - assertThat(retrieved.firstName).isEqualTo("luke"); - assertThat(retrieved.lastName).isEqualTo("SKYWALKER"); - - HashCommands hash2 = ds.hash(String.class, Jedi.class, String.class); - hash2.hset(key1, new Jedi("luke", "skywalker"), "test"); - var retrieved2 = hash2.hget(key1, new Jedi("luke", "skywalker")); - assertThat(retrieved2).isEqualTo("test"); - - HashCommands hash3 = ds.hash(Jedi.class, String.class, String.class); - hash3.hset(new Jedi("luke", "skywalker"), "key", "value"); - var retrieved3 = hash3.hget(new Jedi("luke", "skywalker"), "key"); - assertThat(retrieved3).isEqualTo("value"); + // Check that all codec are registered + assertThat(Codecs.getDefaultCodecFor(Jedi.class)).isInstanceOf(CustomJediCodec.class); + assertThat(Codecs.getDefaultCodecFor(Sith.class)).isInstanceOf(CustomSithCodec.class); + + HashCommands jediHash1 = ds.hash(Jedi.class); + jediHash1.hset(key1, "test", new Jedi("luke", "skywalker")); + var jediRetrieved = jediHash1.hget(key1, "test"); + assertThat(jediRetrieved.firstName).isEqualTo("luke"); + assertThat(jediRetrieved.lastName).isEqualTo("SKYWALKER"); + + HashCommands jediHash2 = ds.hash(String.class, Jedi.class, String.class); + jediHash2.hset(key1, new Jedi("luke", "skywalker"), "test"); + var jediRetrieved2 = jediHash2.hget(key1, new Jedi("luke", "skywalker")); + assertThat(jediRetrieved2).isEqualTo("test"); + + HashCommands jediHash3 = ds.hash(Jedi.class, String.class, String.class); + jediHash3.hset(new Jedi("luke", "skywalker"), "key", "value"); + var jediRetrieved3 = jediHash3.hget(new Jedi("luke", "skywalker"), "key"); + assertThat(jediRetrieved3).isEqualTo("value"); + + HashCommands sithHash1 = ds.hash(Sith.class); + sithHash1.hset(key1, "test", new Sith("darth", "sidious")); + var sithRetrieved = sithHash1.hget(key1, "test"); + assertThat(sithRetrieved.firstName).isEqualTo("darth"); + assertThat(sithRetrieved.lastName).isEqualTo("SIDIOUS"); + + HashCommands sithHash2 = ds.hash(String.class, Sith.class, String.class); + sithHash2.hset(key1, new Sith("darth", "sidious"), "test"); + var sithRetrieved2 = sithHash2.hget(key1, new Sith("darth", "sidious")); + assertThat(sithRetrieved2).isEqualTo("test"); + + HashCommands sithHash3 = ds.hash(Sith.class, String.class, String.class); + sithHash3.hset(new Sith("darth", "sidious"), "key", "value"); + var sithRetrieved3 = sithHash3.hget(new Sith("darth", "sidious"), "key"); + assertThat(sithRetrieved3).isEqualTo("value"); } @ApplicationScoped - public static class MyCustomCodec implements Codec { + public static class CustomJediCodec implements Codec { @Override public boolean canHandle(Type clazz) { @@ -79,6 +97,28 @@ public Object decode(byte[] item) { } } + @ApplicationScoped + public static class CustomSithCodec implements Codec { + + @Override + public boolean canHandle(Type clazz) { + return clazz.equals(Sith.class); + } + + @Override + public byte[] encode(Object item) { + var sith = (Sith) item; + return (sith.firstName + ";" + sith.lastName).getBytes(StandardCharsets.UTF_8); + } + + @Override + public Object decode(byte[] item) { + String s = new String(item, StandardCharsets.UTF_8); + String[] strings = s.split(";"); + return new Sith(strings[0], strings[1].toUpperCase()); + } + } + public static class Jedi { public final String firstName; public final String lastName; @@ -89,4 +129,14 @@ public Jedi(String firstName, String lastName) { } } + public static class Sith { + public final String firstName; + public final String lastName; + + public Sith(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + } + } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java index 1060772089656..cec469fc5d52d 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/client/RedisClientRecorder.java @@ -65,9 +65,8 @@ public void initialize(RuntimeValue vertx, Set name private static void _registerCodecs() { Instance codecs = CDI.current().select(Codec.class); - if (codecs.isResolvable()) { - Codecs.register(codecs.stream()); - } + + Codecs.register(codecs.stream()); } public void _initialize(io.vertx.core.Vertx vertx, Set names) { From e08c5e8c303a63550f465eed74ee35a92d66b519 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 1 Sep 2023 14:01:16 +0100 Subject: [PATCH 24/32] Fix typo which affects OIDC Dev UI when either client credentials or password grant is used (cherry picked from commit 5c46d30456ba3d62970ce685bcfdb8a996724017) --- .../io/quarkus/oidc/runtime/devui/OidcDevServicesUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/devui/OidcDevServicesUtils.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/devui/OidcDevServicesUtils.java index 411c2a6161609..5d9fc9335c0a8 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/devui/OidcDevServicesUtils.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/devui/OidcDevServicesUtils.java @@ -185,9 +185,9 @@ public static Uni testServiceWithPassword(String tokenUrl, String servic return token.eventually(client::close); } - private static Uni testServiceInternal(WebClient client, String serviceUrl, Uni token) { - return token - .flatMap(t -> { + private static Uni testServiceInternal(WebClient client, String serviceUrl, Uni tokenUni) { + return tokenUni + .flatMap(token -> { LOG.infof("Sending token to '%s'", serviceUrl); return client .getAbs(serviceUrl) From 6637dda69a970fda8d04cdfdc29b498385fd16b5 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Fri, 1 Sep 2023 11:11:18 +0200 Subject: [PATCH 25/32] ArC: log warning about removed beans for BeanContainer operations - this warning got accidentally removed in https://github.com/quarkusio/quarkus/pull/28112 (quarkus 2.14) (cherry picked from commit c1e624823cba1120fb130b5776b9d36c5626916a) --- ...rcContainerLookupProblemDetectedTest.java} | 6 +- ...inerSupplierLookupProblemDetectedTest.java | 57 +++++++++++++++++++ ...CDIProviderLookupProblemDetectedTest.java} | 6 +- .../io/quarkus/arc/impl/ArcContainerImpl.java | 6 +- 4 files changed, 68 insertions(+), 7 deletions(-) rename extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/{ApiLookupProblemDetectedTest.java => ArcContainerLookupProblemDetectedTest.java} (92%) create mode 100644 extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerSupplierLookupProblemDetectedTest.java rename extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/{ArcLookupProblemDetectedTest.java => CDIProviderLookupProblemDetectedTest.java} (93%) diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ApiLookupProblemDetectedTest.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerLookupProblemDetectedTest.java similarity index 92% rename from extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ApiLookupProblemDetectedTest.java rename to extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerLookupProblemDetectedTest.java index 1506823c865ef..7eb1d41361030 100644 --- a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ApiLookupProblemDetectedTest.java +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerLookupProblemDetectedTest.java @@ -17,7 +17,7 @@ import io.quarkus.arc.impl.ArcContainerImpl; import io.quarkus.test.QuarkusUnitTest; -public class ApiLookupProblemDetectedTest { +public class ArcContainerLookupProblemDetectedTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() @@ -31,10 +31,10 @@ public class ApiLookupProblemDetectedTest { Formatter fmt = new PatternFormatter("%m"); String message = fmt.format(warning); assertTrue(message.contains( - "Stack frame: io.quarkus.arc.test.unused.ApiLookupProblemDetectedTest.testWarning"), + "Stack frame: io.quarkus.arc.test.unused.ArcContainerLookupProblemDetectedTest.testWarning"), message); assertTrue(message.contains( - "Required type: class io.quarkus.arc.test.unused.ApiLookupProblemDetectedTest$Alpha"), + "Required type: class io.quarkus.arc.test.unused.ArcContainerLookupProblemDetectedTest$Alpha"), message); }); diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerSupplierLookupProblemDetectedTest.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerSupplierLookupProblemDetectedTest.java new file mode 100644 index 0000000000000..0a03a33d3279e --- /dev/null +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcContainerSupplierLookupProblemDetectedTest.java @@ -0,0 +1,57 @@ +package io.quarkus.arc.test.unused; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.logging.Formatter; +import java.util.logging.LogRecord; + +import jakarta.enterprise.context.ApplicationScoped; + +import org.jboss.logmanager.formatters.PatternFormatter; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.impl.ArcContainerImpl; +import io.quarkus.test.QuarkusUnitTest; + +public class ArcContainerSupplierLookupProblemDetectedTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot(root -> root + .addClasses(Alpha.class)) + .setLogRecordPredicate(log -> ArcContainerImpl.class.getPackage().getName().equals(log.getLoggerName())) + .assertLogRecords(records -> { + LogRecord warning = records.stream() + .filter(l -> l.getMessage().contains("programmatic lookup problem detected")).findAny().orElse(null); + assertNotNull(warning); + Formatter fmt = new PatternFormatter("%m"); + String message = fmt.format(warning); + assertTrue(message.contains( + "Stack frame: io.quarkus.arc.test.unused.ArcContainerSupplierLookupProblemDetectedTest.testWarning"), + message); + assertTrue(message.contains( + "Required type: class io.quarkus.arc.test.unused.ArcContainerSupplierLookupProblemDetectedTest$Alpha"), + message); + }); + + @Test + public void testWarning() { + // Note that the warning is only displayed once, subsequent calls use a cached result + assertNull(Arc.container().beanInstanceSupplier(Alpha.class)); + } + + // unused bean, will be removed + @ApplicationScoped + static class Alpha { + + public String ping() { + return "ok"; + } + + } + +} diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcLookupProblemDetectedTest.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/CDIProviderLookupProblemDetectedTest.java similarity index 93% rename from extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcLookupProblemDetectedTest.java rename to extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/CDIProviderLookupProblemDetectedTest.java index 664b4eeac7ece..6c83c69748da6 100644 --- a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/ArcLookupProblemDetectedTest.java +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unused/CDIProviderLookupProblemDetectedTest.java @@ -18,7 +18,7 @@ import io.quarkus.arc.impl.ArcContainerImpl; import io.quarkus.test.QuarkusUnitTest; -public class ArcLookupProblemDetectedTest { +public class CDIProviderLookupProblemDetectedTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() @@ -32,10 +32,10 @@ public class ArcLookupProblemDetectedTest { Formatter fmt = new PatternFormatter("%m"); String message = fmt.format(warning); assertTrue(message.contains( - "Stack frame: io.quarkus.arc.test.unused.ArcLookupProblemDetectedTest"), + "Stack frame: io.quarkus.arc.test.unused.CDIProviderLookupProblemDetectedTest"), message); assertTrue(message.contains( - "Required type: class io.quarkus.arc.test.unused.ArcLookupProblemDetectedTest$Alpha"), + "Required type: class io.quarkus.arc.test.unused.CDIProviderLookupProblemDetectedTest$Alpha"), message); }); diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java index cc12467b83c15..12f6a9ad0a65b 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java @@ -304,7 +304,11 @@ private Supplier> createInstanceSupplier(boolean resolveAm if (qualifiers == null || qualifiers.length == 0) { qualifiers = new Annotation[] { Default.Literal.INSTANCE }; } - Set> resolvedBeans = resolved.getValue(new Resolvable(type, qualifiers)); + Resolvable resolvable = new Resolvable(type, qualifiers); + Set> resolvedBeans = resolved.getValue(resolvable); + if (resolvedBeans.isEmpty()) { + scanRemovedBeans(resolvable); + } Set> filteredBean = resolvedBeans; if (resolvedBeans.size() > 1) { if (resolveAmbiguities) { From d916cebe401619f6ff8b4210cde2a7d5a5c84ce8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 19:15:32 +0000 Subject: [PATCH 26/32] Bump io.smallrye.config:smallrye-config-source-yaml in /devtools/gradle Bumps io.smallrye.config:smallrye-config-source-yaml from 3.3.3 to 3.3.4. --- updated-dependencies: - dependency-name: io.smallrye.config:smallrye-config-source-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] (cherry picked from commit 02e3ea4806e385ef0d1267b2bcc58cac7f8abfb6) --- 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 20615026e8be0..c11fd19627e4f 100644 --- a/devtools/gradle/gradle/libs.versions.toml +++ b/devtools/gradle/gradle/libs.versions.toml @@ -3,7 +3,7 @@ plugin-publish = "1.2.1" # updating Kotlin here makes QuarkusPluginTest > shouldNotFailOnProjectDependenciesWithoutMain(Path) fail kotlin = "1.8.10" -smallrye-config = "3.3.3" +smallrye-config = "3.3.4" junit5 = "5.9.3" assertj = "3.24.2" From ff7bd6f69953af7a89a740e11f8a4057bcaba743 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Fri, 1 Sep 2023 09:14:01 +0200 Subject: [PATCH 27/32] ArC: fix decorators and interface default methods - fixes #35664 (cherry picked from commit ada6761763bd9dcc0d814327d66a8d9e35e78bac) --- .../io/quarkus/arc/processor/Methods.java | 2 +- .../arc/processor/SubclassGenerator.java | 26 +++----- .../DecoratorDefaultMethodTest.java | 59 +++++++++++++++++++ 3 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorDefaultMethodTest.java diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java index d48294834bc68..a5290ed4c1ce9 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java @@ -140,7 +140,7 @@ private static boolean skipForClientProxy(MethodInfo method, boolean transformUn } static boolean skipForDelegateSubclass(MethodInfo method) { - if (Modifier.isStatic(method.flags()) || method.isSynthetic() || isDefault(method)) { + if (Modifier.isStatic(method.flags()) || method.isSynthetic()) { return true; } if (IGNORED_METHODS.contains(method.name())) { diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java index 126e917a878b8..f665300bc4444 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java @@ -637,13 +637,10 @@ private void processDecorator(DecoratorInfo decorator, BeanInfo bean, Type provi } List constructorParameterTypes = new ArrayList<>(); - // Fields and constructor - FieldCreator subclassField = null; - if (decoratedMethods.size() != nextDecoratorsValues.size()) { - subclassField = delegateSubclass.getFieldCreator("subclass", subclass.getClassName()) - .setModifiers(ACC_PRIVATE | ACC_FINAL); - constructorParameterTypes.add(subclass.getClassName()); - } + // Holds a reference to the subclass of the decorated bean + FieldCreator subclassField = delegateSubclass.getFieldCreator("subclass", subclass.getClassName()) + .setModifiers(ACC_PRIVATE | ACC_FINAL); + constructorParameterTypes.add(subclass.getClassName()); Map nextDecoratorToField = new HashMap<>(); for (DecoratorInfo nextDecorator : decoratorParameters) { FieldCreator nextDecoratorField = delegateSubclass @@ -653,6 +650,7 @@ private void processDecorator(DecoratorInfo decorator, BeanInfo bean, Type provi nextDecoratorToField.put(nextDecorator, nextDecoratorField.getFieldDescriptor()); } + // Constructor MethodCreator constructor = delegateSubclass.getMethodCreator(Methods.INIT, "V", constructorParameterTypes.toArray(new String[0])); int param = 0; @@ -664,10 +662,8 @@ private void processDecorator(DecoratorInfo decorator, BeanInfo bean, Type provi constructor.getThis()); } // Set fields - if (subclassField != null) { - constructor.writeInstanceField( - subclassField.getFieldDescriptor(), constructor.getThis(), constructor.getMethodParam(param++)); - } + constructor.writeInstanceField( + subclassField.getFieldDescriptor(), constructor.getThis(), constructor.getMethodParam(param++)); for (FieldDescriptor field : nextDecoratorToField.values()) { constructor.writeInstanceField( field, constructor.getThis(), constructor.getMethodParam(param++)); @@ -700,10 +696,6 @@ private void processDecorator(DecoratorInfo decorator, BeanInfo bean, Type provi for (MethodKey m : methods) { MethodInfo method = m.method; - if (Methods.skipForDelegateSubclass(method)) { - continue; - } - MethodDescriptor methodDescriptor = MethodDescriptor.of(method); MethodCreator forward = delegateSubclass.getMethodCreator(methodDescriptor); // Exceptions @@ -818,9 +810,7 @@ && isDecorated(decoratedMethodDescriptors, methodDescriptor, resolvedMethodDescr // Create new delegate subclass instance and set the DecoratorDelegateProvider to satisfy the delegate IP ResultHandle[] paramHandles = new ResultHandle[constructorParameterTypes.size()]; int paramIdx = 0; - if (subclassField != null) { - paramHandles[paramIdx++] = subclassConstructor.getThis(); - } + paramHandles[paramIdx++] = subclassConstructor.getThis(); for (DecoratorInfo decoratorParameter : decoratorParameters) { ResultHandle decoratorHandle = decoratorToResultHandle.get(decoratorParameter.getIdentifier()); if (decoratorHandle == null) { diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorDefaultMethodTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorDefaultMethodTest.java new file mode 100644 index 0000000000000..ca072e9ae26cd --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorDefaultMethodTest.java @@ -0,0 +1,59 @@ +package io.quarkus.arc.test.decorators; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import jakarta.annotation.Priority; +import jakarta.decorator.Decorator; +import jakarta.decorator.Delegate; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.util.TypeLiteral; +import jakarta.inject.Inject; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.test.ArcTestContainer; + +public class DecoratorDefaultMethodTest { + @RegisterExtension + public ArcTestContainer container = new ArcTestContainer(Converter.class, ToLengthConverter.class, + NoopConverterDecorator.class); + + @SuppressWarnings("serial") + @Test + public void testDecoration() { + Converter converter = Arc.container().instance(new TypeLiteral>() { + }).get(); + assertEquals(5, converter.convert("Hola!")); + } + + interface Converter { + default int convert(T value) { + return Integer.MAX_VALUE; + } + } + + @ApplicationScoped + static class ToLengthConverter implements Converter { + @Override + public int convert(String value) { + return value.length(); + } + } + + @Priority(1) + @Decorator + static class NoopConverterDecorator implements Converter { + + @Inject + @Delegate + Converter delegate; + + @Override + public int convert(String value) { + return delegate.convert(value); + } + } + +} From 33724892f50e97d3da07396ace3528007cafcde7 Mon Sep 17 00:00:00 2001 From: Roberto Cortez Date: Sat, 2 Sep 2023 18:46:09 +0100 Subject: [PATCH 28/32] Use correct default config source name to check Kubernetes config disabled (cherry picked from commit 31d4278913dbdc920ac14a414cc9cf11e55f756b) --- .../config/runtime/KubernetesConfigSourceFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/config/runtime/KubernetesConfigSourceFactory.java b/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/config/runtime/KubernetesConfigSourceFactory.java index 7dfc1b79a389e..f3a98ccec4ea5 100644 --- a/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/config/runtime/KubernetesConfigSourceFactory.java +++ b/extensions/kubernetes-config/runtime/src/main/java/io/quarkus/kubernetes/config/runtime/KubernetesConfigSourceFactory.java @@ -11,7 +11,6 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.client.KubernetesClient; -import io.quarkus.runtime.configuration.AbstractRawDefaultConfigSource; import io.smallrye.config.ConfigSourceContext; import io.smallrye.config.ConfigSourceContext.ConfigSourceContextConfigSource; import io.smallrye.config.ConfigSourceFactory; @@ -51,6 +50,7 @@ public Iterable getConfigSources(final ConfigSourceContext context .getConfigMapping(KubernetesConfigBuildTimeConfig.class); KubernetesConfigSourceConfig kubernetesConfigSourceConfig = config.getConfigMapping(KubernetesConfigSourceConfig.class); + // TODO - radcortez - Move the check that uses the build time config to the processor and skip the builder registration if ((!kubernetesConfigSourceConfig.enabled() && !kubernetesConfigBuildTimeConfig.secretsEnabled()) || isExplicitlyDisabled(context)) { log.debug( @@ -84,7 +84,7 @@ Iterable getConfigSources(final KubernetesConfigSourceConfig confi private boolean isExplicitlyDisabled(ConfigSourceContext context) { ConfigValue configValue = context.getValue("quarkus.kubernetes-config.enabled"); - if (AbstractRawDefaultConfigSource.NAME.equals(configValue.getConfigSourceName())) { + if ("DefaultValuesConfigSource".equals(configValue.getConfigSourceName())) { return false; } if (configValue.getValue() != null) { From 3196d2fc734f2b9f0e35222e7ee6566ee03efd0d Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Sat, 2 Sep 2023 13:36:21 +0300 Subject: [PATCH 29/32] fix: invalid push secret in bc when using internal registry (cherry picked from commit 9d4a8d4a7dfca1205a3f340abb4636cce19f6d37) --- .../deployment/OpenshiftProcessor.java | 13 +++-- .../OpenshiftWithInternalRegistryTest.java | 50 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithInternalRegistryTest.java diff --git a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java index 150961baabacb..13584271e1bb5 100644 --- a/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java +++ b/extensions/container-image/container-image-openshift/deployment/src/main/java/io/quarkus/container/image/openshift/deployment/OpenshiftProcessor.java @@ -244,21 +244,26 @@ public void configureExternalRegistry(ApplicationInfoBuildItem applicationInfo, containerImageInfo.registry.ifPresent(registry -> { final String name = applicationInfo.getName(); final String serviceAccountName = applicationInfo.getName(); - String imagePushSecret = openshiftConfig.imagePushSecret.orElse(applicationInfo.getName() + "-push-secret"); String repositoryWithRegistry = registry + "/" + containerImageInfo.getRepository(); - if (registry.contains(OPENSHIFT_INTERNAL_REGISTRY)) { + if (openshiftConfig.imagePushSecret.isPresent()) { + //if a push secret has been specified, we need to apply it. + String imagePushSecret = openshiftConfig.imagePushSecret.get(); + decorator.produce(new DecoratorBuildItem(OPENSHIFT, new ApplyDockerImageOutputToBuildConfigDecorator( + applicationInfo.getName(), containerImageInfo.getImage(), imagePushSecret))); + } else if (registry.contains(OPENSHIFT_INTERNAL_REGISTRY)) { //no special handling of secrets is really needed. } else if (containerImageInfo.username.isPresent() && containerImageInfo.password.isPresent()) { + String imagePushSecret = applicationInfo.getName() + "-push-secret"; decorator.produce(new DecoratorBuildItem(OPENSHIFT, new AddDockerConfigJsonSecretDecorator(imagePushSecret, containerImageInfo.registry.get(), containerImageInfo.username.get(), containerImageInfo.password.get()))); + decorator.produce(new DecoratorBuildItem(OPENSHIFT, new ApplyDockerImageOutputToBuildConfigDecorator( + applicationInfo.getName(), containerImageInfo.getImage(), imagePushSecret))); } else { LOG.warn("An external image registry has been specified, but no push secret or credentials."); } - decorator.produce(new DecoratorBuildItem(OPENSHIFT, new ApplyDockerImageOutputToBuildConfigDecorator( - applicationInfo.getName(), containerImageInfo.getImage(), imagePushSecret))); decorator.produce(new DecoratorBuildItem(OPENSHIFT, new ApplyDockerImageRepositoryToImageStream(applicationInfo.getName(), repositoryWithRegistry))); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithInternalRegistryTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithInternalRegistryTest.java new file mode 100644 index 0000000000000..66d3817d6aa2c --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithInternalRegistryTest.java @@ -0,0 +1,50 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.openshift.api.model.BuildConfig; +import io.quarkus.builder.Version; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class OpenshiftWithInternalRegistryTest extends BaseOpenshiftWithRemoteRegistry { + + private static final String APP_NAME = "openshift-with-internal-registry"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class)) + .setApplicationName(APP_NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .overrideConfigKey("quarkus.container-image.group", "project") + .overrideConfigKey("quarkus.container-image.registry", "quay.io") + .overrideConfigKey("quarkus.openshift.generate-image-pull-secret", "true") + .setForcedDependencies(List.of(Dependency.of("io.quarkus", "quarkus-openshift", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + Path buildDir = prodModeTestResults.getBuildDir(); + List resourceList = getResources("openshift", buildDir); + assertThat(resourceList).filteredOn(h -> "BuildConfig".equals(h.getKind())).singleElement().satisfies(h -> { + assertThat(h.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(APP_NAME); + }); + assertThat(h).isInstanceOfSatisfying(BuildConfig.class, b -> { + assertThat(b.getSpec().getOutput().getPushSecret()).isNull(); + }); + }); + } +} From e15bc3a7fd42813abc836583262cc2b6db378db5 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 1 Sep 2023 13:11:52 +0100 Subject: [PATCH 30/32] Clarify how PasswordProvider in security-jpa has to be used (cherry picked from commit 104a4c6607bb7d1023047ae8948663a3e1cd5961) --- docs/src/main/asciidoc/security-jpa.adoc | 13 +++++++++---- .../io/quarkus/security/jpa/PasswordProvider.java | 13 +++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/docs/src/main/asciidoc/security-jpa.adoc b/docs/src/main/asciidoc/security-jpa.adoc index 25f4d7195869c..eb5faa68d4698 100644 --- a/docs/src/main/asciidoc/security-jpa.adoc +++ b/docs/src/main/asciidoc/security-jpa.adoc @@ -125,12 +125,15 @@ As such, we do not need dedicated columns to keep them. In cryptography, a salt is a name for random data used as an additional input to a one-way function that hashes data, a password, or a passphrase. ==== -For manual password hashing, create a class that implements the `CustomPasswordProvider`as shown in the example below. +To represent passwords stored in the database which were hashed using different hashing algorithms, create a class that implements `org.wildfly.security.password.PasswordProvider` as shown in the example below. -The following snippet shows how to set a custom password provider that uses the SHA256 hashing algorithm. +The following snippet shows how to set a custom password provider that represents a password which was hashed with the SHA256 hashing algorithm. [source,java] ---- +import org.wildfly.security.password.Password; +import org.wildfly.security.password.PasswordProvider; + @UserDefinition @Table(name = "test_user") @Entity @@ -153,8 +156,10 @@ public class CustomPasswordUserEntity { public class CustomPasswordProvider implements PasswordProvider { @Override - public Password getPassword(String pass) { - byte[] digest = DatatypeConverter.parseHexBinary(pass); + public Password getPassword(String passwordInDatabase) { + byte[] digest = DatatypeConverter.parseHexBinary(passwordInDatabase); + + // Let the security runtime know that this passwordInDatabase is hashed using the SHA256 hashing algorithm return SimpleDigestPassword.createRaw(SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_SHA_256, digest); } } diff --git a/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/PasswordProvider.java b/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/PasswordProvider.java index 10ac7d508896e..53f8fd6a4e180 100644 --- a/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/PasswordProvider.java +++ b/extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/PasswordProvider.java @@ -3,8 +3,17 @@ import org.wildfly.security.password.Password; /** - * Provides the {@link Password} according to how the password is hashed in the database. + * Returns a password stored in the database as {@link Password}. */ public interface PasswordProvider { - Password getPassword(String pass); + /** + * Return a password stored in the database. + * + * @param passwordFromDatabase - password in the database. If this password is hashed then + * {@link Password} implementation must provide a hashing algorithm information. + * Do not create a hash from this password - the security runtime will + * apply the hashing algorithm to the incoming user secret and compare it with this password. + * @return {@link Password} representation of the password stored in the database. + */ + Password getPassword(String passwordFromDatabase); } From 0ea0e807d6ca3835d1ca4c32105c0e6e06928718 Mon Sep 17 00:00:00 2001 From: Max Rydahl Andersen Date: Wed, 30 Aug 2023 12:47:59 +0200 Subject: [PATCH 31/32] Make hibernate reactive status clear in docs (cherry picked from commit 0e2bbf5dfbe9422e6fc79d0f3676c80c5af0aebe) --- docs/src/main/asciidoc/hibernate-reactive.adoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/hibernate-reactive.adoc b/docs/src/main/asciidoc/hibernate-reactive.adoc index 23f984c8737ae..e3afb738ca620 100644 --- a/docs/src/main/asciidoc/hibernate-reactive.adoc +++ b/docs/src/main/asciidoc/hibernate-reactive.adoc @@ -4,10 +4,11 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Using Hibernate Reactive - include::_attributes.adoc[] :config-file: application.properties :reactive-doc-url-prefix: https://hibernate.org/reactive/documentation/1.1/reference/html_single/#getting-started +:extension-status: preview + link:https://hibernate.org/reactive/[Hibernate Reactive] is a reactive API for Hibernate ORM, supporting non-blocking database drivers and a reactive style of interaction with the database. @@ -19,6 +20,8 @@ xref:hibernate-orm.adoc[Hibernate ORM guide]. This guide will only focus on what for Hibernate Reactive. ==== +include::{includes}/extension-status.adoc[] + == Solution We recommend that you follow the instructions in the next sections and create the application step by step. From 59c4f1d218243351701056e5916624c1a3767871 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 4 Sep 2023 20:10:46 +0200 Subject: [PATCH 32/32] Enforce version of a11y-base --- bom/application/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index bed2105755608..1b1850c4b4088 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -3621,6 +3621,12 @@ ${vaadin.version} runtime + + org.mvnpm.at.vaadin + a11y-base + ${vaadin.version} + runtime +