AdviceWithPage edited by Claus IbsenChanges (5)
Full ContentAdviceWithAvailable as of Camel 2.1 AdviceWith is used for testing Camel routes where you can advice an existing route before its being tested. What adviceWith allows is to changes some factors on the route before the test is being run. At current time you can advice an existing route by adding Intercept, Exception Clause etc. which then will apply for the route being advice. For example in the route below we intercept sending a message to the mock:foo endpoint and detour the message. public void testAdvised() throws Exception { // advice the first route using the inlined route builder context.getRouteDefinitions().get(0).adviceWith(context, new RouteBuilder() { @Override public void configure() throws Exception { // intercept sending to mock:foo and do something else interceptSendToEndpoint("mock:foo") .skipSendToOriginalEndpoint() .to("log:foo") .to("mock:advised"); } }); getMockEndpoint("mock:foo").expectedMessageCount(0); getMockEndpoint("mock:advised").expectedMessageCount(1); getMockEndpoint("mock:result").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); }
Using AdviceWithRouteBuilderAvailable as of Camel 2.7 The AdviceWithRouteBuilder is a specialized RouteBuilder which has additional methods for advising routes. For example this allows you to manipulate the advised route, such as replacing a node with some other nodes. The AdviceWithRouteBuilder offers the following extra methods
The pattern option is used for matching. It uses the same rules as the Intercept, which is applied in the following order:
For example to match exact you can use weaveById("foo") which will match only the id in the route which has the value "foo". Using weaveByIdThe weaveById allows you to manipulate the rote, for example by replacing a node with other nodes. The following methods is available:
For example given the following route: Route from("direct:start") .to("mock:foo") .to("mock:bar").id("bar") .to("mock:result"); Then let's go over the four methods to see how you can use them in unit tests: Replace context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // weave the node in the route which has id = bar // and replace it with the following route path weaveById("bar").replace().multicast().to("mock:a").to("mock:b"); } }); In this example we replace the .to("mock:bar").id("bar") with the .multicast().to("mock:a").to("mock:b"). Remove context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // weave the node in the route which has id = bar and remove it weaveById("bar").remove(); } }); In the example above, we simply just remove the .to("mock:bar").id("bar"). Before context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // weave the node in the route which has id = bar // and insert the following route path before the adviced node weaveById("bar").before().to("mock:a").transform(constant("Bye World")); } }); In the example above, we add the following nodes to("mock:a").transform(constant("Bye World")) before the node with the id "bar". After context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // weave the node in the route which has id = bar // and insert the following route path after the advice node weaveById("bar").after().to("mock:a").transform(constant("Bye World")); } }); In the example above, we add the following nodes to("mock:a").transform(constant("Bye World")) after the node with the id "bar". Using weaveByToStringThe weaveByToString also allows you to manipulate the route, for example by replacing a node with other nodes. As opposed to weaveById, this method uses the toString representation of the node(s) when matching. This allows you to match nodes, which may not have assigned ids, or to match EIP pattern. The weaveByToString has the same methods as weaceById. For example to replace any nodes which has "foo" you can do Replace context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // weave nodes in the route which has foo anywhere in their to string representation // and replace them with the following route path weaveByToString(".*foo.*").replace().multicast().to("mock:a").to("mock:b"); } }); Notice that we have to use ".*foo.*" in the pattern to match that "foo" is present anywhere in the string. Using weaveByTypeAvailable as of Camel 2.8 The weaveByToType also allows you to manipulate the route, for example by replacing a node with other nodes. As opposed to weaveById, and weaveByToString this method uses the class type of the node(s) when matching. This allows you to match EIP pattern by its type. The weaveByToType has the same methods as weaceById and weaveByToString. For example to remove a transform from the following route: Route from("direct:start") .transform(simple("Hello ${body}")) .log("Got ${body}") .to("mock:result"); You can do: Remove context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // weave the type in the route and remove it weaveByType(TransformDefinition.class).remove(); } }); Using selectorsAvailable os of Camel 2.8 The following methods weaveById(pattern), weaveByToString(pattern) and weaveByType(Class) each match N+ nodes. By using optional selectors you can narrow down the nodes being used. For example if weaveByType(Class) returns 2 nodes. Then you can use a selector to indicate it should only select the first node.
For example to remove the first .to node in route you can do as follows: context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // only remove the first to node in the route weaveByType(ToDefinition.class).selectFirst().remove(); } }); Using weaveAddFirst / weaveAddLastAvailable os of Camel 2.8 The weaveAddFirst and weaveAddLast is a shorthand to easily add nodes to the route. These methods can only add to an existing routes. If you want to manipulate the route, then there are plenty of methods as already shown on this page. For example if you want to send a message to a mock:input endpoint you can do as follows: context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // send the incoming message to mock:input weaveAddFirst().to("mock:input"); } }); Likewise if you want to easily send a message to a mock:output endpoint you can do as follows: context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // send the outgoing message to mock:output weaveAddLast().to("mock:output"); } }); You can of course combine those in the same advice with: context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { weaveAddFirst().to("mock:input"); weaveAddLast().to("mock:output"); } }); Replace from with another endpointAvailable as of Camel 2.9 You may have routes which consumes messages from endpoints which you want to substitute with another endpoint for easier unit testing. For example a JMS endpoint could be replaced with a SEDA or Direct for unit testing a route, as shown below where we replace the input of the route to a "seda:foo" endpoint: context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { replaceFromWith("seda:foo"); } }); Using isUseAdviceWithAvailable as of Camel 2.9 isUseAdviceWith public class IsUseAdviceWithJUnit4Test extends org.apache.camel.test.junit4.CamelTestSupport { @Test public void testIsUseAdviceWith() throws Exception { context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // replace the from with seda:foo replaceFrom("seda:foo"); } }); // we must manually start when we are done with all the advice with context.start(); getMockEndpoint("mock:result").expectedMessageCount(1); template.sendBody("seda:foo", "Hello World"); assertMockEndpointsSatisfied(); } @Override public boolean isUseAdviceWith() { // tell we are using advice with, which allows us to advice the route // before Camel is being started, and thus can replace activemq with something else. return true; } // This is the route we want to test @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { // we do not have activemq on the classpath // but the route has it included from("activemq:queue:foo") .to("mock:result"); } }; } }
Change Notification Preferences
View Online
|
View Changes
|
Add Comment
|
- [CONF] Apache Camel > AdviceWith confluence
- [CONF] Apache Camel > AdviceWith confluence
- [CONF] Apache Camel > AdviceWith confluence