From 91b904405c5602120069565ef6ea8a9a50bb6cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 30 Jul 2025 18:56:05 -0600 Subject: [PATCH 01/21] Add support for Rabbitmq AMQP 1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- module/spring-boot-amqp/build.gradle | 1 + .../AmqpEnvironmentBuilderCustomizer.java | 39 ++++ .../RabbitAmqpAutoConfiguration.java | 156 ++++++++++++++ .../RabbitAmqpTemplateCustomizer.java | 36 ++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../RabbitAmqpAutoConfigurationTests.java | 204 ++++++++++++++++++ 6 files changed, 437 insertions(+) create mode 100644 module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java create mode 100644 module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java create mode 100644 module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpTemplateCustomizer.java create mode 100644 module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java diff --git a/module/spring-boot-amqp/build.gradle b/module/spring-boot-amqp/build.gradle index 38d9ce92c820..5ba4de34d294 100644 --- a/module/spring-boot-amqp/build.gradle +++ b/module/spring-boot-amqp/build.gradle @@ -41,6 +41,7 @@ dependencies { optional(project(":module:spring-boot-metrics")) optional("io.micrometer:micrometer-core") optional("org.springframework.amqp:spring-rabbit-stream") + optional("org.springframework.amqp:spring-rabbitmq-client") optional("org.testcontainers:rabbitmq") dockerTestImplementation(project(":test-support:spring-boot-docker-test-support")) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java new file mode 100644 index 000000000000..3a8bbb77b443 --- /dev/null +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.amqp.autoconfigure; + +import com.rabbitmq.client.amqp.Environment; +import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder; + +/** + * Callback interface that can be implemented by beans wishing to customize the + * auto-configured {@link Environment} that is created by an + * {@link AmqpEnvironmentBuilder}. + * + * @author Eddú Meléndez + * @since 4.0.0 + */ +@FunctionalInterface +public interface AmqpEnvironmentBuilderCustomizer { + + /** + * Customize the {@code AmqpEnvironmentBuilder}. + * @param builder the builder to customize + */ + void customize(AmqpEnvironmentBuilder builder); + +} diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java new file mode 100644 index 000000000000..8663557d1a7c --- /dev/null +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.amqp.autoconfigure; + +import com.rabbitmq.client.amqp.Connection; +import com.rabbitmq.client.amqp.CredentialsProvider; +import com.rabbitmq.client.amqp.Environment; +import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder; +import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder.EnvironmentConnectionSettings; + +import org.springframework.amqp.rabbit.config.ContainerCustomizer; +import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder; +import org.springframework.amqp.rabbit.retry.MessageRecoverer; +import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer; +import org.springframework.amqp.rabbitmq.client.AmqpConnectionFactory; +import org.springframework.amqp.rabbitmq.client.RabbitAmqpAdmin; +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; +import org.springframework.amqp.rabbitmq.client.SingleAmqpConnectionFactory; +import org.springframework.amqp.rabbitmq.client.config.RabbitAmqpListenerContainerFactory; +import org.springframework.amqp.rabbitmq.client.listener.RabbitAmqpListenerContainer; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.amqp.autoconfigure.RabbitProperties.ListenerRetry; +import org.springframework.boot.amqp.autoconfigure.RabbitRetryTemplateCustomizer.Target; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.context.annotation.Bean; +import org.springframework.retry.support.RetryTemplate; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitAmqpTemplate}. + * + * @author Eddú Meléndez + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ RabbitAmqpTemplate.class, Connection.class }) +@EnableConfigurationProperties(RabbitProperties.class) +public final class RabbitAmqpAutoConfiguration { + + private final RabbitProperties properties; + + RabbitAmqpAutoConfiguration(RabbitProperties properties) { + this.properties = properties; + } + + @Bean + @ConditionalOnMissingBean + RabbitConnectionDetails rabbitConnectionDetails(ObjectProvider sslBundles) { + return new PropertiesRabbitConnectionDetails(this.properties, sslBundles.getIfAvailable()); + } + + @Bean(name = "rabbitAmqpListenerContainerFactory") + @ConditionalOnMissingBean(name = "rabbitAmqpListenerContainerFactory") + public RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory( + AmqpConnectionFactory connectionFactory, + ObjectProvider> amqpContainerCustomizer, + ObjectProvider retryTemplateCustomizers, + ObjectProvider messageRecoverer) { + RabbitAmqpListenerContainerFactory factory = new RabbitAmqpListenerContainerFactory(connectionFactory); + amqpContainerCustomizer.ifUnique(factory::setContainerCustomizer); + + RabbitProperties.AmqpContainer configuration = this.properties.getListener().getSimple(); + factory.setObservationEnabled(configuration.isObservationEnabled()); + ListenerRetry retryConfig = configuration.getRetry(); + if (retryConfig.isEnabled()) { + RetryInterceptorBuilder builder = (retryConfig.isStateless()) ? RetryInterceptorBuilder.stateless() + : RetryInterceptorBuilder.stateful(); + + RetryTemplate retryTemplate = new RetryTemplateFactory(retryTemplateCustomizers.orderedStream().toList()) + .createRetryTemplate(retryConfig, Target.LISTENER); + + builder.retryOperations(retryTemplate); + MessageRecoverer recoverer = (messageRecoverer.getIfAvailable() != null) ? messageRecoverer.getIfAvailable() + : new RejectAndDontRequeueRecoverer(); + builder.recoverer(recoverer); + factory.setAdviceChain(builder.build()); + } + return factory; + } + + @Bean + @ConditionalOnMissingBean + public Environment rabbitAmqpEnvironment(RabbitConnectionDetails connectionDetails, + ObjectProvider customizers, + ObjectProvider credentialsProvider) { + PropertyMapper map = PropertyMapper.get(); + EnvironmentConnectionSettings environmentConnectionSettings = new AmqpEnvironmentBuilder().connectionSettings(); + Address address = connectionDetails.getFirstAddress(); + map.from(address::host).whenNonNull().to(environmentConnectionSettings::host); + map.from(address::port).to(environmentConnectionSettings::port); + map.from(connectionDetails::getUsername).whenNonNull().to(environmentConnectionSettings::username); + map.from(connectionDetails::getPassword).whenNonNull().to(environmentConnectionSettings::password); + map.from(connectionDetails::getVirtualHost).whenNonNull().to(environmentConnectionSettings::virtualHost); + map.from(credentialsProvider::getIfAvailable) + .whenNonNull() + .to(environmentConnectionSettings::credentialsProvider); + + AmqpEnvironmentBuilder builder = environmentConnectionSettings.environmentBuilder(); + customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + public AmqpConnectionFactory amqpConnection(Environment environment) { + return new SingleAmqpConnectionFactory(environment); + } + + @Bean + @ConditionalOnMissingBean + public RabbitAmqpTemplate rabbitAmqpTemplate(AmqpConnectionFactory connectionFactory, + ObjectProvider customizers, + ObjectProvider messageConverter) { + RabbitAmqpTemplate rabbitAmqpTemplate = new RabbitAmqpTemplate(connectionFactory); + if (messageConverter.getIfAvailable() != null) { + rabbitAmqpTemplate.setMessageConverter(messageConverter.getIfAvailable()); + } + RabbitProperties.Template templateProperties = this.properties.getTemplate(); + + PropertyMapper map = PropertyMapper.get(); + map.from(templateProperties::getDefaultReceiveQueue).whenNonNull().to(rabbitAmqpTemplate::setReceiveQueue); + map.from(templateProperties::getExchange).whenNonNull().to(rabbitAmqpTemplate::setExchange); + map.from(templateProperties::getRoutingKey).to(rabbitAmqpTemplate::setRoutingKey); + + customizers.orderedStream().forEach((customizer) -> customizer.customize(rabbitAmqpTemplate)); + return rabbitAmqpTemplate; + } + + @Bean + @ConditionalOnMissingBean + public RabbitAmqpAdmin rabbitAmqpAdmin(AmqpConnectionFactory connectionFactory) { + return new RabbitAmqpAdmin(connectionFactory); + } + +} diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpTemplateCustomizer.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpTemplateCustomizer.java new file mode 100644 index 000000000000..e1eb2404cbb2 --- /dev/null +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpTemplateCustomizer.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.amqp.autoconfigure; + +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; + +/** + * Callback interface that can be used to customize a {@link RabbitAmqpTemplate}. + * + * @author Eddú Meléndez + * @since 4.0.0 + */ +@FunctionalInterface +public interface RabbitAmqpTemplateCustomizer { + + /** + * Callback to customize a {@link RabbitAmqpTemplate} instance. + * @param rabbitAmqpTemplate the rabbitAmqpTemplate to customize + */ + void customize(RabbitAmqpTemplate rabbitAmqpTemplate); + +} diff --git a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index daf8ae3ba45f..c45ad36ad4d5 100644 --- a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,3 +1,4 @@ org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration +org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration org.springframework.boot.amqp.autoconfigure.health.RabbitHealthContributorAutoConfiguration org.springframework.boot.amqp.autoconfigure.metrics.RabbitMetricsAutoConfiguration \ No newline at end of file diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java new file mode 100644 index 000000000000..af91dbab6751 --- /dev/null +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java @@ -0,0 +1,204 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.amqp.autoconfigure; + +import org.aopalliance.aop.Advice; +import org.junit.jupiter.api.Test; +import org.mockito.InOrder; + +import org.springframework.amqp.core.Message; +import org.springframework.amqp.core.MessageProperties; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.config.BaseRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.config.ContainerCustomizer; +import org.springframework.amqp.rabbitmq.client.AmqpConnectionFactory; +import org.springframework.amqp.rabbitmq.client.RabbitAmqpAdmin; +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; +import org.springframework.amqp.rabbitmq.client.config.RabbitAmqpListenerContainerFactory; +import org.springframework.amqp.rabbitmq.client.listener.RabbitAmqpListenerContainer; +import org.springframework.amqp.support.converter.MessageConversionException; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.retry.RetryPolicy; +import org.springframework.retry.policy.NeverRetryPolicy; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link RabbitAmqpAutoConfiguration}. + * + * @author Eddú Meléndez + */ +class RabbitAmqpAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(RabbitAmqpAutoConfiguration.class)); + + @Test + void testDefaultRabbitAmqpConfiguration() { + this.contextRunner.run((context) -> { + RabbitAmqpListenerContainerFactory listenerContainerFactory = context + .getBean(RabbitAmqpListenerContainerFactory.class); + AmqpConnectionFactory connectionFactory = context.getBean(AmqpConnectionFactory.class); + RabbitAmqpTemplate rabbitAmqpTemplate = context.getBean(RabbitAmqpTemplate.class); + RabbitAmqpAdmin rabbitAmqpAdmin = context.getBean(RabbitAmqpAdmin.class); + + assertThat(listenerContainerFactory).isNotNull(); + assertThat(listenerContainerFactory).extracting("containerCustomizer").isNull(); + assertThat(connectionFactory).isNotNull(); + assertThat(rabbitAmqpTemplate).isNotNull(); + assertThat(rabbitAmqpAdmin).isNotNull(); + }); + } + + @Test + void whenMultipleRabbitAmqpTemplateCustomizersAreDefinedThenTheyAreCalledInOrder() { + this.contextRunner.withUserConfiguration(MultipleRabbitAmqpTemplateCustomizersConfiguration.class) + .run((context) -> { + RabbitAmqpTemplateCustomizer firstCustomizer = context.getBean("firstCustomizer", + RabbitAmqpTemplateCustomizer.class); + RabbitAmqpTemplateCustomizer secondCustomizer = context.getBean("secondCustomizer", + RabbitAmqpTemplateCustomizer.class); + InOrder inOrder = inOrder(firstCustomizer, secondCustomizer); + RabbitAmqpTemplate template = context.getBean(RabbitAmqpTemplate.class); + then(firstCustomizer).should(inOrder).customize(template); + then(secondCustomizer).should(inOrder).customize(template); + inOrder.verifyNoMoreInteractions(); + }); + } + + @Test + void testSimpleRabbitListenerContainerFactoryRetryWithCustomizer() { + this.contextRunner.withUserConfiguration(RabbitRetryTemplateCustomizerConfiguration.class) + .withPropertyValues("spring.rabbitmq.listener.simple.retry.enabled:true") + .run((context) -> { + RabbitAmqpListenerContainerFactory rabbitListenerContainerFactory = context + .getBean("rabbitAmqpListenerContainerFactory", RabbitAmqpListenerContainerFactory.class); + assertListenerRetryTemplate(rabbitListenerContainerFactory, + context.getBean(RabbitRetryTemplateCustomizerConfiguration.class).retryPolicy); + }); + } + + private void assertListenerRetryTemplate(BaseRabbitListenerContainerFactory rabbitListenerContainerFactory, + RetryPolicy retryPolicy) { + Advice[] adviceChain = rabbitListenerContainerFactory.getAdviceChain(); + assertThat(adviceChain).isNotNull(); + assertThat(adviceChain).hasSize(1); + Advice advice = adviceChain[0]; + RetryTemplate retryTemplate = (RetryTemplate) ReflectionTestUtils.getField(advice, "retryOperations"); + assertThat(retryTemplate).hasFieldOrPropertyWithValue("retryPolicy", retryPolicy); + } + + @Test + void testListenerContainerFactoryWithContainerCustomizer() { + this.contextRunner.withUserConfiguration(AmqpContainerCustomizerConfiguration.class).run((context) -> { + RabbitAmqpListenerContainerFactory listenerContainerFactory = context + .getBean(RabbitAmqpListenerContainerFactory.class); + + assertThat(listenerContainerFactory).isNotNull(); + assertThat(listenerContainerFactory).extracting("containerCustomizer").isNotNull(); + }); + } + + @Configuration(proxyBeanMethods = false) + static class MultipleRabbitAmqpTemplateCustomizersConfiguration { + + @Bean + @Order(Ordered.LOWEST_PRECEDENCE) + RabbitAmqpTemplateCustomizer secondCustomizer() { + return mock(RabbitAmqpTemplateCustomizer.class); + } + + @Bean + @Order(0) + RabbitAmqpTemplateCustomizer firstCustomizer() { + return mock(RabbitAmqpTemplateCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class RabbitRetryTemplateCustomizerConfiguration { + + private final RetryPolicy retryPolicy = new NeverRetryPolicy(); + + @Bean + RabbitRetryTemplateCustomizer rabbitListenerRetryTemplateCustomizer() { + return (target, template) -> { + if (target.equals(RabbitRetryTemplateCustomizer.Target.LISTENER)) { + template.setRetryPolicy(this.retryPolicy); + } + }; + } + + } + + @Import(TestListener.class) + @Configuration(proxyBeanMethods = false) + static class AmqpContainerCustomizerConfiguration { + + @Bean + @SuppressWarnings("unchecked") + ContainerCustomizer customizer() { + return mock(ContainerCustomizer.class); + } + + } + + @Configuration + static class CustomMessageConverterConfiguration { + + @Bean + MessageConverter messageConverter() { + return new MessageConverter() { + + @Override + public Message toMessage(Object object, MessageProperties messageProperties) + throws MessageConversionException { + return new Message(object.toString().getBytes()); + } + + @Override + public Object fromMessage(Message message) throws MessageConversionException { + return new String(message.getBody()); + } + + }; + } + + } + + static class TestListener { + + @RabbitListener(queues = "test", autoStartup = "false") + void listen(String in) { + } + + } + +} From 02ba8887fb977fdbee541f3a9906cc8f88971913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 30 Jul 2025 18:56:22 -0600 Subject: [PATCH 02/21] Add smoke test for RabbitMQ AMQP 1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- settings.gradle | 1 + .../build.gradle | 34 +++++++++++ ...ampleRabbitAmqpSimpleApplicationTests.java | 54 ++++++++++++++++ .../SampleRabbitAmqpSimpleApplication.java | 61 +++++++++++++++++++ .../src/main/java/smoketest/amqp/Sender.java | 31 ++++++++++ 5 files changed, 181 insertions(+) create mode 100644 smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle create mode 100644 smoke-test/spring-boot-smoke-test-rabbit-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java create mode 100644 smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java create mode 100644 smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/Sender.java diff --git a/settings.gradle b/settings.gradle index 65e82571407d..ec7d0fefcb08 100644 --- a/settings.gradle +++ b/settings.gradle @@ -331,6 +331,7 @@ include ":smoke-test:spring-boot-smoke-test-prometheus" include ":smoke-test:spring-boot-smoke-test-property-validation" include ":smoke-test:spring-boot-smoke-test-pulsar" include ":smoke-test:spring-boot-smoke-test-quartz" +include ":smoke-test:spring-boot-smoke-test-rabbit-amqp" include ":smoke-test:spring-boot-smoke-test-reactive-oauth2-client" include ":smoke-test:spring-boot-smoke-test-reactive-oauth2-resource-server" include ":smoke-test:spring-boot-smoke-test-rsocket" diff --git a/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle b/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle new file mode 100644 index 000000000000..305f0a702e5c --- /dev/null +++ b/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle @@ -0,0 +1,34 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id "java" + id "org.springframework.boot.docker-test" +} + +description = "Spring Boot RabbitMQ AMQP smoke test" + +dependencies { + implementation(project(":starter:spring-boot-starter-amqp")) + implementation("org.springframework.amqp:spring-rabbitmq-client") + + dockerTestImplementation(project(":starter:spring-boot-starter-test")) + dockerTestImplementation(project(":core:spring-boot-testcontainers")) + dockerTestImplementation(project(":test-support:spring-boot-docker-test-support")) + dockerTestImplementation("org.awaitility:awaitility") + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:rabbitmq") +} \ No newline at end of file diff --git a/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java new file mode 100644 index 000000000000..d5ef51eff469 --- /dev/null +++ b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.amqp; + +import java.time.Duration; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.RabbitMQContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@Testcontainers(disabledWithoutDocker = true) +@ExtendWith(OutputCaptureExtension.class) +class SampleRabbitAmqpSimpleApplicationTests { + + @Container + @ServiceConnection + static final RabbitMQContainer rabbit = new RabbitMQContainer("rabbitmq:4.0-management-alpine"); + + @Autowired + private Sender sender; + + @Test + void sendSimpleMessage(CapturedOutput output) { + this.sender.send("Test message"); + Awaitility.waitAtMost(Duration.ofMinutes(1)).untilAsserted(() -> assertThat(output).contains("Test message")); + } + +} diff --git a/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java new file mode 100644 index 000000000000..aff9bc342e3b --- /dev/null +++ b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.amqp; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.messaging.handler.annotation.Payload; + +@SpringBootApplication +@RabbitListener(queues = "foo") +public class SampleRabbitAmqpSimpleApplication { + + private static final Log logger = LogFactory.getLog(SampleRabbitAmqpSimpleApplication.class); + + @Bean + public Sender mySender() { + return new Sender(); + } + + @Bean + public Queue fooQueue() { + return new Queue("foo"); + } + + @RabbitHandler + public void process(@Payload String foo) { + logger.info(foo); + } + + @Bean + public ApplicationRunner runner(Sender sender) { + return (args) -> sender.send("Hello"); + } + + public static void main(String[] args) { + SpringApplication.run(SampleRabbitAmqpSimpleApplication.class, args); + } + +} diff --git a/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/Sender.java b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/Sender.java new file mode 100644 index 000000000000..6639bc0316ce --- /dev/null +++ b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/Sender.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.amqp; + +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; +import org.springframework.beans.factory.annotation.Autowired; + +public class Sender { + + @Autowired + private RabbitAmqpTemplate rabbitAmqpTemplate; + + public void send(String message) { + this.rabbitAmqpTemplate.convertAndSend("foo", message); + } + +} From 93d232d91059199ad2684bd0e1c0a7feba39cd24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 30 Jul 2025 19:17:55 -0600 Subject: [PATCH 03/21] Fix checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../autoconfigure/RabbitAmqpAutoConfiguration.java | 10 +++++----- ...mework.boot.autoconfigure.AutoConfiguration.imports | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java index 8663557d1a7c..d45179242597 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -72,7 +72,7 @@ RabbitConnectionDetails rabbitConnectionDetails(ObjectProvider sslBu @Bean(name = "rabbitAmqpListenerContainerFactory") @ConditionalOnMissingBean(name = "rabbitAmqpListenerContainerFactory") - public RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory( + RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory( AmqpConnectionFactory connectionFactory, ObjectProvider> amqpContainerCustomizer, ObjectProvider retryTemplateCustomizers, @@ -101,7 +101,7 @@ public RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory( @Bean @ConditionalOnMissingBean - public Environment rabbitAmqpEnvironment(RabbitConnectionDetails connectionDetails, + Environment rabbitAmqpEnvironment(RabbitConnectionDetails connectionDetails, ObjectProvider customizers, ObjectProvider credentialsProvider) { PropertyMapper map = PropertyMapper.get(); @@ -123,13 +123,13 @@ public Environment rabbitAmqpEnvironment(RabbitConnectionDetails connectionDetai @Bean @ConditionalOnMissingBean - public AmqpConnectionFactory amqpConnection(Environment environment) { + AmqpConnectionFactory amqpConnection(Environment environment) { return new SingleAmqpConnectionFactory(environment); } @Bean @ConditionalOnMissingBean - public RabbitAmqpTemplate rabbitAmqpTemplate(AmqpConnectionFactory connectionFactory, + RabbitAmqpTemplate rabbitAmqpTemplate(AmqpConnectionFactory connectionFactory, ObjectProvider customizers, ObjectProvider messageConverter) { RabbitAmqpTemplate rabbitAmqpTemplate = new RabbitAmqpTemplate(connectionFactory); @@ -149,7 +149,7 @@ public RabbitAmqpTemplate rabbitAmqpTemplate(AmqpConnectionFactory connectionFac @Bean @ConditionalOnMissingBean - public RabbitAmqpAdmin rabbitAmqpAdmin(AmqpConnectionFactory connectionFactory) { + RabbitAmqpAdmin rabbitAmqpAdmin(AmqpConnectionFactory connectionFactory) { return new RabbitAmqpAdmin(connectionFactory); } diff --git a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index c45ad36ad4d5..febc373b38a8 100644 --- a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,4 +1,4 @@ -org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration +org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration org.springframework.boot.amqp.autoconfigure.health.RabbitHealthContributorAutoConfiguration org.springframework.boot.amqp.autoconfigure.metrics.RabbitMetricsAutoConfiguration \ No newline at end of file From 6572c3635c576901d85a434c9eb3c7ad630e8f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Mon, 4 Aug 2025 21:53:51 -0600 Subject: [PATCH 04/21] Fix comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../RabbitAmqpAutoConfiguration.java | 23 ++----------------- .../RabbitAmqpAutoConfigurationTests.java | 12 ---------- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java index d45179242597..e629f77c8db6 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -23,9 +23,7 @@ import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder.EnvironmentConnectionSettings; import org.springframework.amqp.rabbit.config.ContainerCustomizer; -import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder; import org.springframework.amqp.rabbit.retry.MessageRecoverer; -import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer; import org.springframework.amqp.rabbitmq.client.AmqpConnectionFactory; import org.springframework.amqp.rabbitmq.client.RabbitAmqpAdmin; import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; @@ -35,8 +33,6 @@ import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; -import org.springframework.boot.amqp.autoconfigure.RabbitProperties.ListenerRetry; -import org.springframework.boot.amqp.autoconfigure.RabbitRetryTemplateCustomizer.Target; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -45,7 +41,6 @@ import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; -import org.springframework.retry.support.RetryTemplate; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitAmqpTemplate}. @@ -53,7 +48,7 @@ * @author Eddú Meléndez * @since 4.0.0 */ -@AutoConfiguration +@AutoConfiguration(before = RabbitAutoConfiguration.class) @ConditionalOnClass({ RabbitAmqpTemplate.class, Connection.class }) @EnableConfigurationProperties(RabbitProperties.class) public final class RabbitAmqpAutoConfiguration { @@ -82,20 +77,6 @@ RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory( RabbitProperties.AmqpContainer configuration = this.properties.getListener().getSimple(); factory.setObservationEnabled(configuration.isObservationEnabled()); - ListenerRetry retryConfig = configuration.getRetry(); - if (retryConfig.isEnabled()) { - RetryInterceptorBuilder builder = (retryConfig.isStateless()) ? RetryInterceptorBuilder.stateless() - : RetryInterceptorBuilder.stateful(); - - RetryTemplate retryTemplate = new RetryTemplateFactory(retryTemplateCustomizers.orderedStream().toList()) - .createRetryTemplate(retryConfig, Target.LISTENER); - - builder.retryOperations(retryTemplate); - MessageRecoverer recoverer = (messageRecoverer.getIfAvailable() != null) ? messageRecoverer.getIfAvailable() - : new RejectAndDontRequeueRecoverer(); - builder.recoverer(recoverer); - factory.setAdviceChain(builder.build()); - } return factory; } @@ -123,7 +104,7 @@ Environment rabbitAmqpEnvironment(RabbitConnectionDetails connectionDetails, @Bean @ConditionalOnMissingBean - AmqpConnectionFactory amqpConnection(Environment environment) { + AmqpConnectionFactory amqpConnectionFactory(Environment environment) { return new SingleAmqpConnectionFactory(environment); } diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java index af91dbab6751..fbc7a2b75f2f 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java @@ -92,18 +92,6 @@ void whenMultipleRabbitAmqpTemplateCustomizersAreDefinedThenTheyAreCalledInOrder }); } - @Test - void testSimpleRabbitListenerContainerFactoryRetryWithCustomizer() { - this.contextRunner.withUserConfiguration(RabbitRetryTemplateCustomizerConfiguration.class) - .withPropertyValues("spring.rabbitmq.listener.simple.retry.enabled:true") - .run((context) -> { - RabbitAmqpListenerContainerFactory rabbitListenerContainerFactory = context - .getBean("rabbitAmqpListenerContainerFactory", RabbitAmqpListenerContainerFactory.class); - assertListenerRetryTemplate(rabbitListenerContainerFactory, - context.getBean(RabbitRetryTemplateCustomizerConfiguration.class).retryPolicy); - }); - } - private void assertListenerRetryTemplate(BaseRabbitListenerContainerFactory rabbitListenerContainerFactory, RetryPolicy retryPolicy) { Advice[] adviceChain = rabbitListenerContainerFactory.getAdviceChain(); From a3913a1d9530dc41978f9a1d3adc938f35ca702f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Tue, 5 Aug 2025 14:47:47 -0600 Subject: [PATCH 05/21] Fix format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java index e629f77c8db6..4515a902d0a1 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -67,8 +67,7 @@ RabbitConnectionDetails rabbitConnectionDetails(ObjectProvider sslBu @Bean(name = "rabbitAmqpListenerContainerFactory") @ConditionalOnMissingBean(name = "rabbitAmqpListenerContainerFactory") - RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory( - AmqpConnectionFactory connectionFactory, + RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory(AmqpConnectionFactory connectionFactory, ObjectProvider> amqpContainerCustomizer, ObjectProvider retryTemplateCustomizers, ObjectProvider messageRecoverer) { From f983ae2c75b192dc3b4f5027ddfc618870c3ceea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 6 Aug 2025 15:44:55 -0600 Subject: [PATCH 06/21] Autoconfigure only AMQP 1.0 or 0.9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- module/spring-boot-amqp/build.gradle | 3 +-- .../amqp/autoconfigure/RabbitAmqpAutoConfiguration.java | 4 ++-- .../boot/amqp/autoconfigure/RabbitAutoConfiguration.java | 4 ++++ .../amqp/autoconfigure/RabbitAutoConfigurationTests.java | 4 +++- .../amqp/autoconfigure/RabbitStreamConfigurationTests.java | 5 ++++- .../RabbitHealthContributorAutoConfigurationTests.java | 6 +++++- ...csAutoConfigurationMeterBinderCycleIntegrationTests.java | 3 +++ .../metrics/RabbitMetricsAutoConfigurationTests.java | 6 +++++- 8 files changed, 27 insertions(+), 8 deletions(-) diff --git a/module/spring-boot-amqp/build.gradle b/module/spring-boot-amqp/build.gradle index 5ba4de34d294..9a1901534343 100644 --- a/module/spring-boot-amqp/build.gradle +++ b/module/spring-boot-amqp/build.gradle @@ -28,7 +28,7 @@ description = "Spring Boot AMQP" dependencies { api(project(":core:spring-boot")) api("org.springframework:spring-messaging") - api("org.springframework.amqp:spring-rabbit") + api("org.springframework.amqp:spring-rabbitmq-client") compileOnly("com.fasterxml.jackson.core:jackson-annotations") @@ -41,7 +41,6 @@ dependencies { optional(project(":module:spring-boot-metrics")) optional("io.micrometer:micrometer-core") optional("org.springframework.amqp:spring-rabbit-stream") - optional("org.springframework.amqp:spring-rabbitmq-client") optional("org.testcontainers:rabbitmq") dockerTestImplementation(project(":test-support:spring-boot-docker-test-support")) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java index 4515a902d0a1..5170d2ef872e 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -65,8 +65,8 @@ RabbitConnectionDetails rabbitConnectionDetails(ObjectProvider sslBu return new PropertiesRabbitConnectionDetails(this.properties, sslBundles.getIfAvailable()); } - @Bean(name = "rabbitAmqpListenerContainerFactory") - @ConditionalOnMissingBean(name = "rabbitAmqpListenerContainerFactory") + @Bean(name = "rabbitListenerContainerFactory") + @ConditionalOnMissingBean(name = "rabbitListenerContainerFactory") RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory(AmqpConnectionFactory connectionFactory, ObjectProvider> amqpContainerCustomizer, ObjectProvider retryTemplateCustomizers, diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java index 159245f42cfc..aebe4e54c080 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java @@ -36,6 +36,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.ssl.SslBundles; @@ -71,10 +72,13 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Scott Frederick + * @author Eddú Meléndez * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ RabbitTemplate.class, Channel.class }) +@ConditionalOnMissingClass({ "com.rabbitmq.client.amqp.Connection", + "org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate" }) @EnableConfigurationProperties(RabbitProperties.class) @Import({ RabbitAnnotationDrivenConfiguration.class, RabbitStreamConfiguration.class }) public final class RabbitAutoConfiguration { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java index 56f57061096e..e8f8843b9fbb 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java @@ -115,13 +115,15 @@ * @author Phillip Webb * @author Scott Frederick * @author Yanming Zhou + * @author Eddú Meléndez */ @ExtendWith(OutputCaptureExtension.class) class RabbitAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, SslAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader("org.springframework.rabbit.stream")); // gh-38750 + .withClassLoader(new FilteredClassLoader("org.springframework.rabbit.stream", "com.rabbitmq.client.amqp", + "org.springframework.amqp.rabbitmq.client")); // gh-38750 @Test void testDefaultRabbitConfiguration() { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java index 27bbc9918845..3c256a173fe3 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java @@ -33,6 +33,7 @@ import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -60,7 +61,9 @@ class RabbitStreamConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class)) + .withClassLoader( + new FilteredClassLoader("com.rabbitmq.client.amqp", "org.springframework.amqp.rabbitmq.client")); @Test @SuppressWarnings("unchecked") diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java index 8739399d0aae..62636bdfd00d 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java @@ -22,6 +22,7 @@ import org.springframework.boot.amqp.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -30,12 +31,15 @@ * Tests for {@link RabbitHealthContributorAutoConfiguration}. * * @author Phillip Webb + * @author Eddú Meléndez */ class RabbitHealthContributorAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, - RabbitHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class)); + RabbitHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class)) + .withClassLoader( + new FilteredClassLoader("com.rabbitmq.client.amqp", "org.springframework.amqp.rabbitmq.client")); @Test void runShouldCreateIndicator() { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java index 76c0f82e5987..a65e3d31c815 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java @@ -24,6 +24,7 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,8 +37,10 @@ * dependency cycle when used with {@link MeterBinder}. * * @author Phillip Webb + * @author Eddú Meléndez * @see gh-30636 */ +@ClassPathExclusions(files = "spring-rabbitmq-client-*.jar", packages = "com.rabbitmq.client.amqp") class RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests { @Test diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java index fea709700fc0..3d90d386bb29 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java @@ -25,6 +25,7 @@ import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -35,6 +36,7 @@ * Tests for {@link RabbitMetricsAutoConfiguration}. * * @author Stephane Nicoll + * @author Eddú Meléndez */ class RabbitMetricsAutoConfigurationTests { @@ -42,7 +44,9 @@ class RabbitMetricsAutoConfigurationTests { .withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, RabbitMetricsAutoConfiguration.class, MetricsAutoConfiguration.class)) - .withPropertyValues("management.metrics.use-global-registry=false"); + .withPropertyValues("management.metrics.use-global-registry=false") + .withClassLoader( + new FilteredClassLoader("com.rabbitmq.client.amqp", "org.springframework.amqp.rabbitmq.client")); @Test void autoConfiguredConnectionFactoryIsInstrumented() { From db4589278ed10567568287ab6a46e45d2d29bcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 6 Aug 2025 15:45:40 -0600 Subject: [PATCH 07/21] Add new starter for rabbitmq 0.9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- settings.gradle | 1 + .../spring-boot-starter-rabbitmq/build.gradle | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 starter/spring-boot-starter-rabbitmq/build.gradle diff --git a/settings.gradle b/settings.gradle index ec7d0fefcb08..850d472783b0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -234,6 +234,7 @@ include "starter:spring-boot-starter-pulsar" include "starter:spring-boot-starter-pulsar-reactive" include "starter:spring-boot-starter-quartz" include "starter:spring-boot-starter-r2dbc" +include "starter:spring-boot-starter-rabbitmq" include "starter:spring-boot-starter-reactor" include "starter:spring-boot-starter-reactor-netty" include "starter:spring-boot-starter-restclient" diff --git a/starter/spring-boot-starter-rabbitmq/build.gradle b/starter/spring-boot-starter-rabbitmq/build.gradle new file mode 100644 index 000000000000..cd27bb185ec9 --- /dev/null +++ b/starter/spring-boot-starter-rabbitmq/build.gradle @@ -0,0 +1,30 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id "org.springframework.boot.starter" +} + +description = "Starter for using Spring AMQP and Rabbit MQ" + +dependencies { + api(project(":starter:spring-boot-starter")) + + api(project(":module:spring-boot-amqp")) { + exclude group: "org.springframework.amqp", module: "spring-rabbitmq-client" + } + api("org.springframework.amqp:spring-rabbit") +} From b6ec014eca236fb5815936dcfa11a5bf69c27fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 6 Aug 2025 15:46:09 -0600 Subject: [PATCH 08/21] Use new starter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- smoke-test/spring-boot-smoke-test-amqp/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smoke-test/spring-boot-smoke-test-amqp/build.gradle b/smoke-test/spring-boot-smoke-test-amqp/build.gradle index edf318600ce7..1616a33fa649 100644 --- a/smoke-test/spring-boot-smoke-test-amqp/build.gradle +++ b/smoke-test/spring-boot-smoke-test-amqp/build.gradle @@ -22,7 +22,7 @@ plugins { description = "Spring Boot AMQP smoke test" dependencies { - implementation(project(":starter:spring-boot-starter-amqp")) + implementation(project(":starter:spring-boot-starter-rabbitmq")) dockerTestImplementation(project(":starter:spring-boot-starter-test")) dockerTestImplementation(project(":core:spring-boot-testcontainers")) From 58692fb6247a2b33fe978dc1bc324e59963e6ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 6 Aug 2025 15:46:36 -0600 Subject: [PATCH 09/21] Update smoke test rabbit amqp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle | 1 - .../java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle b/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle index 305f0a702e5c..d4d9a57a60a1 100644 --- a/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle +++ b/smoke-test/spring-boot-smoke-test-rabbit-amqp/build.gradle @@ -23,7 +23,6 @@ description = "Spring Boot RabbitMQ AMQP smoke test" dependencies { implementation(project(":starter:spring-boot-starter-amqp")) - implementation("org.springframework.amqp:spring-rabbitmq-client") dockerTestImplementation(project(":starter:spring-boot-starter-test")) dockerTestImplementation(project(":core:spring-boot-testcontainers")) diff --git a/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java index aff9bc342e3b..258131766e21 100644 --- a/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java +++ b/smoke-test/spring-boot-smoke-test-rabbit-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.amqp.core.Queue; +import org.springframework.amqp.rabbit.annotation.EnableRabbit; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.boot.ApplicationRunner; @@ -29,6 +30,7 @@ import org.springframework.messaging.handler.annotation.Payload; @SpringBootApplication +@EnableRabbit @RabbitListener(queues = "foo") public class SampleRabbitAmqpSimpleApplication { From 2644bc2065b43a15b20223a4035d48ec11ccaae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Fri, 8 Aug 2025 15:23:30 -0600 Subject: [PATCH 10/21] Fix starter's description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- starter/spring-boot-starter-amqp/build.gradle | 2 +- starter/spring-boot-starter-rabbitmq/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/starter/spring-boot-starter-amqp/build.gradle b/starter/spring-boot-starter-amqp/build.gradle index bd8d7c906e19..13a1e0d9974c 100644 --- a/starter/spring-boot-starter-amqp/build.gradle +++ b/starter/spring-boot-starter-amqp/build.gradle @@ -18,7 +18,7 @@ plugins { id "org.springframework.boot.starter" } -description = "Starter for using Spring AMQP and Rabbit MQ" +description = "Starter for using Spring AMQP with Rabbit MQ over AMQP 1.0 protocol" dependencies { api(project(":starter:spring-boot-starter")) diff --git a/starter/spring-boot-starter-rabbitmq/build.gradle b/starter/spring-boot-starter-rabbitmq/build.gradle index cd27bb185ec9..2f29ebb4d920 100644 --- a/starter/spring-boot-starter-rabbitmq/build.gradle +++ b/starter/spring-boot-starter-rabbitmq/build.gradle @@ -18,7 +18,7 @@ plugins { id "org.springframework.boot.starter" } -description = "Starter for using Spring AMQP and Rabbit MQ" +description = "Starter for using Spring AMQP with Rabbit MQ over AMQP 0.9.1 protocol" dependencies { api(project(":starter:spring-boot-starter")) From b3b1d45785ea936dde9b5824b18edf6e01316ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Tue, 12 Aug 2025 12:20:25 -0600 Subject: [PATCH 11/21] Switch to ConditionalOnMissingBean MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../boot/amqp/autoconfigure/RabbitAutoConfiguration.java | 5 ++--- .../amqp/autoconfigure/RabbitAutoConfigurationTests.java | 4 +--- .../amqp/autoconfigure/RabbitStreamConfigurationTests.java | 5 +---- .../RabbitHealthContributorAutoConfigurationTests.java | 6 +----- ...csAutoConfigurationMeterBinderCycleIntegrationTests.java | 3 --- .../metrics/RabbitMetricsAutoConfigurationTests.java | 6 +----- 6 files changed, 6 insertions(+), 23 deletions(-) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java index aebe4e54c080..9e4b8fd12c5b 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java @@ -29,6 +29,7 @@ import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate; import org.springframework.amqp.rabbit.core.RabbitOperations; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -36,7 +37,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.ssl.SslBundles; @@ -77,8 +77,7 @@ */ @AutoConfiguration @ConditionalOnClass({ RabbitTemplate.class, Channel.class }) -@ConditionalOnMissingClass({ "com.rabbitmq.client.amqp.Connection", - "org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate" }) +@ConditionalOnMissingBean(type = "org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate") @EnableConfigurationProperties(RabbitProperties.class) @Import({ RabbitAnnotationDrivenConfiguration.class, RabbitStreamConfiguration.class }) public final class RabbitAutoConfiguration { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java index e8f8843b9fbb..56f57061096e 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java @@ -115,15 +115,13 @@ * @author Phillip Webb * @author Scott Frederick * @author Yanming Zhou - * @author Eddú Meléndez */ @ExtendWith(OutputCaptureExtension.class) class RabbitAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, SslAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader("org.springframework.rabbit.stream", "com.rabbitmq.client.amqp", - "org.springframework.amqp.rabbitmq.client")); // gh-38750 + .withClassLoader(new FilteredClassLoader("org.springframework.rabbit.stream")); // gh-38750 @Test void testDefaultRabbitConfiguration() { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java index 3c256a173fe3..27bbc9918845 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java @@ -33,7 +33,6 @@ import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -61,9 +60,7 @@ class RabbitStreamConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class)) - .withClassLoader( - new FilteredClassLoader("com.rabbitmq.client.amqp", "org.springframework.amqp.rabbitmq.client")); + .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class)); @Test @SuppressWarnings("unchecked") diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java index 62636bdfd00d..8739399d0aae 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java @@ -22,7 +22,6 @@ import org.springframework.boot.amqp.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -31,15 +30,12 @@ * Tests for {@link RabbitHealthContributorAutoConfiguration}. * * @author Phillip Webb - * @author Eddú Meléndez */ class RabbitHealthContributorAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, - RabbitHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class)) - .withClassLoader( - new FilteredClassLoader("com.rabbitmq.client.amqp", "org.springframework.amqp.rabbitmq.client")); + RabbitHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class)); @Test void runShouldCreateIndicator() { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java index a65e3d31c815..76c0f82e5987 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java @@ -24,7 +24,6 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -37,10 +36,8 @@ * dependency cycle when used with {@link MeterBinder}. * * @author Phillip Webb - * @author Eddú Meléndez * @see gh-30636 */ -@ClassPathExclusions(files = "spring-rabbitmq-client-*.jar", packages = "com.rabbitmq.client.amqp") class RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests { @Test diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java index 3d90d386bb29..fea709700fc0 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java @@ -25,7 +25,6 @@ import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,7 +35,6 @@ * Tests for {@link RabbitMetricsAutoConfiguration}. * * @author Stephane Nicoll - * @author Eddú Meléndez */ class RabbitMetricsAutoConfigurationTests { @@ -44,9 +42,7 @@ class RabbitMetricsAutoConfigurationTests { .withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, RabbitMetricsAutoConfiguration.class, MetricsAutoConfiguration.class)) - .withPropertyValues("management.metrics.use-global-registry=false") - .withClassLoader( - new FilteredClassLoader("com.rabbitmq.client.amqp", "org.springframework.amqp.rabbitmq.client")); + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void autoConfiguredConnectionFactoryIsInstrumented() { From b97cd4838d7a17623ebb2bf7f46fe8d90f495200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Tue, 12 Aug 2025 12:38:50 -0600 Subject: [PATCH 12/21] Fix checkstyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../boot/amqp/autoconfigure/RabbitAutoConfiguration.java | 1 - 1 file changed, 1 deletion(-) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java index 9e4b8fd12c5b..616418ac68c4 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java @@ -29,7 +29,6 @@ import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate; import org.springframework.amqp.rabbit.core.RabbitOperations; import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; From a10a54f7b9edfab05bf3361ead2522d44365cca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 09:19:52 -0600 Subject: [PATCH 13/21] spring-boot-amqp -> spring-boot-rabbitmq and spring-boot-amqp host AMQP 1.0 implementation --- .../reference/pages/actuator/endpoints.adoc | 2 +- .../pages/features/dev-services.adoc | 2 +- .../reference/pages/messaging/amqp.adoc | 16 +- .../pages/testing/testcontainers.adoc | 2 +- ...nectionDetailsFactoryIntegrationTests.java | 1 + ...nectionDetailsFactoryIntegrationTests.java | 1 + .../AmqpEnvironmentBuilderCustomizer.java | 2 +- .../RabbitAmqpAutoConfiguration.java | 25 +- .../main/resources/META-INF/spring.factories | 5 +- ...ot.autoconfigure.AutoConfiguration.imports | 1 - .../RabbitAmqpAutoConfigurationTests.java | 23 +- .../compose/RabbitEnvironmentTests.java | 2 + module/spring-boot-rabbitmq/build.gradle | 65 + ...nectionDetailsFactoryIntegrationTests.java | 51 + ...nectionDetailsFactoryIntegrationTests.java | 6 +- ...nectionDetailsFactoryIntegrationTests.java | 99 ++ .../src/dockerTest/resources/logback-test.xml | 4 + .../docker/compose/rabbit-compose.yaml | 8 + .../dockerTest/resources/spring.properties | 1 + .../AbstractConnectionFactoryConfigurer.java | 2 +- ...bitListenerContainerFactoryConfigurer.java | 6 +- .../AmqpEnvironmentBuilderCustomizer.java | 39 + .../CachingConnectionFactoryConfigurer.java | 2 +- .../ConnectionFactoryCustomizer.java | 2 +- ...bitListenerContainerFactoryConfigurer.java | 2 +- .../EnvironmentBuilderCustomizer.java | 2 +- .../PropertiesRabbitConnectionDetails.java | 88 ++ .../RabbitAmqpTemplateCustomizer.java | 36 + .../RabbitAnnotationDrivenConfiguration.java | 2 +- .../RabbitAutoConfiguration.java | 2 +- .../RabbitConnectionDetails.java | 96 ++ ...RabbitConnectionFactoryBeanConfigurer.java | 4 +- ...RabbitListenerRetrySettingsCustomizer.java | 2 +- .../autoconfigure/RabbitProperties.java | 1364 +++++++++++++++++ .../RabbitRetryTemplateSettings.java | 2 +- .../RabbitStreamConfiguration.java | 4 +- .../RabbitStreamTemplateConfigurer.java | 2 +- .../RabbitTemplateConfigurer.java | 2 +- .../RabbitTemplateCustomizer.java | 2 +- ...RabbitTemplateRetrySettingsCustomizer.java | 2 +- ...bitListenerContainerFactoryConfigurer.java | 2 +- .../SslBundleRabbitConnectionFactoryBean.java | 2 +- ...bitHealthContributorAutoConfiguration.java | 6 +- .../autoconfigure/health/package-info.java | 2 +- ...ConnectionFactoryMetricsPostProcessor.java | 4 +- .../RabbitMetricsAutoConfiguration.java | 4 +- .../autoconfigure/metrics/package-info.java | 2 +- .../rabbitmq/autoconfigure/package-info.java | 23 + ...DockerComposeConnectionDetailsFactory.java | 90 ++ .../docker/compose/RabbitEnvironment.java | 50 + .../rabbitmq/docker/compose/package-info.java | 23 + .../health/RabbitHealthIndicator.java | 2 +- .../boot/rabbitmq}/health/package-info.java | 2 +- .../boot/rabbitmq}/metrics/RabbitMetrics.java | 2 +- .../boot/rabbitmq}/metrics/package-info.java | 2 +- ...bbitContainerConnectionDetailsFactory.java | 85 + ...bbitContainerConnectionDetailsFactory.java | 82 + .../rabbitmq/testcontainers/package-info.java | 23 + ...itional-spring-configuration-metadata.json | 0 .../main/resources/META-INF/spring.factories | 5 + ...ot.autoconfigure.AutoConfiguration.imports | 3 + ...ropertiesRabbitConnectionDetailsTests.java | 4 +- .../RabbitAutoConfigurationTests.java | 2 +- .../autoconfigure/RabbitPropertiesTests.java | 2 +- .../RabbitStreamConfigurationTests.java | 2 +- ...althContributorAutoConfigurationTests.java | 6 +- ...ationMeterBinderCycleIntegrationTests.java | 4 +- .../RabbitMetricsAutoConfigurationTests.java | 4 +- .../compose/RabbitEnvironmentTests.java | 72 + .../health/RabbitHealthIndicatorTests.java | 2 +- .../rabbitmq}/metrics/RabbitMetricsTests.java | 2 +- .../src/test/resources/logback-test.xml | 4 + .../boot/rabbitmq/autoconfigure/test.jks | Bin 0 -> 1294 bytes settings.gradle | 5 +- .../spring-boot-smoke-test-amqp/build.gradle | 8 +- ...ampleRabbitAmqpSimpleApplicationTests.java | 2 +- .../SampleRabbitAmqpSimpleApplication.java | 0 .../src/main/java/smoketest/amqp/Sender.java | 6 +- .../build.gradle | 20 +- .../SampleAmqpSimpleApplicationSslTests.java | 0 .../SampleAmqpSimpleApplicationTests.java | 0 .../amqp/SecureRabbitMqContainer.java | 0 .../amqp/SampleAmqpSimpleApplication.java | 0 .../src/main/java/smoketest/amqp/Sender.java | 6 +- .../java/smoketest/amqp/package-info.java | 20 + .../src/test/resources/ssl/rabbitmq.conf | 0 .../src/test/resources/ssl/test-ca.crt | 0 .../src/test/resources/ssl/test-ca.key | 0 .../src/test/resources/ssl/test-client.crt | 0 .../src/test/resources/ssl/test-client.key | 0 .../src/test/resources/ssl/test-server.crt | 0 .../src/test/resources/ssl/test-server.key | 0 .../build.gradle | 28 + .../spring-boot-starter-rabbitmq/build.gradle | 2 +- 94 files changed, 2472 insertions(+), 122 deletions(-) create mode 100644 module/spring-boot-rabbitmq/build.gradle create mode 100644 module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java (93%) create mode 100644 module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java create mode 100644 module/spring-boot-rabbitmq/src/dockerTest/resources/logback-test.xml create mode 100644 module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-compose.yaml create mode 100644 module/spring-boot-rabbitmq/src/dockerTest/resources/spring.properties rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/AbstractConnectionFactoryConfigurer.java (98%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java (96%) create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/CachingConnectionFactoryConfigurer.java (98%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/ConnectionFactoryCustomizer.java (95%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java (97%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/EnvironmentBuilderCustomizer.java (95%) create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetails.java create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitAnnotationDrivenConfiguration.java (99%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitAutoConfiguration.java (99%) create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionDetails.java rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java (98%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitListenerRetrySettingsCustomizer.java (95%) create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitProperties.java rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitRetryTemplateSettings.java (96%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitStreamConfiguration.java (97%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitStreamTemplateConfigurer.java (98%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitTemplateConfigurer.java (99%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitTemplateCustomizer.java (94%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java (95%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java (97%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/SslBundleRabbitConnectionFactoryBean.java (96%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java (91%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/health/package-info.java (91%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java (96%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java (93%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/autoconfigure/metrics/package-info.java (91%) create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/package-info.java create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironment.java create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/package-info.java rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/health/RabbitHealthIndicator.java (97%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/health/package-info.java (93%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/metrics/RabbitMetrics.java (97%) rename module/{spring-boot-amqp/src/main/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq}/metrics/package-info.java (93%) create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactory.java create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java create mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/package-info.java rename module/{spring-boot-amqp => spring-boot-rabbitmq}/src/main/resources/META-INF/additional-spring-configuration-metadata.json (100%) create mode 100644 module/spring-boot-rabbitmq/src/main/resources/META-INF/spring.factories create mode 100644 module/spring-boot-rabbitmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/PropertiesRabbitConnectionDetailsTests.java (95%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitAutoConfigurationTests.java (99%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitPropertiesTests.java (99%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/RabbitStreamConfigurationTests.java (99%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java (89%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java (94%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java (95%) create mode 100644 module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironmentTests.java rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/health/RabbitHealthIndicatorTests.java (98%) rename module/{spring-boot-amqp/src/test/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq}/metrics/RabbitMetricsTests.java (97%) create mode 100644 module/spring-boot-rabbitmq/src/test/resources/logback-test.xml create mode 100644 module/spring-boot-rabbitmq/src/test/resources/org/springframework/boot/rabbitmq/autoconfigure/test.jks rename smoke-test/{spring-boot-smoke-test-rabbit-amqp => spring-boot-smoke-test-amqp}/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java (97%) rename smoke-test/{spring-boot-smoke-test-rabbit-amqp => spring-boot-smoke-test-amqp}/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java (100%) rename smoke-test/{spring-boot-smoke-test-rabbit-amqp => spring-boot-smoke-test-rabbitmq}/build.gradle (69%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/dockerTest/java/smoketest/amqp/SampleAmqpSimpleApplicationSslTests.java (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/dockerTest/java/smoketest/amqp/SampleAmqpSimpleApplicationTests.java (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/dockerTest/java/smoketest/amqp/SecureRabbitMqContainer.java (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/main/java/smoketest/amqp/SampleAmqpSimpleApplication.java (100%) rename smoke-test/{spring-boot-smoke-test-rabbit-amqp => spring-boot-smoke-test-rabbitmq}/src/main/java/smoketest/amqp/Sender.java (82%) create mode 100644 smoke-test/spring-boot-smoke-test-rabbitmq/src/main/java/smoketest/amqp/package-info.java rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/rabbitmq.conf (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/test-ca.crt (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/test-ca.key (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/test-client.crt (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/test-client.key (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/test-server.crt (100%) rename smoke-test/{spring-boot-smoke-test-amqp => spring-boot-smoke-test-rabbitmq}/src/test/resources/ssl/test-server.key (100%) create mode 100644 starter/spring-boot-starter-rabbitmq-test/build.gradle diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc index 57c74d4e94df..acf1f83f6625 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc @@ -670,7 +670,7 @@ with the `key` listed in the following table: | Always responds with `UP`. | `rabbit` -| javadoc:org.springframework.boot.amqp.health.RabbitHealthIndicator[] +| javadoc:org.springframework.boot.rabbitmq.health.RabbitHealthIndicator[] | Checks that a Rabbit server is up. | `redis` diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc index 18f1940d7957..d18aca724188 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc @@ -125,7 +125,7 @@ The following service connections are currently supported: | javadoc:org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails[] | Containers named "clickhouse/clickhouse-server", "gvenzl/oracle-free", "gvenzl/oracle-xe", "mariadb", "mssql/server", "mysql", or "postgres" -| javadoc:org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails[] +| javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails[] | Containers named "rabbitmq" | javadoc:org.springframework.boot.data.redis.autoconfigure.DataRedisConnectionDetails[] diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/amqp.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/amqp.adoc index 56b05eeb7b8e..2089dd80b512 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/amqp.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/amqp.adoc @@ -38,12 +38,12 @@ spring: NOTE: When specifying addresses that way, the `host` and `port` properties are ignored. If the address uses the `amqps` protocol, SSL support is enabled automatically. -See javadoc:org.springframework.boot.amqp.autoconfigure.RabbitProperties[] for more of the supported property-based configuration options. -To configure lower-level details of the RabbitMQ javadoc:com.rabbitmq.client.ConnectionFactory[] that is used by Spring AMQP, define a javadoc:org.springframework.boot.amqp.autoconfigure.ConnectionFactoryCustomizer[] bean. +See javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties[] for more of the supported property-based configuration options. +To configure lower-level details of the RabbitMQ javadoc:com.rabbitmq.client.ConnectionFactory[] that is used by Spring AMQP, define a javadoc:org.springframework.boot.rabbitmq.autoconfigure.ConnectionFactoryCustomizer[] bean. If a javadoc:org.springframework.amqp.rabbit.connection.ConnectionNameStrategy[] bean exists in the context, it will be automatically used to name connections created by the auto-configured javadoc:org.springframework.amqp.rabbit.connection.CachingConnectionFactory[]. -To make an application-wide, additive customization to the javadoc:org.springframework.amqp.rabbit.core.RabbitTemplate[], use a javadoc:org.springframework.boot.amqp.autoconfigure.RabbitTemplateCustomizer[] bean. +To make an application-wide, additive customization to the javadoc:org.springframework.amqp.rabbit.core.RabbitTemplate[], use a javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitTemplateCustomizer[] bean. TIP: See https://spring.io/blog/2010/06/14/understanding-amqp-the-protocol-used-by-rabbitmq/[Understanding AMQP, the protocol used by RabbitMQ] for more details. @@ -74,9 +74,9 @@ spring: ---- Retries are disabled by default. -You can also customize the javadoc:org.springframework.core.retry.RetryTemplate[] programmatically by declaring a javadoc:org.springframework.boot.amqp.autoconfigure.RabbitTemplateRetrySettingsCustomizer[] bean. +You can also customize the javadoc:org.springframework.core.retry.RetryTemplate[] programmatically by declaring a javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitTemplateRetrySettingsCustomizer[] bean. -If you need to create more javadoc:org.springframework.amqp.rabbit.core.RabbitTemplate[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.amqp.autoconfigure.RabbitTemplateConfigurer[] bean that you can use to initialize a javadoc:org.springframework.amqp.rabbit.core.RabbitTemplate[] with the same settings as the factories used by the auto-configuration. +If you need to create more javadoc:org.springframework.amqp.rabbit.core.RabbitTemplate[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitTemplateConfigurer[] bean that you can use to initialize a javadoc:org.springframework.amqp.rabbit.core.RabbitTemplate[] with the same settings as the factories used by the auto-configuration. @@ -95,7 +95,7 @@ spring: If a javadoc:org.springframework.amqp.support.converter.MessageConverter[], javadoc:org.springframework.rabbit.stream.support.converter.StreamMessageConverter[], or javadoc:org.springframework.rabbit.stream.producer.ProducerCustomizer[] bean is defined, it is associated automatically to the auto-configured javadoc:org.springframework.rabbit.stream.producer.RabbitStreamTemplate[]. -If you need to create more javadoc:org.springframework.rabbit.stream.producer.RabbitStreamTemplate[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.amqp.autoconfigure.RabbitStreamTemplateConfigurer[] bean that you can use to initialize a javadoc:org.springframework.rabbit.stream.producer.RabbitStreamTemplate[] with the same settings as the factories used by the auto-configuration. +If you need to create more javadoc:org.springframework.rabbit.stream.producer.RabbitStreamTemplate[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamTemplateConfigurer[] bean that you can use to initialize a javadoc:org.springframework.rabbit.stream.producer.RabbitStreamTemplate[] with the same settings as the factories used by the auto-configuration. @@ -112,7 +112,7 @@ include-code::MyBean[] TIP: See javadoc:org.springframework.amqp.rabbit.annotation.EnableRabbit[format=annotation] for more details. -If you need to create more javadoc:org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.amqp.autoconfigure.SimpleRabbitListenerContainerFactoryConfigurer[] and a javadoc:org.springframework.boot.amqp.autoconfigure.DirectRabbitListenerContainerFactoryConfigurer[] that you can use to initialize a javadoc:org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory[] and a javadoc:org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory[] with the same settings as the factories used by the auto-configuration. +If you need to create more javadoc:org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.rabbitmq.autoconfigure.SimpleRabbitListenerContainerFactoryConfigurer[] and a javadoc:org.springframework.boot.rabbitmq.autoconfigure.DirectRabbitListenerContainerFactoryConfigurer[] that you can use to initialize a javadoc:org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory[] and a javadoc:org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory[] with the same settings as the factories used by the auto-configuration. TIP: It does not matter which container type you chose. Those two beans are exposed by the auto-configuration. @@ -129,7 +129,7 @@ You can enable retries to handle situations where your listener throws an except By default, javadoc:org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer[] is used, but you can define a javadoc:org.springframework.amqp.rabbit.retry.MessageRecoverer[] of your own. When retries are exhausted, the message is rejected and either dropped or routed to a dead-letter exchange if the broker is configured to do so. By default, retries are disabled. -You can also customize the javadoc:org.springframework.core.retry.RetryPolicy[] programmatically by declaring a javadoc:org.springframework.boot.amqp.autoconfigure.RabbitListenerRetrySettingsCustomizer[] bean. +You can also customize the javadoc:org.springframework.core.retry.RetryPolicy[] programmatically by declaring a javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitListenerRetrySettingsCustomizer[] bean. IMPORTANT: By default, if retries are disabled and the listener throws an exception, the delivery is retried indefinitely. You can modify this behavior in two ways: Set the `defaultRequeueRejected` property to `false` so that zero re-deliveries are attempted or throw an javadoc:org.springframework.amqp.AmqpRejectAndDontRequeueException[] to signal the message should be rejected. diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc index 4df927c0a0b5..79c5c9fe01de 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc @@ -173,7 +173,7 @@ javadoc:org.testcontainers.clickhouse.ClickHouseContainer[], javadoc:{url-testcontainers-mariadb-javadoc}/org.testcontainers.mariadb.MariaDBContainer[], javadoc:{url-testcontainers-mssqlserver-javadoc}/org.testcontainers.mssqlserver.MSSQLServerContainer[], javadoc:{url-testcontainers-mysql-javadoc}/org.testcontainers.mysql.MySQLContainer[], javadoc:org.testcontainers.oracle.OracleContainer[OracleContainer (free)], javadoc:{url-testcontainers-oracle-xe-javadoc}/org.testcontainers.containers.OracleContainer[OracleContainer (XE)] or javadoc:{url-testcontainers-postgresql-javadoc}/org.testcontainers.postgresql.PostgreSQLContainer[] -| javadoc:org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails[] +| javadoc:org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails[] | Containers of type javadoc:{url-testcontainers-rabbitmq-javadoc}/org.testcontainers.rabbitmq.RabbitMQContainer[] | javadoc:org.springframework.boot.data.redis.autoconfigure.DataRedisConnectionDetails[] diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java index fbf86b3889dd..10f40f0fd384 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -18,6 +18,7 @@ import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.amqp.docker.compose.RabbitDockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java index 898f9fad3dc5..023419ae3b3a 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java index 3a8bbb77b443..1403d61f19ea 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AmqpEnvironmentBuilderCustomizer.java @@ -25,7 +25,7 @@ * {@link AmqpEnvironmentBuilder}. * * @author Eddú Meléndez - * @since 4.0.0 + * @since 4.1.0 */ @FunctionalInterface public interface AmqpEnvironmentBuilderCustomizer { diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java index 5170d2ef872e..40f96c8b4e51 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -23,7 +23,6 @@ import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder.EnvironmentConnectionSettings; import org.springframework.amqp.rabbit.config.ContainerCustomizer; -import org.springframework.amqp.rabbit.retry.MessageRecoverer; import org.springframework.amqp.rabbitmq.client.AmqpConnectionFactory; import org.springframework.amqp.rabbitmq.client.RabbitAmqpAdmin; import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; @@ -46,9 +45,9 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitAmqpTemplate}. * * @author Eddú Meléndez - * @since 4.0.0 + * @since 4.1.0 */ -@AutoConfiguration(before = RabbitAutoConfiguration.class) +@AutoConfiguration @ConditionalOnClass({ RabbitAmqpTemplate.class, Connection.class }) @EnableConfigurationProperties(RabbitProperties.class) public final class RabbitAmqpAutoConfiguration { @@ -68,9 +67,7 @@ RabbitConnectionDetails rabbitConnectionDetails(ObjectProvider sslBu @Bean(name = "rabbitListenerContainerFactory") @ConditionalOnMissingBean(name = "rabbitListenerContainerFactory") RabbitAmqpListenerContainerFactory rabbitAmqpListenerContainerFactory(AmqpConnectionFactory connectionFactory, - ObjectProvider> amqpContainerCustomizer, - ObjectProvider retryTemplateCustomizers, - ObjectProvider messageRecoverer) { + ObjectProvider> amqpContainerCustomizer) { RabbitAmqpListenerContainerFactory factory = new RabbitAmqpListenerContainerFactory(connectionFactory); amqpContainerCustomizer.ifUnique(factory::setContainerCustomizer); @@ -87,14 +84,12 @@ Environment rabbitAmqpEnvironment(RabbitConnectionDetails connectionDetails, PropertyMapper map = PropertyMapper.get(); EnvironmentConnectionSettings environmentConnectionSettings = new AmqpEnvironmentBuilder().connectionSettings(); Address address = connectionDetails.getFirstAddress(); - map.from(address::host).whenNonNull().to(environmentConnectionSettings::host); + map.from(address::host).to(environmentConnectionSettings::host); map.from(address::port).to(environmentConnectionSettings::port); - map.from(connectionDetails::getUsername).whenNonNull().to(environmentConnectionSettings::username); - map.from(connectionDetails::getPassword).whenNonNull().to(environmentConnectionSettings::password); - map.from(connectionDetails::getVirtualHost).whenNonNull().to(environmentConnectionSettings::virtualHost); - map.from(credentialsProvider::getIfAvailable) - .whenNonNull() - .to(environmentConnectionSettings::credentialsProvider); + map.from(connectionDetails::getUsername).to(environmentConnectionSettings::username); + map.from(connectionDetails::getPassword).to(environmentConnectionSettings::password); + map.from(connectionDetails::getVirtualHost).to(environmentConnectionSettings::virtualHost); + map.from(credentialsProvider::getIfAvailable).to(environmentConnectionSettings::credentialsProvider); AmqpEnvironmentBuilder builder = environmentConnectionSettings.environmentBuilder(); customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); @@ -119,8 +114,8 @@ RabbitAmqpTemplate rabbitAmqpTemplate(AmqpConnectionFactory connectionFactory, RabbitProperties.Template templateProperties = this.properties.getTemplate(); PropertyMapper map = PropertyMapper.get(); - map.from(templateProperties::getDefaultReceiveQueue).whenNonNull().to(rabbitAmqpTemplate::setReceiveQueue); - map.from(templateProperties::getExchange).whenNonNull().to(rabbitAmqpTemplate::setExchange); + map.from(templateProperties::getDefaultReceiveQueue).to(rabbitAmqpTemplate::setReceiveQueue); + map.from(templateProperties::getExchange).to(rabbitAmqpTemplate::setExchange); map.from(templateProperties::getRoutingKey).to(rabbitAmqpTemplate::setRoutingKey); customizers.orderedStream().forEach((customizer) -> customizer.customize(rabbitAmqpTemplate)); diff --git a/module/spring-boot-amqp/src/main/resources/META-INF/spring.factories b/module/spring-boot-amqp/src/main/resources/META-INF/spring.factories index f086b1a88ce8..26349b11ffa2 100644 --- a/module/spring-boot-amqp/src/main/resources/META-INF/spring.factories +++ b/module/spring-boot-amqp/src/main/resources/META-INF/spring.factories @@ -1,5 +1,4 @@ # Connection Details Factories org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ -org.springframework.boot.amqp.docker.compose.RabbitDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.amqp.testcontainers.DeprecatedRabbitContainerConnectionDetailsFactory,\ -org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory +org.springframework.boot.rabbitmq.docker.compose.RabbitDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory \ No newline at end of file diff --git a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index febc373b38a8..c301889a23c3 100644 --- a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,4 +1,3 @@ org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration -org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration org.springframework.boot.amqp.autoconfigure.health.RabbitHealthContributorAutoConfiguration org.springframework.boot.amqp.autoconfigure.metrics.RabbitMetricsAutoConfiguration \ No newline at end of file diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java index fbc7a2b75f2f..bb553d5eb081 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java @@ -32,6 +32,8 @@ import org.springframework.amqp.rabbitmq.client.listener.RabbitAmqpListenerContainer; import org.springframework.amqp.support.converter.MessageConversionException; import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration; +import org.springframework.boot.amqp.autoconfigure.RabbitAmqpTemplateCustomizer; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -39,9 +41,8 @@ import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; -import org.springframework.retry.RetryPolicy; -import org.springframework.retry.policy.NeverRetryPolicy; -import org.springframework.retry.support.RetryTemplate; +import org.springframework.core.retry.RetryPolicy; +import org.springframework.core.retry.RetryTemplate; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -130,22 +131,6 @@ RabbitAmqpTemplateCustomizer firstCustomizer() { } - @Configuration(proxyBeanMethods = false) - static class RabbitRetryTemplateCustomizerConfiguration { - - private final RetryPolicy retryPolicy = new NeverRetryPolicy(); - - @Bean - RabbitRetryTemplateCustomizer rabbitListenerRetryTemplateCustomizer() { - return (target, template) -> { - if (target.equals(RabbitRetryTemplateCustomizer.Target.LISTENER)) { - template.setRetryPolicy(this.retryPolicy); - } - }; - } - - } - @Import(TestListener.class) @Configuration(proxyBeanMethods = false) static class AmqpContainerCustomizerConfiguration { diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java index 1ecb0b4d6ff4..5c10aaf910ab 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java @@ -21,6 +21,8 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.amqp.docker.compose.RabbitEnvironment; + import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/module/spring-boot-rabbitmq/build.gradle b/module/spring-boot-rabbitmq/build.gradle new file mode 100644 index 000000000000..018fda1e6280 --- /dev/null +++ b/module/spring-boot-rabbitmq/build.gradle @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id "java-library" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot RabbiqMQ" + +dependencies { + api(project(":core:spring-boot")) + api("org.springframework:spring-messaging") + api("org.springframework.amqp:spring-rabbitmq-client") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + implementation(project(":module:spring-boot-transaction")) + + optional(project(":core:spring-boot-autoconfigure")) + optional(project(":core:spring-boot-docker-compose")) + optional(project(":core:spring-boot-testcontainers")) + optional(project(":module:spring-boot-health")) + optional(project(":module:spring-boot-micrometer-metrics")) + optional("io.micrometer:micrometer-core") + optional("org.springframework.amqp:spring-rabbit-stream") + optional("org.testcontainers:testcontainers-rabbitmq") + + dockerTestImplementation(project(":test-support:spring-boot-docker-test-support")) + dockerTestImplementation(testFixtures(project(":core:spring-boot-docker-compose"))) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.testcontainers:testcontainers-junit-jupiter") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":core:spring-boot-test")) + testImplementation(project(":test-support:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} + +tasks.named("compileTestJava") { + options.nullability.checking = "tests" +} + +tasks.named("compileDockerTestJava") { + options.nullability.checking = "tests" +} diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java new file mode 100644 index 000000000000..3ac846109087 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.docker.compose; + +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.testsupport.container.TestImage; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link RabbitDockerComposeConnectionDetailsFactory}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class RabbitDockerComposeConnectionDetailsFactoryIntegrationTests { + + @DockerComposeTest(composeFile = "rabbit-compose.yaml", image = TestImage.RABBITMQ) + void runCreatesConnectionDetails(RabbitConnectionDetails connectionDetails) { + assertConnectionDetails(connectionDetails); + } + + private void assertConnectionDetails(RabbitConnectionDetails connectionDetails) { + assertThat(connectionDetails.getUsername()).isEqualTo("myuser"); + assertThat(connectionDetails.getPassword()).isEqualTo("secret"); + assertThat(connectionDetails.getVirtualHost()).isEqualTo("/"); + assertThat(connectionDetails.getAddresses()).hasSize(1); + Address address = connectionDetails.getFirstAddress(); + assertThat(address.host()).isNotNull(); + assertThat(address.port()).isGreaterThan(0); + } + +} diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java index 51e32711184d..facdc9cda997 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.testcontainers; +package org.springframework.boot.rabbitmq.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -30,8 +30,8 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java new file mode 100644 index 000000000000..c3d624598131 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.testcontainers; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.rabbitmq.RabbitMQContainer; + +import org.springframework.amqp.rabbit.annotation.Queue; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link RabbitContainerConnectionDetailsFactory}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + */ +@SpringJUnitConfig +@Testcontainers(disabledWithoutDocker = true) +class RabbitContainerConnectionDetailsFactoryIntegrationTests { + + @Container + @ServiceConnection + static final RabbitMQContainer rabbit = TestImage.container(RabbitMQContainer.class); + + @Autowired(required = false) + private RabbitConnectionDetails connectionDetails; + + @Autowired + private RabbitTemplate rabbitTemplate; + + @Autowired + private TestListener listener; + + @Test + void connectionCanBeMadeToRabbitContainer() { + assertThat(this.connectionDetails).isNotNull(); + this.rabbitTemplate.convertAndSend("test", "message"); + Awaitility.waitAtMost(Duration.ofMinutes(4)) + .untilAsserted(() -> assertThat(this.listener.messages).containsExactly("message")); + + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration(RabbitAutoConfiguration.class) + static class TestConfiguration { + + @Bean + TestListener testListener() { + return new TestListener(); + } + + } + + static class TestListener { + + private final List messages = new ArrayList<>(); + + @RabbitListener(queuesToDeclare = @Queue("test")) + void processMessage(String message) { + this.messages.add(message); + } + + } + +} diff --git a/module/spring-boot-rabbitmq/src/dockerTest/resources/logback-test.xml b/module/spring-boot-rabbitmq/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-compose.yaml b/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-compose.yaml new file mode 100644 index 000000000000..1951fba4bb08 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-compose.yaml @@ -0,0 +1,8 @@ +services: + rabbitmq: + image: '{imageName}' + environment: + - 'RABBITMQ_DEFAULT_USER=myuser' + - 'RABBITMQ_DEFAULT_PASS=secret' + ports: + - '5672' diff --git a/module/spring-boot-rabbitmq/src/dockerTest/resources/spring.properties b/module/spring-boot-rabbitmq/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractConnectionFactoryConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AbstractConnectionFactoryConfigurer.java similarity index 98% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractConnectionFactoryConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AbstractConnectionFactoryConfigurer.java index 07b17ce5a9a1..dd3ae0e53623 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractConnectionFactoryConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AbstractConnectionFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.util.stream.Collectors; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java similarity index 96% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java index 21ebe011dda3..c427732825ea 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.util.List; import java.util.concurrent.Executor; @@ -27,8 +27,8 @@ import org.springframework.amqp.rabbit.retry.MessageRecoverer; import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer; import org.springframework.amqp.support.converter.MessageConverter; -import org.springframework.boot.amqp.autoconfigure.RabbitProperties.ListenerRetry; -import org.springframework.boot.amqp.autoconfigure.RabbitProperties.Retry; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.ListenerRetry; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.Retry; import org.springframework.boot.retry.RetryPolicySettings; import org.springframework.core.retry.RetryPolicy; import org.springframework.util.Assert; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java new file mode 100644 index 000000000000..8fd969bcce3a --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.autoconfigure; + +import com.rabbitmq.client.amqp.Environment; +import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder; + +/** + * Callback interface that can be implemented by beans wishing to customize the + * auto-configured {@link Environment} that is created by an + * {@link AmqpEnvironmentBuilder}. + * + * @author Eddú Meléndez + * @since 4.0.0 + */ +@FunctionalInterface +public interface AmqpEnvironmentBuilderCustomizer { + + /** + * Customize the {@code AmqpEnvironmentBuilder}. + * @param builder the builder to customize + */ + void customize(AmqpEnvironmentBuilder builder); + +} diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/CachingConnectionFactoryConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/CachingConnectionFactoryConfigurer.java similarity index 98% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/CachingConnectionFactoryConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/CachingConnectionFactoryConfigurer.java index 2221595f78d1..923ba0dd1483 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/CachingConnectionFactoryConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/CachingConnectionFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.time.Duration; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/ConnectionFactoryCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/ConnectionFactoryCustomizer.java similarity index 95% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/ConnectionFactoryCustomizer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/ConnectionFactoryCustomizer.java index 15f2e14dfff8..229f46fa6b3b 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/ConnectionFactoryCustomizer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/ConnectionFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import com.rabbitmq.client.ConnectionFactory; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java similarity index 97% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java index e4057b5c2ecf..5f467163a189 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/EnvironmentBuilderCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/EnvironmentBuilderCustomizer.java similarity index 95% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/EnvironmentBuilderCustomizer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/EnvironmentBuilderCustomizer.java index 8d5f2373cd8e..3bc11bb9d393 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/EnvironmentBuilderCustomizer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/EnvironmentBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import com.rabbitmq.stream.Environment; import com.rabbitmq.stream.EnvironmentBuilder; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetails.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetails.java new file mode 100644 index 000000000000..3e3900f8a475 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetails.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.autoconfigure; + +import java.util.ArrayList; +import java.util.List; + +import org.jspecify.annotations.Nullable; + +import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.Ssl; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Adapts {@link RabbitProperties} to {@link RabbitConnectionDetails}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + */ +class PropertiesRabbitConnectionDetails implements RabbitConnectionDetails { + + private final RabbitProperties properties; + + private final @Nullable SslBundles sslBundles; + + PropertiesRabbitConnectionDetails(RabbitProperties properties, @Nullable SslBundles sslBundles) { + this.properties = properties; + this.sslBundles = sslBundles; + } + + @Override + public String getUsername() { + return this.properties.determineUsername(); + } + + @Override + public @Nullable String getPassword() { + return this.properties.determinePassword(); + } + + @Override + public @Nullable String getVirtualHost() { + return this.properties.determineVirtualHost(); + } + + @Override + public List
getAddresses() { + List
addresses = new ArrayList<>(); + for (String address : this.properties.determineAddresses()) { + int portSeparatorIndex = address.lastIndexOf(':'); + String host = address.substring(0, portSeparatorIndex); + String port = address.substring(portSeparatorIndex + 1); + addresses.add(new Address(host, Integer.parseInt(port))); + } + return addresses; + } + + @Override + public @Nullable SslBundle getSslBundle() { + Ssl ssl = this.properties.getSsl(); + if (!ssl.determineEnabled()) { + return null; + } + if (StringUtils.hasLength(ssl.getBundle())) { + Assert.notNull(this.sslBundles, "SSL bundle name has been set but no SSL bundles found in context"); + return this.sslBundles.getBundle(ssl.getBundle()); + } + return null; + } + +} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java new file mode 100644 index 000000000000..108734d55eb3 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.autoconfigure; + +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; + +/** + * Callback interface that can be used to customize a {@link RabbitAmqpTemplate}. + * + * @author Eddú Meléndez + * @since 4.0.0 + */ +@FunctionalInterface +public interface RabbitAmqpTemplateCustomizer { + + /** + * Callback to customize a {@link RabbitAmqpTemplate} instance. + * @param rabbitAmqpTemplate the rabbitAmqpTemplate to customize + */ + void customize(RabbitAmqpTemplate rabbitAmqpTemplate); + +} diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAnnotationDrivenConfiguration.java similarity index 99% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAnnotationDrivenConfiguration.java index def138432fbf..7dea48ddc311 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAnnotationDrivenConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.springframework.amqp.rabbit.annotation.EnableRabbit; import org.springframework.amqp.rabbit.config.ContainerCustomizer; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAutoConfiguration.java similarity index 99% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAutoConfiguration.java index ee5f822acf9c..837df7a5e6f9 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import com.rabbitmq.client.Channel; import com.rabbitmq.client.impl.CredentialsProvider; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionDetails.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionDetails.java new file mode 100644 index 000000000000..401cb302eddc --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionDetails.java @@ -0,0 +1,96 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.autoconfigure; + +import java.util.List; + +import org.jspecify.annotations.Nullable; + +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.util.Assert; + +/** + * Details required to establish a connection to a RabbitMQ service. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +public interface RabbitConnectionDetails extends ConnectionDetails { + + /** + * Login user to authenticate to the broker. + * @return the login user to authenticate to the broker or {@code null} + */ + default @Nullable String getUsername() { + return null; + } + + /** + * Login to authenticate against the broker. + * @return the login to authenticate against the broker or {@code null} + */ + default @Nullable String getPassword() { + return null; + } + + /** + * Virtual host to use when connecting to the broker. + * @return the virtual host to use when connecting to the broker or {@code null} + */ + default @Nullable String getVirtualHost() { + return null; + } + + /** + * List of addresses to which the client should connect. Must return at least one + * address. + * @return the list of addresses to which the client should connect + */ + List
getAddresses(); + + /** + * Returns the first address. + * @return the first address + * @throws IllegalStateException if the address list is empty + */ + default Address getFirstAddress() { + List
addresses = getAddresses(); + Assert.state(!addresses.isEmpty(), "Address list is empty"); + return addresses.get(0); + } + + /** + * SSL bundle to use. + * @return the SSL bundle to use + */ + default @Nullable SslBundle getSslBundle() { + return null; + } + + /** + * A RabbitMQ address. + * + * @param host the host + * @param port the port + */ + record Address(String host, int port) { + } + +} diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java similarity index 98% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java index de03b57613ca..2187838ee69d 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.time.Duration; @@ -23,7 +23,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitListenerRetrySettingsCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitListenerRetrySettingsCustomizer.java similarity index 95% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitListenerRetrySettingsCustomizer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitListenerRetrySettingsCustomizer.java index 8a3bc26dd23e..50a9232ef978 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitListenerRetrySettingsCustomizer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitListenerRetrySettingsCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.springframework.boot.retry.RetryPolicySettings; import org.springframework.core.retry.RetryPolicy; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitProperties.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitProperties.java new file mode 100644 index 000000000000..eca707d04919 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitProperties.java @@ -0,0 +1,1364 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.autoconfigure; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; + +import org.jspecify.annotations.Nullable; + +import org.springframework.amqp.core.AcknowledgeMode; +import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.AddressShuffleMode; +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.CacheMode; +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.ConfirmType; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; +import org.springframework.boot.convert.DurationUnit; +import org.springframework.boot.retry.RetryPolicySettings; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.springframework.util.unit.DataSize; + +/** + * Configuration properties for Rabbit. + * + * @author Greg Turnquist + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Josh Thornhill + * @author Gary Russell + * @author Artsiom Yudovin + * @author Franjo Zilic + * @author Eddú Meléndez + * @author Rafael Carvalho + * @author Scott Frederick + * @author Lasse Wulff + * @author Yanming Zhou + * @since 4.0.0 + */ +@ConfigurationProperties("spring.rabbitmq") +public class RabbitProperties { + + private static final int DEFAULT_PORT = 5672; + + private static final int DEFAULT_PORT_SECURE = 5671; + + private static final int DEFAULT_STREAM_PORT = 5552; + + /** + * RabbitMQ host. Ignored if an address is set. + */ + private String host = "localhost"; + + /** + * RabbitMQ port. Ignored if an address is set. Default to 5672, or 5671 if SSL is + * enabled. + */ + private @Nullable Integer port; + + /** + * Login user to authenticate to the broker. + */ + private String username = "guest"; + + /** + * Login to authenticate against the broker. + */ + private String password = "guest"; + + /** + * SSL configuration. + */ + private final Ssl ssl = new Ssl(); + + /** + * Virtual host to use when connecting to the broker. + */ + private @Nullable String virtualHost; + + /** + * List of addresses to which the client should connect. When set, the host and port + * are ignored. + */ + private @Nullable List addresses; + + /** + * Mode used to shuffle configured addresses. + */ + private AddressShuffleMode addressShuffleMode = AddressShuffleMode.NONE; + + /** + * Requested heartbeat timeout; zero for none. If a duration suffix is not specified, + * seconds will be used. + */ + @DurationUnit(ChronoUnit.SECONDS) + private @Nullable Duration requestedHeartbeat; + + /** + * Number of channels per connection requested by the client. Use 0 for unlimited. + */ + private int requestedChannelMax = 2047; + + /** + * Whether to enable publisher returns. + */ + private boolean publisherReturns; + + /** + * Type of publisher confirms to use. + */ + private @Nullable ConfirmType publisherConfirmType; + + /** + * Connection timeout. Set it to zero to wait forever. + */ + private @Nullable Duration connectionTimeout; + + /** + * Continuation timeout for RPC calls in channels. Set it to zero to wait forever. + */ + private Duration channelRpcTimeout = Duration.ofMinutes(10); + + /** + * Maximum size of the body of inbound (received) messages. + */ + private DataSize maxInboundMessageBodySize = DataSize.ofMegabytes(64); + + /** + * Cache configuration. + */ + private final Cache cache = new Cache(); + + /** + * Listener container configuration. + */ + private final Listener listener = new Listener(); + + private final Template template = new Template(); + + private final Stream stream = new Stream(); + + private @Nullable List
parsedAddresses; + + public String getHost() { + return this.host; + } + + /** + * Returns the host from the first address, or the configured host if no addresses + * have been set. + * @return the host + * @see #setAddresses(List) + * @see #getHost() + */ + public String determineHost() { + if (CollectionUtils.isEmpty(this.parsedAddresses)) { + return getHost(); + } + return this.parsedAddresses.get(0).host; + } + + public void setHost(String host) { + this.host = host; + } + + public @Nullable Integer getPort() { + return this.port; + } + + /** + * Returns the port from the first address, or the configured port if no addresses + * have been set. + * @return the port + * @see #setAddresses(List) + * @see #getPort() + */ + public int determinePort() { + if (CollectionUtils.isEmpty(this.parsedAddresses)) { + Integer port = getPort(); + if (port != null) { + return port; + } + return Boolean.TRUE.equals(getSsl().getEnabled()) ? DEFAULT_PORT_SECURE : DEFAULT_PORT; + } + return this.parsedAddresses.get(0).port; + } + + public void setPort(@Nullable Integer port) { + this.port = port; + } + + public @Nullable List getAddresses() { + return this.addresses; + } + + /** + * Returns the configured addresses or a single address ({@code host:port}) created + * from the configured host and port if no addresses have been set. + * @return the addresses + */ + public List determineAddresses() { + if (CollectionUtils.isEmpty(this.parsedAddresses)) { + if (this.host.contains(",")) { + throw new InvalidConfigurationPropertyValueException("spring.rabbitmq.host", this.host, + "Invalid character ','. Value must be a single host. For multiple hosts, use property 'spring.rabbitmq.addresses' instead."); + } + return List.of(this.host + ":" + determinePort()); + } + List addressStrings = new ArrayList<>(); + for (Address parsedAddress : this.parsedAddresses) { + addressStrings.add(parsedAddress.host + ":" + parsedAddress.port); + } + return addressStrings; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + this.parsedAddresses = parseAddresses(addresses); + } + + private List
parseAddresses(List addresses) { + List
parsedAddresses = new ArrayList<>(); + for (String address : addresses) { + parsedAddresses.add(new Address(address, Boolean.TRUE.equals(getSsl().getEnabled()))); + } + return parsedAddresses; + } + + public String getUsername() { + return this.username; + } + + /** + * If addresses have been set and the first address has a username it is returned. + * Otherwise returns the result of calling {@code getUsername()}. + * @return the username + * @see #setAddresses(List) + * @see #getUsername() + */ + public String determineUsername() { + if (CollectionUtils.isEmpty(this.parsedAddresses)) { + return this.username; + } + Address address = this.parsedAddresses.get(0); + return (address.username != null) ? address.username : this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return this.password; + } + + /** + * If addresses have been set and the first address has a password it is returned. + * Otherwise returns the result of calling {@code getPassword()}. + * @return the password or {@code null} + * @see #setAddresses(List) + * @see #getPassword() + */ + public @Nullable String determinePassword() { + if (CollectionUtils.isEmpty(this.parsedAddresses)) { + return getPassword(); + } + Address address = this.parsedAddresses.get(0); + return (address.password != null) ? address.password : getPassword(); + } + + public void setPassword(String password) { + this.password = password; + } + + public Ssl getSsl() { + return this.ssl; + } + + public @Nullable String getVirtualHost() { + return this.virtualHost; + } + + /** + * If addresses have been set and the first address has a virtual host it is returned. + * Otherwise returns the result of calling {@code getVirtualHost()}. + * @return the virtual host or {@code null} + * @see #setAddresses(List) + * @see #getVirtualHost() + */ + public @Nullable String determineVirtualHost() { + if (CollectionUtils.isEmpty(this.parsedAddresses)) { + return getVirtualHost(); + } + Address address = this.parsedAddresses.get(0); + return (address.virtualHost != null) ? address.virtualHost : getVirtualHost(); + } + + public void setVirtualHost(@Nullable String virtualHost) { + this.virtualHost = StringUtils.hasText(virtualHost) ? virtualHost : "/"; + } + + public AddressShuffleMode getAddressShuffleMode() { + return this.addressShuffleMode; + } + + public void setAddressShuffleMode(AddressShuffleMode addressShuffleMode) { + this.addressShuffleMode = addressShuffleMode; + } + + public @Nullable Duration getRequestedHeartbeat() { + return this.requestedHeartbeat; + } + + public void setRequestedHeartbeat(@Nullable Duration requestedHeartbeat) { + this.requestedHeartbeat = requestedHeartbeat; + } + + public int getRequestedChannelMax() { + return this.requestedChannelMax; + } + + public void setRequestedChannelMax(int requestedChannelMax) { + this.requestedChannelMax = requestedChannelMax; + } + + public boolean isPublisherReturns() { + return this.publisherReturns; + } + + public void setPublisherReturns(boolean publisherReturns) { + this.publisherReturns = publisherReturns; + } + + public @Nullable Duration getConnectionTimeout() { + return this.connectionTimeout; + } + + public void setPublisherConfirmType(@Nullable ConfirmType publisherConfirmType) { + this.publisherConfirmType = publisherConfirmType; + } + + public @Nullable ConfirmType getPublisherConfirmType() { + return this.publisherConfirmType; + } + + public void setConnectionTimeout(@Nullable Duration connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public Duration getChannelRpcTimeout() { + return this.channelRpcTimeout; + } + + public void setChannelRpcTimeout(Duration channelRpcTimeout) { + this.channelRpcTimeout = channelRpcTimeout; + } + + public DataSize getMaxInboundMessageBodySize() { + return this.maxInboundMessageBodySize; + } + + public void setMaxInboundMessageBodySize(DataSize maxInboundMessageBodySize) { + this.maxInboundMessageBodySize = maxInboundMessageBodySize; + } + + public Cache getCache() { + return this.cache; + } + + public Listener getListener() { + return this.listener; + } + + public Template getTemplate() { + return this.template; + } + + public Stream getStream() { + return this.stream; + } + + public class Ssl { + + private static final String SUN_X509 = "SunX509"; + + /** + * Whether to enable SSL support. Determined automatically if an address is + * provided with the protocol (amqp:// vs. amqps://). + */ + private @Nullable Boolean enabled; + + /** + * SSL bundle name. + */ + private @Nullable String bundle; + + /** + * Path to the key store that holds the SSL certificate. + */ + private @Nullable String keyStore; + + /** + * Key store type. + */ + private String keyStoreType = "PKCS12"; + + /** + * Password used to access the key store. + */ + private @Nullable String keyStorePassword; + + /** + * Key store algorithm. + */ + private String keyStoreAlgorithm = SUN_X509; + + /** + * Trust store that holds SSL certificates. + */ + private @Nullable String trustStore; + + /** + * Trust store type. + */ + private String trustStoreType = "JKS"; + + /** + * Password used to access the trust store. + */ + private @Nullable String trustStorePassword; + + /** + * Trust store algorithm. + */ + private String trustStoreAlgorithm = SUN_X509; + + /** + * SSL algorithm to use. By default, configured by the Rabbit client library. + */ + private @Nullable String algorithm; + + /** + * Whether to enable server side certificate validation. + */ + private boolean validateServerCertificate = true; + + /** + * Whether to enable hostname verification. + */ + private boolean verifyHostname = true; + + public @Nullable Boolean getEnabled() { + return this.enabled; + } + + /** + * Returns whether SSL is enabled from the first address, or the configured ssl + * enabled flag if no addresses have been set. + * @return whether ssl is enabled + * @see #setAddresses(List) + * @see #getEnabled() () + */ + public boolean determineEnabled() { + boolean defaultEnabled = Boolean.TRUE.equals(getEnabled()) || this.bundle != null; + if (CollectionUtils.isEmpty(RabbitProperties.this.parsedAddresses)) { + return defaultEnabled; + } + Address address = RabbitProperties.this.parsedAddresses.get(0); + return address.determineSslEnabled(defaultEnabled); + } + + public void setEnabled(@Nullable Boolean enabled) { + this.enabled = enabled; + } + + public @Nullable String getBundle() { + return this.bundle; + } + + public void setBundle(@Nullable String bundle) { + this.bundle = bundle; + } + + public @Nullable String getKeyStore() { + return this.keyStore; + } + + public void setKeyStore(@Nullable String keyStore) { + this.keyStore = keyStore; + } + + public String getKeyStoreType() { + return this.keyStoreType; + } + + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + public @Nullable String getKeyStorePassword() { + return this.keyStorePassword; + } + + public void setKeyStorePassword(@Nullable String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } + + public String getKeyStoreAlgorithm() { + return this.keyStoreAlgorithm; + } + + public void setKeyStoreAlgorithm(String keyStoreAlgorithm) { + this.keyStoreAlgorithm = keyStoreAlgorithm; + } + + public @Nullable String getTrustStore() { + return this.trustStore; + } + + public void setTrustStore(@Nullable String trustStore) { + this.trustStore = trustStore; + } + + public String getTrustStoreType() { + return this.trustStoreType; + } + + public void setTrustStoreType(String trustStoreType) { + this.trustStoreType = trustStoreType; + } + + public @Nullable String getTrustStorePassword() { + return this.trustStorePassword; + } + + public void setTrustStorePassword(@Nullable String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } + + public String getTrustStoreAlgorithm() { + return this.trustStoreAlgorithm; + } + + public void setTrustStoreAlgorithm(String trustStoreAlgorithm) { + this.trustStoreAlgorithm = trustStoreAlgorithm; + } + + public @Nullable String getAlgorithm() { + return this.algorithm; + } + + public void setAlgorithm(@Nullable String sslAlgorithm) { + this.algorithm = sslAlgorithm; + } + + public boolean isValidateServerCertificate() { + return this.validateServerCertificate; + } + + public void setValidateServerCertificate(boolean validateServerCertificate) { + this.validateServerCertificate = validateServerCertificate; + } + + public boolean isVerifyHostname() { + return this.verifyHostname; + } + + public void setVerifyHostname(boolean verifyHostname) { + this.verifyHostname = verifyHostname; + } + + } + + public static class Cache { + + private final Channel channel = new Channel(); + + private final Connection connection = new Connection(); + + public Channel getChannel() { + return this.channel; + } + + public Connection getConnection() { + return this.connection; + } + + public static class Channel { + + /** + * Number of channels to retain in the cache. When "check-timeout" > 0, max + * channels per connection. + */ + private @Nullable Integer size; + + /** + * Duration to wait to obtain a channel if the cache size has been reached. If + * 0, always create a new channel. + */ + private @Nullable Duration checkoutTimeout; + + public @Nullable Integer getSize() { + return this.size; + } + + public void setSize(@Nullable Integer size) { + this.size = size; + } + + public @Nullable Duration getCheckoutTimeout() { + return this.checkoutTimeout; + } + + public void setCheckoutTimeout(@Nullable Duration checkoutTimeout) { + this.checkoutTimeout = checkoutTimeout; + } + + } + + public static class Connection { + + /** + * Connection factory cache mode. + */ + private CacheMode mode = CacheMode.CHANNEL; + + /** + * Number of connections to cache. Only applies when mode is CONNECTION. + */ + private @Nullable Integer size; + + public CacheMode getMode() { + return this.mode; + } + + public void setMode(CacheMode mode) { + this.mode = mode; + } + + public @Nullable Integer getSize() { + return this.size; + } + + public void setSize(@Nullable Integer size) { + this.size = size; + } + + } + + } + + public enum ContainerType { + + /** + * Container where the RabbitMQ consumer dispatches messages to an invoker thread. + */ + SIMPLE, + + /** + * Container where the listener is invoked directly on the RabbitMQ consumer + * thread. + */ + DIRECT, + + /** + * Container that uses the RabbitMQ Stream Client. + */ + STREAM + + } + + public static class Listener { + + /** + * Listener container type. + */ + private ContainerType type = ContainerType.SIMPLE; + + private final SimpleContainer simple = new SimpleContainer(); + + private final DirectContainer direct = new DirectContainer(); + + private final StreamContainer stream = new StreamContainer(); + + public ContainerType getType() { + return this.type; + } + + public void setType(ContainerType containerType) { + this.type = containerType; + } + + public SimpleContainer getSimple() { + return this.simple; + } + + public DirectContainer getDirect() { + return this.direct; + } + + public StreamContainer getStream() { + return this.stream; + } + + } + + public abstract static class BaseContainer { + + /** + * Whether to enable observation. + */ + private boolean observationEnabled; + + public boolean isObservationEnabled() { + return this.observationEnabled; + } + + public void setObservationEnabled(boolean observationEnabled) { + this.observationEnabled = observationEnabled; + } + + } + + public abstract static class AmqpContainer extends BaseContainer { + + /** + * Whether to start the container automatically on startup. + */ + private boolean autoStartup = true; + + /** + * Acknowledge mode of container. + */ + private @Nullable AcknowledgeMode acknowledgeMode; + + /** + * Maximum number of unacknowledged messages that can be outstanding at each + * consumer. + */ + private @Nullable Integer prefetch; + + /** + * Whether rejected deliveries are re-queued by default. + */ + private @Nullable Boolean defaultRequeueRejected; + + /** + * How often idle container events should be published. + */ + private @Nullable Duration idleEventInterval; + + /** + * Whether the container should present batched messages as discrete messages or + * call the listener with the batch. + */ + private boolean deBatchingEnabled = true; + + /** + * Whether the container (when stopped) should stop immediately after processing + * the current message or stop after processing all pre-fetched messages. + */ + private boolean forceStop; + + /** + * Optional properties for a retry interceptor. + */ + private final ListenerRetry retry = new ListenerRetry(); + + public boolean isAutoStartup() { + return this.autoStartup; + } + + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + public @Nullable AcknowledgeMode getAcknowledgeMode() { + return this.acknowledgeMode; + } + + public void setAcknowledgeMode(@Nullable AcknowledgeMode acknowledgeMode) { + this.acknowledgeMode = acknowledgeMode; + } + + public @Nullable Integer getPrefetch() { + return this.prefetch; + } + + public void setPrefetch(@Nullable Integer prefetch) { + this.prefetch = prefetch; + } + + public @Nullable Boolean getDefaultRequeueRejected() { + return this.defaultRequeueRejected; + } + + public void setDefaultRequeueRejected(@Nullable Boolean defaultRequeueRejected) { + this.defaultRequeueRejected = defaultRequeueRejected; + } + + public @Nullable Duration getIdleEventInterval() { + return this.idleEventInterval; + } + + public void setIdleEventInterval(@Nullable Duration idleEventInterval) { + this.idleEventInterval = idleEventInterval; + } + + public abstract boolean isMissingQueuesFatal(); + + public boolean isDeBatchingEnabled() { + return this.deBatchingEnabled; + } + + public void setDeBatchingEnabled(boolean deBatchingEnabled) { + this.deBatchingEnabled = deBatchingEnabled; + } + + public boolean isForceStop() { + return this.forceStop; + } + + public void setForceStop(boolean forceStop) { + this.forceStop = forceStop; + } + + public ListenerRetry getRetry() { + return this.retry; + } + + } + + /** + * Configuration properties for {@code SimpleMessageListenerContainer}. + */ + public static class SimpleContainer extends AmqpContainer { + + /** + * Minimum number of listener invoker threads. + */ + private @Nullable Integer concurrency; + + /** + * Maximum number of listener invoker threads. + */ + private @Nullable Integer maxConcurrency; + + /** + * Batch size, expressed as the number of physical messages, to be used by the + * container. + */ + private @Nullable Integer batchSize; + + /** + * Whether to fail if the queues declared by the container are not available on + * the broker and/or whether to stop the container if one or more queues are + * deleted at runtime. + */ + private boolean missingQueuesFatal = true; + + /** + * Whether the container creates a batch of messages based on the + * 'receive-timeout' and 'batch-size'. Coerces 'de-batching-enabled' to true to + * include the contents of a producer created batch in the batch as discrete + * records. + */ + private boolean consumerBatchEnabled; + + public @Nullable Integer getConcurrency() { + return this.concurrency; + } + + public void setConcurrency(@Nullable Integer concurrency) { + this.concurrency = concurrency; + } + + public @Nullable Integer getMaxConcurrency() { + return this.maxConcurrency; + } + + public void setMaxConcurrency(@Nullable Integer maxConcurrency) { + this.maxConcurrency = maxConcurrency; + } + + public @Nullable Integer getBatchSize() { + return this.batchSize; + } + + public void setBatchSize(@Nullable Integer batchSize) { + this.batchSize = batchSize; + } + + @Override + public boolean isMissingQueuesFatal() { + return this.missingQueuesFatal; + } + + public void setMissingQueuesFatal(boolean missingQueuesFatal) { + this.missingQueuesFatal = missingQueuesFatal; + } + + public boolean isConsumerBatchEnabled() { + return this.consumerBatchEnabled; + } + + public void setConsumerBatchEnabled(boolean consumerBatchEnabled) { + this.consumerBatchEnabled = consumerBatchEnabled; + } + + } + + /** + * Configuration properties for {@code DirectMessageListenerContainer}. + */ + public static class DirectContainer extends AmqpContainer { + + /** + * Number of consumers per queue. + */ + private @Nullable Integer consumersPerQueue; + + /** + * Whether to fail if the queues declared by the container are not available on + * the broker. + */ + private boolean missingQueuesFatal; + + public @Nullable Integer getConsumersPerQueue() { + return this.consumersPerQueue; + } + + public void setConsumersPerQueue(@Nullable Integer consumersPerQueue) { + this.consumersPerQueue = consumersPerQueue; + } + + @Override + public boolean isMissingQueuesFatal() { + return this.missingQueuesFatal; + } + + public void setMissingQueuesFatal(boolean missingQueuesFatal) { + this.missingQueuesFatal = missingQueuesFatal; + } + + } + + public static class StreamContainer extends BaseContainer { + + /** + * Whether the container will support listeners that consume native stream + * messages instead of Spring AMQP messages. + */ + private boolean nativeListener; + + public boolean isNativeListener() { + return this.nativeListener; + } + + public void setNativeListener(boolean nativeListener) { + this.nativeListener = nativeListener; + } + + } + + public static class Template { + + private final Retry retry = new Retry(); + + /** + * Whether to enable mandatory messages. + */ + private @Nullable Boolean mandatory; + + /** + * Timeout for receive() operations. + */ + private @Nullable Duration receiveTimeout; + + /** + * Timeout for sendAndReceive() operations. + */ + private @Nullable Duration replyTimeout; + + /** + * Name of the default exchange to use for send operations. + */ + private String exchange = ""; + + /** + * Value of a default routing key to use for send operations. + */ + private String routingKey = ""; + + /** + * Name of the default queue to receive messages from when none is specified + * explicitly. + */ + private @Nullable String defaultReceiveQueue; + + /** + * Whether to enable observation. + */ + private boolean observationEnabled; + + /** + * Simple patterns for allowable packages/classes for deserialization. + */ + private @Nullable List allowedListPatterns; + + public Retry getRetry() { + return this.retry; + } + + public @Nullable Boolean getMandatory() { + return this.mandatory; + } + + public void setMandatory(@Nullable Boolean mandatory) { + this.mandatory = mandatory; + } + + public @Nullable Duration getReceiveTimeout() { + return this.receiveTimeout; + } + + public void setReceiveTimeout(@Nullable Duration receiveTimeout) { + this.receiveTimeout = receiveTimeout; + } + + public @Nullable Duration getReplyTimeout() { + return this.replyTimeout; + } + + public void setReplyTimeout(@Nullable Duration replyTimeout) { + this.replyTimeout = replyTimeout; + } + + public String getExchange() { + return this.exchange; + } + + public void setExchange(String exchange) { + this.exchange = exchange; + } + + public String getRoutingKey() { + return this.routingKey; + } + + public void setRoutingKey(String routingKey) { + this.routingKey = routingKey; + } + + public @Nullable String getDefaultReceiveQueue() { + return this.defaultReceiveQueue; + } + + public void setDefaultReceiveQueue(@Nullable String defaultReceiveQueue) { + this.defaultReceiveQueue = defaultReceiveQueue; + } + + public boolean isObservationEnabled() { + return this.observationEnabled; + } + + public void setObservationEnabled(boolean observationEnabled) { + this.observationEnabled = observationEnabled; + } + + public @Nullable List getAllowedListPatterns() { + return this.allowedListPatterns; + } + + public void setAllowedListPatterns(@Nullable List allowedListPatterns) { + this.allowedListPatterns = allowedListPatterns; + } + + } + + public static class Retry { + + /** + * Whether publishing retries are enabled. + */ + private boolean enabled; + + /** + * Maximum number of retry attempts to deliver a message. + */ + private long maxRetries = 3; + + /** + * Duration between the first and second attempt to deliver a message. + */ + private Duration initialInterval = Duration.ofMillis(1000); + + /** + * Multiplier to apply to the previous retry interval. + */ + private double multiplier = 1.0; + + /** + * Maximum duration between attempts. + */ + private Duration maxInterval = Duration.ofMillis(10000); + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public long getMaxRetries() { + return this.maxRetries; + } + + public void setMaxRetries(long maxRetries) { + this.maxRetries = maxRetries; + } + + public Duration getInitialInterval() { + return this.initialInterval; + } + + public void setInitialInterval(Duration initialInterval) { + this.initialInterval = initialInterval; + } + + public double getMultiplier() { + return this.multiplier; + } + + public void setMultiplier(double multiplier) { + this.multiplier = multiplier; + } + + public Duration getMaxInterval() { + return this.maxInterval; + } + + public void setMaxInterval(Duration maxInterval) { + this.maxInterval = maxInterval; + } + + RetryPolicySettings initializeRetryPolicySettings() { + PropertyMapper map = PropertyMapper.get(); + RetryPolicySettings settings = new RetryPolicySettings(); + map.from(this::getMaxRetries).to(settings::setMaxRetries); + map.from(this::getInitialInterval).to(settings::setDelay); + map.from(this::getMultiplier).to(settings::setMultiplier); + map.from(this::getMaxInterval).to(settings::setMaxDelay); + return settings; + } + + } + + public static class ListenerRetry extends Retry { + + /** + * Whether retries are stateless or stateful. + */ + private boolean stateless = true; + + public boolean isStateless() { + return this.stateless; + } + + public void setStateless(boolean stateless) { + this.stateless = stateless; + } + + } + + private static final class Address { + + private static final String PREFIX_AMQP = "amqp://"; + + private static final String PREFIX_AMQP_SECURE = "amqps://"; + + private String host; + + private int port; + + private @Nullable String username; + + private @Nullable String password; + + private @Nullable String virtualHost; + + private @Nullable Boolean secureConnection; + + private Address(String input, boolean sslEnabled) { + input = input.trim(); + input = trimPrefix(input); + input = parseUsernameAndPassword(input); + input = parseVirtualHost(input); + parseHostAndPort(input, sslEnabled); + } + + private String trimPrefix(String input) { + if (input.startsWith(PREFIX_AMQP_SECURE)) { + this.secureConnection = true; + return input.substring(PREFIX_AMQP_SECURE.length()); + } + if (input.startsWith(PREFIX_AMQP)) { + this.secureConnection = false; + return input.substring(PREFIX_AMQP.length()); + } + return input; + } + + private String parseUsernameAndPassword(String input) { + String[] splitInput = StringUtils.split(input, "@"); + if (splitInput == null) { + return input; + } + String credentials = splitInput[0]; + String[] splitCredentials = StringUtils.split(credentials, ":"); + if (splitCredentials == null) { + this.username = credentials; + } + else { + this.username = splitCredentials[0]; + this.password = splitCredentials[1]; + } + return splitInput[1]; + } + + private String parseVirtualHost(String input) { + int hostIndex = input.indexOf('/'); + if (hostIndex >= 0) { + this.virtualHost = input.substring(hostIndex + 1); + if (this.virtualHost.isEmpty()) { + this.virtualHost = "/"; + } + input = input.substring(0, hostIndex); + } + return input; + } + + private void parseHostAndPort(String input, boolean sslEnabled) { + int bracketIndex = input.lastIndexOf(']'); + int colonIndex = input.lastIndexOf(':'); + if (colonIndex == -1 || colonIndex < bracketIndex) { + this.host = input; + this.port = (determineSslEnabled(sslEnabled)) ? DEFAULT_PORT_SECURE : DEFAULT_PORT; + } + else { + this.host = input.substring(0, colonIndex); + this.port = Integer.parseInt(input.substring(colonIndex + 1)); + } + } + + private boolean determineSslEnabled(boolean sslEnabled) { + return (this.secureConnection != null) ? this.secureConnection : sslEnabled; + } + + } + + public static final class Stream { + + /** + * Host of a RabbitMQ instance with the Stream plugin enabled. + */ + private String host = "localhost"; + + /** + * Stream port of a RabbitMQ instance with the Stream plugin enabled. + */ + private int port = DEFAULT_STREAM_PORT; + + /** + * Virtual host of a RabbitMQ instance with the Stream plugin enabled. When not + * set, spring.rabbitmq.virtual-host is used. + */ + private @Nullable String virtualHost; + + /** + * Login user to authenticate to the broker. When not set, + * spring.rabbitmq.username is used. + */ + private @Nullable String username; + + /** + * Login password to authenticate to the broker. When not set + * spring.rabbitmq.password is used. + */ + private @Nullable String password; + + /** + * Name of the stream. + */ + private @Nullable String name; + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return this.port; + } + + public void setPort(int port) { + this.port = port; + } + + public @Nullable String getVirtualHost() { + return this.virtualHost; + } + + public void setVirtualHost(@Nullable String virtualHost) { + this.virtualHost = virtualHost; + } + + public @Nullable String getUsername() { + return this.username; + } + + public void setUsername(@Nullable String username) { + this.username = username; + } + + public @Nullable String getPassword() { + return this.password; + } + + public void setPassword(@Nullable String password) { + this.password = password; + } + + public @Nullable String getName() { + return this.name; + } + + public void setName(@Nullable String name) { + this.name = name; + } + + } + +} diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitRetryTemplateSettings.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitRetryTemplateSettings.java similarity index 96% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitRetryTemplateSettings.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitRetryTemplateSettings.java index 8e29c1d440e0..c8c2e7625826 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitRetryTemplateSettings.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitRetryTemplateSettings.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.util.LinkedList; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java similarity index 97% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfiguration.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java index 38826821b68f..103d8e8522ed 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import com.rabbitmq.stream.Environment; import com.rabbitmq.stream.EnvironmentBuilder; @@ -22,7 +22,7 @@ import org.springframework.amqp.rabbit.config.ContainerCustomizer; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.amqp.autoconfigure.RabbitProperties.StreamContainer; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.StreamContainer; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamTemplateConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamTemplateConfigurer.java similarity index 98% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamTemplateConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamTemplateConfigurer.java index 6fb5519ab6a6..3ccf98118e66 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamTemplateConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamTemplateConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.jspecify.annotations.Nullable; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateConfigurer.java similarity index 99% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateConfigurer.java index 50cfc248c68c..e7098f18596a 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.time.Duration; import java.util.List; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateCustomizer.java similarity index 94% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateCustomizer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateCustomizer.java index 9015fa8ca49d..eac42c300000 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateCustomizer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.springframework.amqp.rabbit.core.RabbitTemplate; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java similarity index 95% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java index 099b510132bb..7c46996557e0 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitTemplateRetrySettingsCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.core.retry.RetryTemplate; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java similarity index 97% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java index 10fac5395c1d..34332c70eded 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SslBundleRabbitConnectionFactoryBean.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/SslBundleRabbitConnectionFactoryBean.java similarity index 96% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SslBundleRabbitConnectionFactoryBean.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/SslBundleRabbitConnectionFactoryBean.java index ae2345fb06bb..da53a2cbe28b 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SslBundleRabbitConnectionFactoryBean.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/SslBundleRabbitConnectionFactoryBean.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import org.jspecify.annotations.Nullable; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java similarity index 91% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java index 0abccb7e34cf..6b7368effad8 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure.health; +package org.springframework.boot.rabbitmq.autoconfigure.health; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.amqp.health.RabbitHealthIndicator; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/package-info.java similarity index 91% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/package-info.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/package-info.java index bbd0d5e86d39..27f98c583ad9 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/package-info.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/package-info.java @@ -18,6 +18,6 @@ * Auto-configuration for RabbitMQ health. */ @NullMarked -package org.springframework.boot.amqp.autoconfigure.health; +package org.springframework.boot.rabbitmq.autoconfigure.health; import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java similarity index 96% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java index 9841b953e937..2f9f18802c76 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure.metrics; +package org.springframework.boot.rabbitmq.autoconfigure.metrics; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.MetricsCollector; @@ -24,7 +24,7 @@ import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.amqp.metrics.RabbitMetrics; +import org.springframework.boot.rabbitmq.metrics.RabbitMetrics; import org.springframework.context.ApplicationContext; import org.springframework.core.Ordered; import org.springframework.util.StringUtils; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java similarity index 93% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java index 27b5b6ad36ed..f9b650e8be05 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure.metrics; +package org.springframework.boot.rabbitmq.autoconfigure.metrics; import com.rabbitmq.client.ConnectionFactory; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/package-info.java similarity index 91% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/package-info.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/package-info.java index ab0814c6f728..94b2c885530b 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/package-info.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/package-info.java @@ -18,6 +18,6 @@ * Auto-configuration for RabbitMQ metrics. */ @NullMarked -package org.springframework.boot.amqp.autoconfigure.metrics; +package org.springframework.boot.rabbitmq.autoconfigure.metrics; import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/package-info.java new file mode 100644 index 000000000000..8b021e23bb05 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RabbitMQ. + */ +@NullMarked +package org.springframework.boot.rabbitmq.autoconfigure; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java new file mode 100644 index 000000000000..e2485fdd942d --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.docker.compose; + +import java.util.List; + +import org.jspecify.annotations.Nullable; + +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.docker.compose.core.RunningService; +import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; +import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; + +/** + * {@link DockerComposeConnectionDetailsFactory} to create {@link RabbitConnectionDetails} + * for a {@code rabbitmq} service. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class RabbitDockerComposeConnectionDetailsFactory + extends DockerComposeConnectionDetailsFactory { + + private static final int RABBITMQ_PORT = 5672; + + protected RabbitDockerComposeConnectionDetailsFactory() { + super("rabbitmq"); + } + + @Override + protected RabbitConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) { + return new RabbitDockerComposeConnectionDetails(source.getRunningService()); + } + + /** + * {@link RabbitConnectionDetails} backed by a {@code rabbitmq} + * {@link RunningService}. + */ + static class RabbitDockerComposeConnectionDetails extends DockerComposeConnectionDetails + implements RabbitConnectionDetails { + + private final RabbitEnvironment environment; + + private final List
addresses; + + protected RabbitDockerComposeConnectionDetails(RunningService service) { + super(service); + this.environment = new RabbitEnvironment(service.env()); + this.addresses = List.of(new Address(service.host(), service.ports().get(RABBITMQ_PORT))); + } + + @Override + public @Nullable String getUsername() { + return this.environment.getUsername(); + } + + @Override + public @Nullable String getPassword() { + return this.environment.getPassword(); + } + + @Override + public String getVirtualHost() { + return "/"; + } + + @Override + public List
getAddresses() { + return this.addresses; + } + + } + +} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironment.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironment.java new file mode 100644 index 000000000000..1d37579e1a84 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironment.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.docker.compose; + +import java.util.Map; + +import org.jspecify.annotations.Nullable; + +/** + * RabbitMQ environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class RabbitEnvironment { + + private final @Nullable String username; + + private final @Nullable String password; + + RabbitEnvironment(Map env) { + this.username = env.getOrDefault("RABBITMQ_DEFAULT_USER", env.getOrDefault("RABBITMQ_USERNAME", "guest")); + this.password = env.getOrDefault("RABBITMQ_DEFAULT_PASS", env.getOrDefault("RABBITMQ_PASSWORD", "guest")); + } + + @Nullable String getUsername() { + return this.username; + } + + @Nullable String getPassword() { + return this.password; + } + +} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/package-info.java new file mode 100644 index 000000000000..7fffb63a7c4c --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose RabbitMQ service connections. + */ +@NullMarked +package org.springframework.boot.rabbitmq.docker.compose; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/RabbitHealthIndicator.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/health/RabbitHealthIndicator.java similarity index 97% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/RabbitHealthIndicator.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/health/RabbitHealthIndicator.java index 045ab2f89c27..f26777421eb5 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/RabbitHealthIndicator.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/health/RabbitHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.health; +package org.springframework.boot.rabbitmq.health; import org.jspecify.annotations.Nullable; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/health/package-info.java similarity index 93% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/package-info.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/health/package-info.java index ecb6ea0b1649..83f913732e91 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/package-info.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/health/package-info.java @@ -18,6 +18,6 @@ * Health integration for AMQP and RabbitMQ. */ @NullMarked -package org.springframework.boot.amqp.health; +package org.springframework.boot.rabbitmq.health; import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/RabbitMetrics.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/metrics/RabbitMetrics.java similarity index 97% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/RabbitMetrics.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/metrics/RabbitMetrics.java index 20ae4111b162..1fef99a6ba1d 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/RabbitMetrics.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/metrics/RabbitMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.metrics; +package org.springframework.boot.rabbitmq.metrics; import java.util.Collections; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/metrics/package-info.java similarity index 93% rename from module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/package-info.java rename to module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/metrics/package-info.java index e63026906cd8..c40e5aed68fc 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/package-info.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/metrics/package-info.java @@ -18,6 +18,6 @@ * Metrics for AMQP and RabbitMQ. */ @NullMarked -package org.springframework.boot.amqp.metrics; +package org.springframework.boot.rabbitmq.metrics; import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactory.java new file mode 100644 index 000000000000..445d8410611a --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactory.java @@ -0,0 +1,85 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.testcontainers; + +import java.net.URI; +import java.util.List; + +import org.jspecify.annotations.Nullable; +import org.testcontainers.containers.RabbitMQContainer; + +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; + +/** + * {@link ContainerConnectionDetailsFactory} to create {@link RabbitConnectionDetails} + * from a {@link ServiceConnection @ServiceConnection}-annotated + * {@link RabbitMQContainer}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @deprecated since 4.0.0 for removal in 4.2.0 in favor of + * {@link RabbitContainerConnectionDetailsFactory}. + */ +@Deprecated(since = "4.0.0", forRemoval = true) +class DeprecatedRabbitContainerConnectionDetailsFactory + extends ContainerConnectionDetailsFactory { + + @Override + protected RabbitConnectionDetails getContainerConnectionDetails( + ContainerConnectionSource source) { + return new RabbitMqContainerConnectionDetails(source); + } + + /** + * {@link RabbitConnectionDetails} backed by a {@link ContainerConnectionSource}. + */ + private static final class RabbitMqContainerConnectionDetails extends ContainerConnectionDetails + implements RabbitConnectionDetails { + + private RabbitMqContainerConnectionDetails(ContainerConnectionSource source) { + super(source); + } + + @Override + public String getUsername() { + return getContainer().getAdminUsername(); + } + + @Override + public String getPassword() { + return getContainer().getAdminPassword(); + } + + @Override + public List
getAddresses() { + URI uri = URI.create((getSslBundle() != null) ? getContainer().getAmqpsUrl() : getContainer().getAmqpUrl()); + return List.of(new Address(uri.getHost(), uri.getPort())); + } + + @Override + public @Nullable SslBundle getSslBundle() { + return super.getSslBundle(); + } + + } + +} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java new file mode 100644 index 000000000000..9f549ce296a8 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.testcontainers; + +import java.net.URI; +import java.util.List; + +import org.jspecify.annotations.Nullable; +import org.testcontainers.rabbitmq.RabbitMQContainer; + +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; + +/** + * {@link ContainerConnectionDetailsFactory} to create {@link RabbitConnectionDetails} + * from a {@link ServiceConnection @ServiceConnection}-annotated + * {@link RabbitMQContainer}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + */ +class RabbitContainerConnectionDetailsFactory + extends ContainerConnectionDetailsFactory { + + @Override + protected RabbitConnectionDetails getContainerConnectionDetails( + ContainerConnectionSource source) { + return new RabbitMqContainerConnectionDetails(source); + } + + /** + * {@link RabbitConnectionDetails} backed by a {@link ContainerConnectionSource}. + */ + private static final class RabbitMqContainerConnectionDetails extends ContainerConnectionDetails + implements RabbitConnectionDetails { + + private RabbitMqContainerConnectionDetails(ContainerConnectionSource source) { + super(source); + } + + @Override + public String getUsername() { + return getContainer().getAdminUsername(); + } + + @Override + public String getPassword() { + return getContainer().getAdminPassword(); + } + + @Override + public List
getAddresses() { + URI uri = URI.create((getSslBundle() != null) ? getContainer().getAmqpsUrl() : getContainer().getAmqpUrl()); + return List.of(new Address(uri.getHost(), uri.getPort())); + } + + @Override + public @Nullable SslBundle getSslBundle() { + return super.getSslBundle(); + } + + } + +} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/package-info.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/package-info.java new file mode 100644 index 000000000000..272d19a6b982 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers RabbitMQ service connections. + */ +@NullMarked +package org.springframework.boot.rabbitmq.testcontainers; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-amqp/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/module/spring-boot-rabbitmq/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 100% rename from module/spring-boot-amqp/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to module/spring-boot-rabbitmq/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/module/spring-boot-rabbitmq/src/main/resources/META-INF/spring.factories b/module/spring-boot-rabbitmq/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..998e930b263b --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/resources/META-INF/spring.factories @@ -0,0 +1,5 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.rabbitmq.docker.compose.RabbitDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.rabbitmq.testcontainers.DeprecatedRabbitContainerConnectionDetailsFactory,\ +org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory diff --git a/module/spring-boot-rabbitmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-rabbitmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..9ec393f97b32 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration +org.springframework.boot.rabbitmq.autoconfigure.health.RabbitHealthContributorAutoConfiguration +org.springframework.boot.rabbitmq.autoconfigure.metrics.RabbitMetricsAutoConfiguration \ No newline at end of file diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetailsTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetailsTests.java similarity index 95% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetailsTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetailsTests.java index fb37bd6f2712..aed57edc4e04 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetailsTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/PropertiesRabbitConnectionDetailsTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.ssl.DefaultSslBundleRegistry; import org.springframework.boot.ssl.SslBundle; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAutoConfigurationTests.java similarity index 99% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAutoConfigurationTests.java index b170f51e9648..93cdce85cf5e 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.security.NoSuchAlgorithmException; import java.util.Collection; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitPropertiesTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitPropertiesTests.java similarity index 99% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitPropertiesTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitPropertiesTests.java index cc3f17a5a802..49cb9ad85147 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitPropertiesTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.util.List; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java similarity index 99% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java index 27bbc9918845..e4925da8a759 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure; +package org.springframework.boot.rabbitmq.autoconfigure; import java.time.Duration; import java.util.List; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java similarity index 89% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java index 8739399d0aae..5218481d9894 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure.health; +package org.springframework.boot.rabbitmq.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.amqp.health.RabbitHealthIndicator; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java similarity index 94% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java index 8c8c31a499e0..e780e0e4ba6a 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure.metrics; +package org.springframework.boot.rabbitmq.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.MeterBinder; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java similarity index 95% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java index b75b0e1857d9..cbcee9e1c58f 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.autoconfigure.metrics; +package org.springframework.boot.rabbitmq.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; @@ -22,7 +22,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironmentTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironmentTests.java new file mode 100644 index 000000000000..356d93ad535e --- /dev/null +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/docker/compose/RabbitEnvironmentTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rabbitmq.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link RabbitEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class RabbitEnvironmentTests { + + @Test + void getUsernameWhenNoRabbitmqDefaultUser() { + RabbitEnvironment environment = new RabbitEnvironment(Collections.emptyMap()); + assertThat(environment.getUsername()).isEqualTo("guest"); + } + + @Test + void getUsernameWhenHasRabbitmqDefaultUser() { + RabbitEnvironment environment = new RabbitEnvironment(Map.of("RABBITMQ_DEFAULT_USER", "me")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getUsernameWhenHasRabbitmqUsername() { + RabbitEnvironment environment = new RabbitEnvironment(Map.of("RABBITMQ_USERNAME", "me")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getUsernameWhenNoRabbitmqDefaultPass() { + RabbitEnvironment environment = new RabbitEnvironment(Collections.emptyMap()); + assertThat(environment.getPassword()).isEqualTo("guest"); + } + + @Test + void getUsernameWhenHasRabbitmqDefaultPass() { + RabbitEnvironment environment = new RabbitEnvironment(Map.of("RABBITMQ_DEFAULT_PASS", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getUsernameWhenHasRabbitmqPassword() { + RabbitEnvironment environment = new RabbitEnvironment(Map.of("RABBITMQ_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + +} diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/health/RabbitHealthIndicatorTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/health/RabbitHealthIndicatorTests.java similarity index 98% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/health/RabbitHealthIndicatorTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/health/RabbitHealthIndicatorTests.java index 5ce2f8e64a20..161cb2fa6e94 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/health/RabbitHealthIndicatorTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/health/RabbitHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.health; +package org.springframework.boot.rabbitmq.health; import java.util.Collections; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/metrics/RabbitMetricsTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/metrics/RabbitMetricsTests.java similarity index 97% rename from module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/metrics/RabbitMetricsTests.java rename to module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/metrics/RabbitMetricsTests.java index 780de803e4f6..a8b3f5b3c1d3 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/metrics/RabbitMetricsTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/metrics/RabbitMetricsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.metrics; +package org.springframework.boot.rabbitmq.metrics; import com.rabbitmq.client.ConnectionFactory; import io.micrometer.core.instrument.Tags; diff --git a/module/spring-boot-rabbitmq/src/test/resources/logback-test.xml b/module/spring-boot-rabbitmq/src/test/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/module/spring-boot-rabbitmq/src/test/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/module/spring-boot-rabbitmq/src/test/resources/org/springframework/boot/rabbitmq/autoconfigure/test.jks b/module/spring-boot-rabbitmq/src/test/resources/org/springframework/boot/rabbitmq/autoconfigure/test.jks new file mode 100644 index 0000000000000000000000000000000000000000..8413be810956262d0da0387e8781fc4d27f6b027 GIT binary patch literal 1294 zcmezO_TO6u1_mY|W&~r_+{*0KN+2&TwQlnkAl+}!#Mo`X$Ht}2#>m2`#U#kc$jZRd z#8^J5!~Wmp7|YE9c_o202CEfvPJAt&F-z+E+Y5Je-P@SM3x!M{?<`L$d7kPy>HgY< z0rl+7ddFPf9_^UC?)~PM8U_ciTzNlZu6ENGso!d;PtM$lt<~ROC~|P;oYPIU`ifCm z3xrl>nF}qFRax}#!Gf-mKc9ryWTqXD5RA>>WDIzayKC#wV=9~F(x>fBQsZQ6{U|+U z!WW$>x*Dgfn4=QHB86`zaB53NZvW1sG()7e{`TIV! z&3V4Ogyo;agqT?@rcVEe)EOO%0lu zJ}+QqVq{`s(UY*NH{fPt*J|@PXTieE%3zRVC;*H-=1>+kVfN6x?7aN)JeUXvh6p=` z2p5J3H--o^T*N?5oY&CYz!C_}4NXl=qCi|jBLfR4m(H$fV%z~ty*jYqU<7jHnHn1z z{?-RK%9aXg2Hp3Xqxa^?^KXLNgKXZrFdUY%Z`c;7mgySnpcME!(zZ9^*Z!klcNu&; zJv%h#dZTrNtV#Z-w1n;1GXs_`nLqypOSOQ~A^+Vgum9VAO!|j)`14~cmWlGS{BHhs z`Ka7sCesk%D6xq~-%3BP(@wmu_5PC*v*g^19*oDCL>ZQ_-Kd;Z$Hmz)N^9lLmRQG?vR>ZjR%X@$!Tw1Ryr|naXt4hMbo5@zmuvM zRjkh}`M7UI;DpW<&G#QhJ)O@ssXHyMp*mDGh0(|Q-+50h=EhbAkUKiu|LR|O{i|~8 zG#9?b`_jG2zRtb(d;J9c=WfRw1SLMc;#t4^)bdH$I%1_8mU!~AelPGZ&F0$q@R`9O zTlJYe_wAPLtUcO4Q%WhRoN3F19Qh9Ow1TBSOuwH0IP>TZsa20}Jy&_$o4sju^m418 zzVifG8;&#`T)}fG(e3OcJ!7?pmWGQJ4de}Ef$3J3k420{WPN8vSnXA Date: Wed, 18 Feb 2026 09:42:30 -0600 Subject: [PATCH 14/21] Fix format and checkstyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../RabbitDockerComposeConnectionDetailsFactory.java | 4 ++-- .../RabbitConnectionFactoryBeanConfigurer.java | 2 +- .../autoconfigure/RabbitStreamConfiguration.java | 9 ++++----- .../health/RabbitHealthContributorAutoConfiguration.java | 4 ++-- .../metrics/RabbitMetricsAutoConfiguration.java | 2 +- .../RabbitDockerComposeConnectionDetailsFactory.java | 2 +- ...abbitStreamDockerComposeConnectionDetailsFactory.java | 4 ++-- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java index 982a7a8a953f..8d3180126f71 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java @@ -26,8 +26,8 @@ import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; /** - * {@link DockerComposeConnectionDetailsFactory} to create - * {@link RabbitConnectionDetails} for a {@code rabbitmq} service. + * {@link DockerComposeConnectionDetailsFactory} to create {@link RabbitConnectionDetails} + * for a {@code rabbitmq} service. * * @author Andy Wilkinson */ diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java index 2187838ee69d..affee3b6b58c 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java @@ -23,8 +23,8 @@ import org.jspecify.annotations.Nullable; import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.core.io.ResourceLoader; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java index 4f22d3c7dcb9..3929d1b74535 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java @@ -23,13 +23,12 @@ import org.springframework.amqp.rabbit.config.ContainerCustomizer; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; - -import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.Stream; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.StreamContainer; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.Stream; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitProperties.StreamContainer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.rabbit.stream.config.StreamRabbitListenerContainerFactory; @@ -128,8 +127,8 @@ private static EnvironmentBuilder configure(EnvironmentBuilder builder, RabbitPr map.from(streamConnectionDetails.getHost()).to(builder::host); map.from(streamConnectionDetails.getPort()).to(builder::port); map.from(streamConnectionDetails.getVirtualHost()) - .orFrom(connectionDetails::getVirtualHost) - .to(builder::virtualHost); + .orFrom(connectionDetails::getVirtualHost) + .to(builder::virtualHost); map.from(streamConnectionDetails.getUsername()).orFrom(connectionDetails::getUsername).to(builder::username); map.from(streamConnectionDetails.getPassword()).orFrom(connectionDetails::getPassword).to(builder::password); return builder; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java index 6b7368effad8..4bd77803bbc3 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java @@ -18,8 +18,6 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.rabbitmq.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -28,6 +26,8 @@ import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.health.RabbitHealthIndicator; import org.springframework.context.annotation.Bean; /** diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java index f9b650e8be05..2ac68c1396db 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java @@ -20,11 +20,11 @@ import io.micrometer.core.instrument.MeterRegistry; import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java index e2485fdd942d..fe1af5077184 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java @@ -20,10 +20,10 @@ import org.jspecify.annotations.Nullable; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link RabbitConnectionDetails} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactory.java index e6c26c37862c..b1f91fcd8a61 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactory.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactory.java @@ -18,11 +18,11 @@ import org.jspecify.annotations.Nullable; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link RabbitConnectionDetails} From a8a85e82582d08136e4b2d6d2aa8d13abf966a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 09:52:42 -0600 Subject: [PATCH 15/21] Fix build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- ...ringframework.boot.autoconfigure.AutoConfiguration.imports | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index c301889a23c3..050f5729e283 100644 --- a/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/module/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,3 +1 @@ -org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration -org.springframework.boot.amqp.autoconfigure.health.RabbitHealthContributorAutoConfiguration -org.springframework.boot.amqp.autoconfigure.metrics.RabbitMetricsAutoConfiguration \ No newline at end of file +org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration \ No newline at end of file From 06aa868a8524909ae17bbbdae40d1f75c5a33a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 10:15:51 -0600 Subject: [PATCH 16/21] Fix build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- ...erConnectionDetailsFactoryIntegrationTests.java | 11 +++++------ .../RabbitAmqpAutoConfigurationTests.java | 2 -- .../docker/compose/RabbitEnvironmentTests.java | 2 -- ...seConnectionDetailsFactoryIntegrationTests.java | 8 ++++---- ...seConnectionDetailsFactoryIntegrationTests.java | 4 ++-- ...seConnectionDetailsFactoryIntegrationTests.java | 8 ++++---- ...erConnectionDetailsFactoryIntegrationTests.java | 14 +++++++------- ...erConnectionDetailsFactoryIntegrationTests.java | 14 +++++++------- ...erConnectionDetailsFactoryIntegrationTests.java | 14 +++++++------- .../autoconfigure/RabbitStreamConfiguration.java | 4 ++-- .../RabbitContainerConnectionDetailsFactory.java | 2 +- .../RabbitStreamConfigurationTests.java | 2 +- ...bitHealthContributorAutoConfigurationTests.java | 4 ++-- ...figurationMeterBinderCycleIntegrationTests.java | 2 +- .../RabbitMetricsAutoConfigurationTests.java | 2 +- 15 files changed, 44 insertions(+), 49 deletions(-) rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java (89%) rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java (92%) rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java (88%) rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java (86%) rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java (89%) rename module/{spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq}/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java (88%) diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java index 8a6c087bd566..ab4cf8da98ca 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -28,11 +28,10 @@ import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.RabbitListener; -import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration; import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; @@ -61,7 +60,7 @@ class RabbitContainerConnectionDetailsFactoryIntegrationTests { private RabbitConnectionDetails connectionDetails; @Autowired - private RabbitTemplate rabbitTemplate; + private RabbitAmqpTemplate rabbitAmqpTemplate; @Autowired private TestListener listener; @@ -69,13 +68,13 @@ class RabbitContainerConnectionDetailsFactoryIntegrationTests { @Test void connectionCanBeMadeToRabbitContainer() { assertThat(this.connectionDetails).isNotNull(); - this.rabbitTemplate.convertAndSend("test", "message"); + this.rabbitAmqpTemplate.convertAndSend("test", "message"); Awaitility.waitAtMost(Duration.ofMinutes(4)) .untilAsserted(() -> assertThat(this.listener.messages).containsExactly("message")); } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(RabbitAutoConfiguration.class) + @ImportAutoConfiguration(RabbitAmqpAutoConfiguration.class) static class TestConfiguration { @Bean diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java index bb553d5eb081..11ff3588403d 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfigurationTests.java @@ -32,8 +32,6 @@ import org.springframework.amqp.rabbitmq.client.listener.RabbitAmqpListenerContainer; import org.springframework.amqp.support.converter.MessageConversionException; import org.springframework.amqp.support.converter.MessageConverter; -import org.springframework.boot.amqp.autoconfigure.RabbitAmqpAutoConfiguration; -import org.springframework.boot.amqp.autoconfigure.RabbitAmqpTemplateCustomizer; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java index 5c10aaf910ab..1ecb0b4d6ff4 100644 --- a/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java +++ b/module/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java @@ -21,8 +21,6 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.amqp.docker.compose.RabbitEnvironment; - import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 89% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java index 5b1c7797bbac..ed3a542b4a71 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.amqp.docker.compose; +package org.springframework.boot.rabbitmq.docker.compose; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java index 1547fbf825c4..64da2785d53d 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.amqp.docker.compose; +package org.springframework.boot.rabbitmq.docker.compose; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 88% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java index d9f077bc21cd..cd4617688a6a 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.amqp.docker.compose; +package org.springframework.boot.rabbitmq.docker.compose; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java similarity index 86% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java index 1e65d213f2ac..d20002624910 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.testcontainers; +package org.springframework.boot.rabbitmq.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -31,12 +31,12 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.amqp.autoconfigure.EnvironmentBuilderCustomizer; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.EnvironmentBuilderCustomizer; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; +import org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; +import org.springframework.boot.rabbitmq.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java similarity index 89% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java index 778f6536bd57..b9e80bcbfee6 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.testcontainers; +package org.springframework.boot.rabbitmq.testcontainers; import java.nio.charset.StandardCharsets; import java.time.Duration; @@ -35,12 +35,12 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.amqp.autoconfigure.EnvironmentBuilderCustomizer; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.EnvironmentBuilderCustomizer; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; +import org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; +import org.springframework.boot.rabbitmq.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java similarity index 88% rename from module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java rename to module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java index 6dc8b12291c3..ebf8cdd94453 100644 --- a/module/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.amqp.testcontainers; +package org.springframework.boot.rabbitmq.testcontainers; import java.nio.charset.StandardCharsets; import java.time.Duration; @@ -35,12 +35,12 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.amqp.autoconfigure.EnvironmentBuilderCustomizer; -import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; -import org.springframework.boot.amqp.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.EnvironmentBuilderCustomizer; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; +import org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; +import org.springframework.boot.rabbitmq.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java index 3929d1b74535..84e3a2cad7c0 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfiguration.java @@ -127,8 +127,8 @@ private static EnvironmentBuilder configure(EnvironmentBuilder builder, RabbitPr map.from(streamConnectionDetails.getHost()).to(builder::host); map.from(streamConnectionDetails.getPort()).to(builder::port); map.from(streamConnectionDetails.getVirtualHost()) - .orFrom(connectionDetails::getVirtualHost) - .to(builder::virtualHost); + .orFrom(connectionDetails::getVirtualHost) + .to(builder::virtualHost); map.from(streamConnectionDetails.getUsername()).orFrom(connectionDetails::getUsername).to(builder::username); map.from(streamConnectionDetails.getPassword()).orFrom(connectionDetails::getPassword).to(builder::password); return builder; diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java index 9f549ce296a8..32a89a3e23ac 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactory.java @@ -49,7 +49,7 @@ protected RabbitConnectionDetails getContainerConnectionDetails( /** * {@link RabbitConnectionDetails} backed by a {@link ContainerConnectionSource}. */ - private static final class RabbitMqContainerConnectionDetails extends ContainerConnectionDetails + static final class RabbitMqContainerConnectionDetails extends ContainerConnectionDetails implements RabbitConnectionDetails { private RabbitMqContainerConnectionDetails(ContainerConnectionSource source) { diff --git a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java index 7ac24400d685..87b21eff7e26 100644 --- a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitStreamConfigurationTests.java @@ -33,8 +33,8 @@ import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.amqp.support.converter.MessageConverter; -import org.springframework.boot.amqp.autoconfigure.RabbitStreamConfiguration.PropertiesRabbitStreamConnectionDetails; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConfiguration.PropertiesRabbitStreamConnectionDetails; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java index 5218481d9894..4b3571c2c8c6 100644 --- a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java @@ -18,10 +18,10 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; -import org.springframework.boot.rabbitmq.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.rabbitmq.health.RabbitHealthIndicator; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java index e780e0e4ba6a..81928ab80091 100644 --- a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java @@ -22,8 +22,8 @@ import org.junit.jupiter.api.Test; import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java index cbcee9e1c58f..937a1203a096 100644 --- a/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java +++ b/module/spring-boot-rabbitmq/src/test/java/org/springframework/boot/rabbitmq/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java @@ -22,9 +22,9 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; From 13309202e85f419dd65df6b8cd64c4da3728fe55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 10:27:34 -0600 Subject: [PATCH 17/21] Fix checkstyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- ...amDockerComposeConnectionDetailsFactoryIntegrationTests.java | 2 +- ...itDockerComposeConnectionDetailsFactoryIntegrationTests.java | 2 +- ...amDockerComposeConnectionDetailsFactoryIntegrationTests.java | 2 +- ...amDockerComposeConnectionDetailsFactoryIntegrationTests.java | 2 +- ...RabbitContainerConnectionDetailsFactoryIntegrationTests.java | 2 +- ...RabbitContainerConnectionDetailsFactoryIntegrationTests.java | 2 +- ...StreamContainerConnectionDetailsFactoryIntegrationTests.java | 2 +- ...StreamContainerConnectionDetailsFactoryIntegrationTests.java | 2 +- ...StreamContainerConnectionDetailsFactoryIntegrationTests.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java index ed3a542b4a71..dcef4737265a 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -16,10 +16,10 @@ package org.springframework.boot.rabbitmq.docker.compose; +import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; -import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java index 3ac846109087..eeb49157abf9 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -16,9 +16,9 @@ package org.springframework.boot.rabbitmq.docker.compose; +import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; -import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java index 64da2785d53d..7e6092db4285 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/RabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.rabbitmq.docker.compose; -import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java index cd4617688a6a..ae9d61597f63 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/docker/compose/SingleServiceRabbitAndRabbitStreamDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -16,10 +16,10 @@ package org.springframework.boot.rabbitmq.docker.compose; +import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; -import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java index facdc9cda997..91aed53b74b5 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/DeprecatedRabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -30,9 +30,9 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java index c3d624598131..0dda1bfa18d6 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -30,9 +30,9 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java index d20002624910..8820db4606a9 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/RabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java @@ -31,13 +31,13 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.EnvironmentBuilderCustomizer; import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; import org.springframework.boot.rabbitmq.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java index b9e80bcbfee6..e28c2657a7c8 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SeparateContainersRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java @@ -35,13 +35,13 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.EnvironmentBuilderCustomizer; import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; import org.springframework.boot.rabbitmq.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java index ebf8cdd94453..3d306284fa4f 100644 --- a/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-rabbitmq/src/dockerTest/java/org/springframework/boot/rabbitmq/testcontainers/SingleContainerRabbitAndRabbitStreamContainerConnectionDetailsFactoryIntegrationTests.java @@ -35,13 +35,13 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.EnvironmentBuilderCustomizer; import org.springframework.boot.rabbitmq.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.rabbitmq.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.rabbitmq.autoconfigure.RabbitStreamConnectionDetails; import org.springframework.boot.rabbitmq.testcontainers.RabbitContainerConnectionDetailsFactory.RabbitMqContainerConnectionDetails; import org.springframework.boot.rabbitmq.testcontainers.RabbitStreamContainerConnectionDetailsFactory.RabbitMqStreamContainerConnectionDetails; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; From 3a9cd501182dac0b51576eb8dfa0cc2678d2dd27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 10:58:28 -0600 Subject: [PATCH 18/21] Update rabbitmq docker image version and support EnableRabbit for AMPQ 1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../RabbitAmqpAutoConfiguration.java | 2 + .../RabbitAnnotationDrivenConfiguration.java | 41 +++++++++++++++++++ ...ampleRabbitAmqpSimpleApplicationTests.java | 3 +- .../SampleRabbitAmqpSimpleApplication.java | 2 - .../boot/testsupport/container/TestImage.java | 2 +- 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java index 40f96c8b4e51..39f4979c2bef 100644 --- a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAmqpAutoConfiguration.java @@ -40,6 +40,7 @@ import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitAmqpTemplate}. @@ -50,6 +51,7 @@ @AutoConfiguration @ConditionalOnClass({ RabbitAmqpTemplate.class, Connection.class }) @EnableConfigurationProperties(RabbitProperties.class) +@Import(RabbitAnnotationDrivenConfiguration.class) public final class RabbitAmqpAutoConfiguration { private final RabbitProperties properties; diff --git a/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java new file mode 100644 index 000000000000..c2c766c096e7 --- /dev/null +++ b/module/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.amqp.autoconfigure; + +import org.springframework.amqp.rabbit.annotation.EnableRabbit; +import org.springframework.amqp.rabbit.config.RabbitListenerConfigUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for Spring AMQP annotation driven endpoints. + * + * @author Eddú Meléndez + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(EnableRabbit.class) +class RabbitAnnotationDrivenConfiguration { + + @Configuration(proxyBeanMethods = false) + @EnableRabbit + @ConditionalOnMissingBean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME) + static class EnableRabbitConfiguration { + + } + +} diff --git a/smoke-test/spring-boot-smoke-test-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java b/smoke-test/spring-boot-smoke-test-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java index 105c727ae758..bd9f51c562a5 100644 --- a/smoke-test/spring-boot-smoke-test-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java +++ b/smoke-test/spring-boot-smoke-test-amqp/src/dockerTest/java/smoketest/amqp/SampleRabbitAmqpSimpleApplicationTests.java @@ -30,6 +30,7 @@ import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; @@ -40,7 +41,7 @@ class SampleRabbitAmqpSimpleApplicationTests { @Container @ServiceConnection - static final RabbitMQContainer rabbit = new RabbitMQContainer("rabbitmq:4.0-management-alpine"); + static final RabbitMQContainer rabbit = TestImage.container(RabbitMQContainer.class); @Autowired private Sender sender; diff --git a/smoke-test/spring-boot-smoke-test-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java b/smoke-test/spring-boot-smoke-test-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java index 258131766e21..aff9bc342e3b 100644 --- a/smoke-test/spring-boot-smoke-test-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java +++ b/smoke-test/spring-boot-smoke-test-amqp/src/main/java/smoketest/amqp/SampleRabbitAmqpSimpleApplication.java @@ -20,7 +20,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.amqp.core.Queue; -import org.springframework.amqp.rabbit.annotation.EnableRabbit; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.boot.ApplicationRunner; @@ -30,7 +29,6 @@ import org.springframework.messaging.handler.annotation.Payload; @SpringBootApplication -@EnableRabbit @RabbitListener(queues = "foo") public class SampleRabbitAmqpSimpleApplication { diff --git a/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java b/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java index e64fc32615cf..67b52a1fa2be 100644 --- a/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java +++ b/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java @@ -247,7 +247,7 @@ public enum TestImage { /** * A container image suitable for testing RabbitMQ. */ - RABBITMQ("rabbitmq", "3.11-alpine", () -> RabbitMQContainer.class, + RABBITMQ("rabbitmq", "4.2.4-alpine", () -> RabbitMQContainer.class, (container) -> ((RabbitMQContainer) container).withStartupTimeout(Duration.ofMinutes(4))), /** From 0443251bd70c56ae31eebc57a9a91dae50f3b7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 11:12:42 -0600 Subject: [PATCH 19/21] Fix spring-boot-rabbimq test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- .../src/test/resources/logback-test.xml | 4 ---- .../boot/amqp/autoconfigure/test.jks | Bin 1294 -> 0 bytes .../RabbitAutoConfigurationTests.java | 14 +++++++------- 3 files changed, 7 insertions(+), 11 deletions(-) delete mode 100644 module/spring-boot-amqp/src/test/resources/logback-test.xml delete mode 100644 module/spring-boot-amqp/src/test/resources/org/springframework/boot/amqp/autoconfigure/test.jks diff --git a/module/spring-boot-amqp/src/test/resources/logback-test.xml b/module/spring-boot-amqp/src/test/resources/logback-test.xml deleted file mode 100644 index b8a41480d7d6..000000000000 --- a/module/spring-boot-amqp/src/test/resources/logback-test.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/module/spring-boot-amqp/src/test/resources/org/springframework/boot/amqp/autoconfigure/test.jks b/module/spring-boot-amqp/src/test/resources/org/springframework/boot/amqp/autoconfigure/test.jks deleted file mode 100644 index 8413be810956262d0da0387e8781fc4d27f6b027..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1294 zcmezO_TO6u1_mY|W&~r_+{*0KN+2&TwQlnkAl+}!#Mo`X$Ht}2#>m2`#U#kc$jZRd z#8^J5!~Wmp7|YE9c_o202CEfvPJAt&F-z+E+Y5Je-P@SM3x!M{?<`L$d7kPy>HgY< z0rl+7ddFPf9_^UC?)~PM8U_ciTzNlZu6ENGso!d;PtM$lt<~ROC~|P;oYPIU`ifCm z3xrl>nF}qFRax}#!Gf-mKc9ryWTqXD5RA>>WDIzayKC#wV=9~F(x>fBQsZQ6{U|+U z!WW$>x*Dgfn4=QHB86`zaB53NZvW1sG()7e{`TIV! z&3V4Ogyo;agqT?@rcVEe)EOO%0lu zJ}+QqVq{`s(UY*NH{fPt*J|@PXTieE%3zRVC;*H-=1>+kVfN6x?7aN)JeUXvh6p=` z2p5J3H--o^T*N?5oY&CYz!C_}4NXl=qCi|jBLfR4m(H$fV%z~ty*jYqU<7jHnHn1z z{?-RK%9aXg2Hp3Xqxa^?^KXLNgKXZrFdUY%Z`c;7mgySnpcME!(zZ9^*Z!klcNu&; zJv%h#dZTrNtV#Z-w1n;1GXs_`nLqypOSOQ~A^+Vgum9VAO!|j)`14~cmWlGS{BHhs z`Ka7sCesk%D6xq~-%3BP(@wmu_5PC*v*g^19*oDCL>ZQ_-Kd;Z$Hmz)N^9lLmRQG?vR>ZjR%X@$!Tw1Ryr|naXt4hMbo5@zmuvM zRjkh}`M7UI;DpW<&G#QhJ)O@ssXHyMp*mDGh0(|Q-+50h=EhbAkUKiu|LR|O{i|~8 zG#9?b`_jG2zRtb(d;J9c=WfRw1SLMc;#t4^)bdH$I%1_8mU!~AelPGZ&F0$q@R`9O zTlJYe_wAPLtUcO4Q%WhRoN3F19Qh9Ow1TBSOuwH0IP>TZsa20}Jy&_$o4sju^m418 zzVifG8;&#`T)}fG(e3OcJ!7?pmWGQJ4de}Ef$3J3k420{WPN8vSnXA { com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(context); @@ -954,9 +954,9 @@ void enableSslWithBundle() { void enableSslWithKeystoreTypeAndTrustStoreTypeShouldWork() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.key-store=/org/springframework/boot/amqp/autoconfigure/test.jks", + "spring.rabbitmq.ssl.key-store=/org/springframework/boot/rabbitmq/autoconfigure/test.jks", "spring.rabbitmq.ssl.key-store-type=jks", "spring.rabbitmq.ssl.key-store-password=secret", - "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/amqp/autoconfigure/test.jks", + "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/rabbitmq/autoconfigure/test.jks", "spring.rabbitmq.ssl.trust-store-type=jks", "spring.rabbitmq.ssl.trust-store-password=secret") .run((context) -> assertThat(context).hasNotFailed()); } @@ -988,10 +988,10 @@ void enableSslWithValidateServerCertificateDefault(CapturedOutput output) { void enableSslWithValidStoreAlgorithmShouldWork() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.key-store=/org/springframework/boot/amqp/autoconfigure/test.jks", + "spring.rabbitmq.ssl.key-store=/org/springframework/boot/rabbitmq/autoconfigure/test.jks", "spring.rabbitmq.ssl.key-store-type=jks", "spring.rabbitmq.ssl.key-store-password=secret", "spring.rabbitmq.ssl.key-store-algorithm=PKIX", - "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/amqp/autoconfigure/test.jks", + "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/rabbitmq/autoconfigure/test.jks", "spring.rabbitmq.ssl.trust-store-type=jks", "spring.rabbitmq.ssl.trust-store-password=secret", "spring.rabbitmq.ssl.trust-store-algorithm=PKIX") .run((context) -> assertThat(context).hasNotFailed()); @@ -1001,7 +1001,7 @@ void enableSslWithValidStoreAlgorithmShouldWork() { void enableSslWithInvalidKeyStoreAlgorithmShouldFail() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.key-store=/org/springframework/boot/amqp/autoconfigure/test.jks", + "spring.rabbitmq.ssl.key-store=/org/springframework/boot/rabbitmq/autoconfigure/test.jks", "spring.rabbitmq.ssl.key-store-type=jks", "spring.rabbitmq.ssl.key-store-password=secret", "spring.rabbitmq.ssl.key-store-algorithm=test-invalid-algo") .run((context) -> { @@ -1015,7 +1015,7 @@ void enableSslWithInvalidKeyStoreAlgorithmShouldFail() { void enableSslWithInvalidTrustStoreAlgorithmShouldFail() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/amqp/autoconfigure/test.jks", + "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/rabbitmq/autoconfigure/test.jks", "spring.rabbitmq.ssl.trust-store-type=jks", "spring.rabbitmq.ssl.trust-store-password=secret", "spring.rabbitmq.ssl.trust-store-algorithm=test-invalid-algo") .run((context) -> { From 8eac6a3c7507be7d072ea4ef62a0b11d3f0dfc7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 11:28:31 -0600 Subject: [PATCH 20/21] Remove exclusion from starter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- starter/spring-boot-starter-rabbitmq/build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/starter/spring-boot-starter-rabbitmq/build.gradle b/starter/spring-boot-starter-rabbitmq/build.gradle index c0bd8bad9b7b..2069eb480971 100644 --- a/starter/spring-boot-starter-rabbitmq/build.gradle +++ b/starter/spring-boot-starter-rabbitmq/build.gradle @@ -23,8 +23,7 @@ description = "Starter for using Spring AMQP with Rabbit MQ over AMQP 0.9.1 prot dependencies { api(project(":starter:spring-boot-starter")) - api(project(":module:spring-boot-rabbitmq")) { - exclude group: "org.springframework.amqp", module: "spring-rabbitmq-client" - } + api(project(":module:spring-boot-rabbitmq")) + api("org.springframework.amqp:spring-rabbit") } From ca9519bd3f874bc15948a6d669f176b8d91a9a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 18 Feb 2026 12:41:57 -0600 Subject: [PATCH 21/21] Cleanup and fix spring-boot-rabbitmq tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eddú Meléndez --- module/spring-boot-rabbitmq/build.gradle | 2 +- ...bbit-stream-separate-services-compose.yaml | 2 +- ...-rabbit-stream-single-service-compose.yaml | 0 .../docker/compose/rabbit-stream-compose.yaml | 0 .../AmqpEnvironmentBuilderCustomizer.java | 39 ------------------- .../RabbitAmqpTemplateCustomizer.java | 36 ----------------- ...DockerComposeConnectionDetailsFactory.java | 10 ++++- 7 files changed, 10 insertions(+), 79 deletions(-) rename module/{spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq}/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml (92%) rename module/{spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq}/docker/compose/rabbit-and-rabbit-stream-single-service-compose.yaml (100%) rename module/{spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp => spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq}/docker/compose/rabbit-stream-compose.yaml (100%) delete mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java delete mode 100644 module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java diff --git a/module/spring-boot-rabbitmq/build.gradle b/module/spring-boot-rabbitmq/build.gradle index 018fda1e6280..fcc106775fb9 100644 --- a/module/spring-boot-rabbitmq/build.gradle +++ b/module/spring-boot-rabbitmq/build.gradle @@ -28,7 +28,7 @@ description = "Spring Boot RabbiqMQ" dependencies { api(project(":core:spring-boot")) api("org.springframework:spring-messaging") - api("org.springframework.amqp:spring-rabbitmq-client") + api("org.springframework.amqp:spring-rabbit") compileOnly("com.fasterxml.jackson.core:jackson-annotations") diff --git a/module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml b/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml similarity index 92% rename from module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml rename to module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml index b6ea102d7bb6..a39fef48210d 100644 --- a/module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml +++ b/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-and-rabbit-stream-separate-services-compose.yaml @@ -18,4 +18,4 @@ services: - '5552' configs: plugins: - content: "[rabbitmq_stream]." + content: "[rabbitmq_stream]." \ No newline at end of file diff --git a/module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-and-rabbit-stream-single-service-compose.yaml b/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-and-rabbit-stream-single-service-compose.yaml similarity index 100% rename from module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-and-rabbit-stream-single-service-compose.yaml rename to module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-and-rabbit-stream-single-service-compose.yaml diff --git a/module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-stream-compose.yaml b/module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-stream-compose.yaml similarity index 100% rename from module/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-stream-compose.yaml rename to module/spring-boot-rabbitmq/src/dockerTest/resources/org/springframework/boot/rabbitmq/docker/compose/rabbit-stream-compose.yaml diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java deleted file mode 100644 index 8fd969bcce3a..000000000000 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/AmqpEnvironmentBuilderCustomizer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.rabbitmq.autoconfigure; - -import com.rabbitmq.client.amqp.Environment; -import com.rabbitmq.client.amqp.impl.AmqpEnvironmentBuilder; - -/** - * Callback interface that can be implemented by beans wishing to customize the - * auto-configured {@link Environment} that is created by an - * {@link AmqpEnvironmentBuilder}. - * - * @author Eddú Meléndez - * @since 4.0.0 - */ -@FunctionalInterface -public interface AmqpEnvironmentBuilderCustomizer { - - /** - * Customize the {@code AmqpEnvironmentBuilder}. - * @param builder the builder to customize - */ - void customize(AmqpEnvironmentBuilder builder); - -} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java deleted file mode 100644 index 108734d55eb3..000000000000 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/autoconfigure/RabbitAmqpTemplateCustomizer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.rabbitmq.autoconfigure; - -import org.springframework.amqp.rabbitmq.client.RabbitAmqpTemplate; - -/** - * Callback interface that can be used to customize a {@link RabbitAmqpTemplate}. - * - * @author Eddú Meléndez - * @since 4.0.0 - */ -@FunctionalInterface -public interface RabbitAmqpTemplateCustomizer { - - /** - * Callback to customize a {@link RabbitAmqpTemplate} instance. - * @param rabbitAmqpTemplate the rabbitAmqpTemplate to customize - */ - void customize(RabbitAmqpTemplate rabbitAmqpTemplate); - -} diff --git a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java index fe1af5077184..c7a619dc0649 100644 --- a/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java +++ b/module/spring-boot-rabbitmq/src/main/java/org/springframework/boot/rabbitmq/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java @@ -44,8 +44,14 @@ protected RabbitDockerComposeConnectionDetailsFactory() { } @Override - protected RabbitConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) { - return new RabbitDockerComposeConnectionDetails(source.getRunningService()); + protected @Nullable RabbitConnectionDetails getDockerComposeConnectionDetails( + DockerComposeConnectionSource source) { + try { + return new RabbitDockerComposeConnectionDetails(source.getRunningService()); + } + catch (IllegalStateException ex) { + return null; + } } /**