INT-2404 Fix Auto-Created Channel; Event, TCP, UDP

The AbstractChannelAdapterParser creates an implicit DirectChannel
if the adapter has no 'channel' attribute.

The Event, TCP, and UDP channel adapter parsers did not bind
this channel to the adapter and AC initialization failed with
'outputChannel is required'.

Further, the event schema marked the channel as being 'required',
precluding this feature.

INT-2407 Remove Channel use="required"

Parsers automatically generate the channel when none is provided.

- JMX
- JDBC
- SFTP
- Redis
- Feed
- XMPP
- Mail
- FTP
- HTTP
This commit is contained in:
Gary Russell
2012-01-17 09:23:35 -05:00
committed by Mark Fisher
parent e7b514a1e4
commit 292aa90599
47 changed files with 457 additions and 130 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer;
/**
* @author Oleg Zhurakousky
@@ -34,9 +35,9 @@ public class EventInboundChannelAdapterParser extends AbstractChannelAdapterPars
@Override
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "channel", "outputChannel");
BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(ApplicationEventListeningMessageProducer.class);
adapterBuilder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(adapterBuilder, element, "error-channel", "errorChannel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "event-types");
IntegrationNamespaceUtils.setValueIfAttributeDefined(adapterBuilder, element, "payload-expression");

View File

@@ -25,7 +25,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:ID" use="optional" />
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -25,7 +25,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional" />
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -38,6 +38,10 @@
<int:queue/>
</int:channel>
<int-event:inbound-channel-adapter id="autoChannel" payload-expression="source + '-test'"/>
<int:bridge input-channel="autoChannel" output-channel="nullChannel"/>
<context:property-placeholder location="classpath:org/springframework/integration/event/config/inbound-adapter.properties"/>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -19,6 +19,7 @@ package org.springframework.integration.event.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.Properties;
@@ -31,6 +32,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
@@ -60,6 +62,12 @@ public class EventInboundChannelAdapterParserTests {
@Autowired
MessageChannel errorChannel;
@Autowired
MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
ApplicationEventListeningMessageProducer eventListener;
@Test
public void validateEventParser() {
Object adapter = context.getBean("eventAdapterSimple");
@@ -126,6 +134,10 @@ public class EventInboundChannelAdapterParserTests {
Assert.assertEquals("source + '-test'", expression.getExpressionString());
}
@Test
public void testAutoCreateChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(eventListener, "outputChannel"));
}
@SuppressWarnings("serial")
public static class SampleEvent extends ApplicationEvent {

View File

@@ -30,7 +30,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" use="required" type="xsd:string">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:feed="http://www.springframework.org/schema/integration/feed"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/feed http://www.springframework.org/schema/integration/feed/spring-integration-feed.xsd">
<feed:inbound-channel-adapter id="autoChannel"
auto-startup="false"
url="file:dummy.rss">
<int:poller fixed-rate="10000" max-messages-per-poll="100" />
</feed:inbound-channel-adapter>
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -18,6 +18,7 @@ package org.springframework.integration.feed.config;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -36,6 +37,7 @@ import org.mockito.Mockito;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageHandler;
@@ -52,6 +54,7 @@ import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
*/
public class FeedInboundChannelAdapterParserTests {
@@ -154,6 +157,15 @@ public class FeedInboundChannelAdapterParserTests {
verify(handler, atLeast(3)).handleMessage(Mockito.any(Message.class));
}
@Test
public void testAutoChannel() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"FeedInboundChannelAdapterParserTests-autoChannel-context.xml", this.getClass());
MessageChannel autoChannel = context.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter adapter = context.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(adapter, "outputChannel"));
context.destroy();
}
public static class SampleService {

View File

@@ -388,7 +388,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" use="required" type="xsd:string">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -60,4 +60,13 @@
<constructor-arg value="org.springframework.integration.file.filters.FileListFilter"/>
</bean>
<int-ftp:inbound-channel-adapter id="autoChannel"
session-factory="ftpSessionFactory"
local-directory="."
remote-directory="foo/bar">
<int:poller fixed-rate="1000"/>
</int-ftp:inbound-channel-adapter>
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -20,6 +20,7 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -33,6 +34,7 @@ import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.Session;
@@ -45,6 +47,7 @@ import org.springframework.integration.test.util.TestUtils;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author Gary Russell
*/
public class FtpInboundChannelAdapterParserTests {
@@ -105,6 +108,15 @@ public class FtpInboundChannelAdapterParserTests {
assertNotNull(adapter);
}
@Test
public void testAutoChannel() {
ApplicationContext context =
new ClassPathXmlApplicationContext("FtpInboundChannelAdapterParserTests-context.xml", this.getClass());
// Auto-created channel
MessageChannel autoChannel = context.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter autoChannelAdapter = context.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
public static class TestSessionFactoryBean implements FactoryBean<DefaultFtpSessionFactory> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -19,6 +19,7 @@ package org.springframework.integration.http.config;
import java.util.List;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
@@ -26,6 +27,7 @@ import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.CollectionUtils;
@@ -41,6 +43,7 @@ import org.w3c.dom.Element;
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gary Russell
*/
public class HttpInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@@ -65,11 +68,16 @@ public class HttpInboundEndpointParser extends AbstractSingleBeanDefinitionParse
String id = super.resolveId(element, definition, parserContext);
if (!StringUtils.hasText(id)) {
id = element.getAttribute("name");
} else {
if (!element.hasAttribute(getInputChannelAttributeName())) {
// the created channel will get the 'id', so the adapter's bean name includes a suffix
id = id + ".adapter";
}
}
if (!StringUtils.hasText(id)) {
id = BeanDefinitionReaderUtils.generateBeanName(definition, parserContext.getRegistry());
}
return id;
}
@@ -79,8 +87,12 @@ public class HttpInboundEndpointParser extends AbstractSingleBeanDefinitionParse
String inputChannelAttributeName = this.getInputChannelAttributeName();
String inputChannelRef = element.getAttribute(inputChannelAttributeName);
if (!StringUtils.hasText(inputChannelRef)) {
parserContext.getReaderContext().error(
"a '" + inputChannelAttributeName + "' reference is required", element);
if (this.expectReply) {
parserContext.getReaderContext().error(
"a '" + inputChannelAttributeName + "' reference is required", element);
} else {
inputChannelRef = createDirectChannel(element, parserContext);
}
}
builder.addPropertyReference("requestChannel", inputChannelRef);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "error-channel");
@@ -158,4 +170,15 @@ public class HttpInboundEndpointParser extends AbstractSingleBeanDefinitionParse
return this.expectReply ? "request-channel" : "channel";
}
private String createDirectChannel(Element element, ParserContext parserContext) {
String channelId = element.getAttribute("id");
if (!StringUtils.hasText(channelId)) {
parserContext.getReaderContext().error("The channel-adapter's 'id' attribute is required when no 'channel' "
+ "reference has been provided, because that 'id' would be used for the created channel.", element);
}
BeanDefinitionBuilder channelBuilder = BeanDefinitionBuilder.genericBeanDefinition(DirectChannel.class);
BeanDefinitionHolder holder = new BeanDefinitionHolder(channelBuilder.getBeanDefinition(), channelId);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext.getRegistry());
return channelId;
}
}

View File

@@ -32,7 +32,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
@@ -284,7 +284,7 @@ The String "HTTP_REQUEST_HEADERS" will match against any of the standard HTTP Re
<xsd:union memberTypes="httpMethodEnumeration xsd:string" />
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -50,4 +50,13 @@
<header name="lname" expression="#pathVariables.l"/>
</inbound-channel-adapter>
<inbound-channel-adapter id="autoChannel"
path="/fname/{f}/lname/{l}"
mapped-request-headers="foo,bar"
payload-expression="#pathVariables.f">
<header name="lname" expression="#pathVariables.l"/>
</inbound-channel-adapter>
<si:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans:beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -19,6 +19,7 @@ package org.springframework.integration.http.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
@@ -40,6 +41,7 @@ import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.http.MockHttpServletRequest;
@@ -56,6 +58,7 @@ import org.springframework.util.MultiValueMap;
/**
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gary Russell
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -90,6 +93,11 @@ public class HttpInboundChannelAdapterParserTests {
@Autowired
private HttpRequestHandlingController inboundController;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private HttpRequestHandlingMessagingGateway autoChannelAdapter;
@Test
@SuppressWarnings("unchecked")
@@ -259,6 +267,10 @@ public class HttpInboundChannelAdapterParserTests {
assertEquals("oops", errorCode);
}
@Test
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "requestChannel"));
}
@SuppressWarnings("serial")
private static class TestObject implements Serializable {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -21,6 +21,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.w3c.dom.Element;
/**
@@ -31,15 +32,11 @@ import org.w3c.dom.Element;
*/
public class TcpInboundChannelAdapterParser extends AbstractChannelAdapterParser {
private static final String BASE_PACKAGE = "org.springframework.integration.ip.tcp";
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BASE_PACKAGE +
".TcpReceivingChannelAdapter");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TcpReceivingChannelAdapter.class);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
IpAdapterParserUtils.TCP_CONNECTION_FACTORY);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,
element, "channel", "outputChannel");
builder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,
element, "error-channel", "errorChannel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -21,6 +21,8 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.ip.udp.MulticastReceivingChannelAdapter;
import org.springframework.integration.ip.udp.UnicastReceivingChannelAdapter;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -32,8 +34,6 @@ import org.w3c.dom.Element;
*/
public class UdpInboundChannelAdapterParser extends AbstractChannelAdapterParser {
private static final String BASE_PACKAGE = "org.springframework.integration.ip.udp";
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
BeanDefinitionBuilder builder = parseUdp(element, parserContext);
IpAdapterParserUtils.addCommonSocketOptions(builder, element);
@@ -41,8 +41,7 @@ public class UdpInboundChannelAdapterParser extends AbstractChannelAdapterParser
IpAdapterParserUtils.RECEIVE_BUFFER_SIZE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element,
IpAdapterParserUtils.POOL_SIZE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,
element, "channel", "outputChannel");
builder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,
element, "error-channel", "errorChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
@@ -72,12 +71,10 @@ public class UdpInboundChannelAdapterParser extends AbstractChannelAdapterParser
BeanDefinitionBuilder builder;
String multicast = IpAdapterParserUtils.getMulticast(element);
if (multicast.equals("false")) {
builder = BeanDefinitionBuilder.genericBeanDefinition(BASE_PACKAGE +
".UnicastReceivingChannelAdapter");
builder = BeanDefinitionBuilder.genericBeanDefinition(UnicastReceivingChannelAdapter.class);
}
else {
builder = BeanDefinitionBuilder.genericBeanDefinition(BASE_PACKAGE +
".MulticastReceivingChannelAdapter");
builder = BeanDefinitionBuilder.genericBeanDefinition(MulticastReceivingChannelAdapter.class);
String mcAddress = element
.getAttribute(IpAdapterParserUtils.MULTICAST_ADDRESS);
if (!StringUtils.hasText(mcAddress)) {

View File

@@ -331,4 +331,12 @@
<task:scheduler id="sched"/>
<ip:tcp-inbound-channel-adapter id="tcpAutoChannel" />
<int:bridge input-channel="tcpAutoChannel" output-channel="nullChannel" />
<ip:udp-inbound-channel-adapter id="udpAutoChannel" port="#{tcpIpUtils.findAvailableUdpSocket(5050)}" />
<int:bridge input-channel="udpAutoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -195,6 +195,18 @@ public class ParserUnitTests {
@Qualifier(value="org.springframework.integration.ip.tcp.TcpSendingMessageHandler#3")
TcpSendingMessageHandler tcpOutClientMode;
@Autowired
MessageChannel tcpAutoChannel;
@Autowired
MessageChannel udpAutoChannel;
@Autowired @Qualifier("tcpAutoChannel.adapter")
TcpReceivingChannelAdapter tcpAutoAdapter;
@Autowired @Qualifier("udpAutoChannel.adapter")
UnicastReceivingChannelAdapter udpAutoAdapter;
@Test
public void testInUdp() {
DirectFieldAccessor dfa = new DirectFieldAccessor(udpIn);
@@ -518,4 +530,13 @@ public class ParserUnitTests {
assertEquals(125000L, dfa.getPropertyValue("retryInterval"));
}
@Test
public void testAutoTcp() {
assertSame(tcpAutoChannel, TestUtils.getPropertyValue(tcpAutoAdapter, "outputChannel"));
}
@Test
public void testAutoUdp() {
assertSame(udpAutoChannel, TestUtils.getPropertyValue(udpAutoAdapter, "outputChannel"));
}
}

View File

@@ -178,7 +178,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<xsd:documentation>
@@ -267,7 +267,7 @@
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="id" type="xsd:string" use="optional"/>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<xsd:documentation>
@@ -681,7 +681,7 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<xsd:documentation>
@@ -1096,7 +1096,7 @@
<xsd:union memberTypes="xsd:boolean xsd:string" />
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Channel to which polled messages will be send. If the stored

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -19,6 +19,7 @@ package org.springframework.integration.jdbc.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.List;
@@ -32,8 +33,10 @@ import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -43,6 +46,12 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
/**
* @author David Syer
* @author Gary Russell
* @since 2.0
*
*/
// Not transactional because the poller threads need access to the data
// @Transactional
public class JdbcPollingChannelAdapterParserTests {
@@ -149,6 +158,14 @@ public class JdbcPollingChannelAdapterParserTests {
}
}
@Test
public void testAutoChannel() {
setUp("autoChannelJdbcPollingChannelAdapterParserTests-context.xml", getClass());
MessageChannel autoChannel = appCtx.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter autoChannelAdapter = appCtx.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
@After
public void tearDown() {
if (appCtx != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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. You may obtain a copy of the License at
@@ -13,6 +13,12 @@
package org.springframework.integration.jdbc.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.sql.Types;
import java.util.List;
import java.util.Map;
@@ -20,25 +26,22 @@ import java.util.Map.Entry;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.jdbc.storedproc.PrimeMapper;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlInOutParameter;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author Gunnar Hillert
* @author Gary Russell
* @since 2.1
*
*/
@@ -185,6 +188,14 @@ public class StoredProcPollingChannelAdapterParserTests {
}
@Test
public void testAutoChannel() throws Exception {
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
MessageChannel autoChannel = context.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter autoChannelAdapter = context.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
@After
public void tearDown(){
if(context != null){

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-jdbc:inbound-channel-adapter id="autoChannel"
query="select * from item where status=2"
data-source="dataSource" />
<int:bridge input-channel="autoStartup" output-channel="nullChannel" />
<import resource="jdbcInboundChannelAdapterCommonConfig.xml" />
</beans>

View File

@@ -19,7 +19,7 @@
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
@@ -29,4 +29,23 @@
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:poller default="true" fixed-rate="10000"/>
<int-jdbc:stored-proc-inbound-channel-adapter id="autoChannel"
data-source="dataSource"
stored-procedure-name="GET_PRIME_NUMBERS"
is-function="false">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
</int-jdbc:stored-proc-inbound-channel-adapter>
<int:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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,19 +16,20 @@
package org.springframework.integration.jmx.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.StringUtils;
import org.springframework.integration.jmx.NotificationListeningMessageProducer;
import org.w3c.dom.Element;
/**
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
*/
public class NotificationListeningChannelAdapterParser extends AbstractSimpleBeanDefinitionParser {
public class NotificationListeningChannelAdapterParser extends AbstractChannelAdapterParser {
@Override
protected boolean shouldGenerateIdAsFallback() {
@@ -36,23 +37,16 @@ public class NotificationListeningChannelAdapterParser extends AbstractSimpleBea
}
@Override
protected String getBeanClassName(Element element) {
return "org.springframework.integration.jmx.NotificationListeningMessageProducer";
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
Object source = parserContext.extractSource(element);
String channel = element.getAttribute("channel");
if (!StringUtils.hasText(channel)) {
parserContext.getReaderContext().error("The 'channel' attribute is required.", source);
}
builder.addPropertyReference("outputChannel", channel);
protected AbstractBeanDefinition doParse(Element element,
ParserContext parserContext, String channelName) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(NotificationListeningMessageProducer.class);
builder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "server");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "notification-filter", "filter");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "handback");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "send-timeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "object-name");
return builder.getBeanDefinition();
}
}

View File

@@ -149,7 +149,7 @@
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="mbeanServerIdentifyerType">
<xsd:attribute name="channel" type="xsd:string" use="required" />
<xsd:attribute name="channel" type="xsd:string" />
<xsd:attribute name="object-name" type="xsd:string" use="required" />
</xsd:extension>
</xsd:complexContent>

View File

@@ -30,4 +30,13 @@
<bean id="testBean1" class="org.springframework.integration.jmx.config.TestBean"/>
<jmx:attribute-polling-channel-adapter id="autoChannel"
object-name="org.springframework.integration.jmx.config:type=TestBean,name=testBean1"
attribute-name="FirstMessage"
auto-startup="false">
<si:poller max-messages-per-poll="1" fixed-rate="2000"/>
</jmx:attribute-polling-channel-adapter>
<si:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -18,19 +18,23 @@ package org.springframework.integration.jmx.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
*/
@ContextConfiguration
@@ -46,6 +50,11 @@ public class AttributePollingChannelAdapterParserTests {
@Autowired
private TestBean testBean;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private SourcePollingChannelAdapter autoChannelAdapter;
@Test
public void pollForAttribute() throws Exception {
@@ -56,4 +65,9 @@ public class AttributePollingChannelAdapterParserTests {
assertEquals("foo", result.getPayload());
}
@Test
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
}

View File

@@ -26,4 +26,9 @@
<bean id="testPublisher" class="org.springframework.integration.jmx.config.TestPublisher"/>
<jmx:notification-listening-channel-adapter id="autoChannel"
object-name="org.springframework.integration.jmx.config:type=TestPublisher,name=testPublisher"/>
<si:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -19,14 +19,19 @@ package org.springframework.integration.jmx.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import javax.management.Notification;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.jmx.NotificationListeningMessageProducer;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -44,6 +49,11 @@ public class NotificationListeningChannelAdapterParserTests {
@Autowired
private TestPublisher testPublisher;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private NotificationListeningMessageProducer autoChannelAdapter;
@Test
public void receiveNotification() throws Exception {
@@ -55,4 +65,9 @@ public class NotificationListeningChannelAdapterParserTests {
assertEquals("ABC", ((Notification) message.getPayload()).getMessage());
}
@Test
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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,16 +16,17 @@
package org.springframework.integration.mail.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.Assert;
import org.springframework.integration.mail.ImapIdleChannelAdapter;
import org.springframework.integration.mail.ImapMailReceiver;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the &lt;imap-idle-channel-adapter&gt; element in the 'mail' namespace.
@@ -35,34 +36,19 @@ import org.springframework.util.StringUtils;
* @author Oleg Zhurakousky
* @author Gary Russell
*/
public class ImapIdleChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
public class ImapIdleChannelAdapterParser extends AbstractChannelAdapterParser {
private static final String BASE_PACKAGE = "org.springframework.integration.mail";
protected String getBeanClassName(Element element) {
return BASE_PACKAGE + ".ImapIdleChannelAdapter";
}
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String channel = element.getAttribute("channel");
Assert.hasText(channel, "the 'channel' attribute is required");
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ImapIdleChannelAdapter.class);
builder.addConstructorArgValue(this.parseImapMailReceiver(element, parserContext));
builder.addPropertyReference("outputChannel", channel);
builder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "error-channel", "errorChannel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup");
return builder.getBeanDefinition();
}
private BeanDefinition parseImapMailReceiver(Element element, ParserContext parserContext) {
BeanDefinitionBuilder receiverBuilder = BeanDefinitionBuilder.genericBeanDefinition(BASE_PACKAGE + ".ImapMailReceiver");
BeanDefinitionBuilder receiverBuilder = BeanDefinitionBuilder.genericBeanDefinition(ImapMailReceiver.class);
Object source = parserContext.extractSource(element);
String uri = element.getAttribute("store-uri");
if (StringUtils.hasText(uri)) {

View File

@@ -135,7 +135,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Reference for the MessageChannel to which this adapter will send Messages.

View File

@@ -71,4 +71,12 @@
<task:executor id="executor" pool-size="5"/>
<mail:imap-idle-channel-adapter
id="autoChannel"
store-uri="imap:foo"
auto-startup="false"
should-delete-messages="true"/>
<integration:bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans>

View File

@@ -28,9 +28,12 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.mail.ImapIdleChannelAdapter;
import org.springframework.integration.mail.ImapMailReceiver;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -46,6 +49,11 @@ public class ImapIdleChannelAdapterParserTests {
@Autowired
private ApplicationContext context;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private ImapIdleChannelAdapter autoChannelAdapter;
@Test
public void simpleAdapter() {
@@ -140,4 +148,9 @@ public class ImapIdleChannelAdapterParserTests {
assertEquals("bar", properties.getProperty("foo"));
assertEquals(Boolean.FALSE, receiverAccessor.getPropertyValue("shouldDeleteMessages"));
}
@Test
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
}

View File

@@ -98,6 +98,11 @@
<mail:inbound-channel-adapter id="imapShouldMarkAsReadTrue" channel="testChannel" protocol="imap" should-delete-messages="false" auto-startup="false" should-mark-messages-as-read="true"/>
<!-- INT-2407 -->
<mail:inbound-channel-adapter id="autoChannel" protocol="pop3" should-delete-messages="false" auto-startup="false"/>
<si:bridge input-channel="autoChannel" output-channel="nullChannel"/>
<!-- COMMON CONFIGURATION -->

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -27,19 +28,22 @@ import javax.mail.Authenticator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xml.sax.SAXParseException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.mail.AbstractMailReceiver;
import org.springframework.integration.mail.ImapIdleChannelAdapter;
import org.springframework.integration.mail.ImapMailReceiver;
import org.springframework.integration.mail.Pop3MailReceiver;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.xml.sax.SAXParseException;
/**
* @author Mark Fisher
@@ -53,6 +57,11 @@ public class InboundChannelAdapterParserTests {
@Autowired
private ApplicationContext context;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private SourcePollingChannelAdapter autoChannelAdapter;
//==================== INT-982 =====================
@@ -283,4 +292,9 @@ public class InboundChannelAdapterParserTests {
return (AbstractMailReceiver) new DirectFieldAccessor(target).getPropertyValue("mailReceiver");
}
@Test
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.integration.redis.config;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
@@ -28,6 +27,7 @@ import org.w3c.dom.Element;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author Gary Russell
* @since 2.1
*/
public class RedisInboundChannelAdapterParser extends AbstractChannelAdapterParser {
@@ -41,7 +41,7 @@ public class RedisInboundChannelAdapterParser extends AbstractChannelAdapterPars
connectionFactory = "redisConnectionFactory";
}
builder.addConstructorArgReference(connectionFactory);
builder.addPropertyValue("outputChannel", new RuntimeBeanReference(channelName));
builder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "topics");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "error-channel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converter");

View File

@@ -173,7 +173,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string" use="required">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Channel to which Messages will be sent.

View File

@@ -23,4 +23,10 @@
<bean id="testConverter"
class="org.springframework.integration.redis.config.RedisInboundChannelAdapterParserTests$TestMessageConverter" />
<int-redis:inbound-channel-adapter
id="autoChannel" topics="foo, bar" error-channel="testErrorChannel"
message-converter="testConverter" />
<int:bridge input-channel="autoChannel" output-channel="nullChannel"/>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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,26 +16,30 @@
package org.springframework.integration.redis.config;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.redis.inbound.RedisInboundChannelAdapter;
import org.springframework.integration.redis.rules.RedisAvailable;
import org.springframework.integration.redis.rules.RedisAvailableTests;
import org.springframework.integration.support.converter.SimpleMessageConverter;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static junit.framework.Assert.assertEquals;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author Gary Russell
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@@ -43,7 +47,12 @@ public class RedisInboundChannelAdapterParserTests extends RedisAvailableTests{
@Autowired
private ApplicationContext context;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private RedisInboundChannelAdapter autoChannelAdapter;
@Test
@RedisAvailable
@@ -72,6 +81,11 @@ public class RedisInboundChannelAdapterParserTests extends RedisAvailableTests{
assertEquals("Hello Redis from bar", receiveChannel.receive(1000).getPayload());
}
@Test
@RedisAvailable
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
@SuppressWarnings("unused")
private static class TestMessageConverter extends SimpleMessageConverter {

View File

@@ -389,7 +389,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" use="required" type="xsd:string">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -93,5 +93,16 @@
<beans:constructor-arg value="."/>
</beans:bean>
<sftp:inbound-channel-adapter id="autoChannel"
session-factory="sftpSessionFactory"
filter="filter"
remote-directory="/foo"
local-directory="file:foo"
auto-create-local-directory="false"
delete-remote-files="false">
<poller fixed-rate="1000"/>
</sftp:inbound-channel-adapter>
<bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans:beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -20,6 +20,7 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertSame;
import java.io.File;
import java.util.Comparator;
@@ -33,6 +34,7 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.sftp.inbound.SftpInboundFileSynchronizer;
@@ -41,6 +43,7 @@ import org.springframework.integration.test.util.TestUtils;
/**
* @author Oleg Zhurakousky
* @author Gary Russell
*/
public class InboundChannelAdapterParserTests {
@@ -82,6 +85,16 @@ public class InboundChannelAdapterParserTests {
assertNotNull(requestChannel.receive(2000));
}
@Test
public void testAutoChannel() {
ApplicationContext context =
new ClassPathXmlApplicationContext("InboundChannelAdapterParserTests-context.xml", this.getClass());
// Auto-created channel
MessageChannel autoChannel = context.getBean("autoChannel", MessageChannel.class);
SourcePollingChannelAdapter autoChannelAdapter = context.getBean("autoChannel.adapter", SourcePollingChannelAdapter.class);
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
@Test(expected=BeanDefinitionStoreException.class)
//exactly one of 'filename-pattern' or 'filter' is allowed on SFTP inbound adapter
public void testFailWithFilePatternAndFilter() throws Exception{

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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,23 +16,24 @@
package org.springframework.integration.xmpp.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.xmpp.support.DefaultXmppHeaderMapper;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Base class for XMPP inbound parsers
*
* @author Oleg Zhurakousky
* @author Gary Russell
* @since 2.0.1
*/
public abstract class AbstractXmppInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
public abstract class AbstractXmppInboundChannelAdapterParser extends AbstractChannelAdapterParser {
@Override
protected boolean shouldGenerateId() {
@@ -44,13 +45,15 @@ public abstract class AbstractXmppInboundChannelAdapterParser extends AbstractSi
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
protected abstract String getBeanClassName(Element element);
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(getBeanClassName(element));
IntegrationNamespaceUtils.configureHeaderMapper(element, builder, parserContext, DefaultXmppHeaderMapper.class, null);
String connectionName = element.getAttribute("xmpp-connection");
if (StringUtils.hasText(connectionName)){
builder.addConstructorArgReference(connectionName);
}
@@ -62,10 +65,11 @@ public abstract class AbstractXmppInboundChannelAdapterParser extends AbstractSi
"'xmpp-connection' attribute or have default XMPP connection bean registered under the name 'xmppConnection'" +
"(e.g., <int-xmpp:xmpp-connection .../>). If 'id' is not provided the default will be 'xmppConnection'.");
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "outputChannel");
builder.addPropertyReference("outputChannel", channelName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "error-channel");
this.postProcess(element, parserContext, builder);
return builder.getBeanDefinition();
}
protected void postProcess(Element element, ParserContext parserContext, BeanDefinitionBuilder builder){

View File

@@ -161,7 +161,7 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" use="required" type="xsd:string">
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -21,14 +21,21 @@
<beans:bean id="testConnection" class="org.mockito.Mockito" factory-method="mock">
<beans:constructor-arg value="org.jivesoftware.smack.XMPPConnection"/>
</beans:bean>
<channel id="xmppInbound">
<queue/>
</channel>
<xmpp:inbound-channel-adapter id="xmppInboundAdapter" channel="xmppInbound"
xmpp-connection="testConnection" extract-payload="false"
<xmpp:inbound-channel-adapter id="xmppInboundAdapter" channel="xmppInbound"
xmpp-connection="testConnection" extract-payload="false"
auto-startup="false" error-channel="errorChannel"
mapped-request-headers="foo*, xmpp*"/>
<xmpp:inbound-channel-adapter id="autoChannel"
xmpp-connection="testConnection" extract-payload="false"
auto-startup="false" error-channel="errorChannel"
mapped-request-headers="foo*, xmpp*"/>
<bridge input-channel="autoChannel" output-channel="nullChannel" />
</beans:beans>

View File

@@ -16,6 +16,10 @@
package org.springframework.integration.xmpp.config;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import java.lang.reflect.Field;
import org.jivesoftware.smack.Chat;
@@ -23,12 +27,11 @@ import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Message;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.channel.QueueChannel;
@@ -38,9 +41,6 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.ReflectionUtils;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
@@ -51,10 +51,16 @@ public class ChatMessageInboundChannelAdapterParserTests {
@Autowired
private ApplicationContext context;
@Autowired
private QueueChannel xmppInbound;
@Autowired
private MessageChannel autoChannel;
@Autowired @Qualifier("autoChannel.adapter")
private ChatMessageListeningEndpoint autoChannelAdapter;
@Test
public void testInboundAdapter(){
ChatMessageListeningEndpoint adapter = context.getBean("xmppInboundAdapter", ChatMessageListeningEndpoint.class);
@@ -94,4 +100,8 @@ public class ChatMessageInboundChannelAdapterParserTests {
assertEquals("oleg", siMessage.getHeaders().get("xmpp_to"));
}
@Test
public void testAutoChannel() {
assertSame(autoChannel, TestUtils.getPropertyValue(autoChannelAdapter, "outputChannel"));
}
}