From 55b8cae1d5e5ffdfd9774414e3565f38cdc30fd8 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 13 Nov 2007 18:18:00 +0000 Subject: [PATCH] Cleaned up sandbox a bit --- sandbox/pom.xml | 34 +- .../client/object/MarshallingInvocation.java | 22 ++ .../client/object/WebServiceInvocation.java | 40 +++ .../ws/client/object/package.html | 12 + .../addressing/WsAddressingInterceptor.java | 9 +- .../AbstractPollingMonitoringStrategy.java | 90 ------ .../transport/mail/MailMessageReceiver.java | 191 ------------ .../ws/transport/mail/MailMessageSender.java | 104 ------- .../transport/mail/MailSenderConnection.java | 291 ------------------ .../mail/MailTransportException.java | 46 --- .../ws/transport/mail/MonitoringStrategy.java | 40 --- .../ws/transport/mail/support/MailUtils.java | 82 ----- .../ws/transport/tcp/TcpMessageReceiver.java | 30 +- .../ws/transport/tcp/TcpMessageSender.java | 27 +- .../ws/transport/tcp/TcpSenderConnection.java | 17 +- .../transport/tcp/TcpTransportConstants.java | 29 ++ ...stractWsAddressingInterceptorTestCase.java | 6 +- .../ws/transport/tcp/TcpIntegrationTest.java | 45 +++ .../transport/tcp/tcp-applicationContext.xml | 38 +++ 19 files changed, 245 insertions(+), 908 deletions(-) create mode 100644 sandbox/src/main/java/org/springframework/ws/client/object/MarshallingInvocation.java create mode 100644 sandbox/src/main/java/org/springframework/ws/client/object/WebServiceInvocation.java create mode 100644 sandbox/src/main/java/org/springframework/ws/client/object/package.html delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java create mode 100644 sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpTransportConstants.java create mode 100644 sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpIntegrationTest.java create mode 100644 sandbox/src/test/resources/org/springframework/ws/transport/tcp/tcp-applicationContext.xml diff --git a/sandbox/pom.xml b/sandbox/pom.xml index 18c3c524..8372d8f6 100644 --- a/sandbox/pom.xml +++ b/sandbox/pom.xml @@ -3,7 +3,7 @@ spring-ws org.springframework.ws - 1.0.3-SNAPSHOT + 1.1-SNAPSHOT 4.0.0 spring-ws-sandbox @@ -41,6 +41,10 @@ org.springframework.ws spring-oxm + + org.springframework.ws + spring-ws-support + org.springframework @@ -92,17 +96,6 @@ jms provided - - javax.mail - mail - provided - - - javax.ejb - ejb - 2.1 - true - javax.xml.ws jaxws-api @@ -124,23 +117,6 @@ commons-httpclient true - - org.apache.activemq - activemq-core - 4.1.1 - test - - - org.apache.derby - derby - 10.1.1.0 - - - org.mortbay.jetty - jetty - 6.0.1 - test - easymock diff --git a/sandbox/src/main/java/org/springframework/ws/client/object/MarshallingInvocation.java b/sandbox/src/main/java/org/springframework/ws/client/object/MarshallingInvocation.java new file mode 100644 index 00000000..1a24411e --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/client/object/MarshallingInvocation.java @@ -0,0 +1,22 @@ +/* + * 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.client.object; + +/** @author Arjen Poutsma */ +public abstract class MarshallingInvocation extends WebServiceInvocation { + +} diff --git a/sandbox/src/main/java/org/springframework/ws/client/object/WebServiceInvocation.java b/sandbox/src/main/java/org/springframework/ws/client/object/WebServiceInvocation.java new file mode 100644 index 00000000..ade9a146 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/client/object/WebServiceInvocation.java @@ -0,0 +1,40 @@ +/* + * 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.client.object; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.ws.client.core.WebServiceTemplate; + +/** @author Arjen Poutsma */ +public abstract class WebServiceInvocation { + + /** Logger available to subclasses. */ + protected final Log logger = LogFactory.getLog(getClass()); + + /** Lower-level class used to invoke Web service. */ + private WebServiceTemplate webServiceTemplate = new WebServiceTemplate(); + + /** Returns the {@link WebServiceTemplate} used by this object. */ + public WebServiceTemplate getWebServiceTemplate() { + return webServiceTemplate; + } + + public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) { + this.webServiceTemplate = webServiceTemplate; + } +} diff --git a/sandbox/src/main/java/org/springframework/ws/client/object/package.html b/sandbox/src/main/java/org/springframework/ws/client/object/package.html new file mode 100644 index 00000000..2e76509b --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/client/object/package.html @@ -0,0 +1,12 @@ + + +Contains classes that represent Web service invocations as threadsafe, reusable objects. This approach is similar to +the JDBC Object support in the Spring framework (see the org.springframework.jdbc.object package). +

+ This higher level of Web service abstraction depends on the lower-level + abstraction in the org.springframework.jdbc.core package. + Exceptions thrown are as in the org.springframework.dao package, + meaning that code using this package does not need to implement JDBC or + RDBMS-specific error handling. + + diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingInterceptor.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingInterceptor.java index e312ff90..93461930 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingInterceptor.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressingInterceptor.java @@ -17,9 +17,8 @@ package org.springframework.ws.soap.addressing; import java.io.IOException; +import java.net.URI; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; import org.springframework.ws.context.MessageContext; import org.springframework.ws.soap.SoapHeaderElement; @@ -29,6 +28,9 @@ import org.springframework.ws.soap.server.SoapEndpointInterceptor; import org.springframework.ws.transport.WebServiceConnection; import org.springframework.ws.transport.WebServiceMessageSender; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * {@link SoapEndpointInterceptor} implementation that u * @@ -111,8 +113,9 @@ class WsAddressingInterceptor implements SoapEndpointInterceptor { } } - private void sendOutOfBand(String uri, SoapMessage message) throws IOException { + private void sendOutOfBand(String uriString, SoapMessage message) throws IOException { boolean supported = false; + URI uri = URI.create(uriString); for (int i = 0; i < messageSenders.length; i++) { if (messageSenders[i].supports(uri)) { supported = true; diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java deleted file mode 100644 index fd6fc8b8..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java +++ /dev/null @@ -1,90 +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.mail; - -import javax.mail.Folder; -import javax.mail.Message; -import javax.mail.MessagingException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; - -/** - * Abstract base class for {@link MonitoringStrategy} implementations that use a polling mechanism. Defines a {@link - * #setPollingInterval(int) polling interval} property which defines the interval in between message polls. - * - * @author Arjen Poutsma - */ -public abstract class AbstractPollingMonitoringStrategy implements MonitoringStrategy, InitializingBean { - - /** - * Defines the default polling frequency. Set to 1000 * 60 * 5 milliseconds (i.e. 5 minutes). - */ - public static final int DEFAULT_POLLING_FREQUENCY = 1000 * 60 * 5; - - /** - * Logger available to subclasses. - */ - private final Log logger = LogFactory.getLog(getClass()); - - private int pollingInterval = DEFAULT_POLLING_FREQUENCY; - - public void afterPropertiesSet() throws Exception { - logger.info("Polling every " + getPollingInterval() + " milliseconds"); - } - - /** - * Returns the polling interval. - */ - public int getPollingInterval() { - return pollingInterval; - } - - /** - * Sets the interval used in between message polls, in milliseconds. The default is 1000 * 60 * 5 - * ms, that is 5 minutes. - */ - public void setPollingInterval(int pollingInterval) { - this.pollingInterval = pollingInterval; - } - - /** - * Sleeps for the {@link #setPollingInterval(int) defined amount of milliseconds}, and calls {@link - * #pollForNewMessages(Folder)}. - * - * @param folder the folder to look in - * @return the new messages - * @throws MessagingException in case of JavaMail errors. - */ - public final Message[] getNewMessages(Folder folder) throws MessagingException { - try { - Thread.sleep(getPollingInterval()); - folder.getMessageCount(); - return pollForNewMessages(folder); - } - catch (InterruptedException e) { - logger.warn(e); - return new Message[0]; - } - } - - /** - * Abstract template method that is invoked every interval. - */ - protected abstract Message[] pollForNewMessages(Folder folder) throws MessagingException; -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java deleted file mode 100644 index a3d46b62..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java +++ /dev/null @@ -1,191 +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.mail; - -import java.util.Properties; -import javax.mail.Folder; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.Store; -import javax.mail.URLName; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; - -import org.springframework.util.Assert; -import org.springframework.ws.transport.mail.support.MailUtils; -import org.springframework.ws.transport.support.AbstractMultiThreadedMessageReceiver; - -/** - * @author Arjen Poutsma - */ -public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { - - private Session session = Session.getInstance(new Properties(), null); - - private URLName storeUri; - - private URLName transportUri; - - private Folder folder; - - private Store store; - - private MonitoringStrategy monitoringStrategy = new DefaultMonitoringStrategy(); - - private InternetAddress from; - - public void setFrom(String from) throws AddressException { - this.from = new InternetAddress(from); - } - - /** - * Set JavaMail properties for the {@link Session}. - *

- * A new {@link Session} will be created with those properties. Use either this method or {@link #setSession}, but - * not both. - *

- * Non-default properties in this instance will override given JavaMail properties. - */ - public void setJavaMailProperties(Properties javaMailProperties) { - session = Session.getInstance(javaMailProperties, null); - } - - /** - * - * @param monitoringStrategy - */ - public void setMonitoringStrategy(MonitoringStrategy monitoringStrategy) { - this.monitoringStrategy = monitoringStrategy; - } - - /** - * Set the JavaMail Session, possibly pulled from JNDI. - *

- * Default is a new Session without defaults, that is completely configured via this instance's - * properties. - *

- * If using a pre-configured Session, non-default properties in this instance will override the - * settings in the Session. - * - * @see #setJavaMailProperties - */ - public void setSession(Session session) { - Assert.notNull(session, "Session must not be null"); - this.session = session; - } - - public void setStoreUri(String storeUri) { - this.storeUri = new URLName(storeUri); - } - - public void setTransportUri(String transportUri) { - this.transportUri = new URLName(transportUri); - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(storeUri, "Property 'storeUri' is required"); - Assert.notNull(transportUri, "Property 'transportUri' is required"); - Assert.notNull(monitoringStrategy, "Property 'monitoringStrategy' is required"); - super.afterPropertiesSet(); - } - - protected void onActivate() throws Exception { - openFolder(); - } - - protected void onStart() { - if (logger.isInfoEnabled()) { - logger.info("Starting mail receiver [" + storeUri.toString() + "]"); - } - getTaskExecutor().execute(new MonitoringRunnable()); - } - - protected void onStop() { - if (logger.isInfoEnabled()) { - logger.info("Stopping mail receiver [" + storeUri.toString() + "]"); - } - } - - protected void onShutdown() { - if (logger.isInfoEnabled()) { - logger.info("Shutting down mail receiver [" + storeUri.toString() + "]"); - } - closeFolder(); - } - - protected void closeFolder() { - MailUtils.closeFolder(folder, true); - MailUtils.closeService(store); - } - - protected void openFolder() throws MessagingException, MailTransportException { - store = session.getStore(storeUri); - store.connect(); - folder = store.getFolder(storeUri); - if (folder == null || !folder.exists()) { - throw new MailTransportException("No default folder to receive from"); - } - folder.open(Folder.READ_WRITE); - } - - private class MonitoringRunnable implements Runnable { - - public void run() { - while (isRunning()) { - try { - Message[] newMessages = monitoringStrategy.getNewMessages(folder); - for (int i = 0; i < newMessages.length; i++) { - if (logger.isDebugEnabled()) { - if (newMessages[i] instanceof MimeMessage) { - MimeMessage mimeMessage = (MimeMessage) newMessages[i]; - logger.debug("Received email message with MessageID " + mimeMessage.getMessageID()); - } - } - MessageRequestHandler handler = new MessageRequestHandler(newMessages[i]); - getTaskExecutor().execute(handler); - } - } - catch (MessagingException ex) { - logger.warn(ex); - } - } - } - } - - private class MessageRequestHandler implements Runnable { - - private final Message message; - - public MessageRequestHandler(Message message) { - this.message = message; - } - - public void run() { - MailReceiverConnection connection = new MailReceiverConnection(message, session); - connection.setTransportUri(transportUri); - connection.setFrom(from); - try { - handleConnection(connection); - } - catch (Exception ex) { - logger.warn("Could not handle message", ex); - } - } - } -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java deleted file mode 100644 index 2c40232b..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java +++ /dev/null @@ -1,104 +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.mail; - -import java.io.IOException; -import java.util.Properties; -import javax.mail.Session; -import javax.mail.URLName; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.ws.transport.WebServiceConnection; -import org.springframework.ws.transport.WebServiceMessageSender; - -/** - * @author Arjen Poutsma - */ -public class MailMessageSender implements WebServiceMessageSender, InitializingBean { - - private Session session = Session.getInstance(new Properties(), null); - - private URLName storeUri; - - private URLName transportUri; - - private InternetAddress from; - - public void setFrom(String from) throws AddressException { - this.from = new InternetAddress(from); - } - - /** - * Set JavaMail properties for the {@link Session}. - *

- * A new {@link Session} will be created with those properties. Use either this method or {@link #setSession}, but - * not both. - *

- * Non-default properties in this instance will override given JavaMail properties. - */ - public void setJavaMailProperties(Properties javaMailProperties) { - session = Session.getInstance(javaMailProperties, null); - } - - /** - * Set the JavaMail Session, possibly pulled from JNDI. - *

- * Default is a new Session without defaults, that is completely configured via this instance's - * properties. - *

- * If using a pre-configured Session, non-default properties in this instance will override the - * settings in the Session. - * - * @see #setJavaMailProperties - */ - public void setSession(Session session) { - Assert.notNull(session, "Session must not be null"); - this.session = session; - } - - public void setStoreUri(String storeUri) { - this.storeUri = new URLName(storeUri); - } - - public void setTransportUri(String transportUri) { - this.transportUri = new URLName(transportUri); - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(from, "Property 'from' is required"); - } - - public WebServiceConnection createConnection(String uri) throws IOException { - MailtoUri mailtoUri = new MailtoUri(uri); - MailSenderConnection connection = new MailSenderConnection(mailtoUri, session, from); - if (transportUri != null) { - connection.setTransportUri(transportUri); - } - if (storeUri != null) { - connection.setStoreUri(storeUri); - } - return connection; - } - - public boolean supports(String uri) { - return StringUtils.hasLength(uri) && uri.startsWith(MailTransportConstants.URI_SCHEME + ":"); - } -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java deleted file mode 100644 index 856334e6..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java +++ /dev/null @@ -1,291 +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.mail; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import javax.activation.DataHandler; -import javax.activation.DataSource; -import javax.mail.Flags; -import javax.mail.Folder; -import javax.mail.Header; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.Store; -import javax.mail.Transport; -import javax.mail.URLName; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; -import javax.mail.search.HeaderTerm; -import javax.mail.search.SearchTerm; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.ws.WebServiceMessage; -import org.springframework.ws.transport.AbstractSenderConnection; -import org.springframework.ws.transport.TransportConstants; -import org.springframework.ws.transport.mail.support.MailUtils; - -/** - * @author Arjen Poutsma - */ -public class MailSenderConnection extends AbstractSenderConnection { - - private static final Log logger = LogFactory.getLog(MailSenderConnection.class); - - private final Session session; - - private final MailtoUri uri; - - private MimeMessage requestMessage; - - private Message responseMessage; - - private String requestContentType; - - private boolean deleteAfterReceive = false; - - private URLName storeUri; - - private URLName transportUri; - - private ByteArrayOutputStream requestBuffer; - - private InternetAddress from; - - protected MailSenderConnection(MailtoUri uri, Session session, InternetAddress from) { - Assert.notNull(uri, "'uri' must not be null"); - Assert.notNull(session, "'session' must not be null"); - this.uri = uri; - this.session = session; - this.from = from; - } - - public Message getRequestMessage() { - return requestMessage; - } - - public void setTransportUri(URLName transportUri) { - this.transportUri = transportUri; - } - - public void setStoreUri(URLName storeUri) { - this.storeUri = storeUri; - } - - /* - * Sending - */ - - protected void onSendBeforeWrite(WebServiceMessage message) throws IOException { - try { - requestMessage = new MimeMessage(session); - requestMessage.setFrom(from); - requestMessage.setRecipient(Message.RecipientType.TO, uri.getTo()); - if (uri.hasCc()) { - requestMessage.setRecipient(Message.RecipientType.CC, uri.getCc()); - } - if (uri.hasSubject()) { - requestMessage.setSubject(uri.getSubject()); - } - requestMessage.setSentDate(new Date()); - - requestBuffer = new ByteArrayOutputStream(); - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - } - } - - protected void addRequestHeader(String name, String value) throws IOException { - try { - requestMessage.addHeader(name, value); - if (TransportConstants.HEADER_CONTENT_TYPE.equals(name)) { - requestContentType = value; - } - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - } - } - - protected OutputStream getRequestOutputStream() throws IOException { - return requestBuffer; - } - - protected void onSendAfterWrite(WebServiceMessage message) throws IOException { - Transport transport = null; - try { - requestMessage.setDataHandler( - new DataHandler(new ByteArrayDataSource(requestContentType, requestBuffer.toByteArray()))); - transport = session.getTransport(transportUri); - transport.connect(); - requestMessage.saveChanges(); - transport.sendMessage(requestMessage, requestMessage.getAllRecipients()); - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - } - finally { - MailUtils.closeService(transport); - } - } - - /* - * Receiving - */ - - protected void onReceiveBeforeRead() throws IOException { - Store store = null; - Folder folder = null; - try { - String requestMessageId = requestMessage.getMessageID(); - if (StringUtils.hasLength(requestMessageId)) { - try { - Thread.sleep(5000); - } - catch (InterruptedException e) { - logger.debug(e); - } - store = session.getStore(storeUri); - store.connect(); - folder = store.getFolder(storeUri); - if (folder == null || !folder.exists()) { - throw new MailTransportException("No default folder to receive from"); - } - if (deleteAfterReceive) { - folder.open(Folder.READ_WRITE); - } - else { - folder.open(Folder.READ_ONLY); - } - SearchTerm searchTerm = new HeaderTerm(MailTransportConstants.HEADER_IN_REPLY_TO, requestMessageId); - Message[] responses = folder.search(searchTerm); - if (responses.length > 0) { - if (responses.length > 1) { - logger.warn("Received more than one response for request with ID [" + requestMessageId + "]"); - } - responseMessage = responses[0]; - } - if (deleteAfterReceive) { - responseMessage.setFlag(Flags.Flag.DELETED, true); - } - } - else { - logger.warn("Request message had no Message ID, could not find response"); - } - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - } - finally { - MailUtils.closeFolder(folder, deleteAfterReceive); - MailUtils.closeService(store); - } - } - - protected boolean hasResponse() throws IOException { - return responseMessage != null; - } - - protected Iterator getResponseHeaderNames() throws IOException { - try { - List headers = new ArrayList(); - Enumeration enumeration = responseMessage.getAllHeaders(); - while (enumeration.hasMoreElements()) { - Header header = (Header) enumeration.nextElement(); - headers.add(header.getName()); - } - return headers.iterator(); - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - } - } - - protected Iterator getResponseHeaders(String name) throws IOException { - try { - String[] headers = responseMessage.getHeader(name); - return Arrays.asList(headers).iterator(); - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - - } - } - - protected InputStream getResponseInputStream() throws IOException { - try { - return responseMessage.getDataHandler().getInputStream(); - } - catch (MessagingException ex) { - throw new MailTransportException(ex); - } - } - - public boolean hasError() throws IOException { - return false; - } - - public String getErrorMessage() throws IOException { - return null; - } - - public void close() throws IOException { - } - - private class ByteArrayDataSource implements DataSource { - - private byte[] data; - - private String contentType; - - public ByteArrayDataSource(String contentType, byte[] data) { - this.data = data; - this.contentType = contentType; - } - - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(data); - } - - public OutputStream getOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - public String getContentType() { - return contentType; - } - - public String getName() { - return "ByteArrayDataSource"; - } - } - -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java deleted file mode 100644 index c047fde1..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java +++ /dev/null @@ -1,46 +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.mail; - -import javax.jms.JMSException; -import javax.mail.MessagingException; - -import org.springframework.ws.transport.TransportException; - -/** @author Arjen Poutsma */ -public class MailTransportException extends TransportException { - - private MessagingException messagingException; - - public MailTransportException(String msg) { - super(msg); - } - - public MailTransportException(String msg, MessagingException ex) { - super(msg + ": " + ex.getMessage()); - initCause(ex); - } - - public MailTransportException(MessagingException ex) { - super(ex.getMessage()); - initCause(ex); - } - - public MessagingException getMessagingException() { - return messagingException; - } -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java deleted file mode 100644 index 3e6bf859..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java +++ /dev/null @@ -1,40 +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.mail; - -import javax.mail.Folder; -import javax.mail.Message; -import javax.mail.MessagingException; - -/** - * Defines the contract for objects that monitor a given folder for new messages. Allows for multiple implementation - * strategies, including polling, or event-driven techniques such as IMAP's IDLE command. - * - * @author Arjen Poutsma - */ -public interface MonitoringStrategy { - - /** - * Return the new messages in a given JavaMail folder. - * - * @param folder the folder in which to look for new messages - * @return the new messages - * @throws MessagingException in case of JavaMail errors - */ - Message[] getNewMessages(Folder folder) throws MessagingException; - -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java deleted file mode 100644 index 0314883a..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java +++ /dev/null @@ -1,82 +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.mail.support; - -import javax.mail.Folder; -import javax.mail.MessagingException; -import javax.mail.Service; -import javax.mail.Store; -import javax.mail.Transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** @author Arjen Poutsma */ -public abstract class MailUtils { - - private static final Log logger = LogFactory.getLog(MailUtils.class); - - /** - * Close the given JavaMail Service and ignore any thrown exception. This is useful for typical finally - * blocks in manual JavaMail code. - * - * @param service the JavaMail Service to close (may be null) - * @see Transport - * @see Store - */ - public static void closeService(Service service) { - if (service != null) { - try { - service.close(); - } - catch (MessagingException ex) { - logger.debug("Could not close JavaMail Transport", ex); - } - } - } - - /** - * Close the given JavaMail Folder and ignore any thrown exception. This is useful for typical finally - * blocks in manual JavaMail code. - * - * @param folder the JavaMail Folder to close (may be null) - */ - - public static void closeFolder(Folder folder) { - closeFolder(folder, false); - } - - /** - * Close the given JavaMail Folder and ignore any thrown exception. This is useful for typical finally - * blocks in manual JavaMail code. - * - * @param folder the JavaMail Folder to close (may be null) - * @param expunge whether all deleted messages should be expunged from the folder - */ - public static void closeFolder(Folder folder, boolean expunge) { - if (folder != null) { - try { - folder.close(expunge); - } - catch (MessagingException ex) { - logger.debug("Could not close JavaMail Transport", ex); - } - } - } - - -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java index 886ecb7d..d5302fd8 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java @@ -23,11 +23,13 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; +import org.springframework.scheduling.SchedulingAwareRunnable; import org.springframework.ws.transport.WebServiceConnection; -import org.springframework.ws.transport.support.AbstractMultiThreadedMessageReceiver; +import org.springframework.ws.transport.support.AbstractAsyncStandaloneMessageReceiver; /** @author Arjen Poutsma */ -public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { +public class TcpMessageReceiver extends AbstractAsyncStandaloneMessageReceiver { + public static final int DEFAULT_PORT = 8081; private ServerSocket serverSocket; @@ -52,8 +54,8 @@ public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { * Sets the local internet address the server will bind to. By default, it will accept connections on any/all local * addresses. * - * @throws java.net.UnknownHostException when the given address is not known - * @see java.net.ServerSocket#ServerSocket(int,int,java.net.InetAddress) + * @throws UnknownHostException when the given address is not known + * @see ServerSocket#ServerSocket(int,int,java.net.InetAddress) */ public void setBindAddress(String bindAddress) throws UnknownHostException { this.bindAddress = InetAddress.getByName(bindAddress); @@ -67,7 +69,7 @@ public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { if (logger.isInfoEnabled()) { logger.info("Starting tcp receiver [" + serverSocket.getLocalSocketAddress() + "]"); } - getTaskExecutor().execute(new SocketAcceptingRunnable()); + execute(new SocketAcceptingRunnable()); } protected void onStop() { @@ -83,9 +85,7 @@ public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { closeServerSocket(); } - /** - * Establish a ServerSocket for this receiver. - */ + /** Establish a ServerSocket for this receiver. */ protected void openServerSocket() throws IOException { closeServerSocket(); serverSocket = new ServerSocket(port, backlog, bindAddress); @@ -103,14 +103,14 @@ public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { } } - private class SocketAcceptingRunnable implements Runnable { + private class SocketAcceptingRunnable implements SchedulingAwareRunnable { public void run() { while (isRunning()) { try { Socket socket = serverSocket.accept(); TcpRequestHandler handler = new TcpRequestHandler(socket); - getTaskExecutor().execute(handler); + execute(handler); } catch (InterruptedIOException ex) { logger.warn(ex); @@ -120,9 +120,13 @@ public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { } } } + + public boolean isLongLived() { + return true; + } } - private class TcpRequestHandler implements Runnable { + private class TcpRequestHandler implements SchedulingAwareRunnable { private final Socket socket; @@ -139,6 +143,10 @@ public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver { logger.warn("Could not handle request", ex); } } + + public boolean isLongLived() { + return false; + } } } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java index 9be37a0b..4d72066f 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; +import java.net.URI; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -29,8 +30,6 @@ import org.springframework.ws.transport.WebServiceMessageSender; /** @author Arjen Poutsma */ public class TcpMessageSender implements WebServiceMessageSender { - private static final String TCP_SCHEME = "tcp://"; - public static final int DEFAULT_PORT = 8081; private int timeOut = 1000; @@ -40,26 +39,18 @@ public class TcpMessageSender implements WebServiceMessageSender { this.timeOut = timeOut; } - public boolean supports(String uri) { - return StringUtils.hasLength(uri) && uri.startsWith(TCP_SCHEME); - } - - public WebServiceConnection createConnection(String uri) throws IOException { - Assert.isTrue(uri.startsWith(TCP_SCHEME), "Invalid uri: " + uri); - uri = uri.substring(TCP_SCHEME.length()); - int idx = uri.indexOf(':'); - String hostname; - int port; - if (idx != -1) { - hostname = uri.substring(0, idx); - port = Integer.parseInt(uri.substring(idx + 1)); - } else { - hostname = uri; + public WebServiceConnection createConnection(URI theUri) throws IOException { + int port = theUri.getPort(); + if (port == -1) { port = DEFAULT_PORT; } Socket socket = new Socket(); - SocketAddress socketAddress = new InetSocketAddress(hostname, port); + SocketAddress socketAddress = new InetSocketAddress(theUri.getHost(), port); socket.connect(socketAddress, timeOut); return new TcpSenderConnection(socket); } + + public boolean supports(URI uri) { + return uri.getScheme().equals(TcpTransportConstants.TCP_URI_SCHEME); + } } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java index ad5c0a4f..c5e865c3 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java @@ -27,21 +27,36 @@ import java.util.Iterator; import org.springframework.util.Assert; import org.springframework.ws.transport.AbstractSenderConnection; +import org.springframework.ws.transport.WebServiceConnection; -/** @author Arjen Poutsma */ +/** + * Implementation of {@link WebServiceConnection} that is used for client-side TCP/IP access. Exposes a {@link Socket}. + * + * @author Arjen Poutsma + */ public class TcpSenderConnection extends AbstractSenderConnection { private final Socket socket; + /** Constructs a new TCP/IP connection with the given socket. */ protected TcpSenderConnection(Socket socket) { Assert.notNull(socket, "socket must not be null"); this.socket = socket; } + /** Returns the socket for this connection. */ + public Socket getSocket() { + return socket; + } + public void close() throws IOException { socket.close(); } + /* + * Errors + */ + public boolean hasError() throws IOException { return false; } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpTransportConstants.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpTransportConstants.java new file mode 100644 index 00000000..c726cebe --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpTransportConstants.java @@ -0,0 +1,29 @@ +/* + * 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.tcp; + +/** + * Declares TCP/IP-specific transport constants. + * + * @author Arjen Poutsma + */ +public interface TcpTransportConstants { + + /** The "tcp" URI scheme. */ + String TCP_URI_SCHEME = "tcp"; + +} diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingInterceptorTestCase.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingInterceptorTestCase.java index be23cf1d..5241f119 100644 --- a/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingInterceptorTestCase.java +++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AbstractWsAddressingInterceptorTestCase.java @@ -4,9 +4,9 @@ package org.springframework.ws.soap.addressing; +import java.net.URI; import java.util.Iterator; -import org.easymock.MockControl; import org.springframework.ws.context.DefaultMessageContext; import org.springframework.ws.context.MessageContext; import org.springframework.ws.soap.SoapHeaderElement; @@ -16,6 +16,8 @@ import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; import org.springframework.ws.transport.WebServiceConnection; import org.springframework.ws.transport.WebServiceMessageSender; +import org.easymock.MockControl; + public abstract class AbstractWsAddressingInterceptorTestCase extends AbstractWsAddressingTestCase { protected WsAddressingInterceptor interceptor; @@ -107,7 +109,7 @@ public abstract class AbstractWsAddressingInterceptorTestCase extends AbstractWs String messageId = "uid:1234"; strategyControl.expectAndReturn(strategyMock.newMessageId(response), messageId); - String uri = "http://example.com/business/client1"; + URI uri = new URI("http://example.com/business/client1"); senderControl.expectAndReturn(senderMock.supports(uri), true); senderControl.expectAndReturn(senderMock.createConnection(uri), connectionMock); connectionMock.send(response); diff --git a/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpIntegrationTest.java b/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpIntegrationTest.java new file mode 100644 index 00000000..63abc69f --- /dev/null +++ b/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpIntegrationTest.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.tcp; + +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 TcpIntegrationTest extends AbstractDependencyInjectionSpringContextTests { + + private WebServiceTemplate webServiceTemplate; + + protected String[] getConfigLocations() { + return new String[]{"classpath:org/springframework/ws/transport/tcp/tcp-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(); + } +} \ No newline at end of file diff --git a/sandbox/src/test/resources/org/springframework/ws/transport/tcp/tcp-applicationContext.xml b/sandbox/src/test/resources/org/springframework/ws/transport/tcp/tcp-applicationContext.xml new file mode 100644 index 00000000..16f1d53b --- /dev/null +++ b/sandbox/src/test/resources/org/springframework/ws/transport/tcp/tcp-applicationContext.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file