Skip to content

Commit

Permalink
Merge pull request #45192 from gsmet/3.17.5-backports-1
Browse files Browse the repository at this point in the history
[3.17] 3.17.5 backports 1
  • Loading branch information
gsmet authored Dec 19, 2024
2 parents 72b3d01 + c6608bf commit 7bb1cc8
Show file tree
Hide file tree
Showing 64 changed files with 962 additions and 214 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/ci-actions-incremental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,13 @@ jobs:
elif [ "${GIB_IMPACTED_MODULES}" != '_all_' ]
then
# Important: keep -pl ... in actual jobs in sync with the following grep commands!
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -qPv 'integration-tests/(devtools|gradle|maven|devmode|kubernetes/.*)|tcks/.*'; then run_jvm=false; fi
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'integration-tests/devtools'; then run_devtools=false; fi
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'integration-tests/gradle'; then run_gradle=false; fi
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -qP 'integration-tests/(maven|devmode)'; then run_maven=false; fi
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -qP 'integration-tests/kubernetes/.*'; then run_kubernetes=false; fi
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -qPv '(docs|integration-tests|tcks)/.*'; then run_quickstarts=false; fi
if ! echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'tcks/.*'; then run_tcks=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qPv 'integration-tests/(devtools|gradle|maven|devmode|kubernetes/.*)|tcks/.*'); then run_jvm=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'integration-tests/devtools'); then run_devtools=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'integration-tests/gradle'); then run_gradle=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qP 'integration-tests/(maven|devmode)'); then run_maven=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qP 'integration-tests/kubernetes/.*'); then run_kubernetes=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qPv '(docs|integration-tests|tcks)/.*'); then run_quickstarts=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'tcks/.*'); then run_tcks=false; fi
fi
echo "run_jvm=${run_jvm}, run_devtools=${run_devtools}, run_gradle=${run_gradle}, run_maven=${run_maven}, run_kubernetes=${run_kubernetes}, run_quickstarts=${run_quickstarts}, run_tcks=${run_tcks}"
echo "run_jvm=${run_jvm}" >> $GITHUB_OUTPUT
Expand Down
6 changes: 3 additions & 3 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<opentelemetry.version>1.42.1</opentelemetry.version>
<opentelemetry-alpha.version>2.8.0-alpha</opentelemetry-alpha.version>
<opentelemetry-semconv.version>1.27.0-alpha</opentelemetry-semconv.version>
<quarkus-http.version>5.3.3</quarkus-http.version>
<quarkus-http.version>5.3.4</quarkus-http.version>
<micrometer.version>1.13.7</micrometer.version><!-- keep in sync with hdrhistogram -->
<hdrhistogram.version>2.2.2</hdrhistogram.version><!-- keep in sync with micrometer -->
<google-auth.version>0.22.0</google-auth.version>
Expand Down Expand Up @@ -119,7 +119,7 @@
<h2.version>2.3.230</h2.version> <!-- When updating, needs to be matched in io.quarkus.hibernate.orm.runtime.config.DialectVersions
and the dependency jts-core needs to be updated in extensions/jdbc/jdbc-h2/runtime/pom.xml -->
<postgresql-jdbc.version>42.7.4</postgresql-jdbc.version>
<mariadb-jdbc.version>3.5.0</mariadb-jdbc.version>
<mariadb-jdbc.version>3.4.1</mariadb-jdbc.version>
<mysql-jdbc.version>8.3.0</mysql-jdbc.version>
<mssql-jdbc.version>12.8.1.jre11</mssql-jdbc.version>
<adal4j.version>1.6.7</adal4j.version>
Expand Down Expand Up @@ -214,7 +214,7 @@
<mime4j.version>0.8.11</mime4j.version>
<mutiny-zero.version>1.1.0</mutiny-zero.version>
<pulsar-client.version>3.3.0</pulsar-client.version>
<async-http-client.version>2.12.3</async-http-client.version>
<async-http-client.version>2.12.4</async-http-client.version>
<!-- keep in-sync, if possible, with Micrometer registry Prometheus -->
<prometheus.version>0.16.0</prometheus.version>
<!-- Dev UI -->
Expand Down
5 changes: 5 additions & 0 deletions build-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,11 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.smallrye.certs</groupId>
<artifactId>smallrye-certificate-generator-maven-plugin</artifactId>
<version>${smallrye-certificate-generator.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/centralized-log-management.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ For this you can use the same `docker-compose.yml` file as above but with a diff
input {
tcp {
port => 4560
coded => json
codec => json
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,11 @@ quarkus.http.auth.inclusive=true
If the authentication is inclusive then `SecurityIdentity` created by the first authentication mechanism can be
injected into the application code.
For example, if both <<mutual-tls>> and basic authentication mechanism authentications are required,
the <<mutual-tls>> authentication mechanism will create `SecurityIdentity` first.
the <<mutual-tls>> mechanism will create `SecurityIdentity` first.

NOTE: The <<mutual-tls>> mechanism has the highest priority when inclusive authentication is enabled, to ensure
that an injected `SecurityIdentity` always represents <<mutual-tls>> and can be used to get access to `SecurityIdentity`
identities provided by other authentication mechanisms.

Additional `SecurityIdentity` instances can be accessed as a `quarkus.security.identities` attribute on the first
`SecurityIdentity`, however, accessing these extra identities directly may not be necessary, for example,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,49 @@ Authentication that requires a dynamic tenant will fail.
You can filter OIDC requests made by Quarkus to the OIDC provider by registering one or more `OidcRequestFilter` implementations, which can update or add new request headers, and log requests.
For more information, see xref:security-oidc-code-flow-authentication#code-flow-oidc-request-filters[OIDC request filters].

[[bearer-token-oidc-response-filters]]
=== OIDC response filters

You can filter responses from the OIDC providers by registering one or more `OidcResponseFilter` implementations, which can check the response status, headers and body in order to log them or perform other actions.

You can have a single filter intercepting all the OIDC responses, or use an `@OidcEndpoint` annotation to apply this filter to the specific endpoint responses only. For example:

[source,java]
----
package io.quarkus.it.keycloak;
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.Unremovable;
import io.quarkus.logging.Log;
import io.quarkus.oidc.common.OidcEndpoint;
import io.quarkus.oidc.common.OidcEndpoint.Type;
import io.quarkus.oidc.common.OidcResponseFilter;
import io.quarkus.oidc.common.runtime.OidcConstants;
import io.quarkus.oidc.runtime.OidcUtils;
@ApplicationScoped
@Unremovable
@OidcEndpoint(value = Type.DISCOVERY) <1>
public class DiscoveryEndpointResponseFilter implements OidcResponseFilter {
@Override
public void filter(OidcResponseContext rc) {
String contentType = rc.responseHeaders().get("Content-Type"); <2>
if (contentType.equals("application/json") {
String tenantId = rc.requestProperties().get(OidcUtils.TENANT_ID_ATTRIBUTE); <3>
String metadata = rc.responseBody().toString(); <4>
Log.debugf("Tenant %s OIDC metadata: %s", tenantId, metadata);
}
}
}
----
<1> Restrict this filter to requests targeting the OIDC discovery endpoint only.
<2> Check the response `Content-Type` header.
<3> Use `OidcRequestContextProperties` request properties to get the tenant id.
<4> Get the response data as String.

== References

* xref:security-oidc-configuration-properties-reference.adoc[OIDC configuration properties]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,8 @@ package io.quarkus.it.keycloak;
import jakarta.enterprise.context.ApplicationScoped;
import org.jboss.logging.Logger;
import io.quarkus.arc.Unremovable;
import io.quarkus.logging.Log;
import io.quarkus.oidc.common.OidcEndpoint;
import io.quarkus.oidc.common.OidcEndpoint.Type;
import io.quarkus.oidc.common.OidcResponseFilter;
Expand All @@ -405,16 +404,15 @@ import io.quarkus.oidc.runtime.OidcUtils;
@Unremovable
@OidcEndpoint(value = Type.TOKEN) <1>
public class TokenEndpointResponseFilter implements OidcResponseFilter {
private static final Logger LOG = Logger.getLogger(TokenResponseFilter.class);
@Override
public void filter(OidcResponseContext rc) {
String contentType = rc.responseHeaders().get("Content-Type"); <2>
if (contentType.equals("application/json")
&& OidcConstants.AUTHORIZATION_CODE.equals(rc.requestProperties().get(OidcConstants.GRANT_TYPE)) <3>
&& "code-flow-user-info-cached-in-idtoken".equals(rc.requestProperties().get(OidcUtils.TENANT_ID_ATTRIBUTE)) <3>
&& rc.responseBody().toJsonObject().containsKey("id_token")) { <4>
LOG.debug("Authorization code completed for tenant 'code-flow-user-info-cached-in-idtoken'");
Log.debug("Authorization code completed for tenant 'code-flow-user-info-cached-in-idtoken'");
}
}
}
Expand Down
21 changes: 14 additions & 7 deletions docs/src/main/asciidoc/writing-native-applications-tips.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public class MyReflectionConfiguration {
}
----

Note: By default the `@RegisterForReflection` annotation will also registered any potential nested classes for reflection. If you want to avoid this behavior, you can set the `ignoreNested` attribute to `true`.
Note: By default the `@RegisterForReflection` annotation will also register any potential nested classes for reflection. If you want to avoid this behavior, you can set the `ignoreNested` attribute to `true`.

==== Using a configuration file

Expand Down Expand Up @@ -320,6 +320,7 @@ and in the case of using the Maven configuration instead of `application.propert
----
====

[[managing-proxy-classes-app]]
=== Managing Proxy Classes

While writing native application you'll need to define proxy classes at image build time by specifying the list of interfaces that they implement.
Expand All @@ -331,9 +332,10 @@ In such a situation, the error you might encounter is:
com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface org.apache.http.conn.HttpClientConnectionManager, interface org.apache.http.pool.ConnPoolControl, interface com.amazonaws.http.conn.Wrapped] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
----

Solving this issue requires creating a `proxy-config.json` file under the `src/main/resources/META-INF/native-image/<group-id>/<artifact-id>` folder.
This way the configuration will be automatically parsed by the native build, without additional configuration.
For more information about the format of this file, see the link:https://www.graalvm.org/{graalvm-docs-version}/reference-manual/native-image/metadata/#dynamic-proxy-metadata-in-json[Dynamic Proxy Metadata in JSON] documentation.
To solve the issue you can create a `proxy-config.json` file under the `src/main/resources/META-INF/native-image/<group-id>/<artifact-id>` folder.
For more information about the format of the `proxy-config.json`, see the https://www.graalvm.org/{graalvm-docs-version}/reference-manual/native-image/metadata/#dynamic-proxy-metadata-in-json[Dynamic Proxy Metadata in JSON] documentation.

Alternatively, you can create a quarkus extension and register the proxy classes as described in <<managing-proxy-classes-extension>>.

[[modularity-benefits]]
=== Modularity Benefits
Expand Down Expand Up @@ -633,9 +635,10 @@ Using such a construct means that a `--initialize-at-run-time` option will autom
For more information about the `--initialize-at-run-time` option, see the link:https://www.graalvm.org/{graalvm-docs-version}/reference-manual/native-image/optimizations-and-performance/ClassInitialization/[GraalVM Class Initialization in Native Image] guide.
====

[[managing-proxy-classes-extension]]
=== Managing Proxy Classes

Very similarly, Quarkus allows extensions authors to register a `NativeImageProxyDefinitionBuildItem`. An example of doing so is:
Similarly, Quarkus allows extensions authors to register a `NativeImageProxyDefinitionBuildItem`. An example of doing so is:

[source,java]
----
Expand All @@ -650,11 +653,15 @@ public class S3Processor {
}
----

Using such a construct means that a `-H:DynamicProxyConfigurationResources` option will automatically be added to the `native-image` command line.
This will allow Quarkus to generate the necessary configuration for handling the proxy class.

Alternatively, you may create a `proxy-config.json` as described in <<managing-proxy-classes-app>>.

[NOTE]
====
For more information about Proxy Classes, see the link:https://www.graalvm.org/{graalvm-docs-version}/reference-manual/native-image/guides/configure-dynamic-proxies/[GraalVM Configure Dynamic Proxies Manually] guide.
In both cases the configuration will be automatically parsed by the native build, without additional configuration.
For more information about using Proxy Classes in native executables, see https://www.graalvm.org/jdk21/reference-manual/native-image/dynamic-features/DynamicProxy/[Dynamic Proxy in Native Image] and https://www.graalvm.org/{graalvm-docs-version}/reference-manual/native-image/guides/configure-dynamic-proxies/[GraalVM Configure Dynamic Proxies Manually].
====

=== Logging with Native Image
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem;
import io.quarkus.deployment.logging.LoggingSetupBuildItem;
import io.quarkus.deployment.recording.RecorderContext;
import io.quarkus.flyway.FlywayDataSource;
import io.quarkus.flyway.runtime.FlywayBuildTimeConfig;
Expand Down Expand Up @@ -184,7 +183,6 @@ private void addJavaMigrations(Collection<ClassInfo> candidates, RecorderContext

@BuildStep
@Produce(SyntheticBeansRuntimeInitBuildItem.class)
@Consume(LoggingSetupBuildItem.class)
@Record(ExecutionTime.RUNTIME_INIT)
void createBeans(FlywayRecorder recorder,
List<JdbcDataSourceBuildItem> jdbcDataSourceBuildItems,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.quarkus.micrometer.deployment.binder;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.search.Search;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.quarkus.rest.client.reactive.Url;
import io.quarkus.test.QuarkusUnitTest;

public class RestClientUriParameterTest {

final static SimpleMeterRegistry registry = new SimpleMeterRegistry();

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.withApplicationRoot(
jar -> jar.addClasses(Resource.class, Client.class))
.overrideConfigKey("quarkus.redis.devservices.enabled", "false")
.overrideConfigKey("quarkus.rest-client.\"client\".url", "http://does-not-exist.io");

@RestClient
Client client;

@ConfigProperty(name = "quarkus.http.test-port")
Integer testPort;

@BeforeAll
static void setRegistry() {
Metrics.addRegistry(registry);
}

@AfterAll()
static void removeRegistry() {
Metrics.removeRegistry(registry);
}

@Test
public void testOverride() {
String result = client.getById("http://localhost:" + testPort, "bar");
assertEquals("bar", result);

Timer clientTimer = registry.find("http.client.requests").timer();
assertNotNull(clientTimer);
assertEquals("/example/{id}", clientTimer.getId().getTag("uri"));
}

private Search getMeter(String name) {
return registry.find(name);
}

@Path("/example")
@RegisterRestClient(baseUri = "http://dummy")
public interface Client {

@GET
@Path("/{id}")
String getById(@Url String baseUri, @PathParam("id") String id);
}

@Path("/example")
public static class Resource {

@RestClient
Client client;

@GET
@Path("/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String example() {
return "bar";
}

@GET
@Path("/call")
@Produces(MediaType.TEXT_PLAIN)
public String call() {
return client.getById("http://localhost:8080", "1");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public class UriTagWithHttpRootTest {
@Inject
MeterRegistry registry;

@Test
public void testClient() throws InterruptedException {
when().get("/ping/one").then().statusCode(200);
Util.waitForMeters(registry.find("http.server.requests").timers(), 1);
Util.waitForMeters(registry.find("http.client.requests").timers(), 1);
Assertions.assertEquals(1, registry.find("http.client.requests").tag("uri", "/pong/{message}").timers().size());
}

@Test
public void testRequestUris() throws Exception {
RestAssured.basePath = "/";
Expand Down
5 changes: 5 additions & 0 deletions extensions/oidc/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@
<artifactId>quarkus-elytron-security-properties-file-deployment</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.certs</groupId>
<artifactId>smallrye-certificate-generator-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Loading

0 comments on commit 7bb1cc8

Please sign in to comment.