Split / Aggregate
Pipelite supports the Splitter and Aggregator Enterprise Integration Patterns via the .split() method of the DSL.
A single incoming message carrying a collection is broken down into one message per element, each element is processed independently through a dedicated sequence of steps, and the results are recombined into a single message before the flow continues.
Basic usage
FlowDefinition flow = Pipelite.defineFlow("order-batch-flow")
.fromSource("http://orders/inbound")
.split("split-orders", segment -> segment (1)
.process("validate", orderValidator) (2)
.process("enrich", orderEnricher)
.end()) (3)
.toSink("kafka://orders-processed")
.build();
| 1 | .split(name, configurator) splits the input payload — which must be a Collection — into one message per element. |
| 2 | Each element is processed through the steps defined inside the segment, using the same .process(…) operation available in the main flow (see Flow Definition). |
| 3 | .end() closes the segment definition. .split(…) then returns to the main flow, so it can be followed by further steps or by .toSink(…), exactly like .process(…). |
Behavior
-
Elements are processed in order, one at a time; the aggregated result preserves the original order of the input collection.
-
An empty collection is a valid input: the flow continues normally with an empty aggregated result, no element is processed.
-
A segment can contain any number of
.process(…)steps, including zero — in that case, each element passes through the split unchanged. -
Headers set on the incoming message are visible to every element while it is processed inside the segment. Changes a step makes to one element’s headers (e.g. adding a header) never affect the other elements or the original message.
-
The aggregated message carries the same identity, headers, and properties as the message that entered
.split(…)— from the rest of the flow’s point of view, a split step is indistinguishable from an ordinary processing step. -
If any element fails during processing, the split step fails as a whole — there is no per-element retry or partial recovery. Combined with
.withRetryChannel()(see Error Handling), a failure causes the entire batch to be retried, not just the failed element.
Aggregation result
The output payload of the aggregated message is a list containing, in the original order, the result produced by the segment for each element.
If the desired outcome isn’t a list — for example a sum, a count, or a merged object — add a regular .process(…) step right after .split(…) that reads the list and applies the domain-specific combination:
.split("split-items", segment -> segment
.process("price", priceCalculator)
.end())
.process("sum-total", exchange -> {
List<BigDecimal> prices = exchange.getInputPayloadAs(List.class);
BigDecimal total = prices.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
exchange.setOutputPayload(total);
})