This is an automated email from the ASF dual-hosted git repository. zregvart pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-website.git
commit 9257e43abc570d44f504941fd394e9eee78fe748 Author: Steve973 <steve...@gmail.com> AuthorDate: Thu Jan 13 14:49:00 2022 -0500 CAMEL-17154: Added Dynamic Router EIP Component blog entry. --- .../01/dynamic-router-eip-component/featured.png | Bin 0 -> 3975989 bytes .../2022/01/dynamic-router-eip-component/index.md | 146 +++++++++++++++++++++ 2 files changed, 146 insertions(+) diff --git a/content/blog/2022/01/dynamic-router-eip-component/featured.png b/content/blog/2022/01/dynamic-router-eip-component/featured.png new file mode 100644 index 0000000..e5077f5 Binary files /dev/null and b/content/blog/2022/01/dynamic-router-eip-component/featured.png differ diff --git a/content/blog/2022/01/dynamic-router-eip-component/index.md b/content/blog/2022/01/dynamic-router-eip-component/index.md new file mode 100644 index 0000000..2b69fa5 --- /dev/null +++ b/content/blog/2022/01/dynamic-router-eip-component/index.md @@ -0,0 +1,146 @@ +--- +title: "Camel Dynamic Router EIP Component" +date: 2022-01-11T18:46:58-05:00 +draft: true +authors: ["Steve973"] +categories: ["EIP"] +preview: "Apache Camel 3.15.0 introduces a new Dynamic Router EIP Component" +--- + +Apache Camel 3.15.0 introduces a new Dynamic Router EIP component. Although Camel core includes a Dynamic Router processor, I wanted a Dynamic Router implementation that was much closer, and more adherent, to the EIP specification. + +### The Dynamic Router as a "glue" component, not a messaging server + +It is important to note that, while this implementation of the Dynamic Router is a component, it is not meant to be a component for some type of messaging system (like JMS, etc.), or to act as a server for a new type of messaging system. It could have been implemented as a part of Camel Core, but since it does not need to introduce elements into the Camel DSL, it is better as a component. Even as a component, it is still intended to provide useful "glue" between sources and destination [...] + +Seeing the similarities and differences between the Dynamic Router component, and other Camel features, is helpful to understand its use: + +* [Content Based Router](/components/next/eips/choice-eip.html) (Choice): but the choices are fully subscriber-initiated and do not need to be known at compile time. +* [Dynamic Router](/components/next/eips/dynamicRouter-eip.html) (processor): This will be discussed in detail below. +* [Message Filter](/components/next/eips/filter-eip.html): but instead of creating the filter at compile time, consumers provide their own filter at runtime. +* [Selective Consumer](/components/next/eips/selective-consumer.html): but turned the other way around: instead of sending messages to (potentially a list of) recipients, and letting them all determine which messages to process or discard, this component allows a consumer to subscribe with its filter so that the router can handle this (centrally) and only send messages to the (first) appropriate subscriber. +* [To Dynamic](/components/next/eips/toD-eip.html): but the sender does not need to know about dynamic recipients, and "to" endpoint variables do not have to be set. + +It is true that a developer could achieve almost anything in software by composing a solution of several separate pieces, and implementing the glue that helps them to work together. Also, in this case, it would be necessary to implement the runtime registration and management of routing participants. In order to simplify messaging to and from other sources, this component ties aspects of these things together in a way that allows the evaluation to be truly runtime-based. This componen [...] + + +So, let’s have a look at both implementations to see what this new component provides that might suggest some new use cases and solutions for Apache Camel users. + + +### A Look at the Dynamic Router EIP + +![Dynamic Router EIP](https://www.enterpriseintegrationpatterns.com/img/DynamicRouter.gif "Dynamic Router EIP") + + +Above, you see a diagram of the Dynamic Router [EIP](https://www.enterpriseintegrationpatterns.com/DynamicRouter.html). What I like best about this pattern is that the routing participants (A, B, and C) can utilize a control channel to provide their routing rules to the rule base inside the Dynamic Router itself. When a message comes in through the input channel, the message router consults the dynamic rule base, and sends the message to the recipient with matching rules in the rule base. + + +### Skip Reading? Jump Right In! + +In the `camel-spring-boot-examples` module, I have created a `dynamic-router-eip` module that provides a suggestion of one way that you might use this new Dynamic Router EIP component. I will elaborate more on the example in a subsequent section. Feel free to jump to that example in the repository, or continue to read the following sections for more information and a deeper dive into the example afterward. + + +### The Current (Camel Core) Implementation + +The Dynamic Router in Camel core uses an approach that builds on the [Routing Slip EIP](/components/next/eips/routingSlip-eip.html), and makes it dynamic. Unlike the standard routing slip that is evaluated only once (at the beginning), the dynamic router slip is evaluated on-the-fly. The dynamic rule base is implemented, here, as the dynamic routing slip. It contains the conditions under which a message is routed to recipients, and the endpoint URI to which the message is routed. Afte [...] + + +### The New (Component) Implementation + +While this implementation has many good use cases, I saw a different implementation, because I did not want to have to know the routing rules before runtime. I wanted routing participants to be able to potentially come and go during the course of runtime, and subscribe with their rules, and unsubscribe from routing, as needed, thus making it truly dynamic. + + +#### Control Channel Messages + +A routing participant can, at any time, send a Control Message through the Control Channel, specifying a simple or complex [Predicate](/manual/predicate.html) to evaluate an Exchange for suitability, and a destination Endpoint to send matching Exchanges. When a participant wants to unsubscribe, they can send another Control Message that removes the participant from the routing. + + +##### Subscribe Example + + +```java +// Create a subscription that accepts an exchange +// when the message body contains an even number +DynamicRouterControlMessage evenSubscribeMsg = + new DynamicRouterControlMessage( + ControlMessageType.SUBSCRIBE, + "evenNumberSubscription", "test", 2, "jms:even", + body().regex("^\\d*[02468]$")); +template.sendBody("dynamic-router:control", evenSubscribeMsg); +``` + + +The message contains the message type, the subscription ID, the Dynamic Router channel, message priority (where lower = higher priority), the destination URI for matching exchanges, and the [Predicate](https://camel.apache.org/manual/predicate.html) to evaluate the exchange. + + +##### Unsubscribe Example + + +```java +DynamicRouterControlMessage unsubscribeMessage = + new DynamicRouterControlMessage("testSubscriptionId", "test"); +template.sendBody("dynamic-router:control", unsubscribeMessage); +``` + + +The control message to unsubscribe requires fewer parameters. It requires only the subscription ID and the channel, since the remaining parameters are irrelevant in the context of unsubscribing. + + +#### Dynamic Routing Channels + +This component utilizes routing “channels” that are analogous to VLANs in the networking world, or like queue/topic names in JMS. We have already discussed the specialized control channel, but any number of channels can be created and used at runtime. These channels logically separate exchanges, participants, and their rules, from those on other channels. + + +##### Building a Route to Route Exchanges Through a Dynamic Router Channel + +Simply use a RouteBuilder to utilize a Dynamic Router and route Exchanges through a channel: + + +```java +from("direct:start").to("dynamic-router://test"); +``` + + +Now, messages that are sent to `direct:start` will go to the `test` channel of the Dynamic Router, and the exchanges will be evaluated against all subscription rules/predicates until the first match is found, and the exchange will be sent to the subscription’s supplied destination endpoint URI. + + +### A Somewhat-Practical Example + +As I mentioned above, there is a `dynamic-router-eip` module in the `camel-spring-boot-examples` repository. After the Spring Boot application starts, the routing participants send a message to the dynamic router control channel URI. There are eleven routing participants, where each participant subscribes with a predicate that examines the message body to determine if it is suitable for processing, and a destination URI where matching exchanges will be sent. Ten of these participants [...] + +``` + . ____ _ __ _ _ + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ + \\/ ___)| |_)| | | | | || (_| | ) ) ) ) + ' |____| .__|_| |_|_| |_\__, | / / / / + =========|_|==============|___/=/_/_/_/ + :: Spring Boot :: (v2.6.2) + +INFO 23130 --- [main] NumbersService : Subscribing participants +INFO 23130 --- [main] NumbersService : Sending messages to the dynamic router +INFO 23130 --- [main] NumbersService : Finished +Dynamic Router Spring Boot Numbers Example Results: + odd: 150077 + even: 114287 + sevens: 101588 + tens: 100000 + nines: 100000 + eights: 88889 + primes: 78494 + threes: 76191 + fives: 76190 + sixes: 57142 + fours: 57142 +Received count: 1000000 in 5709ms +``` + + +### How Does This All Sound To You? + +If this component implementation of the Dynamic Router EIP might suit your needs and use cases, please give it a try and let us know what you think. Thank you for taking the time to read about this new Dynamic Router EIP component! + + +### Postscript: Dedication + +I dedicate this work to my late brother, Jeffrey T. Storck, who passed away on 8 June 2020. He was an excellent and very successful software engineer, he loved Apache Camel, and he was on the PMC of another prominent Apache project. We shared a passion for clean, testable, maintainable, and elegant software, and for always learning how to do it better. He taught me a lot, and he was probably the largest single influence in helping to make me the software engineer that I am today. Man [...]