diff --git a/spring-integration-adapters/.classpath b/spring-integration-adapters/.classpath
index 28994fe72a..1f743c678d 100644
--- a/spring-integration-adapters/.classpath
+++ b/spring-integration-adapters/.classpath
@@ -6,6 +6,7 @@
+
@@ -18,6 +19,7 @@
+
diff --git a/spring-integration-adapters/ivy.xml b/spring-integration-adapters/ivy.xml
index 8a6feb4314..902635a383 100644
--- a/spring-integration-adapters/ivy.xml
+++ b/spring-integration-adapters/ivy.xml
@@ -23,6 +23,7 @@
+
@@ -30,6 +31,7 @@
+
\ No newline at end of file
diff --git a/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/AbstractMessageHandlingSourceAdapter.java b/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/AbstractMessageHandlingSourceAdapter.java
index e180a45504..4f1e321f6a 100644
--- a/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/AbstractMessageHandlingSourceAdapter.java
+++ b/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/AbstractMessageHandlingSourceAdapter.java
@@ -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.
@@ -75,6 +75,10 @@ public abstract class AbstractMessageHandlingSourceAdapter implements SourceAdap
}
public final void afterPropertiesSet() throws Exception {
+ if (this.channel == null) {
+ throw new MessagingConfigurationException("The 'channel' property of '" +
+ this.getClass().getName() + "' must not be null.");
+ }
synchronized (this.lifecycleMonitor) {
if (this.initialized) {
return;
diff --git a/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/httpinvoker/HttpInvokerSourceAdapter.java b/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/httpinvoker/HttpInvokerSourceAdapter.java
new file mode 100644
index 0000000000..2c5cfdabc9
--- /dev/null
+++ b/spring-integration-adapters/src/main/java/org/springframework/integration/adapter/httpinvoker/HttpInvokerSourceAdapter.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.integration.adapter.AbstractMessageHandlingSourceAdapter;
+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;
+
+/**
+ * A source channel adapter for HttpInvoker-based remoting.
+ *
+ * @author Mark Fisher
+ */
+public class HttpInvokerSourceAdapter extends AbstractMessageHandlingSourceAdapter implements HttpRequestHandler {
+
+ private volatile HttpInvokerServiceExporter exporter;
+
+
+ public HttpInvokerSourceAdapter(MessageChannel channel) {
+ Assert.notNull(channel, "'channel' must not be null");
+ this.setChannel(channel);
+ }
+
+
+ public void initialize() {
+ HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
+ exporter.setService(this);
+ exporter.setServiceInterface(MessageHandler.class);
+ exporter.afterPropertiesSet();
+ this.exporter = exporter;
+ }
+
+ public void handleRequest(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ if (this.exporter == null) {
+ throw new MessageHandlingException("adapter has not been initialized");
+ }
+ this.exporter.handleRequest(request, response);
+ }
+
+}
diff --git a/spring-integration-adapters/src/test/java/org/springframework/integration/adapter/httpinvoker/HttpInvokerSourceAdapterTests.java b/spring-integration-adapters/src/test/java/org/springframework/integration/adapter/httpinvoker/HttpInvokerSourceAdapterTests.java
new file mode 100644
index 0000000000..c4df56366e
--- /dev/null
+++ b/spring-integration-adapters/src/test/java/org/springframework/integration/adapter/httpinvoker/HttpInvokerSourceAdapterTests.java
@@ -0,0 +1,108 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.concurrent.Executors;
+
+import org.junit.Test;
+
+import org.springframework.integration.channel.MessageChannel;
+import org.springframework.integration.channel.SimpleChannel;
+import org.springframework.integration.message.Message;
+import org.springframework.integration.message.StringMessage;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.remoting.support.RemoteInvocation;
+import org.springframework.remoting.support.RemoteInvocationResult;
+
+/**
+ * @author Mark Fisher
+ */
+public class HttpInvokerSourceAdapterTests {
+
+ @Test
+ public void testRequestOnly() throws Exception {
+ MessageChannel channel = new SimpleChannel();
+ HttpInvokerSourceAdapter adapter = new HttpInvokerSourceAdapter(channel);
+ adapter.setExpectReply(false);
+ adapter.afterPropertiesSet();
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ request.setContent(createRequestContent(new StringMessage("test")));
+ adapter.handleRequest(request, response);
+ Message> message = channel.receive(500);
+ assertNotNull(message);
+ assertEquals("test", message.getPayload());
+ }
+
+ @Test
+ public void testRequestExpectingReply() throws Exception {
+ final MessageChannel channel = new SimpleChannel();
+ Executors.newSingleThreadExecutor().execute(new Runnable() {
+ public void run() {
+ Message> message = channel.receive();
+ MessageChannel replyChannel = (MessageChannel) message.getHeader().getReturnAddress();
+ replyChannel.send(new StringMessage(message.getPayload().toString().toUpperCase()));
+ }
+ });
+ HttpInvokerSourceAdapter adapter = new HttpInvokerSourceAdapter(channel);
+ adapter.setExpectReply(true);
+ adapter.afterPropertiesSet();
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ request.setContent(createRequestContent(new StringMessage("test")));
+ adapter.handleRequest(request, response);
+ Message> reply = extractMessageFromResponse(response);
+ assertEquals("TEST", reply.getPayload());
+ }
+
+
+ private static byte[] createRequestContent(Message> message) throws IOException {
+ RemoteInvocation invocation = new RemoteInvocation(
+ "handle", new Class[] { Message.class }, new Object[] { message });
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ try {
+ oos.writeObject(invocation);
+ oos.flush();
+ }
+ finally {
+ oos.close();
+ }
+ return baos.toByteArray();
+ }
+
+ private static Message> extractMessageFromResponse(MockHttpServletResponse response) throws IOException, ClassNotFoundException {
+ byte[] responseContent = response.getContentAsByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(responseContent);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ RemoteInvocationResult remoteResult = (RemoteInvocationResult) ois.readObject();
+ Object resultValue = remoteResult.getValue();
+ assertTrue(resultValue instanceof Message);
+ return (Message>) resultValue;
+ }
+
+}