16

I have the following route for demo purposes

from("direct:external")
    .routeId("external")
    .to("http4://www.third-party.com/foo").id("ext");

For testing, I would like to * replace the http4: endpoint with a direct: endpoint * add a mock: endpoint at the end of the route for verification

I've added the following adviceWithRouteBuilder

context.getRouteDefinition("external").adviceWith(context, new AdviceWithRouteBuilder() {
    @Override
    public void configure() throws Exception {
        weaveAddLast().to("mock:result");
        weaveByToUri(".*http4://.*")
            .replace()
            .to("direct:foo");
    }
});

This one seems to work but if I change the order of the weave* statements, like so

public void configure() throws Exception {
    weaveByToUri(".*http4://.*")
        .replace()
        .to("direct:foo");
    weaveAddLast().to("mock:result");
}

It gives me the following error

java.lang.IllegalArgumentException: There are no outputs which matches: * in the route: Route(external)[[From[direct:external]] -> [pipeline -> [[To[direct:foo]]]]]

I would actually expect to get the same result, independent of the order.

helpermethod
  • 59,493
  • 71
  • 188
  • 276
  • 3
    For most of the usage I've had with Camel I've never used weaving functions for the functionality you'd like to achieve. What about using `interceptSendToEndpoint(fromEndpoint).skipSendToOriginalEndpoint().to(toEndpoint);` ? Since camel-test package is actually causing more pain than benefit I've created a camel-test-support package, which is a little bit easier to use. Please check it out, examples attached: https://github.com/gmaslowski/camel-test-support – gmaslowski Feb 08 '17 at 19:41

1 Answers1

10

One thing to note here is that the weave* calls are only aware of the original RouteBuilder. So when you perform the weaveByUri() call first, it replaces .to("http4://www.third-party.com/foo") with .to("direct:foo"), which incidentally happens to be the last endpoint in your route. Now, when you perform the weaveAddLast() call, it looks for "http4://www.third-party.com/foo" but doesn't find it, since it was replaced by "direct:foo". This results in an exception being thrown.

So if, hypothetically, there's another endpoint after the "http4..." endpoint such that it's not the last endpoint in your route anymore, your adviceWith() should work. For instance, it will work if your original route looked something like this:

from("direct://external")
  .routeId("external")
  .to("http4://www.third-party.com/foo")
  .id("ext")
  .to("direct://bar")
;

I should note that I think that this is a bug and that the order shouldn't matter.

Khaled
  • 644
  • 1
  • 8
  • 14
  • Perfect answer, it's a pity that you didn't answer before the bounty timed out (that would have granted you 500 SO points). – helpermethod Feb 17 '17 at 09:58
  • 1
    Thanks I logged a ticket to see if we can improve/fix this: https://issues.apache.org/jira/browse/CAMEL-10855 – Claus Ibsen Feb 17 '17 at 10:10