diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java index 02f7fbc4..bca36897 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java @@ -17,17 +17,18 @@ package org.springframework.ws.transport.jms; import java.io.IOException; +import java.util.Properties; import javax.jms.BytesMessage; +import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Queue; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.QueueSession; -import javax.jms.Session; +import javax.naming.Context; +import javax.naming.NamingException; -import org.springframework.jms.support.destination.DestinationResolver; -import org.springframework.jms.support.destination.DynamicDestinationResolver; -import org.springframework.util.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.jndi.JndiTemplate; +import org.springframework.util.StringUtils; import org.springframework.ws.transport.WebServiceConnection; import org.springframework.ws.transport.WebServiceMessageSender; @@ -42,30 +43,27 @@ import org.springframework.ws.transport.WebServiceMessageSender; */ public class JmsMessageSender implements WebServiceMessageSender { - /** Default timeout for receive operations. */ - public static final long DEFAULT_RECEIVE_TIMEOUT = 0; + private static final Log logger = LogFactory.getLog(JmsMessageSender.class); - private QueueConnectionFactory connectionFactory; + /** Default timeout for receive operations: -1 indicates a blocking receive without timeout. */ + public static final long DEFAULT_RECEIVE_TIMEOUT = -1; - private Object queue; + private static final String JMS_SCHEME = "jms:"; - private DestinationResolver destinationResolver = new DynamicDestinationResolver(); + private ConnectionFactory defaultConnectionFactory; private long receiveTimeout = DEFAULT_RECEIVE_TIMEOUT; - /** Set the QueueConnectionFactory to use for obtaining JMS QueueConnections. */ - public void setConnectionFactory(QueueConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; + public JmsMessageSender() { } - /** Set the target Queue to send invoker requests to. */ - public void setQueue(Queue queue) { - this.queue = queue; + public JmsMessageSender(ConnectionFactory defaultConnectionFactory) { + this.defaultConnectionFactory = defaultConnectionFactory; } - /** Set the name of target queue to send invoker requests to. */ - public void setQueueName(String queueName) { - queue = queueName; + /** Set the default ConnectionFactory to use for obtaining JMS Connections. */ + public void setDefaultConnectionFactory(ConnectionFactory defaultConnectionFactory) { + this.defaultConnectionFactory = defaultConnectionFactory; } /** Set the timeout to use for receive calls. The default is 0, which means no timeout. */ @@ -73,72 +71,51 @@ public class JmsMessageSender implements WebServiceMessageSender { this.receiveTimeout = receiveTimeout; } - /** - * Set the DestinationResolver that is to be used to resolve Queue references for this accessor.

The default - * resolver is a DynamicDestinationResolver. Specify a JndiDestinationResolver for resolving destination names as - * JNDI locations. - * - * @param destinationResolver the DestinationResolver that is to be used - * @see org.springframework.jms.support.destination.DynamicDestinationResolver - * @see org.springframework.jms.support.destination.JndiDestinationResolver - */ - public void setDestinationResolver(DestinationResolver destinationResolver) { - Assert.notNull(destinationResolver, "DestinationResolver must not be null"); - this.destinationResolver = destinationResolver; - } - - public void afterPropertiesSet() { - if (connectionFactory == null) { - throw new IllegalArgumentException("connectionFactory is required"); - } - if (queue == null) { - throw new IllegalArgumentException("'queue' or 'queueName' is required"); - } - } - - /** - * Resolve this accessor's target queue. - * - * @param session the current JMS Session - * @return the resolved target Queue - * @throws JMSException if resolution failed - */ - protected Queue resolveQueue(Session session) throws JMSException { - if (queue instanceof Queue) { - return (Queue) queue; - } - else if (queue instanceof String) { - return resolveQueueName(session, (String) queue); - } - else { - throw new javax.jms.IllegalStateException( - "Queue object [" + queue + "] is neither a [javax.jms.Queue] nor a queue name String"); - } - } - - /** - * Resolve the given queue name into a JMS {@link javax.jms.Queue}, via this accessor's {@link - * DestinationResolver}. - * - * @param session the current JMS Session - * @param queueName the name of the queue - * @return the located Queue - * @throws JMSException if resolution failed - * @see #setDestinationResolver - */ - protected Queue resolveQueueName(Session session, String queueName) throws JMSException { - return (Queue) destinationResolver.resolveDestinationName(session, queueName, false); - } - - public WebServiceConnection createConnection() throws IOException { + public WebServiceConnection createConnection(String uriString) throws IOException { + JmsSenderConnection connection = null; try { - QueueConnection con = connectionFactory.createQueueConnection(); - QueueSession session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - Queue queueToUse = resolveQueue(session); - return new JmsSendingWebServiceConnection(con, session, queueToUse, receiveTimeout); + JmsUri uri = new JmsUri(uriString); + ConnectionFactory connectionFactory = resolveConnectionFactory(uri); + connection = new JmsSenderConnection(uri, connectionFactory, receiveTimeout); + return connection; } catch (JMSException ex) { + if (connection != null) { + connection.close(); + } throw new JmsTransportException(ex); } } + + public boolean supports(String uri) { + return StringUtils.hasLength(uri) && uri.startsWith(JMS_SCHEME); + } + + protected ConnectionFactory resolveConnectionFactory(JmsUri uri) { + if (uri.hasConnectionFactoryName()) { + Properties environment = new Properties(); + if (uri.hasInitialContextFactory()) { + environment.setProperty(Context.INITIAL_CONTEXT_FACTORY, uri.getInitialContextFactory()); + } + if (uri.hasJndiUrl()) { + environment.setProperty(Context.PROVIDER_URL, uri.getJndiUrl()); + } + try { + JndiTemplate jndiTemplate = new JndiTemplate(environment); + return (ConnectionFactory) jndiTemplate.lookup(uri.getConnectionFactoryName(), ConnectionFactory.class); + } + catch (NamingException ex) { + logger.debug("ConnectionFactory [" + uri.getConnectionFactoryName() + "] not found in JNDI", ex); + // fall through to the default + } + } + if (defaultConnectionFactory != null) { + return defaultConnectionFactory; + } + else { + throw new IllegalStateException("Could not resolve JMS ConnectionFactory. " + + "Specify a 'defaultConnectionFactory' or 'connectionFactoryName' in the URI."); + } + } + } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceivingWebServiceConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceiverConnection.java similarity index 51% rename from sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceivingWebServiceConnection.java rename to sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceiverConnection.java index 20ee524a..46a083ab 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceivingWebServiceConnection.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceiverConnection.java @@ -19,21 +19,26 @@ package org.springframework.ws.transport.jms; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Collections; +import java.util.Enumeration; import java.util.Iterator; +import java.util.List; import javax.jms.BytesMessage; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.Session; +import org.apache.commons.logging.Log; import org.springframework.jms.support.JmsUtils; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.ws.transport.AbstractReceivingWebServiceConnection; -import org.springframework.ws.transport.support.EnumerationIterator; +import org.springframework.ws.WebServiceMessage; +import org.springframework.ws.transport.AbstractReceiverConnection; /** @author Arjen Poutsma */ -public class JmsReceivingWebServiceConnection extends AbstractReceivingWebServiceConnection { +public class JmsReceiverConnection extends AbstractReceiverConnection implements JmsTransportConstants { + + private final Log logger; private final BytesMessage requestMessage; @@ -41,78 +46,41 @@ public class JmsReceivingWebServiceConnection extends AbstractReceivingWebServic private BytesMessage responseMessage; - public JmsReceivingWebServiceConnection(BytesMessage requestMessage, Session session) { + protected JmsReceiverConnection(BytesMessage requestMessage, Session session, Log logger) { Assert.notNull(requestMessage, "requestMessage must not be null"); Assert.notNull(session, "session must not be null"); + Assert.notNull(logger, "'logger' must not be null"); this.requestMessage = requestMessage; this.session = session; + this.logger = logger; + } + + public String getErrorMessage() throws IOException { + return null; + } + + public boolean hasError() throws IOException { + return false; } public void close() throws IOException { - try { - session.close(); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not close session", ex); - } } - protected void sendResponse() throws IOException { - if (responseMessage != null) { - MessageProducer producer = null; - try { - if (requestMessage.getJMSReplyTo() != null) { - producer = session.createProducer(requestMessage.getJMSReplyTo()); - producer.send(responseMessage); - } - else { - logger.warn("Incoming message has no ReplyTo set, not sending response"); - } - } - catch (JMSException ex) { - throw new JmsTransportException("Could not send response", ex); - } - finally { - if (producer != null) { - JmsUtils.closeMessageProducer(producer); - } - } - } - } - - private void createResponseMessage() throws IOException { - if (responseMessage == null) { - try { - responseMessage = session.createBytesMessage(); - String correlationID = requestMessage.getJMSCorrelationID(); - if (StringUtils.hasLength(correlationID)) { - responseMessage.setJMSCorrelationID(correlationID); - } - } - catch (JMSException ex) { - throw new JmsTransportException("Could not create response message", ex); - } - } - } - - protected void addResponseHeader(String name, String value) throws IOException { - try { - createResponseMessage(); - responseMessage.setStringProperty(name, value); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not set property", ex); - } - } - - protected OutputStream getResponseOutputStream() throws IOException { - createResponseMessage(); - return new BytesMessageOutputStream(responseMessage); - } + /* + * Receiving + */ protected Iterator getRequestHeaderNames() throws IOException { try { - return new EnumerationIterator(requestMessage.getPropertyNames()); + Enumeration headers = requestMessage.getPropertyNames(); + List results = new ArrayList(); + while (headers.hasMoreElements()) { + String header = (String) headers.nextElement(); + if (header.startsWith(JmsTransportConstants.PROPERTY_PREFIX)) { + results.add(header); + } + } + return results.iterator(); } catch (JMSException ex) { throw new JmsTransportException("Could not get property names", ex); @@ -132,4 +100,56 @@ public class JmsReceivingWebServiceConnection extends AbstractReceivingWebServic protected InputStream getRequestInputStream() throws IOException { return new BytesMessageInputStream(requestMessage); } + + /* + * Sending + */ + + protected void onSendBeforeWrite(WebServiceMessage message) throws IOException { + try { + responseMessage = session.createBytesMessage(); + responseMessage.setJMSCorrelationID(requestMessage.getJMSMessageID()); + responseMessage.setStringProperty(PROPERTY_BINDING_VERSION, "1.0"); + responseMessage.setBooleanProperty(PROPERTY_IS_FAULT, message.hasFault()); + } + catch (JMSException ex) { + throw new JmsTransportException("Could not create response message", ex); + } + } + + protected void addResponseHeader(String name, String value) throws IOException { + try { + String property = JmsTransportUtils.headerToJmsProperty(name); + responseMessage.setStringProperty(property, value); + } + catch (JMSException ex) { + throw new JmsTransportException("Could not set property", ex); + } + } + + protected OutputStream getResponseOutputStream() throws IOException { + return new BytesMessageOutputStream(responseMessage); + } + + protected void onSendAfterWrite(WebServiceMessage message) throws IOException { + MessageProducer messageProducer = null; + try { + if (requestMessage.getJMSReplyTo() != null) { + messageProducer = session.createProducer(requestMessage.getJMSReplyTo()); + messageProducer.setDeliveryMode(requestMessage.getJMSDeliveryMode()); + messageProducer.setPriority(requestMessage.getJMSPriority()); + messageProducer.send(responseMessage); + } + else { + logger.warn("Incoming message has no ReplyTo set, not sending response"); + } + } + catch (JMSException ex) { + throw new JmsTransportException(ex); + } + finally { + JmsUtils.closeMessageProducer(messageProducer); + } + } + } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java new file mode 100644 index 00000000..d269c35e --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java @@ -0,0 +1,244 @@ +/* + * 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 java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +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.Session; +import javax.jms.TemporaryQueue; + +import org.springframework.jms.connection.ConnectionFactoryUtils; +import org.springframework.jms.support.JmsUtils; +import org.springframework.util.Assert; +import org.springframework.ws.WebServiceMessage; +import org.springframework.ws.transport.AbstractSenderConnection; +import org.springframework.ws.transport.FaultAwareWebServiceConnection; + +/** @author Arjen Poutsma */ +public class JmsSenderConnection extends AbstractSenderConnection + implements FaultAwareWebServiceConnection, JmsTransportConstants { + + private final ConnectionFactory connectionFactory; + + private final Connection connection; + + private final Session session; + + private final Destination requestDestination; + + private Destination responseDestination; + + private final JmsUri uri; + + private BytesMessage requestMessage; + + private BytesMessage responseMessage; + + private long receiveTimeout; + + protected JmsSenderConnection(JmsUri uri, ConnectionFactory connectionFactory, long receiveTimeout) + throws JMSException { + Assert.notNull(uri, "'uri' must not be null"); + Assert.notNull(connectionFactory, "'connectionFactory' must not be null"); + this.connectionFactory = connectionFactory; + connection = connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + if (uri.isPubSubDomain()) { + requestDestination = session.createTopic(uri.getDestination()); + } + else { + requestDestination = session.createQueue(uri.getDestination()); + } + this.uri = uri; + this.receiveTimeout = receiveTimeout; + } + + public BytesMessage getRequestMessage() { + return requestMessage; + } + + public BytesMessage getResponseMessage() { + return responseMessage; + } + + /* + * Sending + */ + + protected void onSendBeforeWrite(WebServiceMessage message) throws IOException { + try { + requestMessage = session.createBytesMessage(); + requestMessage.setStringProperty(PROPERTY_BINDING_VERSION, "1.0"); + requestMessage.setBooleanProperty(PROPERTY_IS_FAULT, message.hasFault()); + requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.getUri()); + } + catch (JMSException ex) { + throw new JmsTransportException(ex); + } + } + + protected void addRequestHeader(String name, String value) throws IOException { + try { + String property = JmsTransportUtils.headerToJmsProperty(name); + requestMessage.setStringProperty(property, value); + } + catch (JMSException ex) { + throw new JmsTransportException("Could not set property", ex); + } + } + + protected OutputStream getRequestOutputStream() throws IOException { + return new BytesMessageOutputStream(requestMessage); + } + + protected void onSendAfterWrite(WebServiceMessage message) throws IOException { + MessageProducer messageProducer = null; + try { + messageProducer = session.createProducer(requestDestination); + messageProducer.setDeliveryMode(uri.getDeliveryMode()); + messageProducer.setTimeToLive(uri.getTimeToLive()); + messageProducer.setPriority(uri.getPriority()); + if (uri.hasReplyTo()) { + if (uri.isPubSubDomain()) { + responseDestination = session.createTopic(uri.getReplyTo()); + } + else { + responseDestination = session.createQueue(uri.getReplyTo()); + } + + } + else { + responseDestination = session.createTemporaryQueue(); + } + requestMessage.setJMSReplyTo(responseDestination); + connection.start(); + messageProducer.send(requestMessage); + } + catch (JMSException ex) { + throw new JmsTransportException(ex); + } + finally { + JmsUtils.closeMessageProducer(messageProducer); + } + } + + /* + * Receiving + */ + + protected void onReceiveBeforeRead() throws IOException { + MessageConsumer messageConsumer = null; + try { + messageConsumer = session.createConsumer(responseDestination); + responseMessage = (BytesMessage) (receiveTimeout >= 0 ? messageConsumer.receive(receiveTimeout) : + messageConsumer.receive()); + } + catch (JMSException ex) { + throw new JmsTransportException(ex); + } + finally { + JmsUtils.closeMessageConsumer(messageConsumer); + if (responseDestination instanceof TemporaryQueue) { + try { + ((TemporaryQueue) responseDestination).delete(); + } + catch (JMSException e) { + // ignore + } + } + } + } + + protected Iterator getResponseHeaderNames() throws IOException { + try { + List headerNames = new ArrayList(); + Enumeration propertyNames = responseMessage.getPropertyNames(); + while (propertyNames.hasMoreElements()) { + String propertyName = (String) propertyNames.nextElement(); + headerNames.add(JmsTransportUtils.jmsPropertyToHeader(propertyName)); + } + return headerNames.iterator(); + } + catch (JMSException ex) { + throw new JmsTransportException("Could not get property names", ex); + } + } + + protected Iterator getResponseHeaders(String name) throws IOException { + try { + String propertyName = JmsTransportUtils.headerToJmsProperty(name); + String value = responseMessage.getStringProperty(propertyName); + if (value != null) { + return Collections.singletonList(value).iterator(); + } + else { + return Collections.EMPTY_LIST.iterator(); + } + } + catch (JMSException ex) { + throw new JmsTransportException("Could not get property value", ex); + } + } + + protected InputStream getResponseInputStream() throws IOException { + return new BytesMessageInputStream(responseMessage); + } + + public void close() throws IOException { + JmsUtils.closeSession(session); + ConnectionFactoryUtils.releaseConnection(connection, connectionFactory, true); + } + + protected boolean hasResponse() throws IOException { + return responseMessage != null; + } + + public boolean hasFault() throws IOException { + if (responseMessage != null) { + try { + return responseMessage.getBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT); + } + catch (JMSException ex) { + throw new JmsTransportException(ex); + } + } + else { + return false; + } + } + + public boolean hasError() throws IOException { + return false; + } + + public String getErrorMessage() throws IOException { + return null; + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSendingWebServiceConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSendingWebServiceConnection.java deleted file mode 100644 index f90eb4ab..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSendingWebServiceConnection.java +++ /dev/null @@ -1,179 +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 java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Collections; -import java.util.Iterator; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.Queue; -import javax.jms.QueueConnection; -import javax.jms.QueueReceiver; -import javax.jms.QueueSender; -import javax.jms.QueueSession; -import javax.jms.TemporaryQueue; - -import org.springframework.util.Assert; -import org.springframework.ws.transport.AbstractSendingWebServiceConnection; -import org.springframework.ws.transport.support.EnumerationIterator; - -/** @author Arjen Poutsma */ -public class JmsSendingWebServiceConnection extends AbstractSendingWebServiceConnection { - - private final BytesMessage requestMessage; - - private BytesMessage responseMessage; - - private final QueueSession session; - - private TemporaryQueue responseQueue = null; - - private QueueConnection connection; - - private long receiveTimeout; - - private Queue queue; - - public JmsSendingWebServiceConnection(QueueConnection connection, - QueueSession session, - Queue queue, - long receiveTimeout) throws JMSException { - Assert.notNull(connection, "connection must not be null"); - Assert.notNull(session, "session must not be null"); - Assert.notNull(queue, "queue must not be null"); - this.connection = connection; - this.session = session; - this.queue = queue; - this.receiveTimeout = receiveTimeout; - requestMessage = session.createBytesMessage(); - } - - public void close() throws IOException { - try { - session.close(); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not close session", ex); - } - try { - connection.close(); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not close connection", ex); - } - } - - protected void addRequestHeader(String name, String value) throws IOException { - try { - requestMessage.setStringProperty(name, value); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not set property", ex); - } - } - - protected OutputStream getRequestOutputStream() throws IOException { - return new BytesMessageOutputStream(requestMessage); - } - - protected void sendRequest() throws IOException { - QueueSender sender = null; - try { - sender = session.createSender(queue); - responseQueue = session.createTemporaryQueue(); - requestMessage.setJMSReplyTo(responseQueue); - connection.start(); - sender.send(requestMessage); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not send request message", ex); - } - finally { - try { - if (sender != null) { - sender.close(); - } - } - catch (JMSException ex) { - throw new JmsTransportException("Could not close QueueSender", ex); - } - } - } - - protected boolean hasResponse() throws IOException { - if (responseMessage != null) { - return true; - } - else if (responseQueue != null) { - QueueReceiver receiver = null; - try { - receiver = session.createReceiver(responseQueue); - responseMessage = (BytesMessage) receiver.receive(receiveTimeout); - return responseMessage != null; - } - catch (JMSException ex) { - throw new JmsTransportException("Could not receive message", ex); - } - finally { - try { - if (receiver != null) { - receiver.close(); - } - } - catch (JMSException ex) { - throw new JmsTransportException("Could not close QueueReceiver", ex); - } - try { - responseQueue.delete(); - responseQueue = null; - } - catch (JMSException ex) { - throw new JmsTransportException("Could not delete temporary response queue", ex); - } - } - } - else { - return false; - } - } - - protected Iterator getResponseHeaderNames() throws IOException { - try { - return new EnumerationIterator(responseMessage.getPropertyNames()); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not get property names", ex); - } - } - - protected Iterator getResponseHeaders(String name) throws IOException { - try { - String value = responseMessage.getStringProperty(name); - return Collections.singletonList(value).iterator(); - } - catch (JMSException ex) { - throw new JmsTransportException("Could not get property value", ex); - } - } - - protected InputStream getResponseInputStream() throws IOException { - return new BytesMessageInputStream(responseMessage); - } -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java new file mode 100644 index 00000000..9d8d024b --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java @@ -0,0 +1,63 @@ +/* + * 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.ws.transport.TransportConstants; + +/** @author Arjen Poutsma */ +public interface JmsTransportConstants extends TransportConstants { + + String URI_SCHEME = "jms"; + + String PARAM_DELIVERY_MODE = "deliveryMode"; + + String PARAM_CONNECTION_FACTORY_NAME = "connectionFactoryName"; + + String PARAM_INITIAL_CONTEXT_FACTORY = "initialContextFactory"; + + String PARAM_JNDI_URL = "jndiURL"; + + String PARAM_TIME_TO_LIVE = "timeToLive"; + + String PARAM_PRIORITY = "priority"; + + String PARAM_DESTINATION_TYPE = "destinationType"; + + String PARAM_REPLY_TO_NAME = "replyToName"; + + String DESTINATION_TYPE_QUEUE = "queue"; + + String DESTINATION_TYPE_TOPIC = "topic"; + + String PROPERTY_PREFIX = "SOAPJMS_"; + + String PROPERTY_IS_FAULT = PROPERTY_PREFIX + "isFault"; + + String PROPERTY_SOAP_ACTION = PROPERTY_PREFIX + "soapAction"; + + String PROPERTY_CONTENT_LENGTH = PROPERTY_PREFIX + "contentLength"; + + String PROPERTY_CONTENT_TYPE = PROPERTY_PREFIX + "contentType"; + + String PROPERTY_BINDING_VERSION = PROPERTY_PREFIX + "bindingVersion"; + + String PROPERTY_TARGET_SERVICE = PROPERTY_PREFIX + "targetService"; + + String PROPERTY_REQUEST_IRI = PROPERTY_PREFIX + "requestIRI"; + + String PROPERTY_SOAP_MEP = PROPERTY_PREFIX + "soapMEP"; +} 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 index 95ab4e3f..1c8839c9 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java @@ -20,20 +20,22 @@ import javax.jms.JMSException; import org.springframework.ws.transport.TransportException; -/** - * @author Arjen Poutsma - */ +/** @author Arjen Poutsma */ public class JmsTransportException extends TransportException { - public JmsTransportException(String msg) { - super(msg); - } + private final JMSException jmsException; public JmsTransportException(String msg, JMSException ex) { super(msg + ": " + ex.getMessage()); + jmsException = ex; } public JmsTransportException(JMSException ex) { super(ex.getMessage()); + jmsException = ex; + } + + public JMSException getJmsException() { + return jmsException; } } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java new file mode 100644 index 00000000..6eec7c4b --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java @@ -0,0 +1,49 @@ +/* + * 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; + +/** @author Arjen Poutsma */ +public class JmsTransportUtils { + + 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, + JmsTransportConstants.PROPERTY_SOAP_ACTION}; + + private JmsTransportUtils() { + + } + + public static String headerToJmsProperty(String headerName) { + for (int i = 0; i < CONVERSION_TABLE.length; i = i + 2) { + if (CONVERSION_TABLE[i].equals(headerName)) { + return CONVERSION_TABLE[i + 1]; + } + } + return headerName; + } + + public static String jmsPropertyToHeader(String propertyName) { + for (int i = 1; i < CONVERSION_TABLE.length; i = i + 2) { + if (CONVERSION_TABLE[i].equals(propertyName)) { + return CONVERSION_TABLE[i - 1]; + } + } + return propertyName; + } + +} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsUri.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsUri.java new file mode 100644 index 00000000..7df5ec1e --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsUri.java @@ -0,0 +1,210 @@ +/* + * 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 java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.Message; +import javax.jms.Queue; +import javax.jms.Topic; +import javax.naming.Context; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * @author Arjen Poutsma + * @see RI + * Scheme for Java Message Service 1.0 RC1 + */ +public class JmsUri implements JmsTransportConstants { + + private final String uri; + + private final String destination; + + // keys are string parameter names; values are string parameter values + private final Map parameters = new HashMap(); + + public JmsUri(String uri) { + Assert.hasLength(uri, "'uri' must not be empty"); + String scheme = URI_SCHEME + ":"; + Assert.isTrue(uri.startsWith(scheme), uri + " does not start with " + scheme); + Assert.isTrue(uri.length() > scheme.length(), uri + " does not have a destination"); + int paramStart = uri.indexOf('?'); + if (paramStart == -1) { + destination = uri.substring(scheme.length()); + } + else { + destination = uri.substring(scheme.length(), paramStart); + parseParameters(uri.substring(paramStart + 1)); + } + this.uri = uri; + } + + 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); + } + validateParameters(); + } + + private void validateParameters() { + validateIntegerParameter(PARAM_DELIVERY_MODE); + validateIntegerParameter(PARAM_PRIORITY); + validateIntegerParameter(PARAM_TIME_TO_LIVE); + String destinationType = getDestinationType(); + 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 = (String) parameters.get(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); + } + + /** Returns thethe JNDI name of the destination queue or topic. */ + public String getDestination() { + return destination; + } + + /** + * Specifies whether the destination is a {@link Queue} or a {@link Topic}, with the value "queue" or + * "topic", respectively. + */ + public String getDestinationType() { + return (String) parameters.get(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 int getTimeToLive() { + return getIntegerParameter(PARAM_TIME_TO_LIVE, (int) Message.DEFAULT_TIME_TO_LIVE); + } + + private int getIntegerParameter(String paramName, int defaultValue) { + String paramValue = (String) parameters.get(paramName); + return paramValue != null ? Integer.parseInt(paramValue) : defaultValue; + } + + /** Returns the full JMS URI. */ + public String getUri() { + return uri; + } + + /** Indicates whether this URI has a connection factory name. */ + public boolean hasConnectionFactoryName() { + return StringUtils.hasLength(getConnectionFactoryName()); + } + + /** Returns the JNDI name of the Java class providing the connection factory. */ + public String getConnectionFactoryName() { + return (String) parameters.get(PARAM_CONNECTION_FACTORY_NAME); + } + + /** Indicates whether this URI has a "InitialContextFactory". */ + public boolean hasInitialContextFactory() { + return StringUtils.hasLength(getInitialContextFactory()); + } + + /** + * Returns the fully qualified Java class name of the "InitialContextFactory" implementation class to use. + * + * @see Context#INITIAL_CONTEXT_FACTORY + */ + public String getInitialContextFactory() { + return (String) parameters.get(PARAM_INITIAL_CONTEXT_FACTORY); + } + + /** Indicates whether this URI has a JNDI provider URL. */ + public boolean hasJndiUrl() { + return StringUtils.hasLength(getJndiUrl()); + } + + /** + * Returns the JNDI provider URL. + * + * @see Context#PROVIDER_URL + */ + public String getJndiUrl() { + return (String) parameters.get(PARAM_JNDI_URL); + } + + /** 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 (String) parameters.get(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()); + } + + /** Returns the value of a custom parameter with the given name. */ + public String getCustomParameter(String paramName) { + return (String) parameters.get(paramName); + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java index 14c98bad..f50573ca 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java @@ -44,7 +44,7 @@ public abstract class JmsWebServiceMessageReceiverObjectSupport extends SimpleWe */ protected final void handleMessage(Message request, Session session) throws Exception { if (request instanceof BytesMessage) { - WebServiceConnection connection = new JmsReceivingWebServiceConnection((BytesMessage) request, session); + WebServiceConnection connection = new JmsReceiverConnection((BytesMessage) request, session, logger); handleConnection(connection, getMessageReceiver()); } else { diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageReceiverMessageListener.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java similarity index 92% rename from sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageReceiverMessageListener.java rename to sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java index 77c39fea..5b3a874d 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageReceiverMessageListener.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java @@ -37,13 +37,16 @@ import org.springframework.ws.transport.WebServiceMessageReceiver; * @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory) * @see #setMessageReceiver(org.springframework.ws.transport.WebServiceMessageReceiver) */ -public class WebServiceMessageReceiverMessageListener extends JmsWebServiceMessageReceiverObjectSupport +public class WebServiceMessageListener extends JmsWebServiceMessageReceiverObjectSupport implements SessionAwareMessageListener { public void onMessage(Message message, Session session) throws JMSException { try { handleMessage(message, session); } + catch (JmsTransportException ex) { + throw ex.getJmsException(); + } catch (Exception ex) { JMSException jmsException = new JMSException(ex.getMessage()); jmsException.setLinkedException(ex); diff --git a/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml b/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml index 26f8f54b..8daf7253 100644 --- a/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml +++ b/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml @@ -28,7 +28,7 @@ - + Spring 2.0 SessionAwareMessageListener that creates a SOAP message from the invoming JMS message using a messageFactory, and forwards it to the message to the messageDispatcher. Both of these beans are defined diff --git a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java index 029eb97e..cc0aac6d 100644 --- a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java +++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsMessageSenderIntegrationTest.java @@ -18,113 +18,113 @@ package org.springframework.ws.transport.jms; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.Iterator; import javax.jms.BytesMessage; +import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; +import javax.xml.soap.MessageFactory; +import javax.xml.soap.SOAPConstants; +import javax.xml.soap.SOAPMessage; +import junit.framework.TestCase; +import org.apache.activemq.ActiveMQConnectionFactory; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; -import org.springframework.test.AbstractDependencyInjectionSpringContextTests; -import org.springframework.util.FileCopyUtils; -import org.springframework.ws.transport.TransportInputStream; -import org.springframework.ws.transport.TransportOutputStream; +import org.springframework.ws.soap.SoapMessage; +import org.springframework.ws.soap.saaj.SaajSoapMessage; +import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; import org.springframework.ws.transport.WebServiceConnection; -public class JmsMessageSenderIntegrationTest extends AbstractDependencyInjectionSpringContextTests { - - private static final String REQUEST_HEADER_NAME = "RequestHeader"; - - private static final String REQUEST_HEADER_VALUE = "RequestHeaderValue"; - - private static final String RESPONSE_HEADER_NAME = "ResponseHeader"; - - private static final String RESPONSE_HEADER_VALUE = "ResponseHeaderValue"; - - private static final String REQUEST = "Request"; - - private static final String RESPONSE = "Response"; +public class JmsMessageSenderIntegrationTest extends TestCase { private JmsMessageSender messageSender; private JmsTemplate jmsTemplate; - public void setMessageSender(JmsMessageSender messageSender) { - this.messageSender = messageSender; + private MessageFactory messageFactory; + + private static final String URI = "jms:RequestQueue"; + + private static final String SOAP_ACTION = "http://springframework.org/DoIt"; + + protected void setUp() throws Exception { + ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); + jmsTemplate = new JmsTemplate(connectionFactory); + jmsTemplate.setDefaultDestinationName("RequestQueue"); + messageSender = new JmsMessageSender(connectionFactory); + messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); } - public void setJmsTemplate(JmsTemplate jmsTemplate) { - this.jmsTemplate = jmsTemplate; - } - - protected String[] getConfigLocations() { - return new String[]{"classpath:org/springframework/ws/transport/jms/jms-sender-applicationContext.xml"}; - } - - public void testSendAndReceiveNoResponse() throws Exception { - WebServiceConnection wsConnection = null; + public void testSendAndReceiveQueueNoResponse() throws Exception { + WebServiceConnection connection = null; try { - wsConnection = messageSender.createConnection(); - TransportOutputStream tos = wsConnection.getTransportOutputStream(); - tos.addHeader("Content-Type", "text/xml"); - tos.addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE); - FileCopyUtils.copy(REQUEST.getBytes("UTF-8"), tos); - - BytesMessage request = (BytesMessage) jmsTemplate.receive(); - assertEquals("Invalid header value received on server side", REQUEST_HEADER_VALUE, - request.getStringProperty(REQUEST_HEADER_NAME)); - assertEquals("Invalid request received", REQUEST, getMessageContents(request)); - assertNull("Response", wsConnection.getTransportInputStream()); + connection = messageSender.createConnection(URI); + SOAPMessage saajMessage = messageFactory.createMessage(); + SoapMessage soapRequest = new SaajSoapMessage(saajMessage); + soapRequest.setSoapAction(SOAP_ACTION); + connection.send(soapRequest); + BytesMessage jmsRequest = (BytesMessage) jmsTemplate.receive(); + validateMessage(jmsRequest); } finally { - if (wsConnection != null) { - wsConnection.close(); + if (connection != null) { + connection.close(); } } } + private void validateMessage(BytesMessage message) throws JMSException, IOException { + assertEquals("Invalid SOAPAction", SOAP_ACTION, + message.getStringProperty(JmsTransportConstants.PROPERTY_SOAP_ACTION)); + assertEquals("Invalid binding version", "1.0", + message.getStringProperty(JmsTransportConstants.PROPERTY_BINDING_VERSION)); + assertEquals("Invalid service IRI", 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); + assertTrue("No Content Length", message.getIntProperty(JmsTransportConstants.PROPERTY_CONTENT_LENGTH) > 0); + + assertTrue("Message has no contents", getMessageContents(message).length() > 0); + + } + public void testSendAndReceiveResponse() throws Exception { - WebServiceConnection wsConnection = null; + WebServiceConnection connection = null; try { - wsConnection = messageSender.createConnection(); - TransportOutputStream tos = wsConnection.getTransportOutputStream(); - tos.addHeader("Content-Type", "text/xml"); - tos.addHeader(REQUEST_HEADER_NAME, REQUEST_HEADER_VALUE); - FileCopyUtils.copy(REQUEST.getBytes("UTF-8"), tos); + connection = messageSender.createConnection(URI); + SoapMessage soapRequest = new SaajSoapMessage(messageFactory.createMessage()); + soapRequest.setSoapAction(SOAP_ACTION); + connection.send(soapRequest); BytesMessage request = (BytesMessage) jmsTemplate.receive(); - assertEquals("Invalid header value received on server side", REQUEST_HEADER_VALUE, - request.getStringProperty(REQUEST_HEADER_NAME)); - assertEquals("Invalid request received", REQUEST, getMessageContents(request)); - final byte[] bytes = RESPONSE.getBytes("UTF-8"); + validateMessage(request); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + messageFactory.createMessage().writeTo(bos); + final byte[] buf = bos.toByteArray(); jmsTemplate.send(request.getJMSReplyTo(), new MessageCreator() { + public Message createMessage(Session session) throws JMSException { BytesMessage response = session.createBytesMessage(); - response.setStringProperty(RESPONSE_HEADER_NAME, RESPONSE_HEADER_VALUE); - response.writeBytes(bytes); + response.setStringProperty(JmsTransportConstants.PROPERTY_BINDING_VERSION, "1.0"); + 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, URI); + response.setStringProperty(JmsTransportConstants.PROPERTY_SOAP_ACTION, SOAP_ACTION); + + response.writeBytes(buf); return response; } }); - assertNotNull("No response", wsConnection.getTransportInputStream()); - TransportInputStream tis = wsConnection.getTransportInputStream(); - boolean headerFound = false; - for (Iterator iterator = tis.getHeaderNames(); iterator.hasNext();) { - String headerName = (String) iterator.next(); - if (RESPONSE_HEADER_NAME.equals(headerName)) { - headerFound = true; - } - } - assertTrue("Response has invalid header", headerFound); - Iterator headerValues = tis.getHeaders(RESPONSE_HEADER_NAME); - assertTrue("Response has no header values", headerValues.hasNext()); - assertEquals("Response has invalid header values", RESPONSE_HEADER_VALUE, headerValues.next()); - String result = new String(FileCopyUtils.copyToByteArray(tis), "UTF-8"); - assertEquals("Invalid response", RESPONSE, result); + SoapMessage response = (SoapMessage) connection.receive(new SaajSoapMessageFactory(messageFactory)); + assertNotNull("No response received", response); + assertEquals("Invalid SOAPAction", SOAP_ACTION, response.getSoapAction()); + assertFalse("Message is fault", response.hasFault()); } finally { - if (wsConnection != null) { - wsConnection.close(); + if (connection != null) { + connection.close(); } } } @@ -139,5 +139,4 @@ public class JmsMessageSenderIntegrationTest extends AbstractDependencyInjection out.flush(); return out.toString("UTF-8"); } - } \ No newline at end of file diff --git a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportUtilsTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportUtilsTest.java new file mode 100644 index 00000000..90aa01cb --- /dev/null +++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportUtilsTest.java @@ -0,0 +1,27 @@ +/* + * 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 JmsTransportUtilsTest extends TestCase { + + public void testHeaderToJmsProperty() throws Exception { + String result = JmsTransportUtils.headerToJmsProperty("SOAPAction"); + assertEquals("Invalid result", "SOAPJMS_soapAction", result); + } +} \ No newline at end of file diff --git a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java new file mode 100644 index 00000000..028d72d5 --- /dev/null +++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java @@ -0,0 +1,88 @@ +/* + * 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 connection factory name", "SOAPJMSFactory", uri.getConnectionFactoryName()); + 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 initial context factory", "com.sun.jndi.ldap.LdapCtxFactory", + uri.getInitialContextFactory()); + assertEquals("Invalid prority", 8, uri.getPriority()); + assertEquals("Invalid time to live", 10, uri.getTimeToLive()); + assertEquals("Invalid reply to name", "interested", uri.getReplyTo()); + assertEquals("Invalid custom property", "mystuff", uri.getCustomParameter("userprop")); + + } + + 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 testInvalidScheme() { + testIllegalArgument("http://localhost"); + } + + public void testNoDestination() { + testIllegalArgument("jms:"); + } + + 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/sandbox/src/test/java/org/springframework/ws/transport/jms/MessageEndpointMessageListenerTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/MessageEndpointMessageListenerTest.java index 2960f5f3..72b7cd5e 100644 --- a/sandbox/src/test/java/org/springframework/ws/transport/jms/MessageEndpointMessageListenerTest.java +++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/MessageEndpointMessageListenerTest.java @@ -41,7 +41,7 @@ public class MessageEndpointMessageListenerTest extends TestCase { " \n" + " DIS\n" + " \n" + " \n" + ""; - private WebServiceMessageReceiverMessageListener messageListener; + private WebServiceMessageListener messageListener; private BytesMessage request; @@ -50,7 +50,7 @@ public class MessageEndpointMessageListenerTest extends TestCase { private Session sessionMock; protected void setUp() throws Exception { - messageListener = new WebServiceMessageReceiverMessageListener(); + messageListener = new WebServiceMessageListener(); request = new ActiveMQBytesMessage(); request.writeBytes(REQUEST.getBytes("UTF-8")); messageListener.setMessageFactory(new MockWebServiceMessageFactory()); diff --git a/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-receiver-applicationContext.xml b/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-receiver-applicationContext.xml index b65ff699..24108581 100644 --- a/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-receiver-applicationContext.xml +++ b/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-receiver-applicationContext.xml @@ -21,7 +21,7 @@ - + diff --git a/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml b/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml deleted file mode 100644 index 7359a7dd..00000000 --- a/sandbox/src/test/resources/org/springframework/ws/transport/jms/jms-sender-applicationContext.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file