Resolves https://github.com/spring-projects/spring-amqp/issues/1236
The user may set the contentType to a `MimeType`.
Always use `toString()` when replacing the `contentType`.
**cherry-pick to 2.2.x, 2.1.x, 1.7.x**
(cherry picked from commit 8c7e4f95ee)
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/annotation/ContentTypeDelegatingMessageConverterIntegrationTests.java
Replaces https://github.com/spring-projects/spring-amqp/pull/1225
`manager.stop()` was never called to destroy the connection factory, preventing
JVM exit.
Also protect for re-connecting after stop (both appenders).
Tested with a Spring Boot application.
**cherry-pick to 2.2.x, 2.1.x, 1.7.x**
Resolves https://github.com/spring-projects/spring-amqp/issues/1219
The headers were mapped after message conversion.
This prevented using a `ContentTypeDelegatingMessageConverter` because
the content type was not set.
Add a header to control whether the user or converter gets to set the
content type property in the final message.
**cherry-pick to 2.2.x, 2.1.x, 1.7.x**
# Conflicts:
# spring-amqp/src/main/java/org/springframework/amqp/support/AmqpHeaders.java
# spring-amqp/src/main/java/org/springframework/amqp/support/converter/MessagingMessageConverter.java
# src/reference/asciidoc/amqp.adoc
# Conflicts:
# src/reference/asciidoc/amqp.adoc
* Respect `failedDeclarationRetryInterval` even when logging is not enabled.
**Cherry-pick to 2.1.x, 2.0.x & 1.7.x**
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/BlockingQueueConsumer.java
Fixes https://github.com/spring-projects/spring-amqp/issues/1038
Don't set `evaluatedFastReplyTo` if we didn't actually evaluate it because
the broker is down on the first request.
**cherry-pick to all 2.x; backport to 1.7.x**
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitTemplateTests.java
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitTemplateTests.java
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitTemplateTests.java
Fixes https://github.com/spring-projects/spring-amqp/issues/1026
When using a `channelCheckoutTimeout` with `CacheModeConnection`,
we incorrectly spin waiting for a connection until the timeout
expires.
We should only wait for a connection if the limit is exceeded.
**cherry-pick to all supported**
(cherry picked from commit dde7a37350)
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/CachingConnectionFactory.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/CachingConnectionFactoryTests.java
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/CachingConnectionFactoryTests.java
Fixes https://github.com/spring-projects/spring-amqp/issues/905
Default container thread names are based on the bean name. `@RabbitListener`
containers are not beans; use `getListenerId()` instead (which falls back
to bean name for other containers).
**cherry-pick to all supported branches**
(cherry picked from commit 5f4c60a969)
Fixes https://github.com/spring-projects/spring-amqp/issues/905
Default container thread names are based on the bean name. `@RabbitListener`
containers are not beans; use `getListenerId()` instead (which falls back
to bean name for other containers).
**cherry-pick to all supported branches**
(cherry picked from commit 5f4c60a969)
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/annotation/EnableRabbitIntegrationTests.java
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java
JIRA: https://jira.spring.io/browse/AMQP-847
To avoid unacked messages race condition when client timeouts, but at
this moment the message becomes available in queue, physically close
a receive channel on the `TimeoutException` from the `Future.get()`
**Cherry-pick to 2.0.x & 1.7.x**
When a connection is auto-recovered, the `RabbitAdmin` is not
invoked to re-declare auto-delete queues because the connection
listeners are not invoked.
Close an auto-recovered connection before it is recovered.
Tested with a stand-alone spring-cloud-bus application.
**Cherry-pick to 2.0.x, 1.7.x**
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/CachingConnectionFactoryIntegrationTests.java
JIRA: https://jira.spring.io/browse/AMQP-828
Close auto-recoving channels during recovery since the consumer is
no longer there.
This was previously fixed for the `BlockingQueueConsumer`, but not for
`template.receive()` operations.
* Polishing - PR Comments
AMQP-828: Fix race, removing the shutdown listener
The channel might close between the `isOpen()` test and removing the listener.
JIRA: https://jira.spring.io/browse/AMQP-827
Use the correct `payloadConverter` in the `MessagingMessageConverter`
to support `@RabbitListener` `Message<?>` return types.
**cherry-pick to 2.0.x, 1.7.x**
# Conflicts:
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/annotation/EnableRabbitIntegrationTests.java
https://build.spring.io/browse/PLATFORM-COM2-JOB1-605
* A couple tests doesn't send to the proper queue for the
consecutive consumers start logic to be triggered properly
* The `testIncreaseMinAtMax()` used "too long"
`startConsumerMinInterval` therefore existing consumers were able to
consumer all the messages
- add delivery tag to inbound delivery logs
- add trace logging to channel method calls
**cherry-pick to 2.0.x, 1.7.x**
(cherry picked from commit 4fdb1e4)
JIRA: https://jira.spring.io/browse/AMQP-814
Add retry to avoid race conditions with auto-delete, exclusive queues.
**cherry-pick to 2.0.x**
**back port to 1.7.x, without lambda in RabbitAdmin**
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java
Make it easier to customize the logging behavior of the default
error handler.
Add protected `log()` method and make `causeChainContainsARADRE()` protected.
**cherry-pick to 2.0.x, 1.7.x**
https://stackoverflow.com/questions/50350377/hide-runtime-exception-in-rabbitmq-listener/50354643#50354643
(cherry picked from commit 3a6176e)
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/ConditionalRejectingErrorHandler.java
JIRA: https://jira.spring.io/browse/AMQP-810
SMLC: adjusting the `concurrentConsumers` did not consider `maxConcurrentConsumers`.
- increase added consumers even if at max
- decrease removed consumers when they had increased due to max being set
Further, decreasing the `maxConcurrentConsumers` did not remove consumers if there
were more consumers than the new max.
- don't add consumers beyond the max
- don't remove consumers unless the new max is exceeded
**cherry-pick to 2.0.x, 1.7.x**
There will be some minor conflicts in 1.7.x since the modified test is JUnit5.
(cherry picked from commit daebf40)
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainerLongTests.java
* GH-723: Add AmqpResourceNotAvailableException
Fixesspring-projects/spring-amqp#723
To avoid an `NPE` when connection returns `null` for the
`createChannel()` in case of `channelMax` is reached, throw newly
introduced `AmqpResourceNotAvailableException`.
This exception can be used in the `RetryPolicy` to retry the original
operation after some back-off - the channel permit may be released in
between
**Cherry-pick to 2.0.x and 1.7.x**
* * Fix `AbstractConnectionFactoryTests` for proper mock
* Fix `amqp.adoc` according PR comments
JIRA: https://jira.spring.io/browse/AMQP-805
Fixes https://github.com/spring-projects/spring-amqp/issues/722
The `AmqpAppender.postProcessMessageBeforeSend()` is `public`
and uses a `protected` `Event` API.
This combination is useless when we use it from outside call and
also it is clashes with Kotlin
* Make `postProcessMessageBeforeSend()` as `protected` because
it's never been designed for public usage.
**Cherry-pick to 2.0.x, master**
JIRA: https://jira.spring.io/browse/AMQP-801
To properly assign the queue to the `ConsumeOkEvent`, we need perform
such a logic in the `Consumer.handleConsumeOk()`.
* Introduce `BlockingQueueConsumer.ConsumerDecorator` to be created on
each `channel.basicConsume()` for wrapping the target `InternalConsumer`
per queue
* Add getters to the `ConsumeOkEvent` for better interoperability
* Assert assigned queue names for the `ConsumeOkEvent`s in the
`SimpleMessageListenerContainerIntegration2Tests`
**Cherry-pick to 1.7.x**
* Add `ConsumerDecorator.consumerTag` property
* Add `ConsumerDecorator.toString()`
* Add JavaDocs for the `ConsumeOkEvent`
JIRA: https://jira.spring.io/browse/AMQP-801
The proper place to emit the `ConsumeOkEvent` is really a
`handleConsumeOk()` callback when broker answers us that consumer has
been subscribed to the queue
**Cherry-pick to 1.7.x**
https://build.spring.io/browse/AMQP-SA17X-120
There is some race condition in the Log4J that log messages
are processed on a wrong thread.
* Decrease logging level to the `WARN` for the `spring-rabbit` to
minimize the level of vulnerability for the `AmqpAppenderIntegrationTests`
JIRA: https://jira.spring.io/browse/AMQP-796
If an admin uses a transactional `RabbitTemplate` it will start a transaction.
If the connection was opened due to a `RabbitTemplate` operation it should participate
in the same transaction.
Previously, the template used a second channel and treated it as a local transaction.
Also fix the `RabbitAdmin` so it does no work if there is nothing to declare.
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitAdmin.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminDeclarationTests.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitAdminTests.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/core/RabbitTemplateTests.java
* Remove `RabbitTemplateTests` changes since they are not related to
the current state of the `RabbitAdmin`: the `RabbitTemplate`-based
constructor has been introduced since version `2.0`
JIRA: https://jira.spring.io/browse/AMQP-794
In the `ConditionalRejectingErrorHandleri.DefaultExceptionStrategy`,
if the `cause` of the `ListenerExecutionFailedException` is a `MessagingException`,
traverse the `cause` tree to find the root cause of all such exceptions unless
it's a fatal cause itself (`MethodArgumentResolutionException` or `MessageConversionException`).
The final fatal check is performed on the root cause.
JIRA: https://jira.spring.io/browse/AMQP-790
Previously, `afterReceivePostProcessors` were not called on `sendAndReceive()`
operations.
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java
JIRA: https://jira.spring.io/browse/AMQP-785Fixes: spring-projects/spring-amqp#689
- Only stop the container on one thread
- Ignore concurrent stops
- Interrupt consumer threads that are attempting to declare queues
- In `restart()` don't start a new consumer if the container is stopping
- Defer publishing consumer failure events until container is stopped
- Add a RecoveryListener if needed to ensure channels are never recovered
- Fix event publishing for `Error` - it is fatal
__backport to 1.7.x will require work__
Clear the declaring flag when exiting `start()` with exception.
Release the `activeObjectCounter` when interrupted while declaring.
Polishing stopped container lifecycle
Since restarted consumer is not be aware about stopped container,
it can restart properly when RabbitMQ comes back on-line independently
of the container state
* Add `active` flag to the `ActiveObjectCounter` and `deactivate()`
and `isActive()` hooks
* Use `ActiveObjectCounter.deactivate()` in the container shutdown
* Use `ActiveObjectCounter.isActive()` in the
`BlockingQueueConsumer.cancelled()`
* Use `BlockingQueueConsumer.cancelled()` in its `start()` toi check
container activity before performing network job
* Check `isActive()` state in the `AbstractMessageListenerContainer.shutdown()`
* Remove `SimpleMessageListenerContainer.containerStopping` in favor of
`isActive()` hook
Conflicts:
build.gradle
spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java
spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/ActiveObjectCounter.java
spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java
Resolved.
JIRA: https://jira.spring.io/browse/AMQP-776
JIRA: https://jira.spring.io/browse/AMQP-777
JIRA: https://jira.spring.io/browse/AMQP-782
Publish an event when a consumer successfully consumes from a queue.
Publish an event when an SMLC listener throws an `Error`.
Doc polishing.
Update minimum client version in docs; remove reference to broker version
since that's no longer linked to the client.
__cherry-pick to 1.7.x (minus DMLC change)__
# Conflicts:
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/DirectMessageListenerContainer.java
# spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/DirectMessageListenerContainerIntegrationTests.java
# spring-rabbit/src/test/java/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainerIntegration2Tests.java
# src/reference/asciidoc/quick-tour.adoc
* Rework `SimpleMessageListenerContainerIntegration2Tests` do not use
lambda for the `ApplicationEventPublisher` since it is there since
Spring 5 only
JIRA: https://jira.spring.io/browse/AMQP-784
When looking for matching methods, we matched on no annotation or @Payload.
Match should have been no annotation(s) or not @Header.
__cherry-pick to 1.7.x__
(cherry picked from commit 1ddc74f)
* Replace `@NonNull` with the `@Validated` for Spring `4.3` support