Reputation: 21
I have successfully created few routes overriding configure() method of RouteBuilder. A for loop is used to generate routes on application startup, for eg:
Route1: from("direct:Route1").to("netty-http:http://localhost:8080/route1)
Route2: from("direct:Route2").to("netty-http:http://localhost:8081/route2)
Route3: from("direct:Route3").to("netty-http:http://localhost:8082/route3)
Route4: from("direct:Route4").to("netty-http:http://localhost:8083/route4)
Route5: from("direct:Route5").to("netty-http:http://localhost:8084/route5)
for (endpoint in endpoints.iterator()) {
from("direct:" + endpoint.getEndpointRouteName())
.process(getProcessor(endpoint.getEndpointProcessor(), endpoint.getEndpointRouteName(), objectMapper))
.setHeader(Exchange.HTTP_METHOD, simple(endpoint.getEndpointRequestMethod()))
.setHeader(Exchange.CONTENT_TYPE, constant(endpoint.getEndpointContentType()))
.to("netty-http:" + endpoint.getEndpointUrl())
}
private fun getProcessor(processorClassName: String, name: String, objectMapper: ObjectMapper): Processor {
var processorClass = Class.forName("com.demo.camelpoc.processors.$name.$processorClassName")
return processorClass.getDeclaredConstructor(ObjectMapper::class.java).newInstance(objectMapper) as Processor
}
And there is a source endpoint which starts the workflow. For example the default workflow generated in runtime:
// Workflow
from("netty-http:$sourceUrl").process {
it.setProperty("Workflow", workflowMap)
}
.dynamicRouter(bean(DynamicRouteBean::class.java, "route(*, *, ${startEndpoint})"))
where workflowMap (Used in DynamicRouteBean) is a map of endpoint strings like Key: "direct:Route1 " Value : "direct:Route2", Key: "direct:Route2 " Value : "direct:Route3"... etc
Requirement: Retry sending to the same endpoint in the workflow when exception is thrown in that particular route
For eg:
Lets say, an exception occurs at direct:Route2, I want to retry sending to direct:Route2.
Here is my DynamicRouteBean class.
class DynamicRouteBean {
fun route(
@Header(Exchange.SLIP_ENDPOINT) previousRoute: String?,
exchange: Exchange,
startEndpoint: String
): String? {
if(checkException(exchange)) {
return exchange.getProperty(Exchange.SLIP_ENDPOINT) as String
}
if (exchange.getProperty(Properties.STOP_ROUTE) != null && exchange.getProperty(Properties.STOP_ROUTE) == true) {
return null
}
val workflow: MutableMap<String, Pair<String, String?>> =
exchange.getProperty("Workflow") as MutableMap<String, Pair<String, String?>>
return when (previousRoute) {
null ->
startEndpoint
else -> {
val message = exchange.getIn(NettyHttpMessage::class.java)
// Signifies last endpoint and thus means end of the route
if (!workflow.containsKey(previousRoute)) {
return null
}
if (message?.getHeader(previousRoute.substring(9)) != null) {
val isSuccess = message.getHeader(previousRoute.substring(9)) == true
if (isSuccess) {
"${workflow[previousRoute]?.first}"
} else if (workflow[previousRoute]?.second != null) {
"${workflow[previousRoute]?.second}"
} else {
null
}
} else {
null
}
}
}
}
When I return current Exchange.SLIP_ENDPOINT property as String on exception, it doesn't call that endpoint again but exception message is returned back to the consumer.
Whereas it works in normal cases when there is no exception. Suggestions would be very helpful on handling this scenario.
Upvotes: 2
Views: 373