From 9f5cdfa27d8e1bb41539992febd22aaf0bcda231 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Sat, 4 Jul 2009 23:25:36 +0000 Subject: [PATCH] Refactored support for DestinationProvider according to INT-512 without allowing arbitrary URIs from Message header values. --- .../ws/AbstractWebServiceOutboundGateway.java | 19 ++-- .../MarshallingWebServiceOutboundGateway.java | 20 ++--- .../ws/SimpleWebServiceOutboundGateway.java | 19 ++-- .../FixedUriDestinationProvider.java} | 44 +++++---- .../WebServiceOutboundGatewayParser.java | 58 +++++------- .../FixedUriDestinationProvider.java | 38 -------- .../HeaderBasedDestinationProvider.java | 86 ------------------ .../MessageAwareDestinationProvider.java | 35 -------- .../ws/config/spring-integration-ws-1.0.xsd | 51 +++++++++-- .../ws/config/StubDestinationProvider.java | 18 ++-- .../WebServiceOutboundGatewayParserTests.java | 34 +++---- ...tewayWithBothUriAndDestinationProvider.xml | 29 ++++++ ...ayWithNeitherUriNorDestinationProvider.xml | 27 ++++++ ...leWebServiceOutboundGatewayParserTests.xml | 7 +- .../HeaderBasedDestinationProviderTests.java | 90 ------------------- 15 files changed, 202 insertions(+), 373 deletions(-) rename org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/{destination/SpringWsDestinationProviderWrapper.java => config/FixedUriDestinationProvider.java} (50%) delete mode 100644 org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/FixedUriDestinationProvider.java delete mode 100644 org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProvider.java delete mode 100644 org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/MessageAwareDestinationProvider.java create mode 100644 org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithBothUriAndDestinationProvider.xml create mode 100644 org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithNeitherUriNorDestinationProvider.xml delete mode 100644 org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProviderTests.java diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java index b2a0f6ff49..05ad08db9f 100644 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java +++ b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java @@ -17,13 +17,11 @@ package org.springframework.integration.ws; import java.io.IOException; -import java.net.URI; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.handler.ReplyMessageHolder; -import org.springframework.integration.ws.destination.MessageAwareDestinationProvider; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.ws.WebServiceMessage; @@ -31,6 +29,7 @@ import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.client.core.FaultMessageResolver; import org.springframework.ws.client.core.WebServiceMessageCallback; import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.client.support.destination.DestinationProvider; import org.springframework.ws.soap.SoapMessage; import org.springframework.ws.soap.client.core.SoapActionCallback; import org.springframework.ws.transport.WebServiceMessageSender; @@ -47,16 +46,14 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro private volatile WebServiceMessageCallback requestCallback; - private final MessageAwareDestinationProvider destinationProvider; - private volatile boolean ignoreEmptyResponses = true; - public AbstractWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, WebServiceMessageFactory messageFactory) { + public AbstractWebServiceOutboundGateway(DestinationProvider destinationProvider, WebServiceMessageFactory messageFactory) { Assert.notNull(destinationProvider, "DestinationProvider must not be null"); - this.destinationProvider = destinationProvider; this.webServiceTemplate = (messageFactory != null) ? new WebServiceTemplate(messageFactory) : new WebServiceTemplate(); + this.webServiceTemplate.setDestinationProvider(destinationProvider); } @@ -97,14 +94,9 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro return this.webServiceTemplate; } - protected MessageAwareDestinationProvider getDestinationProvider(){ - return destinationProvider; - } - @Override public final void handleRequestMessage(Message message, ReplyMessageHolder replyHolder) { - Object responsePayload = this.doHandle(message.getPayload(), - this.getRequestCallback(message), this.getDestinationProvider().getDestination(message)); + Object responsePayload = this.doHandle(message.getPayload(), this.getRequestCallback(message)); if (responsePayload != null) { boolean shouldIgnore = (this.ignoreEmptyResponses && responsePayload instanceof String && !StringUtils.hasText((String) responsePayload)); @@ -114,7 +106,8 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro } } - protected abstract Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback, URI uri); + protected abstract Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback); + private WebServiceMessageCallback getRequestCallback(Message requestMessage) { if (this.requestCallback != null) { diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceOutboundGateway.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceOutboundGateway.java index 979800a6bc..f87ce6769c 100644 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceOutboundGateway.java +++ b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceOutboundGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -16,14 +16,12 @@ package org.springframework.integration.ws; -import java.net.URI; - import org.springframework.oxm.Marshaller; import org.springframework.oxm.Unmarshaller; import org.springframework.util.Assert; import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.client.core.WebServiceMessageCallback; -import org.springframework.integration.ws.destination.MessageAwareDestinationProvider; +import org.springframework.ws.client.support.destination.DestinationProvider; /** * An outbound Messaging Gateway for invoking Web Services that also supports @@ -35,7 +33,7 @@ import org.springframework.integration.ws.destination.MessageAwareDestinationPro */ public class MarshallingWebServiceOutboundGateway extends AbstractWebServiceOutboundGateway { - public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, Marshaller marshaller, Unmarshaller unmarshaller, WebServiceMessageFactory messageFactory) { + public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller, Unmarshaller unmarshaller, WebServiceMessageFactory messageFactory) { super(destinationProvider, messageFactory); Assert.notNull(marshaller, "marshaller must not be null"); Assert.notNull(unmarshaller, "unmarshaller must not be null"); @@ -43,29 +41,29 @@ public class MarshallingWebServiceOutboundGateway extends AbstractWebServiceOutb this.getWebServiceTemplate().setUnmarshaller(unmarshaller); } - public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, Marshaller marshaller, Unmarshaller unmarshaller) { + public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller, Unmarshaller unmarshaller) { this(destinationProvider, marshaller, unmarshaller, null); } - public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, Marshaller marshaller, WebServiceMessageFactory messageFactory) { + public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller, WebServiceMessageFactory messageFactory) { super(destinationProvider, messageFactory); Assert.notNull(marshaller, "marshaller must not be null"); Assert.isInstanceOf(Unmarshaller.class, marshaller, "Marshaller [" + marshaller + "] does not implement the Unmarshaller interface. " + "Please set an Unmarshaller explicitly by using the " + this.getClass().getName() + - "(String uri, Marshaller marshaller, Unmarshaller unmarshaller) constructor."); + "(DestinationProvider destinationProvider, Marshaller marshaller, Unmarshaller unmarshaller) constructor."); this.getWebServiceTemplate().setMarshaller(marshaller); this.getWebServiceTemplate().setUnmarshaller((Unmarshaller) marshaller); } - public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, Marshaller marshaller) { + public MarshallingWebServiceOutboundGateway(DestinationProvider destinationProvider, Marshaller marshaller) { this(destinationProvider, marshaller, (WebServiceMessageFactory) null); } @Override - protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback,URI uri) { - return this.getWebServiceTemplate().marshalSendAndReceive(uri.toString(),requestPayload, requestCallback); + protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback) { + return this.getWebServiceTemplate().marshalSendAndReceive(requestPayload, requestCallback); } } diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/SimpleWebServiceOutboundGateway.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/SimpleWebServiceOutboundGateway.java index 2aef3cf47e..1cb61090aa 100644 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/SimpleWebServiceOutboundGateway.java +++ b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/SimpleWebServiceOutboundGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -17,7 +17,6 @@ package org.springframework.integration.ws; import java.io.IOException; -import java.net.URI; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; @@ -27,10 +26,10 @@ import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.springframework.integration.core.MessagingException; -import org.springframework.integration.ws.destination.MessageAwareDestinationProvider; import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.client.core.SourceExtractor; import org.springframework.ws.client.core.WebServiceMessageCallback; +import org.springframework.ws.client.support.destination.DestinationProvider; import org.springframework.xml.transform.StringResult; import org.springframework.xml.transform.StringSource; import org.springframework.xml.transform.TransformerObjectSupport; @@ -45,35 +44,35 @@ public class SimpleWebServiceOutboundGateway extends AbstractWebServiceOutboundG private final SourceExtractor sourceExtractor; - public SimpleWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider) { + public SimpleWebServiceOutboundGateway(DestinationProvider destinationProvider) { this(destinationProvider, null, null); } - public SimpleWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, SourceExtractor sourceExtractor) { + public SimpleWebServiceOutboundGateway(DestinationProvider destinationProvider, SourceExtractor sourceExtractor) { this(destinationProvider, sourceExtractor, (WebServiceMessageFactory) null); } - public SimpleWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, SourceExtractor sourceExtractor, WebServiceMessageFactory messageFactory) { + public SimpleWebServiceOutboundGateway(DestinationProvider destinationProvider, SourceExtractor sourceExtractor, WebServiceMessageFactory messageFactory) { super(destinationProvider, messageFactory); this.sourceExtractor = (sourceExtractor != null) ? sourceExtractor : new DefaultSourceExtractor(); } @Override - protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback,URI uri) { + protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback) { if (requestPayload instanceof Source) { - return this.getWebServiceTemplate().sendSourceAndReceive(uri.toString(), + return this.getWebServiceTemplate().sendSourceAndReceive( (Source) requestPayload, requestCallback, this.sourceExtractor); } if (requestPayload instanceof String) { StringResult result = new StringResult(); - this.getWebServiceTemplate().sendSourceAndReceiveToResult(uri.toString(), + this.getWebServiceTemplate().sendSourceAndReceiveToResult( new StringSource((String) requestPayload), requestCallback, result); return result.toString(); } if (requestPayload instanceof Document) { DOMResult result = new DOMResult(); - this.getWebServiceTemplate().sendSourceAndReceiveToResult(uri.toString(), + this.getWebServiceTemplate().sendSourceAndReceiveToResult( new DOMSource((Document) requestPayload), requestCallback, result); return (Document)result.getNode(); } diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/SpringWsDestinationProviderWrapper.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/FixedUriDestinationProvider.java similarity index 50% rename from org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/SpringWsDestinationProviderWrapper.java rename to org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/FixedUriDestinationProvider.java index 66023f5fff..019a6fd652 100644 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/SpringWsDestinationProviderWrapper.java +++ b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/FixedUriDestinationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -14,29 +14,41 @@ * limitations under the License. */ -package org.springframework.integration.ws.destination; - -import org.springframework.ws.client.support.destination.DestinationProvider; -import org.springframework.integration.core.Message; -import org.springframework.util.Assert; +package org.springframework.integration.ws.config; import java.net.URI; +/** + * @author Jonas Partner + * @author Mark Fisher + * @since 1.0.3 + */ +import org.springframework.util.Assert; +import org.springframework.ws.client.support.destination.DestinationProvider; + /** - * Simple wrapper for Spring WS DestinationProvider instances + * A {@link DestinationProvider} implementation that returns a fixed URI. + * This is used by the outbound gateway parser when no 'destination-provider' + * reference has been configured. + * * @author Jonas Partner + * @author Mark Fisher + * @since 1.0.3 */ -public class SpringWsDestinationProviderWrapper implements MessageAwareDestinationProvider { +class FixedUriDestinationProvider implements DestinationProvider { - private final DestinationProvider destinationProvider; + private final URI uri; - public SpringWsDestinationProviderWrapper(DestinationProvider destinationProvider){ - Assert.notNull(destinationProvider, "DestinationProvider can not be null"); - this.destinationProvider = destinationProvider; - } - public URI getDestination(Message message) { - return destinationProvider.getDestination(); - } + public FixedUriDestinationProvider(String uri) { + Assert.hasText(uri, "uri must not be null or empty"); + this.uri = URI.create(uri); + } + + + public URI getDestination() { + return this.uri; + } + } diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParser.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParser.java index e1cd8e9655..e99751ed28 100644 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParser.java +++ b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParser.java @@ -18,7 +18,9 @@ package org.springframework.integration.ws.config; import org.w3c.dom.Element; +import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.adapter.config.AbstractRemotingOutboundGatewayParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; @@ -39,51 +41,37 @@ public class WebServiceOutboundGatewayParser extends AbstractRemotingOutboundGat protected String getGatewayClassName(Element element) { String simpleClassName = (StringUtils.hasText(element.getAttribute("marshaller"))) ? "MarshallingWebServiceOutboundGateway" : "SimpleWebServiceOutboundGateway"; - return "org.springframework.integration.ws." + simpleClassName; - } - - - protected void buildDestinationProvider(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - String uri = element.getAttribute("uri"); - String uriHeader = element.getAttribute("uri-header"); - String destinationProvider = element.getAttribute("destination-provider"); - - if (StringUtils.hasText(destinationProvider) && (StringUtils.hasText(uri) || StringUtils.hasText(uriHeader))) { - parserContext.getReaderContext().error("The 'uri' and/or 'uri-header' are not allowed if setting destination-provider.", element); - } - - if (!StringUtils.hasText(destinationProvider) && !(StringUtils.hasText(uri) || StringUtils.hasText(uriHeader))) { - parserContext.getReaderContext().error("At least one of 'uri' or 'uri-header' must be specified if not setting destination-provider.", element); - } - - if (StringUtils.hasText(destinationProvider)) { - builder.addConstructorArgReference(destinationProvider); - } - else if (StringUtils.hasText(uri) && ! StringUtils.hasText(uriHeader)) { - BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - BASE_PACKAGE + ".destination.FixedUriDestinationProvider"); - destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, uri); - builder.addConstructorArgValue(destinationProviderBuilder.getBeanDefinition()); - } - else { - BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - BASE_PACKAGE + ".destination.HeaderBasedDestinationProvider"); - destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, uri); - destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(1, uriHeader); - builder.addConstructorArgValue(destinationProviderBuilder.getBeanDefinition()); - } + return BASE_PACKAGE + "." + simpleClassName; } @Override protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getGatewayClassName(element)); - this.buildDestinationProvider(element, parserContext,builder); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getGatewayClassName(element)); + this.buildDestinationProvider(builder, element, parserContext); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-empty-responses"); this.postProcessGateway(builder, element, parserContext); return builder; } + private void buildDestinationProvider(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) { + String uri = element.getAttribute("uri"); + String destinationProvider = element.getAttribute("destination-provider"); + if (!(StringUtils.hasText(destinationProvider) ^ StringUtils.hasText(uri))) { + parserContext.getReaderContext().error("Exactly one of 'uri' or 'destination-provider' is required.", element); + return; + } + if (StringUtils.hasText(destinationProvider)) { + builder.addConstructorArgReference(destinationProvider); + } + else { + ConstructorArgumentValues cavs = new ConstructorArgumentValues(); + cavs.addGenericArgumentValue(uri); + builder.addConstructorArgValue(new RootBeanDefinition( + BASE_PACKAGE +".config.FixedUriDestinationProvider", cavs, null)); + } + } + @Override protected void postProcessGateway(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) { String marshallerRef = element.getAttribute("marshaller"); diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/FixedUriDestinationProvider.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/FixedUriDestinationProvider.java deleted file mode 100644 index c3edfb070a..0000000000 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/FixedUriDestinationProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.integration.ws.destination; - -import org.springframework.integration.core.Message; - -import java.net.URI; - - -/** - * @author Jonas Partner - */ -public class FixedUriDestinationProvider implements MessageAwareDestinationProvider { - - private final URI uri; - - public FixedUriDestinationProvider(URI uri){ - this.uri = uri; - } - - public URI getDestination(Message message) { - return uri; - } -} diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProvider.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProvider.java deleted file mode 100644 index 4ea3d4dea8..0000000000 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProvider.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.integration.ws.destination; - -import org.springframework.integration.core.Message; -import org.springframework.integration.message.MessageHandlingException; -import org.springframework.util.StringUtils; -import org.springframework.util.Assert; - -import java.net.URI; - -/** - * Determines a Web Service destination based on a URI provided in a header - * value. The header value's type may be either a {@link URI} or a String. - * - * @author Jonas Partner - * @author Mark Fisher - * @since 1.0.3 - */ -public class HeaderBasedDestinationProvider implements MessageAwareDestinationProvider { - - private final URI defaultUri; - - private final String headerName; - - - public HeaderBasedDestinationProvider(URI defaultUri, String headerName) { - Assert.isTrue(!(defaultUri == null && headerName == null), - "At least one of headerName or defaultUri must be provided"); - this.defaultUri = defaultUri; - this.headerName = headerName; - } - - public HeaderBasedDestinationProvider(URI defaultUri) { - this(defaultUri, null); - } - - public HeaderBasedDestinationProvider(String headerName) { - this(null, headerName); - } - - - public URI getDestination(Message message) { - URI uri = null; - if (StringUtils.hasText(this.headerName)) { - Object headerValue = message.getHeaders().get(this.headerName); - if (headerValue instanceof URI) { - uri = (URI) headerValue; - } - else if (headerValue instanceof String && StringUtils.hasText((String) headerValue)) { - uri = URI.create((String) headerValue); - } - else if (headerValue != null) { - throw new MessageHandlingException( - message, - "Invalid type for Web Service destination URI header '" - + this.headerName - + "', expected java.net.URI or java.lang.String, but received [" - + headerValue.getClass() + "]."); - } - } - if (uri == null) { - uri = defaultUri; - } - if (uri == null) { - throw new MessageHandlingException(message, - "Unable to determine URI for message and no default has been set."); - } - return uri; - } - -} diff --git a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/MessageAwareDestinationProvider.java b/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/MessageAwareDestinationProvider.java deleted file mode 100644 index 5b20dc3fe1..0000000000 --- a/org.springframework.integration.ws/src/main/java/org/springframework/integration/ws/destination/MessageAwareDestinationProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.integration.ws.destination; - -import org.springframework.integration.core.Message; - -import java.net.URI; - -/** - * @author Jonas Partner - */ -public interface MessageAwareDestinationProvider { - - /** - * Determine the URI based on the Message - * @param message - * @return - */ - public URI getDestination(Message message); - -} diff --git a/org.springframework.integration.ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-1.0.xsd b/org.springframework.integration.ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-1.0.xsd index aa4f69e7e3..17bf6b3b71 100644 --- a/org.springframework.integration.ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-1.0.xsd +++ b/org.springframework.integration.ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-1.0.xsd @@ -28,9 +28,18 @@ - + + + + A unique identifier for this Gateway. + + + + + The channel where Messages should be sent to invoke the Web Service. + @@ -40,6 +49,11 @@ + + The channel where Messages created from the Web Service responses will be sent. + This is optional. However, if non-empty responses are expected and this is not set, + then the request Messages must contain a REPLY_CHANNEL header. + @@ -47,19 +61,33 @@ - - - - + + + + The Destination URI for this Web Service Gateway. If the URI should be determined at runtime + (e.g. registry lookup), then configure a 'destination-provider' reference instead. + + + + + + + Reference to a DestinationProvider implementation. Either provide this or a 'uri', never both. + See org.springframework.ws.client.support.destination.DestinationProvider for more detail. + - + + + Reference to a Spring OXM Mashaller. If the Marshaller instance also implements + the Unmarshaller interface, then the 'unmarshaller' attribute is not required. + @@ -69,6 +97,9 @@ + + Reference to a Spring OXM Unmarshaller. + @@ -86,6 +117,9 @@ + + Reference to a Spring Web Services SourceExtractor. + @@ -95,6 +129,11 @@ + + Reference to a Spring Web Services WebServiceMessageCallback. This enables changing + the Web Service request message after the payload has been written to it but prior + to invocation of the actual Web Service. + diff --git a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/StubDestinationProvider.java b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/StubDestinationProvider.java index 0300b3c5a8..fab0930721 100644 --- a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/StubDestinationProvider.java +++ b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/StubDestinationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -16,13 +16,17 @@ package org.springframework.integration.ws.config; -import org.springframework.integration.ws.destination.MessageAwareDestinationProvider; -import org.springframework.integration.core.Message; - import java.net.URI; +import org.springframework.ws.client.support.destination.DestinationProvider; + +/** + * @author Jonas Partner + */ +public class StubDestinationProvider implements DestinationProvider { + + public URI getDestination() { + return null; + } -public class StubDestinationProvider implements MessageAwareDestinationProvider {public URI getDestination(Message message) { - return null; -} } diff --git a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java index 135df60e0f..e62ded0e28 100644 --- a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java +++ b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java @@ -21,6 +21,7 @@ import static org.junit.Assert.*; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.endpoint.AbstractEndpoint; @@ -29,7 +30,6 @@ import org.springframework.integration.endpoint.PollingConsumer; import org.springframework.integration.scheduling.IntervalTrigger; import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway; import org.springframework.integration.ws.SimpleWebServiceOutboundGateway; -import org.springframework.integration.ws.destination.HeaderBasedDestinationProvider; import org.springframework.oxm.Marshaller; import org.springframework.oxm.Unmarshaller; import org.springframework.ws.WebServiceMessageFactory; @@ -307,25 +307,7 @@ public class WebServiceOutboundGatewayParserTests { assertEquals(messageFactory, templateAccessor.getPropertyValue("messageFactory")); } - @Test - public void simpleGatewayWithUriHeader() { - ApplicationContext context = new ClassPathXmlApplicationContext( - "simpleWebServiceOutboundGatewayParserTests.xml", this.getClass()); - AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithUriHeader"); - assertEquals(EventDrivenConsumer.class, endpoint.getClass()); - Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler"); - assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass()); - DirectFieldAccessor accessor = new DirectFieldAccessor(gateway); - Object destinationProviderObject = accessor.getPropertyValue("destinationProvider"); - assertNotNull("DestinationProvider not set", destinationProviderObject); - assertEquals("Wrong type for destiantion provider", HeaderBasedDestinationProvider.class, destinationProviderObject.getClass()); - accessor = new DirectFieldAccessor(destinationProviderObject); - Object headerName = accessor.getPropertyValue("headerName"); - assertEquals("Wrong value for headerName in DestiantionProvider", "testHeaderName", headerName); - } - - @Test public void simpleGatewayWithDestinationProvider() { ApplicationContext context = new ClassPathXmlApplicationContext( "simpleWebServiceOutboundGatewayParserTests.xml", this.getClass()); @@ -334,8 +316,20 @@ public class WebServiceOutboundGatewayParserTests { Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler"); assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass()); DirectFieldAccessor accessor = new DirectFieldAccessor(gateway); - Object destinationProviderObject = accessor.getPropertyValue("destinationProvider"); + Object destinationProviderObject = new DirectFieldAccessor( + accessor.getPropertyValue("webServiceTemplate")).getPropertyValue("destinationProvider"); StubDestinationProvider stubProvider = (StubDestinationProvider)context.getBean("destinationProvider"); assertEquals("Wrong DestinationProvider", stubProvider, destinationProviderObject ); } + + @Test(expected = BeanDefinitionParsingException.class) + public void invalidGatewayWithBothUriAndDestinationProvider() { + new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml", this.getClass()); + } + + @Test(expected = BeanDefinitionParsingException.class) + public void invalidGatewayWithNeitherUriNorDestinationProvider() { + new ClassPathXmlApplicationContext("invalidGatewayWithNeitherUriNorDestinationProvider.xml", this.getClass()); + } + } diff --git a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithBothUriAndDestinationProvider.xml b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithBothUriAndDestinationProvider.xml new file mode 100644 index 0000000000..e2a6e688b3 --- /dev/null +++ b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithBothUriAndDestinationProvider.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithNeitherUriNorDestinationProvider.xml b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithNeitherUriNorDestinationProvider.xml new file mode 100644 index 0000000000..21325c8c89 --- /dev/null +++ b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/invalidGatewayWithNeitherUriNorDestinationProvider.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml index 24467d194e..5dbb8877a5 100644 --- a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml +++ b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml @@ -71,8 +71,7 @@ - + message-senders="messageSenders"/> - - diff --git a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProviderTests.java b/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProviderTests.java deleted file mode 100644 index a3c7e83c3e..0000000000 --- a/org.springframework.integration.ws/src/test/java/org/springframework/integration/ws/destination/HeaderBasedDestinationProviderTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.integration.ws.destination; - -import static org.junit.Assert.*; - -import org.springframework.integration.core.Message; -import org.springframework.integration.message.MessageBuilder; -import org.springframework.integration.message.MessageHandlingException; -import org.junit.Before; -import org.junit.Test; - -import java.net.URI; - - -/** - * @author Jonas Partner - */ -public class HeaderBasedDestinationProviderTests { - - Message messageNoHeader; - - Message messageWithHeaderSet; - - URI uriInHeader = URI.create("uriInHeader"); - - URI defaultURI = URI.create("testDefaultUri"); - - String testHeaderName = "testUriHeaderName"; - - @Before - public void setUp() { - messageNoHeader = MessageBuilder.withPayload("testPayload").build(); - messageWithHeaderSet = MessageBuilder.withPayload("otherTestPayload").setHeader(testHeaderName, uriInHeader.toString()).build(); - } - - @Test - public void testDefaultUriNoHeaderNameSet() { - - HeaderBasedDestinationProvider provider = new HeaderBasedDestinationProvider(defaultURI, null); - URI resolvedURI = provider.getDestination(messageNoHeader); - assertEquals("Wrong URI", defaultURI, resolvedURI); - } - - @Test - public void testDefaultUriAndHeaderNameSetAndPresent() { - HeaderBasedDestinationProvider provider = new HeaderBasedDestinationProvider(defaultURI, testHeaderName); - URI resolvedURI = provider.getDestination(messageWithHeaderSet); - assertEquals("Wrong URI", uriInHeader, resolvedURI); - } - - @Test - public void testDefaultUriAndHeaderNameSetAndNotPresent() { - HeaderBasedDestinationProvider provider = new HeaderBasedDestinationProvider(defaultURI, testHeaderName); - URI resolvedURI = provider.getDestination(messageNoHeader); - assertEquals("Wrong URI", defaultURI, resolvedURI); - } - - - @Test(expected = IllegalArgumentException.class) - public void testNoDefaultUriAndNoHeaderName() { - HeaderBasedDestinationProvider provider = new HeaderBasedDestinationProvider(null, null); - URI resolvedURI = provider.getDestination(messageNoHeader); - assertEquals("Wrong URI", defaultURI, resolvedURI); - } - - - @Test(expected = MessageHandlingException.class) - public void testNoDefaultUriAndHeaderNameSetButNotPresent() { - HeaderBasedDestinationProvider provider = new HeaderBasedDestinationProvider(null, testHeaderName); - URI resolvedURI = provider.getDestination(messageNoHeader); - assertEquals("Wrong URI", defaultURI, resolvedURI); - } - -} -