'Apache Camel: routes inheritance - moving code to the super class
I have the following supercalss BaseRouteBuilder where I am handling the common exception. All my routes extends this class 1234Route extends BaseRouteBuilder. In all my route I am calling at the end a http request to create the order and I am using a format to convert it to JSON. Is it possible in apache Camel to move the format and this conding to the supercass BaseRouteBuilder?
.marshal(format)
.setHeader(
Exchange.HTTP_METHOD,
constant(org.apache.camel.component.http.HttpMethods.POST)
)
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("http://localhost:8080/orders/create-order")
**Superclass - BaseRouteBuilder **
@Component
public class BaseRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
//@formatter:off
onException(Exception.class).process(new Processor() {
public void process(Exchange exchange) throws Exception {
//Coding to enrich the exception error
}
})
.handled(true)
.to("activemq:queue:dead-messages");
//@formatter:on
}
}
**Subclass - 1234Route
@Component
public class 1234Route extends BaseRouteBuilder {
@Override
public void configure() throws Exception {
super.configure();
JacksonDataFormat format = new JacksonDataFormat();
format.useList();
format.setUnmarshalType(DataBase.class);
//@formatter:off
from("activemq:queue:1234")
// my route coding (I have deleted it)
//.setHeader()
//.process
//.bean()
//This is the common coding I want to move it to the super class.
.marshal(format)
.setHeader(
Exchange.HTTP_METHOD,
constant(
org.apache.camel.component.http.HttpMethods.POST
)
)
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("http://localhost:8080/orders/create-order");
//@formatter:on
}
}
Solution 1:[1]
RouteBuilder supports inheritance just like any other class, since onException is RouteBuilder scoped it's fine to define it in a base class. I would however advice against or at least be very careful when defining routes in something like BaseRouteBuilder.
You should also mark BaseRouteBuilder abstract and I would also try to give it more descriptive name like RouteBuilderWithGenericErrorHandler.
RouteBuilders are used to create and add RouteDefinitions to CamelContext and you're not limited to using just one RouteBuilder. Now if you add multiple RouteBuilders to CamelContext that all inherit from BaseRouteBuilder this will cause BaseRouteBuilder.configure to be called multiple times.
This can cause problems like:
- RouteId conflicts.
- Consumer endpoint URI conflicts.
- Same configuration changes getting applied multiple times.
- i.e if you use
RouteBuilder.getContextto modify the CamelContext in some way.
- i.e if you use
In all my route I am calling at the end a http request to create the order and I am using a format to convert it to JSON.
If many of your routes share same routing logic you should split that part to separate route and use it like function. It also makes it easier to add route-scope error handling like what to do when orders api isn't responding or the body provided to direct:createOrder consumer endpoint is invalid.
@Override
public void configure() throws Exception {
from("direct:createOrderA")
.routeId("createOrderA")
// .. do stuff for A
.to("direct:createOrder");
from("direct:createOrderB")
.routeId("createOrderB")
// .. do stuff for B
.to("direct:createOrder");
DataFormat format = ...;
from("direct:createOrder")
.routeId("createOrder")
.marshal(format)
.setHeader(
Exchange.HTTP_METHOD,
constant(org.apache.camel.component.http.HttpMethods.POST)
)
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("http://localhost:8080/orders/create-order");
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
