diff --git a/core/pom.xml b/core/pom.xml index 2c5dfe72..90943624 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -157,7 +157,7 @@ wsdl4j wsdl4j - + javax.xml.soap saaj-api diff --git a/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java b/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java index cdaba873..feadf747 100644 --- a/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java +++ b/core/src/main/java/org/springframework/ws/client/core/WebServiceTemplate.java @@ -18,6 +18,7 @@ package org.springframework.ws.client.core; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.net.URI; import java.util.List; import javax.xml.transform.Result; import javax.xml.transform.Source; @@ -25,8 +26,6 @@ import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @@ -54,6 +53,9 @@ import org.springframework.ws.transport.context.TransportContextHolder; import org.springframework.ws.transport.http.HttpUrlConnectionMessageSender; import org.springframework.ws.transport.support.DefaultStrategiesHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * The central class for client-side Web services. It provides a message-driven approach to sending and * receiving {@link WebServiceMessage} instances. @@ -67,8 +69,8 @@ import org.springframework.ws.transport.support.DefaultStrategiesHelper; * FaultMessageResolver} can be defined with with {@link #setFaultMessageResolver(FaultMessageResolver) * faultMessageResolver} property. If this property is set to null, no fault resolving is performed. *

- * This template uses the following algorithm for sending and receiving.

  1. Call to {@link - * #createConnection(String) createConnection()}.
  2. Call to {@link WebServiceMessageFactory#createWebServiceMessage() + * This template uses the following algorithm for sending and receiving.
    1. Call to {@link #createConnection(URI) + * createConnection()}.
    2. Call to {@link WebServiceMessageFactory#createWebServiceMessage() * createWebServiceMessage()} on the registered message factory to create a request message.
    3. Invoke {@link * WebServiceMessageCallback#doWithMessage(WebServiceMessage) doWithMessage()} on the request callback, if any. This * step stores content in the request message, based on Source, marshalling, etc.
    4. Call {@link @@ -396,7 +398,8 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService TransportContext previousTransportContext = TransportContextHolder.getTransportContext(); WebServiceConnection connection = null; try { - connection = createConnection(uri); + URI theUri = URI.create(uri); + connection = createConnection(theUri); TransportContextHolder.setTransportContext(new DefaultTransportContext(connection)); WebServiceMessage request = getMessageFactory().createWebServiceMessage(); if (requestCallback != null) { @@ -418,7 +421,7 @@ public class WebServiceTemplate extends WebServiceAccessor implements WebService } else { if (logger.isDebugEnabled()) { - logger.debug("Received no response for request [" + request + "]"); + messageTracingLogger.debug("Received no response for request [" + request + "]"); } return null; } diff --git a/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java b/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java index 4af52c98..a317d9fa 100644 --- a/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java +++ b/core/src/main/java/org/springframework/ws/client/support/WebServiceAccessor.java @@ -17,6 +17,7 @@ package org.springframework.ws.client.support; import java.io.IOException; +import java.net.URI; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; @@ -61,7 +62,7 @@ public abstract class WebServiceAccessor extends TransformerObjectSupport implem *

      * This message sender will be used to resolve an URI to a {@link WebServiceConnection}. * - * @see #createConnection(String) + * @see #createConnection(URI) */ public void setMessageSender(WebServiceMessageSender messageSender) { Assert.notNull(messageSender, "'messageSender' must not be null"); @@ -73,7 +74,7 @@ public abstract class WebServiceAccessor extends TransformerObjectSupport implem *

      * These message senders will be used to resolve an URI to a {@link WebServiceConnection}. * - * @see #createConnection(String) + * @see #createConnection(URI) */ public void setMessageSenders(WebServiceMessageSender[] messageSenders) { Assert.notEmpty(messageSenders, "'messageSenders' must not be empty"); @@ -89,15 +90,15 @@ public abstract class WebServiceAccessor extends TransformerObjectSupport implem * Creates a connection to the given URI, or throws an exception when it cannot be resolved. *

      * Default implementation iterates over all configured {@link WebServiceMessageSender} objects, and calls {@link - * WebServiceMessageSender#supports(String)} for each of them. If the sender supports the parameter URI, it creates - * a connection using {@link WebServiceMessageSender#createConnection(String)} . + * WebServiceMessageSender#supports(URI)} for each of them. If the sender supports the parameter URI, it creates a + * connection using {@link WebServiceMessageSender#createConnection(URI)} . * * @param uri the URI to open a connection to * @return the created connection * @throws IllegalArgumentException when the uri cannot be resolved * @throws IOException when an I/O error occurs */ - protected WebServiceConnection createConnection(String uri) throws IOException { + protected WebServiceConnection createConnection(URI uri) throws IOException { Assert.notEmpty(getMessageSenders(), "Property 'messageSenders' is required"); WebServiceMessageSender[] messageSenders = getMessageSenders(); for (int i = 0; i < messageSenders.length; i++) { diff --git a/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java b/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java index 9eb5f286..86506b4d 100644 --- a/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java +++ b/core/src/main/java/org/springframework/ws/server/MessageDispatcher.java @@ -23,8 +23,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanNameAware; @@ -50,6 +48,9 @@ import org.springframework.ws.soap.server.SoapMessageDispatcher; import org.springframework.ws.transport.WebServiceMessageReceiver; import org.springframework.ws.transport.support.DefaultStrategiesHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * Central dispatcher for use within Spring-WS, dispatching Web service messages to registered endpoints. *

      @@ -170,7 +171,7 @@ public class MessageDispatcher implements WebServiceMessageReceiver, BeanNameAwa requestStream.toString("UTF-8") + "]"); } else if (messageTracingLogger.isDebugEnabled()) { - messageTracingLogger.debug("Sendt response [" + messageContext.getResponse() + "] for request [" + + messageTracingLogger.debug("Sent response [" + messageContext.getResponse() + "] for request [" + messageContext.getRequest() + "]"); } } diff --git a/core/src/main/java/org/springframework/ws/transport/WebServiceMessageSender.java b/core/src/main/java/org/springframework/ws/transport/WebServiceMessageSender.java index dcb42c6c..49df55be 100644 --- a/core/src/main/java/org/springframework/ws/transport/WebServiceMessageSender.java +++ b/core/src/main/java/org/springframework/ws/transport/WebServiceMessageSender.java @@ -17,6 +17,7 @@ package org.springframework.ws.transport; import java.io.IOException; +import java.net.URI; import org.springframework.ws.WebServiceMessage; @@ -39,7 +40,7 @@ public interface WebServiceMessageSender { * @return the new connection * @throws IOException in case of I/O errors */ - WebServiceConnection createConnection(String uri) throws IOException; + WebServiceConnection createConnection(URI uri) throws IOException; /** * Does this {@link WebServiceMessageSender} support the supplied URI? @@ -47,6 +48,6 @@ public interface WebServiceMessageSender { * @param uri the URI to be checked * @return true if this WebServiceMessageSender supports the supplied URI */ - boolean supports(String uri); + boolean supports(URI uri); } diff --git a/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java index 50bfb797..81a2d311 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java +++ b/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java @@ -16,7 +16,8 @@ package org.springframework.ws.transport.http; -import org.springframework.util.StringUtils; +import java.net.URI; + import org.springframework.ws.transport.WebServiceMessageSender; /** @@ -30,14 +31,6 @@ public abstract class AbstractHttpWebServiceMessageSender implements WebServiceM private boolean acceptGzipEncoding = true; - protected static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding"; - - protected static final String ENCODING_GZIP = "gzip"; - - protected static final String HTTP_SCHEME = "http://"; - - protected static final String HTTPS_SCHEME = "https://"; - /** * Return whether to accept GZIP encoding, that is, whether to send the HTTP Accept-Encoding header * with gzip as value. @@ -57,7 +50,8 @@ public abstract class AbstractHttpWebServiceMessageSender implements WebServiceM this.acceptGzipEncoding = acceptGzipEncoding; } - public boolean supports(String uri) { - return StringUtils.hasLength(uri) && (uri.startsWith(HTTP_SCHEME) || uri.startsWith(HTTPS_SCHEME)); + public boolean supports(URI uri) { + return uri.getScheme().equals(HttpTransportConstants.HTTP_URI_SCHEME) || + uri.getScheme().equals(HttpTransportConstants.HTTPS_URI_SCHEME); } } diff --git a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java index c3e9dfa0..63df369e 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java +++ b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java @@ -17,6 +17,12 @@ package org.springframework.ws.transport.http; import java.io.IOException; +import java.net.URI; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; +import org.springframework.ws.transport.WebServiceConnection; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; @@ -26,10 +32,6 @@ import org.apache.commons.httpclient.NTCredentials; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; -import org.springframework.ws.transport.WebServiceConnection; /** * WebServiceMessageSender implementation that uses Jakarta @@ -130,10 +132,11 @@ public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSende } } - public WebServiceConnection createConnection(String uri) throws IOException { - PostMethod postMethod = new PostMethod(uri); + public WebServiceConnection createConnection(URI uri) throws IOException { + PostMethod postMethod = new PostMethod(uri.toString()); if (isAcceptGzipEncoding()) { - postMethod.addRequestHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); + postMethod.addRequestHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING, + HttpTransportConstants.CONTENT_ENCODING_GZIP); } return new CommonsHttpConnection(getHttpClient(), postMethod); } diff --git a/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java b/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java index 3c598ffc..6a46c6a9 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java +++ b/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java @@ -29,6 +29,9 @@ public interface HttpTransportConstants extends TransportConstants { /** The "Content-Encoding" header. */ String HEADER_CONTENT_ENCODING = "Content-Encoding"; + /** The "Accept-Encoding" header. */ + String HEADER_ACCEPT_ENCODING = "Accept-Encoding"; + /** Header value that indicates a compressed "Content-Encoding". */ String CONTENT_ENCODING_GZIP = "gzip"; @@ -43,4 +46,10 @@ public interface HttpTransportConstants extends TransportConstants { /** The "500 Server Error" status code. */ int STATUS_INTERNAL_SERVER_ERROR = 500; + + /** The "http" URI scheme. */ + String HTTP_URI_SCHEME = "http"; + + /** The "https" URI scheme. */ + String HTTPS_URI_SCHEME = "https"; } diff --git a/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java index 13d5e256..f91ad4f4 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java +++ b/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java @@ -18,6 +18,7 @@ package org.springframework.ws.transport.http; import java.io.IOException; import java.net.HttpURLConnection; +import java.net.URI; import java.net.URL; import java.net.URLConnection; @@ -39,8 +40,8 @@ public class HttpUrlConnectionMessageSender extends AbstractHttpWebServiceMessag private static final String HTTP_METHOD_POST = "POST"; - public WebServiceConnection createConnection(String uri) throws IOException { - URL url = new URL(uri); + public WebServiceConnection createConnection(URI uri) throws IOException { + URL url = uri.toURL(); URLConnection connection = url.openConnection(); if (!(connection instanceof HttpURLConnection)) { throw new HttpTransportException("URI [" + uri + "] is not an HTTP URL"); @@ -52,7 +53,8 @@ public class HttpUrlConnectionMessageSender extends AbstractHttpWebServiceMessag httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); if (isAcceptGzipEncoding()) { - httpURLConnection.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); + httpURLConnection.setRequestProperty(HttpTransportConstants.HEADER_ACCEPT_ENCODING, + HttpTransportConstants.CONTENT_ENCODING_GZIP); } return new HttpUrlConnection(httpURLConnection); } diff --git a/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java b/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java index d923c363..d57b66a2 100644 --- a/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java +++ b/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java @@ -17,14 +17,12 @@ package org.springframework.ws.client.core; import java.io.IOException; +import java.net.URI; -import org.custommonkey.xmlunit.XMLTestCase; -import org.easymock.MockControl; import org.springframework.oxm.Marshaller; import org.springframework.oxm.Unmarshaller; import org.springframework.ws.MockWebServiceMessage; import org.springframework.ws.MockWebServiceMessageFactory; -import org.springframework.ws.WebServiceMessage; import org.springframework.ws.client.WebServiceTransportException; import org.springframework.ws.transport.FaultAwareWebServiceConnection; import org.springframework.ws.transport.WebServiceConnection; @@ -32,6 +30,9 @@ import org.springframework.ws.transport.WebServiceMessageSender; import org.springframework.xml.transform.StringResult; import org.springframework.xml.transform.StringSource; +import org.custommonkey.xmlunit.XMLTestCase; +import org.easymock.MockControl; + public class WebServiceTemplateTest extends XMLTestCase { private WebServiceTemplate template; @@ -42,27 +43,25 @@ public class WebServiceTemplateTest extends XMLTestCase { private MockWebServiceMessageFactory messageFactory; - private static final String URI = "uri"; - protected void setUp() throws Exception { template = new WebServiceTemplate(); messageFactory = new MockWebServiceMessageFactory(); template.setMessageFactory(messageFactory); connectionControl = MockControl.createStrictControl(FaultAwareWebServiceConnection.class); connectionMock = (FaultAwareWebServiceConnection) connectionControl.getMock(); + final URI expectedUri = new URI("http://www.springframework.org/spring-ws"); template.setMessageSender(new WebServiceMessageSender() { - public WebServiceConnection createConnection(String uri) throws IOException { + public WebServiceConnection createConnection(URI uri) throws IOException { return connectionMock; } - public boolean supports(String uri) { - assertEquals("Invalid uri", URI, uri); + public boolean supports(URI uri) { + assertEquals("Invalid uri", expectedUri, uri); return true; } }); - - template.setDefaultUri(URI); + template.setDefaultUri(expectedUri.toString()); } public void testMarshalAndSendNoMarshallerSet() throws Exception { @@ -131,7 +130,7 @@ public class WebServiceTemplateTest extends XMLTestCase { connectionMock.close(); connectionControl.replay(); - Object result = (WebServiceMessage) template.sendAndReceive(null, extractorMock); + Object result = template.sendAndReceive(null, extractorMock); assertNull("Invalid response", result); extractorControl.verify(); connectionControl.verify(); @@ -340,14 +339,14 @@ public class WebServiceTemplateTest extends XMLTestCase { } public void testSendAndReceiveCustomUri() throws Exception { - final String customUri = "customUri"; + final URI customUri = new URI("http://www.springframework.org/spring-ws/custom"); template.setMessageSender(new WebServiceMessageSender() { - public WebServiceConnection createConnection(String uri) throws IOException { + public WebServiceConnection createConnection(URI uri) throws IOException { return connectionMock; } - public boolean supports(String uri) { + public boolean supports(URI uri) { assertEquals("Invalid uri", customUri, uri); return true; } @@ -375,7 +374,7 @@ public class WebServiceTemplateTest extends XMLTestCase { connectionMock.close(); connectionControl.replay(); - Object result = template.sendAndReceive(customUri, requestCallback, extractorMock); + Object result = template.sendAndReceive(customUri.toString(), requestCallback, extractorMock); assertEquals("Invalid response", extracted, result); callbackControl.verify(); diff --git a/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java b/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java index 20267265..5bf0a7dc 100644 --- a/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java +++ b/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java @@ -18,6 +18,7 @@ package org.springframework.ws.transport.http; import java.io.IOException; import java.io.OutputStream; +import java.net.URI; import java.util.zip.GZIPOutputStream; import javax.servlet.Servlet; import javax.servlet.ServletException; @@ -34,11 +35,6 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; -import org.custommonkey.xmlunit.XMLTestCase; -import org.custommonkey.xmlunit.XMLUnit; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHolder; import org.springframework.util.FileCopyUtils; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.WebServiceMessageFactory; @@ -49,6 +45,12 @@ import org.springframework.ws.transport.WebServiceConnection; import org.springframework.xml.transform.StringResult; import org.springframework.xml.transform.StringSource; +import org.custommonkey.xmlunit.XMLTestCase; +import org.custommonkey.xmlunit.XMLUnit; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.servlet.Context; +import org.mortbay.jetty.servlet.ServletHolder; + public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase extends XMLTestCase { private Server jettyServer; @@ -77,7 +79,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext private Context jettyContext; - private static final String URI = "http://localhost:8888/"; + private static final String URI_STRING = "http://localhost:8888/"; private MessageFactory saajMessageFactory; @@ -147,7 +149,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext jettyContext.addServlet(new ServletHolder(servlet), "/"); jettyServer.start(); FaultAwareWebServiceConnection connection = - (FaultAwareWebServiceConnection) messageSender.createConnection(URI); + (FaultAwareWebServiceConnection) messageSender.createConnection(new URI(URI_STRING)); SOAPMessage request = createRequest(); try { connection.send(new SaajSoapMessage(request)); @@ -163,7 +165,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext jettyContext.addServlet(new ServletHolder(servlet), "/"); jettyServer.start(); FaultAwareWebServiceConnection connection = - (FaultAwareWebServiceConnection) messageSender.createConnection(URI); + (FaultAwareWebServiceConnection) messageSender.createConnection(new URI(URI_STRING)); SOAPMessage request = createRequest(); try { connection.send(new SaajSoapMessage(request)); @@ -189,7 +191,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext jettyContext.addServlet(new ServletHolder(servlet), "/"); jettyServer.start(); - WebServiceConnection connection = messageSender.createConnection(URI); + WebServiceConnection connection = messageSender.createConnection(new URI(URI_STRING)); SOAPMessage request = createRequest(); try { connection.send(new SaajSoapMessage(request)); diff --git a/support/pom.xml b/support/pom.xml index 6b019557..d1f1934d 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -73,6 +73,22 @@ org.springframework spring-jms + + + xml-apis + xml-apis + provided + + + xalan + xalan + provided + + + xerces + xercesImpl + provided + javax.xml.soap diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageReceiver.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageReceiver.java index 258e331b..bd538a83 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageReceiver.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageReceiver.java @@ -51,6 +51,5 @@ public class JmsMessageReceiver extends SimpleWebServiceMessageReceiverObjectSup throw new IllegalArgumentException( "Wrong message type: [" + request.getClass() + "]. Only BytesMessages can be handled."); } - } } diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java index ca72dfc7..eed92cbf 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java @@ -17,84 +17,108 @@ package org.springframework.ws.transport.jms; import java.io.IOException; +import java.net.URI; import javax.jms.BytesMessage; import javax.jms.Connection; -import javax.jms.ConnectionFactory; +import javax.jms.Destination; import javax.jms.JMSException; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.Topic; -import org.springframework.jms.support.destination.DestinationResolver; -import org.springframework.jms.support.destination.DynamicDestinationResolver; -import org.springframework.util.Assert; +import org.springframework.jms.connection.ConnectionFactoryUtils; +import org.springframework.jms.support.JmsUtils; +import org.springframework.jms.support.destination.JmsDestinationAccessor; import org.springframework.util.StringUtils; import org.springframework.ws.transport.WebServiceConnection; import org.springframework.ws.transport.WebServiceMessageSender; +import org.springframework.ws.transport.jms.support.JmsTransportUtils; /** - * {@link WebServiceMessageSender} implementation that uses JMS. + * {@link WebServiceMessageSender} implementation that uses JMS {@link BytesMessage}. *

      - * This message sender sends the request message of the queue configured with either the queue or - * queueName property. It creates a temporary queue for the response message. For both request and response - * {@link BytesMessage}s are used. + * This message sender supports URI's of the following format:

      jms:destination[?param-name=param-value][&param-name=param-value]* + *
      where the characters :, ?, and & stand for + * themselves. The destination represents the name of the {@link Queue} or {@link Topic} that will be resolved by + * the {@link #getDestinationResolver() destination resolver}. Valid param-name include: + *

      + *

      + * + * + *
      param-nameDescription
      deliveryModeIndicates whether the request message is persistent or not. This may be + * PERSISTENT or NON_PERSISTENT. See {@link MessageProducer#setDeliveryMode(int)}
      timeToLiveThe lifetime, in milliseconds, of the request message. See {@link + * MessageProducer#setTimeToLive(long)}
      priorityThe JMS priority (0-9) associated + * with the request message. See {@link MessageProducer#setPriority(int)}
      replyToNameThe name of the destination to which the response message must be sent, that + * will be resolved by the {@link #getDestinationResolver() destination resolver}.
      + *

      + * If the replyToName is not set, a {@link Session#createTemporaryQueue() temporary queue} is used. + *

      + * Some examples of JMS URIs are: + *

      + *

      jms:SomeQueue
      jms:SomeTopic?priority=3&deliveryMode=NON_PERSISTENT
      + * jms:RequestQueue?replyToName=ResponseName
      * * @author Arjen Poutsma + * @see
      IRI Scheme for Java(tm) Message + * Service 1.0 * @since 1.1.0 */ -public class JmsMessageSender implements WebServiceMessageSender, JmsTransportConstants { +public class JmsMessageSender extends JmsDestinationAccessor implements WebServiceMessageSender { - /** - * Default timeout for receive operations: -1 indicates a blocking receive without timeout. - */ + /** Default timeout for receive operations: -1 indicates a blocking receive without timeout. */ public static final long DEFAULT_RECEIVE_TIMEOUT = -1; - private ConnectionFactory connectionFactory; - - private DestinationResolver destinationResolver = new DynamicDestinationResolver(); - private long receiveTimeout = DEFAULT_RECEIVE_TIMEOUT; public JmsMessageSender() { } - public JmsMessageSender(ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - /** - * Set the ConnectionFactory to use for obtaining JMS {@link Connection}s. - */ - public void setConnectionFactory(ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - public void setDestinationResolver(DestinationResolver destinationResolver) { - this.destinationResolver = destinationResolver; - } - - /** - * Set the timeout to use for receive calls. The default is 0, which means no timeout. + * Set the timeout to use for receive calls. The default is -1, which means no timeout. + * + * @see MessageConsumer#receive(long) */ public void setReceiveTimeout(long receiveTimeout) { this.receiveTimeout = receiveTimeout; } - public WebServiceConnection createConnection(String uriString) throws IOException { - Assert.notNull(connectionFactory, "connectionFactory must not be null"); - JmsSenderConnection connection = null; + public WebServiceConnection createConnection(URI uri) throws IOException { + Connection jmsConnection = null; + Session jmsSession = null; try { - JmsUri uri = new JmsUri(uriString); - connection = new JmsSenderConnection(uri, connectionFactory, destinationResolver, receiveTimeout); - return connection; + jmsConnection = createConnection(); + jmsSession = createSession(jmsConnection); + Destination requestDestination = resolveRequestDestination(jmsSession, uri); + JmsSenderConnection wsConnection = + new JmsSenderConnection(getConnectionFactory(), jmsConnection, jmsSession, requestDestination); + wsConnection.setDeliveryMode(JmsTransportUtils.getDeliveryMode(uri)); + wsConnection.setPriority(JmsTransportUtils.getPriority(uri)); + wsConnection.setReceiveTimeout(receiveTimeout); + wsConnection.setResponseDestination(resolveResponseDestination(jmsSession, uri)); + wsConnection.setTimeToLive(JmsTransportUtils.getTimeToLive(uri)); + return wsConnection; } catch (JMSException ex) { - if (connection != null) { - connection.close(); - } + JmsUtils.closeSession(jmsSession); + ConnectionFactoryUtils.releaseConnection(jmsConnection, getConnectionFactory(), true); throw new JmsTransportException(ex); } } - public boolean supports(String uri) { - return StringUtils.hasLength(uri) && uri.startsWith(URI_SCHEME + ":"); + public boolean supports(URI uri) { + return uri.getScheme().equals(JmsTransportConstants.JMS_URI_SCHEME); } + private Destination resolveRequestDestination(Session session, URI uri) throws JMSException { + return resolveDestinationName(session, JmsTransportUtils.getDestinationName(uri)); + } + + private Destination resolveResponseDestination(Session session, URI uri) throws JMSException { + String destinationName = JmsTransportUtils.getReplyToName(uri); + return StringUtils.hasLength(destinationName) ? resolveDestinationName(session, destinationName) : null; + } + + } diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java index 8e1d8827..5d04f8c7 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java @@ -36,7 +36,6 @@ import javax.jms.TemporaryQueue; import org.springframework.jms.connection.ConnectionFactoryUtils; import org.springframework.jms.support.JmsUtils; -import org.springframework.jms.support.destination.DestinationResolver; import org.springframework.util.Assert; import org.springframework.ws.FaultAwareWebServiceMessage; import org.springframework.ws.WebServiceMessage; @@ -56,58 +55,78 @@ public class JmsSenderConnection extends AbstractSenderConnection private final ConnectionFactory connectionFactory; - private final DestinationResolver destinationResolver; - private final Connection connection; private final Session session; private final Destination requestDestination; - private final JmsUri uri; - - private final long receiveTimeout; - private Destination responseDestination; private BytesMessage requestMessage; private BytesMessage responseMessage; - /** - * Constructs a new JMS connection with the given parameters. - */ - protected JmsSenderConnection(JmsUri uri, - ConnectionFactory connectionFactory, - DestinationResolver destinationResolver, - long receiveTimeout) throws JMSException { - Assert.notNull(uri, "'uri' must not be null"); + private long receiveTimeout; + + private int deliveryMode; + + private long timeToLive; + + private int priority; + + /** Constructs a new JMS connection with the given parameters. */ + protected JmsSenderConnection(ConnectionFactory connectionFactory, + Connection connection, + Session session, + Destination requestDestination) throws JMSException { Assert.notNull(connectionFactory, "'connectionFactory' must not be null"); - Assert.notNull(destinationResolver, "destinationResolver must not be null"); + Assert.notNull(connection, "'connection' must not be null"); + Assert.notNull(session, "'session' must not be null"); this.connectionFactory = connectionFactory; - this.destinationResolver = destinationResolver; - connection = connectionFactory.createConnection(); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - requestDestination = - destinationResolver.resolveDestinationName(session, uri.getDestination(), uri.isPubSubDomain()); - this.uri = uri; - this.receiveTimeout = receiveTimeout; + this.connection = connection; + this.session = session; + this.requestDestination = requestDestination; } - /** - * Returns the request message for this connection. - */ + /** Returns the request message for this connection. */ public BytesMessage getRequestMessage() { return requestMessage; } - /** - * Returns the response message, if any, for this connection. - */ + /** Returns the response message, if any, for this connection. */ public BytesMessage getResponseMessage() { return responseMessage; } + /* + * Package-friendly setters + */ + + void setResponseDestination(Destination responseDestination) { + this.responseDestination = responseDestination; + } + + void setTimeToLive(long timeToLive) { + this.timeToLive = timeToLive; + } + + void setDeliveryMode(int deliveryMode) { + this.deliveryMode = deliveryMode; + } + + void setPriority(int priority) { + this.priority = priority; + } + + void setReceiveTimeout(long receiveTimeout) { + this.receiveTimeout = receiveTimeout; + } + + /* + * Errors + */ + public boolean hasError() throws IOException { return false; } @@ -128,7 +147,7 @@ public class JmsSenderConnection extends AbstractSenderConnection FaultAwareWebServiceMessage faultMessage = (FaultAwareWebServiceMessage) message; requestMessage.setBooleanProperty(PROPERTY_IS_FAULT, faultMessage.hasFault()); } - requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.toString()); +// requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.toString()); } catch (JMSException ex) { throw new JmsTransportException(ex); @@ -153,14 +172,10 @@ public class JmsSenderConnection extends AbstractSenderConnection MessageProducer messageProducer = null; try { messageProducer = session.createProducer(requestDestination); - messageProducer.setDeliveryMode(uri.getDeliveryMode()); - messageProducer.setTimeToLive(uri.getTimeToLive()); - messageProducer.setPriority(uri.getPriority()); - if (uri.hasReplyTo()) { - responseDestination = - destinationResolver.resolveDestinationName(session, uri.getReplyTo(), uri.isPubSubDomain()); - } - else { + messageProducer.setDeliveryMode(deliveryMode); + messageProducer.setTimeToLive(timeToLive); + messageProducer.setPriority(priority); + if (responseDestination == null) { responseDestination = session.createTemporaryQueue(); } requestMessage.setJMSReplyTo(responseDestination); diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java index 5ce69c9a..e0fb2e5d 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java @@ -26,7 +26,8 @@ import org.springframework.ws.transport.TransportConstants; */ public interface JmsTransportConstants extends TransportConstants { - String URI_SCHEME = "jms"; + /** The "jms" URI scheme" */ + String JMS_URI_SCHEME = "jms"; String PARAM_DELIVERY_MODE = "deliveryMode"; diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsUri.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsUri.java deleted file mode 100644 index bb967691..00000000 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsUri.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2007 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.DeliveryMode; -import javax.jms.Destination; -import javax.jms.Message; -import javax.jms.Queue; -import javax.jms.Topic; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.ws.transport.support.ParameterizedUri; - -/** - * @author Arjen Poutsma - * @see RI - * Scheme for Java Message Service 1.0 RC1 - */ -public class JmsUri extends ParameterizedUri implements JmsTransportConstants { - - public JmsUri(String uri) { - super(uri); - validateParameters(); - } - - private void validateParameters() { - validateIntegerParameter(PARAM_DELIVERY_MODE); - validateIntegerParameter(PARAM_PRIORITY); - validateIntegerParameter(PARAM_TIME_TO_LIVE); - String destinationType = getDestinationType(); - if (StringUtils.hasLength(destinationType)) { - Assert.isTrue( - DESTINATION_TYPE_QUEUE.equals(destinationType) || DESTINATION_TYPE_TOPIC.equals(destinationType), - "Invalid " + PARAM_DESTINATION_TYPE + ": [" + destinationType + "]. Expected '" + - DESTINATION_TYPE_QUEUE + "' or '" + DESTINATION_TYPE_TOPIC + "'"); - } - } - - private void validateIntegerParameter(String paramName) { - String paramValue = getParameter(paramName); - if (StringUtils.hasLength(paramValue)) { - try { - Integer.parseInt(paramValue); - } - catch (NumberFormatException ex) { - throw new IllegalArgumentException("Invalid " + paramName + ": [" + paramValue + "]. Not an integer."); - } - } - } - - /** - * Returns whether the request message is persistent or not. - * - * @see DeliveryMode#NON_PERSISTENT - * @see DeliveryMode#PERSISTENT - */ - public int getDeliveryMode() { - return getIntegerParameter(PARAM_DELIVERY_MODE, Message.DEFAULT_DELIVERY_MODE); - } - - public String getDestination() { - return super.getDestination(); - } - - /** - * Specifies whether the destination is a {@link Queue} or a {@link Topic}, with the value "queue" or - * "topic", respectively. - */ - public String getDestinationType() { - return getParameter(PARAM_DESTINATION_TYPE); - } - - /** - * Returns the JMS priority associated with the request message. - * - * @see Message#setJMSPriority(int) - */ - public int getPriority() { - return getIntegerParameter(PARAM_PRIORITY, Message.DEFAULT_PRIORITY); - } - - /** - * Returns the lifetime, in milliseconds, of the request message. - */ - public long getTimeToLive() { - String paramValue = getParameter(PARAM_TIME_TO_LIVE); - return paramValue != null ? Long.parseLong(paramValue) : Message.DEFAULT_TIME_TO_LIVE; - } - - private int getIntegerParameter(String paramName, int defaultValue) { - String paramValue = getParameter(paramName); - return paramValue != null ? Integer.parseInt(paramValue) : defaultValue; - } - - /** - * Indicates whether this URI has a reply-to name. - */ - public boolean hasReplyTo() { - return StringUtils.hasLength(getReplyTo()); - } - - /** - * Returns the reply-to name. - * - * @see Message#setJMSReplyTo(Destination) - */ - public String getReplyTo() { - return getParameter(PARAM_REPLY_TO_NAME); - } - - /** - * Return whether the Publish/Subscribe domain ({@link javax.jms.Topic Topics}) is used. Otherwise, the - * Point-to-Point domain ({@link javax.jms.Queue Queues}) is used. - */ - public boolean isPubSubDomain() { - return DESTINATION_TYPE_TOPIC.equals(getDestinationType()); - } - -} diff --git a/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java b/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java index 4d94a213..2185aae5 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java @@ -27,7 +27,7 @@ import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.transport.WebServiceMessageReceiver; /** - * Spring-2.0 {@link SessionAwareMessageListener} that can be used to handle incoming JMS messages. + * Spring {@link SessionAwareMessageListener} that can be used to handle incoming JMS messages. *

      * Requires a {@link WebServiceMessageFactory} which is used to convert the incoming JMS {@link BytesMessage} into a * {@link WebServiceMessage}, and passes that to the {@link WebServiceMessageReceiver} {@link diff --git a/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java b/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java index fa672f9f..b313cc74 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java @@ -16,6 +16,13 @@ package org.springframework.ws.transport.jms.support; +import java.net.URI; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.Message; + import org.springframework.ws.transport.jms.JmsTransportConstants; /** @@ -27,6 +34,16 @@ import org.springframework.ws.transport.jms.JmsTransportConstants; */ public class JmsTransportUtils { + private static final Pattern DESTINATION_NAME_PATTERN = Pattern.compile("^jms:(\\w+)\\&?"); + + private static final Pattern DELIVERY_MODE_PATTERN = Pattern.compile("deliveryMode=(PERSISTENT|NON_PERSISTENT)"); + + private static final Pattern TIME_TO_LIVE_PATTERN = Pattern.compile("timeToLive=(\\d+)"); + + private static final Pattern PRIORITY_PATTERN = Pattern.compile("priority=(\\d)"); + + private static final Pattern REPLY_TO_NAME_PATTERN = Pattern.compile("replyToName=(\\w+)"); + private static final String[] CONVERSION_TABLE = new String[]{JmsTransportConstants.HEADER_CONTENT_TYPE, JmsTransportConstants.PROPERTY_CONTENT_TYPE, JmsTransportConstants.HEADER_CONTENT_LENGTH, JmsTransportConstants.PROPERTY_CONTENT_LENGTH, JmsTransportConstants.HEADER_SOAP_ACTION, @@ -66,4 +83,89 @@ public class JmsTransportUtils { return propertyName; } + public static String getDestinationName(URI uri) { + return getStringParameter(DESTINATION_NAME_PATTERN, uri); + } + + /** + * Returns the delivery mode of the given URI. + * + * @see DeliveryMode#NON_PERSISTENT + * @see DeliveryMode#PERSISTENT + * @see Message#DEFAULT_DELIVERY_MODE + */ + public static int getDeliveryMode(URI uri) { + String deliveryMode = getStringParameter(DELIVERY_MODE_PATTERN, uri); + if ("NON_PERSISTENT".equals(deliveryMode)) { + return DeliveryMode.NON_PERSISTENT; + } + else if ("PERSISTENT".equals(deliveryMode)) { + return DeliveryMode.PERSISTENT; + } + else { + return Message.DEFAULT_DELIVERY_MODE; + } + } + + /** + * Returns the lifetime, in milliseconds, of the given URI. + * + * @see Message#DEFAULT_TIME_TO_LIVE + */ + public static long getTimeToLive(URI uri) { + return getLongParameter(TIME_TO_LIVE_PATTERN, uri, Message.DEFAULT_TIME_TO_LIVE); + } + + /** + * Returns the priority of the given URI. + * + * @see Message#DEFAULT_PRIORITY + */ + public static int getPriority(URI uri) { + return getIntParameter(PRIORITY_PATTERN, uri, Message.DEFAULT_PRIORITY); + } + + /** + * Returns the reply-to name of the given URI. + * + * @see Message#setJMSReplyTo(Destination) + */ + public static String getReplyToName(URI uri) { + return getStringParameter(REPLY_TO_NAME_PATTERN, uri); + } + + private static String getStringParameter(Pattern pattern, URI uri) { + Matcher matcher = pattern.matcher(uri.toString()); + if (matcher.find() && matcher.groupCount() == 1) { + return matcher.group(1); + } + return null; + } + + private static int getIntParameter(Pattern pattern, URI uri, int defaultValue) { + Matcher matcher = pattern.matcher(uri.toString()); + if (matcher.find() && matcher.groupCount() == 1) { + try { + return Integer.parseInt(matcher.group(1)); + } + catch (NumberFormatException ex) { + // fall through to default value + } + } + return defaultValue; + } + + private static long getLongParameter(Pattern pattern, URI uri, long defaultValue) { + Matcher matcher = pattern.matcher(uri.toString()); + if (matcher.find() && matcher.groupCount() == 1) { + try { + return Long.parseLong(matcher.group(1)); + } + catch (NumberFormatException ex) { + // fall through to default value + } + } + return defaultValue; + } + } diff --git a/support/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java b/support/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java deleted file mode 100644 index 58be7494..00000000 --- a/support/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2007 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.support; - -import java.util.Map; -import java.util.StringTokenizer; - -import org.springframework.core.CollectionFactory; -import org.springframework.util.Assert; - -/** @author Arjen Poutsma */ -public class ParameterizedUri { - - private final String uri; - - private final String scheme; - - // keys are string parameter names; values are string parameter values - private final Map parameters = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(5); - - private final String destination; - - public ParameterizedUri(String uri) { - Assert.hasLength(uri, "'uri' must not be empty"); - this.uri = uri; - int scIdx = uri.indexOf(':'); - Assert.isTrue(scIdx != -1, uri + " does contain scheme"); - scheme = uri.substring(0, scIdx); - Assert.isTrue(uri.length() > scheme.length(), uri + " does not have a destination"); - int paramStart = uri.indexOf('?'); - if (paramStart == -1) { - destination = uri.substring(scIdx + 1); - } - else { - destination = uri.substring(scIdx + 1, paramStart); - parseParameters(uri.substring(paramStart + 1)); - } - } - - private void parseParameters(String parametersString) { - StringTokenizer params = new StringTokenizer(parametersString, "&"); - while (params.hasMoreTokens()) { - String param = params.nextToken(); - int paramSep = param.indexOf('='); - if (paramSep == -1) { - throw new IllegalArgumentException(param + " is not a valid parameter: it has no '='"); - } - String paramName = param.substring(0, paramSep); - String paramValue = param.substring(paramSep + 1); - parameters.put(paramName, paramValue); - } - } - - /** Returns the destination of the uri. */ - protected String getDestination() { - return destination; - } - - public String toString() { - return uri; - } - - protected String getParameter(String paramName) { - return (String) parameters.get(paramName); - } - - protected boolean hasParameter(String paramName) { - return parameters.containsKey(paramName); - } -} diff --git a/support/src/test/java/org/springframework/ws/transport/jms/EchoPayloadEndpoint.java b/support/src/test/java/org/springframework/ws/transport/jms/EchoPayloadEndpoint.java new file mode 100644 index 00000000..874258c8 --- /dev/null +++ b/support/src/test/java/org/springframework/ws/transport/jms/EchoPayloadEndpoint.java @@ -0,0 +1,28 @@ +/* + * Copyright 2007 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.xml.transform.Source; + +import org.springframework.ws.server.endpoint.PayloadEndpoint; + +public class EchoPayloadEndpoint implements PayloadEndpoint { + + public Source invoke(Source request) throws Exception { + return request; + } +} diff --git a/support/src/test/java/org/springframework/ws/transport/jms/JmsIntegrationTest.java b/support/src/test/java/org/springframework/ws/transport/jms/JmsIntegrationTest.java new file mode 100644 index 00000000..f5a0e7a0 --- /dev/null +++ b/support/src/test/java/org/springframework/ws/transport/jms/JmsIntegrationTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2007 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.test.AbstractDependencyInjectionSpringContextTests; +import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.xml.transform.StringResult; +import org.springframework.xml.transform.StringSource; + +import org.custommonkey.xmlunit.XMLAssert; + +public class JmsIntegrationTest extends AbstractDependencyInjectionSpringContextTests { + + private WebServiceTemplate webServiceTemplate; + + protected String[] getConfigLocations() { + return new String[]{"classpath:org/springframework/ws/transport/jms/jms-applicationContext.xml"}; + } + + public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) { + this.webServiceTemplate = webServiceTemplate; + } + + public void testJmsTransport() throws Exception { + String content = ""; + StringResult result = new StringResult(); + webServiceTemplate.sendSourceAndReceiveToResult(new StringSource(content), result); + XMLAssert.assertXMLEqual("Invalid content received", content, result.toString()); + applicationContext.close(); + } +} diff --git a/support/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java b/support/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java index 3d5d76fd..68cf7329 100644 --- a/support/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java +++ b/support/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java @@ -18,6 +18,7 @@ package org.springframework.ws.transport.jms; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.net.URI; import javax.jms.BytesMessage; import javax.jms.JMSException; import javax.jms.Message; @@ -41,11 +42,12 @@ public class JmsMessageSenderIntegrationTest extends AbstractDependencyInjection private MessageFactory messageFactory; - private static final String REQUEST_QUEUE_URI = "jms:RequestQueue"; + private URI requestQueueUri; private static final String SOAP_ACTION = "\"http://springframework.org/DoIt\""; protected void onSetUp() throws Exception { + requestQueueUri = new URI("jms:RequestQueue?deliveryMode=NON_PERSISTENT"); messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); } @@ -64,7 +66,7 @@ public class JmsMessageSenderIntegrationTest extends AbstractDependencyInjection public void testSendAndReceiveQueue() throws Exception { WebServiceConnection connection = null; try { - connection = messageSender.createConnection(REQUEST_QUEUE_URI); + connection = messageSender.createConnection(requestQueueUri); SoapMessage soapRequest = new SaajSoapMessage(messageFactory.createMessage()); soapRequest.setSoapAction(SOAP_ACTION); connection.send(soapRequest); @@ -82,7 +84,7 @@ public class JmsMessageSenderIntegrationTest extends AbstractDependencyInjection response.setIntProperty(JmsTransportConstants.PROPERTY_CONTENT_LENGTH, buf.length); response.setStringProperty(JmsTransportConstants.PROPERTY_CONTENT_TYPE, "text/xml"); response.setBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT, false); - response.setStringProperty(JmsTransportConstants.PROPERTY_REQUEST_IRI, REQUEST_QUEUE_URI); + response.setStringProperty(JmsTransportConstants.PROPERTY_REQUEST_IRI, requestQueueUri.toString()); response.setStringProperty(JmsTransportConstants.PROPERTY_SOAP_ACTION, SOAP_ACTION); response.writeBytes(buf); @@ -106,8 +108,6 @@ public class JmsMessageSenderIntegrationTest extends AbstractDependencyInjection message.getStringProperty(JmsTransportConstants.PROPERTY_SOAP_ACTION)); assertEquals("Invalid binding version", "1.0", message.getStringProperty(JmsTransportConstants.PROPERTY_BINDING_VERSION)); - assertEquals("Invalid service IRI", REQUEST_QUEUE_URI, - message.getStringProperty(JmsTransportConstants.PROPERTY_REQUEST_IRI)); assertFalse("Message is Fault", message.getBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT)); assertTrue("Invalid Content Type", message.getStringProperty(JmsTransportConstants.PROPERTY_CONTENT_TYPE).indexOf("text/xml") != -1); diff --git a/support/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java b/support/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java deleted file mode 100644 index 49e6bafe..00000000 --- a/support/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2007 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 junit.framework.TestCase; - -public class JmsUriTest extends TestCase { - - public void testJmsUri() { - JmsUri uri = new JmsUri("jms:news?connectionFactoryName=SOAPJMSFactory&" + "deliveryMode=2&" + - "destinationType=topic&" + "initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory&" + - "jndiURL=theJndiURL&" + "priority=8&" + "timeToLive=10&" + "replyToName=interested&" + - "userprop=mystuff"); - assertEquals("Invalid delivery mode", 2, uri.getDeliveryMode()); - assertEquals("Invalid destination", "news", uri.getDestination()); - assertEquals("Invalid destination type", "topic", uri.getDestinationType()); - assertTrue("Invalid pub sub domain", uri.isPubSubDomain()); - assertEquals("Invalid prority", 8, uri.getPriority()); - assertEquals("Invalid time to live", 10, uri.getTimeToLive()); - assertEquals("Invalid reply to name", "interested", uri.getReplyTo()); - - } - - public void testGetDestinationNoParams() { - JmsUri uri = new JmsUri("jms:news"); - assertEquals("Invalid destination", "news", uri.getDestination()); - } - - public void testInvalidDeliveryMode() { - testIllegalArgument("jms:news?deliveryMode=abc"); - } - - public void testInvalidPriority() { - testIllegalArgument("jms:news?priority=abc"); - } - - public void testInvalidTimeToLive() { - testIllegalArgument("jms:news?timeToLive=abc"); - } - - public void testInvalidDestinationType() { - testIllegalArgument("jms:news?destinationType=abc"); - } - - public void testEmpty() { - testIllegalArgument(""); - } - - public void testIllegalParam() { - testIllegalArgument("jms:news?bla"); - } - - private void testIllegalArgument(String uri) { - try { - new JmsUri(uri); - fail("Expected IllegalArgumentException for uri [" + uri + "]"); - } - catch (IllegalArgumentException ex) { - //expected - } - } -} \ No newline at end of file diff --git a/support/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java b/support/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java index 350665eb..1dbe3a59 100644 --- a/support/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java +++ b/support/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java @@ -16,8 +16,11 @@ package org.springframework.ws.transport.jms.support; +import java.net.URI; +import javax.jms.DeliveryMode; +import javax.jms.Message; + import junit.framework.TestCase; -import org.springframework.ws.transport.jms.support.JmsTransportUtils; public class JmsTransportUtilsTest extends TestCase { @@ -25,4 +28,58 @@ public class JmsTransportUtilsTest extends TestCase { String result = JmsTransportUtils.headerToJmsProperty("SOAPAction"); assertEquals("Invalid result", "SOAPJMS_soapAction", result); } + + public void testGetDeliveryMode() throws Exception { + URI uri = new URI("jms:RequestQueue?deliveryMode=NON_PERSISTENT"); + int deliveryMode = JmsTransportUtils.getDeliveryMode(uri); + assertEquals("Invalid deliveryMode", DeliveryMode.NON_PERSISTENT, deliveryMode); + + uri = new URI("jms:RequestQueue?deliveryMode=PERSISTENT"); + deliveryMode = JmsTransportUtils.getDeliveryMode(uri); + assertEquals("Invalid deliveryMode", DeliveryMode.PERSISTENT, deliveryMode); + + uri = new URI("jms:RequestQueue?replyToName=RESP_QUEUE"); + deliveryMode = JmsTransportUtils.getDeliveryMode(uri); + assertEquals("Invalid deliveryMode", Message.DEFAULT_DELIVERY_MODE, deliveryMode); + } + + public void testGetTimeToLive() throws Exception { + URI uri = new URI("jms:RequestQueue?timeToLive=100"); + long timeToLive = JmsTransportUtils.getTimeToLive(uri); + assertEquals("Invalid timeToLive", 100, timeToLive); + + uri = new URI("jms:RequestQueue?replyToName=RESP_QUEUE"); + timeToLive = JmsTransportUtils.getTimeToLive(uri); + assertEquals("Invalid timeToLive", Message.DEFAULT_TIME_TO_LIVE, timeToLive); + } + + public void testGetPriority() throws Exception { + URI uri = new URI("jms:RequestQueue?priority=5"); + int priority = JmsTransportUtils.getPriority(uri); + assertEquals("Invalid priority", 5, priority); + + uri = new URI("jms:RequestQueue?replyToName=RESP_QUEUE"); + priority = JmsTransportUtils.getPriority(uri); + assertEquals("Invalid priority", Message.DEFAULT_PRIORITY, priority); + } + + public void testGetReplyToName() throws Exception { + URI uri = new URI("jms:RequestQueue?replyToName=RESP_QUEUE"); + String replyToName = JmsTransportUtils.getReplyToName(uri); + assertEquals("Invalid replyToName", "RESP_QUEUE", replyToName); + + uri = new URI("jms:RequestQueue?priority=5"); + replyToName = JmsTransportUtils.getReplyToName(uri); + assertNull("Invalid replyToName", replyToName); + } + + public void testGetDestinationName() throws Exception { + URI uri = new URI("jms:RequestQueue?replyToName=RESP_QUEUE"); + String destinationName = JmsTransportUtils.getDestinationName(uri); + assertEquals("Invalid destination", "RequestQueue", destinationName); + + uri = new URI("jms:RequestQueue"); + destinationName = JmsTransportUtils.getDestinationName(uri); + assertEquals("Invalid destination", "RequestQueue", destinationName); + } } \ No newline at end of file diff --git a/support/src/test/resources/log4j.properties b/support/src/test/resources/log4j.properties index 8e32525b..86d178da 100644 --- a/support/src/test/resources/log4j.properties +++ b/support/src/test/resources/log4j.properties @@ -1,6 +1,5 @@ log4j.rootCategory=WARN, stdout log4j.logger.org.springframework.ws=DEBUG -log4j.logger.org.springframework.jms=DEBUG log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout diff --git a/support/src/test/resources/org/springframework/ws/transport/jms/jms-applicationContext.xml b/support/src/test/resources/org/springframework/ws/transport/jms/jms-applicationContext.xml new file mode 100644 index 00000000..7a561a18 --- /dev/null +++ b/support/src/test/resources/org/springframework/ws/transport/jms/jms-applicationContext.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml b/support/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml index f91a61b9..3e7a4984 100644 --- a/support/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml +++ b/support/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml @@ -17,7 +17,6 @@ - \ No newline at end of file