JIRA: https://jira.spring.io/browse/AMQP-490 Currently, we suppress the error log if the channel is closed normally. However, we should also suppress if the channel is closed because the connection is closed normally.
JIRA: https://jira.spring.io/browse/AMQP-487 The `ChannelProxy.target` can be closed externally in between several `close` operations on the proxy. The second `close()` caused an NPE before this fix. In addition the closed `ChannelProxy` may be returned from the cache. Prevent NPE on the `target.close()` operation. **Cherry-pick to 1.4.x**
Enable attribute substitution in the code blocks, per http://asciidoctor.org/docs/user-manual/#applying-substitutions
JIRA: https://jira.spring.io/browse/AMQP-486 Initial Conversion Sentence-per-Line Considered best practice; easier to read future diffs. Polishing - Add 'Introduction' subsection to sections that have other subsections - Clean up container attribute table; use literal formatting on the first column Polishing More Polish Formatting in table Use `sourceDir = asciidoctor.outputDir` instead of `sourceDir = file("$buildDir/html")` for `reference` task Add `message-properties-converters` documentation from the latest master.
JIRA: https://jira.spring.io/browse/AMQP-476 Although the tangle was exposed by the `BatchingRabbitTemplate`, the `RabbitGatewaySupport` was incorrectly referencing the parent package. Move that class to `core` from `core.support`. Also fix some additional Sonar violations.
JIRA: https://jira.spring.io/browse/AMQP-474 Instead of replacing the placeholder on every log event, replace it once during initialization. Polishing; Restore ampqProps.appId AMQP-474: Polishing
JIRA: https://jira.spring.io/browse/AMQP-474 When logs are generated soon after initialization (as is the case for the test cases), some log messages could (infrequently) be lost. This is due to the `EventSender` seeing a `null` `applicationId`, generating a routing key: [null.org.springframework.amqp.rabbit.logback.AmqpAppenderIntegrationTests.DEBUG] instead of: [AmqpAppenderTest.org.springframework.amqp.rabbit.logback.AmqpAppenderIntegrationTests.DEBUG] (in the case of the logback test case). Since this does not match a binding, the log message is discarded and the test fails. Since the `applicationId` setter is called before `start()`, on the same thread, the only way this can happen is if the `EventSender` runs on a CPU that has a stale copy of the `AmqpAppender` in its cache (the applicationId field is not marked `volatile`). Rather than making all the log variables volatile, synchronized blocks are now used during `EventSender` initialization, to ensure the senders see the variable values correctly.
JIRA: https://jira.spring.io/browse/AMQP-469 Since `OtpConnection` isn't thread-safe between `sendRPC` and `receiveRPC`, add a new `sendAndReceiveRPC` and make its implementation in the `DefaultConnection` as `synchronized`. Modify `ErlangTemplate` to use that new operation. Having that even with `SingleConnectionFactory` we don't meet race condition when one thread may receive result of another one.
JIRA: https://jira.spring.io/browse/AMQP-472 Previously, any `IOException` during passive queue declaration would enter declaration retry and eventually throw a `QueuesNotAvailableException`. Whether or not that is recoverable depends on the container's `missingQueuesFatal` property. If the `IOException` is due to a connection close, we should not try to redeclare and, further, recovery should be unconditional. When a queue declaration fails, check if the connection is open and, if not, throw an `AmqpIOException`, causing container recovery to begin. If the connection is open continue retrying queue declaration as before. In addition, expose the queue declaration retry properties on the `SimpleMessageListenerContainer`. AMQP-472: Polishing Polishing - PR Comments AMQP-472: Polishing to the last changes
JIRA: https://jira.spring.io/browse/AMQP-466 Avoid (unlikely, but possible) breaking change. Deprecate `AddressUtils` altogether. Revert the impacted code to use only `message.getMessageProperties().getReplyToAddress()`, where the decoding operation is located now.
JIRA: https://jira.spring.io/browse/AMQP-466 1.4.1 introduced direct reply to and reply to address decoding required using `AddressUtils`. The code should have been put in the `Address` ctor.
JIRA: https://jira.spring.io/browse/AMQP-463 JRockit throws an `IllegalArgumentException` if a `TreeMap$Entry` is used after removal via the `Iterator`. The `PublishSubscribeChannelImpl` uses this technique. Obtain the entry value before removing the entry. Add a test to reproduce the problem with the JRockit JVM. Currently sends 10k messages across 100 threads; also tested with 1m messages across 100 threads with no lost confirms.
JIRA: https://jira.spring.io/browse/AMQP-457 If the listener container is configured to listen to multiple queues, it would be useful for the listener to have access to which queue a message was received from. Instead of a collection of consumer tags, maintain a `Map` of consumer tags to queue names and populate the message properties with the tag and queue name. In the spring-messaging header mapper, map the properties to headers (inbound only).