417 Commits

Author SHA1 Message Date
Gary Russell
cadd35f852 AMQP-504: Update to RabbitMQ 3.5.3 Client
JIRA: https://jira.spring.io/browse/AMQP-504

`TimeoutException`, deprecations.

Also, the JDK `javac` now seems to honor `@SuppressWarnings("deprecation")` - remove the lint `-deprecation` option

Conflicts:
	build.gradle
	spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/CachingConnectionFactoryTests.java
Resolved.
2015-10-02 11:00:08 -04:00
Gary Russell
9f3579155a AMQP-526: Backport AMQP-519 and AMQP-496
JIRA: https://jira.spring.io/browse/AMQP-526

Backport:

AMQP-496: CCF: Do Not Connect After AC Close

JIRA: https://jira.spring.io/browse/AMQP-496

Infrastructure only; assertion not backported due to it being a breaking change.

Backport:

AMQP-519: Shut Down Deferred Close Executor

JIRA: https://jira.spring.io/browse/AMQP-519
2015-10-01 12:14:27 -04:00
Gary Russell
4e129e06a7 AMQP-532: Fix Pub.Conf. Nacks on close()
JIRA: https://jira.spring.io/browse/AMQP-532

Properly use the iterator to remove the entries.
2015-09-13 13:22:49 -04:00
Gary Russell
5eac90369d AMQP-532: Pub.Conf. Concurrency
JIRA: https://jira.spring.io/browse/AMQP-532

Previously, pending confirms were synchronized on the map value (itself a map).

A concurrent modifification exception was reported in `generateNacksForPendingAcks`.

It's not clear how this could happen because all uses synchronize on the map value.

However, since only one thread can use a channel at a time (obtained from the CF), it
is safe to simply synchronize on the channel itself rather than using a complex locking
scheme.

Change synchronization to the channel object; synchronize on the channel in the
`RabbitTemplate.getUnconfirmed()` method.

Add javadocs to `addListener` to tell users they must synchronize on the channel.

In a future release, we should not expose the map - add a note to the Javadoc.

Also, while testing, it was determined that an issue could occur if the channel closes
after the listener is added but before the message was sent.

When the channel is a `PublisherCallbackChannel` throw an exception to the called if
the underlying channel closes; call the channel so it will distribute pending acks as
nacks.
(cherry picked from commit 7770da8)
2015-09-09 12:02:02 -04:00
Gary Russell
a30239cc58 AMQP-522: Make RabbitAdmin Constants Public
JIRA: https://jira.spring.io/browse/AMQP-522

Update docs.

Conflicts:
	src/reference/asciidoc/amqp.adoc
2015-08-12 17:05:34 -04:00
Artem Bilan
be36ffd120 AMQP-508: Queue Declaration IllegalArgumentExcept
JIRA: https://jira.spring.io/browse/AMQP-508

Fix cherry-pick conflicts: https://build.spring.io/browse/AMQP-B12X-44
2015-06-29 12:40:44 -04:00
Gary Russell
344fcb9f03 AMQP-508: Queue Declaration IllegalArgumentExcept.
JIRA: https://jira.spring.io/browse/AMQP-508

Workaround for https://github.com/rabbitmq/rabbitmq-java-client/issues/72
2015-06-29 12:02:26 -04:00
Gary Russell
460a74a800 AMQP-506: Publisher Confirms Concurrency
JIRA:https://jira.spring.io/browse/AMQP-506

`RabbitTemplate` provides a method `getUnconfirmed` to get aged
non-confirmed correlation data.

This was not thread-safe.

While the `pendingConfirms` objects in `RabbitTemplate` and `PublisherCallbackChannelImpl`
are concurrent hash maps, they are maps of maps with the inner maps being
`Collections.synchronizedSortedMap`. While iterating over these maps, they must be
synchronized.

Add a test case to reproduce the exception and verify the problem is resovled.
2015-06-29 11:27:12 -04:00
Gary Russell
75187b8df5 AMQP-500: Configurable SSL Algo, No Properties
JIRA: https://jira.spring.io/browse/AMQP-500

Enable algorithm selection when not using certificates.
(cherry picked from commit 059057e)
2015-06-02 10:12:31 -04:00
Gary Russell
436ffcd758 AMQP-498: Adjust Consumers With ChannelTransacted
JIRA: https://jira.spring.io/browse/AMQP-498

In earlier versions, the while loop to drain the queue took an early exit
when the channel was transacted. (This was actually incorrect since message
delivery is not transactional, only acks).

AMQP-388 introduced a new OR condition on the loop: `consumer.hasDelivery()`.

This effectively made the `continuable` boolean in the OR condition irrelevant.
This boolean was true if messages were received and the channel was not transactional.

Another side effect was the `continuable` boolean was incorrectly used to adjust the consumers
if the workload demanded. Instead, that decision should have depended just on whether
messages were received; whether the channel is transacted is irrelevent.

Remove the `continuable` boolean; fix the while loop and use a new boolean `receivedOk` which
indicates whether messages were received and so whether we should consider increasing the
consumers.

Add a test to verify consumers are adjusted for transactional channels.
2015-05-12 18:09:49 +03:00
Artem Bilan
e20037bb65 AMQP-481: Register @RabbitListener for @Lazy
JIRA: https://jira.spring.io/browse/AMQP-481

Previously the `@Lazy` components haven't been registered with `MessageListenerContainer`,
because `RabbitListenerEndpointRegistrar` has done that from its `afterPropertiesSet()`.

Add logic to `registerListenerContainer` on demand from the `RabbitListenerEndpointRegistrar#registerEndpoint`

**Cherry-pick to 1.4.x**
2015-05-06 15:12:55 +01:00
Gary Russell
b87f36263a AMQP-494: Extract RoutingConnectionFactory Iface
JIRA: https://jira.spring.io/browse/AMQP-494
2015-05-01 13:24:45 +03:00
Gary Russell
afeb2b64e7 AMQP-492: Enhance Timeout Exception (RPC)
JIRA: https://jira.spring.io/browse/AMQP-492

Add method name and arguments to timeout exception in Spring Remoting proxy.
2015-04-27 18:45:57 +03:00
Gary Russell
fa8cf62440 AMQP-493: Add Consumer Tag Naming Strategy
JIRA: https://jira.spring.io/browse/AMQP-493

Allow the user to generate custom consumer tags instead of the default server-generated tag.

Remove `ServerGeneratesConsumerTagStrategy` and replace it with ternary operator:
`(this.tagStrategy != null ? this.tagStrategy.createConsumerTag(queue) : "")`
2015-04-27 17:17:06 +03:00
Gary Russell
6947b31a67 AMQP-490: Suppress ERROR on Normal Close
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.
(cherry picked from commit d21b795)
2015-04-22 20:35:34 +03:00
Gary Russell
098f78d4f5 AMQP-489: Enhanced RepublishMessageRecoverer
JIRA: https://jira.spring.io/browse/AMQP-489

Support the addition of other headers to the republished message.
2015-04-09 19:03:07 +03:00
Gary Russell
078fd4ce36 AMQP-467: INFO Log When Connection is Opened
JIRA: https://jira.spring.io/browse/AMQP-467

Log at INFO level when a new connection is established; useful
when recovering a connection after a broker loss.
2015-04-03 19:54:31 +03:00
Artem Bilan
41ccf8a185 AMQP-487: Fix NPE in the CachingConnectionFactory
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**

Conflicts:
	spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/CachingConnectionFactoryTests.java

Resolved.
2015-04-03 11:39:06 +01:00
Attila Bukor
96386ffa5e AMQP-485: Fix SimpleMessageLContainer JavaDoc
JIRA: https://jira.spring.io/browse/AMQP-485
2015-03-17 12:38:06 +02:00
Gary Russell
8d65032fd5 AMQP-484: Selectable SSL Algo
JIRA: https://jira.spring.io/browse/AMQP-484

(must remain at SSLv3 when backporting to 1.4.x)

Also add overridable method for additional context customization.

AMQP-484: Javadoc Polishing

Change `TLSv1.1` to the `SSLv3` by default
2015-03-16 20:58:17 +02:00
Gary Russell
684c58d0da AMQP-482: Make LongString Limit Configurable
JIRA: https://jira.spring.io/browse/AMQP-482

Make the threshold at which `LongString`s are converted as `DataInputStream`s configurable.

Polishing

Revert `whats-new.xml` and `amqp.xml` changes
2015-03-04 21:25:19 +02:00
Gary Russell
23bd1dff38 AMQP-474:Log Appenders appId Replacement Once Only
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

Conflicts:
	spring-rabbit/src/main/java/org/springframework/amqp/rabbit/log4j/AmqpAppender.java
	spring-rabbit/src/main/java/org/springframework/amqp/rabbit/logback/AmqpAppender.java
2015-02-10 11:51:33 +02:00
Gary Russell
71051fdbbd AMQP-474: Fix Log Appenders
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.
2015-02-07 13:20:04 +02:00
Gary Russell
ac9fa0526f AMQP-472: Recover From Conn. Close During Init
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
2015-01-30 18:03:17 +02:00
Artem Bilan
55590cef12 AMQP-470 Make basicQos IOException non-fatal
JIRA: https://jira.spring.io/browse/AMQP-470

**Cherry-pick to 1.3.x & 1.4.x**
2015-01-28 09:49:58 -05:00
Gary Russell
53d15cbaad AMQP-466: Reinstate and Deprecate Constant
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.
2015-01-12 18:12:12 +02:00
Gary Russell
0055277ba7 AMQP-466: Move Direct reply-to Decoding to Address
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.
2015-01-12 12:52:30 +02:00
Gary Russell
ca14e276c6 AMQP-463: Fix Publisher Confirms with JRockit
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.
2015-01-05 14:45:25 -05:00
Gary Russell
1f38cee752 AMQP-457: ListenerContainer Provide Consumer Queue
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).
2015-01-05 17:41:45 +02:00
Gary Russell
171833571b AMQP-459: Add Channel Limit Option to CCF
JIRA: https://jira.spring.io/browse/AMQP-459

Add configuration such that the `channelCacheSize` can be
considered a limit of how many channels can be created and
a timeout when requesting a channel.

Polishing
2015-01-05 15:55:18 +02:00
Gary Russell
a50c47b664 Fix CCF Javadocs For CacheMode.CONNECTION 2014-12-26 12:34:20 -05:00
Gary Russell
f2922d1bfa XD-2079: Classloader for ContainerDelegate
JIRA: https://jira.spring.io/browse/XD-2079

Use the `ContainerDelegate`'s class loader to create the proxy.
Problems in XD creating the proxy to apply the advice chain
in the rabbit source.
2014-12-20 16:15:20 -05:00
Gary Russell
b789db4f44 AMQP-451: Change Release to Return Collection
JIRA: https://jira.spring.io/browse/AMQP-451

Change the return type of `releaseBatch` to `Collection` and
rename to `releaseBatches`.
2014-12-18 12:41:27 -05:00
Gary Russell
aa94105f03 AMQP-456: Don't ERROR Log For Passive Declare
JIRA: https://jira.spring.io/browse/AMQP-456

Previously all abnormal channel closes were logged at ERROR level,
even NOT FOUND for passive declarations.
2014-12-18 10:56:36 -05:00
Gary Russell
d9724d6a61 AMQP-453: Support Compression
JIRA: https://jira.spring.io/browse/AMQP-453

Add optional compression (gzip, zip) to the `RabbitTemplate` and
`SimpleMessageListenerContainer`.

- MessagePostProcessors
  -- support gzip, zip compression, decompression

- RabbitTemplate
  -- new properties `beforePublishPostProcessor`, `afterReceivePostProcessor`
  -- configure compression on send, decompression on receive

- Listener Container
  -- support decompression

- New Header
  -- `springAutoDecompress`, required for backards compatibility (so we don't decompress existing messages)

- Test cases

Fix Javadocs

AMQP-453 Polishing - PR Comments

- Support customization of the deflating streams
- Support ordered lists of post processors

Revert to Simple Subclasses

- Add support for compression level
- Default compression level is BEST_SPEED

AMQP-453 Add Tests to Verify Level

Refactoring Names
2014-12-17 17:33:57 -05:00
Gary Russell
882e94f6f4 AMQP-451: Support Flushing Batch
JIRA: https://jira.spring.io/browse/AMQP-451

- Add `flush()` to support flushing any partial batch.
- Implement `Lifecycle` and invoke `flush()` when stopped.
2014-12-12 11:19:44 -05:00
Gary Russell
2f22bb6e42 AMQP-451 Override 4 Argument send() (Batching)
JIRA: https://jira.spring.io/browse/AMQP-451

Spring Integration always invokes the 4 arg method.
2014-12-11 18:15:06 -05:00
Gary Russell
4fdfe1cdeb AMQP-446 Reduce Logs for Temporary Declarations
JIRA: https://jira.spring.io/browse/AMQP-446

Previously, 3 WARN log entries were generated when declaring
a non-durable, auto-delete, exclusive queue. 2 logs were generated
for a non-durable, auto-delete exchange.

Reduce log level to INFO and only emit 1 log per queue/exchange.
2014-12-11 12:16:29 -05:00
Gary Russell
eb6725f248 AMQP-451 Batching RabbitTemplate
JIRA: https://jira.spring.io/browse/AMQP-451

Released in stealth mode for now (no docs, javadocs marked `Experimental`).

This feature is to support XD; we can't incubate in XD because it needs a
change to the listener container.

AMQP-451 Add Perf Test

Move Debatching Code

Move from `SMLC.doReceiveAndExecute()` to `AMLC.executeListener()`.

- Change the cause of the `ListenerExecutionFailedException` on a bad
decode to a `MessageConversionException` so that the default error handler
will cause the message to be rejected - otherwise the badly formed message
will continually be redelivered by default.
- Add a test case to ensure a badly formed message is rejected.
2014-12-11 13:07:43 +02:00
Gary Russell
f08df63feb AMQP-448 Support 3.4.x Direct reply-to
JIRA: https://jira.spring.io/browse/AMQP-448

RabbitMQ now supports "Direct reply-to" where an RPC sender
can specify `amq.rabbitmq.reply-to` and the broker provides
special handling to return the reply to the sending channel.

This is more efficient than creating a temporary reply queue each
time. The `RabbitTemplate` has provided an alternative to creating
new reply queues via a reply message listener container and correlation
data.

With this change, the template now supports "Direct reply-to" and will
use it instead of temporary reply queues when no reply-listener is
provided.

Tested on a server with 3.4.1 RabbitMQ as well as one with 3.1.1 for
backwards compatibility.

__NOTE:__ On the receiving side, the message `reply_to` property
has the form `amq.rabbitmq.reply-to.<base64string>`. Because `/` is a
valid `base64` character, we can't use normal reply-to address decoding
`<exchange>/<routingKey>`. The `MessageListenerAdapter` therefore detects
that Direct reply-to is being used before decoding the address.

Polishing

Move reply address decoding to a static method in `Address` and invoke from all places
where it is needed.

Causes a minor leak of rabbitmq into spring-amqp (the name of the direct reply queue).

AMQP-448 Polishing; PR Comments
2014-12-08 19:15:07 +02:00
Gary Russell
5f45c3ee8a Fix Test Timing Issues
`template.getUnconfirmed(0)` won't return confirms pending in the
current millisecond. Change age to `-1`.
2014-11-13 13:15:32 -05:00
Jasper de Vries
30adfae9ec AMQP-439: RabbitListener.queues: add SpEL support
JIRA: https://jira.spring.io/browse/AMQP-439
2014-11-10 16:36:04 +02:00
Artem Bilan
d58a7b2599 AMQP-438: Fix MessagingMessageListenerAdapter
JIRA: https://jira.spring.io/browse/AMQP-438

Since `DefaultExceptionStrategy` treats only `org.springframework.amqp.support.converter.MessageConversionException` as `fatal`
and assuming backward compatibility for SF < 4.1, add `catch (org.springframework.messaging.converter.MessageConversionException ex) {`
to the `MessagingMessageListenerAdapter` to wrap that exception to the `org.springframework.amqp.support.converter.MessageConversionException`.
Having that the `DefaultExceptionStrategy` works with `@RabbitListener` as it is with generic `<rabbit:listener>`.
2014-10-31 12:26:30 +02:00
Gary Russell
fd1c08a99d AMQP-435 RabbitMQ Client 3.4.x Compatibility
JIRA: https://jira.spring.io/browse/AMQP-435

Add ...NoWait methods to the PublisherCallbackChannelImpl.
Invoke the wait versions for now; add TODOs to change to the
...NoWait versions when 3.4.0 is the minimum client.

AMQP-435 Polishing - Add getDelegate()

Throw UnsupportedOperationException telling users to invoke
via getDelegate().

Add `What's New` notice
2014-10-23 12:00:54 +03:00
Gary Russell
6b82463f58 AMQP-426 SMLC: Support Routing Connection Factory
JIRA: https://jira.spring.io/browse/AMQP-436

Use the list of queue names as the lookup key.

Polishing `testAbstractRoutingConnectionFactoryWithListenerContainer()` to reflect the dynamic usage
2014-10-23 11:40:40 +03:00
Artem Bilan
421152d2de AMQP-431: Add RabbitTemplate.recoveryCallback
JIRA: https://jira.spring.io/browse/AMQP-431

AMQP-431: Address PR comments

Doc Polishing
2014-10-21 12:09:50 -04:00
Gary Russell
fdd5ac9b20 AMQP-430 Fix Package Tangle
JIRA: https://jira.spring.io/browse/AMQP-430

Annotation support introduced a tangle between config and annotation.

Polishing - Move Test Cases
2014-10-20 16:12:27 +03:00
Soeren Unruh
ef0b1834d8 AMQP-432: Properly convert BasicProperties values to and from
MessageProperties

JIRA: https://jira.spring.io/browse/AMQP-432

Previously `DefaultMessagePropertiesConverter` converted just
`LongString`,
but BasicProperties may contain List and Map values with nested
LongStrings. Values unsupported by AMQP which are contained in Lists or
Maps are also not converted from `MessageProperties` to
`BasicProperties`.

Add logic to properly convert from LongString values nested in
Lists/Maps.
Add logic to properly convert unsupported values nested in Lists/Maps to
Strings.

**Cherry-pick to 1.3.x**

Code style polishing
2014-10-17 21:07:33 +03:00
Artem Bilan
ce0d165741 AMQP-428: Add Logback AmqpAppender
JIRA: https://jira.spring.io/browse/AMQP-433, https://jira.spring.io/browse/AMQP-428

Fix `amqp.rabbit.log4j.AmqpAppender` JavaDoc typo

Polishing

Add category abbreviation [o.s.a.r.l.AmqpAppenderIntegrationTests].

Retain full category in AMQP headers.
2014-10-16 09:09:38 -04:00
Artem Bilan
cbd330f0e4 AMQP-406: Add RoutingCF to the RabbitTemplate
JIRA: https://jira.spring.io/browse/AMQP-406

* Add support of `connection-factory-selector-expression` for the `RabbitTemplate`
and provide logic to bind target `ConnectionFactory` to the invocation context based on the result of the expression evaluation.

AMQP-406: Fix double ThreadLocal resource

Polishing

AMQP-406: introduce `receiveConnectionFactorySelectorExpression`

Doc Polishing
2014-10-15 13:45:10 -04:00