From 4ce1b53300346c4edb5e24a09f5e53747863ed55 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 17 Nov 2006 00:35:11 +0000 Subject: [PATCH] Finishing up on JMS support. --- .../ServerTransportObjectSupport.java | 124 ++++++++++++++++++ .../http/MessageEndpointHandlerAdapter.java | 97 ++++++-------- sandbox/pom.xml | 18 +++ .../transport/jms/JmsTransportException.java | 33 ----- .../jms/JmsTransportInputStream.java | 19 ++- .../jms/JmsTransportMessageListener.java | 116 +++++++++------- .../jms/JmsTransportOutputStream.java | 57 ++++++-- .../jms/JmsTransportMessageListenerTest.java | 114 ++++++++++++++++ 8 files changed, 425 insertions(+), 153 deletions(-) create mode 100644 core/src/main/java/org/springframework/ws/transport/ServerTransportObjectSupport.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java create mode 100644 sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportMessageListenerTest.java diff --git a/core/src/main/java/org/springframework/ws/transport/ServerTransportObjectSupport.java b/core/src/main/java/org/springframework/ws/transport/ServerTransportObjectSupport.java new file mode 100644 index 00000000..78b9d76e --- /dev/null +++ b/core/src/main/java/org/springframework/ws/transport/ServerTransportObjectSupport.java @@ -0,0 +1,124 @@ +/* + * Copyright 2006 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.ws.transport; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; +import org.springframework.ws.NoEndpointFoundException; +import org.springframework.ws.WebServiceMessage; +import org.springframework.ws.WebServiceMessageFactory; +import org.springframework.ws.context.DefaultMessageContext; +import org.springframework.ws.context.MessageContext; +import org.springframework.ws.endpoint.MessageEndpoint; + +/** + * Convenience base class for server-side transport objects. Contains a {@link WebServiceMessageFactory}, and has + * methods for handling incoming WebServiceMessage requests. + * + * @author Arjen Poutsma + * @see #handle(TransportInputStream,TransportOutputStream,org.springframework.ws.endpoint.MessageEndpoint) + */ +public abstract class ServerTransportObjectSupport implements InitializingBean { + + /** + * Logger available to subclasses. + */ + protected final Log logger = LogFactory.getLog(getClass()); + + private WebServiceMessageFactory messageFactory; + + /** + * Returns the WebServiceMessageFactory. + */ + public WebServiceMessageFactory getMessageFactory() { + return messageFactory; + } + + /** + * Sets the WebServiceMessageFactory. + */ + public void setMessageFactory(WebServiceMessageFactory messageFactory) { + this.messageFactory = messageFactory; + } + + public void afterPropertiesSet() throws Exception { + Assert.notNull(messageFactory, "messageFactory is required"); + logger.info("Using message factory [" + messageFactory + "]"); + } + + protected final void handle(TransportInputStream tis, TransportOutputStream tos, MessageEndpoint endpoint) + throws Exception { + TransportContext previousTransportContext = TransportContextHolder.getTransportContext(); + TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos)); + + try { + WebServiceMessage messageRequest = getMessageFactory().createWebServiceMessage(tis); + MessageContext messageContext = new DefaultMessageContext(messageRequest, getMessageFactory()); + endpoint.invoke(messageContext); + if (!messageContext.hasResponse()) { + handleNoResponse(tis, tos); + } + else { + handleResponse(tis, tos, messageContext.getResponse()); + } + } + catch (NoEndpointFoundException ex) { + handleNoEndpointFound(tis, tos); + } + finally { + TransportContextHolder.setTransportContext(previousTransportContext); + } + } + + /** + * Invoked from handle() when no response is given. Default implementation does nothing. Can be + * overriden to set certain transport-specific headers. + * + * @param tis the transport input stream + * @param tos the transport output stream + */ + protected void handleNoResponse(TransportInputStream tis, TransportOutputStream tos) { + } + + /** + * Handles the sending of the response. Invoked from handle(). Default implementation writes the given + * response to the given TransportOutputStream. Can be overriden to set certain transport-specific + * headers. + * + * @param tis the transport input stream + * @param tos the transport output stream + * @param response the response message + * @see WebServiceMessage#writeTo(java.io.OutputStream) + */ + protected void handleResponse(TransportInputStream tis, TransportOutputStream tos, WebServiceMessage response) + throws Exception { + response.writeTo(tos); + } + + /** + * Invoked when no suitable endpoint is found. Default implementation does nothing. Can be overriden to set certain + * transport-specific headers. + * + * @param tis the transport input stream + * @param tos the transport output stream + */ + protected void handleNoEndpointFound(TransportInputStream tis, TransportOutputStream tos) { + } + +} diff --git a/core/src/main/java/org/springframework/ws/transport/http/MessageEndpointHandlerAdapter.java b/core/src/main/java/org/springframework/ws/transport/http/MessageEndpointHandlerAdapter.java index 1a4f5f74..92f44041 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/MessageEndpointHandlerAdapter.java +++ b/core/src/main/java/org/springframework/ws/transport/http/MessageEndpointHandlerAdapter.java @@ -20,47 +20,31 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ModelAndView; -import org.springframework.ws.NoEndpointFoundException; import org.springframework.ws.WebServiceMessage; -import org.springframework.ws.WebServiceMessageFactory; -import org.springframework.ws.context.DefaultMessageContext; -import org.springframework.ws.context.MessageContext; import org.springframework.ws.endpoint.MessageEndpoint; import org.springframework.ws.soap.SoapMessage; -import org.springframework.ws.transport.DefaultTransportContext; -import org.springframework.ws.transport.TransportContext; -import org.springframework.ws.transport.TransportContextHolder; +import org.springframework.ws.transport.ServerTransportObjectSupport; import org.springframework.ws.transport.TransportInputStream; import org.springframework.ws.transport.TransportOutputStream; /** * Adapter to use the MessageEndpoint interface with the generic DispatcherServlet. Requires a - * {@link WebServiceMessageFactory}, which is used to convert the incoming HttpServletRequest into a {@link - * WebServiceMessage}, and passes that context to the mapped MessageEndpoint. If a response is created, - * that is sent via the HttpServletResponse. + * WebServiceMessageFactory which is used to convert the incoming HttpServletRequest into a + * WebServiceMessage, and passes that context to the mapped MessageEndpoint. If a response is + * created, that is sent via the HttpServletResponse. *

* Note that the MessageDispatcher implements the MessageEndpoint interface, enabling this * adapter to function as a gateway to further message handling logic. * * @author Arjen Poutsma + * @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory) + * @see org.springframework.ws.WebServiceMessageFactory * @see org.springframework.ws.endpoint.MessageEndpoint * @see org.springframework.ws.MessageDispatcher */ -public class MessageEndpointHandlerAdapter implements HandlerAdapter, InitializingBean { - - private static final Log logger = LogFactory.getLog(MessageEndpointHandlerAdapter.class); - - private WebServiceMessageFactory messageFactory; - - public void setMessageFactory(WebServiceMessageFactory messageFactory) { - this.messageFactory = messageFactory; - } +public class MessageEndpointHandlerAdapter extends ServerTransportObjectSupport implements HandlerAdapter { public long getLastModified(HttpServletRequest request, Object handler) { return -1L; @@ -70,7 +54,9 @@ public class MessageEndpointHandlerAdapter implements HandlerAdapter, Initializi HttpServletResponse httpServletResponse, Object handler) throws Exception { if ("POST".equals(httpServletRequest.getMethod())) { - handlePost(httpServletRequest, (MessageEndpoint) handler, httpServletResponse); + TransportInputStream tis = new HttpServletTransportInputStream(httpServletRequest); + TransportOutputStream tos = new HttpServletTransportOutputStream(httpServletResponse); + handle(tis, tos, (MessageEndpoint) handler); return null; } else { @@ -82,44 +68,35 @@ public class MessageEndpointHandlerAdapter implements HandlerAdapter, Initializi return handler instanceof MessageEndpoint; } - public final void afterPropertiesSet() throws Exception { - Assert.notNull(messageFactory, "messageFactory is required"); - logger.info("Using message factory [" + messageFactory + "]"); + /** + * Sets the response code to 204, No Content. + */ + protected void handleNoResponse(TransportInputStream tis, TransportOutputStream tos) { + HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse(); + httpServletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT); } - private void handlePost(HttpServletRequest httpServletRequest, - MessageEndpoint endpoint, - HttpServletResponse httpServletResponse) throws Exception { - TransportInputStream tis = new HttpServletTransportInputStream(httpServletRequest); - TransportOutputStream tos = new HttpServletTransportOutputStream(httpServletResponse); + /** + * Sets the response code to 200, OK, for normal responses. Set the code to 500, Internal Server Error, in case of a + * SOAP Fault, + */ + protected void handleResponse(TransportInputStream tis, TransportOutputStream tos, WebServiceMessage response) + throws Exception { + HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse(); + if (response instanceof SoapMessage && ((SoapMessage) response).getSoapBody().hasFault()) { + httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + else { + httpServletResponse.setStatus(HttpServletResponse.SC_OK); + } + response.writeTo(tos); + } - TransportContext previousTransportContext = TransportContextHolder.getTransportContext(); - TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos)); - - try { - WebServiceMessage messageRequest = messageFactory.createWebServiceMessage(tis); - MessageContext messageContext = new DefaultMessageContext(messageRequest, messageFactory); - endpoint.invoke(messageContext); - if (!messageContext.hasResponse()) { - httpServletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT); - } - else { - WebServiceMessage messageResponse = messageContext.getResponse(); - if (messageResponse instanceof SoapMessage && - ((SoapMessage) messageResponse).getSoapBody().hasFault()) { - httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - else { - httpServletResponse.setStatus(HttpServletResponse.SC_OK); - } - messageResponse.writeTo(tos); - } - } - catch (NoEndpointFoundException ex) { - httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND); - } - finally { - TransportContextHolder.setTransportContext(previousTransportContext); - } + /** + * Sets the response code to 404, Not Found. + */ + protected void handleNoEndpointFound(TransportInputStream tis, TransportOutputStream tos) { + HttpServletResponse httpServletResponse = ((HttpServletTransportOutputStream) tos).getHttpServletResponse(); + httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND); } } diff --git a/sandbox/pom.xml b/sandbox/pom.xml index e4ace595..366df6c3 100644 --- a/sandbox/pom.xml +++ b/sandbox/pom.xml @@ -9,6 +9,24 @@ spring-ws-sandbox jar Spring WS Sandbox + + + spring-2.0 + + + spring.version + 2.0 + + + + + org.springframework + spring-jms + ${spring.version} + + + + diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java deleted file mode 100644 index 2590d624..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2006 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.ws.transport.jms; - -import org.springframework.ws.transport.TransportException; - -/** - * @author Arjen Poutsma - */ -public class JmsTransportException extends TransportException { - - public JmsTransportException(String string) { - super(string); - } - - public JmsTransportException(String string, Throwable throwable) { - super(string, throwable); - } -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportInputStream.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportInputStream.java index 9af1fff7..6a992aeb 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportInputStream.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportInputStream.java @@ -29,17 +29,34 @@ import org.springframework.ws.transport.TransportInputStream; import org.springframework.ws.transport.support.EnumerationIterator; /** + * JMS specific implementation of the TransportInputStream interface. Exposes a JMS + * TextMessage. + * * @author Arjen Poutsma + * @see #getTextMessage() */ public class JmsTransportInputStream extends TransportInputStream { private final TextMessage textMessage; - public JmsTransportInputStream(TextMessage textMessage) throws IOException { + /** + * Constructs a new instance of the JmsTransportInputStream using the provided JMS + * TextMessage. + * + * @param textMessage the JMS message + */ + public JmsTransportInputStream(TextMessage textMessage) { Assert.notNull(textMessage, "textMessage must not be null"); this.textMessage = textMessage; } + /** + * Returns the wrapped JMS TextMessage. + */ + public TextMessage getTextMessage() { + return textMessage; + } + protected InputStream createInputStream() throws IOException { try { return new ByteArrayInputStream(textMessage.getText().getBytes("UTF-8")); diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportMessageListener.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportMessageListener.java index 43f989b8..f35a467e 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportMessageListener.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportMessageListener.java @@ -16,94 +16,114 @@ package org.springframework.ws.transport.jms; -import java.io.IOException; +import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; +import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; +import org.springframework.jms.listener.SessionAwareMessageListener; +import org.springframework.jms.support.JmsUtils; import org.springframework.util.Assert; -import org.springframework.ws.NoEndpointFoundException; import org.springframework.ws.WebServiceMessage; -import org.springframework.ws.WebServiceMessageFactory; -import org.springframework.ws.context.DefaultMessageContext; -import org.springframework.ws.context.MessageContext; import org.springframework.ws.endpoint.MessageEndpoint; -import org.springframework.ws.transport.DefaultTransportContext; -import org.springframework.ws.transport.TransportContext; -import org.springframework.ws.transport.TransportContextHolder; +import org.springframework.ws.transport.ServerTransportObjectSupport; import org.springframework.ws.transport.TransportInputStream; import org.springframework.ws.transport.TransportOutputStream; /** + * JMS MessageListener that can be used to handle incoming JMS messages. Requires a + * WebServiceMessageFactory which is used to convert the incoming JMS TextMessage into a + * WebServiceMessage, and passes that context to the required MessageEndpoint. If a response + * is created, it is sent using a response JMS message. + *

+ * This class implements both MessageListener, for + *

+ * Note that the MessageDispatcher implements the MessageEndpoint interface, enabling this + * adapter to function as a gateway to further message handling logic. + * * @author Arjen Poutsma + * @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory) + * @see #setMessageEndpoint(org.springframework.ws.endpoint.MessageEndpoint) */ -public class JmsTransportMessageListener implements MessageListener, InitializingBean { - // TODO: implemement SessionAwareMessageListener +public class JmsTransportMessageListener extends ServerTransportObjectSupport + implements SessionAwareMessageListener, MessageListener, InitializingBean { private static final Log logger = LogFactory.getLog(JmsTransportMessageListener.class); - private WebServiceMessageFactory messageFactory; + private MessageEndpoint messageEndpoint; - private MessageEndpoint endpoint; + /** + * Returns the MessageEndpoint used by this listener. + */ + public MessageEndpoint getMessageEndpoint() { + return messageEndpoint; + } - public void setMessageFactory(WebServiceMessageFactory messageFactory) { - this.messageFactory = messageFactory; + /** + * Sets the MessageEndpoint used by this listener. + */ + public void setMessageEndpoint(MessageEndpoint messageEndpoint) { + this.messageEndpoint = messageEndpoint; } public void afterPropertiesSet() throws Exception { - Assert.notNull(messageFactory, "messageFactory is required"); - logger.info("Using message factory [" + messageFactory + "]"); + Assert.notNull(getMessageFactory(), "messageFactory is required"); + Assert.notNull(getMessageEndpoint(), "messageEndpoint must not be null"); + logger.info("Using message factory [" + getMessageFactory() + "]"); } public void onMessage(Message message) { + try { + onMessage(message, null); + } + catch (JMSException ex) { + logger.error("Could not handle message: " + ex.getMessage(), ex); + } + } + + public void onMessage(Message message, Session session) throws JMSException { if (message instanceof TextMessage) { - TextMessage textMessage = (TextMessage) message; try { - handleTextMessage(textMessage); - } - catch (IOException ex) { - logger.error("Could not create message: " + ex.getMessage(), ex); + TransportInputStream tis = new JmsTransportInputStream((TextMessage) message); + TransportOutputStream tos; + if (session == null) { + tos = null; + } + else { + tos = new JmsTransportOutputStream(session, ((TextMessage) message).getJMSCorrelationID()); + } + handle(tis, tos, getMessageEndpoint()); } catch (Exception ex) { - logger.error("Could not handle message: " + ex.getMessage(), ex); + throw new JMSException(ex.getMessage()); } } else { - throw new JmsTransportException("JmsTransportMessageListener can only handle TextMessages"); + throw new IllegalArgumentException("JmsTransportMessageListener can only handle TextMessages"); } } - private void handleTextMessage(TextMessage textMessage) throws Exception { - TransportInputStream tis = new JmsTransportInputStream(textMessage); - TransportOutputStream tos = new JmsTransportOutputStream(getSession()); - - TransportContext previousTransportContext = TransportContextHolder.getTransportContext(); - TransportContextHolder.setTransportContext(new DefaultTransportContext(tis, tos)); - - try { - WebServiceMessage messageRequest = messageFactory.createWebServiceMessage(tis); - MessageContext messageContext = new DefaultMessageContext(messageRequest, messageFactory); - endpoint.invoke(messageContext); - if (messageContext.hasResponse()) { - WebServiceMessage messageResponse = messageContext.getResponse(); - messageResponse.writeTo(tos); + protected void handleResponse(TransportInputStream tis, TransportOutputStream tos, WebServiceMessage response) + throws Exception { + if (tos != null) { + TextMessage requestMessage = ((JmsTransportInputStream) tis).getTextMessage(); + TextMessage responseMessage = ((JmsTransportOutputStream) tos).getTextMessage(); + Session session = ((JmsTransportOutputStream) tos).getSession(); + MessageProducer producer = session.createProducer(requestMessage.getJMSReplyTo()); + try { + producer.send(responseMessage); + } + finally { + JmsUtils.closeMessageProducer(producer); } } - catch (NoEndpointFoundException ex) { - // do nothing + else { + logger.warn("JMS Session is not available, sending of response is impossible"); } - finally { - TransportContextHolder.setTransportContext(previousTransportContext); - } - - } - - private Session getSession() { - //TODO implement - throw new UnsupportedOperationException("Not implemented"); } } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportOutputStream.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportOutputStream.java index b19464f8..00104fce 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportOutputStream.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportOutputStream.java @@ -24,26 +24,67 @@ import javax.jms.Session; import javax.jms.TextMessage; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import org.springframework.ws.transport.TransportOutputStream; /** + * JMS specific implementation of the TransportOutputStream interface. Exposes a JMS + * TextMessage, constructed lazily using a Session. + * * @author Arjen Poutsma + * @see #getTextMessage() */ public class JmsTransportOutputStream extends TransportOutputStream { private TextMessage textMessage; - private Session session; + private final Session session; + private String correlationId; + + /** + * Constructs a new instance of the JmsTransportOutputStream with the given session. + * + * @param session the JMS session + * @see javax.jms.Message#setJMSCorrelationID(String) + */ public JmsTransportOutputStream(Session session) { Assert.notNull(session, "session must not be null"); this.session = session; } - private TextMessage getTextMessage() throws IOException { + /** + * Constructs a new instance of the JmsTransportOutputStream with the given session and correlation ID. + * The correlation ID is used for creating a response to a request JMS message. + * + * @param session the JMS session + * @param correlationId the correlation id + * @see javax.jms.Message#setJMSCorrelationID(String) + */ + public JmsTransportOutputStream(Session session, String correlationId) { + Assert.notNull(session, "session must not be null"); + Assert.hasLength(correlationId, "correlationId must not be null"); + this.session = session; + this.correlationId = correlationId; + } + + /** + * Returns the wrapped JMS Session. + */ + public Session getSession() { + return session; + } + + /** + * Returns the wrapped JMS TextMessage. Created lazily. + */ + public TextMessage getTextMessage() throws IOException { if (textMessage == null) { try { textMessage = session.createTextMessage(); + if (StringUtils.hasLength(correlationId)) { + textMessage.setJMSCorrelationID(correlationId); + } } catch (JMSException ex) { throw new IOException("Could not create text message: " + ex.getMessage()); @@ -53,7 +94,7 @@ public class JmsTransportOutputStream extends TransportOutputStream { } protected OutputStream getOutputStream() throws IOException { - return new TextMessageOutputStream(getTextMessage()); + return new TextMessageOutputStream(); } public void addHeader(String name, String value) throws IOException { @@ -65,17 +106,11 @@ public class JmsTransportOutputStream extends TransportOutputStream { } } - private static class TextMessageOutputStream extends ByteArrayOutputStream { - - private final TextMessage textMessage; - - public TextMessageOutputStream(TextMessage textMessage) { - this.textMessage = textMessage; - } + private class TextMessageOutputStream extends ByteArrayOutputStream { public void close() throws IOException { try { - textMessage.setText(new String(toString("UTF-8"))); + getTextMessage().setText(new String(toString("UTF-8"))); } catch (JMSException ex) { throw new IOException("Could not set message text: " + ex.getMessage()); diff --git a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportMessageListenerTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportMessageListenerTest.java new file mode 100644 index 00000000..cd817e57 --- /dev/null +++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportMessageListenerTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2006 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.ws.transport.jms; + +import javax.jms.BytesMessage; +import javax.jms.Destination; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +import junit.framework.TestCase; +import org.easymock.MockControl; +import org.springframework.ws.MockWebServiceMessageFactory; +import org.springframework.ws.context.MessageContext; +import org.springframework.ws.endpoint.MessageEndpoint; + +public class JmsTransportMessageListenerTest extends TestCase { + + private static final String REQUEST = " \n" + " \n" + + " \n" + " DIS\n" + + " \n" + " \n" + ""; + + private JmsTransportMessageListener messageListener; + + private MockControl messageControl; + + private TextMessage requestMock; + + protected void setUp() throws Exception { + messageListener = new JmsTransportMessageListener(); + messageControl = MockControl.createControl(TextMessage.class); + requestMock = (TextMessage) messageControl.getMock(); + messageListener.setMessageFactory(new MockWebServiceMessageFactory()); + } + + public void testOnMessageInvalidMessage() throws Exception { + MockControl mockControl = MockControl.createControl(BytesMessage.class); + BytesMessage bytesMessage = (BytesMessage) mockControl.getMock(); + try { + messageListener.onMessage(bytesMessage); + fail("Expected IllegalArgumentException"); + } + catch (IllegalArgumentException ex) { + // expected + } + } + + public void testOnMessageNoResponse() throws Exception { + messageControl.expectAndReturn(requestMock.getText(), REQUEST); + messageControl.replay(); + + MessageEndpoint endpoint = new MessageEndpoint() { + + public void invoke(MessageContext messageContext) throws Exception { + } + }; + messageListener.setMessageEndpoint(endpoint); + + messageListener.onMessage(requestMock); + + messageControl.verify(); + } + + public void testOnMessageResponse() throws Exception { + MockControl sessionControl = MockControl.createControl(Session.class); + Session sessionMock = (Session) sessionControl.getMock(); + MockControl producerControl = MockControl.createControl(MessageProducer.class); + MessageProducer producerMock = (MessageProducer) producerControl.getMock(); + TextMessage responseMock = (TextMessage) messageControl.getMock(); + messageControl.expectAndReturn(requestMock.getText(), REQUEST); + String correlationId = "correlationId"; + Destination replyTo = new Destination() { + }; + messageControl.expectAndReturn(requestMock.getJMSCorrelationID(), correlationId); + sessionControl.expectAndReturn(sessionMock.createTextMessage(), responseMock); + responseMock.setJMSCorrelationID(correlationId); + messageControl.expectAndReturn(requestMock.getJMSReplyTo(), replyTo); + sessionControl.expectAndReturn(sessionMock.createProducer(replyTo), producerMock); + producerMock.send(responseMock); + messageControl.replay(); + sessionControl.replay(); + producerControl.replay(); + + MessageEndpoint endpoint = new MessageEndpoint() { + + public void invoke(MessageContext messageContext) throws Exception { + messageContext.getResponse(); + } + }; + messageListener.setMessageEndpoint(endpoint); + + messageListener.onMessage(requestMock, sessionMock); + + messageControl.verify(); + sessionControl.verify(); + producerControl.verify(); + } +} \ No newline at end of file