简体   繁体   中英

Apache camel 2.16 enrich - No consumers available on endpoint in JUnit

I upgraded to camel 2.16 and one of my route Unit Tests started failing.

Here is my route definition:

public class Route extends RouteBuilder{

    @Override
    public void configure() throws Exception {

        from(start).enrich("second");

        from("direct:second")
          .log(LoggingLevel.DEBUG, "foo", "Route [direct:second] started.");

    }
}

Here is my test:

@RunWith(MockitoJUnitRunner.class)
public class RouteTest extends CamelTestSupport  {

    private Route builder;

    @Produce(uri = "direct:start")
    protected ProducerTemplate template;

    @Before
    public void config() {
        BasicConfigurator.configure();
    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        builder = new Route();
        return builder;
    }

    @Override
    protected CamelContext createCamelContext() throws Exception {
        SimpleRegistry registry = new SimpleRegistry();
        return new DefaultCamelContext(registry);
    }

    @Test
    public void testPrimeRouteForSubscriptionId() {
        Exchange exchange = ExchangeBuilder.anExchange(new DefaultCamelContext()).build();
        exchange.getIn().setBody(new String("test"));
        template.send(exchange);
    }
}

The error I'm getting when I run the test is:

org.apache.camel.component.direct.DirectConsumerNotAvailableException: No consumers available on endpoint: Endpoint[direct://second]. Exchange[][Message: test]

Worthy of note is the following line in the camel 2.16 notes: http://camel.apache.org/camel-2160-release.html

The resourceUri and resourceRef attributes on and has been removed as they now support a dynamic uris computed from an Expression.

Thanks in advance for any help.

Swap the order so the the direct route is started before the enrich. http://camel.apache.org/configuring-route-startup-ordering-and-autostartup.html

Or use seda instead of direct in your unit test: http://camel.apache.org/seda

Or use ?block=true in the direct uri to tell Camel to block and wait for a consumer to be started and ready before it sends a message to it: http://camel.apache.org/direct

The blueprint test keeps throwing exception, No Consumers available.

My scenario was that I have an osgi svc which exposes a method which can be called from any another osgi svc .

So the exposed svc method makes a call to a direct:

@EndpointInject(uri = "direct-vm:toRestCall")
    ProducerTemplate toRestCall;

svcMethod(Exchange xch){
exchange.setOut(
        toRestCall.send("seda:toDirectCall", xch -> {
            try{
                xch.getIn().setBody("abc");
            }catch (Exception ex){
                ex.getMessage();
            }
          }
        }).getIn());

And when I tested the direct that it calls, Blueprint advice with JUnit used to keep throwing the following exception:

org.apache.camel.component.direct.DirectConsumerNotAvailableException: No consumers available on endpoint: Endpoint. Exchange[Message: {..........

This is a somewhat old issue, but since i pulled out most of my hair out last night, trying to figure out why it was ok to use to("direct:myEndpoint") but not enrich("direct:myEndpoint") , I'll post the answer anyway - maybe it'll save somebody else from getting bald spots ;-)

It turns out to be a test-issue. In case of Direct endpoints, enrich checks whether there is a running route in the context before passing the Exchange to it, but it does so by looking at the CamelContext held by the Exchange it is currently handling. Since you passed your ProducerTemplate an Exchange what was created with a new DefaultCamelContext() , it has no "direct:second" route available.

Luckily there is a couple of simple solutions. Either create the Exchange using the CamelContext from CamelTestSupport, or use the ProducerTemplate sendBody(...) method instead:

@Test
public void testWithSendBody() {
    template.sendBody(new String("test"));
}

@Test
public void testPrimeRouteForSubscriptionId() {
    Exchange exchange = ExchangeBuilder.anExchange(context()).build();
    exchange.getIn().setBody(new String("test"));
    template.send(exchange);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM