Commit Graph

11332 Commits

Author SHA1 Message Date
Gary Russell
fa298f8ec2 Increase Timeouts in FTP RotatingServersTests
Some unknown delays on MacOS cause the tests to fail.
2023-11-14 09:54:37 +01:00
Artem Bilan
605fb2d788 GH-8786: Make FtpSession.finalizeRaw() robust
Fixes https://github.com/spring-projects/spring-integration/issues/8786

If `FtpSession.readRaw()` fails, the next `FtpSession.finalizeRaw()` call
would lead to `FTPClient.completePendingCommand()` failure since
there is no command to finish.

* Fix `FtpSession.finalizeRaw()` to exit earlier positively in case of
`FTPReply.isNegativePermanent()` for the current reply code set by the failure
from a previous `FtpSession.readRaw()`

**Cherry-pick to `6.1.x`, `6.0.x` & `5.5.x`**
2023-11-14 09:31:17 +01:00
Artem Bilan
66362915c6 GH-8785: Propagate WebSocket client connect fail
Fixes https://github.com/spring-projects/spring-integration/issues/8785

The `ClientWebSocketContainer.start()` delegates to the `IntegrationWebSocketConnectionManager`
which performs an async connection to the server.

* Wait for `connectionLatch` in the `ClientWebSocketContainer.start()`
and check for `this.openConnectionException != null` to re-throw.
Mark `ClientWebSocketContainer` as stopped in that case

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

# Conflicts:
#	spring-integration-websocket/src/main/java/org/springframework/integration/websocket/ClientWebSocketContainer.java
2023-11-09 10:31:07 -05:00
Artem Bilan
e5939f093b GH-8778: Fix KafkaMessageSource deadlock (#8780)
* GH-8778: Fix KafkaMessageSource deadlock

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

The `KafkaMessageSource.doReceive()` have a lock around its whole body.
That includes the `pollRecord()` which can be blocked on the `KafkaConsumer.poll()`.
This way the rest of lifecycle management callbacks can be blocked until `KafkaConsumer.poll()` returns.

* Rework lifecycle management flags to `AtomicBoolean` since there is not too much work
in their respective callbacks
* Decrease a locking block in the `doReceive()` just to consumer setup part.
Leave `pollRecord()` outside of the lock
* Add `this.consumer.wakeup()` into `stopConsumer()` to break a `poll()` cycle
and return immediately for the next `close()` call

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

* * Use `compareAndSet` in `start` & `stop`
2023-10-26 15:34:21 -04:00
Artem Bilan
3af38a6bac GH-8779: MongoDbMS Fix distinct result conversion (#8781)
Fixes https://github.com/spring-projects/spring-integration/issues/8779

The `MongoTemplate` has now a `findDistinct()` API with a smart
result conversion instead of native driver plain expectations

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-10-26 15:29:56 -04:00
Artem Bilan
c7b5453212 KafkaMessageSource: Lock instead of synchronized
Related to https://github.com/spring-projects/spring-integration/issues/8778

**Cherry-pick to `6.0.x`**
2023-10-26 13:29:17 -04:00
Artem Bilan
938b27055b GH-8770: Add PostgresSubsChannel.errorHandler (#8777)
* GH-8770: Add `PostgresSubsChannel.errorHandler`

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

The problem with the `PostgresSubscribableChannel.notifyUpdate()` is that the try-catch block is outside the loop,
so the loop will die on an exception, leaving further messages unprocessed.

* Add ``PostgresSubscribableChannel.errorHandler` option to be invoked
after a `RetryTemplate` and for every failed message.
* The `askForMessage()` new logic is to catch an exception on a message and call `errorHandler`
returning a `FALLBACK_STUB` to continue an outer loop in the `notifyUpdate()`

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

* * Rename private `PostgresSubscribableChannel.askForMessage()` method to more specific `pollAndDispatchMessage()`
2023-10-25 13:29:22 -04:00
Artem Bilan
012a03ff77 Fix PostgresSubscribableChannel race condition
The `PostgresSubscribableChannel` uses a task executor
for dispatching messages.
Even if we stop `PostgresChannelMessageTableSubscriber` and
unsubscribe from the channel, the task might be ongoing.

* Use explicit `ThreadPoolTaskExecutor` in the test
to shout it down and wait for tasks to be completed before
verifying DB status
* Optimize `PostgresSubscribableChannel` to mark TX for rollback
when we got a message from DB, but no handlers subscribed

# Conflicts:
#	spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/channel/PostgresChannelMessageTableSubscriberTests.java
2023-10-25 10:11:23 -04:00
Spring Builds
1aac947aad [artifactory-release] Next development version 2023-10-17 14:09:43 +00:00
Spring Builds
72fb0c4d44 [artifactory-release] Release version 6.0.8 2023-10-17 14:09:36 +00:00
Artem Bilan
59a88c2d67 Update dependencies; prepare for release
* Adapt AMQP module for the latest Spring AMQP changes
2023-10-16 15:27:14 -04:00
Christian Tzolov
45bbaf90d0 Streamline UUIDConverter
* Use `StandardCharsets.UTF_8` as a charset configuration instead of string.
   Later remove the necessity of handling encoder errors.
* Use regular expressions to validate the `UUID` string standard representation.
   Later obsolete the need for try/catch exceptions.
* Deprecate `UUIDConverter.DEFAULT_CHARSET` since it is out of use.

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

Code clean up for `UUIDConverter`
2023-10-16 14:15:16 -04:00
Johannes Edmeier
52952a4347 Reduce log noise for AbstractCorrelatingMH
We use an aggregate handler that uses a group timeout.
It's expected that this timeout will be hit frequently.
However, this causes a info log message emitted every time.
I'd propose to log this message on debug.

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

(cherry picked from commit f89ca99bde)
2023-10-16 11:06:22 -04:00
Artem Bilan
7d73e52b43 GH-8745: Add RFT.shouldMarkSessionAsDirty() (#8759)
* GH-8745: Add RFT.shouldMarkSessionAsDirty()

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

Not all errors caught in the `RemoteFileTemplate.execute()`
are fatal to mark session as dirty and physically close the target session
in the cache

* Introduce a `RemoteFileTemplate.shouldMarkSessionAsDirty()`
to consult with an exception if it is really a fatal error to close
the session in the end.
* Override `shouldMarkSessionAsDirty()` in the `RemoteFileTemplate`
implementations to check statuses of respective protocol errors

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

* * Fix tests for pool interaction

* * Fix language in Javadocs
* Add more `not dirty` statuses to `SftpRemoteFileTemplate` & `SmbRemoteFileTemplate`
2023-10-11 11:01:05 -04:00
Artem Bilan
31de789900 IntFlowContext: Fix missed import for @Nullable 2023-10-10 14:01:02 -04:00
Falk Hanisch
680acfbb97 GH-8750: Add @Nullable to getRegistrationById()
Fixes https://github.com/spring-projects/spring-integration/issues/8750

* annotate `IntegrationFlowRegistration.getRegistrationById(String flowId)` with `@org.springframework.lang.Nullable`
* annotate `StandardIntegrationFlowContext.getRegistrationById(String flowId)` with `@org.springframework.lang.Nullable`

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

(cherry picked from commit 49cd14cb8a)
2023-10-10 13:47:50 -04:00
Falk Hanisch
f64cda7e20 GH-8754: MessageBuilder: enhance @Nullable
Fixes spring-projects/spring-integration#8754

* `AbstractIntegrationMessageBuilder.setExpirationDate(@Nullable Long expirationDate)`
* `MessageBuilder.setExpirationDate(@Nullable Long expirationDate)`
* `MessageBuilder.setExpirationDate(@Nullable Date expirationDate)`

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

(cherry picked from commit 75fcddac00)
2023-10-10 12:29:33 -04:00
Artem Bilan
96bea492f0 GH-8748: JDBC locks: use READ_COMMITTED isolation (#8749)
Fixes https://github.com/spring-projects/spring-integration/issues/8748

The Oracle DB throws `ORA-08177: can't serialize access for this transaction`
when other transaction on the row has begun

* Change the isolation for `DefaultLockRepository.acquire()` transaction
to the `READ_COMMITTED` for what database automatically and silently
restarts the entire SQL statement, and no error occurs.
* Add `oracle` dependencies to JDBC module
* Introduce `OracleContainerTest` and implement it for `OracleLockRegistryTests`

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-10-09 11:54:00 -04:00
Artem Bilan
5489b1541c Fix maxMessagesPerPoll for SourcePollingChAdapter (#8747)
* Fix maxMessagesPerPoll for SourcePollingChAdapter

The `AbstractMethodAnnotationPostProcessor` does not check
for `PollerMetadata.MAX_MESSAGES_UNBOUNDED` before setting
`maxMessagesPerPoll` into a `SourcePollingChannelAdapter`
which in this case must be `1`

Also fix `SourcePollingChannelAdapterFactoryBean` to not mutate
the provided `PollerMetadata` (which might be global default)
with a new `maxMessagesPerPoll`

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

* * Fix `this.` prefix in `SourcePollingChannelAdapterFactoryBean`
2023-10-04 11:50:34 -04:00
Artem Bilan
18aff7835d Fix JMS Inbound Endpoints for observation
The `JmsMessageDrivenEndpoint` delegates all the hard work to the
`ChannelPublishingJmsMessageListener`, but missed to propagate an `ObservationRegistry`
and other related options.
The `JmsInboundGateway` is worse: it delegated to the `JmsMessageDrivenEndpoint`

* Add `IntegrationObservation.HANDLER` observation to the `MessagingGatewaySupport.send()`
operation: used by the delegate in the `ChannelPublishingJmsMessageListener`
* Expose and propagate observation-related options from `JmsInboundGateway`
and `JmsMessageDrivenEndpoint`
* Expose `observationConvention()` option on the `MessagingGatewaySpec`
and `MessageProducerSpec`
* Remove unused imports
* Do not start a new `RECEIVER` observation if there is already `SERVER` one
* Fix `MessagingGatewaySupport` for `Observation.NOOP` check.
The parent process may still use `ObservationRegistry.NOOP` which sets
`Observation.NOOP` instance into the current context and thread local.
* fix merge conflicts

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-09-19 18:49:27 +02:00
Artem Bilan
0b7c769bdb Fix ThreadSPropagationChInterceptor for stacking (#8735)
* Fix ThreadSPropagationChInterceptor for stacking

Related SO thread: https://stackoverflow.com/questions/77058188/multiple-threadstatepropagationchannelinterceptors-not-possible

The current `ThreadStatePropagationChannelInterceptor` logic is to wrap one
message to another (`MessageWithThreadState`), essentially stacking contexts.
The `postReceive()` logic is to unwrap a `MessageWithThreadState`,
therefore we deal with the latest pushed context which leads to the `ClassCastException`

* Rework `ThreadStatePropagationChannelInterceptor` logic to reuse existing `MessageWithThreadState`
and add the current context to its `stateQueue`.
Therefore, the `postReceive()` will `poll()` the oldest context which is, essentially,
the one populated by this interceptor before, according to the interceptors order
* Fix `AbstractMessageChannel.setInterceptors()` to not modify provided list of interceptors
* The new `ThreadStatePropagationChannelInterceptorTests` demonstrates the problem
described in that mentioned SO question and verifies that context are propagated
in the order they have been populated

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

* * Fix `ThreadStatePropagationChannelInterceptor` for publish-subscribe scenario.
Essentially, copy the state queue to a new decorated message
* Fix `BroadcastingDispatcher` to always decorate message, even if not `applySequence`

* * Fix unused import in the `BroadcastingDispatcher`

* * Fix unused import in the `ThreadStatePropagationChannelInterceptor`
2023-09-18 12:39:14 -04:00
Myeonghyeon-Lee
e2ccd10549 Fix Checkstyle violation in the JdbcLockRegistry
**Cherry-pick to `6.1.x` & `6.0.x`**

(cherry picked from commit 0f1304494f)
2023-09-18 11:00:12 -04:00
Myeonghyeon-Lee
e8cf812b31 GH-8730: Fix isAcquiredInThisProcess to use localLock
The `ExpirableLockRegistry.expireUnusedOlderThan()` uses a query to the target store by mistake.
The logic of this API is indeed about the local cache for those lock instances.
We cannot effect any other processes with this cache.
And even if we remove our local instance while it is locked in other process,
that doesn't mean that on the next `obtain()` call, when we got a fresh local instance, we will be able to acquire a lock in target store.

* Fix `isAcquiredInThisProcess()` to check only `localLock.isLocked()`

**Cherry-pick to `6.1.x` & `6.0.x`**
# Conflicts:
#	spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/JdbcLockRegistry.java
2023-09-18 10:42:22 -04:00
Artem Bilan
d8a4765362 Fix PostgresSubscribableChannel.notifyUpdate()
When transaction is configured for the `PostgresSubscribableChannel.notifyUpdate()`
and it is rolled back, the next poll in that loop will return the same message.
Again and again if transaction is always rolled back.
This leads to the condition when we never leave this loop even if
we fully unsubscribed from this channel.

The issue has need spotted after introducing `SKIP LOCKED`
for `PostgresChannelMessageStoreQueryProvider` which leads to
the locked record in DB in the mentioned above transaction.

* Introduce `PostgresSubscribableChannel.hasHandlers` flag
to check in the `notifyUpdate()` before performing poll query in DB.

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-09-18 14:36:29 +02:00
Artem Bilan
2a22bf8090 GH-8720: Check MQTT topics if not empty strings
Fixes https://github.com/spring-projects/spring-integration/issues/8720

Validate MQTT topics for empty strings in the channel adapters configuration

Use plural names for varargs params

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-09-13 17:06:55 +02:00
Adama Sorho
26fae85fa1 GH-8692 Add createIndexes to MongoDbMessageStore
Fixes https://github.com/spring-projects/spring-integration/issues/8692

* Added `createIndexes` in `AbstractConfigurableMongoDbMessageStore`
* Added Javadoc for `setCreateIndex()` method
* Removed `afterPropertiesSet()` in `MongoDbChannelMessageStore` and update `whats-new.adoc` and `mongodb.adoc` files

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

# Conflicts:
#	src/reference/antora/modules/ROOT/pages/whats-new.adoc
#	src/reference/asciidoc/mongodb.adoc
2023-08-30 11:58:05 -04:00
Spring Builds
bdfbf7b03d [artifactory-release] Next development version 2023-08-22 19:23:26 +00:00
Spring Builds
1a20199f35 [artifactory-release] Release version 6.0.7 2023-08-22 19:23:23 +00:00
Artem Bilan
91060d4501 Fix SF version to 6.0.11 2023-08-22 11:36:16 -07:00
Artem Bilan
21f53bcd03 Upgrade Spring deps; prepare for release 2023-08-22 11:30:08 -07:00
Artem Bilan
698a7c36b5 GH-8708: Fix concurrency around SFTP client (#8709)
Fixes https://github.com/spring-projects/spring-integration/issues/8708

According to the `org.apache.sshd.common.channel.ChannelAsyncOutputStream.writeBuffer()` JavaDocs cannot be used concurrently.

* Introduce internal `DefaultSftpSessionFactory.ConcurrentSftpClient` extension
of the `DefaultSftpClient` to set a `Lock` around `super.send(cmd, buffer);`
* Remove lock from the `SftpSession` since it now is managed by the mentioned `ConcurrentSftpClient`

**Cherry-pick to `6.1.x` & `6.0.x`**
# Conflicts:
#	spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java
2023-08-22 11:21:23 -07:00
Eddie Cho
d1f18b1d8c GH-8699: Fix Issue of removeLockKey()
In the current code, an `IllegalStateException` might be thrown from the try block while invoking the `removeLockKeyInnerUnlink()` method, especially when caused by key expiration (resulting in `unlinkResult == false`).

This triggers the check block, which incorrectly sets the `unlinkAvailable` flag to `false`, even if the Redis server supports the unlink operation.

As a consequence, the subsequent `removeLockKeyInnerDelete()` method is invoked when it should not be.

* `IllegalStateException` should not be thrown from try block
* Add a comment and fix Checkstyle violations

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

(cherry picked from commit ba6d35d123)
2023-08-15 13:48:55 -04:00
EddieChoCho
2e627075ab GH-8699: Atomic Redis script for unlock()
Expected Behavior

Using a single Lua script to verify ownership of the lock and remove it.

Current Behavior

`unlock()` method of `RedisLock` uses two separate Redis operations:

    * `isAcquiredInThisProcess()`` method executes a `GET` operation to verify if the lock is owned by the process.
    * `removeLockKey()`` method executes `UNLINK/DEL` operation to remove the lock.

* The `removeLockKeyInnerUnlink()`, and `removeLockKeyInnerDelete()`
methods will execute a script both verify ownership of the lock and remove it.

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

# Conflicts:
#	spring-integration-redis/src/main/java/org/springframework/integration/redis/util/RedisLockRegistry.java
2023-08-14 10:53:17 -04:00
Artem Bilan
b81ab75994 GH-8697: No autowire for Int ConversionService
Fixes https://github.com/spring-projects/spring-integration/issues/8697

The `IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME` is not designed
for end-user code autowire, rather internal framework requirement

* Mark `BeanDefinition` for `IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME`
as `setAutowireCandidate(false)`

(cherry picked from commit f9dc75c739)
2023-08-11 10:27:34 -04:00
abilan
a7c05edfd9 Fix AbstrMongoDbMesGrStoreTests according to main 2023-07-24 11:10:33 -04:00
Artem Bilan
638276ff23 GH-8685: Re-fetch group after setting condition (#8686)
* GH-8685: Re-fetch group after setting condition

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

The `AbstractCorrelatingMessageHandler` updates the group metadata in DB
not only for provided `condition`, but also a `lastModified` field.
A subsequent scheduling for group timeout takes the `lastModified`
to compare with the value in the store after re-fetching group in task.
This does not reflect reality since adding `condition` modifies the data in DB,
but in-memory state remains the same.

* Re-fetch a group from the store in the `AbstractCorrelatingMessageHandler.setGroupConditionIfAny()`.
* Verify expected behavior via new `ConfigurableMongoDbMessageGroupStoreTests.groupIsForceReleaseAfterTimeoutWhenGroupConditionIsSet()`

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

* * Fix Checkstyle violation in the test
2023-07-24 09:12:01 -04:00
Julian Koch
e73894bf74 Fix ClientWebSocketContainerTests for current API
**Cherry-pick to `5.5.x`**
2023-07-18 11:15:13 -04:00
Julian Koch
7dee98ba6e GH-8678: Add BufferOverflowStrategy for WebScoket
Within Spring Integration's WebSocket support, a `ConcurrentWebSocketSessionDecorator`,
which buffers outbound messages if sending is slow,
is used to decorate all websocket sessions in `IntegrationWebSocketContainer`,
the standard entrypoint for using websockets with Integration.

* Expose a `ConcurrentWebSocketSessionDecorator.OverflowStrategy` option on the `IntegrationWebSocketContainer`

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

(cherry picked from commit be53593af9)
2023-07-18 11:07:38 -04:00
Artem Bilan
c267bd53fd GH-8674: Fix ServerKeyVerifier impl for key type (#8675)
Fixes https://github.com/spring-projects/spring-integration/issues/8674

The `ResourceKnownHostsServerKeyVerifier` does not take into account that several different
keys can be present in the known hosts resource for the same host/port

* Fix `ResourceKnownHostsServerKeyVerifier` to find a list of knows host for the requested session.
Then iterate of this result to match the key type first and then compare keys and their `revoked` marker

**Cherry-pick to `6.1.x` & `6.0.x`**
2023-07-17 14:28:42 -04:00
abilan
0d60c39510 Fix section separation in the amqp.adoc 2023-07-13 09:59:38 -04:00
Gary Russell
1ec3fd2903 GH-8668: AMQP Docs for Exclusive and S-A Consumers
Resolves https://github.com/spring-projects/spring-integration/issues/8668

**cherry-pick to all supported branches**

(cherry picked from commit fc3c8d2c8d)

# Conflicts:
#	src/reference/asciidoc/amqp.adoc
2023-07-12 16:53:24 -04:00
pziobron
bb57f08f50 GH-8659: Fix WatchService to react for renames
Fixes https://github.com/spring-projects/spring-integration/issues/8659

* GH-8659: Updating the documentation as requested

* GH-8659: Fixes requested after coder review

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

(cherry picked from commit 0798c8df95)

# Conflicts:
#	spring-integration-file/src/main/java/org/springframework/integration/file/FileReadingMessageSource.java
2023-06-29 14:26:56 -04:00
Artem Bilan
6228eaa7df Fix Kotlin DSL delegation (#8658)
The `ConsumerEndpointSpec` extensions for Kotlin
don't delegate to the provided `endpointFactoryBean`

* Introduce `KotlinConsumerEndpointSpec` extension for `ConsumerEndpointSpec`
with the proper delegation to the provided spec
* Use `KotlinConsumerEndpointSpec` in the Kotlin-specific `Spec` classes

**Cherry-pick to `6.1.x`, `6.0.x` & `5.5.x`**
2023-06-26 15:12:07 -04:00
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