Link Channel Adapter
The link adapter allows two internal flows within the same PipeliteContext to be connected, forwarding the Exchange from one flow to the consumer of another.
Usage
// Main flow
Pipelite.defineFlow("main-flow")
.fromSource("http://ingest")
.process("enrich", exchange -> { /* enrichment */ })
.toSink("link://secondary-flow") (1)
.build();
// Linked secondary flow
Pipelite.defineFlow("secondary-flow")
.fromSource("secondary-flow") (2)
.process("finalize", exchange -> { /* ... */ })
.toSink("slf4j://output")
.build();
| 1 | The link://secondary-flow sink sends the Exchange directly to the secondary flow consumer. |
| 2 | The source is the plain name secondary-flow, with no protocol: it receives what the main flow sends to link://secondary-flow. |
URL format
link://<source-endpoint-name>
| Parameter | Description |
|---|---|
|
The name the receiving flow declares in |
The way to address an internal flow
A flow is always addressed by URL, and link://<source endpoint name> is the URL of an internal one. The same rule holds everywhere a destination is written - toSink(…), the destinations of toRoute(…) and toRecipientList(…), wireTap(…), toChannel(…) - and for PipeliteContext.supplyExchange(…). A bare name is not a destination: it is rejected when the flow is defined, or when the exchange is delivered if the value is only known at runtime.
The receiving side is the exception on purpose: fromSource(…) takes the name of its own source endpoint, with no protocol.
Characteristics
-
Exchange handoff is synchronous in the sender flow thread.
-
No serialization is involved: the
Exchangeis passed by reference. -
Useful for splitting complex pipelines into modular, reusable flows.
-
The receiving flow’s source can declare
?concurrency=Nto process linked Exchanges concurrently — see Flow Definition.
Startup validation
PipeliteContext.start() checks that every link:// target is the source endpoint name of a flow registered in the same context: the destinations of toSink(…), of the routes and the recipient list, of wireTap(…), and the target of toChannel(…), alone or as the exhaustion action of a retry. If one is not - a typo, a rename on one side only - start() throws a ContextValidationException that lists every problem, naming the flow and the DSL construct, before anything is started.
A destination that contains an expression (#{…}) is only known when an exchange is routed, so it is not checked at startup; if it names no flow then, the delivery fails with an IllegalArgumentException. Destinations with any other protocol are not checked either.