I am working on an application that uses Apache Camel to flow a single request message (input) through some initial Camel components/logic and then to a multicast at which point the route branches out into multiple branches. The purpose of each branch is to retrieve data from a specific web service (or other back-end data source, e.g. database) and then after the web service invocation / data retrieval operation completes, each of the branches dumps its output data in the same way via a custom bean endpoint. I expect to eventually have approximately 40 different branches in the Camel route, each of which might flow through a different set of Camel components in order to prepare its request, submit the request, process the response, etc... I anticipate that a fair number of the branches will be quite similar (e.g. all SOAP invocations quite similar, all REST invocations quite similar, etc.) and so have concocted an approach whereby a config file stores the list of back-end data sources to be invoked/retrieved-from along with the ability to define (indirectly) the route that should be taken to reach each of those sources. The config file looks something like this:
[a]
route=X + Y
Y.url=http://someservice
[b]
route=Z
Z.someproperty=123
And then I have code that reads through that config file and treats each of the "sections" (e.g. "[a]", "[b]", etc.) as a branch (i.e. a destination out of the multicast) and relies on classes that are dynamically instantiated (e.g. XRouteSegment, YRouteSegment, ZRouteSegment) in order to each in-turn populate/define the route for its specific branch. As some examples, I have built RouteSegment helper classes for wiring up components such as Velocity, CXF, CXF-RS, for data marshalling/unmarshalling, etc... based on properties set in config file.
As far as initialization of the Camel context goes, it starts out in a fairly typical way with a single RouteBuilder which builds out the first part of the route up to the multicast. But then I go into a for loop and loop through all of the sources found in the config file (e.g. "a", "b", etc.) and create seda nodes for each of those which the multicast flows to. And then I call into each of the RouteSegment instances associated with a given source (e.g. X + Y) and allow those to add to the RouteDefinition as they need (e.g. from their seda start point going forward). And then back in my "main" RouteBuilder I tack on some final routing/components that is to be the same for all of the branches (i.e. the logic that forces each of the branches to store its data via the same custom bean).
The code works just fine, but I am questioning whether this approach is overkill and/or whether there is some easier/cleaner way of doing this that I am overlooking. Would I be better off just having individual Java classes (i.e. RouteBuilders) for each of the branches (in addition to the "trunk" and "tails" of the route)? What I was trying to avoid was having too much duplicated logic/code across all of those classes ... e.g. 20 classes all pulling data from SOAP web services in pretty much exactly the same way. So I am using a RouteSegment instance like "X" referenced above as re-usable shorthand for what would otherwise be a sequence of different Camel Java DSL calls (e.g. from/to/process/log/etc ... with parameters to control the specifics of the individual statements). Are there any other strategies/approaches I should consider in order to dynamically build out a Camel route (+ sizable number of branches) at runtime (e.g. within a for loop, or via some sort of reflection/discovery process (app runs using Spring Boot))?
Thanks in advance for any ideas you might be able to provide/suggest that I might not have thought of / tried yet!