Repository: camel Updated Branches: refs/heads/master f686fcb0d -> 0273cd737
CAMEL-8052 Added RemovePropertiesDefinition Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/29ba4c3d Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/29ba4c3d Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/29ba4c3d Branch: refs/heads/master Commit: 29ba4c3da595a6e09e1c93151b671750a14f8eff Parents: f686fcb Author: ancosen <anco...@gmail.com> Authored: Sat Nov 15 16:20:04 2014 +0100 Committer: Willem Jiang <willem.ji...@gmail.com> Committed: Mon Nov 17 12:06:02 2014 +0800 ---------------------------------------------------------------------- .../main/java/org/apache/camel/Exchange.java | 18 ++++ .../apache/camel/builder/ProcessorBuilder.java | 32 ++++++ .../org/apache/camel/impl/DefaultExchange.java | 34 ++++++ .../apache/camel/model/ProcessorDefinition.java | 27 +++++ .../camel/model/RemovePropertiesDefinition.java | 106 +++++++++++++++++++ .../resources/org/apache/camel/model/jaxb.index | 1 + .../apache/camel/impl/DefaultExchangeTest.java | 70 ++++++++++++ .../RemovePropertiesWithExclusionTest.java | 85 +++++++++++++++ .../RemovePropertiesWithoutExclusionTest.java | 79 ++++++++++++++ 9 files changed, 452 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/main/java/org/apache/camel/Exchange.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/Exchange.java b/camel-core/src/main/java/org/apache/camel/Exchange.java index a33253a..d8e5a4c 100644 --- a/camel-core/src/main/java/org/apache/camel/Exchange.java +++ b/camel-core/src/main/java/org/apache/camel/Exchange.java @@ -532,5 +532,23 @@ public interface Exchange { * @return the on completions */ List<Synchronization> handoverCompletions(); + + /** + * Remove all of the properties associated with the exchange matching a specific pattern + * + * @param pattern pattern of names + * @return boolean whether any properties matched + */ + boolean removeProperties(String pattern); + + /** + * Removes the properties from this exchange that match the given <tt>pattern</tt>, + * except for the ones matching one ore more <tt>excludePatterns</tt> + * + * @param pattern pattern of names that should be removed + * @param excludePatterns one or more pattern of properties names that should be excluded (= preserved) + * @return boolean whether any properties matched + */ + boolean removeProperties(String pattern, String... excludePatterns); } http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/main/java/org/apache/camel/builder/ProcessorBuilder.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/builder/ProcessorBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/ProcessorBuilder.java index b909f99..f246f92 100644 --- a/camel-core/src/main/java/org/apache/camel/builder/ProcessorBuilder.java +++ b/camel-core/src/main/java/org/apache/camel/builder/ProcessorBuilder.java @@ -264,6 +264,38 @@ public final class ProcessorBuilder { } }; } + + /** + * Removes the properties on the exchange + */ + public static Processor removeProperties(final String pattern) { + return new Processor() { + public void process(Exchange exchange) { + exchange.removeProperties(pattern); + } + + @Override + public String toString() { + return "removeProperties(" + pattern + ")"; + } + }; + } + + /** + * Removes all properties on the exchange, except for the ones provided in the <tt>names</tt> parameter + */ + public static Processor removeProperties(final String pattern, final String... exceptionPatterns) { + return new Processor() { + public void process(Exchange exchange) { + exchange.removeProperties(pattern, exceptionPatterns); + } + + @Override + public String toString() { + return "removeProperties(" + pattern + ", " + Arrays.toString(exceptionPatterns) + ")"; + } + }; + } /** * Throws an exception http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java index 164ae67..513546d 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java @@ -29,6 +29,7 @@ import org.apache.camel.Message; import org.apache.camel.MessageHistory; import org.apache.camel.spi.Synchronization; import org.apache.camel.spi.UnitOfWork; +import org.apache.camel.util.EndpointHelper; import org.apache.camel.util.ExchangeHelper; import org.apache.camel.util.ObjectHelper; @@ -187,6 +188,30 @@ public final class DefaultExchange implements Exchange { } return getProperties().remove(name); } + + public boolean removeProperties(String pattern) { + return removeProperties(pattern, (String[]) null); + } + + public boolean removeProperties(String pattern, String... excludePatterns) { + if (!hasProperties()) { + return false; + } + + boolean matches = false; + for (Map.Entry<String, Object> entry : properties.entrySet()) { + String key = entry.getKey(); + if (EndpointHelper.matchPattern(key, pattern)) { + if (excludePatterns != null && isExcludePatternMatch(key, excludePatterns)) { + continue; + } + matches = true; + properties.remove(entry.getKey()); + } + + } + return matches; + } public Map<String, Object> getProperties() { if (properties == null) { @@ -450,4 +475,13 @@ public final class DefaultExchange implements Exchange { } return answer; } + + private static boolean isExcludePatternMatch(String key, String... excludePatterns) { + for (String pattern : excludePatterns) { + if (EndpointHelper.matchPattern(key, pattern)) { + return true; + } + } + return false; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java index a6a8457..cf37350 100644 --- a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java @@ -2873,6 +2873,33 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type> addOutput(answer); return (Type) this; } + + /** + * Adds a processor which removes the properties in the exchange + * + * @param pattern a pattern to match properties names to be removed + * @return the builder + */ + @SuppressWarnings("unchecked") + public Type removeProperties(String pattern) { + RemovePropertiesDefinition answer = new RemovePropertiesDefinition(pattern); + addOutput(answer); + return (Type) this; + } + + /** + * Adds a processor which removes the properties in the exchange + * + * @param pattern a pattern to match properties names to be removed + * @param excludePatterns one or more pattern of properties names that should be excluded (= preserved) + * @return the builder + */ + @SuppressWarnings("unchecked") + public Type removeProperties(String pattern, String... excludePatterns) { + RemovePropertiesDefinition answer = new RemovePropertiesDefinition(pattern, excludePatterns); + addOutput(answer); + return (Type) this; + } /** * Converts the IN message body to the specified type http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/main/java/org/apache/camel/model/RemovePropertiesDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/RemovePropertiesDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RemovePropertiesDefinition.java new file mode 100644 index 0000000..8480447 --- /dev/null +++ b/camel-core/src/main/java/org/apache/camel/model/RemovePropertiesDefinition.java @@ -0,0 +1,106 @@ +/** + * 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 javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + +import org.apache.camel.Processor; +import org.apache.camel.builder.ProcessorBuilder; +import org.apache.camel.spi.RouteContext; +import org.apache.camel.util.ObjectHelper; + +/** + * Represents an XML <removeProperties/> element + */ +@XmlRootElement(name = "removeProperties") +@XmlAccessorType(XmlAccessType.FIELD) +public class RemovePropertiesDefinition extends NoOutputDefinition<RemovePropertiesDefinition> { + @XmlAttribute(required = true) + private String pattern; + @XmlAttribute + private String excludePattern; + // in XML we cannot use String[] for attributes, so we provide a single attribute instead + @XmlTransient + private String[] excludePatterns; + + public RemovePropertiesDefinition() { + } + + public RemovePropertiesDefinition(String pattern) { + setPattern(pattern); + } + + public RemovePropertiesDefinition(String pattern, String... excludePatterns) { + setPattern(pattern); + setExcludePatterns(excludePatterns); + } + + @Override + public String toString() { + return "removeProperties[" + getPattern() + "]"; + } + + @Override + public String getShortName() { + return "removeProperties"; + } + + @Override + public String getLabel() { + return "removeProperties[" + getPattern() + "]"; + } + + @Override + public Processor createProcessor(RouteContext routeContext) throws Exception { + ObjectHelper.notNull(getPattern(), "patterns", this); + if (getExcludePatterns() != null) { + return ProcessorBuilder.removeProperties(getPattern(), getExcludePatterns()); + } else if (getExcludePattern() != null) { + return ProcessorBuilder.removeProperties(getPattern(), getExcludePattern()); + } else { + return ProcessorBuilder.removeProperties(getPattern()); + } + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String getPattern() { + return pattern; + } + + public String[] getExcludePatterns() { + return excludePatterns; + } + + public void setExcludePatterns(String[] excludePatterns) { + this.excludePatterns = excludePatterns; + } + + public String getExcludePattern() { + return excludePattern; + } + + public void setExcludePattern(String excludePattern) { + this.excludePattern = excludePattern; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/main/resources/org/apache/camel/model/jaxb.index ---------------------------------------------------------------------- diff --git a/camel-core/src/main/resources/org/apache/camel/model/jaxb.index b/camel-core/src/main/resources/org/apache/camel/model/jaxb.index index ea0d2b9..7e47451 100644 --- a/camel-core/src/main/resources/org/apache/camel/model/jaxb.index +++ b/camel-core/src/main/resources/org/apache/camel/model/jaxb.index @@ -58,6 +58,7 @@ RedeliveryPolicyDefinition RemoveHeaderDefinition RemoveHeadersDefinition RemovePropertyDefinition +RemovePropertiesDefinition ResequenceDefinition RestContextRefDefinition RollbackDefinition http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java index 87e858a..cd6fd7e 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java @@ -120,6 +120,76 @@ public class DefaultExchangeTest extends ExchangeTestSupport { assertEquals("banana", exchange.getProperty("beer", "banana")); assertEquals("banana", exchange.getProperty("beer", "banana", String.class)); } + + public void testRemoveProperties() throws Exception { + exchange.removeProperty("foobar"); + assertFalse(exchange.hasProperties()); + + exchange.setProperty("fruit", "apple"); + exchange.setProperty("fruit1", "banana"); + exchange.setProperty("zone", "Africa"); + assertTrue(exchange.hasProperties()); + + assertEquals("apple", exchange.getProperty("fruit")); + assertEquals("banana", exchange.getProperty("fruit1")); + assertEquals("Africa", exchange.getProperty("zone")); + + exchange.removeProperties("fr*"); + assertTrue(exchange.hasProperties()); + assertEquals(exchange.getProperties().size(), 1); + assertEquals(null, exchange.getProperty("fruit", String.class)); + assertEquals(null, exchange.getProperty("fruit1", String.class)); + assertEquals("Africa", exchange.getProperty("zone", String.class)); + } + + public void testRemovePropertiesWithExclusion() throws Exception { + exchange.removeProperty("foobar"); + assertFalse(exchange.hasProperties()); + + exchange.setProperty("fruit", "apple"); + exchange.setProperty("fruit1", "banana"); + exchange.setProperty("fruit2", "peach"); + exchange.setProperty("zone", "Africa"); + assertTrue(exchange.hasProperties()); + + assertEquals("apple", exchange.getProperty("fruit")); + assertEquals("banana", exchange.getProperty("fruit1")); + assertEquals("peach", exchange.getProperty("fruit2")); + assertEquals("Africa", exchange.getProperty("zone")); + + exchange.removeProperties("fr*","fruit1","fruit2"); + assertTrue(exchange.hasProperties()); + assertEquals(exchange.getProperties().size(), 3); + assertEquals(null, exchange.getProperty("fruit", String.class)); + assertEquals("banana", exchange.getProperty("fruit1", String.class)); + assertEquals("peach", exchange.getProperty("fruit2", String.class)); + assertEquals("Africa", exchange.getProperty("zone", String.class)); + } + + public void testRemovePropertiesPatternWithAllExcluded() throws Exception { + exchange.removeProperty("foobar"); + assertFalse(exchange.hasProperties()); + + exchange.setProperty("fruit", "apple"); + exchange.setProperty("fruit1", "banana"); + exchange.setProperty("fruit2", "peach"); + exchange.setProperty("zone", "Africa"); + assertTrue(exchange.hasProperties()); + + assertEquals("apple", exchange.getProperty("fruit")); + assertEquals("banana", exchange.getProperty("fruit1")); + assertEquals("peach", exchange.getProperty("fruit2")); + assertEquals("Africa", exchange.getProperty("zone")); + + exchange.removeProperties("fr*","fruit","fruit1","fruit2","zone"); + assertTrue(exchange.hasProperties()); + assertEquals(exchange.getProperties().size(), 4); + assertEquals("apple", exchange.getProperty("fruit", String.class)); + assertEquals("banana", exchange.getProperty("fruit1", String.class)); + assertEquals("peach", exchange.getProperty("fruit2", String.class)); + assertEquals("Africa", exchange.getProperty("zone", String.class)); + } + public void testInType() throws Exception { exchange.setIn(new MyMessage()); http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithExclusionTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithExclusionTest.java b/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithExclusionTest.java new file mode 100644 index 0000000..058681c --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithExclusionTest.java @@ -0,0 +1,85 @@ +/** + * 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; + +import java.util.List; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; + +public class RemovePropertiesWithExclusionTest extends ContextTestSupport { + private MockEndpoint end; + private MockEndpoint mid; + private String propertyName = "foo"; + private String expectedPropertyValue = "bar"; + private String propertyName1 = "fee"; + private String expectedPropertyValue1 = "bar1"; + private String propertyName2 = "fiu"; + private String expectedPropertyValue2 = "bar2"; + private String pattern = "f*"; + private String exclusion = "fiu"; + + public void testSetExchangePropertiesMidRouteThenRemoveWithPatternAndExclusion() throws Exception { + mid.expectedMessageCount(1); + end.expectedMessageCount(1); + + template.sendBody("direct:start", "message"); + + // make sure we got the message + assertMockEndpointsSatisfied(); + + List<Exchange> midExchanges = mid.getExchanges(); + Exchange midExchange = midExchanges.get(0); + String actualPropertyValue = midExchange.getProperty(propertyName, String.class); + String actualPropertyValue1 = midExchange.getProperty(propertyName1, String.class); + String actualPropertyValue2 = midExchange.getProperty(propertyName2, String.class); + + assertEquals(expectedPropertyValue, actualPropertyValue); + assertEquals(expectedPropertyValue1, actualPropertyValue1); + assertEquals(expectedPropertyValue2, actualPropertyValue2); + + List<Exchange> endExchanges = end.getExchanges(); + Exchange endExchange = endExchanges.get(0); + + // property should be removed + assertNull(endExchange.getProperty(propertyName, String.class)); + assertNull(endExchange.getProperty(propertyName1, String.class)); + assertEquals(expectedPropertyValue2, endExchange.getProperty(propertyName2, String.class)); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + end = getMockEndpoint("mock:end"); + mid = getMockEndpoint("mock:mid"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start"). + setProperty(propertyName).constant(expectedPropertyValue) + .setProperty(propertyName1).constant(expectedPropertyValue1) + .setProperty(propertyName2).constant(expectedPropertyValue2).to("mock:mid"). + removeProperties(pattern,exclusion).to("mock:end"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/29ba4c3d/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithoutExclusionTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithoutExclusionTest.java b/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithoutExclusionTest.java new file mode 100644 index 0000000..698d7b1 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/processor/RemovePropertiesWithoutExclusionTest.java @@ -0,0 +1,79 @@ +/** + * 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; + +import java.util.List; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; + +public class RemovePropertiesWithoutExclusionTest extends ContextTestSupport { + private MockEndpoint end; + private MockEndpoint mid; + private String propertyName = "foo"; + private String expectedPropertyValue = "bar"; + private String propertyName1 = "fee"; + private String expectedPropertyValue1 = "bar1"; + private String pattern = "f*"; + + public void testSetExchangePropertiesMidRouteThenRemoveWithPattern() throws Exception { + mid.expectedMessageCount(1); + end.expectedMessageCount(1); + + template.sendBody("direct:start", "message"); + + // make sure we got the message + assertMockEndpointsSatisfied(); + + List<Exchange> midExchanges = mid.getExchanges(); + Exchange midExchange = midExchanges.get(0); + String actualPropertyValue = midExchange.getProperty(propertyName, String.class); + String actualPropertyValue1 = midExchange.getProperty(propertyName1, String.class); + + assertEquals(expectedPropertyValue, actualPropertyValue); + assertEquals(expectedPropertyValue1, actualPropertyValue1); + + List<Exchange> endExchanges = end.getExchanges(); + Exchange endExchange = endExchanges.get(0); + + // property should be removed + assertNull(endExchange.getProperty(propertyName, String.class)); + assertNull(endExchange.getProperty(propertyName1, String.class)); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + end = getMockEndpoint("mock:end"); + mid = getMockEndpoint("mock:mid"); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("direct:start"). + setProperty(propertyName).constant(expectedPropertyValue) + .setProperty(propertyName1).constant(expectedPropertyValue1) + .to("mock:mid"). + removeProperties(pattern).to("mock:end"); + } + }; + } +}