diff --git a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java index 08ed5e00f0961..83d9f1b865cfa 100644 --- a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java +++ b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java @@ -1,6 +1,9 @@ package io.quarkus.narayana.jta.runtime; import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -29,6 +32,7 @@ @Recorder public class NarayanaJtaRecorder { + public static final String HASH_ALGORITHM_FOR_SHORTENING = "SHA-224"; private static Properties defaultProperties; @@ -37,14 +41,28 @@ public class NarayanaJtaRecorder { public void setNodeName(final TransactionManagerConfiguration transactions) { try { + if (transactions.nodeName.getBytes(StandardCharsets.UTF_8).length > 28 + && transactions.shortenNodeNameIfNecessary) { + shortenNodeName(transactions); + } arjPropertyManager.getCoreEnvironmentBean().setNodeIdentifier(transactions.nodeName); jtaPropertyManager.getJTAEnvironmentBean().setXaRecoveryNodes(Collections.singletonList(transactions.nodeName)); TxControl.setXANodeName(transactions.nodeName); - } catch (CoreEnvironmentBeanException e) { - e.printStackTrace(); + } catch (CoreEnvironmentBeanException | NoSuchAlgorithmException e) { + log.error("Could not set node name", e); } } + private static void shortenNodeName(TransactionManagerConfiguration transactions) throws NoSuchAlgorithmException { + String originalNodeName = transactions.nodeName; + log.warnf("Node name \"%s\" is longer than 28 bytes, shortening it by using %s.", originalNodeName, + HASH_ALGORITHM_FOR_SHORTENING); + final byte[] nodeNameAsBytes = originalNodeName.getBytes(); + MessageDigest messageDigest224 = MessageDigest.getInstance(HASH_ALGORITHM_FOR_SHORTENING); + transactions.nodeName = new String(messageDigest224.digest(nodeNameAsBytes), StandardCharsets.UTF_8); + log.warnf("New node name is \"%s\"", transactions.nodeName); + } + public void setDefaultProperties(Properties properties) { //TODO: this is a huge hack to avoid loading XML parsers //this needs a proper SPI diff --git a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerConfiguration.java b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerConfiguration.java index 86f580ae3a6e4..6719ea8e1d128 100644 --- a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerConfiguration.java +++ b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerConfiguration.java @@ -16,10 +16,24 @@ public final class TransactionManagerConfiguration { /** * The node name used by the transaction manager. + * Must not exceed a length of 28 bytes. + * + * @see #shortenNodeNameIfNecessary */ @ConfigItem(defaultValue = "quarkus") public String nodeName; + /** + * Whether the node name should be shortened if necessary. + * The node name must not exceed a length of 28 bytes. If this property is set to {@code true}, and the node name exceeds 28 + * bytes, the node name is shortened by calculating the SHA-224 hash, + * which has a length of 28 bytes. + * + * @see #nodeName + */ + @ConfigItem(defaultValue = "false") + public boolean shortenNodeNameIfNecessary; + /** * The default transaction timeout. */