GH-2788: Add MongoDbChangeStreamMessageProducer

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

* Introduce a `MessageProducerSupport.subscribeToPublisher(Publisher<Message<?>>)`
for components which produces `Flux` for data from their source
* Such a component is auto-stopped when subscription to that `Publisher` is canceled
* Implement a `MongoDbChangeStreamMessageProducer` based on the reactive support for
in Spring Data MongoDb
* Implement a Java DSL for `MongoDbChangeStreamMessageProducer`
* Disable a test for change stream since it requires server of version 4.x started with 'replSet' option
* Add `MongoHeaders` for change stream events

* Change `MessageProducerSupport` to use a `takeWhile((message) -> isRunning())`
instead of storing a `subscription` from a callback
* Document new features

* Remove trailing whitespaces

* Doc Polishing.
This commit is contained in:
Artem Bilan
2020-04-02 21:32:08 -04:00
committed by Gary Russell
parent 2d7e47355b
commit d8c378bd28
11 changed files with 745 additions and 16 deletions

View File

@@ -348,6 +348,37 @@ If the result of an expression is null or void, no message is generated.
For more information about transaction synchronization, see <<./transactions.adoc#transaction-synchronization,Transaction Synchronization>>.
[[mongodb-change-stream-channel-adapter]]
=== MongoDB Change Stream Inbound Channel Adapter
Starting with version 5.3, the `spring-integration-mongodb` module introduces the `MongoDbChangeStreamMessageProducer` - a reactive `MessageProducerSupport` implementation for the Spring Data `ReactiveMongoOperations.changeStream(String, ChangeStreamOptions, Class)` API.
This component produces a `Flux` of messages with a `body` of `ChangeStreamEvent` as the payload by default and some change stream related headers (see `MongoHeaders`).
It is recommended that this `MongoDbChangeStreamMessageProducer` is combined with a `FluxMessageChannel` as the `outputChannel` for on-demand subscription and event consumption downstream.
The Java DSL configuration for this channel adapter may look like this:
====
[source,java]
----
@Bean
IntegrationFlow changeStreamFlow(ReactiveMongoOperations mongoTemplate) {
return IntegrationFlows.from(
MongoDb.changeStreamInboundChannelAdapter(mongoTemplate)
.domainType(Person.class)
.collection("person")
.extractBody(false))
.channel(MessageChannels.flux())
.get();
}
----
====
When the `MongoDbChangeStreamMessageProducer` is stopped, or the subscription is cancelled downstream, or the MongoDb change stream produces an `OperationType.INVALIDATE`, the `Publisher` is completed.
The channel adapter can be started again and a new `Publisher` of source data is created and it is automatically subscribed in the `MessageProducerSupport.subscribeToPublisher(Publisher<? extends Message<?>>)`.
This channel adapter can be reconfigured for new options between starts, if there is a requirement to consume change stream events from other places.
See more information about change stream support in Spring Data MongoDb https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#change-streams[documentation].
[[mongodb-outbound-channel-adapter]]
=== MongoDB Outbound Channel Adapter

View File

@@ -77,6 +77,18 @@ This way, any `MessageSource` implementation can be turned into a reactive hot s
See <<./polling-consumer.adoc#polling-consumer,Polling Consumer>> for more information.
=== Event-Driven Channel Adapter
`MessageProducerSupport` is the base class for event-driven channel adapters and, typically, its `sendMessage(Message<?>)` is used as a listener callback in the producing driver API.
This callback can also be easily plugged into the `doOnNext()` Reactor operator when a message producer implementation builds a `Flux` of messages instead of listener-based functionality.
In fact, this is done in the framework when an `outputChannel` of the message producer is not a `ReactiveStreamsSubscribableChannel`.
However, for improved end-user experience, and to allow more back-pressure ready functionality, the `MessageProducerSupport` provides a `subscribeToPublisher(Publisher<? extends Message<?>>)` API to be used in the target implementation when a `Publisher<Message<?>>>` is the source of data from the target system.
Typically, it is used from the `doStart()` implementation when target driver API is called for a `Publisher` of source data.
It is recommended to combine a reactive `MessageProducerSupport` implementation with a `FluxMessageChannel` as the `outputChannel` for on-demand subscription and event consumption downstream.
The channel adapter goes to a stopped state when a subscription to the `Publisher` is cancelled.
Calling `stop()` on such a channel adapter completes the producing from the source `Publisher`.
The channel adapter can be restarted with automatic subscription to a newly created source `Publisher`.
=== Splitter and Aggregator
When an `AbstractMessageSplitter` gets a `Publisher` for its logic, the process goes naturally over the items in the `Publisher` to map them into messages for sending to the `outputChannel`.

View File

@@ -55,8 +55,9 @@ See <<./handler-advice.adoc#handle-message-advice,Handling Message Advice>> for
[[x5.3-mongodb-reactive-channel-adapters]]
==== MongoDB Reactive Channel Adapters
`spring-integration-mongodb` module now provides channel adapter implementations for Reactive MongoDB driver support in Spring Data.
See <<./mongodb.adoc#mongodb-reactive-channel-adapters,MongoDB Reactive Channel Adapters>> for more information.
The `spring-integration-mongodb` module now provides channel adapter implementations for the Reactive MongoDb driver support in Spring Data.
Also, a reactive implementation for MongoDb change stream support is present with the `MongoDbChangeStreamMessageProducer`.
See <<./mongodb.adoc#mongodb,MongoDB Support>> for more information.
[[x5.3-general]]
=== General Changes
@@ -84,6 +85,9 @@ See <<./dsl.adoc#java-dsl-intercept,Operator intercept()>> for more information.
The `MessageStoreSelector` has a new mechanism to compare an old and new value.
See <<./handler-advice.adoc#idempotent-receiver,Idempotent Receiver Enterprise Integration Pattern>> for more information.
The `MessageProducerSupport` base class now has a `subscribeToPublisher(Publisher<? extends Message<?>>)` API to allow implementation of message-driven producer endpoints which emit messages via reactive `Publisher`.
See <<./reactive-streams.adoc#reactive-streams,Reactive Streams Support>> for more information.
[[x5.3-amqp]]
=== AMQP Changes