GH-1175: Add @SpringRabbitTest
Resolves https://github.com/spring-projects/spring-amqp/issues/1175 - provision boilerplate infrastructure * Fix test name in doc * Remove `@ContextConfiguration` from doc.
This commit is contained in:
@@ -396,7 +396,7 @@ project('spring-rabbit-junit') {
|
||||
exclude group: 'org.springframework', module: 'spring-web'
|
||||
}
|
||||
api 'org.springframework:spring-web'
|
||||
optionalApi 'org.junit.jupiter:junit-jupiter-api'
|
||||
api 'org.junit.jupiter:junit-jupiter-api'
|
||||
api "org.assertj:assertj-core:$assertjVersion"
|
||||
optionalApi "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
optionalApi 'org.apache.logging.log4j:log4j-core'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* Provides support classes (Rules etc) for JUnit tests.
|
||||
* Provides support classes (Rules etc. with no spring-rabbit dependencies) for JUnit
|
||||
* tests.
|
||||
*/
|
||||
package org.springframework.amqp.rabbit.junit;
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2020 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.amqp.rabbit.test.context;
|
||||
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration;
|
||||
import org.springframework.amqp.rabbit.config.AbstractRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.rabbit.junit.BrokerRunningSupport;
|
||||
import org.springframework.amqp.rabbit.junit.RabbitAvailableCondition;
|
||||
import org.springframework.amqp.rabbit.test.context.SpringRabbitTest.ContainerType;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Adds infrastructure beans to the Spring test context.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.3
|
||||
*
|
||||
*/
|
||||
class SpringRabbitContextCustomizer implements ContextCustomizer {
|
||||
|
||||
private final SpringRabbitTest springRabbitTest;
|
||||
|
||||
SpringRabbitContextCustomizer(SpringRabbitTest test) {
|
||||
this.springRabbitTest = test;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
|
||||
Assert.isInstanceOf(GenericApplicationContext.class, context);
|
||||
GenericApplicationContext applicationContext = (GenericApplicationContext) context;
|
||||
BrokerRunningSupport brokerRunning = RabbitAvailableCondition.getBrokerRunning();
|
||||
CachingConnectionFactory cf;
|
||||
if (brokerRunning != null) {
|
||||
cf = new CachingConnectionFactory(brokerRunning.getConnectionFactory());
|
||||
}
|
||||
else {
|
||||
cf = new CachingConnectionFactory(this.springRabbitTest.host(), this.springRabbitTest.port());
|
||||
cf.setUsername(this.springRabbitTest.user());
|
||||
cf.setPassword(this.springRabbitTest.password());
|
||||
}
|
||||
applicationContext.registerBean("autoConnectionFactory", CachingConnectionFactory.class, () -> cf);
|
||||
applicationContext.registerBean("autoRabbitTemplate", RabbitTemplate.class, () -> new RabbitTemplate(cf));
|
||||
applicationContext.registerBean("autoRabbitAdmin", RabbitAdmin.class, () -> new RabbitAdmin(cf));
|
||||
AbstractRabbitListenerContainerFactory<?> factory;
|
||||
if (this.springRabbitTest.containerType().equals(ContainerType.simple)) {
|
||||
factory = new SimpleRabbitListenerContainerFactory();
|
||||
}
|
||||
else {
|
||||
factory = new DirectRabbitListenerContainerFactory();
|
||||
}
|
||||
factory.setConnectionFactory(cf);
|
||||
applicationContext.registerBean("autoContainerFactory", AbstractRabbitListenerContainerFactory.class,
|
||||
() -> factory);
|
||||
new RabbitBootstrapConfiguration().registerBeanDefinitions(null,
|
||||
(BeanDefinitionRegistry) applicationContext.getBeanFactory());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2020 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.amqp.rabbit.test.context;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.ContextCustomizerFactory;
|
||||
|
||||
/**
|
||||
* The {@link ContextCustomizerFactory} implementation to produce a
|
||||
* {@link SpringRabbitContextCustomizer} if a {@link SpringRabbitTest} annotation
|
||||
* is present on the test class.
|
||||
*
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
*/
|
||||
class SpringRabbitContextCustomizerFactory implements ContextCustomizerFactory {
|
||||
|
||||
@Override
|
||||
public ContextCustomizer createContextCustomizer(Class<?> testClass,
|
||||
List<ContextConfigurationAttributes> configAttributes) {
|
||||
SpringRabbitTest test =
|
||||
AnnotatedElementUtils.findMergedAnnotation(testClass, SpringRabbitTest.class);
|
||||
return test != null ? new SpringRabbitContextCustomizer(test) : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2020 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.amqp.rabbit.test.context;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.amqp.rabbit.junit.RabbitAvailable;
|
||||
|
||||
/**
|
||||
* Adds infrastructure beans to a Spring test context; do not use with Spring Boot since
|
||||
* it has its own auto configuration mechanism.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.3
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface SpringRabbitTest {
|
||||
|
||||
/**
|
||||
* Container type.
|
||||
*/
|
||||
enum ContainerType {
|
||||
simple, direct
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the host when not using {@link RabbitAvailable}.
|
||||
* @return the host.
|
||||
*/
|
||||
String host() default "localhost";
|
||||
|
||||
/**
|
||||
* Set the port when not using {@link RabbitAvailable}.
|
||||
* @return the port.
|
||||
*/
|
||||
int port() default 5672;
|
||||
|
||||
/**
|
||||
* Set the user when not using {@link RabbitAvailable}.
|
||||
* @return the user.
|
||||
*/
|
||||
String user() default "guest";
|
||||
|
||||
/**
|
||||
* Set the password when not using {@link RabbitAvailable}.
|
||||
* @return the password.
|
||||
*/
|
||||
String password() default "guest";
|
||||
|
||||
/**
|
||||
* Set the container type to determine which container factory to configure.
|
||||
* @return the type.
|
||||
*/
|
||||
ContainerType containerType() default ContainerType.simple;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Provides classes relating to the test application context.
|
||||
*/
|
||||
package org.springframework.amqp.rabbit.test.context;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Spring Test ContextCustomizerFactories
|
||||
org.springframework.test.context.ContextCustomizerFactory=\
|
||||
org.springframework.amqp.rabbit.test.context.SpringRabbitContextCustomizerFactory
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2020 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.amqp.rabbit.test.context;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.amqp.rabbit.config.AbstractRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.rabbit.junit.RabbitAvailable;
|
||||
import org.springframework.amqp.rabbit.junit.RabbitAvailableCondition;
|
||||
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.3
|
||||
*
|
||||
*/
|
||||
@RabbitAvailable
|
||||
@SpringJUnitConfig
|
||||
@SpringRabbitTest
|
||||
public class SpringRabbitTestTests {
|
||||
|
||||
@Autowired
|
||||
private RabbitTemplate template;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Autowired
|
||||
private RabbitAdmin admin;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Autowired
|
||||
private AbstractRabbitListenerContainerFactory<?> factory;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Autowired
|
||||
private RabbitListenerEndpointRegistry registry;
|
||||
|
||||
@Test
|
||||
void testAutowiring() {
|
||||
assertThat(((CachingConnectionFactory) template.getConnectionFactory()).getRabbitConnectionFactory())
|
||||
.isSameAs(RabbitAvailableCondition.getBrokerRunning().getConnectionFactory());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -22,6 +22,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* An {@link ImportBeanDefinitionRegistrar} class that registers
|
||||
@@ -44,7 +45,9 @@ import org.springframework.core.type.AnnotationMetadata;
|
||||
public class RabbitBootstrapConfiguration implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
public void registerBeanDefinitions(@Nullable AnnotationMetadata importingClassMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
if (!registry.containsBeanDefinition(
|
||||
RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
[[change-history]]
|
||||
== Change History
|
||||
|
||||
This section describes what changes have been made as versions have changed.
|
||||
@@ -9,6 +10,131 @@ See <<whats-new>>.
|
||||
[[previous-whats-new]]
|
||||
=== Previous Releases
|
||||
|
||||
==== Changes in 2.2 Since 2.1
|
||||
|
||||
This section describes the changes between version 2.1 and version 2.2.
|
||||
|
||||
===== Package Changes
|
||||
|
||||
The following classes/interfaces have been moved from `org.springframework.amqp.rabbit.core.support` to `org.springframework.amqp.rabbit.batch`:
|
||||
|
||||
* `BatchingStrategy`
|
||||
* `MessageBatch`
|
||||
* `SimpleBatchingStrategy`
|
||||
|
||||
In addition, `ListenerExecutionFailedException` has been moved from `org.springframework.amqp.rabbit.listener.exception` to `org.springframework.amqp.rabbit.support`.
|
||||
|
||||
===== Dependency Changes
|
||||
|
||||
JUnit (4) is now an optional dependency and will no longer appear as a transitive dependency.
|
||||
|
||||
The `spring-rabbit-junit` module is now a *compile* dependency in the `spring-rabbit-test` module for a better target application development experience when with only a single `spring-rabbit-test` we get the full stack of testing utilities for AMQP components.
|
||||
|
||||
===== "Breaking" API Changes
|
||||
|
||||
the JUnit (5) `RabbitAvailableCondition.getBrokerRunning()` now returns a `BrokerRunningSupport` instance instead of a `BrokerRunning`, which depends on JUnit 4.
|
||||
It has the same API so it's just a matter of changing the class name of any references.
|
||||
See <<junit5-conditions>> for more information.
|
||||
|
||||
===== ListenerContainer Changes
|
||||
|
||||
Messages with fatal exceptions are now rejected and NOT requeued, by default, even if the acknowledge mode is manual.
|
||||
See <<exception-handling>> for more information.
|
||||
|
||||
Listener performance can now be monitored using Micrometer `Timer` s.
|
||||
See <<micrometer>> for more information.
|
||||
|
||||
===== @RabbitListener Changes
|
||||
|
||||
You can now configure an `executor` on each listener, overriding the factory configuration, to more easily identify threads associated with the listener.
|
||||
You can now override the container factory's `acknowledgeMode` property with the annotation's `ackMode` property.
|
||||
See <<listener-property-overrides,overriding container factory properties>> for more information.
|
||||
|
||||
When using <<receiving-batch,batching>>, `@RabbitListener` methods can now receive a complete batch of messages in one call instead of getting them one-at-a-time.
|
||||
|
||||
When receiving batched messages one-at-a-time, the last message has the `isLastInBatch` message property set to true.
|
||||
|
||||
In addition, received batched messages now contain the `amqp_batchSize` header.
|
||||
|
||||
Listeners can also consume batches created in the `SimpleMessageListenerContainer`, even if the batch is not created by the producer.
|
||||
See <<choose-container>> for more information.
|
||||
|
||||
Spring Data Projection interfaces are now supported by the `Jackson2JsonMessageConverter`.
|
||||
See <<data-projection>> for more information.
|
||||
|
||||
The `Jackson2JsonMessageConverter` now assumes the content is JSON if there is no `contentType` property, or it is the default (`application/octet-string`).
|
||||
See <<Jackson2JsonMessageConverter-from-message>> for more information.
|
||||
|
||||
Similarly. the `Jackson2XmlMessageConverter` now assumes the content is XML if there is no `contentType` property, or it is the default (`application/octet-string`).
|
||||
See <<jackson2xml>> for more information.
|
||||
|
||||
When a `@RabbitListener` method returns a result, the bean and `Method` are now available in the reply message properties.
|
||||
This allows configuration of a `beforeSendReplyMessagePostProcessor` to, for example, set a header in the reply to indicate which method was invoked on the server.
|
||||
See <<async-annotation-driven-reply>> for more information.
|
||||
|
||||
You can now configure a `ReplyPostProcessor` to make modifications to a reply message before it is sent.
|
||||
See <<async-annotation-driven-reply>> for more information.
|
||||
|
||||
===== AMQP Logging Appenders Changes
|
||||
|
||||
The Log4J and Logback `AmqpAppender` s now support a `verifyHostname` SSL option.
|
||||
|
||||
Also these appenders now can be configured to not add MDC entries as headers.
|
||||
The `addMdcAsHeaders` boolean option has been introduces to configure such a behavior.
|
||||
|
||||
The appenders now support the `SaslConfig` property.
|
||||
|
||||
See <<logging>> for more information.
|
||||
|
||||
===== MessageListenerAdapter Changes
|
||||
|
||||
The `MessageListenerAdapter` provides now a new `buildListenerArguments(Object, Channel, Message)` method to build an array of arguments to be passed into target listener and an old one is deprecated.
|
||||
See <<message-listener-adapter>> for more information.
|
||||
|
||||
===== Exchange/Queue Declaration Changes
|
||||
|
||||
The `ExchangeBuilder` and `QueueBuilder` fluent APIs used to create `Exchange` and `Queue` objects for declaration by `RabbitAdmin` now support "well known" arguments.
|
||||
See <<builder-api>> for more information.
|
||||
|
||||
The `RabbitAdmin` has a new property `explicitDeclarationsOnly`.
|
||||
See <<conditional-declaration>> for more information.
|
||||
|
||||
===== Connection Factory Changes
|
||||
|
||||
The `CachingConnectionFactory` has a new property `shuffleAddresses`.
|
||||
When providing a list of broker node addresses, the list will be shuffled before creating a connection so that the order in which the connections are attempted is random.
|
||||
See <<cluster>> for more information.
|
||||
|
||||
When using Publisher confirms and returns, the callbacks are now invoked on the connection factory's `executor`.
|
||||
This avoids a possible deadlock in the `amqp-clients` library if you perform rabbit operations from within the callback.
|
||||
See <<template-confirms>> for more information.
|
||||
|
||||
Also, the publisher confirm type is now specified with the `ConfirmType` enum instead of the two mutually exclusive setter methods.
|
||||
|
||||
The `RabbitConnectionFactoryBean` now uses TLS 1.2 by default when SSL is enabled.
|
||||
See <<rabbitconnectionfactorybean-configuring-ssl>> for more information.
|
||||
|
||||
===== New MessagePostProcessor Classes
|
||||
|
||||
Classes `DeflaterPostProcessor` and `InflaterPostProcessor` were added to support compression and decompression, respectively, when the message content-encoding is set to `deflate`.
|
||||
|
||||
===== Other Changes
|
||||
|
||||
The `Declarables` object (for declaring multiple queues, exchanges, bindings) now has a filtered getter for each type.
|
||||
See <<collection-declaration>> for more information.
|
||||
|
||||
You can now customize each `Declarable` bean before the `RabbitAdmin` processes the declaration thereof.
|
||||
See <<automatic-declaration>> for more information.
|
||||
|
||||
`singleActiveConsumer()` has been added to the `QueueBuilder` to set the `x-single-active-consumer` queue argument.
|
||||
See <<builder-api>> for more information.
|
||||
|
||||
Outbound headers with values of type `Class<?>` are now mapped using `getName()` instead of `toString()`.
|
||||
See <<message-properties-converters>> for more information.
|
||||
|
||||
Recovery of failed producer-created batches is now supported.
|
||||
See <<batch-retry>> for more information.
|
||||
|
||||
==== Changes in 2.1 Since 2.0
|
||||
|
||||
===== AMQP Client library
|
||||
|
||||
@@ -13,6 +13,56 @@ Spring AMQP version 1.6 introduced the `spring-rabbit-test` jar, which provides
|
||||
It is anticipated that this project will expand over time, but we need community feedback to make suggestions for the features needed to help with testing.
|
||||
Please use https://jira.spring.io/browse/AMQP[JIRA] or https://github.com/spring-projects/spring-amqp/issues[GitHub Issues] to provide such feedback.
|
||||
|
||||
[[spring-rabbit-test]]
|
||||
==== @SpringRabbitTest
|
||||
|
||||
Use this annotation to add infrastructure beans to the Spring test `ApplicationContext`.
|
||||
This is not necessary when using, for example `@SpringBootTest` since Spring Boot's auto configuration will add the beans.
|
||||
|
||||
Beans that are registered are:
|
||||
|
||||
* `CachingConnectionFactory` (`autoConnectionFactory`). If `@RabbitEnabled` is present, its connectionn factory is used.
|
||||
* `RabbitTemplate` (`autoRabbitTemplate`)
|
||||
* `RabbitAdmin` (`autoRabbitAdmin`)
|
||||
* `RabbitListenerContainerFactory` (`autoContainerFactory`)
|
||||
|
||||
In addition, the beans associated with `@EnableRabbit` (to support `@RabbitListener`) are added.
|
||||
|
||||
.Junit5 example
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@SpringJunitConfig
|
||||
@SpringRabbitTest
|
||||
public class MyRabbitTests {
|
||||
|
||||
@Autowired
|
||||
private RabbitTemplate template;
|
||||
|
||||
@Autowired
|
||||
private RabbitAdmin admin;
|
||||
|
||||
@Autowired
|
||||
private RabbitListenerEndpointRegistry registry;
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
...
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class Config {
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
With JUnit4, replace `@SpringJunitConfig` with `@RunWith(SpringRunnner.class)`.
|
||||
|
||||
[[mockito-answer]]
|
||||
==== Mockito `Answer<?>` Implementations
|
||||
|
||||
|
||||
@@ -1,127 +1,12 @@
|
||||
[[whats-new]]
|
||||
== What's New
|
||||
|
||||
=== Changes in 2.2 Since 2.1
|
||||
=== Changes in 2.3 Since 2.2
|
||||
|
||||
This section describes the changes between version 2.1 and version 2.2.
|
||||
This section describes the changes between version 2.2 and version 2.3.
|
||||
See <<change-history>> for changes in previous versions.
|
||||
|
||||
==== Package Changes
|
||||
==== Testing Changes
|
||||
|
||||
The following classes/interfaces have been moved from `org.springframework.amqp.rabbit.core.support` to `org.springframework.amqp.rabbit.batch`:
|
||||
|
||||
* `BatchingStrategy`
|
||||
* `MessageBatch`
|
||||
* `SimpleBatchingStrategy`
|
||||
|
||||
In addition, `ListenerExecutionFailedException` has been moved from `org.springframework.amqp.rabbit.listener.exception` to `org.springframework.amqp.rabbit.support`.
|
||||
|
||||
==== Dependency Changes
|
||||
|
||||
JUnit (4) is now an optional dependency and will no longer appear as a transitive dependency.
|
||||
|
||||
The `spring-rabbit-junit` module is now a *compile* dependency in the `spring-rabbit-test` module for a better target application development experience when with only a single `spring-rabbit-test` we get the full stack of testing utilities for AMQP components.
|
||||
|
||||
==== "Breaking" API Changes
|
||||
|
||||
the JUnit (5) `RabbitAvailableCondition.getBrokerRunning()` now returns a `BrokerRunningSupport` instance instead of a `BrokerRunning`, which depends on JUnit 4.
|
||||
It has the same API so it's just a matter of changing the class name of any references.
|
||||
See <<junit5-conditions>> for more information.
|
||||
|
||||
==== ListenerContainer Changes
|
||||
|
||||
Messages with fatal exceptions are now rejected and NOT requeued, by default, even if the acknowledge mode is manual.
|
||||
See <<exception-handling>> for more information.
|
||||
|
||||
Listener performance can now be monitored using Micrometer `Timer` s.
|
||||
See <<micrometer>> for more information.
|
||||
|
||||
==== @RabbitListener Changes
|
||||
|
||||
You can now configure an `executor` on each listener, overriding the factory configuration, to more easily identify threads associated with the listener.
|
||||
You can now override the container factory's `acknowledgeMode` property with the annotation's `ackMode` property.
|
||||
See <<listener-property-overrides,overriding container factory properties>> for more information.
|
||||
|
||||
When using <<receiving-batch,batching>>, `@RabbitListener` methods can now receive a complete batch of messages in one call instead of getting them one-at-a-time.
|
||||
|
||||
When receiving batched messages one-at-a-time, the last message has the `isLastInBatch` message property set to true.
|
||||
|
||||
In addition, received batched messages now contain the `amqp_batchSize` header.
|
||||
|
||||
Listeners can also consume batches created in the `SimpleMessageListenerContainer`, even if the batch is not created by the producer.
|
||||
See <<choose-container>> for more information.
|
||||
|
||||
Spring Data Projection interfaces are now supported by the `Jackson2JsonMessageConverter`.
|
||||
See <<data-projection>> for more information.
|
||||
|
||||
The `Jackson2JsonMessageConverter` now assumes the content is JSON if there is no `contentType` property, or it is the default (`application/octet-string`).
|
||||
See <<Jackson2JsonMessageConverter-from-message>> for more information.
|
||||
|
||||
Similarly. the `Jackson2XmlMessageConverter` now assumes the content is XML if there is no `contentType` property, or it is the default (`application/octet-string`).
|
||||
See <<jackson2xml>> for more information.
|
||||
|
||||
When a `@RabbitListener` method returns a result, the bean and `Method` are now available in the reply message properties.
|
||||
This allows configuration of a `beforeSendReplyMessagePostProcessor` to, for example, set a header in the reply to indicate which method was invoked on the server.
|
||||
See <<async-annotation-driven-reply>> for more information.
|
||||
|
||||
You can now configure a `ReplyPostProcessor` to make modifications to a reply message before it is sent.
|
||||
See <<async-annotation-driven-reply>> for more information.
|
||||
|
||||
==== AMQP Logging Appenders Changes
|
||||
|
||||
The Log4J and Logback `AmqpAppender` s now support a `verifyHostname` SSL option.
|
||||
|
||||
Also these appenders now can be configured to not add MDC entries as headers.
|
||||
The `addMdcAsHeaders` boolean option has been introduces to configure such a behavior.
|
||||
|
||||
The appenders now support the `SaslConfig` property.
|
||||
|
||||
See <<logging>> for more information.
|
||||
|
||||
==== MessageListenerAdapter Changes
|
||||
|
||||
The `MessageListenerAdapter` provides now a new `buildListenerArguments(Object, Channel, Message)` method to build an array of arguments to be passed into target listener and an old one is deprecated.
|
||||
See <<message-listener-adapter>> for more information.
|
||||
|
||||
==== Exchange/Queue Declaration Changes
|
||||
|
||||
The `ExchangeBuilder` and `QueueBuilder` fluent APIs used to create `Exchange` and `Queue` objects for declaration by `RabbitAdmin` now support "well known" arguments.
|
||||
See <<builder-api>> for more information.
|
||||
|
||||
The `RabbitAdmin` has a new property `explicitDeclarationsOnly`.
|
||||
See <<conditional-declaration>> for more information.
|
||||
|
||||
==== Connection Factory Changes
|
||||
|
||||
The `CachingConnectionFactory` has a new property `shuffleAddresses`.
|
||||
When providing a list of broker node addresses, the list will be shuffled before creating a connection so that the order in which the connections are attempted is random.
|
||||
See <<cluster>> for more information.
|
||||
|
||||
When using Publisher confirms and returns, the callbacks are now invoked on the connection factory's `executor`.
|
||||
This avoids a possible deadlock in the `amqp-clients` library if you perform rabbit operations from within the callback.
|
||||
See <<template-confirms>> for more information.
|
||||
|
||||
Also, the publisher confirm type is now specified with the `ConfirmType` enum instead of the two mutually exclusive setter methods.
|
||||
|
||||
The `RabbitConnectionFactoryBean` now uses TLS 1.2 by default when SSL is enabled.
|
||||
See <<rabbitconnectionfactorybean-configuring-ssl>> for more information.
|
||||
|
||||
==== New MessagePostProcessor Classes
|
||||
|
||||
Classes `DeflaterPostProcessor` and `InflaterPostProcessor` were added to support compression and decompression, respectively, when the message content-encoding is set to `deflate`.
|
||||
|
||||
==== Other Changes
|
||||
|
||||
The `Declarables` object (for declaring multiple queues, exchanges, bindings) now has a filtered getter for each type.
|
||||
See <<collection-declaration>> for more information.
|
||||
|
||||
You can now customize each `Declarable` bean before the `RabbitAdmin` processes the declaration thereof.
|
||||
See <<automatic-declaration>> for more information.
|
||||
|
||||
`singleActiveConsumer()` has been added to the `QueueBuilder` to set the `x-single-active-consumer` queue argument.
|
||||
See <<builder-api>> for more information.
|
||||
|
||||
Outbound headers with values of type `Class<?>` are now mapped using `getName()` instead of `toString()`.
|
||||
See <<message-properties-converters>> for more information.
|
||||
|
||||
Recovery of failed producer-created batches is now supported.
|
||||
See <<batch-retry>> for more information.
|
||||
A new annotation `@SpringBootTest` is provided to automatically configure some infrastructure beans for when you are not using `SpringBootTest`.
|
||||
See <<spring-rabbit-test>> for more information.
|
||||
|
||||
Reference in New Issue
Block a user