SlideShare uma empresa Scribd logo
1 de 7
Camel and Spring
Integration (aka SI)
JAVA DSL’s comparison
by implementing Starbucks story
(http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html)
- by Gediminas Siutilas
Requirements for Starbucks story
1. Multiple orders should be submitted for
asynchronous processing.
2. Order for the same customer contains hot
and cold drinks.
3. To prepare a cold drink 1 second is required.
4. To prepare a hot drink 5 seconds are
required.
5. Customer should be served only when both
drinks are ready for the same customer.
SI JAVA DSL (Spring official - no lambdas)
@MessagingGateway
public interface Cafe {
@Gateway(requestChannel = "orders.input")
void placeOrder(Order order);
}
@Autowired
private CafeAggregator cafeAggregator;
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedDelay(1000).get();
}
@Bean
@SuppressWarnings("unchecked")
public IntegrationFlow orders() {
return IntegrationFlows.from("orders.input")
.split("payload.items", (Consumer) null)
.channel(MessageChannels.executor(Executors.newCachedThreadPool()))// 16
.route("payload.iced",
new Consumer<RouterSpec<ExpressionEvaluatingRouter>>() {
@Override
public void accept(RouterSpec<ExpressionEvaluatingRouter> spec) {
spec.channelMapping("true", "iced")
.channelMapping("false", "hot");
}
})
.get();
}
@Bean
public IntegrationFlow icedFlow() {
return IntegrationFlows.from(MessageChannels.queue("iced", 10))
.handle(new GenericHandler<OrderItem>() {
@Override
public Object handle(OrderItem payload,
Map<String, Object> headers) {
Uninterruptibles.sleepUninterruptibly(1,
TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()
+ " prepared cold drink #" +
coldDrinkCounter.incrementAndGet()
+ " for order #" + payload.getOrderNumber()
+ ": " + payload);
return payload;
}
})
.channel("output")
.get();
}
@Bean
public IntegrationFlow hotFlow() {
return IntegrationFlows.from(MessageChannels.queue("hot", 10))
.handle(new GenericHandler<OrderItem>() {
@Override
public Object handle(OrderItem payload,
Map<String, Object> headers) {
Uninterruptibles.sleepUninterruptibly(5,
TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()
+ " prepared hot drink #" +
hotDrinkCounter.incrementAndGet()
+ " for order #" + payload.getOrderNumber()
+ ": " + payload);
return payload;
}
})
.channel("output").get();
}
@Bean
public IntegrationFlow resultFlow() {
return IntegrationFlows.from("output")
.transform(new GenericTransformer<OrderItem, Drink>() {
@Override
public Drink transform(OrderItem orderItem) {
return new Drink(orderItem.getOrderNumber(),
orderItem.getDrinkType(),
orderItem.isIced(),
orderItem.getShots());
}
})
.aggregate(new Consumer<AggregatorSpec>() {
@Override
public void accept(AggregatorSpec aggregatorSpec) {
aggregatorSpec.processor(cafeAggregator, null);
}
}, null)
.handle(CharacterStreamWritingMessageHandler.stdout())
.get();
}
@Component
public static class CafeAggregator {
@Aggregator
public Delivery output(List<Drink> drinks) {
return new Delivery(drinks);
}
@CorrelationStrategy
public Integer correlation(Drink drink) {
return drink.getOrderNumber();
Step-by-Step: http://spring.io/blog/2014/12/01/spring-integration-java-dsl-pre-java-8-line-by-line-tutorial
SI JAVA DSL (Spring official - with lambdas only JAVA8)
@MessagingGateway
public interface Cafe {
@Gateway(requestChannel = "orders.input")
void placeOrder(Order order);
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedDelay(1000).get();
}
@Bean
public IntegrationFlow orders() {
return f -> f
.split(Order.class, Order::getItems)
.channel(c -> c.executor(Executors.newCachedThreadPool()))
.<OrderItem, Boolean>route(OrderItem::isIced, mapping -> mapping
.subFlowMapping("true", sf -> sf
.channel(c -> c.queue(10))
.publishSubscribeChannel(c -> c
.subscribe(s ->
s.handle(m -> sleepUninterruptibly(1, TimeUnit.SECONDS)))
.subscribe(sub -> sub
.<OrderItem, String>transform(item ->
Thread.currentThread().getName()
+ " prepared cold drink #"
+ this.coldDrinkCounter.incrementAndGet()
+ " for order #" + item.getOrderNumber()
+ ": " + item)
.handle(m -> System.out.println(m.getPayload())))))
.subFlowMapping("false", sf -> sf
.channel(c -> c.queue(10))
.publishSubscribeChannel(c -> c
.subscribe(s ->
s.handle(m -> sleepUninterruptibly(5, TimeUnit.SECONDS)))
.subscribe(sub -> sub
.<OrderItem, String>transform(item ->
Thread.currentThread().getName()
+ " prepared hot drink #"
+ this.hotDrinkCounter.incrementAndGet()
+ " for order #" + item.getOrderNumber()
+ ": " + item)
.handle(m -> System.out.println(m.getPayload()))))))
.<OrderItem, Drink>transform(orderItem ->
new Drink(orderItem.getOrderNumber(),
orderItem.getDrinkType(),
orderItem.isIced(),
orderItem.getShots()))
.aggregate(aggregator -> aggregator
.outputProcessor(group ->
new Delivery(group.getMessages()
.stream()
.map(message -> (Drink) message.getPayload())
.collect(Collectors.toList())))
.correlationStrategy(m ->
((Drink) m.getPayload()).getOrderNumber()), null)
.handle(CharacterStreamWritingMessageHandler.stdout());
}
Step-by-Step: http://spring.io/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial
Camel JAVA DSL (Official)
public void configure() {
from("direct:cafe")
.split().method("orderSplitter").to("direct:drink");
from("direct:drink").recipientList().method("drinkRouter");
from("seda:coldDrinks?concurrentConsumers=2").to("bean:barista?method=prepareColdDrink").to("direct:deliveries");
from("seda:hotDrinks?concurrentConsumers=3").to("bean:barista?method=prepareHotDrink").to("direct:deliveries");
from("direct:deliveries")
.aggregate(new CafeAggregationStrategy()).method("waiter", "checkOrder").completionTimeout(5 * 1000L)
.to("bean:waiter?method=prepareDelivery")
.to("bean:waiter?method=deliverCafes");
}
Step-by-Step: http://camel.apache.org/cafe-example.html
As you can see there’s a lot registered services to local JDNI scope like waiter,
barista and etc. More details at: https://github.com/apache/camel/tree/master/examples/camel-
example-cafe/src/main/java/org/apache/camel/example/cafe
Camel JAVA DSL
(My version “All In Route”, exposing everything to the route)
private static RouteBuilder createRoute() {
return new RouteBuilder() {
public void configure() throws Exception {
from(ROUTE_INTPUT).
split(body().method("getItems"))
.setHeader("isIced", body().method("isIced"))
.choice()
.when(header("isIced").isEqualTo("true"))
.to("seda:coldDrinks")
.when(header("isIced").isEqualTo("false"))
.to("seda:hotDrinks")
.otherwise()
.transform(simple("UNKNOWN!!!")).to("stream:out");
from("seda:coldDrinks?concurrentConsumers=1").delay(1000L).to("direct:deliveries");
from("seda:hotDrinks?concurrentConsumers=1").delay(5000L).to("direct:deliveries");
from("direct:deliveries").
process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
OrderItem payload = exchange.getIn().getBody(OrderItem.class);
System.out.println(
Thread.currentThread().getName()
+ " prepared "+ (payload.isIced()?"cold":"hot")+" drink #"
+ hotDrinkCounter.incrementAndGet()
+ " for order #" + payload.getOrderNumber()
+ ": " + payload);
exchange.getIn().setBody(
new Drink(payload.getOrderNumber(),
payload.getDrinkType(),
payload.isIced(),
payload.getShots()));
}
}).
setHeader("order", body().method("getOrderNumber")).
aggregate(header("order"),new CafeAggregationStrategy()).completionSize(2).
process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
List<Drink> drinks = exchange.getIn().getBody(List.class);
exchange.getIn().setBody(
new Delivery(drinks));
}
}).
to("stream:out");
}
};
}
Camel Java DSL:
Pros:
Easy to read and understand.
No need for Generics on every joint.
Cons:
Limited use of JAVA DSL itself inside the route. Yes it supports many
DSL’s but when it comes let say to aggregation with new types of POJO’s, you
endup writing processors producing code boilerplate.
SI JAVA DSL (with Lambdas)
Pros:
Flexible use of JAVA DSL inside the flow.
Flexible access of exchange context inside the flow.
Cons:
Hard to read and understand the flow due to Generics.
SI JAVA DSL with no Lambdas is not even under comparison tables as it too obscure, hard to read and immature
comparing to Camel JAVA DSL.

Mais conteúdo relacionado

Semelhante a Camel vs Spring EIP JAVA DSL

Small pieces loosely joined
Small pieces loosely joinedSmall pieces loosely joined
Small pieces loosely joinedennui2342
 
Building Event Driven Services with Kafka Streams
Building Event Driven Services with Kafka StreamsBuilding Event Driven Services with Kafka Streams
Building Event Driven Services with Kafka StreamsBen Stopford
 
Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19confluent
 
Kotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin MeetupKotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin MeetupSinan KOZAK
 
Sibelius Seraphini - Relay Modern
Sibelius Seraphini - Relay ModernSibelius Seraphini - Relay Modern
Sibelius Seraphini - Relay ModernReact Conf Brasil
 
Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...
Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...
Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...HostedbyConfluent
 
Kick Your Database to the Curb
Kick Your Database to the CurbKick Your Database to the Curb
Kick Your Database to the CurbBill Bejeck
 
MongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your Data
MongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your DataMongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your Data
MongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your DataMongoDB
 
SF Big Analytics meetup : Hoodie From Uber
SF Big Analytics meetup : Hoodie  From UberSF Big Analytics meetup : Hoodie  From Uber
SF Big Analytics meetup : Hoodie From UberChester Chen
 
Deep dive into stateful stream processing in structured streaming by Tathaga...
Deep dive into stateful stream processing in structured streaming  by Tathaga...Deep dive into stateful stream processing in structured streaming  by Tathaga...
Deep dive into stateful stream processing in structured streaming by Tathaga...Databricks
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB
 
Spark streaming with kafka
Spark streaming with kafkaSpark streaming with kafka
Spark streaming with kafkaDori Waldman
 
Spark stream - Kafka
Spark stream - Kafka Spark stream - Kafka
Spark stream - Kafka Dori Waldman
 
Apache Spark Streaming: Architecture and Fault Tolerance
Apache Spark Streaming: Architecture and Fault ToleranceApache Spark Streaming: Architecture and Fault Tolerance
Apache Spark Streaming: Architecture and Fault ToleranceSachin Aggarwal
 
Optimization in django orm
Optimization in django ormOptimization in django orm
Optimization in django ormDenys Levchenko
 
Centralize your Business Logic with Pipelines in Elixir
Centralize your Business Logic with Pipelines in ElixirCentralize your Business Logic with Pipelines in Elixir
Centralize your Business Logic with Pipelines in ElixirMichael Viveros
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 

Semelhante a Camel vs Spring EIP JAVA DSL (20)

Small pieces loosely joined
Small pieces loosely joinedSmall pieces loosely joined
Small pieces loosely joined
 
Building Event Driven Services with Kafka Streams
Building Event Driven Services with Kafka StreamsBuilding Event Driven Services with Kafka Streams
Building Event Driven Services with Kafka Streams
 
Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19Kick your database_to_the_curb_reston_08_27_19
Kick your database_to_the_curb_reston_08_27_19
 
Kotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin MeetupKotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin Meetup
 
Sibelius Seraphini - Relay Modern
Sibelius Seraphini - Relay ModernSibelius Seraphini - Relay Modern
Sibelius Seraphini - Relay Modern
 
ETL
ETLETL
ETL
 
Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...
Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...
Change Data Capture Pipelines with Debezium and Kafka Streams (Gunnar Morling...
 
Kick Your Database to the Curb
Kick Your Database to the CurbKick Your Database to the Curb
Kick Your Database to the Curb
 
MongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your Data
MongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your DataMongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your Data
MongoDB .local Toronto 2019: Using Change Streams to Keep Up with Your Data
 
SF Big Analytics meetup : Hoodie From Uber
SF Big Analytics meetup : Hoodie  From UberSF Big Analytics meetup : Hoodie  From Uber
SF Big Analytics meetup : Hoodie From Uber
 
Deep dive into stateful stream processing in structured streaming by Tathaga...
Deep dive into stateful stream processing in structured streaming  by Tathaga...Deep dive into stateful stream processing in structured streaming  by Tathaga...
Deep dive into stateful stream processing in structured streaming by Tathaga...
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: Keynote
 
Vaadin+Scala
Vaadin+ScalaVaadin+Scala
Vaadin+Scala
 
Functional Web Development using Elm
Functional Web Development using ElmFunctional Web Development using Elm
Functional Web Development using Elm
 
Spark streaming with kafka
Spark streaming with kafkaSpark streaming with kafka
Spark streaming with kafka
 
Spark stream - Kafka
Spark stream - Kafka Spark stream - Kafka
Spark stream - Kafka
 
Apache Spark Streaming: Architecture and Fault Tolerance
Apache Spark Streaming: Architecture and Fault ToleranceApache Spark Streaming: Architecture and Fault Tolerance
Apache Spark Streaming: Architecture and Fault Tolerance
 
Optimization in django orm
Optimization in django ormOptimization in django orm
Optimization in django orm
 
Centralize your Business Logic with Pipelines in Elixir
Centralize your Business Logic with Pipelines in ElixirCentralize your Business Logic with Pipelines in Elixir
Centralize your Business Logic with Pipelines in Elixir
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 

Último

8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 

Último (20)

8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 

Camel vs Spring EIP JAVA DSL

  • 1. Camel and Spring Integration (aka SI) JAVA DSL’s comparison by implementing Starbucks story (http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html) - by Gediminas Siutilas
  • 2. Requirements for Starbucks story 1. Multiple orders should be submitted for asynchronous processing. 2. Order for the same customer contains hot and cold drinks. 3. To prepare a cold drink 1 second is required. 4. To prepare a hot drink 5 seconds are required. 5. Customer should be served only when both drinks are ready for the same customer.
  • 3. SI JAVA DSL (Spring official - no lambdas) @MessagingGateway public interface Cafe { @Gateway(requestChannel = "orders.input") void placeOrder(Order order); } @Autowired private CafeAggregator cafeAggregator; @Bean(name = PollerMetadata.DEFAULT_POLLER) public PollerMetadata poller() { return Pollers.fixedDelay(1000).get(); } @Bean @SuppressWarnings("unchecked") public IntegrationFlow orders() { return IntegrationFlows.from("orders.input") .split("payload.items", (Consumer) null) .channel(MessageChannels.executor(Executors.newCachedThreadPool()))// 16 .route("payload.iced", new Consumer<RouterSpec<ExpressionEvaluatingRouter>>() { @Override public void accept(RouterSpec<ExpressionEvaluatingRouter> spec) { spec.channelMapping("true", "iced") .channelMapping("false", "hot"); } }) .get(); } @Bean public IntegrationFlow icedFlow() { return IntegrationFlows.from(MessageChannels.queue("iced", 10)) .handle(new GenericHandler<OrderItem>() { @Override public Object handle(OrderItem payload, Map<String, Object> headers) { Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); System.out.println(Thread.currentThread().getName() + " prepared cold drink #" + coldDrinkCounter.incrementAndGet() + " for order #" + payload.getOrderNumber() + ": " + payload); return payload; } }) .channel("output") .get(); } @Bean public IntegrationFlow hotFlow() { return IntegrationFlows.from(MessageChannels.queue("hot", 10)) .handle(new GenericHandler<OrderItem>() { @Override public Object handle(OrderItem payload, Map<String, Object> headers) { Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS); System.out.println(Thread.currentThread().getName() + " prepared hot drink #" + hotDrinkCounter.incrementAndGet() + " for order #" + payload.getOrderNumber() + ": " + payload); return payload; } }) .channel("output").get(); } @Bean public IntegrationFlow resultFlow() { return IntegrationFlows.from("output") .transform(new GenericTransformer<OrderItem, Drink>() { @Override public Drink transform(OrderItem orderItem) { return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(), orderItem.getShots()); } }) .aggregate(new Consumer<AggregatorSpec>() { @Override public void accept(AggregatorSpec aggregatorSpec) { aggregatorSpec.processor(cafeAggregator, null); } }, null) .handle(CharacterStreamWritingMessageHandler.stdout()) .get(); } @Component public static class CafeAggregator { @Aggregator public Delivery output(List<Drink> drinks) { return new Delivery(drinks); } @CorrelationStrategy public Integer correlation(Drink drink) { return drink.getOrderNumber(); Step-by-Step: http://spring.io/blog/2014/12/01/spring-integration-java-dsl-pre-java-8-line-by-line-tutorial
  • 4. SI JAVA DSL (Spring official - with lambdas only JAVA8) @MessagingGateway public interface Cafe { @Gateway(requestChannel = "orders.input") void placeOrder(Order order); } @Bean(name = PollerMetadata.DEFAULT_POLLER) public PollerMetadata poller() { return Pollers.fixedDelay(1000).get(); } @Bean public IntegrationFlow orders() { return f -> f .split(Order.class, Order::getItems) .channel(c -> c.executor(Executors.newCachedThreadPool())) .<OrderItem, Boolean>route(OrderItem::isIced, mapping -> mapping .subFlowMapping("true", sf -> sf .channel(c -> c.queue(10)) .publishSubscribeChannel(c -> c .subscribe(s -> s.handle(m -> sleepUninterruptibly(1, TimeUnit.SECONDS))) .subscribe(sub -> sub .<OrderItem, String>transform(item -> Thread.currentThread().getName() + " prepared cold drink #" + this.coldDrinkCounter.incrementAndGet() + " for order #" + item.getOrderNumber() + ": " + item) .handle(m -> System.out.println(m.getPayload()))))) .subFlowMapping("false", sf -> sf .channel(c -> c.queue(10)) .publishSubscribeChannel(c -> c .subscribe(s -> s.handle(m -> sleepUninterruptibly(5, TimeUnit.SECONDS))) .subscribe(sub -> sub .<OrderItem, String>transform(item -> Thread.currentThread().getName() + " prepared hot drink #" + this.hotDrinkCounter.incrementAndGet() + " for order #" + item.getOrderNumber() + ": " + item) .handle(m -> System.out.println(m.getPayload())))))) .<OrderItem, Drink>transform(orderItem -> new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(), orderItem.getShots())) .aggregate(aggregator -> aggregator .outputProcessor(group -> new Delivery(group.getMessages() .stream() .map(message -> (Drink) message.getPayload()) .collect(Collectors.toList()))) .correlationStrategy(m -> ((Drink) m.getPayload()).getOrderNumber()), null) .handle(CharacterStreamWritingMessageHandler.stdout()); } Step-by-Step: http://spring.io/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial
  • 5. Camel JAVA DSL (Official) public void configure() { from("direct:cafe") .split().method("orderSplitter").to("direct:drink"); from("direct:drink").recipientList().method("drinkRouter"); from("seda:coldDrinks?concurrentConsumers=2").to("bean:barista?method=prepareColdDrink").to("direct:deliveries"); from("seda:hotDrinks?concurrentConsumers=3").to("bean:barista?method=prepareHotDrink").to("direct:deliveries"); from("direct:deliveries") .aggregate(new CafeAggregationStrategy()).method("waiter", "checkOrder").completionTimeout(5 * 1000L) .to("bean:waiter?method=prepareDelivery") .to("bean:waiter?method=deliverCafes"); } Step-by-Step: http://camel.apache.org/cafe-example.html As you can see there’s a lot registered services to local JDNI scope like waiter, barista and etc. More details at: https://github.com/apache/camel/tree/master/examples/camel- example-cafe/src/main/java/org/apache/camel/example/cafe
  • 6. Camel JAVA DSL (My version “All In Route”, exposing everything to the route) private static RouteBuilder createRoute() { return new RouteBuilder() { public void configure() throws Exception { from(ROUTE_INTPUT). split(body().method("getItems")) .setHeader("isIced", body().method("isIced")) .choice() .when(header("isIced").isEqualTo("true")) .to("seda:coldDrinks") .when(header("isIced").isEqualTo("false")) .to("seda:hotDrinks") .otherwise() .transform(simple("UNKNOWN!!!")).to("stream:out"); from("seda:coldDrinks?concurrentConsumers=1").delay(1000L).to("direct:deliveries"); from("seda:hotDrinks?concurrentConsumers=1").delay(5000L).to("direct:deliveries"); from("direct:deliveries"). process(new Processor() { @Override public void process(Exchange exchange) throws Exception { OrderItem payload = exchange.getIn().getBody(OrderItem.class); System.out.println( Thread.currentThread().getName() + " prepared "+ (payload.isIced()?"cold":"hot")+" drink #" + hotDrinkCounter.incrementAndGet() + " for order #" + payload.getOrderNumber() + ": " + payload); exchange.getIn().setBody( new Drink(payload.getOrderNumber(), payload.getDrinkType(), payload.isIced(), payload.getShots())); } }). setHeader("order", body().method("getOrderNumber")). aggregate(header("order"),new CafeAggregationStrategy()).completionSize(2). process(new Processor() { @Override public void process(Exchange exchange) throws Exception { List<Drink> drinks = exchange.getIn().getBody(List.class); exchange.getIn().setBody( new Delivery(drinks)); } }). to("stream:out"); } }; }
  • 7. Camel Java DSL: Pros: Easy to read and understand. No need for Generics on every joint. Cons: Limited use of JAVA DSL itself inside the route. Yes it supports many DSL’s but when it comes let say to aggregation with new types of POJO’s, you endup writing processors producing code boilerplate. SI JAVA DSL (with Lambdas) Pros: Flexible use of JAVA DSL inside the flow. Flexible access of exchange context inside the flow. Cons: Hard to read and understand the flow due to Generics. SI JAVA DSL with no Lambdas is not even under comparison tables as it too obscure, hard to read and immature comparing to Camel JAVA DSL.