First Pipeline
Standalone example
The following example creates a pipeline that triggers every second (time adapter) and logs the current payload via SLF4J.
import io.pipelite.core.Pipelite;
import io.pipelite.core.context.PipeliteContext;
import io.pipelite.dsl.definition.FlowDefinition;
public class HelloPipelite {
public static void main(String[] args) {
FlowDefinition flow = Pipelite.defineFlow("hello-flow")
.fromSource("time://ticker?period=1000") (1)
.process("log-step", (exchange) -> { (2)
System.out.println("Tick: " + exchange.getInputPayload());
exchange.setOutputPayload("processed");
})
.toSink("slf4j://output-logger") (3)
.build(); (4)
PipeliteContext context = Pipelite.createContext(); (5)
context.registerFlowDefinition(flow);
context.start(); (6)
}
}
| 1 | The time:// adapter generates a tick every 1000 ms. |
| 2 | An inline processor that receives the Exchange and processes the payload. |
| 3 | The slf4j:// sink logs the output message via SLF4J. |
| 4 | build() returns the immutable FlowDefinition. |
| 5 | The PipeliteContext is the runtime container. |
| 6 | start() starts all consumers and begins processing. |
Spring Boot example
With the Spring Boot starter, flows are declared in a @FlowConfiguration class and activated via @EnablePipelite:
@SpringBootApplication
@EnablePipelite(flowConfigurations = IngressFlowConfiguration.class) (1)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
| 1 | flowConfigurations lists the classes containing @DefineFlow methods. |
@FlowConfiguration
public class IngressFlowConfiguration {
@DefineFlow
public FlowDefinition ingressFlow() {
return Pipelite.defineFlow("ingress-flow")
.fromSource("http://ingress") (1)
.wireTap("audit-log", "slf4j://audit") (2)
.process("validate", exchange -> {
// validation logic
exchange.setOutputPayload(exchange.getInputPayload());
})
.toSink("slf4j://main-log")
.build();
}
}
| 1 | The http://ingress source opens an HTTP listener on port 80 at path /ingress. |
| 2 | wireTap sends a copy of the message to the audit channel without blocking the main flow. |
For full details on the FlowConfiguration SPI — including dependency injection and multiple flow classes — see FlowConfiguration SPI.
Adding error handling
FlowDefinition flow = Pipelite.defineFlow("resilient-flow")
.fromSource("kafka://my-topic")
.process("transform", exchange -> {
// processing that may throw exceptions
})
.toSink("slf4j://output")
.withRetryChannel() (1)
.build();
| 1 | withRetryChannel() enables automatic retry on unhandled exceptions. |
For a custom error channel use withErrorChannel(cfg → …).
For full details see Error Handling.
Multi-channel concurrent example
pipelite-examples/pipelite-fooddelivery-application is a complete Spring Boot application showing several flows linked together, two of them running with concurrency > 1, fed by four different channel adapters:
time:// (order generator) ──┐
http:// (order intake) ─┼──► link:// (concurrent kitchen stage)
file:// (partner orders) ──┘ │
▼
kafka:// (fan-out)
│
▼
link:// (concurrent dispatch stage)
│
▼
file:// (one output file per courier)
A docker-compose.yml in the module starts a local Kafka broker. Run the app with mvn spring-boot:run and watch the console: a built-in load generator produces sample orders on its own, so concurrent processing is visible immediately with no manual input needed.