Add in support for dyanmic resolution of the uri in outbound WS gateways
Resolves INT-512, INT-612
This commit is contained in:
@@ -23,6 +23,7 @@ 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.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
@@ -44,12 +45,14 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
|
||||
private volatile WebServiceMessageCallback requestCallback;
|
||||
|
||||
private final MessageAwareDestinationProvider destinationProvider;
|
||||
|
||||
public AbstractWebServiceOutboundGateway(URI uri, WebServiceMessageFactory messageFactory) {
|
||||
Assert.notNull(uri, "URI must not be null");
|
||||
this.webServiceTemplate = (messageFactory != null) ?
|
||||
|
||||
public AbstractWebServiceOutboundGateway(MessageAwareDestinationProvider 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.setDefaultUri(uri.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -81,15 +84,19 @@ 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));
|
||||
Object responsePayload = this.doHandle(message.getPayload(), this.getRequestCallback(message),this.getDestinationProvider().getDestination(message));
|
||||
if (responsePayload != null) {
|
||||
replyHolder.set(responsePayload);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback);
|
||||
protected abstract Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback, URI uri);
|
||||
|
||||
private WebServiceMessageCallback getRequestCallback(Message<?> requestMessage) {
|
||||
if (this.requestCallback != null) {
|
||||
|
||||
@@ -23,6 +23,7 @@ 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;
|
||||
|
||||
/**
|
||||
* An outbound Messaging Gateway for invoking Web Services that also supports
|
||||
@@ -34,20 +35,20 @@ import org.springframework.ws.client.core.WebServiceMessageCallback;
|
||||
*/
|
||||
public class MarshallingWebServiceOutboundGateway extends AbstractWebServiceOutboundGateway {
|
||||
|
||||
public MarshallingWebServiceOutboundGateway(URI uri, Marshaller marshaller, Unmarshaller unmarshaller, WebServiceMessageFactory messageFactory) {
|
||||
super(uri, messageFactory);
|
||||
public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider 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");
|
||||
this.getWebServiceTemplate().setMarshaller(marshaller);
|
||||
this.getWebServiceTemplate().setUnmarshaller(unmarshaller);
|
||||
}
|
||||
|
||||
public MarshallingWebServiceOutboundGateway(URI uri, Marshaller marshaller, Unmarshaller unmarshaller) {
|
||||
this(uri, marshaller, unmarshaller, null);
|
||||
public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, Marshaller marshaller, Unmarshaller unmarshaller) {
|
||||
this(destinationProvider, marshaller, unmarshaller, null);
|
||||
}
|
||||
|
||||
public MarshallingWebServiceOutboundGateway(URI uri, Marshaller marshaller, WebServiceMessageFactory messageFactory) {
|
||||
super(uri, messageFactory);
|
||||
public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider 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. " +
|
||||
@@ -57,14 +58,14 @@ public class MarshallingWebServiceOutboundGateway extends AbstractWebServiceOutb
|
||||
this.getWebServiceTemplate().setUnmarshaller((Unmarshaller) marshaller);
|
||||
}
|
||||
|
||||
public MarshallingWebServiceOutboundGateway(URI uri, Marshaller marshaller) {
|
||||
this(uri, marshaller, (WebServiceMessageFactory) null);
|
||||
public MarshallingWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, Marshaller marshaller) {
|
||||
this(destinationProvider, marshaller, (WebServiceMessageFactory) null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback) {
|
||||
return this.getWebServiceTemplate().marshalSendAndReceive(requestPayload, requestCallback);
|
||||
protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback,URI uri) {
|
||||
return this.getWebServiceTemplate().marshalSendAndReceive(uri.toString(),requestPayload, requestCallback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ 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;
|
||||
@@ -44,35 +45,35 @@ public class SimpleWebServiceOutboundGateway extends AbstractWebServiceOutboundG
|
||||
private final SourceExtractor sourceExtractor;
|
||||
|
||||
|
||||
public SimpleWebServiceOutboundGateway(URI uri) {
|
||||
this(uri, null, null);
|
||||
public SimpleWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider) {
|
||||
this(destinationProvider, null, null);
|
||||
}
|
||||
|
||||
public SimpleWebServiceOutboundGateway(URI uri, SourceExtractor sourceExtractor) {
|
||||
this(uri, sourceExtractor, (WebServiceMessageFactory) null);
|
||||
public SimpleWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, SourceExtractor sourceExtractor) {
|
||||
this(destinationProvider, sourceExtractor, (WebServiceMessageFactory) null);
|
||||
}
|
||||
|
||||
public SimpleWebServiceOutboundGateway(URI uri, SourceExtractor sourceExtractor, WebServiceMessageFactory messageFactory) {
|
||||
super(uri, messageFactory);
|
||||
public SimpleWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, SourceExtractor sourceExtractor, WebServiceMessageFactory messageFactory) {
|
||||
super(destinationProvider, messageFactory);
|
||||
this.sourceExtractor = (sourceExtractor != null) ? sourceExtractor : new DefaultSourceExtractor();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback) {
|
||||
protected Object doHandle(Object requestPayload, WebServiceMessageCallback requestCallback,URI uri) {
|
||||
if (requestPayload instanceof Source) {
|
||||
return this.getWebServiceTemplate().sendSourceAndReceive(
|
||||
return this.getWebServiceTemplate().sendSourceAndReceive(uri.toString(),
|
||||
(Source) requestPayload, requestCallback, this.sourceExtractor);
|
||||
}
|
||||
if (requestPayload instanceof String) {
|
||||
StringResult result = new StringResult();
|
||||
this.getWebServiceTemplate().sendSourceAndReceiveToResult(
|
||||
this.getWebServiceTemplate().sendSourceAndReceiveToResult(uri.toString(),
|
||||
new StringSource((String) requestPayload), requestCallback, result);
|
||||
return result.toString();
|
||||
}
|
||||
if (requestPayload instanceof Document) {
|
||||
DOMResult result = new DOMResult();
|
||||
this.getWebServiceTemplate().sendSourceAndReceiveToResult(
|
||||
this.getWebServiceTemplate().sendSourceAndReceiveToResult(uri.toString(),
|
||||
new DOMSource((Document) requestPayload), requestCallback, result);
|
||||
return (Document)result.getNode();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ import org.w3c.dom.Element;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.adapter.config.AbstractRemotingOutboundGatewayParser;
|
||||
import org.springframework.integration.ws.destination.MessageAwareDestinationProvider;
|
||||
import org.springframework.integration.ws.destination.HeaderBasedDestinationProvider;
|
||||
import org.springframework.integration.ws.destination.FixedUriDestinationProvider;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -37,13 +40,47 @@ public class WebServiceOutboundGatewayParser extends AbstractRemotingOutboundGat
|
||||
return "org.springframework.integration.ws." + simpleClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parseUrl(Element element, ParserContext parserContext) {
|
||||
|
||||
protected void buildDestinationProvider(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String uri = element.getAttribute("uri");
|
||||
if (!StringUtils.hasText(uri)) {
|
||||
parserContext.getReaderContext().error("The 'uri' attribute is required.", element);
|
||||
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' can not be specified if setting destination-provider.", element);
|
||||
}
|
||||
return uri;
|
||||
|
||||
if (!StringUtils.hasText(destinationProvider) && !(StringUtils.hasText(uri) || StringUtils.hasText(uriHeader))) {
|
||||
parserContext.getReaderContext().error("The 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(FixedUriDestinationProvider.class);
|
||||
destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, uri);
|
||||
builder.addConstructorArgValue(destinationProviderBuilder.getBeanDefinition());
|
||||
}else{
|
||||
BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition(HeaderBasedDestinationProvider.class);
|
||||
destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, uri);
|
||||
destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(1, uriHeader);
|
||||
builder.addConstructorArgValue(destinationProviderBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getGatewayClassName(element));
|
||||
this.buildDestinationProvider(element, parserContext,builder);
|
||||
|
||||
String replyChannel = element.getAttribute("reply-channel");
|
||||
if (StringUtils.hasText(replyChannel)) {
|
||||
builder.addPropertyReference("replyChannel", replyChannel);
|
||||
}
|
||||
this.postProcessGateway(builder, element, parserContext);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,8 +47,18 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="uri" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="marshaller" type="xsd:string">
|
||||
<xsd:attribute name="uri" type="xsd:string" />
|
||||
<xsd:attribute name="uri-header" type="xsd:string" />
|
||||
<xsd:attribute name="destination-provider" type="xsd:string" >
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.ws.destination.MessageAwareDestinationProvider"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="marshaller" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 org.springframework.integration.message.MessageDeliveryException;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
||||
/**
|
||||
* Determines URI based
|
||||
*/
|
||||
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 defaultURI or headerName must be provided");
|
||||
this.defaultUri = defaultUri;
|
||||
this.headerName = headerName;
|
||||
}
|
||||
|
||||
public HeaderBasedDestinationProvider(URI defaultUri) {
|
||||
this.defaultUri = defaultUri;
|
||||
this.headerName = null;
|
||||
}
|
||||
|
||||
public HeaderBasedDestinationProvider( String headerName) {
|
||||
this.defaultUri = null;
|
||||
this.headerName = headerName;
|
||||
}
|
||||
|
||||
|
||||
public URI getDestination(Message<?> message) {
|
||||
URI uri = null;
|
||||
if(StringUtils.hasText(headerName)) {
|
||||
String headerValue = message.getHeaders().get(headerName, String.class);
|
||||
if(StringUtils.hasText(headerValue)){
|
||||
uri = URI.create(headerValue);
|
||||
}
|
||||
}
|
||||
if(uri == null){
|
||||
uri = defaultUri;
|
||||
}
|
||||
|
||||
if(uri == null){
|
||||
throw new MessageHandlingException(message,"Could not determine URI for message and no default set");
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.ws.client.support.destination.DestinationProvider;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
||||
/**
|
||||
* Simple wrapper for Spring WS DestinationProvider instances
|
||||
* @author Jonas Partner
|
||||
*/
|
||||
public class SpringWsDestinationProviderWrapper implements MessageAwareDestinationProvider {
|
||||
|
||||
private final DestinationProvider destinationProvider;
|
||||
|
||||
public SpringWsDestinationProviderWrapper(DestinationProvider destinationProvider){
|
||||
Assert.notNull(destinationProvider, "DestinationProvider can not be null");
|
||||
this.destinationProvider = destinationProvider;
|
||||
}
|
||||
|
||||
public URI getDestination(Message<?> message) {
|
||||
return destinationProvider.getDestination();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user