Apache Camel Dynamic Routing Flow On Exception

362 Views Asked by At

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.

0

There are 0 best solutions below