Fixes: #9821
Issue link: https://github.com/spring-projects/spring-integration/issues/9821
Previously, Spring Integration used JSch library for SFTP protocol,
and that one was able to follow symlinks.
Currently, the `SftpSession` uses `LSTAT` command which does not follow symlinks
* Fix `SftpSession` to call `sftpClient.stat()` instead of `lstat()`
to mitigate migration pain from JSch
**Auto-cherry-pick to `6.4.x` & `6.3.x`**
Adding two messages into a group may end up with wrong insert order.
Or better to say the timestamp of first messages inserted might be behind in the future after the second one.
This leads to a wrong order return for polling operation and, therefore, verification in the test.
* Fix `PostgresChannelMessageTableSubscriberTests` inserting `Thread.sleep(100);`
between `messageStore.addMessageToGroup()` operations
Fixes: https://github.com/spring-projects/spring-integration/issues/9792
The `StreamTransformer` closes `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` header value,
so this becomes unusable afterward.
In addition, it may even cause some problems downstream when the message could be serialized for
subsequent network interaction.
* Add logic to the `StreamTransformer` to build a new message, but remove `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` header
* Verify that header is removed in the `StreamingInboundTests`.
Addition `StreamingInboundTests` clean up for better code style.
Fixes: https://github.com/spring-projects/spring-integration/issues/9801
Spring Integration Apache Kafka inbound channel adapters have always produced
messages without `ID` & `TIMESTAMP` headers.
See `MessagingMessageConverter` used over there by default.
However, for consistency with the rest of Spring Integration channel adapters,
it would be better to have Kafka-specific behave same way.
* Configure default `MessagingMessageConverter` in the `KafkaMessageSource` & `KafkaMessageDrivenChannelAdapter`
for generating `ID` & `TIMESTAMP` headers.
The `spring-io/spring-github-workflows/.github/workflows/spring-merge-dependabot-pr.yml` behaviour has been changed.
So, this change is to test it for the next Dependabot updates cycle.
Fixes: #9794
Issue link: https://github.com/spring-projects/spring-integration/issues/9794
The `SmbConfig.rawUrl()` method doesn't apply any URL encoding,
resulting in parts of the `domainUserPass` that may contain a `@` character to break
the URL logic in regard to determining the hostname.
* Modify `SmbConfig.getDomainUserPass(_includePassword)` to conditionally encode the variables.
Makes sure to encode the individual parts to not undesirably encode the `;` and `:` characters, breaking other logic.
* Modify `SmbConfig.rawUrl(_includePassword)` and `SmbConfig.createUri(_includePassword)`
to call the modified method with the correct `_urlEncode` variable
Signed-off-by: Jelle Smits <110663902+smitsjelle@users.noreply.github.com>
[artem.bilan@broadcom.com: some code cleanup]
* Add author to the affected classes
* Remove redundant explicit exceptions list from the `SmbMessageHistoryTests`
**Auto-cherry-pick to `6.4.x` & `6.3.x`**
Signed-off-by: Artem Bilan <artem.bilan@broadcom.com>
Fixes: #9796
Issue link: https://github.com/spring-projects/spring-integration/issues/9796
The `org.apache.sshd.sftp.client.impl.SftpOutputStreamAsync` is shared object for the `DefaultSftpClient`
and it cannot be used concurrently.
The guarded `send()` operation in the `ConcurrentSftpClient` is not enough
since `DefaultSftpClient.write()` is called directly from the `SftpOutputStreamAsync.internalFlush()`.
And this in the end is called from the `SftpSession.write()`
* Fix `DefaultSftpSessionFactory.ConcurrentSftpClient` to override the `write()` method instead.
Guard it with a `Lock` and call `sftpMessage.waitUntilSent();` to ensure that no concurrent access
to the underlying `SftpOutputStreamAsync`.
**Auto-cherry-pick to `6.4.x` & `6.3.x`**
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