From 40ce2ab79347ef44f1b9530207146c1c23f2ad76 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Fri, 7 Sep 2012 13:08:38 -0400 Subject: [PATCH] INT-2695 WS Support URI Schemes Other than http(s) Previously, only http: or https: URI schemes were supported by the uri attribute. To use other schemes (such as jms:), you had to provide a DestinationProvider. Add support for schemes other than http and https by creating a DestinationProvider internally when such a URI is detected. Note: s are NOT supported except when a URI with an http(s) scheme is provided. An exception is thrown if variables are provided with an incompatible URI, or if a DestinationProvider is supplied. This could break existing applications that provide an external DestinationProvider and have configured s. Previously, these variables were simply ignored. --- .../ws/AbstractWebServiceOutboundGateway.java | 25 ++++++++++++++++--- .../WebServiceOutboundGatewayParserTests.java | 17 ++++++++++++- ...leWebServiceOutboundGatewayParserTests.xml | 5 +++- src/reference/docbook/ws.xml | 17 ++++++++++++- 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java index 439c5a491d..fcc5f07eaf 100644 --- a/spring-integration-ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/AbstractWebServiceOutboundGateway.java @@ -38,6 +38,7 @@ import org.springframework.integration.MessageDeliveryException; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.support.MessageBuilder; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.util.UriTemplate; import org.springframework.web.util.UriUtils; @@ -59,6 +60,7 @@ import org.springframework.xml.transform.TransformerObjectSupport; * @author Mark Fisher * @author Jonas Partner * @author Oleg Zhurakousky + * @author Gary Russell */ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyProducingMessageHandler { @@ -78,12 +80,26 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro protected volatile SoapHeaderMapper headerMapper = new DefaultSoapHeaderMapper(); - public AbstractWebServiceOutboundGateway(String uri, WebServiceMessageFactory messageFactory) { + public AbstractWebServiceOutboundGateway(final String uri, WebServiceMessageFactory messageFactory) { Assert.hasText(uri, "URI must not be empty"); this.webServiceTemplate = (messageFactory != null) ? new WebServiceTemplate(messageFactory) : new WebServiceTemplate(); - this.destinationProvider = null; - this.uriTemplate = new HttpUrlTemplate(uri); + if (uri.toLowerCase().startsWith("http")) { + this.uriTemplate = new HttpUrlTemplate(uri); + this.destinationProvider = null; + } + else { + this.uriTemplate = null; + this.destinationProvider = new DestinationProvider() { + private volatile URI cachedUri; + public URI getDestination() { + if (this.cachedUri == null) { + this.cachedUri = URI.create(uri); + } + return this.cachedUri; + } + }; + } } public AbstractWebServiceOutboundGateway(DestinationProvider destinationProvider, WebServiceMessageFactory messageFactory) { @@ -161,6 +177,9 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro this.evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService)); } this.evaluationContext.addPropertyAccessor(new MapAccessor()); + Assert.state(this.destinationProvider != null ? CollectionUtils.isEmpty(this.uriVariableExpressions) : true, + "uri variables are not supported when a DestinationProvider is supplied, or the uri " + + "scheme is not http: or https:"); } protected WebServiceTemplate getWebServiceTemplate() { diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java index adce8d587d..a9262dd288 100644 --- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayParserTests.java @@ -18,8 +18,10 @@ package org.springframework.integration.ws.config; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import java.net.URI; import java.util.List; import org.junit.Test; @@ -45,6 +47,7 @@ import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.client.core.FaultMessageResolver; 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.ws.client.support.interceptor.ClientInterceptor; import org.springframework.ws.transport.WebServiceMessageSender; @@ -380,7 +383,7 @@ public class WebServiceOutboundGatewayParserTests { } @Test - public void testInt2718AdvisedInsideTheChain() { + public void testInt2718AdvisedInsideAChain() { adviceCalled = 0; ApplicationContext context = new ClassPathXmlApplicationContext( "simpleWebServiceOutboundGatewayParserTests.xml", this.getClass()); @@ -389,6 +392,18 @@ public class WebServiceOutboundGatewayParserTests { assertEquals(1, adviceCalled); } + @Test + public void jmsUri() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "simpleWebServiceOutboundGatewayParserTests.xml", this.getClass()); + AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithJmsUri"); + assertEquals(EventDrivenConsumer.class, endpoint.getClass()); + MessageHandler handler = TestUtils.getPropertyValue(endpoint, "handler", MessageHandler.class); + DestinationProvider destinationProvider = TestUtils.getPropertyValue(handler, "destinationProvider", DestinationProvider.class); + assertNotNull(destinationProvider); + assertEquals(URI.create("jms:wsQueue"), destinationProvider.getDestination()); + } + @Test(expected = BeanDefinitionParsingException.class) public void invalidGatewayWithBothUriAndDestinationProvider() { new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml", this.getClass()); diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml index d28939bad0..80a615ded9 100644 --- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/simpleWebServiceOutboundGatewayParserTests.xml @@ -112,7 +112,6 @@ - @@ -121,6 +120,10 @@ + + diff --git a/src/reference/docbook/ws.xml b/src/reference/docbook/ws.xml index 647ea29fa8..68f1fd8530 100644 --- a/src/reference/docbook/ws.xml +++ b/src/reference/docbook/ws.xml @@ -130,5 +130,20 @@ as per standard Spring Web Services configuration. when a custom Transformer works against the WebServiceMessage directly. - +
+ Outbound URI Configuration + + For URIs with an http: (or https:) scheme, + <uri-variable/> substitution is supported: + + + + +]]> + + For other schemes, such as jms:, or if a DestinationProvider + is supplied, variable substitution is not supported and a configuration error will result if variables + are provided. + +