INT-1505 added support for a 'payload-expression' attribute on the inbound ApplicationEvent Channel Adapter
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
#Wed Sep 22 11:50:06 EDT 2010
|
||||
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/integration\:/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1040" endstart\="1026" start\="985" startend\="1009"/>\n<bounds height\="112" width\="116" x\="19" y\="17"/>\n</element>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1508" endstart\="1494" start\="1445" startend\="1477"/>\n<bounds height\="112" width\="116" x\="19" y\="149"/>\n</element>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1731" endstart\="1717" start\="1657" startend\="1700"/>\n<bounds height\="112" width\="116" x\="19" y\="281"/>\n</element>\n</graph>
|
||||
#Fri Oct 08 14:30:53 EDT 2010
|
||||
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/integration\:/spring-integration-event/src/test/java/org/springframework/integration/event/config/EventInboundChannelAdapterParserTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element clazz\="InboundChannelAdapterModelElement" type\="inbound-channel-adapter">\n<structure end\="982" endstart\="982" start\="906" startend\="982"/>\n<bounds height\="112" width\="116" x\="19" y\="17"/>\n</element>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1040" endstart\="1026" start\="985" startend\="1009"/>\n<bounds height\="112" width\="116" x\="155" y\="17"/>\n</element>\n<element clazz\="InboundChannelAdapterModelElement" type\="inbound-channel-adapter">\n<structure end\="1442" endstart\="1442" start\="1044" startend\="1442"/>\n<bounds height\="112" width\="116" x\="19" y\="149"/>\n</element>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1508" endstart\="1494" start\="1445" startend\="1477"/>\n<bounds height\="112" width\="116" x\="155" y\="149"/>\n</element>\n<element clazz\="InboundChannelAdapterModelElement" type\="inbound-channel-adapter">\n<structure end\="1654" endstart\="1654" start\="1512" startend\="1654"/>\n<bounds height\="112" width\="116" x\="19" y\="281"/>\n</element>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1731" endstart\="1717" start\="1657" startend\="1700"/>\n<bounds height\="112" width\="116" x\="155" y\="281"/>\n</element>\n<element clazz\="InboundChannelAdapterModelElement" type\="inbound-channel-adapter">\n<structure end\="1850" endstart\="1850" start\="1734" startend\="1850"/>\n<bounds height\="112" width\="116" x\="19" y\="413"/>\n</element>\n<element clazz\="ChannelModelElement" type\="channel">\n<structure end\="1912" endstart\="1898" start\="1853" startend\="1881"/>\n<bounds height\="112" width\="116" x\="155" y\="413"/>\n</element>\n</graph>
|
||||
eclipse.preferences.version=1
|
||||
|
||||
@@ -21,14 +21,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.integration.endpoint.MessageProducerSupport;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* An inbound Channel Adapter that passes Spring
|
||||
* {@link ApplicationEvent ApplicationEvents} within messages.
|
||||
* An inbound Channel Adapter that passes Spring {@link ApplicationEvent ApplicationEvents} within messages.
|
||||
* If a {@link #setPayloadExpression(String) payloadExpression} is provided, it will be evaluated against
|
||||
* the ApplicationEvent instance to create the Message payload.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@@ -36,6 +39,10 @@ public class ApplicationEventInboundChannelAdapter extends MessageProducerSuppor
|
||||
|
||||
private final Set<Class<? extends ApplicationEvent>> eventTypes = new CopyOnWriteArraySet<Class<? extends ApplicationEvent>>();
|
||||
|
||||
private volatile Expression payloadExpression;
|
||||
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
|
||||
/**
|
||||
* Set the list of event types (classes that extend ApplicationEvent) that
|
||||
@@ -51,6 +58,24 @@ public class ApplicationEventInboundChannelAdapter extends MessageProducerSuppor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an expression to be evaluated against the received ApplicationEvent
|
||||
* instance (the "root object") in order to create the Message payload. If none
|
||||
* is provided, the ApplicationEvent itself will be used as the payload.
|
||||
*/
|
||||
public void setPayloadExpression(String payloadExpression) {
|
||||
if (payloadExpression == null) {
|
||||
this.payloadExpression = null;
|
||||
}
|
||||
else {
|
||||
this.payloadExpression = this.parser.parseExpression(payloadExpression);
|
||||
}
|
||||
}
|
||||
|
||||
public String getComponentType() {
|
||||
return "event:inbound-channel-adapter";
|
||||
}
|
||||
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (CollectionUtils.isEmpty(this.eventTypes)) {
|
||||
this.sendEventAsMessage(event);
|
||||
@@ -65,11 +90,8 @@ public class ApplicationEventInboundChannelAdapter extends MessageProducerSuppor
|
||||
}
|
||||
|
||||
private void sendEventAsMessage(ApplicationEvent event) {
|
||||
this.sendMessage(MessageBuilder.withPayload(event).build());
|
||||
}
|
||||
|
||||
public String getComponentType(){
|
||||
return "event:inbound-channel-adapter";
|
||||
Object payload = (this.payloadExpression != null) ? this.payloadExpression.getValue(event) : event;
|
||||
this.sendMessage(MessageBuilder.withPayload(payload).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.event.config;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
@@ -30,11 +31,11 @@ import org.w3c.dom.Element;
|
||||
public class EventInboundChannelAdapterParser extends AbstractChannelAdapterParser{
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition doParse(Element element,
|
||||
ParserContext parserContext, String channelName) {
|
||||
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
|
||||
BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.rootBeanDefinition(ApplicationEventInboundChannelAdapter.class);
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "channel", "outputChannel");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "event-types");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "payload-expression");
|
||||
return adapterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,15 @@
|
||||
types will be sent [OPTIONAL]
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="payload-expression">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
SpEL expression to be evaluated against the ApplicationEvent to create the payload instance.
|
||||
If not provided, the ApplicationEvent itself will be used as the payload.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -53,8 +53,8 @@ public class ApplicationEventInboundChannelAdapterTests {
|
||||
assertEquals("event2", ((ApplicationEvent) message3.getPayload()).getSource());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onlyConfiguredEventTypesAreSent() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
ApplicationEventInboundChannelAdapter adapter = new ApplicationEventInboundChannelAdapter();
|
||||
@@ -93,6 +93,24 @@ public class ApplicationEventInboundChannelAdapterTests {
|
||||
assertEquals(ContextClosedEvent.class, closedEventMessage.getPayload().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadExpressionEvaluatedAgainstApplicationEvent() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
ApplicationEventInboundChannelAdapter adapter = new ApplicationEventInboundChannelAdapter();
|
||||
adapter.setPayloadExpression("'received: ' + source");
|
||||
adapter.setOutputChannel(channel);
|
||||
Message<?> message1 = channel.receive(0);
|
||||
assertNull(message1);
|
||||
adapter.onApplicationEvent(new TestApplicationEvent1());
|
||||
adapter.onApplicationEvent(new TestApplicationEvent2());
|
||||
Message<?> message2 = channel.receive(20);
|
||||
assertNotNull(message2);
|
||||
assertEquals("received: event1", message2.getPayload());
|
||||
Message<?> message3 = channel.receive(20);
|
||||
assertNotNull(message3);
|
||||
assertEquals("received: event2", message3.getPayload());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class TestApplicationEvent1 extends ApplicationEvent {
|
||||
@@ -100,6 +118,8 @@ public class ApplicationEventInboundChannelAdapterTests {
|
||||
public TestApplicationEvent1() {
|
||||
super("event1");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,13 @@
|
||||
<int:channel id="inputFilteredPlaceHolder">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
|
||||
<int-event:inbound-channel-adapter id="eventAdapterSpel" channel="inputSpel" payload-expression="source + '-test'"/>
|
||||
|
||||
<int:channel id="inputSpel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<context:property-placeholder location="classpath:org/springframework/integration/event/config/inbound-adapter.properties"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
import org.springframework.integration.event.ApplicationEventInboundChannelAdapter;
|
||||
@@ -62,9 +63,9 @@ public class EventInboundChannelAdapterParserTests {
|
||||
DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter);
|
||||
Assert.assertEquals(context.getBean("input"), adapterAccessor.getPropertyValue("outputChannel"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void validateEventParserWithEventTypes() {
|
||||
Object adapter = context.getBean("eventAdapterFiltered");
|
||||
Assert.assertNotNull(adapter);
|
||||
@@ -77,9 +78,9 @@ public class EventInboundChannelAdapterParserTests {
|
||||
assertTrue(eventTypes.contains(SampleEvent.class));
|
||||
assertTrue(eventTypes.contains(AnotherSampleEvent.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void validateEventParserWithEventTypesAndPlaceholder() {
|
||||
Object adapter = context.getBean("eventAdapterFilteredPlaceHolder");
|
||||
Assert.assertNotNull(adapter);
|
||||
@@ -108,6 +109,16 @@ public class EventInboundChannelAdapterParserTests {
|
||||
assertEquals(SampleEvent.class, message.getPayload().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validatePayloadExpression() {
|
||||
Object adapter = context.getBean("eventAdapterSpel");
|
||||
Assert.assertNotNull(adapter);
|
||||
Assert.assertTrue(adapter instanceof ApplicationEventInboundChannelAdapter);
|
||||
DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter);
|
||||
Expression expression = (Expression) adapterAccessor.getPropertyValue("payloadExpression");
|
||||
Assert.assertEquals("source + '-test'", expression.getExpressionString());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class SampleEvent extends ApplicationEvent {
|
||||
|
||||
Reference in New Issue
Block a user