Skip to content

Commit

Permalink
Merge pull request #45590 from gsmet/3.17.7-backports-1
Browse files Browse the repository at this point in the history
[3.17] 3.17.7 backports 1
  • Loading branch information
gsmet authored Jan 15, 2025
2 parents c9c0339 + ee16cd1 commit e632ab6
Show file tree
Hide file tree
Showing 41 changed files with 859 additions and 213 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<smallrye-config.version>3.10.2</smallrye-config.version>
<smallrye-health.version>4.1.1</smallrye-health.version>
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>4.0.5</smallrye-open-api.version>
<smallrye-open-api.version>4.0.6</smallrye-open-api.version>
<smallrye-graphql.version>2.11.0</smallrye-graphql.version>
<smallrye-fault-tolerance.version>6.6.3</smallrye-fault-tolerance.version>
<smallrye-jwt.version>4.6.1</smallrye-jwt.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ public class BytecodeRecorderImpl implements RecorderContext {
private final Map<Class<?>, NewRecorder> existingRecorderValues = new ConcurrentHashMap<>();
private final List<BytecodeInstruction> storedMethodCalls = new ArrayList<>();

private final IdentityHashMap<Class<?>, String> classProxies = new IdentityHashMap<>();
private final Map<String, String> classProxyNamesToOriginalClassNames = new HashMap<>();
private final Map<String, Class<?>> originalClassNamesToClassProxyClasses = new HashMap<>();
private final Map<Class<?>, SubstitutionHolder> substitutions = new HashMap<>();
private final Map<Class<?>, NonDefaultConstructorHolder> nonDefaultConstructors = new HashMap<>();
private final String className;
Expand Down Expand Up @@ -273,14 +274,20 @@ public Class<?> classProxy(String name) {
return void.class;
}

Class<?> proxyClass = originalClassNamesToClassProxyClasses.get(name);
if (proxyClass != null) {
return proxyClass;
}

ProxyFactory<Object> factory = new ProxyFactory<>(new ProxyConfiguration<Object>()
.setSuperClass(Object.class)
.setClassLoader(classLoader)
.setAnchorClass(getClass())
.setProxyNameSuffix("$$ClassProxy" + COUNT.incrementAndGet()));
Class theClass = factory.defineClass();
classProxies.put(theClass, name);
return theClass;
proxyClass = factory.defineClass();
classProxyNamesToOriginalClassNames.put(proxyClass.getName(), name);
originalClassNamesToClassProxyClasses.put(name, proxyClass);
return proxyClass;
}

@Override
Expand Down Expand Up @@ -743,14 +750,10 @@ ResultHandle doLoad(MethodContext context, MethodCreator method, ResultHandle ar
method.load(param.toString()));
}
};
} else if (param instanceof Class<?>) {
if (!((Class) param).isPrimitive()) {
} else if (param instanceof Class<?> clazz) {
if (!clazz.isPrimitive()) {
// Only try to load the class by name if it is not a primitive class
String name = classProxies.get(param);
if (name == null) {
name = ((Class) param).getName();
}
String finalName = name;
String finalName = classProxyNamesToOriginalClassNames.getOrDefault(clazz.getName(), clazz.getName());
return new DeferredParameter() {
@Override
ResultHandle doLoad(MethodContext context, MethodCreator method, ResultHandle array) {
Expand All @@ -770,7 +773,7 @@ ResultHandle doLoad(MethodContext context, MethodCreator method, ResultHandle ar
return new DeferredParameter() {
@Override
ResultHandle doLoad(MethodContext context, MethodCreator method, ResultHandle array) {
return method.loadClassFromTCCL((Class) param);
return method.loadClassFromTCCL(clazz);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

import org.jboss.logmanager.ExtHandler;
import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.Level;

/**
Expand All @@ -16,7 +16,7 @@
* <p>
* Non-standard levels are counted with the lower standard level.
*/
public class LogMetricsHandler extends Handler {
public class LogMetricsHandler extends ExtHandler {

final NavigableMap<Integer, LongAdder> logCounters;

Expand All @@ -25,15 +25,13 @@ public LogMetricsHandler(NavigableMap<Integer, LongAdder> logCounters) {
}

@Override
public void publish(LogRecord record) {
if (isLoggable(record)) {
Entry<Integer, LongAdder> counter = logCounters.floorEntry(record.getLevel().intValue());
if (counter != null) {
counter.getValue().increment();
} else {
// Default to TRACE for anything lower
logCounters.get(Level.TRACE.intValue()).increment();
}
protected void doPublish(ExtLogRecord record) {
Entry<Integer, LongAdder> counter = logCounters.floorEntry(record.getLevel().intValue());
if (counter != null) {
counter.getValue().increment();
} else {
// Default to TRACE for anything lower
logCounters.get(Level.TRACE.intValue()).increment();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.jboss.logmanager.ExtFormatter;
import org.jboss.logmanager.ExtHandler;
import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.LogContext;
import org.jboss.logmanager.LogContextInitializer;
import org.jboss.logmanager.Logger;
Expand Down Expand Up @@ -183,9 +185,9 @@ public void accept(String loggerName, CleanupFilterConfig config) {
handlers.add(consoleHandler);
}
if (launchMode.isDevOrTest()) {
handlers.add(new Handler() {
handlers.add(new ExtHandler() {
@Override
public void publish(LogRecord record) {
protected void doPublish(ExtLogRecord record) {
if (record.getThrown() != null) {
ExceptionReporting.notifyException(record.getThrown());
}
Expand Down Expand Up @@ -613,9 +615,9 @@ private static Handler configureConsoleHandler(

if (color && launchMode.isDevOrTest() && !config.async().enable()) {
final Handler delegate = handler;
handler = new Handler() {
handler = new ExtHandler() {
@Override
public void publish(LogRecord record) {
protected void doPublish(ExtLogRecord record) {
BiConsumer<LogRecord, Consumer<LogRecord>> formatter = CurrentAppExceptionHighlighter.THROWABLE_FORMATTER;
if (formatter != null) {
formatter.accept(record, delegate::publish);
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/deploying-to-kubernetes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ of secret that contains the required credentials. Quarkus can automatically gene
quarkus.kubernetes.generate-image-pull-secret=true
----

More specifically a `Secret`like the one bellow is genrated:
More specifically a `Secret` like the one below is generated:

[source,yaml]
----
Expand Down
19 changes: 17 additions & 2 deletions docs/src/main/asciidoc/native-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2293,14 +2293,29 @@ One can see which Mandrel version was used to generate a binary by inspecting th

[source,bash]
----
$ strings target/debugging-native-1.0.0-SNAPSHOT-runner | grep GraalVM
com.oracle.svm.core.VM=GraalVM 22.0.0.2-Final Java 11 Mandrel Distribution
$ strings target/debugging-native-1.0.0-SNAPSHOT-runner | \
grep -e 'com.oracle.svm.core.VM=' -e 'com.oracle.svm.core.VM.Java.Version' -F
com.oracle.svm.core.VM.Java.Version=21.0.5
com.oracle.svm.core.VM=Mandrel-23.1.5.0-Final
----

=== How do I enable GC logging in native executables?

See <<gc-logging,Native Memory Management GC Logging section>> for details.

=== Can I get a thread dump of a native executable?

Yes, Quarkus sets up a signal handler for the `SIGQUIT` signal (or `SIGBREAK` on windows) that will result in a thread
dump being printed when receiving the `SIGQUIT/SIGBREAK` signal.
You may use `kill -SIGQUIT <pid>` to trigger a thread dump.

[NOTE]
====
Quarkus uses its own signal handler, to use GraalVM's default signal handler instead you will need to:
1. Add `-H:+DumpThreadStacksOnSignal` to `quarkus.native.additional-build-args` and rebuild the application.
2. Set the environment variable `DISABLE_SIGNAL_HANDLERS` before running the app.
====

[[heap-dumps]]
=== Can I get a heap dump of a native executable? e.g. if it runs out of memory

Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/scheduler-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Property Expressions.
.Time Zone Configuration Property Example
[source,java]
----
@Scheduled(cron = "0 15 10 * * ?", timeZone = "{myMethod.timeZone}")
@Scheduled(cron = "0 15 10 * * ?", timeZone = "${myMethod.timeZone}")
void myMethod() { }
----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,49 @@ public class ProjectPermissionChecker {
TIP: Permission checks run by default on event loops.
Annotate a permission checker method with the `io.smallrye.common.annotation.Blocking` annotation if you want to run the check on a worker thread.

Matching between the `@PermissionsAllowed` values and the `@PermissionChecker` value is based on string equality as shown in the example below:

[source,java]
----
package org.acme.security;
import io.quarkus.security.PermissionChecker;
import io.quarkus.security.PermissionsAllowed;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class FileService {
@PermissionsAllowed({ "delete:all", "delete:dir" }) <1>
void deleteDirectory(Path directoryPath) {
// delete directory
}
@PermissionsAllowed(value = { "delete:service", "delete:file" }, inclusive = true) <2>
void deleteServiceFile(Path serviceFilePath) {
// delete service file
}
@PermissionChecker("delete:all")
boolean canDeleteAllDirectories(SecurityIdentity identity) {
String filePermissions = identity.getAttribute("user-group-file-permissions");
return filePermissions != null && filePermissions.contains("w");
}
@PermissionChecker("delete:service")
boolean canDeleteService(SecurityIdentity identity) {
return identity.hasRole("admin");
}
@PermissionChecker("delete:file")
boolean canDeleteFile(Path serviceFilePath) {
return serviceFilePath != null && !serviceFilePath.endsWith("critical");
}
}
----
<1> The permission checker method `canDeleteAllDirectories` grants access to the `deleteDirectory` because the `delete:all` values are equal.
<2> There must be exactly two permission checker methods, one for the `delete:service` permission and other for the `delete:file` permission.

[[permission-meta-annotation]]
==== Create permission meta-annotations

Expand Down
12 changes: 12 additions & 0 deletions docs/src/main/asciidoc/security-ldap.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ quarkus.security.ldap.identity-mapping.attribute-mappings."0".filter-base-dn=ou=

The `elytron-security-ldap` extension requires a dir-context and an identity-mapping with at least one attribute-mapping to authenticate the user and its identity.

=== Map LDAP groups to `SecurityIdentity` roles

Previously described application configuration showed how to map `CN` attribute of the LDAP Distinguished Name group to a Quarkus `SecurityIdentity` role.
More specifically, the `standardRole` CN was mapped to a `SecurityIdentity` role and thus allowed access to the `UserResource#me` endpoint.
However, required `SecurityIdentity` roles may differ between applications and you may need to map LDAP groups to local `SecurityIdentity` roles like in the example below:

[source,properties]
----
quarkus.http.auth.roles-mapping."standardRole"=user <1>
----
<1> Map the `standardRole` role to the application-specific `SecurityIdentity` role `user`.

== Testing the Application

The application is now protected and the identities are provided by our LDAP server.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ public void onConnectionDestroy(Connection connection) {

@Override
public void onWarning(String warning) {
log.warnv("{0}: {1}", datasourceName, warning);
// See https://github.com/quarkusio/quarkus/issues/44047
if (warning != null && warning.contains("JDBC resources leaked")) {
log.debugv("{0}: {1}", datasourceName, warning);
} else {
log.warnv("{0}: {1}", datasourceName, warning);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.jdbc.oracle.runtime.OracleInitRecorder;

public final class ExtendedCharactersSupport {

@Record(STATIC_INIT)
@BuildStep
@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
public void preinitializeCharacterSets(NativeConfig config, OracleInitRecorder recorder) {
recorder.setupCharSets(config.addAllCharsets());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.maven.dependency.ArtifactKey;

/**
Expand All @@ -35,7 +36,7 @@
* require it, so this would facilitate the option to revert to the older version in
* case of problems.
*/
@BuildSteps
@BuildSteps(onlyIf = NativeOrNativeSourcesBuild.class)
public final class OracleMetadataOverrides {

static final String DRIVER_JAR_MATCH_REGEX = "com\\.oracle\\.database\\.jdbc";
Expand Down
5 changes: 5 additions & 0 deletions extensions/mongodb-client/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-deployment</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.quarkus.mongodb;

import static io.restassured.RestAssured.when;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.concurrent.TimeUnit;

import jakarta.inject.Inject;

import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand Down Expand Up @@ -94,4 +96,11 @@ public void testReactiveClientConfiuration() {
assertThat(clientImpl.getSettings().getReadConcern()).isEqualTo(new ReadConcern(ReadConcernLevel.SNAPSHOT));
assertThat(clientImpl.getSettings().getReadPreference()).isEqualTo(ReadPreference.primary());
}

@Test
public void healthCheck() {
when().get("/q/health/ready")
.then()
.body("status", CoreMatchers.equalTo("UP"));
}
}
Loading

0 comments on commit e632ab6

Please sign in to comment.