Introduce a MessageGroup.condition (#3517)
* Introduce a `groupConditionSupplier` for MGS * Add a `MessageGroup.condition` option * Add a `MessageGroupStore.conditionSupplier` option * Use it from the `SimpleMessageStore.addMessagesToGroup()` API to populate `condition` (if any) into a `MessageGroup` * Introduce a `GroupConditionProvider` contract to be implemented on those `ReleaseStrategy` contracts which could be aware of group condition * Populated a `GroupConditionProvider.getGroupConditionSupplier()` into a `MessageGroupStore` from the `AbstractCorrelatingMessageHandler` for end-user convenience * Rework a `FileMarkerReleaseStrategy` to implement a `GroupConditionProvider` to provide a function which produces a condition from `file_lineCount` header of the `END` marker message * Make the `FileMarkerReleaseStrategy` logic already based on the condition from a group * Delegate `GroupConditionProvider` from the `FileAggregator` * Add test for empty file aggregation * * Implement `condition` in the `AbstractKeyValueMessageStore` and `MongoDbMessageStore` * Test `condition` for `mongo-aggregator-config.xml` and `FileAggregatorTests` against GemFire * * Implement `condition` in the `ConfigurableMongoDbMessageStore` * * Implement `condition` in the `JdbcMessageStore` * `FileAggregatorTests` against `JdbcMessageStore` * Refactor `JdbcMessageStore` for better handling of message group metadata * Remove unused `MARKED` column in the DDL in favor of newly introduced `CONDITION` * * Add docs for message group condition * * Move `conditionSupplier` option from MGS to AbstractCorrelatingMH * Make it as a `BiFunction` to propagate existing condition alongside with the message to consult * Expose `groupConditionSupplier` in Java & XML DSLs * * Fix language in docs
This commit is contained in:
@@ -970,4 +970,12 @@ Flux<Message<?>> window =
|
||||
----
|
||||
====
|
||||
|
||||
[[agg-message-group-condition]]
|
||||
==== Condition on the Message Group
|
||||
|
||||
Starting with version 5.5, an `AbstractCorrelatingMessageHandler` (including its Java & XML DSLs) exposes a `groupConditionSupplier` option of the `BiFunction<Message<?>, String, String>` implementation.
|
||||
This function is used on each message added to the group and a result condition sentence is stored into the group for future consideration.
|
||||
The `ReleaseStrategy` may consult this condition instead of iterating over all the messages in the group.
|
||||
See `GroupConditionProvider` JavaDocs and <<./message-store.adoc#message-group-condition, Message Group Condition>> for more information.
|
||||
|
||||
See also <<./file.adoc#file-aggregator, File Aggregator>>.
|
||||
@@ -1192,6 +1192,8 @@ When markers are enabled on the `FileSplitter`, it does not populate sequence de
|
||||
The `FileHeaders.FILENAME` is still populated for each line emitted, including START/END marker messages.
|
||||
|
||||
- The `FileMarkerReleaseStrategy` - checks for `FileSplitter.FileMarker.Mark.END` message in the group and then compare a `FileHeaders.LINE_COUNT` header value with the group size minus `2` - `FileSplitter.FileMarker` instances.
|
||||
It also implements a convenient `GroupConditionProvider` contact for `conditionSupplier` function to be used in the `AbstractCorrelatingMessageHandler`.
|
||||
See <<./message-store.adoc#message-group-condition, Message Group Condition>> for more information.
|
||||
|
||||
- The `FileAggregatingMessageGroupProcessor` just removes `FileSplitter.FileMarker` messages from the group and collect the rest of messages into a list payload to produce.
|
||||
|
||||
|
||||
@@ -147,4 +147,22 @@ However starting with version 5.5, all the persistent `MessageGroupStore` implem
|
||||
This improves resources utilization when groups are very big in the store.
|
||||
Internally in the framework this new API is used in the <<./delayer.adoc#delayer,Delayer>> (for example) when it reschedules persisted messages on startup.
|
||||
A returned `Stream<Message<?>>` must be closed in the end of processing, e.g. via auto-close by the `try-with-resources`.
|
||||
Whenever a `PersistentMessageGroup` is used, its `streamMessages()` delegates to the `MessageGroupStore.streamMessagesForGroup()`.
|
||||
Whenever a `PersistentMessageGroup` is used, its `streamMessages()` delegates to the `MessageGroupStore.streamMessagesForGroup()`.
|
||||
|
||||
[[message-group-condition]]
|
||||
==== Message Group Condition
|
||||
|
||||
Starting with version 5.5, the `MessageGroup` abstraction provides a `condition` string option.
|
||||
The value of this option can be anything that could be parsed later on for any reason to make a decision for the group.
|
||||
For example a `ReleaseStrategy` from a <<./aggregator.adoc#aggregator-api, correlation message handler>> may consult this property from the group instead of iterating all the messages in the group.
|
||||
The `MessageGroupStore` exposes a `setGroupCondition(Object groupId, String condition)` API.
|
||||
For this purpose a `setGroupConditionSupplier(BiFunction<Message<?>, String, String>)` option has been added to the `AbstractCorrelatingMessageHandler`.
|
||||
This function is evaluated against each message after it has been added to the group as well as the existing condition of the group.
|
||||
The implementation may decide to return a new value, the existing value, or reset the target condition to `null`.
|
||||
The value for a `condition` can be a JSON, SpEL expression, number or anything what can be serialized as a string and parsed afterwards.
|
||||
For example, the `FileMarkerReleaseStrategy` from the <<./file.adoc#file-aggregator, File Aggregator>> component, populates a condition into a group from the `FileHeaders.LINE_COUNT` header of the `FileSplitter.FileMarker.Mark.END` message and consults with it from its `canRelease()` comparing a group size with the value in this condition.
|
||||
This way it doesn't iterate all the messages in group to find a `FileSplitter.FileMarker.Mark.END` message with the `FileHeaders.LINE_COUNT` header.
|
||||
It also allows the end marker to arrive at the aggregator before all the other records; for example when processing a file in a multi-threaded environment.
|
||||
|
||||
In addition, for configuration convenience, a `GroupConditionProvider` contract has been introduced.
|
||||
The `AbstractCorrelatingMessageHandler` checks if the provided `ReleaseStrategy` implements this interface and extracts a `conditionSupplier` for group condition evaluation logic.
|
||||
|
||||
@@ -41,8 +41,12 @@ This is covered as a `ConsumerEndpointSpec.reactive()` option in Java DSL and as
|
||||
See <<./reactive-streams.adoc#reactive-streams,Reactive Streams Support>> for more information.
|
||||
|
||||
The `groupTimeoutExpression` for a correlation message handler (an `Aggregator` and `Resequencer`) can now be evaluated to a `java.util.Date` for some fine-grained scheduling use-cases.
|
||||
Also the `BiFunction groupConditionSupplier` option is added to the `AbstractCorrelatingMessageHandler` to supply a `MessageGroup` condition against a message to be added to the group.
|
||||
See <<./aggregator.adoc#aggregator,Aggregator>> for more information.
|
||||
|
||||
The `MessageGroup` abstraction can be supplied with a `condition` to evaluate later on to make a decision for the group.
|
||||
See <<./message-store.adoc#message-group-condition,Message Group Condition>> for more information.
|
||||
|
||||
[[x5.5-amqp]]
|
||||
==== AMQP Changes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user