Commit Graph

11289 Commits

Author SHA1 Message Date
Artem Bilan
2b724c8a5d GH-8654: Fix bean deps for messaging annotations (#8657)
Fixes https://github.com/spring-projects/spring-integration/issues/8654

Spring Framework has an ability to start dependant beans automatically
when we start the current one.

The `AbstractMethodAnnotationPostProcessor` is missing a bean dependency
registration causing errors in target applications when Messaging Annotations configuration is used.

* Add `registerDependentBean()` into an `AbstractMethodAnnotationPostProcessor` when we generate
and register a `ConsumerEndpointFactoryBean`
* Change one of the `ClientManagerBackToBackTests` configuration to rely on a `@ServiceActivator`
for `Mqttv5PahoMessageHandler` bean to ensure that change in the `AbstractMethodAnnotationPostProcessor`
has a proper effect

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-06-26 15:03:24 -04:00
Spring Builds
6f97cfa4cc [artifactory-release] Next development version 2023-06-20 16:05:31 +00:00
Spring Builds
a9d3550ff4 [artifactory-release] Release version 6.0.6 2023-06-20 16:05:28 +00:00
abilan
7e337cb55b Upgrade dependencies; prepare for release 2023-06-20 11:06:48 -04:00
Vladislav Fefelov
b2533554ce Optimise maybeIndex() in JsonPropertyAccessor
The `NumberFormatException` flow control is costly
operation

* Use `Character.isDigit()` check iterating through property String
instead of `NumberFormatException` flow control

**Cherry-pick to `6.1.x`, `6.0.x` & `5.5.x`**
2023-06-16 13:44:58 -04:00
Gary Russell
192bd7ba0e GH-8638: Kafka: Send All Fails to Failure Channel
Resolves https://github.com/spring-projects/spring-integration/issues/8638

Previously, immediate failures (e.g. timeout getting metadata) were
only thrown as exceptions, and not sent to the failure channel, if present.

**cherry-pick to all supported branches**
2023-06-08 13:46:23 -04:00
Artem Bilan
485aa2a493 Fix memory leak in the FluxMessageChannel (#8622)
The `FluxMessageChannel` can subscribe to any volatile `Publisher`.
For example, we can call Reactor Kafka `Sender.send()` for
input data and pass its result to the `FluxMessageChannel`
for on demand subscription.
These publishers are subscribed in the `FluxMessageChannel`
and their `Disposable` is stored in the internal `Disposable.Composite`
which currently only cleared on `destroy()`

* Extract `Disposable` from those internal `subscribe()` calls
into an `AtomicReference`.
* Use this `AtomicReference` in the `doOnTerminate()`
to remove from the `Disposable.Composite` and `dispose()`
when such a volatile `Publisher` is completed

**Cherry-pick to `6.0.x` & `5.5.x`**
2023-05-15 16:29:18 -04:00
Artem Bilan
5278a389bf GH-8613: Add JsonPropertyAccessor type for native (#8614)
Fixes https://github.com/spring-projects/spring-integration/issues/8613

If `JsonPropertyAccessor` is registered for SpEL, it would be great
to have it working in native images as well.

Since SpEL is fully based on reflection, expose
`JsonPropertyAccessor$ComparableJsonNode` and `JsonPropertyAccessor$ArrayNodeAsList`
reflection hints for their method invocations from SpEL

**Cherry-pick to `6.0.x`**
2023-05-08 10:32:07 -04:00
Kazuki Shimizu
d38370ed05 GH-8609: Fix TcpConnectorInterceptor chain propagation
Fixes https://github.com/spring-projects/spring-integration/issues/8609

* Changed to passed the self instance to `addNewConnection()` instead of argument's connection
in a `TcpConnectionInterceptorSupport` to compose a chain of interceptors from top to down.
This way the target `Sender` get the last interceptor in a chain as its connection.

**Cherry-pick to `6.0.x` & `5.5.x`**
2023-05-05 09:33:31 -04:00
Spring Builds
313c38c222 [artifactory-release] Next development version 2023-04-19 19:26:22 +00:00
Spring Builds
5c77c40a8e [artifactory-release] Release version 6.0.5 2023-04-19 19:26:18 +00:00
abilan
e298f77f67 Upgrade dependencies; prepare for release 2023-04-19 13:28:20 -04:00
abilan
cc56b7a149 Remove trailing space in IntWebSocketContainer
**Cherry-pick to `6.0.x` & `5.5.x`**
2023-04-19 13:19:08 -04:00
Artem Bilan
9b425377af GH-8600: Fix WebSocket removeRegistration (#8601)
* GH-8600: Fix WebSocket `removeRegistration`

Fixes https://github.com/spring-projects/spring-integration/issues/8600

When we register a dynamic WebSocket endpoint and use a `WebSocketHandlerDecoratorFactory`
such an endpoint is not removed on an `IntegrationFlow` destruction.
The actual `WebSocketHandler` is decorated, however we still use an initial one
for condition.

* Refactor `IntegrationWebSocketContainer` to expose a `protected` setter for the
`WebSocketHandler` which is called from the `ServerWebSocketContainer` after decoration

**Cherry-pick to `6.0.x` & `5.5.x`**

* Fix language in Javadocs

Co-authored-by: Gary Russell <grussell@vmware.com>

---------

Co-authored-by: Gary Russell <grussell@vmware.com>
2023-04-19 12:55:24 -04:00
Artem Bilan
a45c3c5396 Fix NPEs in DSL Specs (#8597)
* Fix NPEs in DSL Specs

The `BaseWsInboundGatewaySpec` and `TailAdapterSpec` don't override super methods
and when we call them we fail with NPE since `target` was not populated.

* Fix `BaseWsInboundGatewaySpec` and its inheritors to populate the `target`
from their ctors.
* Remove redundant methods from `BaseWsInboundGatewaySpec` hierarchy
* Propagate `AbstractWebServiceInboundGateway` properties directly to the target
from the `BaseWsInboundGatewaySpec` inheritors
* Override `MessageProducerSpec` methods in the `TailAdapterSpec`
to populate respective option into the `FileTailInboundChannelAdapterFactoryBean`
* Expose more missed options for producer endpoint in the `FileTailInboundChannelAdapterFactoryBean`

**Cherry-pick to `6.0.x` & `5.5.x`**

* * `acceptIfNotNull()` for `errorMessageStrategy` in the `FileTailInboundChannelAdapterFactoryBean`

* * Fix `Unmarshaller` population logic in the `MarshallingWsInboundGatewaySpec`
2023-04-18 11:18:31 -04:00
Artem Bilan
863795c11f Propagate Reactor context over headers (#8591)
* Propagate Reactor context over headers

When we do something like `Flux.from(Publisher)`
and don't compose it with the one involved in the `Subscriber` context,
we lose this context.

* Provide a mechanism to propagate a Reactor context over message header
produce within that context.
* Restore this context in the `FluxMessageChannel` for a new publisher
we use in this channel

**Cherry-pick to `6.0.x`**

* Fix language in docs

Co-authored-by: Gary Russell <grussell@vmware.com>

---------

Co-authored-by: Gary Russell <grussell@vmware.com>
2023-04-10 11:54:33 -04:00
Igor Lovich
5d87360ff3 GH-8582: Add TX support for PostgresSubChannel
Fixes https://github.com/spring-projects/spring-integration/issues/8582

* Introduce a `PostgresSubscribableChannel.setTransactionManager()`
to wrap a message polling and dispatching operation into a transaction
* In addition add a `RetryTemplate` support around transaction attempts

**Cherry-pick to `6.0.x`**
2023-03-29 12:37:02 -04:00
Artem Bilan
9ffc2db9f5 GH-8577: Deprecate ImapIdleCA.sendingTaskExecutor (#8589)
* GH-8577: Deprecate ImapIdleCA.sendingTaskExecutor

Fixes https://github.com/spring-projects/spring-integration/issues/8577

When we process mail messages in async manner, it is possible that we end up
in a race condition situation where the next idle cycle closes the folder.

It is possible to reopen the folder, but feels better to block the current idle
cycle until we are done with the message and therefore keep folder opened.

* Deprecate `ImapIdleChannelAdapter.sendingTaskExecutor` in favor of an `ExecutorChannel`
as an output for this channel adapter or similar async hand-off downstream.
* Make a default one as a `SyncTaskExecutor` to make a sense of this deprecation

* Fix language in docs

Co-authored-by: Gary Russell <grussell@vmware.com>

---------

Co-authored-by: Gary Russell <grussell@vmware.com>
2023-03-29 09:49:59 -04:00
Auke Zaaiman
482a466441 GH-8581: Don't overwrite external SshClient
Fixes https://github.com/spring-projects/spring-integration/issues/8581

Do not overwrite configuration of externally provided `SshClient` in the `DefaultSftpSessionFactory`

* Replace JUnit `assertDoesNotThrow` by AssertJ `assertThatNoException` in test

**Cherry-pick to `6.0.x`**
2023-03-28 11:24:45 -04:00
Spring Builds
8a9a47e190 [artifactory-release] Next development version 2023-03-22 17:28:00 +00:00
Spring Builds
bb0733abb2 [artifactory-release] Release version 6.0.4 2023-03-22 17:27:57 +00:00
abilan
ae58effa25 Fix Kafka test for latest Spring Retry 2023-03-22 12:27:31 -04:00
abilan
9ecf7f4c5b Fix MultipartAsRawByteArrayTests for new SF
The `ByteArrayHttpMessageConverter` now uses a `readNBytes()`
if `Content-Length` is `0`
2023-03-22 10:56:57 -04:00
abilan
1059add6ac Upgrade dependencies; prepare for release 2023-03-22 10:18:32 -04:00
Artem Bilan
61809c5985 GH-8573: Fix KafkaMessageSource samples in docs (#8575)
Fixes https://github.com/spring-projects/spring-integration/issues/8573

* Also add a Kotlin DSL sample

**Cherry-pick to `6.0.x` & `5.5.x`**
2023-03-20 10:59:48 -04:00
Artem Bilan
434c3060bd GH-8566: Fix SftpSession.append() for Write (#8576)
Fixes https://github.com/spring-projects/spring-integration/issues/8566

Turns out some SFTP servers are strict enough to not let to append into existing file
if we don't give in addition a `Write` open mode flag as well

**Cherry-pick to `6.0.x`**
2023-03-20 10:56:48 -04:00
Anton Gabov
46e684ef32 RedisLockRegistry: Don't expire not acquired lock
Fix race condition, when methods `RedisLockRegistry#expireUnusedOlderThan` and `RedisLockRegistry#obtain` are executed successively. 

It's possible to delete the lock from `RedisLockRegistry#expireUnusedOlderThan` method, when lock is created but is not acquired (`RedisLock#getLockedAt = 0`)
It can lead to the situation, when `RedisLockRegistry#obtain` returns multiple locks with the same redis-key, which shouldn't happen at all.

* Skip locks from expiration when their `lockedAt == 0` - new, not acquired yet.

**Cherry-pick to `6.0.x` & `5.5.x`**
2023-03-15 11:18:48 -04:00
Artem Bilan
2adf33467c Some LockRegistryLeaderInitiator improvements (#8570)
* Some `LockRegistryLeaderInitiator` improvements

It is better to not go to the target lock provider at all
if the current thread is already interrupted.

* Check for the `Thread.currentThread().isInterrupted()` in the `while` loop
and `restartSelectorBecauseOfError()` immediately without checking for a lock
* Fix some other simple typos in the `LockRegistryLeaderInitiator`

**Cherry-pick to `6.0.x`**

* * Introduce a `LeaderSelector.yielding` flag
to revoke leader smoothly.
Turns out just canceling the `Future` may lead to a broken lock
where we cannot unlock it because the target lock repository may not work
with interrupted threads.
This way a new leader must wait until the lock is expired in the store
2023-03-15 10:10:51 -04:00
Chris Bono
5c96c0ded0 Reduce instance supplier use to appease AOT
* Remove the use of instance suppliers on bean definitions
that are processed during the AOT phase.

* The remaining areas that use instance suppliers do so
at runtime and do not use reflection, but instead
are passed the configured bean to register.

See https://github.com/spring-cloud/spring-cloud-stream/issues/2655

**Cherry-pick to `6.0.x`**
2023-03-02 19:01:21 -05:00
Artem Bilan
d9f3821b9b GH-8562: Fix streaming source for remote calls (#8564)
* GH-8562: Fix streaming source for remote calls

Fixes https://github.com/spring-projects/spring-integration/issues/8562

The `AbstractRemoteFileStreamingMessageSource.doReceive()` takes files first from a `toBeReceived` queue.
When `AbstractRemoteFileStreamingMessageSource.remoteFileToMessage()` fails to fetch the file content
because of interim connection issue, we reset this file from a filter and rethrow an exception.
The next `receive()` call will just go ahead to the next entry in the `toBeReceived` queue, but the
file we have just failed for will be retried only on the next list call to the remove directory.
This essentially breaks a possible in-order target application logic.

* Introduce `AbstractRemoteFileStreamingMessageSource.strictOrder` option to clear the `toBeReceived` queue
 when we fail in the `remoteFileToMessage()`, so the next `receive()`
 call would re-fetch files from remote dir, because the filter has been reset for those files.
* Fix `AbstractFileInfo.toString()` to not perform remote calls when we just log this file.
For example, we reset the file for connection failure and log the message about it,
but it fails again because we request `size` of the file which may require a remote connection.

**Cherry-pick to `6.0.x` & `5.5.x`**

* * Revert `AbstractFileInfo` changes
* Override `toString()` in `SmbFileInfo` instead -
exactly the place where connection is used to obtain
file attributes like `size` or `lastModified`
2023-02-28 16:43:48 -05:00
abilan
36c05ff3e6 Fix new Sonar smells
**Cherry-pick to `6.0.x`**
2023-02-22 12:39:39 -05:00
Spring Builds
ab32591012 [artifactory-release] Next development version 2023-02-21 19:31:05 +00:00
Spring Builds
7592c64073 [artifactory-release] Release version 6.0.3 2023-02-21 19:31:02 +00:00
abilan
ee5ea036cc Fix deprecations from upstream dependencies 2023-02-21 13:47:15 -05:00
abilan
a8dd9188c1 Upgrade dependencies; prepare for release 2023-02-21 13:14:40 -05:00
Artem Bilan
ee2b6b4098 Fix MQTT Inbound readyToSubscribeOnStart logic (#8557)
We cannot always reset `readyToSubscribeOnStart` to `false` in the `stop()`
since we may be connected to `ClientManager` and have `cleanStart` option,
so we `unsubscribe()` in the stop and then when we start there is no way to subscribe back

* Reset `readyToSubscribeOnStart` in the `AbstractMqttMessageDrivenChannelAdapter.doStop()`
only if we don't unsubscribe for a `cleanSession` reason.
* Also reset it in the `connectionLost`, so next `connectComplete` will take care about subscription
or `readyToSubscribeOnStart` state change
* Use `isActive()` instead of `isRunning()` in the `connectComplete()` since there is a race
condition when connection is established but `doStart()` has not returned yet, but already passed
`if (this.readyToSubscribeOnStart)` line
2023-02-21 12:57:30 -05:00
Artem Bilan
ac577e9ef7 Optional io.micrometer:context-propagation (#8556)
For better performance by default it is better to not pull
a `io.micrometer:context-propagation` a hard dependency.

* Remove `io.micrometer:context-propagation` dependency management
* It is pulled transitively by the `io.micrometer:micrometer-tracing-integration-test` in test scope
* Rework all the `ContextSnapshot` usage in the reactive code to respective recommended `handle()` API in `Flux` and `Mono`
2023-02-21 12:02:15 -05:00
Artem Bilan
b482b002cb GH-4014: MQTT ClientManager: completion timeouts (#8552)
Fixes https://github.com/spring-projects/spring-integration/issues/4014

The `ClientManager` implementations uses by mistake a `connectionTimeout` for operations with completion wait

* Introduce `completionTimeout` and `disconnectCompletionTimeout` for `ClientManager`
abstraction to realign the logic with existing channel adapters and Paho Client by itself.
* Deprecate `DEFAULT_COMPLETION_TIMEOUT` and `DISCONNECT_COMPLETION_TIMEOUT` constants
in the `AbstractMqttMessageDrivenChannelAdapter` in favor of respective replacement in the `ClientManager`
* Pull `disconnectCompletionTimeout` property from the `MqttPahoMessageDrivenChannelAdapter` to its superclass
* Use new `disconnectCompletionTimeout` in the `Mqttv5PahoMessageDrivenChannelAdapter` for similar `disconnectForcibly()` call
* Fix Lifecycle race condition when `ClientManager` is started by the outbound channel adapter
(`Integer.MIN_VALUE` phase and auto-startup - see `DefaultLifecycleProcessor.doStart()` and logic around `dependencies`)
which is much earlier than `MessageProducerSupport` (`Integer.MAX_VALUE / 2` phase) and there a `connectComplete()` callback
might be called before the `MessageProducerSupport.start()`.
For that purpose check for an `isRunning()` in the `connectComplete()` before subscribing and set `readyToSubscribeOnStart` flag
to `subscribe()` in a `doStart()` of this `MqttMessageDrivenChannelAdapter`
* Remove redundant `MqttPahoMessageDrivenChannelAdapter.cleanSession` property in favor of
`this.clientFactory.getConnectionOptions().isCleanSession()` call

GH-8550: MQTT: Always re-subscribe on re-connect

Fixes https://github.com/spring-projects/spring-integration/issues/8550

Turns out the Paho MQTT client does not re-subscribe when connection
re-established on automatic reconnection

* Fix `AbstractMqttMessageDrivenChannelAdapter` to always subscribe to their topics
in the `connectComplete()` independently of the `reconnect` status
* Verify behavior with `MOSQUITTO_CONTAINER` image restart in Docker
2023-02-15 17:26:12 -05:00
abilan
3d245276e4 Fix new Sonar smells 2023-02-14 17:02:23 -05:00
abilan
4cd1085f94 Upgrade some dependencies
* Remove already redundant `parentObservation` population in the `AbstractMessageChannel`:
now it is handled properly by the `SimpleObservation` ctor
2023-02-14 15:01:42 -05:00
Gary Russell
e8a9f95ca1 GH-4013: TCP DSL Improvements
Resolves https://github.com/spring-projects/spring-integration/issues/4013

Add Net/NIO specific Server/Client connection factory specs.

* Shorten DSL method names, as suggested.
2023-02-08 17:01:44 -05:00
Ivan Zaitsev
e6d0a4f826 GH-4008: ZK: Add leader and participants support
Fixes https://github.com/spring-projects/spring-integration/issues/4008

Impossible to retrieve current leader id from ZK `LeaderInitiator`

* change return type of `LeaderInitiator.getContext()` from `Context` to `CuratorContext`
* add `getLeader()` method to `CuratorContext`
* add `getParticipants()` method to `CuratorContext`
2023-02-07 10:36:29 -05:00
Artem Bilan
6a2ff0cd99 GH-4001: Doc for cooperation with some HZ objects (#4003)
* GH-4001: Doc for cooperation with some HZ objects

Fixes https://github.com/spring-projects/spring-integration/issues/4001

The `IQueue`, `ITopic` and `IExecutorService` can be used with Spring Integration
channel as is without any extra component implementations.

* Document the cooperation feature with Hazelcast objects via samples

* * Add a sample about an Inbound Channel Adapter on the `IQueue`

* Fix language in docs

Co-authored-by: Gary Russell <grussell@vmware.com>

---------

Co-authored-by: Gary Russell <grussell@vmware.com>
2023-02-06 12:20:42 -05:00
Artem Bilan
44000b9606 GH-4002: Deprecate ConsumerStopAction in MQTT (#4006)
Fixes https://github.com/spring-projects/spring-integration/issues/4002

Turns out the `ConsumerStopAction` was introduced in a point version to mitigate an unsubscription bug
and let to preserve a previous behaviour.

* Deprecate `ConsumerStopAction` in favor of just `cleanSession` flag in the `MqttConnectOptions`

**Cherry-pick to `5.5.x`**
2023-02-06 11:58:41 -05:00
Artem Bilan
d9d7c49aac Propagate and Observation from Reactive context (#3999)
To propagate an `Observation` from reactive stream (e.g. WebFlux)
we have to capture its context and set it into the current thread scope.

* Add a `io.micrometer:context-propagation` dependency to support reactive context propagation
* Populate a `parentObservation` in the `IntegrationObservation.PRODUCER.observation()`
since it is not available for tracing on `Observation.onStart()`.
Might be tentative until upcoming fix in Micrometer Observation
* Populate from reactive context in the `WebFluxInboundEndpoint` where we use just `send()` operation downstream
* Populate from reactive context in the `MessagingGatewaySupport` where we use `send()` operation downstream or `FluxMessageChannel.subscribeTo()`
* Use `contextCapture()` in the `FluxMessageChannel` to gather a `ThreadLocal` info into a Reactor context
and then set back to `ThreadLocal` in the `transformDeferredContextual()` which really happens on a different thread
* Verify a trace propagation from WebFlux to an integration flow via Brave instrumentation in the `WebFluxObservationPropagationTests`
2023-02-01 14:13:40 -05:00
Artem Bilan
841289002c GH-3998: Fix gateway docs for @Payload (#4000)
* GH-3998: Fix gateway docs for `@Payload`

Fixes https://github.com/spring-projects/spring-integration/issues/3998

The `GatewayProxyFactoryBean` now deals only with a `MethodArgsHolder` as a root evaluation context object.
There is no `#args` and `#method` SpEL variables anymore.
However, the `gateway.adoc` still refer to those.

* Fix `gateway.adoc` for a proper expressions and actual wording

* * Cross link to `gateway-expressions` paragraph for better context
2023-02-01 14:05:20 -05:00
Artem Bilan
f01e2b8553 GH-3994: Register native hints for Graph model (#3996)
Fixes https://github.com/spring-projects/spring-integration/issues/3994

Essentially, migrate those hints from Spring Boot Actuator:
an `IntegrationGraphServer` can be used without Spring Boot

* Introduce `IntegrationGraphRuntimeHints` - implementation of `RuntimeHintsRegistrar`
to register reflection hints for `Graph` and top-level `IntegrationNode` types.
* Use `@ImportRuntimeHints` on the `IntegrationGraphServer` to make those hints
conditional.
2023-01-23 14:22:42 -05:00
Artem Bilan
ebba37497f GH-3993: Fix async race condition in TcpOutGateway (#3995)
* GH-3993: Fix async race condition in TcpOutGateway

Fixes https://github.com/spring-projects/spring-integration/issues/3993

When `TcpOutboundGateway` is in an `async` mode and `CCF` is configured
not for `singleUse` an `Semaphore` around an obtained `TcpConnection` is involved.
If we fail on `TcpConnection.send()`, resources are not clean up, including the
mentioned `Semaphore`: in async mode this happens only when we receive a reply.

* Catch an exception on the `TcpConnection.send()` and perform `cleanUp()` in async mode.
* Add `cleanUp()` into a scheduled task from the `TcpOutboundGateway.AsyncReply`
when no reply arrives in time.
* Optimize `TcpOutboundGateway.AsyncReply` behavior to cancel no-reply scheduled task
when reply arrives into a `CompletableFuture`

**Cherry-pick to `5.5.x`**

* * Call `cleanUp()` from no response scheduled task
only if `future.completeExceptionally()` is `true`
2023-01-23 11:07:19 -05:00
Spring Builds
f8c0779964 [artifactory-release] Next development version 2023-01-18 18:20:29 +00:00
Spring Builds
480a9735bf [artifactory-release] Release version 6.0.2 2023-01-18 18:20:26 +00:00