INT-3581: Support selector-expression on WireTap
JIRA: https://jira.spring.io/browse/INT-3581 Move schemas to 4.2. Add `selector-expression` to `<wire-tap/>`. INT-3781: Fix What's New Bump Namespace Version to 4.2
This commit is contained in:
@@ -44,7 +44,7 @@ public abstract class AbstractIntegrationNamespaceHandler implements NamespaceHa
|
||||
|
||||
protected final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private static final String VERSION = "4.1";
|
||||
private static final String VERSION = "4.2";
|
||||
|
||||
private final NamespaceHandlerDelegate delegate = new NamespaceHandlerDelegate();
|
||||
|
||||
|
||||
@@ -20,16 +20,21 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.channel.interceptor.WireTap;
|
||||
import org.springframework.integration.config.ExpressionFactoryBean;
|
||||
import org.springframework.integration.filter.ExpressionEvaluatingSelector;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <wire-tap> element.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
*/
|
||||
public class WireTapParser implements BeanDefinitionRegisteringParser {
|
||||
|
||||
@Override
|
||||
public String parse(Element element, ParserContext parserContext) {
|
||||
Object source = parserContext.extractSource(element);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(WireTap.class);
|
||||
String targetRef = element.getAttribute("channel");
|
||||
if (!StringUtils.hasText(targetRef)) {
|
||||
@@ -37,9 +42,21 @@ public class WireTapParser implements BeanDefinitionRegisteringParser {
|
||||
}
|
||||
builder.addConstructorArgReference(targetRef);
|
||||
String selectorRef = element.getAttribute("selector");
|
||||
String selectorExpression = element.getAttribute("selector-expression");
|
||||
if (StringUtils.hasText(selectorRef) && StringUtils.hasText(selectorExpression)) {
|
||||
parserContext.getReaderContext().error("Only one of 'selector' or 'selector-expression' is allowed", source);
|
||||
}
|
||||
if (StringUtils.hasText(selectorRef)) {
|
||||
builder.addConstructorArgReference(selectorRef);
|
||||
}
|
||||
else if (StringUtils.hasText(selectorExpression)) {
|
||||
BeanDefinitionBuilder expressionBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(ExpressionFactoryBean.class);
|
||||
expressionBuilder.addConstructorArgValue(selectorExpression);
|
||||
BeanDefinitionBuilder eemsBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExpressionEvaluatingSelector.class);
|
||||
eemsBuilder.addConstructorArgValue(expressionBuilder.getBeanDefinition());
|
||||
builder.addConstructorArgValue(eemsBuilder.getBeanDefinition());
|
||||
}
|
||||
String timeout = element.getAttribute("timeout");
|
||||
if (StringUtils.hasText(timeout)) {
|
||||
builder.addPropertyValue("timeout", Long.parseLong(timeout));
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
http\://www.springframework.org/schema/integration/spring-integration-4.1.xsd=org/springframework/integration/config/xml/spring-integration-4.1.xsd
|
||||
http\://www.springframework.org/schema/integration/spring-integration.xsd=org/springframework/integration/config/xml/spring-integration-4.1.xsd
|
||||
http\://www.springframework.org/schema/integration/spring-integration-4.2.xsd=org/springframework/integration/config/xml/spring-integration-4.2.xsd
|
||||
http\://www.springframework.org/schema/integration/spring-integration.xsd=org/springframework/integration/config/xml/spring-integration-4.2.xsd
|
||||
|
||||
@@ -3749,7 +3749,15 @@
|
||||
<xsd:documentation>
|
||||
A reference to a bean in the Application Context
|
||||
which implements MessageSelector that must accept a message for it to be
|
||||
sent to the intercepting channel
|
||||
sent to the intercepting channel. Mutually exclusive with 'selector-expression'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="selector-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
A boolean expression evaluated against the message to determine whether it should
|
||||
sent to the intercepting channel. Mutually exclusive with 'selector'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -21,7 +21,7 @@
|
||||
<channel id="withId">
|
||||
<queue capacity="10"/>
|
||||
<interceptors>
|
||||
<wire-tap id="wireTap" channel="wireTapChannel"/>
|
||||
<wire-tap id="wireTap" channel="wireTapChannel" selector-expression="@booleanTrue" />
|
||||
</interceptors>
|
||||
</channel>
|
||||
|
||||
@@ -54,4 +54,8 @@
|
||||
<beans:constructor-arg value="false"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="booleanTrue" class="java.lang.Boolean">
|
||||
<beans:constructor-arg value="true" />
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,58 +16,84 @@
|
||||
|
||||
package org.springframework.integration.config;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.interceptor.WireTap;
|
||||
import org.springframework.integration.filter.ExpressionEvaluatingSelector;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.integration.channel.interceptor.WireTap;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class WireTapParserTests {
|
||||
|
||||
@Autowired
|
||||
MessageChannel noSelectors;
|
||||
|
||||
@Autowired
|
||||
MessageChannel accepting;
|
||||
|
||||
@Autowired
|
||||
MessageChannel rejecting;
|
||||
|
||||
@Autowired
|
||||
MessageChannel withId;
|
||||
|
||||
@Autowired
|
||||
PollableChannel wireTapChannel;
|
||||
|
||||
@Autowired @Qualifier("wireTap")
|
||||
WireTap wireTap;
|
||||
|
||||
@Autowired
|
||||
List<WireTap> wireTaps;
|
||||
|
||||
@Test
|
||||
public void simpleWireTap() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"wireTapParserTests.xml", this.getClass());
|
||||
MessageChannel mainChannel = (MessageChannel) context.getBean("noSelectors");
|
||||
PollableChannel wireTapChannel = (PollableChannel) context.getBean("wireTapChannel");
|
||||
assertNull(wireTapChannel.receive(0));
|
||||
Message<?> original = new GenericMessage<String>("test");
|
||||
mainChannel.send(original);
|
||||
noSelectors.send(original);
|
||||
Message<?> intercepted = wireTapChannel.receive(0);
|
||||
assertNotNull(intercepted);
|
||||
assertEquals(original, intercepted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleWireTapWithId() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"wireTapParserTests.xml", this.getClass());
|
||||
WireTap wireTap = (WireTap) context.getBean("wireTap");
|
||||
assertNotNull(wireTap);
|
||||
public void simpleWireTapWithIdAndSelectorExpression() {
|
||||
assertThat(TestUtils.getPropertyValue(wireTap, "selector"), instanceOf(ExpressionEvaluatingSelector.class));
|
||||
Message<?> original = new GenericMessage<String>("test");
|
||||
withId.send(original);
|
||||
Message<?> intercepted = wireTapChannel.receive(0);
|
||||
assertNotNull(intercepted);
|
||||
assertEquals(original, intercepted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wireTapWithAcceptingSelector() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"wireTapParserTests.xml", this.getClass());
|
||||
MessageChannel mainChannel = (MessageChannel) context.getBean("accepting");
|
||||
PollableChannel wireTapChannel = (PollableChannel) context.getBean("wireTapChannel");
|
||||
assertNull(wireTapChannel.receive(0));
|
||||
Message<?> original = new GenericMessage<String>("test");
|
||||
mainChannel.send(original);
|
||||
accepting.send(original);
|
||||
Message<?> intercepted = wireTapChannel.receive(0);
|
||||
assertNotNull(intercepted);
|
||||
assertEquals(original, intercepted);
|
||||
@@ -75,26 +101,19 @@ public class WireTapParserTests {
|
||||
|
||||
@Test
|
||||
public void wireTapWithRejectingSelector() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"wireTapParserTests.xml", this.getClass());
|
||||
MessageChannel mainChannel = (MessageChannel) context.getBean("rejecting");
|
||||
PollableChannel wireTapChannel = (PollableChannel) context.getBean("wireTapChannel");
|
||||
assertNull(wireTapChannel.receive(0));
|
||||
Message<?> original = new GenericMessage<String>("test");
|
||||
mainChannel.send(original);
|
||||
rejecting.send(original);
|
||||
Message<?> intercepted = wireTapChannel.receive(0);
|
||||
assertNull(intercepted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wireTapTimeouts() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"wireTapParserTests.xml", this.getClass());
|
||||
Map<String, WireTap> beans = context.getBeansOfType(WireTap.class);
|
||||
int defaultTimeoutCount = 0;
|
||||
int expectedTimeoutCount = 0;
|
||||
int otherTimeoutCount = 0;
|
||||
for (WireTap wireTap : beans.values()) {
|
||||
for (WireTap wireTap : wireTaps) {
|
||||
long timeout = ((Long) new DirectFieldAccessor(wireTap).getPropertyValue("timeout")).longValue();
|
||||
if (timeout == 0) {
|
||||
defaultTimeoutCount++;
|
||||
|
||||
Reference in New Issue
Block a user