diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java
index fd28191d4c..574592b612 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java
@@ -34,6 +34,7 @@ import org.springframework.integration.channel.config.PriorityChannelParser;
import org.springframework.integration.channel.config.QueueChannelParser;
import org.springframework.integration.channel.config.RendezvousChannelParser;
import org.springframework.integration.channel.config.ThreadLocalChannelParser;
+import org.springframework.integration.gateway.config.GatewayParser;
import org.springframework.integration.router.config.RouterParser;
import org.springframework.integration.router.config.SplitterParser;
import org.springframework.util.ClassUtils;
@@ -66,6 +67,7 @@ public class IntegrationNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("source-endpoint", new SourceEndpointParser());
registerBeanDefinitionParser("handler-endpoint", new HandlerEndpointParser());
registerBeanDefinitionParser("target-endpoint", new TargetEndpointParser());
+ registerBeanDefinitionParser("gateway", new GatewayParser());
registerBeanDefinitionParser("handler", new HandlerParser());
registerBeanDefinitionParser("handler-chain", new HandlerParser());
registerBeanDefinitionParser("router", new RouterParser());
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd
index d2d0b3a149..ef7ddd0e97 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd
@@ -136,6 +136,24 @@
+
+
+
+
+ Defines a Messaging Gateway.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/gateway/config/GatewayParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/gateway/config/GatewayParser.java
new file mode 100644
index 0000000000..d130d971f4
--- /dev/null
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/gateway/config/GatewayParser.java
@@ -0,0 +1,62 @@
+/*
+ * 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.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
+import org.springframework.core.Conventions;
+import org.springframework.integration.gateway.GatewayProxyFactoryBean;
+import org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * Parser for the <gateway/> element.
+ *
+ * @author Mark Fisher
+ */
+public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
+
+ private static String[] referenceAttributes = new String[] {
+ "request-channel", "reply-channel", "message-mapper", "message-creator"
+ };
+
+
+ @Override
+ protected Class> getBeanClass(Element element) {
+ return GatewayProxyFactoryBean.class;
+ }
+
+ @Override
+ protected boolean isEligibleAttribute(String attributeName) {
+ return !ObjectUtils.containsElement(referenceAttributes, attributeName)
+ && super.isEligibleAttribute(attributeName);
+ }
+
+ @Override
+ protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
+ for (String attributeName : referenceAttributes) {
+ String beanName = element.getAttribute(attributeName);
+ if (StringUtils.hasText(beanName)) {
+ beanDefinition.addPropertyReference(
+ Conventions.attributeNameToPropertyName(attributeName), beanName);
+ }
+ }
+ }
+
+}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/GatewayParserTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/GatewayParserTests.java
new file mode 100644
index 0000000000..be44f13f01
--- /dev/null
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/GatewayParserTests.java
@@ -0,0 +1,102 @@
+/*
+ * 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.config;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.Executors;
+
+import org.junit.Test;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.integration.channel.MessageChannel;
+import org.springframework.integration.gateway.TestService;
+import org.springframework.integration.message.Message;
+import org.springframework.integration.message.StringMessage;
+
+/**
+ * @author Mark Fisher
+ */
+public class GatewayParserTests {
+
+ @Test
+ public void testOneWay() {
+ ApplicationContext context = new ClassPathXmlApplicationContext("gatewayParserTests.xml", this.getClass());
+ TestService service = (TestService) context.getBean("oneWay");
+ service.oneWay("foo");
+ MessageChannel channel = (MessageChannel) context.getBean("requestChannel");
+ Message> result = channel.receive(1000);
+ assertEquals("foo", result.getPayload());
+ }
+
+ @Test
+ public void testSolicitResponse() {
+ ApplicationContext context = new ClassPathXmlApplicationContext("gatewayParserTests.xml", this.getClass());
+ MessageChannel channel = (MessageChannel) context.getBean("replyChannel");
+ channel.send(new StringMessage("foo"));
+ TestService service = (TestService) context.getBean("solicitResponse");
+ String result = service.solicitResponse();
+ assertEquals("foo", result);
+ }
+
+ @Test
+ public void testRequestReply() {
+ ApplicationContext context = new ClassPathXmlApplicationContext("gatewayParserTests.xml", this.getClass());
+ MessageChannel requestChannel = (MessageChannel) context.getBean("requestChannel");
+ MessageChannel replyChannel = (MessageChannel) context.getBean("replyChannel");
+ this.startResponder(requestChannel, replyChannel);
+ TestService service = (TestService) context.getBean("requestReply");
+ String result = service.requestReply("foo");
+ assertEquals("foobar", result);
+ }
+
+ @Test
+ public void testRequestReplyWithMessageMapper() {
+ ApplicationContext context = new ClassPathXmlApplicationContext("gatewayParserTests.xml", this.getClass());
+ MessageChannel requestChannel = (MessageChannel) context.getBean("requestChannel");
+ MessageChannel replyChannel = (MessageChannel) context.getBean("replyChannel");
+ this.startResponder(requestChannel, replyChannel);
+ TestService service = (TestService) context.getBean("requestReplyWithMessageMapper");
+ String result = service.requestReply("foo");
+ assertEquals("foobar.mapped", result);
+ }
+
+ @Test
+ public void testRequestReplyWithMessageCreator() {
+ ApplicationContext context = new ClassPathXmlApplicationContext("gatewayParserTests.xml", this.getClass());
+ MessageChannel requestChannel = (MessageChannel) context.getBean("requestChannel");
+ MessageChannel replyChannel = (MessageChannel) context.getBean("replyChannel");
+ this.startResponder(requestChannel, replyChannel);
+ TestService service = (TestService) context.getBean("requestReplyWithMessageCreator");
+ String result = service.requestReply("foo");
+ assertEquals("created.foobar", result);
+ }
+
+
+ private void startResponder(final MessageChannel requestChannel, final MessageChannel replyChannel) {
+ Executors.newSingleThreadExecutor().execute(new Runnable() {
+ public void run() {
+ Message> request = requestChannel.receive();
+ Message> reply = new StringMessage(request.getPayload() + "bar");
+ reply.getHeader().setCorrelationId(request.getId());
+ replyChannel.send(reply);
+ }
+ });
+ }
+
+}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/TestMessageCreator.java b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/TestMessageCreator.java
new file mode 100644
index 0000000000..c26ceaa7c5
--- /dev/null
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/TestMessageCreator.java
@@ -0,0 +1,32 @@
+/*
+ * 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.config;
+
+import org.springframework.integration.message.Message;
+import org.springframework.integration.message.MessageCreator;
+import org.springframework.integration.message.StringMessage;
+
+/**
+ * @author Mark Fisher
+ */
+public class TestMessageCreator implements MessageCreator {
+
+ public Message createMessage(String s) {
+ return new StringMessage("created." + s);
+ }
+
+}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/TestMessageMapper.java b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/TestMessageMapper.java
new file mode 100644
index 0000000000..f0817a2809
--- /dev/null
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/TestMessageMapper.java
@@ -0,0 +1,31 @@
+/*
+ * 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.config;
+
+import org.springframework.integration.message.Message;
+import org.springframework.integration.message.MessageMapper;
+
+/**
+ * @author Mark Fisher
+ */
+public class TestMessageMapper implements MessageMapper {
+
+ public String mapMessage(Message message) {
+ return message.getPayload() + ".mapped";
+ }
+
+}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/gatewayParserTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/gatewayParserTests.xml
new file mode 100644
index 0000000000..a533214a85
--- /dev/null
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/gateway/config/gatewayParserTests.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+