JIRA: https://jira.spring.io/browse/INT-3897
The `StompMessageHandler` synchronized on the `sessionHandler` during `connectIfNecessary()`
performing mutually exclusive connect operation in the `StompSessionManager`.
Since the last one synchronizes on all `sessionHandler`s during its own operations, we end up with the deadlock
waiting for the `connectSemaphore`.
Change synchronization monitor object to the `connectSemaphore` accomplishing the same desired mutually exclusive connect logic
in the `StompMessageHandler`.
**Cherry-pick to 4.2.x**
https://jira.spring.io/browse/INT-3665
Fixes according Travis report
Introduce `...ExpressionString(String)` setter
Some further fixes and polishing
Address PR comments
JIRA: https://jira.spring.io/browse/INT-3904
When we use the same expression several times, the SpEL engine cache an `accessor` after the first use.
The next evaluation just bypass `canRead()` and in case of JSON that mean that we don't check that the income has the field or not.
For this case the `read()` must return `TypedValue.NULL` instead of just `null`.
JIRA: https://jira.spring.io/browse/INT-799
Some test classes (e.g. `TestUtils`) were duplicated in core to avoid cyclic
dependency.
Now that core messaging has been moved to spring-messaging, it is possible
to remove the dependencies on `spring-integration-core` from `spring-integration-test`.
A few minor test cases have been moved to `spring-integration-core`.
The simple polishing to the `build.gradle` and `ServiceActivatorOnMockitoMockTests`
JIRA: https://jira.spring.io/browse/INT-3900
The message-driven adapter should not unsubscribe if `cleanSession` is
`false`.
INT-3900: MQTT: Changes for 4.3 Only
Doc Polishing
JIRA: https://jira.spring.io/browse/INT-3534
Previously the `MethodInvokingMessageListProcessor` copied `Collection<Message<?>>`
in its `process()` method for the `delegate` to a new `Collection` unconditionally.
To improve performance, the collection is no longer copied unconditionally
in the `ExpressionEvaluatingMessageGroupProcessor`.
Also add an `important` note to the `aggregator.adoc` about the restriction with `unmodifiableCollection`.
JIRA: https://jira.spring.io/browse/INT-2787
The `correlationId` is `UUID` object by default Framework behavior.
This type isn't allowed for JMS Message properties mapping.
Add the mapping for the `IntegrationMessageHeaderAccessor.CORRELATION_ID` header as a `String`,
since on the other side it simply can be converted to the `UUID` object back.
For example `AbstractCorrelatingMessageHandler` does that automatically on the correlation function using `UUIDConverter`.
The provided `SplitterAggregatorTests` demonstrates the scenario when we weren't be able to aggregate by the unsupported `UUID` type.
I don't consider this as back-port fix, because the same can be simply achieved with the custom `JmsHeaderMapper`.
From other side this fix maybe like some side-effect breaking change.
I don't consider any `UUID` message header as a candidate to be converted to String and mapped, because to do that unconditionally
may cause some undesired issues. From other side it can be done with the custom `JmsHeaderMapper` in the end-application.
JIRA: https://jira.spring.io/browse/INT-3894
Allow UDP server port (and sender Ack port) to be selected by the operating system.
Also fix multicast tests to run on all platforms.
Change tests to use OS selected port.
JIRA: https://jira.spring.io/browse/INT-3895
* `@Ignore` `DelayerUsageTests.testDelayWithCustomScheduler()` as very weak test. (We can consider it to remove at all: doesn't test anything from our side)
* Add `LogAdjustingTestSupport` diagnostic to the `OutboundGatewayFunctionTests`
Tentative commit to see more logs from Travis
Additional diagnostics
More STOMP Diagnostics
JIRA: https://jira.spring.io/browse/INT-3896
Routers created by the `RouterFactoryBean` were not suppressed from being exported
by the context exporter when an `IMBE` is present.
Move the suppression logic to `postProcessAfterInitialization()` so the annotation on
the bean created by the factory bean is detected. The annotation is not detected on
the factory bean itself in `postProcessBeforeInitialization()`.
See https://jira.spring.io/browse/INT-3888 and its PullRequest
Note: rework `StompIntegrationTests` logic to use SockJS Client (that was enabled on the server side before).
This helps us to use `sessionId` which is as a `user` key on subscription phase.
In case of Standard Tomcat WebSocket Client we end up with the race condition when both client and server uses the same
`static` variable in the `WsSession` class, so we can't determine the server session correctly by the id on the client side.
The subscribe/send/unsubscribe logic works well because we are based on the **web socket** for the session, independently of its id.
JIRA: https://jira.spring.io/browse/INT-3889
The test case `pubSubLostConnectionTest` forces the connection closed and
then sends another message. It is testing recovery.
However, since the pub/sub queue is an auto-delete queue, we need to wait until
the new consumer is established and the queue exists, before sending the message after the test.
Otherwise, since the exchange is fanout, the message is simply dropped.
Also set `@DirtiesContext` on other tests.
Also remove non-tests.
I have __not__ removed the diagnostics because I don't believe this addresses AMQP-543.
JIRA: https://jira.spring.io/browse/INT-3888
Note sure yet what race condition we have in the `DefaultSubscriptionRegistry`,
but that looks for me better to follow with the standard `SubscriptionRegistry.findSubscriptions()`
to check subscription present, unless fail during `send()` because of `destinationLookup` early exit.
Fix for the `StompServerIntegrationTests`
Looks like we have to `reconnect()` for any `handleTransportError()` activity,
otherwise we are just hang in the Reactor's TCP reconnect loop without freeing resources
for other activities, e.g. start Embedded STOMP Broker.
Increase `receive` timeout in case of wait for the Broker Start
JIRA: https://jira.spring.io/browse/INT-3884
Previously, an outbound gateway within a chain allowed a `reply-channel` attribute
but it was ignored. The gateway's output channel is set to send the message to
the next element in the chain, or the chain's output channel if the gateway is
the last element.
Tighten the parser logic to detect and disallow a reply channel within a chain.
Polishing
MessagingTemplate had no timeout and could hang the build.
OnlyOneTrigger could fire before the message is sent; increase
the poller receive timeout so the poller thread blocks until the message is sent.
JIRA: https://jira.spring.io/browse/INT-3823
The test stops the endpoint.
The previous poller thread can 'steal' the `input` message, but since
it is interrupted, it can't send the message to the `publishedChannel`.
Add logic to wait until the previous poller has been interrupted in `receive()`.
Increase the endpoint `receiveTimeout` to ensure the thread will be interrupted.
Bump SF Version to 4.2.3
Remove `TRACE` logging from the `EnableIntegrationTests` since we have the fix already
Make some optimization around `@DirtiesContext`
* `ClientWebSocketContainer`: add some synchronization to avoid race conditions: https://build.spring.io/browse/INT-B41-492
* `TomcatWebSocketTestServer`: convert to `0` port to rely on the OS resolution for `localPort`
* Add `LogAdjustingTestSupport` for STOMP test
* `SftpServerTests`: use `0` port to rely on the OS resolution for `localPort`
* `ImapMailReceiver`, `OutboundGatewayFunctionTests` (JMS), `CachingClientConnectionFactoryTests`,
`AsyncGatewayTests`, `AsyncMessagingTemplateTests`, `GatewayParserTests`, `PriorityChannelTests`, `AggregatorIntegrationTests`: increase timeout
* `EnableIntegrationTests`: use `LogAdjustingTestSupport`
* `FileOutboundChannelAdapterParserTests`: rework `Thread.sleep()` with `CountDownLatch`
* `ConnectionToConnectionTests`: increase timeout and count iteration. Previously with `1sec` we may lose some events. And we can't just rely on the `10sec`,
because the last iteration will be so long
* `TcpOutboundGatewayTests`: `500ms` is so big timeout to wait for the `Exception` that in the high load environment we can yield to other Thread so long.
Like in our case to `server` Thread to send the reply for us. Therefore decrease the Exception timeout to the `50ms` and increase server delay to `2sec`
* `StompInboundChannelAdapterWebSocketIntegrationTests`: remove `@Qualifier("taskScheduler")` as a potential candidate to test against latest SF changes.
We're fine with `SF-4.2.2` and it is just a test-case. So, I don't see reason to wait for their fix here.
STOMP: `session = null` in adapters for any transportError
Polishing
JIRA: https://jira.spring.io/browse/INT-3882
Add reconnect support for the StompSession:
* Introduce `recoveryInterval` for the `AbstractStompSessionManager`
* Add reconnect scheduled task
* Add handling of the `ConnectionLostException` into the `AbstractStompSessionManager`,
as well as for the `StompInboundChannelAdapter` and `StompMessageHandler`
* Cover adapters reconnection feature with tests
* Documentation polishing
Rework logic according PR comments
* Make `StompMessageHandler` as a "lazy-load" for the connection
* Add "direct" connect interaction for the `AbstractStompSessionManager`
* Polishing tests
Polishing
Fix `StompAdaptersParserTests#testStompSessionManagerReconnect()` to use "fake" server port
Address PR comments
The further polishing
Some further polishing
* `AbstractStompSessionManager`: `reconnectFuture.cancel(true)` on each `scheduleReconnect()` to avoid something like "DDoS attack"
* Add reconnect feature test for the `StompInboundChannelAdapterWebSocketIntegrationTests`, closing and then refreshing again the `serverContext`
JIRA: https://jira.spring.io/browse/INT-3885
Possible dropped reply, causing timeout.
WARN org.springframework.integration.jms.JmsOutboundGateway#1.replyListener-1 jms.JmsOutboundGateway:1202
- Failed to consume reply with correlationId 164a49bf-c41d-4c0b-b012-55deecf001d1_2
java.lang.RuntimeException: No sender waiting for reply
- Reproduced by running the test in a loop
- Cleaned up test to aid debugging - capture a unique message at each stage
- Added additional debug logging to th gateway
Polishing
JIRA: https://jira.spring.io/browse/INT-3886
An SO user reported a short message delivery when an NIO connection was timed out.
See JIRA for link.
We could not produce the problem with his deserializer but it did identify a problem
with the standard `ByteArrayRawSerializer`.
With NIO, socket timeouts were reported to the deserializer as a normal EOF (-1). This
caused the raw serializer to emit a short message - it's signal for end of message is the
socket closure.
We can't treat a timeout as a normal EOF.
If the socket is forcibly timed out due to no recent data, throw a `SocketTimeoutException` to
the deserializer.
Just in case the old behavior is being relied upon, a boolean has been added to restore that
behavior. This is not recommended, as using timeout to delimit messages is not reliable.
* Fix typos
* Increase `MongoDbInboundChannelAdapterIntegrationTests` timeouts
* Some code polishing
Message producers are started in phase `Integer.MAX_INT / 2`.
The test case has a stomp inbound adapter and an event producer.
Since they are both in the same phase, the event producer can miss the `StompReceiptEvent`.
Change the phase of the event producer to ensure it is started before other message producers.
Examining the code revealed a possible (but improbable) NPE.
Checking the connection was disjoint from the publish; encapsulate the check within publish.
Synchronize the connectionLost method so it can't null the client while it is being checked.
Add `@SuppressWarnings("deprecation")` on the deprecated `connectIfNeeded()` usage.