Added namespace support for <httpinvoker-source/> and <httpinvoker-target/> (INT-156).

This commit is contained in:
Mark Fisher
2008-03-20 16:47:25 +00:00
parent 5e7141959d
commit 9ecf421bc5
12 changed files with 390 additions and 46 deletions

View File

@@ -4,4 +4,6 @@ jms-source=org.springframework.integration.adapter.jms.config.JmsSourceAdapterPa
jms-target=org.springframework.integration.adapter.jms.config.JmsTargetAdapterParser
rmi-source=org.springframework.integration.adapter.rmi.config.RmiSourceAdapterParser
rmi-target=org.springframework.integration.adapter.rmi.config.RmiTargetAdapterParser
httpinvoker-source=org.springframework.integration.adapter.httpinvoker.config.HttpInvokerSourceAdapterParser
httpinvoker-target=org.springframework.integration.adapter.httpinvoker.config.HttpInvokerTargetAdapterParser
mail-target=org.springframework.integration.adapter.mail.config.MailTargetAdapterParser

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2002-2008 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
*
* 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.springframework.integration.adapter.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
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.MessagingConfigurationException;
import org.springframework.util.StringUtils;
/**
* Base class for request-reply source adapter parsers.
*
* @author Mark Fisher
*/
public abstract class AbstractRequestReplySourceAdapterParser extends AbstractSingleBeanDefinitionParser {
protected abstract Class<?> getBeanClass(Element element);
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
String id = super.resolveId(element, definition, parserContext);
if (!StringUtils.hasText(id)) {
id = element.getAttribute("name");
}
if (!StringUtils.hasText(id)) {
id = parserContext.getReaderContext().generateBeanName(definition);
}
return id;
}
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String channelRef = element.getAttribute("channel");
if (!StringUtils.hasText(channelRef)) {
throw new MessagingConfigurationException("a 'channel' reference is required");
}
builder.addPropertyReference("channel", channelRef);
builder.addPropertyValue("expectReply", element.getAttribute("expect-reply").equals("true"));
String sendTimeout = element.getAttribute("send-timeout");
if (StringUtils.hasText(sendTimeout)) {
builder.addPropertyValue("sendTimeout", Long.parseLong(sendTimeout));
}
String receiveTimeout = element.getAttribute("receive-timeout");
if (StringUtils.hasText(receiveTimeout)) {
builder.addPropertyValue("receiveTimeout", Long.parseLong(receiveTimeout));
}
}
}

View File

@@ -93,19 +93,12 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="rmi-source">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
<xsd:element name="rmi-source" type="requestReplySource">
<xsd:annotation>
<xsd:documentation>
Defines an rmi-based source channel adapter.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="expect-reply" type="xsd:boolean" default="true"/>
<xsd:attribute name="send-timeout" type="xsd:long"/>
<xsd:attribute name="receive-timeout" type="xsd:long"/>
<xsd:attribute name="channel" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="rmi-target">
@@ -122,6 +115,27 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="httpinvoker-source" type="requestReplySource">
<xsd:annotation>
<xsd:documentation>
Defines an httpinvoker-based source channel adapter.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="httpinvoker-target">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines an httpinvoker-based target channel adapter.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="channel" type="xsd:string" use="required"/>
<xsd:attribute name="url" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="mail-target">
<xsd:complexType>
<xsd:annotation>
@@ -139,4 +153,18 @@
</xsd:complexType>
</xsd:element>
<xsd:complexType name="requestReplySource">
<xsd:annotation>
<xsd:documentation>
Defines common configuration for request-reply source adapters.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="expect-reply" type="xsd:boolean" default="true"/>
<xsd:attribute name="send-timeout" type="xsd:long"/>
<xsd:attribute name="receive-timeout" type="xsd:long"/>
<xsd:attribute name="channel" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:schema>

View File

@@ -27,7 +27,6 @@ import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
import org.springframework.util.Assert;
import org.springframework.web.HttpRequestHandler;
/**
@@ -65,8 +64,12 @@ public class HttpInvokerSourceAdapter extends AbstractMessageHandlingSourceAdapt
private volatile HttpInvokerServiceExporter exporter;
public HttpInvokerSourceAdapter() {
super();
}
public HttpInvokerSourceAdapter(MessageChannel channel) {
Assert.notNull(channel, "'channel' must not be null");
this();
this.setChannel(channel);
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2002-2008 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
*
* 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.springframework.integration.adapter.httpinvoker.config;
import org.w3c.dom.Element;
import org.springframework.integration.adapter.config.AbstractRequestReplySourceAdapterParser;
import org.springframework.integration.adapter.httpinvoker.HttpInvokerSourceAdapter;
/**
* Parser for the &lt;httpinvoker-source/&gt; element.
*
* @author Mark Fisher
*/
public class HttpInvokerSourceAdapterParser extends AbstractRequestReplySourceAdapterParser {
@Override
protected Class<?> getBeanClass(Element element) {
return HttpInvokerSourceAdapter.class;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2002-2008 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
*
* 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.springframework.integration.adapter.httpinvoker.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
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.MessagingConfigurationException;
import org.springframework.integration.adapter.httpinvoker.HttpInvokerTargetAdapter;
import org.springframework.integration.endpoint.DefaultMessageEndpoint;
import org.springframework.integration.scheduling.Subscription;
import org.springframework.util.StringUtils;
/**
* Parser for the &lt;httpinvoker-target/&gt; element.
*
* @author Mark Fisher
*/
public class HttpInvokerTargetAdapterParser extends AbstractSingleBeanDefinitionParser {
protected Class<?> getBeanClass(Element element) {
return DefaultMessageEndpoint.class;
}
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
RootBeanDefinition adapterDef = new RootBeanDefinition(HttpInvokerTargetAdapter.class);
String channel = element.getAttribute("channel");
String url = element.getAttribute("url");
if (!StringUtils.hasText(channel)) {
throw new MessagingConfigurationException("The 'channel' attribute is required.");
}
if (!StringUtils.hasText(url)) {
throw new MessagingConfigurationException("The 'url' attribute is required.");
}
adapterDef.getConstructorArgumentValues().addGenericArgumentValue(url);
String adapterBeanName = parserContext.getReaderContext().generateBeanName(adapterDef);
parserContext.registerBeanComponent(new BeanComponentDefinition(adapterDef, adapterBeanName));
builder.addPropertyReference("handler", adapterBeanName);
Subscription subscription = new Subscription(channel);
builder.addPropertyValue("subscription", subscription);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2008 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 java.rmi.RemoteException;
import org.springframework.integration.MessagingConfigurationException;
import org.springframework.integration.adapter.AbstractMessageHandlingSourceAdapter;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.handler.MessageHandler;
import org.springframework.remoting.rmi.RmiServiceExporter;
@@ -33,6 +34,16 @@ public class RmiSourceAdapter extends AbstractMessageHandlingSourceAdapter {
public static final String SERVICE_NAME_PREFIX = "internal.rmiSourceAdapter.";
public RmiSourceAdapter() {
super();
}
public RmiSourceAdapter(MessageChannel channel) {
this();
this.setChannel(channel);
}
public void initialize() throws RemoteException {
String channelName = this.getChannel().getName();
if (channelName == null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2008 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,46 +18,19 @@ package org.springframework.integration.adapter.rmi.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.integration.MessagingConfigurationException;
import org.springframework.integration.adapter.config.AbstractRequestReplySourceAdapterParser;
import org.springframework.integration.adapter.rmi.RmiSourceAdapter;
import org.springframework.util.StringUtils;
/**
* Parser for the &lt;rmi-source/&gt; element.
*
* @author Mark Fisher
*/
public class RmiSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
public class RmiSourceAdapterParser extends AbstractRequestReplySourceAdapterParser {
@Override
protected Class<?> getBeanClass(Element element) {
return RmiSourceAdapter.class;
}
protected boolean shouldGenerateId() {
return false;
}
protected boolean shouldGenerateIdAsFallback() {
return true;
}
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String channelRef = element.getAttribute("channel");
if (!StringUtils.hasText(channelRef)) {
throw new MessagingConfigurationException("a 'channel' reference is required");
}
builder.addPropertyReference("channel", channelRef);
builder.addPropertyValue("expectReply", element.getAttribute("expect-reply").equals("true"));
String sendTimeout = element.getAttribute("send-timeout");
if (StringUtils.hasText(sendTimeout)) {
builder.addPropertyValue("sendTimeout", Long.parseLong(sendTimeout));
}
String receiveTimeout = element.getAttribute("receive-timeout");
if (StringUtils.hasText(receiveTimeout)) {
builder.addPropertyValue("receiveTimeout", Long.parseLong(receiveTimeout));
}
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2002-2008 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
*
* 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.springframework.integration.adapter.httpinvoker.config;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.adapter.httpinvoker.HttpInvokerSourceAdapter;
import org.springframework.integration.channel.MessageChannel;
/**
* @author Mark Fisher
*/
public class HttpInvokerSourceAdapterParserTests {
@Test
public void testAdapterWithDefaults() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"httpInvokerSourceAdapterParserTests.xml", this.getClass());
MessageChannel channel = (MessageChannel) context.getBean("testChannel");
HttpInvokerSourceAdapter adapter = (HttpInvokerSourceAdapter) context.getBean("adapterWithDefaults");
DirectFieldAccessor accessor = new DirectFieldAccessor(adapter);
assertEquals(channel, accessor.getPropertyValue("channel"));
assertEquals(true, accessor.getPropertyValue("expectReply"));
assertEquals(-1L, accessor.getPropertyValue("sendTimeout"));
assertEquals(-1L, accessor.getPropertyValue("receiveTimeout"));
}
@Test
public void testAdapterWithName() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"httpInvokerSourceAdapterParserTests.xml", this.getClass());
MessageChannel channel = (MessageChannel) context.getBean("testChannel");
HttpInvokerSourceAdapter adapter = (HttpInvokerSourceAdapter) context.getBean("/adapter/with/name");
DirectFieldAccessor accessor = new DirectFieldAccessor(adapter);
assertEquals(channel, accessor.getPropertyValue("channel"));
assertEquals(true, accessor.getPropertyValue("expectReply"));
assertEquals(-1L, accessor.getPropertyValue("sendTimeout"));
assertEquals(-1L, accessor.getPropertyValue("receiveTimeout"));
}
@Test
public void testAdapterWithCustomProperties() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"httpInvokerSourceAdapterParserTests.xml", this.getClass());
MessageChannel channel = (MessageChannel) context.getBean("testChannel");
HttpInvokerSourceAdapter adapter = (HttpInvokerSourceAdapter) context.getBean("adapterWithCustomProperties");
DirectFieldAccessor accessor = new DirectFieldAccessor(adapter);
assertEquals(channel, accessor.getPropertyValue("channel"));
assertEquals(false, accessor.getPropertyValue("expectReply"));
assertEquals(123L, accessor.getPropertyValue("sendTimeout"));
assertEquals(456L, accessor.getPropertyValue("receiveTimeout"));
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2002-2008 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
*
* 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.springframework.integration.adapter.httpinvoker.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.adapter.httpinvoker.HttpInvokerTargetAdapter;
import org.springframework.integration.endpoint.DefaultMessageEndpoint;
/**
* @author Mark Fisher
*/
public class HttpInvokerTargetAdapterParserTests {
@Test
public void testHttpInvokerTargetAdapter() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"httpInvokerTargetAdapterParserTests.xml", this.getClass());
DefaultMessageEndpoint endpoint = (DefaultMessageEndpoint) context.getBean("adapter");
assertNotNull(endpoint);
assertEquals(HttpInvokerTargetAdapter.class, endpoint.getHandler().getClass());
assertEquals("testChannel", endpoint.getSubscription().getChannelName());
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
<message-bus/>
<channel id="testChannel"/>
<httpinvoker-source id="adapterWithDefaults" channel="testChannel"/>
<httpinvoker-source name="/adapter/with/name" channel="testChannel"/>
<httpinvoker-source id="adapterWithCustomProperties" channel="testChannel"
expect-reply="false" send-timeout="123" receive-timeout="456"/>
</beans:beans>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
<message-bus/>
<channel id="testChannel"/>
<httpinvoker-target id="adapter" channel="testChannel" url="http://localhost:8080/test"/>
</beans:beans>