In one of my use case, i have all my route information in a json file and i want to read the file and create the routes accordingly.
for example,
if i have declared route like this in my json config file
{
"config": [
{
"routeSrcSystem": "System1",
"routes": [
{
"fromRoute": {
"type": "default",
"typeValue": "direct:CMStart"
},
"toRoute": {
"type": "http"
"typeMethod": "POST",
"typeContent": "application/json",
"typeValue": "http://localhost:8080/v1/System1/inboundMessage"
}
}
]
}
]
}
then i able to create the routes as below dynamically. but here though its dynamic,the route definition is not dynamic because i have used one "from" and one "to" definition but parameter for this definition i am passing dynamically.
public class GenerateRouter extends RouteBuilder {
private RoutesMetadata routesMetadata;
public GenerateRouter(CamelContext context,RoutesMetadata routesMetadata) {
super(context);
this.routesMetadata=routesMetadata;
}
@Override
public void configure() throws Exception {
from(routesMetadata.getFromRoute().getTypeValue())
.setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
.setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
.to(routesMetadata.getToRoute().getTypeValue());
}
}
But i would like to do the route definition itself dynamically. for example, i have route config like this,
{
"config": [
{
"routeSrcSystem": "System1",
"routes": [
{
"fromRoute": {
"type": "default",
"typeValue": "direct:CMStart"
},
"toRoute1": {
"type": "http"
"typeMethod": "POST",
"typeContent": "application/json",
"typeValue": "http://localhost:8080/v1/System1/inboundMessage"
}
"toRoute2": {
"type": "http"
"typeMethod": "POST",
"typeContent": "application/json",
"typeValue": "http://localhost:8080/v1/System2/inboundMessage"
}
}
]
}
]
}
then in my route definition i need to add one more "to" definition dynamically. its just example. it could be more dynamic. for example, configuration can be changed to introduce "process" or "bean" or "class" definition. so based on the config, we need to decide how many "to" to be created and how many "process" to be created and etc. I might need to call the next rest end point after some validation and etc and some times i need to call kafka to put the message in queue. i do see an option to list all routes in a list and execute it but i think we need to have flexibility to add process or to or class definition before we call next end point and this has to be based on configuration.
public class GenerateRouter extends RouteBuilder {
private RoutesMetadata routesMetadata;
public GenerateRouter(CamelContext context,RoutesMetadata routesMetadata) {
super(context);
this.routesMetadata=routesMetadata;
}
@Override
public void configure() throws Exception {
from(routesMetadata.getFromRoute().getTypeValue())
.setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
.setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
.to(routesMetadata.getToRoute().getTypeValue())
.setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
.setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
.to(routesMetadata.getToRoute().getTypeValue());
}
}
I saw some information where route definition itself can be defined dynamically and i am doing research on it. but meantime i would like to post this here to get experts opinion. Also, please suggest whether I am using the camel on right way? because in my use case i am thinking to add "to" definition to which pass the class name dynamically based on configuration file, so that application developer can do their logic for transformation, enrich or manipulation in this class on the fly before deliver to target system. please let me know if we have any better approach. also, let me know whether XML way of doing is good way or defining own config file in json format is a good way to create dynamic route.
i am planning to read the json file and create a router definition as a string dynamically. but i would need to load this string as a definition in context it seems. i think i am missing this part.
.to("class:com.xxx.camel.layoutTransform?method=layout()")
if we provide all these configurations in xml file and if camel supports to create the route definition automatically using this file then we can consider this option as well.
Below is the one of the way from another source to create the router definition using XML file. within the XML, we have router information defined and this xml considered as a string and this string is converted as router-definition object and finally added into context.
<routes xmlns=\"http://camel.apache.org/schema/spring\"> <route> <from uri='direct:c'/> <to uri='mock:d'/> </route> </routes>
CamelContext context = new DefaultCamelContext();
context.setTracing(true);
String xmlString = "<routes xmlns=\"http://camel.apache.org/schema/spring\"><route><from uri='direct:c'/><to uri='mock:d'/></route></routes>";
InputStream is = new ByteArrayInputStream(xmlString.getBytes());
RoutesDefinition routes = context.loadRoutesDefinition(is);
context.addRouteDefinitions(routes.getRoutes());
context.start();
ProducerTemplate template = null;
template = context.createProducerTemplate();
template.start();
template.sendBody("direct:c", "HelloC");
Thread.sleep(10000);
context.stop();
I would like to do the similar concept using java dsl definition as a string.
for example, if i have string as below then can this be converted as a router definition?
String dslString = "from("direct:starting").to("seda:end")";
Here is my use case. Sometime, we want to call 2 http services as below
from("direct:start").to(http://localhost:8080/service1).to("http://localhost:8080/service2")
Somtimes we might need to call 3 services as like below
from("direct:start").to(http://localhost:8080/service1).to("http://localhost:8080/service2").to("http://localhost:8080/service3")
sometimes we need to do transformation before we invoke service2 as like below.
from("direct:start").to(http://localhost:8080/service1).to("class:com.xxx.yyy").to("http://localhost:8080/service2").to("http://localhost:8080/service3")
In the even driven architecture, we will have set of routes must be defined for each event types. so the idea is, if we define these routes in a table for each event type, then at the time of service start up all the routes will be loaded in context and will be started. I am able to do the same in XML DSL way but trying to do the same in java DSL.
Thanks in advance!