2
votes

I'm working on finding a solution to route a message through a processor dynamically decided at the runtime depending on some attibute on message header or body.

Let's say I have two message Processors (eg : Type1RequestProcessor, Type2RequestProcessor) as mentioned below.

What I want to do is executing either Type1RequestProcessor or Type2RequestProcessor dynamically decided using a property in the message header ot body.(Here I don't want to create multiple routers per Processor types.)

I tried as mentioned below (passing typeId in header). But it obviously gives below error saying No bean could be found in the registry for: ${header.messageId}RequestProcessor of type: org.apache.camel.Processor.

HTTPRouter.java

import javax.enterprise.context.ApplicationScoped;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.cdi.ContextName;

@ApplicationScoped
@ContextName("camel-cdi-context")
public class HTTPRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        from("direct:oneRouter")
        .process("${header.typeId}RequestProcessor")
        .to("direct:anotherRouter");
    }
}

Error :

org.apache.camel.FailedToCreateRouteException: Failed to create route route19 at: >>> process[ref:${header.messageId}RequestProcessor] <<< in route: Route(route19)[[From[direct:oneRouter]] -> [process[ref:${he... because of No bean could be found in the registry for: ${header.messageId}RequestProcessor of type: org.apache.camel.Processor
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1298)
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:204)
    at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:1087)
    at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:3540)
    at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3271)
    at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:202)

I tried with the bean component also but the result is same.

Can anyone give a little hand here? How to load the Processors dynamically?

Type1RequestProcessor.java

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class Type1RequestProcessor implements Processor {

    public void process(Exchange exchange) throws Exception {

        // Do Type1 process implementation

    }

}

Type2RequestProcessor.java

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class Type2RequestProcessor implements Processor {

    public void process(Exchange exchange) throws Exception {

        // Do Type2 process implementation

    }

}

Note : I have plan B of loading these implementation dynamically within a process method in router itself (Anonymous Inner Class). But I'm still looking for this since it will perfectly suit what I'm looking for.

  • Camel Version : 2.19.2
  • WildFly version : 10.1.0
  • Camel Patch Version : wildfly-camel-patch-4.9.0
1
Thanx Claus Ibsen, but what I'm looking for is dynamically loading the processor. Not calling URI dynamically. If i need to call URI dynamically I could use toD() also since I'm using camel 2.19.namalfernandolk

1 Answers

2
votes

Dynamic expression language cannot be used inside process method, but you can annotate your Processors with @Named to make it available in CDI registry. Then invoke it with bean component using .toD(bean:${header.typeId}RequestProcessor) or directly with .toD(${header.typeId}RequestProcessor).

Please note Named bean name translates to class name in camelCase by default. You can customize this behavior with @Named("Type1RequestProcessor").