You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2012/01/05 10:00:28 UTC
svn commit: r1227529 - in /camel/trunk/camel-core/src:
main/java/org/apache/camel/ main/java/org/apache/camel/impl/
main/java/org/apache/camel/model/
test/java/org/apache/camel/processor/intercept/
Author: davsclaus
Date: Thu Jan 5 09:00:27 2012
New Revision: 1227529
URL: http://svn.apache.org/viewvc?rev=1227529&view=rev
Log:
CAMEL-4809: Fixed interceptSendToEndpoint with when predicate and skip option enabled, should only skip sending if the predicate was true. Thanks to Raul for part of this work.
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/WhenSkipSendToEndpointDefinition.java
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/intercept/InterceptSendToEndpointConditionalSkipTest.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/InterceptSendToEndpoint.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ExpressionNode.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterDefinition.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java?rev=1227529&r1=1227528&r2=1227529&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java Thu Jan 5 09:00:27 2012
@@ -136,6 +136,7 @@ public interface Exchange {
String HTTP_SERVLET_RESPONSE = "CamelHttpServletResponse";
String INTERCEPTED_ENDPOINT = "CamelInterceptedEndpoint";
+ String INTERCEPT_SEND_TO_ENDPOINT_WHEN_MATCHED = "CamelInterceptSendToEndpointWhenMatched";
String LANGUAGE_SCRIPT = "CamelLanguageScript";
String LOG_DEBUG_BODY_MAX_CHARS = "CamelLogDebugBodyMaxChars";
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/InterceptSendToEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/InterceptSendToEndpoint.java?rev=1227529&r1=1227528&r2=1227529&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/InterceptSendToEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/InterceptSendToEndpoint.java Thu Jan 5 09:00:27 2012
@@ -73,6 +73,7 @@ public class InterceptSendToEndpoint imp
public EndpointConfiguration getEndpointConfiguration() {
return delegate.getEndpointConfiguration();
}
+
public String getEndpointKey() {
return delegate.getEndpointKey();
}
@@ -133,7 +134,16 @@ public class InterceptSendToEndpoint imp
return;
}
- if (!skip) {
+ // determine if we should skip or not
+ boolean shouldSkip = skip;
+
+ // if then interceptor had a when predicate, then we should only skip if it matched
+ Boolean whenMatches = (Boolean) exchange.removeProperty(Exchange.INTERCEPT_SEND_TO_ENDPOINT_WHEN_MATCHED);
+ if (whenMatches != null) {
+ shouldSkip = skip && whenMatches;
+ }
+
+ if (!shouldSkip) {
if (exchange.hasOut()) {
// replace OUT with IN as detour changed something
exchange.setIn(exchange.getOut());
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/ExpressionNode.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ExpressionNode.java?rev=1227529&r1=1227528&r2=1227529&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/ExpressionNode.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/ExpressionNode.java Thu Jan 5 09:00:27 2012
@@ -97,9 +97,26 @@ public class ExpressionNode extends Proc
return getExpression().getLabel();
}
+ /**
+ * Creates the {@link FilterProcessor} from the expression node.
+ *
+ * @param routeContext the route context
+ * @return the created {@link FilterProcessor}
+ * @throws Exception is thrown if error creating the processor
+ */
protected FilterProcessor createFilterProcessor(RouteContext routeContext) throws Exception {
Processor childProcessor = this.createChildProcessor(routeContext, false);
- return new FilterProcessor(getExpression().createPredicate(routeContext), childProcessor);
+ return new FilterProcessor(createPredicate(routeContext), childProcessor);
+ }
+
+ /**
+ * Creates the {@link Predicate} from the expression node.
+ *
+ * @param routeContext the route context
+ * @return the created predicate
+ */
+ protected Predicate createPredicate(RouteContext routeContext) {
+ return getExpression().createPredicate(routeContext);
}
@Override
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterDefinition.java?rev=1227529&r1=1227528&r2=1227529&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterDefinition.java Thu Jan 5 09:00:27 2012
@@ -61,7 +61,6 @@ public class FilterDefinition extends Ex
return "filter";
}
-
@Override
public FilterProcessor createProcessor(RouteContext routeContext) throws Exception {
return createFilterProcessor(routeContext);
@@ -71,7 +70,7 @@ public class FilterDefinition extends Ex
protected FilterProcessor createFilterProcessor(RouteContext routeContext) throws Exception {
// filter EIP should have child outputs
Processor childProcessor = this.createChildProcessor(routeContext, true);
- return new FilterProcessor(getExpression().createPredicate(routeContext), childProcessor);
+ return new FilterProcessor(createPredicate(routeContext), childProcessor);
}
}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java?rev=1227529&r1=1227528&r2=1227529&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java Thu Jan 5 09:00:27 2012
@@ -87,14 +87,13 @@ public class InterceptSendToEndpointDefi
// register endpoint callback so we can proxy the endpoint
routeContext.getCamelContext().addRegisterEndpointCallback(new EndpointStrategy() {
public Endpoint registerEndpoint(String uri, Endpoint endpoint) {
-
if (endpoint instanceof InterceptSendToEndpoint) {
// endpoint already decorated
return endpoint;
} else if (getUri() == null || EndpointHelper.matchEndpoint(uri, getUri())) {
// only proxy if the uri is matched decorate endpoint with our proxy
// should be false by default
- boolean skip = getSkipSendToOriginalEndpoint() != null ? getSkipSendToOriginalEndpoint() : false;
+ boolean skip = isSkipSendToOriginalEndpoint();
InterceptSendToEndpoint proxy = new InterceptSendToEndpoint(endpoint, skip);
proxy.setDetour(detour);
return proxy;
@@ -153,19 +152,30 @@ public class InterceptSendToEndpointDefi
return;
}
+ // if there is a when definition at first, then its a predicate for this interceptor
ProcessorDefinition first = getOutputs().get(0);
- if (first instanceof WhenDefinition) {
+ if (first instanceof WhenDefinition && !(first instanceof WhenSkipSendToEndpointDefinition)) {
WhenDefinition when = (WhenDefinition) first;
+
+ // create a copy of when to use as replacement
+ WhenSkipSendToEndpointDefinition newWhen = new WhenSkipSendToEndpointDefinition();
+ newWhen.setExpression(when.getExpression());
+ newWhen.setId(when.getId());
+ newWhen.setInheritErrorHandler(when.isInheritErrorHandler());
+ newWhen.setParent(when.getParent());
+ newWhen.setOtherAttributes(when.getOtherAttributes());
+ newWhen.setNodeFactory(when.getNodeFactory());
+ newWhen.setDescription(when.getDescription());
+
// move this outputs to the when, expect the first one
// as the first one is the interceptor itself
for (int i = 1; i < outputs.size(); i++) {
ProcessorDefinition out = outputs.get(i);
- when.addOutput(out);
+ newWhen.addOutput(out);
}
// remove the moved from the original output, by just keeping the first one
- ProcessorDefinition keep = outputs.get(0);
clearOutput();
- outputs.add(keep);
+ outputs.add(newWhen);
}
}
@@ -176,6 +186,10 @@ public class InterceptSendToEndpointDefi
public void setSkipSendToOriginalEndpoint(Boolean skipSendToOriginalEndpoint) {
this.skipSendToOriginalEndpoint = skipSendToOriginalEndpoint;
}
+
+ public boolean isSkipSendToOriginalEndpoint() {
+ return skipSendToOriginalEndpoint != null && skipSendToOriginalEndpoint;
+ }
public String getUri() {
return uri;
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/model/WhenSkipSendToEndpointDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/WhenSkipSendToEndpointDefinition.java?rev=1227529&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/WhenSkipSendToEndpointDefinition.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/WhenSkipSendToEndpointDefinition.java Thu Jan 5 09:00:27 2012
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.model;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.spi.RouteContext;
+
+/**
+ *
+ */
+public class WhenSkipSendToEndpointDefinition extends WhenDefinition {
+
+ @Override
+ protected Predicate createPredicate(RouteContext routeContext) {
+ // we need to keep track whether the when matches or not, so delegate
+ // the predicate and add the matches result as a property on the exchange
+ final Predicate delegate = super.createPredicate(routeContext);
+ return new Predicate() {
+ @Override
+ public boolean matches(Exchange exchange) {
+ boolean matches = delegate.matches(exchange);
+ exchange.setProperty(Exchange.INTERCEPT_SEND_TO_ENDPOINT_WHEN_MATCHED, matches);
+ return matches;
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ };
+ }
+
+}
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/intercept/InterceptSendToEndpointConditionalSkipTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/intercept/InterceptSendToEndpointConditionalSkipTest.java?rev=1227529&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/intercept/InterceptSendToEndpointConditionalSkipTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/intercept/InterceptSendToEndpointConditionalSkipTest.java Thu Jan 5 09:00:27 2012
@@ -0,0 +1,129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor.intercept;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * Unit tests on the conditional skip support on InterceptSendToEndpoint.
+ *
+ * @version
+ */
+public class InterceptSendToEndpointConditionalSkipTest extends ContextTestSupport {
+
+ /**
+ * Verify that the endpoint is only skipped if the adjacent 'when' condition is satisfied
+ */
+ public void testInterceptSendToEndpointSkipConditionSatisfied() throws Exception {
+ getMockEndpoint("mock:a").expectedMessageCount(1);
+ getMockEndpoint("mock:skippable").expectedMessageCount(0);
+ getMockEndpoint("mock:detour").expectedMessageCount(1);
+ getMockEndpoint("mock:c").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "skip");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ /**
+ * Verify that the endpoint is not skipped if the adjacent 'when' condition evaluates to false
+ */
+ public void testInterceptSendToEndpointSkipConditionNotSatisfied() throws Exception {
+ getMockEndpoint("mock:a").expectedMessageCount(1);
+ getMockEndpoint("mock:skippable").expectedMessageCount(1);
+ getMockEndpoint("mock:detour").expectedMessageCount(0);
+ getMockEndpoint("mock:c").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ /**
+ * Verify that the conditional skip support is only activated when using interceptSendToEndpoint().when() and not
+ * interceptSendToEndpoint().choice()..., as the choice keyword is not directly associated with the interception behaviour and it belongs to the
+ * interception body (initiating a new routing block)
+ */
+ public void testInterceptSendToEndpointSkipConditionNoEffectChoice() throws Exception {
+ getMockEndpoint("mock:a").expectedMessageCount(2);
+ getMockEndpoint("mock:skippableNoEffect").expectedMessageCount(0);
+ getMockEndpoint("mock:c").expectedMessageCount(2);
+
+ getMockEndpoint("mock:noSkipWhen").expectedMessageCount(1);
+ getMockEndpoint("mock:noSkipOW").expectedMessageCount(1);
+
+ template.sendBody("direct:startNoEffect", "skipNoEffectWhen");
+ template.sendBody("direct:startNoEffect", "Hello Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ /**
+ * Test that when multiple conditions are chained together in Java DSL, only the first one will determine whether the endpoint is skipped or not
+ */
+ public void testInterceptSendToEndpointSkipMultipleConditions() throws Exception {
+ getMockEndpoint("mock:a").expectedMessageCount(1);
+ getMockEndpoint("mock:skippableMultipleConditions").expectedMessageCount(0);
+ getMockEndpoint("mock:detour").expectedMessageCount(1);
+ getMockEndpoint("mock:c").expectedMessageCount(1);
+
+ template.sendBody("direct:startMultipleConditions", "skip");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ // only skip if the body equals 'skip'
+ interceptSendToEndpoint("mock:skippable").skipSendToOriginalEndpoint()
+ .when(body().isEqualTo("skip")).to("mock:detour");
+
+ // always skip with a normal with a normal choice inside instructing where to route instead
+ interceptSendToEndpoint("mock:skippableNoEffect").skipSendToOriginalEndpoint()
+ .choice()
+ .when(body().isEqualTo("skipNoEffectWhen")).to("mock:noSkipWhen")
+ .otherwise().to("mock:noSkipOW");
+
+ // in this case, the original endpoint will be skipped but no message will be sent to mock:detour
+ interceptSendToEndpoint("mock:skippableMultipleConditions").skipSendToOriginalEndpoint()
+ .when(body().isEqualTo("skip"))
+ .when(body().isNotEqualTo("skip"))
+ .to("mock:detour");
+
+ from("direct:start")
+ .to("mock:a")
+ .to("mock:skippable")
+ .to("mock:c");
+
+ from("direct:startNoEffect")
+ .to("mock:a")
+ .to("mock:skippableNoEffect")
+ .to("mock:c");
+
+ from("direct:startMultipleConditions")
+ .to("mock:a")
+ .to("mock:skippableMultipleConditions")
+ .to("mock:c");
+ }
+ };
+ }
+
+}