INT-707
This commit is contained in:
@@ -16,11 +16,18 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.gateway.GatewayMethodDefinition;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <gateway/> element.
|
||||
@@ -33,6 +40,24 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
"default-request-channel", "default-reply-channel", "message-mapper"
|
||||
};
|
||||
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, builder);
|
||||
List<Element> elements = DomUtils.getChildElementsByTagName(element, "method");
|
||||
ManagedMap<String, GatewayMethodDefinition> methodToChannelMap = null;
|
||||
if (elements != null && elements.size() > 0){
|
||||
methodToChannelMap = new ManagedMap<String, GatewayMethodDefinition>();
|
||||
}
|
||||
for (Element methodElement : elements) {
|
||||
String methodName = methodElement.getAttribute("name");
|
||||
GatewayMethodDefinition gatewayDefinition = new GatewayMethodDefinition();
|
||||
gatewayDefinition.setRequestChannelName(methodElement.getAttribute("request-channel"));
|
||||
gatewayDefinition.setReplyChannelName(methodElement.getAttribute("reply-channel"));
|
||||
gatewayDefinition.setRequestTimeout(methodElement.getAttribute("request-timeout"));
|
||||
gatewayDefinition.setReplyTimeout(methodElement.getAttribute("reply-timeout"));
|
||||
methodToChannelMap.put(methodName, gatewayDefinition);
|
||||
}
|
||||
builder.addPropertyValue("methodToChannelMap", methodToChannelMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBeanClassName(Element element) {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.gateway;
|
||||
|
||||
/**
|
||||
* Represents the definition of Gateway methods, when using multiple methos per
|
||||
* Gateway interface <br>
|
||||
* <si:method name="echo" request-channel="inputA" reply-timeout="2" request-timeout="200"/>
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0.M1
|
||||
*/
|
||||
public class GatewayMethodDefinition {
|
||||
|
||||
private String requestChannelName;
|
||||
private String replyChannelName;
|
||||
private String requestTimeout;
|
||||
private String replyTimeout;
|
||||
public String getRequestChannelName() {
|
||||
return requestChannelName;
|
||||
}
|
||||
public void setRequestChannelName(String requestChannelName) {
|
||||
this.requestChannelName = requestChannelName;
|
||||
}
|
||||
public String getReplyChannelName() {
|
||||
return replyChannelName;
|
||||
}
|
||||
public void setReplyChannelName(String replyChannelName) {
|
||||
this.replyChannelName = replyChannelName;
|
||||
}
|
||||
public String getRequestTimeout() {
|
||||
return requestTimeout;
|
||||
}
|
||||
public void setRequestTimeout(String requestTimeout) {
|
||||
this.requestTimeout = requestTimeout;
|
||||
}
|
||||
public String getReplyTimeout() {
|
||||
return replyTimeout;
|
||||
}
|
||||
public void setReplyTimeout(String replyTimeout) {
|
||||
this.replyTimeout = replyTimeout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import org.springframework.util.StringUtils;
|
||||
* with messaging components without application code being aware of them.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class GatewayProxyFactoryBean extends AbstractEndpoint implements FactoryBean, MethodInterceptor, BeanClassLoaderAware {
|
||||
|
||||
@@ -70,7 +71,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
|
||||
private volatile boolean initialized;
|
||||
|
||||
private final Object initializationMonitor = new Object();
|
||||
|
||||
private Map<String, GatewayMethodDefinition> methodToChannelMap;
|
||||
|
||||
public void setServiceInterface(Class<?> serviceInterface) {
|
||||
if (serviceInterface != null && !serviceInterface.isInterface()) {
|
||||
@@ -236,17 +237,28 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
|
||||
if (gatewayAnnotation != null) {
|
||||
Assert.state(this.getChannelResolver() != null, "ChannelResolver is required");
|
||||
String requestChannelName = gatewayAnnotation.requestChannel();
|
||||
if (StringUtils.hasText(requestChannelName)) {
|
||||
requestChannel = this.getChannelResolver().resolveChannelName(requestChannelName);
|
||||
Assert.notNull(requestChannel, "failed to resolve request channel '" + requestChannelName + "'");
|
||||
}
|
||||
requestChannel = this.resolveChannel(requestChannel, requestChannelName);
|
||||
String replyChannelName = gatewayAnnotation.replyChannel();
|
||||
if (StringUtils.hasText(replyChannelName)) {
|
||||
replyChannel = this.getChannelResolver().resolveChannelName(replyChannelName);
|
||||
Assert.notNull(replyChannel, "failed to resolve reply channel '" + replyChannelName + "'");
|
||||
}
|
||||
replyChannel = this.resolveChannel(replyChannel, replyChannelName);
|
||||
requestTimeout = gatewayAnnotation.requestTimeout();
|
||||
replyTimeout = gatewayAnnotation.replyTimeout();
|
||||
} else if (methodToChannelMap != null && methodToChannelMap.size() > 0) {
|
||||
Assert.state(this.getChannelResolver() != null, "ChannelResolver is required");
|
||||
GatewayMethodDefinition gatewayDefinition = methodToChannelMap.get(method.getName());
|
||||
if (gatewayDefinition != null){
|
||||
String requestChannelName = gatewayDefinition.getRequestChannelName();
|
||||
requestChannel = this.resolveChannel(requestChannel, requestChannelName);
|
||||
String replyChannelName = gatewayDefinition.getReplyChannelName();
|
||||
replyChannel = this.resolveChannel(replyChannel, replyChannelName);
|
||||
String reqTimeout = gatewayDefinition.getRequestTimeout();
|
||||
if (StringUtils.hasText(reqTimeout)){
|
||||
requestTimeout = typeConverter.convertIfNecessary(reqTimeout, Long.class);
|
||||
}
|
||||
String repTimeout = gatewayDefinition.getReplyTimeout();
|
||||
if (StringUtils.hasText(repTimeout)){
|
||||
replyTimeout = typeConverter.convertIfNecessary(repTimeout, Long.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
gateway.setRequestChannel(requestChannel);
|
||||
gateway.setReplyChannel(replyChannel);
|
||||
@@ -257,6 +269,14 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
|
||||
}
|
||||
return gateway;
|
||||
}
|
||||
|
||||
private MessageChannel resolveChannel(MessageChannel channel, String channelName) {
|
||||
if (StringUtils.hasText(channelName)) {
|
||||
channel = this.getChannelResolver().resolveChannelName(channelName);
|
||||
Assert.notNull(channel, "failed to resolve channel '" + channelName + "'");
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
// Lifecycle implementation
|
||||
|
||||
@@ -277,5 +297,13 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, GatewayMethodDefinition> getMethodToChannelMap() {
|
||||
return methodToChannelMap;
|
||||
}
|
||||
|
||||
public void setMethodToChannelMap(Map<String, GatewayMethodDefinition> methodToChannelMap) {
|
||||
this.methodToChannelMap = methodToChannelMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -304,6 +304,17 @@
|
||||
Defines a Messaging Gateway.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="method" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="request-channel" type="xsd:string" />
|
||||
<xsd:attribute name="reply-channel" type="xsd:string" />
|
||||
<xsd:attribute name="request-timeout" type="xsd:string" />
|
||||
<xsd:attribute name="reply-timeout" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:ID" use="required" />
|
||||
<xsd:attribute name="service-interface" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"
|
||||
xmlns:si="http://www.springframework.org/schema/integration">
|
||||
|
||||
<si:gateway id="myGateway" service-interface="org.springframework.integration.gateway.MultiMethodGatewayConfig$TestGateway"
|
||||
default-request-channel="inputC">
|
||||
<si:method name="echo" request-channel="inputA" reply-timeout="2" request-timeout="200"/>
|
||||
<si:method name="echoUpperCase" request-channel="inputB"/>
|
||||
<si:method name="echoViaDefault"/>
|
||||
</si:gateway>
|
||||
|
||||
<si:channel id="inputA"/>
|
||||
<si:service-activator input-channel="inputA" method="echo">
|
||||
<bean class="org.springframework.integration.gateway.MultiMethodGatewayConfig$TestBeanA"/>
|
||||
</si:service-activator>
|
||||
<!-- -->
|
||||
<si:channel id="inputB"/>
|
||||
<si:service-activator input-channel="inputB" method="echo">
|
||||
<bean class="org.springframework.integration.gateway.MultiMethodGatewayConfig$TestBeanB"/>
|
||||
</si:service-activator>
|
||||
|
||||
<si:channel id="inputC"/>
|
||||
<si:service-activator input-channel="inputC" method="echo">
|
||||
<bean class="org.springframework.integration.gateway.MultiMethodGatewayConfig$TestBeanC"/>
|
||||
</si:service-activator>
|
||||
|
||||
</beans>
|
||||
@@ -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.gateway;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0.M1
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MultiMethodGatewayConfig {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Test
|
||||
public void validateGatewayMethods(){
|
||||
TestGateway gateway = (TestGateway) applicationContext.getBean("myGateway");
|
||||
Assert.assertEquals(gateway.echo("oleg"),
|
||||
"org.springframework.integration.gateway.MultiMethodGatewayConfig$TestBeanA:oleg");
|
||||
Assert.assertEquals(gateway.echoUpperCase("oleg"),
|
||||
"org.springframework.integration.gateway.MultiMethodGatewayConfig$TestBeanB:oleg");
|
||||
Assert.assertEquals(gateway.echoViaDefault("oleg"),
|
||||
"org.springframework.integration.gateway.MultiMethodGatewayConfig$TestBeanC:oleg");
|
||||
}
|
||||
|
||||
public static class TestBeanA{
|
||||
public String echo(String str){
|
||||
return this.getClass().getName() + ":" + str;
|
||||
}
|
||||
}
|
||||
public static class TestBeanB{
|
||||
public String echo(String str){
|
||||
return this.getClass().getName() + ":" + str;
|
||||
}
|
||||
}
|
||||
public static class TestBeanC{
|
||||
public String echo(String str){
|
||||
return this.getClass().getName() + ":" + str;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface TestGateway{
|
||||
public String echo(String str);
|
||||
public String echoViaDefault(String str);
|
||||
public String echoUpperCase(String str);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user