Fixes: https://github.com/spring-projects/spring-integration/issues/9754
Right now a correlation handler can discard messages in the expired group one by one.
In some scenarios it would be useful to have single message in discard for the whole group.
* Expose `discardIndividuallyOnExpiry` for the `AbstractCorrelatingMessageHandler`,
and `AggregatorFactoryBean`, and respective `CorrelationHandlerSpec` for DSL.
This new option takes action only if a `discardChannel` is provided,
and `sendPartialResultOnExpiry` is not set to `true`.
When `discardIndividuallyOnExpiry` is false, the messages in the expired group are packed
into a list for payload of a discarding single message.
* Test and document the new feature
Fixes: #9745
Issue link: https://github.com/spring-projects/spring-integration/issues/9745
The `IntegrationEvaluationContextFactoryBean` does not provide a `TypeLocator` by default.
That may lead to a class-not-found problem from different `ClassLoader` in the parallel Java `Stream` executor.
* Fix `IntegrationEvaluationContextFactoryBean` to use a `StandardTypeLocator` based on the `applicationContext.getClassLoader()`
**Auto-cherry-pick to `6.4.x` & `6.3.x`**
Fixes: https://github.com/spring-projects/spring-integration/issues/9743
Spring Integration provides observation for the `MessageChannel`, `MessageHandler`
and `MessageProducerSupport`.
The `SourcePollingChannelAdapter` is missing, and it is that only special endpoint which
deals with `MessageSource` implementations via scheduled tasks in the poller.
Essentially, this endpoint is a start of the flow, but it still is a consumer of data from the source system.
* Add an `Observation` logic to the `SourcePollingChannelAdapter`.
* Divide it into two phases: start (and open scope) when message is received; stop (and close scope) when the whole polling task for a message is done.
We need this separation because of transaction scope for the polling task.
At the same time we don't want to emit an observation for a void polling task.
* Change `MessageReceiverContext` to accept a `handlerType`.
The `MessageHandler` contributes a `handler`.
The new support in the `SourcePollingChannelAdapter` - `message-source`.
And change `MessageProducerSupport` to contribute a `message-producer`
* Verify the single trace is supported for the whole flow (including transaction synchronization) starting from a `SourcePollingChannelAdapter` in a new `SourcePollingChannelAdapterObservationTests`
* Document this new feature
Fixes: https://github.com/spring-projects/spring-integration/issues/5123
When `RedisMessageStore`, for example, adds and removes messages, it operates on two keys separately, which may cause problems in multi-threading due to non-atomic operations.
Although using Redis to delay messages is not a good idea, the abnormal loss of messages in the logs alerted me when the number of requests was not large.
By comparing the logs, the problem that the message group representing the metadata is not consistent with the actual message.
A simple solution is to add lock like in the `SimpleMessageStore`, which is also the approach taken in this pull request.
* Add `LockRegistry` to `AbstractMessageGroupStore`
* Normalize access levels and method name about the lock of `MessageGroupStore`
* Add document about the lock of `AbstractMessageGroupStore`
Fixes: https://github.com/spring-projects/spring-integration/issues/9706
Previously, if a `MessageGroupProcessor` returns a collection of payloads,
the `AbstractCorrelatingMessageHandler` has failed with the `IllegalArgumentException`
stating that only collection of messages is possible.
From now on such a restriction is eliminated and returned collection of payloads
is emitted as a single reply message from the aggregator.
* Add `AbstractCorrelatingMessageHandler.isResultCollectionOfMessages()`
to return `true` only if result is a collection of messages, treating them as a "partial sequence".
* Deprecate `AbstractCorrelatingMessageHandler.verifyResultCollectionConsistsOfMessages()`
since it is out of use now.
Fixes: https://github.com/spring-projects/spring-integration/issues/9683
Since we don't support SpEL-based Control Bus functionality anymore,
there is no need to keep separate `controlBusOnRegistry()`
* In all DSLs Deprecate `controlBusOnRegistry()` and restore `controlBus()` which is now fully based
on the `ControlBusCommandRegistry`
* Deprecate now out of use `<control-bus use-registry="">` attribute
* Fix `ControlBusParser` to not deal with `use-registry` attribute anymore
* Remove deprecated before `ExpressionControlBusFactoryBean` and `ExpressionCommandMessageProcessor`
* Remove `use-registry` from test configs
* Fix `ControlBusChainTests` to rely on a new Control Bus functionality
* Upgrade dependencies to latest reasonable
* Add `6.4.x` branch to Dependabot config
* Move `whats-new.adoc` content to `changes-6.3-6.4.adoc`
* Optimize `build.gradle` moving `add-opens` for `java.base/java.util` to common config block
Fixes: #9711
Issue link: https://github.com/spring-projects/spring-integration/issues/9711
The `SmbConfig.getUrl(_includePassword)` uses `URI.toASCIIString()` which has all the parts of the URI encoded.
Then this string is used by the `SmbShare` for its super constructor, which, in turn, calls `new URL()`
leading, essentially, to a second encoding round.
* Add `SmbConfig.rawUrl()` methods to return an `smb://` url as a plain string.
* Use this new API in the `SmbShare` for a delegation constructor
* Modify some tests to reflect and cover new behavior
**Auto-cherry-pick to `6.3.x`**
Fixes: #9684
Issue link: https://github.com/spring-projects/spring-integration/issues/9684
The `RemoteFileTemplate` is missing to create a temporary remote directory
* Fix `RemoteFileTemplate.sendFileToRemoteDirectory()` to create a `temporaryRemoteDirectory`
as well if it is different from already created `remoteDirectory`
* Add `SftpServerOutboundTests.autoCreateTemporaryDirectory()` to verify that `temporaryRemoteDirectory` is created and in-use
* Some other `SftpServerOutboundTests` refactoring for better code style
**Auto-cherry-pick to `6.3.x`**
Fixes: #9709
Issue link: https://github.com/spring-projects/spring-integration/issues/9709
The Java DSL loses an `inputChannel` when existing channel is referenced by its name.
Then the target IntegrationFlow does not contain a bean reference for this channel and when we call its `getInputChannel()` we got something from middle of the flow.
However, that `inputChannel` is really expected to be an input for the flow.
* Fix `IntegrationFlowBeanPostProcessor` to get a bean by `MessageChannelReference` and populate it into `targetIntegrationComponents`
as we do for newly created `DirectChannel` if there is no bean for provided `MessageChannelReference`
**Auto-cherry-pick to `6.3.x`**
Fixes: #9705
Issue link: https://github.com/spring-projects/spring-integration/issues/9705
Currently when any class that implements `AbstractReplyProducingMessageHandler` doesn't produce a reply it will log the message, even if no reply is required.
The message should only be logged if `isLoggingEnabled()` returns true as a handler that doesn't require a reply may be a normal operation that is expected, and if we've set `loggingEnabled` to false it shouldn't log the message.
* Prevent logging when no reply is provided for an `AbstractReplyProducingMessageHandler` if logging is disabled
**Auto-cherry-pick to `6.3.x`**
Fixes: #9702
Issue link: https://github.com/spring-projects/spring-integration/issues/9702
The current `CheckedCallable.unchecked()` returns `Runnable`, which is not an expectation.
* Deprecate `CheckedCallable.unchecked()` in favor of newly introduced `CheckedCallable.uncheckedCallable()`.
We cannot call it `unchecked()` as well, since `Callable` after erasure becomes similar to class signature as `Runnable`.
**Auto-cherry-pick to `6.3.x`**