Skip to content

Commit

Permalink
Merge pull request #34892 from gsmet/3.2.2-backports-1
Browse files Browse the repository at this point in the history
3.2.2 backports 1
  • Loading branch information
gsmet committed Jul 21, 2023
2 parents 96a3152 + 2819921 commit 7d29dd7
Show file tree
Hide file tree
Showing 23 changed files with 324 additions and 100 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<microprofile-lra.version>2.0</microprofile-lra.version>
<microprofile-openapi.version>3.1.1</microprofile-openapi.version>
<smallrye-common.version>2.1.0</smallrye-common.version>
<smallrye-config.version>3.3.0</smallrye-config.version>
<smallrye-config.version>3.3.2</smallrye-config.version>
<smallrye-health.version>4.0.2</smallrye-health.version>
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>3.4.0</smallrye-open-api.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public abstract class NativeImageBuildContainerRunner extends NativeImageBuildRu

protected NativeImageBuildContainerRunner(NativeConfig nativeConfig) {
this.nativeConfig = nativeConfig;
containerRuntime = nativeConfig.containerRuntime().orElseGet(ContainerRuntimeUtil::detectContainerRuntime);
containerRuntime = ContainerRuntimeUtil.detectContainerRuntime();

this.baseContainerRuntimeArgs = new String[] { "--env", "LANG=C", "--rm" };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ private boolean runUpxInContainer(NativeImageBuildItem nativeImage, NativeConfig
List<String> extraArgs = nativeConfig.compression().additionalArgs().orElse(Collections.emptyList());

List<String> commandLine = new ArrayList<>();
ContainerRuntimeUtil.ContainerRuntime containerRuntime = nativeConfig.containerRuntime()
.orElseGet(ContainerRuntimeUtil::detectContainerRuntime);
ContainerRuntimeUtil.ContainerRuntime containerRuntime = ContainerRuntimeUtil.detectContainerRuntime();
commandLine.add(containerRuntime.getExecutableName());

commandLine.add("run");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class BuildAnalyticsConfig {
/**
* The Segment base URI.
*/
@ConfigItem
@ConfigItem(name = "uri.base")
public Optional<String> uriBase;

/**
Expand Down
17 changes: 17 additions & 0 deletions core/runtime/src/main/java/io/quarkus/runtime/LaunchConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.runtime;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;

@ConfigMapping(prefix = "quarkus.launch")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface LaunchConfig {

/**
* If set to true, Quarkus will perform re-augmentation (assuming the {@code mutable-jar} package type is used)
*/
@WithDefault("false")
boolean rebuild();
}
2 changes: 1 addition & 1 deletion devtools/gradle/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugin-publish = "1.2.0"

# updating Kotlin here makes QuarkusPluginTest > shouldNotFailOnProjectDependenciesWithoutMain(Path) fail
kotlin = "1.8.10"
smallrye-config = "3.3.0"
smallrye-config = "3.3.2"

junit5 = "5.9.3"
assertj = "3.24.2"
Expand Down
3 changes: 2 additions & 1 deletion devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,8 @@ private QuarkusDevModeLauncher newLauncher(Boolean debugPortOk, String bootstrap
}

// Add other properties that may be required for expansion
for (String value : effectiveProperties.values()) {
List<String> effectivePropertyValues = new ArrayList<>(effectiveProperties.values());
for (String value : effectivePropertyValues) {
for (String reference : Expression.compile(value, LENIENT_SYNTAX, NO_TRIM).getReferencedStrings()) {
String referenceValue = session.getUserProperties().getProperty(reference);
if (referenceValue != null) {
Expand Down
5 changes: 4 additions & 1 deletion docs/src/main/asciidoc/datasource.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ quarkus.datasource.reactive.max-size=20
----
<1> This configuration value is only required if there is more than one Reactive driver extension on the classpath.

[[configure-datasources]]
== Configure datasources

The following section describes the configuration for single or multiple datasources.
Expand Down Expand Up @@ -431,7 +432,9 @@ You can override this by setting the `transactions` configuration property:
* `quarkus.datasource.jdbc.transactions` for default unnamend datasource
* `quarkus.datasource._<datasource-name>_.jdbc.transactions` for named datasource

See the <<configuration-reference,Configuration Reference>> section below.
For more information, see the <<configuration-reference,Configuration reference>> section below.

To facilitate the storage of transaction logs in a database by using JDBC, see xref:transaction.adoc#jdbcstore[Configuring transaction logs to be stored in a datasource] section of the xref:transaction.adoc[Using transactions in Quarkus] guide.

==== Named datasources

Expand Down
31 changes: 26 additions & 5 deletions docs/src/main/asciidoc/transaction.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -362,15 +362,36 @@ NOTE: The `event` object represents the transaction ID, and defines `toString()`
TIP: In listener methods, you can access more information about the transaction in progress by accessing the `TransactionManager`,
which is a CDI bean and can be ``@Inject``ed.

== Configuring transaction log to be stored in a DataSource
[[jdbcstore]]
== Configure storing of Quarkus transaction logs in a database

The Narayana project has the capability to store the transaction logs into a JDBC Datasource; this should be our recommendation for users needing transaction recovery capabilities, especially when running in volatile containers.
In cloud environments where persistent storage is not available, such as when application containers are unable to use persistent volumes, you can configure the transaction management to store transaction logs in a database by using a JDBC datasource.

To enable this capability, you need to set `quarkus.transaction-manager.object-store.type` to `jdbc` explicitly. Also, you can specify a datasource name to be used for the transaction log storage by setting `quarkus.transaction-manager.object-store.datasource`. It will use the default datasource configuration if not specified.
IMPORTANT: While there are several benefits to using a database to store transaction logs, you might notice a reduction in performance compared with using the file system to store the logs.

If you enable `quarkus.transaction-manager.object-store.create-table`, the transaction log table will be created automatically if it does not exist.
Quarkus allows the following JDBC-specific configuration of the object store included in `quarkus.transacion-manager.object-store.<property>` properties, where <property> can be:

NOTE: When enabling this capability, the transaction node identifier must be set through `quarkus.transaction-manager.node-name`.
* `type` (_string_): Configure this property to `jdbc` to enable usage of a Quarkus JDBC datasource for transaction logging.
The default value is `file-system`.
* `datasource` (_string_): Specify the name of the datasource for the transaction log storage.
If no value is provided for the `datasource` property, Quarkus uses the xref:datasource.adoc#configure-datasources[default datasource].
* `create-table` (_boolean_): When set to `true`, the transaction log table gets automatically created if it does not already exist.
The default value is `false`.
* `drop-table` (_boolean_): When set to `true`, the tables are dropped on startup if they already exist.
The default value is `false`.
* `table-prefix` (string): Specify the prefix for a related table name.
The default value is `quarkus_`.

[NOTE]
====
To work around the current known issue of link:https://issues.redhat.com/browse/AG-209[Agroal having a different view on running transaction checks], set the datasource transaction type for the datasource responsible for writing the transaction logs to `disabled`:
----
quarkus.datasource.TX_LOG.jdbc.transactions=disabled
----
This example uses TX_LOG as the datasource name.
====


== Why always having a transaction manager?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void testImageWithJava17() {
Path path = getPath("openjdk-17-runtime");
var result = sut.determine(path);
assertThat(result).hasValueSatisfying(v -> {
assertThat(v.getBaseImage()).isEqualTo("registry.access.redhat.com/ubi8/openjdk-17-runtime:1.17");
assertThat(v.getBaseImage()).isEqualTo("registry.access.redhat.com/ubi8/openjdk-17-runtime:1.16");
assertThat(v.getJavaVersion()).isEqualTo(17);
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Use Java 17 base image
FROM registry.access.redhat.com/ubi8/openjdk-17-runtime:1.17
FROM registry.access.redhat.com/ubi8/openjdk-17-runtime:1.16

ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class JibConfig {
/**
* The base image to be used when a container image is being produced for the jar build.
*
* When the application is built against Java 17 or higher, {@code registry.access.redhat.com/ubi8/openjdk-17-runtime:1.17}
* When the application is built against Java 17 or higher, {@code registry.access.redhat.com/ubi8/openjdk-17-runtime:1.16}
* is used as the default.
* Otherwise {@code registry.access.redhat.com/ubi8/openjdk-11-runtime:1.16} is used as the default.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class JibProcessor {
private static final IsClassPredicate IS_CLASS_PREDICATE = new IsClassPredicate();
private static final String BINARY_NAME_IN_CONTAINER = "application";

private static final String JAVA_17_BASE_IMAGE = "registry.access.redhat.com/ubi8/openjdk-17-runtime:1.17";
private static final String JAVA_17_BASE_IMAGE = "registry.access.redhat.com/ubi8/openjdk-17-runtime:1.16";
private static final String JAVA_11_BASE_IMAGE = "registry.access.redhat.com/ubi8/openjdk-11-runtime:1.16";
private static final String DEFAULT_BASE_IMAGE_USER = "185";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.xerial.snappy.OSInfo;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
Expand Down Expand Up @@ -95,6 +94,7 @@
import io.quarkus.kafka.client.runtime.KafkaBindingConverter;
import io.quarkus.kafka.client.runtime.KafkaRecorder;
import io.quarkus.kafka.client.runtime.KafkaRuntimeConfigProducer;
import io.quarkus.kafka.client.runtime.SnappyRecorder;
import io.quarkus.kafka.client.runtime.ui.KafkaTopicClient;
import io.quarkus.kafka.client.runtime.ui.KafkaUiRecorder;
import io.quarkus.kafka.client.runtime.ui.KafkaUiUtils;
Expand Down Expand Up @@ -292,7 +292,7 @@ public void build(

}

@BuildStep(onlyIf = { IsSnappy.class, NativeOrNativeSourcesBuild.class })
@BuildStep(onlyIf = { HasSnappy.class, NativeOrNativeSourcesBuild.class })
public void handleSnappyInNative(NativeImageRunnerBuildItem nativeImageRunner,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<NativeImageResourceBuildItem> nativeLibs) {
Expand All @@ -307,19 +307,17 @@ public void handleSnappyInNative(NativeImageRunnerBuildItem nativeImageRunner,
String path = root + dir + "/" + snappyNativeLibraryName;
nativeLibs.produce(new NativeImageResourceBuildItem(path));
} else { // otherwise the native lib of the platform this build runs on
String dir = OSInfo.getNativeLibFolderPathForCurrentOS();
String dir = SnappyUtils.getNativeLibFolderPathForCurrentOS();
String snappyNativeLibraryName = System.mapLibraryName("snappyjava");
String path = root + dir + "/" + snappyNativeLibraryName;
nativeLibs.produce(new NativeImageResourceBuildItem(path));
}
}

@BuildStep
@BuildStep(onlyIf = HasSnappy.class)
@Record(ExecutionTime.RUNTIME_INIT)
void loadSnappyIfEnabled(KafkaRecorder recorder, KafkaBuildTimeConfig config) {
if (config.snappyEnabled) {
recorder.loadSnappy();
}
void loadSnappyIfEnabled(SnappyRecorder recorder, KafkaBuildTimeConfig config) {
recorder.loadSnappy();
}

@Consume(RuntimeConfigSetupCompleteBuildItem.class)
Expand Down Expand Up @@ -585,17 +583,17 @@ public DevConsoleWebjarBuildItem setupWebJar(LaunchModeBuildItem launchModeBuild
.build();
}

public static final class IsSnappy implements BooleanSupplier {
public static final class HasSnappy implements BooleanSupplier {

private final KafkaBuildTimeConfig config;

public IsSnappy(KafkaBuildTimeConfig config) {
public HasSnappy(KafkaBuildTimeConfig config) {
this.config = config;
}

@Override
public boolean getAsBoolean() {
return config.snappyEnabled;
return QuarkusClassLoader.isClassPresentAtRuntime("org.xerial.snappy.OSInfo") && config.snappyEnabled;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.kafka.client.deployment;

import org.xerial.snappy.OSInfo;

/**
* This class should only be used if Snappy is available on the classpath.
*/
public class SnappyUtils {

private SnappyUtils() {
// Avoid direct instantiation
}

public static String getNativeLibFolderPathForCurrentOS() {
return OSInfo.getNativeLibFolderPathForCurrentOS();
}
}
Original file line number Diff line number Diff line change
@@ -1,69 +1,15 @@
package io.quarkus.kafka.client.runtime;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Optional;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.xerial.snappy.OSInfo;
import org.xerial.snappy.SnappyError;
import org.xerial.snappy.SnappyErrorCode;
import org.xerial.snappy.SnappyLoader;

import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class KafkaRecorder {

public void loadSnappy() {
// Resolve the library file name with a suffix (e.g., dll, .so, etc.)
String snappyNativeLibraryName = System.mapLibraryName("snappyjava");
String snappyNativeLibraryPath = "/org/xerial/snappy/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
boolean hasNativeLib = hasResource(snappyNativeLibraryPath + "/" + snappyNativeLibraryName);

if (!hasNativeLib) {
String errorMessage = String.format("no native library is found for os.name=%s and os.arch=%s", OSInfo.getOSName(),
OSInfo.getArchName());
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, errorMessage);
}

File out = extractLibraryFile(
SnappyLoader.class.getResource(snappyNativeLibraryPath + "/" + snappyNativeLibraryName),
snappyNativeLibraryName);

System.load(out.getAbsolutePath());
}

private static boolean hasResource(String path) {
return SnappyLoader.class.getResource(path) != null;
}

private static File extractLibraryFile(URL library, String name) {
String tmp = System.getProperty("java.io.tmpdir");
File extractedLibFile = new File(tmp, name);

try (BufferedInputStream inputStream = new BufferedInputStream(library.openStream());
FileOutputStream fileOS = new FileOutputStream(extractedLibFile)) {
byte[] data = new byte[8192];
int byteContent;
while ((byteContent = inputStream.read(data, 0, 8192)) != -1) {
fileOS.write(data, 0, byteContent);
}
} catch (IOException e) {
throw new UncheckedIOException(
"Unable to extract native library " + name + " to " + extractedLibFile.getAbsolutePath(), e);
}

extractedLibFile.deleteOnExit();

return extractedLibFile;
}

public void checkBoostrapServers() {
Config config = ConfigProvider.getConfig();
Boolean serviceBindingEnabled = config.getValue("quarkus.kubernetes-service-binding.enabled", Boolean.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.quarkus.kafka.client.runtime;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;

import org.xerial.snappy.OSInfo;
import org.xerial.snappy.SnappyLoader;

import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class SnappyRecorder {

public void loadSnappy() {
// Resolve the library file name with a suffix (e.g., dll, .so, etc.)
String snappyNativeLibraryName = System.mapLibraryName("snappyjava");
String snappyNativeLibraryPath = "/org/xerial/snappy/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
boolean hasNativeLib = hasResource(snappyNativeLibraryPath + "/" + snappyNativeLibraryName);

if (!hasNativeLib) {
String errorMessage = String.format("no native library is found for os.name=%s and os.arch=%s", OSInfo.getOSName(),
OSInfo.getArchName());
throw new RuntimeException(errorMessage);
}

File out = extractLibraryFile(
SnappyLoader.class.getResource(snappyNativeLibraryPath + "/" + snappyNativeLibraryName),
snappyNativeLibraryName);

System.load(out.getAbsolutePath());
}

private static boolean hasResource(String path) {
return SnappyLoader.class.getResource(path) != null;
}

private static File extractLibraryFile(URL library, String name) {
String tmp = System.getProperty("java.io.tmpdir");
File extractedLibFile = new File(tmp, name);

try (BufferedInputStream inputStream = new BufferedInputStream(library.openStream());
FileOutputStream fileOS = new FileOutputStream(extractedLibFile)) {
byte[] data = new byte[8192];
int byteContent;
while ((byteContent = inputStream.read(data, 0, 8192)) != -1) {
fileOS.write(data, 0, byteContent);
}
} catch (IOException e) {
throw new UncheckedIOException(
"Unable to extract native library " + name + " to " + extractedLibFile.getAbsolutePath(), e);
}

extractedLibFile.deleteOnExit();

return extractedLibFile;
}
}
Loading

0 comments on commit 7d29dd7

Please sign in to comment.