From 32a461f3ff172de493fd07d4629069e473e1acb9 Mon Sep 17 00:00:00 2001 From: luisgomez29 Date: Thu, 11 Dec 2025 15:21:08 -0500 Subject: [PATCH 1/2] build(deps): update jackson-databind dependency to latest version --- async/async-commons/async-commons.gradle | 2 +- async/async-rabbit/async-rabbit.gradle | 2 +- async/cloudevents-json-jackson/cloudevents-json-jackson.gradle | 2 +- domain/domain-events/domain-events-api.gradle | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/async/async-commons/async-commons.gradle b/async/async-commons/async-commons.gradle index d6b8d435..381b446b 100644 --- a/async/async-commons/async-commons.gradle +++ b/async/async-commons/async-commons.gradle @@ -9,7 +9,7 @@ dependencies { api project(':cloudevents-json-jackson') compileOnly 'io.projectreactor:reactor-core' - api 'tools.jackson.core:jackson-databind:3.0.3' + api 'tools.jackson.core:jackson-databind' implementation 'commons-io:commons-io:2.21.0' implementation 'io.cloudevents:cloudevents-core:4.0.1' diff --git a/async/async-rabbit/async-rabbit.gradle b/async/async-rabbit/async-rabbit.gradle index a7827a2a..fd887bb1 100644 --- a/async/async-rabbit/async-rabbit.gradle +++ b/async/async-rabbit/async-rabbit.gradle @@ -13,7 +13,7 @@ dependencies { api 'io.projectreactor:reactor-core-micrometer' api 'io.projectreactor.rabbitmq:reactor-rabbitmq:1.5.6' api 'com.rabbitmq:amqp-client' - api 'tools.jackson.core:jackson-databind:3.0.3' + api 'tools.jackson.core:jackson-databind' implementation 'io.cloudevents:cloudevents-core:4.0.1' testImplementation 'io.projectreactor:reactor-test' diff --git a/async/cloudevents-json-jackson/cloudevents-json-jackson.gradle b/async/cloudevents-json-jackson/cloudevents-json-jackson.gradle index a3c85349..161f122a 100644 --- a/async/cloudevents-json-jackson/cloudevents-json-jackson.gradle +++ b/async/cloudevents-json-jackson/cloudevents-json-jackson.gradle @@ -4,7 +4,7 @@ ext { } dependencies { - api 'tools.jackson.core:jackson-databind:3.0.3' + api 'tools.jackson.core:jackson-databind' implementation 'io.cloudevents:cloudevents-api:4.0.1' implementation 'io.cloudevents:cloudevents-core:4.0.1' } \ No newline at end of file diff --git a/domain/domain-events/domain-events-api.gradle b/domain/domain-events/domain-events-api.gradle index 702f146a..7af7f448 100644 --- a/domain/domain-events/domain-events-api.gradle +++ b/domain/domain-events/domain-events-api.gradle @@ -6,5 +6,4 @@ ext { dependencies { api 'org.reactivestreams:reactive-streams:1.0.4' api 'io.cloudevents:cloudevents-api:4.0.1' - implementation 'io.cloudevents:cloudevents-json-jackson:4.0.1' } \ No newline at end of file From 21656f5ff2b450e3d5a6ccb086d2e618717a6965 Mon Sep 17 00:00:00 2001 From: luisgomez29 Date: Fri, 19 Dec 2025 08:31:13 -0500 Subject: [PATCH 2/2] fix: simplify SSL setup in RabbitMQSetupUtils and utilize Netty's SslContext --- .../jackson/CloudEventDeserializer.java | 4 - .../io/cloudevents/jackson/data/Data.java | 2 +- build.gradle | 8 +- main.gradle | 4 +- .../async/rabbit/RabbitMQSetupUtils.java | 105 ++++++------------ 5 files changed, 41 insertions(+), 82 deletions(-) diff --git a/async/cloudevents-json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java b/async/cloudevents-json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java index 11721a38..fb88d10f 100644 --- a/async/cloudevents-json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java +++ b/async/cloudevents-json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java @@ -45,10 +45,6 @@ class CloudEventDeserializer extends StdDeserializer { private final boolean forceIgnoreInvalidExtensionNameDeserialization; private final boolean disableDataContentTypeDefaulting; - protected CloudEventDeserializer() { - this(false, false, false); - } - protected CloudEventDeserializer( boolean forceExtensionNameLowerCaseDeserialization, boolean forceIgnoreInvalidExtensionNameDeserialization, diff --git a/async/cloudevents-json-jackson/src/test/java/io/cloudevents/jackson/data/Data.java b/async/cloudevents-json-jackson/src/test/java/io/cloudevents/jackson/data/Data.java index c3e199ae..acdb70c0 100644 --- a/async/cloudevents-json-jackson/src/test/java/io/cloudevents/jackson/data/Data.java +++ b/async/cloudevents-json-jackson/src/test/java/io/cloudevents/jackson/data/Data.java @@ -125,7 +125,7 @@ public class Data { .withExtension("integer", 42) .withExtension("decimal", new BigDecimal("42.42")) .withExtension("float", 4.2f) - .withExtension("long", new Long(4200)) + .withExtension("long",4200L) .build(); public static Stream allEvents() { diff --git a/build.gradle b/build.gradle index 038feb11..a9ea1222 100644 --- a/build.gradle +++ b/build.gradle @@ -12,10 +12,10 @@ buildscript { plugins { id 'jacoco' - id 'org.sonarqube' version '7.2.0.6526' - id 'org.springframework.boot' version '4.0.0' apply false + id 'org.sonarqube' version '7.2.2.6593' + id 'org.springframework.boot' version '4.0.1' apply false id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' - id 'co.com.bancolombia.cleanArchitecture' version '3.28.0' + id 'co.com.bancolombia.cleanArchitecture' version '4.0.0' } repositories { @@ -23,4 +23,4 @@ repositories { } apply from: './main.gradle' -apply plugin: 'com.github.ben-manes.versions' +apply plugin: 'com.github.ben-manes.versions' \ No newline at end of file diff --git a/main.gradle b/main.gradle index 58b470c0..d7d3d2cd 100644 --- a/main.gradle +++ b/main.gradle @@ -66,7 +66,7 @@ subprojects { testCompileOnly 'org.projectlombok:lombok' } - //TODO: Remove once it has been updated in spring boot 4.0.1 + //TODO: Remove once it has been updated in spring boot ext["rabbit-amqp-client.version"] = '5.28.0' test.finalizedBy(project.tasks.jacocoTestReport) @@ -90,7 +90,7 @@ subprojects { dependencyManagement { imports { - mavenBom 'org.springframework.boot:spring-boot-dependencies:4.0.0' + mavenBom 'org.springframework.boot:spring-boot-dependencies:4.0.1' } } diff --git a/starters/async-rabbit-starter/src/main/java/org/reactivecommons/async/rabbit/RabbitMQSetupUtils.java b/starters/async-rabbit-starter/src/main/java/org/reactivecommons/async/rabbit/RabbitMQSetupUtils.java index 3196a15a..f27f9389 100644 --- a/starters/async-rabbit-starter/src/main/java/org/reactivecommons/async/rabbit/RabbitMQSetupUtils.java +++ b/starters/async-rabbit-starter/src/main/java/org/reactivecommons/async/rabbit/RabbitMQSetupUtils.java @@ -2,6 +2,8 @@ import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.java.Log; @@ -31,24 +33,17 @@ import reactor.rabbitmq.Utils; import reactor.util.retry.Retry; -import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.time.Duration; -import java.util.Arrays; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; @@ -57,29 +52,12 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class RabbitMQSetupUtils { private static final String SHARED_TYPE = "shared"; - private static final String DEFAULT_PROTOCOL; public static final int START_INTERVAL = 300; public static final int MAX_BACKOFF_INTERVAL = 3000; private static final ConcurrentMap FACTORY_CACHE = new ConcurrentHashMap<>(); private static final ConcurrentMap> CONNECTION_CACHE = new ConcurrentHashMap<>(); - static { - String protocol = "TLSv1.1"; - try { - String[] protocols = SSLContext.getDefault().getSupportedSSLParameters().getProtocols(); - for (String prot : protocols) { - if ("TLSv1.2".equals(prot)) { - protocol = "TLSv1.2"; - break; - } - } - } catch (NoSuchAlgorithmException e) { - // nothing - } - DEFAULT_PROTOCOL = protocol; - } - public static ConnectionFactoryProvider connectionFactoryProvider(AsyncProps asyncProps, ConnectionFactoryCustomizer cfCustomizer) { final ConnectionFactory factory = FACTORY_CACHE.computeIfAbsent(asyncProps, props -> { @@ -177,25 +155,32 @@ private static Mono createConnectionMono(ConnectionFactory factory, // SSL based on RabbitConnectionFactoryBean // https://github.com/spring-projects/spring-amqp/blob/main/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/RabbitConnectionFactoryBean.java + // Adapted for Netty: https://www.rabbitmq.com/client-libraries/java-api-guide#netty private static void setUpSSL(ConnectionFactory factory, RabbitProperties properties) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException, + throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException { var ssl = properties.getSsl(); if (ssl != null && ssl.isEnabled()) { - var keyManagers = configureKeyManagers(ssl); - var trustManagers = configureTrustManagers(ssl); - var secureRandom = SecureRandom.getInstanceStrong(); + SslContextBuilder sslContextBuilder = SslContextBuilder.forClient(); + + // Configure TrustManager + var trustManagerFactory = configureTrustManagerFactory(ssl); + sslContextBuilder.trustManager(trustManagerFactory); - if (log.isLoggable(Level.FINE)) { - log.fine("Initializing SSLContext with KM: " + Arrays.toString(keyManagers) + - ", TM: " + Arrays.toString(trustManagers) + ", random: " + secureRandom); + // Configure KeyManager if keystore is provided + if (ssl.getKeyStore() != null) { + var keyManagerFactory = configureKeyManagerFactory(ssl); + sslContextBuilder.keyManager(keyManagerFactory); } - var context = createSSLContext(ssl); - context.init(keyManagers, trustManagers, secureRandom); - factory.useSslProtocol(context); - logDetails(trustManagers); + // Set SSL protocol if specified + if (ssl.getAlgorithm() != null) { + log.info("Using SSL protocol: " + ssl.getAlgorithm()); + } + + SslContext sslContext = sslContextBuilder.build(); + factory.netty().sslContext(sslContext); if (ssl.isVerifyHostname()) { factory.enableHostnameVerification(); @@ -203,28 +188,23 @@ private static void setUpSSL(ConnectionFactory factory, RabbitProperties propert } } - private static KeyManager[] configureKeyManagers(RabbitPropertiesBase.Ssl ssl) throws KeyStoreException, - IOException, - NoSuchAlgorithmException, + private static KeyManagerFactory configureKeyManagerFactory(RabbitPropertiesBase.Ssl ssl) + throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException { - KeyManager[] keyManagers = null; - if (ssl.getKeyStore() != null) { - var ks = KeyStore.getInstance(ssl.getKeyStoreType()); - char[] keyPassphrase = null; - if (ssl.getKeyStorePassword() != null) { - keyPassphrase = ssl.getKeyStorePassword().toCharArray(); - } - try (var inputStream = new FileInputStream(ssl.getKeyStore())) { - ks.load(inputStream, keyPassphrase); - } - var kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, keyPassphrase); - keyManagers = kmf.getKeyManagers(); + var ks = KeyStore.getInstance(ssl.getKeyStoreType()); + char[] keyPassphrase = null; + if (ssl.getKeyStorePassword() != null) { + keyPassphrase = ssl.getKeyStorePassword().toCharArray(); } - return keyManagers; + try (var inputStream = new FileInputStream(ssl.getKeyStore())) { + ks.load(inputStream, keyPassphrase); + } + var kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, keyPassphrase); + return kmf; } - private static TrustManager[] configureTrustManagers(RabbitPropertiesBase.Ssl ssl) + private static TrustManagerFactory configureTrustManagerFactory(RabbitPropertiesBase.Ssl ssl) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { KeyStore tks = null; if (ssl.getTrustStore() != null) { @@ -240,24 +220,7 @@ private static TrustManager[] configureTrustManagers(RabbitPropertiesBase.Ssl ss var tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(tks); - return tmf.getTrustManagers(); - } - - private static SSLContext createSSLContext(RabbitPropertiesBase.Ssl ssl) throws NoSuchAlgorithmException { - return SSLContext.getInstance(ssl.getAlgorithm() != null ? ssl.getAlgorithm() : DEFAULT_PROTOCOL); - } - - private static void logDetails(TrustManager[] managers) { - var found = false; - for (var trustManager : managers) { - if (trustManager instanceof X509TrustManager x509TrustManager) { - found = true; - log.info("Loaded " + x509TrustManager.getAcceptedIssuers().length + " accepted issuers for rabbitmq"); - } - } - if (!found) { - log.warning("No X509TrustManager found in the truststore."); - } + return tmf; } }