From ea8c454d3bbbee108b89722ca55dd2a4025dac9d Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Thu, 20 Feb 2020 14:59:32 -0500 Subject: [PATCH] GH-2818: DSL support for -ws module Resolves https://github.com/spring-projects/spring-integration/issues/2818 * Rework to improve fluency * reduce the number of factory methods and use a different spec when an external WST is provided. * Docs and address comments --- .../ws/AbstractWebServiceOutboundGateway.java | 12 +- .../MarshallingWebServiceInboundGateway.java | 17 +- .../ws/dsl/BaseWsInboundGatewaySpec.java | 65 ++++++ .../ws/dsl/BaseWsOutboundGatewaySpec.java | 167 ++++++++++++++ .../dsl/MarshallingWsInboundGatewaySpec.java | 68 ++++++ .../dsl/MarshallingWsOutboundGatewaySpec.java | 149 ++++++++++++ .../ws/dsl/SimpleWsInboundGatewaySpec.java | 51 +++++ .../ws/dsl/SimpleWsOutboundGatewaySpec.java | 193 ++++++++++++++++ .../integration/ws/dsl/Ws.java | 99 ++++++++ .../integration/ws/dsl/package-info.java | 4 + .../SimpleWebServiceOutboundGatewayTests.java | 4 +- ...eOutboundGatewayWithHeaderMapperTests.java | 4 +- .../integration/ws/dsl/WsDslTests.java | 215 ++++++++++++++++++ src/reference/asciidoc/whats-new.adoc | 6 + src/reference/asciidoc/ws.adoc | 107 +++++++++ 15 files changed, 1145 insertions(+), 16 deletions(-) create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsInboundGatewaySpec.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsOutboundGatewaySpec.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsInboundGatewaySpec.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsOutboundGatewaySpec.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsInboundGatewaySpec.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsOutboundGatewaySpec.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/Ws.java create mode 100644 spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/package-info.java create mode 100644 spring-integration-ws/src/test/java/org/springframework/integration/ws/dsl/WsDslTests.java 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 5cc240a222..6b82fec441 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -165,10 +165,14 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro this.webServiceTemplate.setFaultMessageResolver(faultMessageResolver); } + /** + * Specify the {@link WebServiceMessageSender} to use. + * @param messageSender the sender. + * @deprecated in favor of {@link #setMessageSenders(WebServiceMessageSender...)} + */ + @Deprecated public void setMessageSender(WebServiceMessageSender messageSender) { - Assert.state(!this.webServiceTemplateExplicitlySet, - () -> "'messageSender' must be specified on the provided: " + this.webServiceTemplate); - this.webServiceTemplate.setMessageSender(messageSender); + setMessageSenders(messageSender); } public void setMessageSenders(WebServiceMessageSender... messageSenders) { diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceInboundGateway.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceInboundGateway.java index b23b274d8a..1b0ae426f9 100644 --- a/spring-integration-ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceInboundGateway.java +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/MarshallingWebServiceInboundGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -30,13 +30,14 @@ import org.springframework.ws.support.MarshallingUtils; /** * @author Mark Fisher * @author Oleg Zhurakousky + * @author Gary Russell * @since 1.0.2 */ public class MarshallingWebServiceInboundGateway extends AbstractWebServiceInboundGateway { - private volatile Marshaller marshaller; + private Marshaller marshaller; - private volatile Unmarshaller unmarshaller; + private Unmarshaller unmarshaller; /** * Creates a new MarshallingWebServiceInboundGateway. @@ -58,7 +59,7 @@ public class MarshallingWebServiceInboundGateway extends AbstractWebServiceInbou * @see #MarshallingWebServiceInboundGateway(Marshaller, Unmarshaller) */ public MarshallingWebServiceInboundGateway(Marshaller marshaller) { - Assert.notNull(marshaller, "'marshaller' must no be null"); + Assert.notNull(marshaller, "'marshaller' must not be null"); Assert.isInstanceOf(Unmarshaller.class, marshaller, "When using this constructor the provided " + "Marshaller must also implement Unmarshaller"); this.marshaller = marshaller; @@ -72,19 +73,19 @@ public class MarshallingWebServiceInboundGateway extends AbstractWebServiceInbou * @param unmarshaller The unmarshaller. */ public MarshallingWebServiceInboundGateway(Marshaller marshaller, Unmarshaller unmarshaller) { - Assert.notNull(marshaller, "'marshaller' must no be null"); - Assert.notNull(unmarshaller, "'unmarshaller' must no be null"); + Assert.notNull(marshaller, "'marshaller' must not be null"); + Assert.notNull(unmarshaller, "'unmarshaller' must not be null"); this.marshaller = marshaller; this.unmarshaller = unmarshaller; } public void setMarshaller(Marshaller marshaller) { - Assert.notNull(marshaller, "'marshaller' must no be null"); + Assert.notNull(marshaller, "'marshaller' must not be null"); this.marshaller = marshaller; } public void setUnmarshaller(Unmarshaller unmarshaller) { - Assert.notNull(unmarshaller, "'unmarshaller' must no be null"); + Assert.notNull(unmarshaller, "'unmarshaller' must not be null"); this.unmarshaller = unmarshaller; } diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsInboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsInboundGatewaySpec.java new file mode 100644 index 0000000000..fa0e02320e --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsInboundGatewaySpec.java @@ -0,0 +1,65 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import org.springframework.integration.dsl.MessagingGatewaySpec; +import org.springframework.integration.ws.AbstractWebServiceInboundGateway; +import org.springframework.integration.ws.SoapHeaderMapper; + +/** + * Base {@link MessagingGatewaySpec} for web services. + * + * @param the target {@link BaseWsInboundGatewaySpec} implementation type. + * @param the target {@link AbstractWebServiceInboundGateway} implementation type. + * + * @author Gary Russell + * @since 5.3 + * + */ +public abstract class BaseWsInboundGatewaySpec< + S extends BaseWsInboundGatewaySpec, E extends AbstractWebServiceInboundGateway> + extends MessagingGatewaySpec { + + /** + * Construct an instance. + */ + protected BaseWsInboundGatewaySpec() { + super(null); + } + + /** + * Configure the header mapper. + * @param headerMapper the mapper. + * @return the spec. + */ + public S headerMapper(SoapHeaderMapper headerMapper) { + this.target.setHeaderMapper(headerMapper); + return _this(); + } + + @Override + protected E doGet() { + return assemble(create()); + } + + protected abstract E create(); + + protected E assemble(E gateway) { + return gateway; + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsOutboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsOutboundGatewaySpec.java new file mode 100644 index 0000000000..0f36d86436 --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/BaseWsOutboundGatewaySpec.java @@ -0,0 +1,167 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.expression.Expression; +import org.springframework.integration.dsl.MessageHandlerSpec; +import org.springframework.integration.util.JavaUtils; +import org.springframework.integration.ws.AbstractWebServiceOutboundGateway; +import org.springframework.integration.ws.SoapHeaderMapper; +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.client.support.interceptor.ClientInterceptor; +import org.springframework.ws.transport.WebServiceMessageSender; + +/** + * The base {@link MessageHandlerSpec} for {@link AbstractWebServiceOutboundGateway}s. + * + * @param the target {@link BaseWsOutboundGatewaySpec} implementation type. + * @param the target {@link AbstractWebServiceOutboundGateway} implementation type. + * + * @author Gary Russell + * @since 5.3 + * + */ +public abstract class BaseWsOutboundGatewaySpec< + S extends BaseWsOutboundGatewaySpec, E extends AbstractWebServiceOutboundGateway> + extends MessageHandlerSpec { + + private final Map uriVariableExpressions = new HashMap<>(); + + protected WebServiceTemplate template; // NOSONAR + + protected DestinationProvider destinationProvider; // NOSONAR + + protected String uri; // NOSONAR + + protected WebServiceMessageFactory webServiceMessageFactory; // NOSONAR + + private SoapHeaderMapper headerMapper; + + private boolean encodeUri = true; + + private boolean ignoreEmptyResponses = true; + + private WebServiceMessageCallback requestCallback; + + protected FaultMessageResolver faultMessageResolver; // NOSONAR + + protected WebServiceMessageSender[] messageSenders; // NOSONAR + + protected ClientInterceptor[] gatewayInterceptors; // NOSONAR + + protected boolean extractPayload = true; // NOSONAR + + /** + * Configure with a destination provider; + * @param destinationProvider the destination provider. + * @return the spec. + */ + public S destinationProvider(DestinationProvider destinationProvider) { + this.destinationProvider = destinationProvider; + return _this(); + } + + /** + * Configure with a URI. + * @param uri the uri. + * @return the spec. + */ + public S uri(String uri) { + this.uri = uri; + return _this(); + } + + /** + * Configure the header mapper. + * @param headerMapper the mapper. + * @return the spec. + */ + public S headerMapper(SoapHeaderMapper headerMapper) { + this.headerMapper = headerMapper; + return _this(); + } + + /** + * Set the Map of URI variable expressions to evaluate against the outbound message + * when replacing the variable placeholders in a URI template. + * @param uriVariableExpressions The URI variable expressions. + * @return the spec. + */ + public S uriVariableExpressions(Map uriVariableExpressions) { + this.uriVariableExpressions.putAll(uriVariableExpressions); + return _this(); + } + + /** + * Specify whether the URI should be encoded after any uriVariables + * are expanded and before sending the request. The default value is true. + * @param encodeUri true if the URI should be encoded. + * @return the spec. + * @see org.springframework.web.util.UriComponentsBuilder + */ + public S encodeUri(boolean encodeUri) { + this.encodeUri = encodeUri; + return _this(); + } + + /** + * Specify whether empty String response payloads should be ignored. + * The default is true. Set this to false if + * you want to send empty String responses in reply Messages. + * @param ignoreEmptyResponses true if empty responses should be ignored. + * @return the spec. + */ + public S ignoreEmptyResponses(boolean ignoreEmptyResponses) { + this.ignoreEmptyResponses = ignoreEmptyResponses; + return _this(); + } + + /** + * Specify the {@link WebServiceMessageCallback} to use. + * @param requestCallback the call back. + * @return the spec. + */ + public S requestCallback(WebServiceMessageCallback requestCallback) { + this.requestCallback = requestCallback; + return _this(); + } + + @Override + protected E doGet() { + return assemble(create()); + } + + protected abstract E create(); + + protected E assemble(E gateway) { + gateway.setUriVariableExpressions(this.uriVariableExpressions); + JavaUtils.INSTANCE + .acceptIfNotNull(this.headerMapper, gateway::setHeaderMapper); + gateway.setEncodeUri(this.encodeUri); + gateway.setIgnoreEmptyResponses(this.ignoreEmptyResponses); + gateway.setRequestCallback(this.requestCallback); + return gateway; + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsInboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsInboundGatewaySpec.java new file mode 100644 index 0000000000..70d47c887e --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsInboundGatewaySpec.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import org.springframework.integration.ws.MarshallingWebServiceInboundGateway; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.Unmarshaller; + +/** + * The spec for a {@link MarshallingWebServiceInboundGateway}. + * + * @author Gary Russell + * @since 5.3 + * + */ +public class MarshallingWsInboundGatewaySpec extends BaseWsInboundGatewaySpec { + + protected Marshaller gatewayMarshaller; // NOSONAR + + protected Unmarshaller gatewayUnmarshaller; // NOSONAR + + /** + * Specify a marshaller to use. + * @param marshaller the marshaller. + * @return the spec. + */ + public MarshallingWsInboundGatewaySpec marshaller(Marshaller marshaller) { + this.gatewayMarshaller = marshaller; + return this; + } + + /** + * Specify an unmarshaller to use. Required if the {@link #gatewayMarshaller} is not also + * an {@link Unmarshaller}. + * @param unmarshaller the unmarshaller. + * @return the spec. + */ + public MarshallingWsInboundGatewaySpec unmarshaller(Unmarshaller unmarshaller) { + this.gatewayUnmarshaller = unmarshaller; + return this; + } + + @Override + protected MarshallingWebServiceInboundGateway create() { + if (this.gatewayUnmarshaller != null) { + return new MarshallingWebServiceInboundGateway(this.gatewayMarshaller, this.gatewayUnmarshaller); + } + else { + return new MarshallingWebServiceInboundGateway(this.gatewayMarshaller); + } + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsOutboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsOutboundGatewaySpec.java new file mode 100644 index 0000000000..a800af2b11 --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsOutboundGatewaySpec.java @@ -0,0 +1,149 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import java.util.Arrays; + +import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.Unmarshaller; +import org.springframework.ws.WebServiceMessageFactory; +import org.springframework.ws.client.core.FaultMessageResolver; +import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.client.support.interceptor.ClientInterceptor; +import org.springframework.ws.transport.WebServiceMessageSender; + +/** + * The spec for a {@link MarshallingWebServiceOutboundGateway}. + * + * @author Gary Russell + * @since 5.3 + * + */ +public class MarshallingWsOutboundGatewaySpec extends BaseWsOutboundGatewaySpec< + MarshallingWsOutboundGatewaySpec, MarshallingWebServiceOutboundGateway> { + + protected MarshallingWsOutboundGatewaySpec(WebServiceTemplate template) { + this.template = template; + } + + @Override + protected MarshallingWebServiceOutboundGateway create() { + if (this.destinationProvider != null) { + return new MarshallingWebServiceOutboundGateway(this.destinationProvider, this.template); + } + else { + return new MarshallingWebServiceOutboundGateway(this.uri, this.template); + } + } + + /** + * Spec for a {@link MarshallingWebServiceOutboundGateway} where an external + * {@link WebServiceTemplate} is not provided. + * + */ + public static class MarshallingWsOutboundGatewayNoTemplateSpec extends BaseWsOutboundGatewaySpec< + MarshallingWsOutboundGatewayNoTemplateSpec, MarshallingWebServiceOutboundGateway> { + + protected Marshaller gatewayMarshaller; + + protected Unmarshaller gatewayUnmarshaller; + + /** + * Configure the marshaller to use. + * @param marshaller the marshaller. + * @return the spec. + */ + public MarshallingWsOutboundGatewayNoTemplateSpec marshaller(Marshaller marshaller) { + this.gatewayMarshaller = marshaller; + return this; + } + + /** + * Configure the unmarshaller to use. + * @param unmarshaller the unmarshaller. + * @return the spec. + */ + public MarshallingWsOutboundGatewayNoTemplateSpec unmarshaller(Unmarshaller unmarshaller) { + this.gatewayUnmarshaller = unmarshaller; + return this; + } + + /** + * Specify the {@link WebServiceMessageFactory} to use. + * @param messageFactory the message factory. + * @return the spec. + */ + public MarshallingWsOutboundGatewayNoTemplateSpec messageFactory(WebServiceMessageFactory messageFactory) { + this.webServiceMessageFactory = messageFactory; + return this; + } + + /** + * Specify the {@link FaultMessageResolver} to use. + * @param resolver the resolver. + * @return the spec. + */ + public MarshallingWsOutboundGatewayNoTemplateSpec faultMessageResolver(FaultMessageResolver resolver) { + this.faultMessageResolver = resolver; + return this; + } + + /** + * Specify the {@link WebServiceMessageSender}s to use. + * @param senders the senders. + * @return the spec. + */ + public MarshallingWsOutboundGatewayNoTemplateSpec messageSenders(WebServiceMessageSender... senders) { + this.messageSenders = Arrays.copyOf(senders, senders.length); + return this; + } + + /** + * Specify the {@link ClientInterceptor}s to use. + * @param interceptors the interceptors. + * @return the spec. + */ + public MarshallingWsOutboundGatewayNoTemplateSpec interceptors(ClientInterceptor... interceptors) { + this.gatewayInterceptors = Arrays.copyOf(interceptors, interceptors.length); + return this; + } + + @Override + protected MarshallingWebServiceOutboundGateway create() { + if (this.destinationProvider != null) { + return new MarshallingWebServiceOutboundGateway(this.destinationProvider, this.gatewayMarshaller, + this.gatewayUnmarshaller, this.webServiceMessageFactory); + } + else { + return new MarshallingWebServiceOutboundGateway(this.uri, this.gatewayMarshaller, + this.gatewayUnmarshaller, this.webServiceMessageFactory); + } + } + + @Override + protected MarshallingWebServiceOutboundGateway assemble(MarshallingWebServiceOutboundGateway gateway) { + MarshallingWebServiceOutboundGateway assembled = super.assemble(gateway); + assembled.setFaultMessageResolver(this.faultMessageResolver); + assembled.setMessageSenders(this.messageSenders); + assembled.setInterceptors(this.gatewayInterceptors); + return assembled; + } + + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsInboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsInboundGatewaySpec.java new file mode 100644 index 0000000000..258e1486a8 --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsInboundGatewaySpec.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import org.springframework.integration.ws.SimpleWebServiceInboundGateway; + +/** + * The spec for a {@link SimpleWebServiceInboundGateway}. + * + * @author Gary Russell + * @since 5.3 + * + */ +public class SimpleWsInboundGatewaySpec extends BaseWsInboundGatewaySpec { + + protected boolean extractPayload = true; // NOSONAR + + /** + * Specify true to extract the payloadSource from the request or use + * the entire request as the payload; default true. + * @param extract true to extract. + * @return the spec. + */ + public SimpleWsInboundGatewaySpec extractPayload(boolean extract) { + this.extractPayload = extract; + return this; + } + + @Override + protected SimpleWebServiceInboundGateway create() { + SimpleWebServiceInboundGateway gateway = new SimpleWebServiceInboundGateway(); + gateway.setExtractPayload(this.extractPayload); + return gateway; + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsOutboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsOutboundGatewaySpec.java new file mode 100644 index 0000000000..0770d8d8c8 --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/SimpleWsOutboundGatewaySpec.java @@ -0,0 +1,193 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import java.util.Arrays; + +import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway; +import org.springframework.integration.ws.SimpleWebServiceOutboundGateway; +import org.springframework.ws.WebServiceMessage; +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.WebServiceTemplate; +import org.springframework.ws.client.support.interceptor.ClientInterceptor; +import org.springframework.ws.transport.WebServiceMessageSender; + +/** + * The spec for a {@link SimpleWebServiceOutboundGateway}. + * + * @author Gary Russell + * @since 5.3 + * + */ +public class SimpleWsOutboundGatewaySpec extends BaseWsOutboundGatewaySpec< + SimpleWsOutboundGatewaySpec, SimpleWebServiceOutboundGateway> { + + protected SourceExtractor sourceExtractor; // NOSONAR + + protected SimpleWsOutboundGatewaySpec(WebServiceTemplate template) { + this.template = template; + } + + /** + * Configure a {@link SourceExtractor} to use. + * @param extractor the extractor. + * @return the spec. + */ + public SimpleWsOutboundGatewaySpec sourceExtractor(SourceExtractor extractor) { + this.sourceExtractor = extractor; + return this; + } + + /** + * Specify a flag to return the whole {@link WebServiceMessage} or build the + * {@code payload} based on {@link WebServiceMessage} + * and populated headers according {@code headerMapper} configuration. + * Defaults to extract payload. + * @param extract build payload or return a whole {@link WebServiceMessage} + * @return the spec. + */ + public SimpleWsOutboundGatewaySpec extractPayload(boolean extract) { + this.extractPayload = extract; + return this; + } + + + @Override + protected SimpleWebServiceOutboundGateway assemble(SimpleWebServiceOutboundGateway gateway) { + SimpleWebServiceOutboundGateway assembled = super.assemble(gateway); + assembled.setExtractPayload(this.extractPayload); + return assembled; + } + + @Override + protected SimpleWebServiceOutboundGateway create() { + SimpleWebServiceOutboundGateway gateway; + if (this.destinationProvider != null) { + gateway = new SimpleWebServiceOutboundGateway(this.destinationProvider, this.sourceExtractor, + this.webServiceMessageFactory); + } + else { + gateway = new SimpleWebServiceOutboundGateway(this.uri, this.sourceExtractor, + this.webServiceMessageFactory); + } + gateway.setWebServiceTemplate(this.template); + return gateway; + } + + /** + * Spec for a {@link MarshallingWebServiceOutboundGateway} where an external + * {@link WebServiceTemplate} is not provided. + * + */ + public static class SimpleWsOutboundGatewayNoTemplateSpec extends BaseWsOutboundGatewaySpec< + SimpleWsOutboundGatewayNoTemplateSpec, SimpleWebServiceOutboundGateway> { + + protected SourceExtractor sourceExtractor; // NOSONAR + + private boolean extractPayload; + + /** + * Configure a {@link SourceExtractor} to use. + * @param extractor the extractor. + * @return the spec. + */ + public SimpleWsOutboundGatewayNoTemplateSpec sourceExtractor(SourceExtractor extractor) { + this.sourceExtractor = extractor; + return this; + } + + + /** + * Specify the {@link WebServiceMessageFactory} to use. + * @param messageFactory the message factory. + * @return the spec. + */ + public SimpleWsOutboundGatewayNoTemplateSpec messageFactory(WebServiceMessageFactory messageFactory) { + this.webServiceMessageFactory = messageFactory; + return this; + } + + /** + * Specify the {@link FaultMessageResolver} to use. + * @param resolver the resolver. + * @return the spec. + */ + public SimpleWsOutboundGatewayNoTemplateSpec faultMessageResolver(FaultMessageResolver resolver) { + this.faultMessageResolver = resolver; + return this; + } + + /** + * Specify the {@link WebServiceMessageSender}s to use. + * @param senders the senders. + * @return the spec. + */ + public SimpleWsOutboundGatewayNoTemplateSpec messageSenders(WebServiceMessageSender... senders) { + this.messageSenders = Arrays.copyOf(senders, senders.length); + return this; + } + + /** + * Specify the {@link ClientInterceptor}s to use. + * @param interceptors the interceptors. + * @return the spec. + */ + public SimpleWsOutboundGatewayNoTemplateSpec interceptors(ClientInterceptor... interceptors) { + this.gatewayInterceptors = Arrays.copyOf(interceptors, interceptors.length); + return this; + } + + /** + * Specify a flag to return the whole {@link WebServiceMessage} or build the + * {@code payload} based on {@link WebServiceMessage} + * and populated headers according {@code headerMapper} configuration. + * Defaults to extract payload. + * @param extract build payload or return a whole {@link WebServiceMessage} + * @return the spec. + */ + public SimpleWsOutboundGatewayNoTemplateSpec extractPayload(boolean extract) { + this.extractPayload = extract; + return this; + } + + @Override + protected SimpleWebServiceOutboundGateway create() { + if (this.destinationProvider != null) { + return new SimpleWebServiceOutboundGateway(this.destinationProvider, this.sourceExtractor, + this.webServiceMessageFactory); + } + else { + return new SimpleWebServiceOutboundGateway(this.uri, this.sourceExtractor, + this.webServiceMessageFactory); + } + } + + @Override + protected SimpleWebServiceOutboundGateway assemble(SimpleWebServiceOutboundGateway gateway) { + SimpleWebServiceOutboundGateway assembled = super.assemble(gateway); + assembled.setFaultMessageResolver(this.faultMessageResolver); + assembled.setMessageSenders(this.messageSenders); + assembled.setInterceptors(this.gatewayInterceptors); + assembled.setExtractPayload(this.extractPayload); + return assembled; + } + + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/Ws.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/Ws.java new file mode 100644 index 0000000000..67d7f4690f --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/Ws.java @@ -0,0 +1,99 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import org.springframework.integration.ws.dsl.MarshallingWsOutboundGatewaySpec.MarshallingWsOutboundGatewayNoTemplateSpec; +import org.springframework.integration.ws.dsl.SimpleWsOutboundGatewaySpec.SimpleWsOutboundGatewayNoTemplateSpec; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.Unmarshaller; +import org.springframework.ws.client.core.WebServiceTemplate; + +/** + * Factory class for web service components. + * + * @author Gary Russell + * @since 5.3 + * + */ +public final class Ws { + + /** + * Create an instance. + * @return the spec. + */ + public static MarshallingWsInboundGatewaySpec marshallingInboundGateway() { + return new MarshallingWsInboundGatewaySpec(); + } + + /** + * Create an instance with the provided {@link Marshaller} (which must also implement + * {@link Unmarshaller}). + * @param marshaller the marshaller. + * @return the spec. + */ + public static MarshallingWsInboundGatewaySpec marshallingInboundGateway(Marshaller marshaller) { + MarshallingWsInboundGatewaySpec spec = new MarshallingWsInboundGatewaySpec(); + spec.marshaller(marshaller); + return spec; + } + + /** + * Create an instance. + * @return the spec. + */ + public static SimpleWsInboundGatewaySpec simpleInboundGateway() { + return new SimpleWsInboundGatewaySpec(); + } + + /** + * Create an instance with a default {@link WebServiceTemplate}. + * @return the spec. + */ + public static MarshallingWsOutboundGatewayNoTemplateSpec marshallingOutboundGateway() { + return new MarshallingWsOutboundGatewayNoTemplateSpec(); + } + + /** + * Create an instance with the provided {@link WebServiceTemplate}. + * @param template the template. + * @return the spec. + */ + public static MarshallingWsOutboundGatewaySpec marshallingOutboundGateway(WebServiceTemplate template) { + return new MarshallingWsOutboundGatewaySpec(template); + } + + /** + * Create an instance. + * @return the spec. + */ + public static SimpleWsOutboundGatewayNoTemplateSpec simpleOutboundGateway() { + return new SimpleWsOutboundGatewayNoTemplateSpec(); + } + + /** + * Create an instance with the provided {@link WebServiceTemplate}. + * @param template the template. + * @return the spec. + */ + public static SimpleWsOutboundGatewaySpec simpleOutboundGateway(WebServiceTemplate template) { + return new SimpleWsOutboundGatewaySpec(template); + } + + private Ws() { + } + +} diff --git a/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/package-info.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/package-info.java new file mode 100644 index 0000000000..b2fce402d2 --- /dev/null +++ b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains classes for DSL support. + */ +package org.springframework.integration.ws.dsl; diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/SimpleWebServiceOutboundGatewayTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/SimpleWebServiceOutboundGatewayTests.java index 8fe6b77617..5ebba21468 100644 --- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/SimpleWebServiceOutboundGatewayTests.java +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/SimpleWebServiceOutboundGatewayTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -131,7 +131,7 @@ public class SimpleWebServiceOutboundGatewayTests { SimpleWebServiceOutboundGateway gateway = new SimpleWebServiceOutboundGateway("http://testInt3022"); gateway.setRequiresReply(true); WebServiceMessageSender messageSender = createMockMessageSender(responseEmptyBodySoapMessage); - gateway.setMessageSender(messageSender); + gateway.setMessageSenders(messageSender); gateway.handleMessage(new GenericMessage("foo")); } diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayWithHeaderMapperTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayWithHeaderMapperTests.java index a2b9869d15..5a52421a9a 100644 --- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayWithHeaderMapperTests.java +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/config/WebServiceOutboundGatewayWithHeaderMapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -261,7 +261,7 @@ public class WebServiceOutboundGatewayWithHeaderMapperTests { return wsMessage; }).when(wsConnection).receive(Mockito.any(WebServiceMessageFactory.class)); - gateway.setMessageSender(messageSender); + gateway.setMessageSenders(messageSender); MessageChannel inputChannel = context.getBean(channelName, MessageChannel.class); Message message = diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/dsl/WsDslTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/dsl/WsDslTests.java new file mode 100644 index 0000000000..9f329a5905 --- /dev/null +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/dsl/WsDslTests.java @@ -0,0 +1,215 @@ +/* + * Copyright 2020 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 + * + * https://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.dsl; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import org.springframework.expression.Expression; +import org.springframework.expression.common.LiteralExpression; +import org.springframework.integration.test.util.TestUtils; +import org.springframework.integration.ws.MarshallingWebServiceInboundGateway; +import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway; +import org.springframework.integration.ws.SimpleWebServiceInboundGateway; +import org.springframework.integration.ws.SimpleWebServiceOutboundGateway; +import org.springframework.integration.ws.SoapHeaderMapper; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.Unmarshaller; +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.core.WebServiceTemplate; +import org.springframework.ws.client.support.destination.DestinationProvider; +import org.springframework.ws.client.support.interceptor.ClientInterceptor; +import org.springframework.ws.transport.WebServiceMessageSender; + +/** + * @author Gary Russell + * @since 5.3 + * + */ +public class WsDslTests { + + @Test + void marshallingInbound() { + Marshaller marshaller = mock(Marshaller.class); + Unmarshaller unmarshaller = mock(Unmarshaller.class); + MarshallingWebServiceInboundGateway gateway = Ws.marshallingInboundGateway(marshaller) + .unmarshaller(unmarshaller) + .get(); + assertThat(TestUtils.getPropertyValue(gateway, "marshaller")).isSameAs(marshaller); + assertThat(TestUtils.getPropertyValue(gateway, "unmarshaller")).isSameAs(unmarshaller); + + marshaller = mock(Both.class); + gateway = Ws.marshallingInboundGateway(marshaller).get(); + assertThat(TestUtils.getPropertyValue(gateway, "marshaller")).isSameAs(marshaller); + assertThat(TestUtils.getPropertyValue(gateway, "unmarshaller")).isSameAs(marshaller); + } + + @Test + void simpleInbound() { + SimpleWebServiceInboundGateway gateway = Ws.simpleInboundGateway() + .extractPayload(false) + .get(); + assertThat(TestUtils.getPropertyValue(gateway, "extractPayload", Boolean.class)).isFalse(); + } + + @Test + void marshallingOutbound() { + DestinationProvider destinationProvider = mock(DestinationProvider.class); + Marshaller marshaller = mock(Marshaller.class); + Unmarshaller unmarshaller = mock(Unmarshaller.class); + WebServiceMessageFactory messageFactory = mock(WebServiceMessageFactory.class); + FaultMessageResolver faultMessageResolver = mock(FaultMessageResolver.class); + SoapHeaderMapper headerMapper = mock(SoapHeaderMapper.class); + ClientInterceptor interceptor = mock(ClientInterceptor.class); + WebServiceMessageSender messageSender = mock(WebServiceMessageSender.class); + WebServiceMessageCallback requestCallback = msg -> { }; + Map uriVariableExpressions = new HashMap<>(); + uriVariableExpressions.put("foo", new LiteralExpression("bar")); + MarshallingWebServiceOutboundGateway gateway = + Ws.marshallingOutboundGateway() + .destinationProvider(destinationProvider) + .marshaller(marshaller) + .unmarshaller(unmarshaller) + .messageFactory(messageFactory) + .encodeUri(true) + .faultMessageResolver(faultMessageResolver) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .interceptors(interceptor) + .messageSenders(messageSender) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions) + .get(); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.marshaller")).isSameAs(marshaller); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.unmarshaller")).isSameAs(unmarshaller); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageFactory")).isSameAs(messageFactory); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.faultMessageResolver")) + .isSameAs(faultMessageResolver); + assertThat(TestUtils.getPropertyValue(gateway, "headerMapper")).isSameAs(headerMapper); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.interceptors", ClientInterceptor[].class)[0]) + .isSameAs(interceptor); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageSenders", + WebServiceMessageSender[].class)[0]) + .isSameAs(messageSender); + assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback); + assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions); + } + + @Test + void simpleOutbound() { + DestinationProvider destinationProvider = mock(DestinationProvider.class); + WebServiceMessageFactory messageFactory = mock(WebServiceMessageFactory.class); + FaultMessageResolver faultMessageResolver = mock(FaultMessageResolver.class); + SoapHeaderMapper headerMapper = mock(SoapHeaderMapper.class); + ClientInterceptor interceptor = mock(ClientInterceptor.class); + WebServiceMessageSender messageSender = mock(WebServiceMessageSender.class); + WebServiceMessageCallback requestCallback = msg -> { }; + Map uriVariableExpressions = new HashMap<>(); + uriVariableExpressions.put("foo", new LiteralExpression("bar")); + SourceExtractor sourceExtractor = mock(SourceExtractor.class); + SimpleWebServiceOutboundGateway gateway = + Ws.simpleOutboundGateway() + .destinationProvider(destinationProvider) + .sourceExtractor(sourceExtractor) + .messageFactory(messageFactory) + .encodeUri(true) + .faultMessageResolver(faultMessageResolver) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .interceptors(interceptor) + .messageSenders(messageSender) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions) + .extractPayload(false) + .get(); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageFactory")).isSameAs(messageFactory); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.faultMessageResolver")) + .isSameAs(faultMessageResolver); + assertThat(TestUtils.getPropertyValue(gateway, "headerMapper")).isSameAs(headerMapper); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.interceptors", ClientInterceptor[].class)[0]) + .isSameAs(interceptor); + assertThat(TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageSenders", + WebServiceMessageSender[].class)[0]) + .isSameAs(messageSender); + assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback); + assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions); + assertThat(TestUtils.getPropertyValue(gateway, "extractPayload", Boolean.class)).isFalse(); + } + + @Test + void marshallingOutboundTemplate() { + SoapHeaderMapper headerMapper = mock(SoapHeaderMapper.class); + WebServiceMessageCallback requestCallback = msg -> { }; + Map uriVariableExpressions = new HashMap<>(); + uriVariableExpressions.put("foo", new LiteralExpression("bar")); + WebServiceTemplate template = mock(WebServiceTemplate.class); + String uri = "foo"; + MarshallingWebServiceOutboundGateway gateway = + Ws.marshallingOutboundGateway(template) + .uri(uri) + .encodeUri(true) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions) + .get(); + assertThat(TestUtils.getPropertyValue(gateway, "uri")).isSameAs(uri); + assertThat(TestUtils.getPropertyValue(gateway, "headerMapper")).isSameAs(headerMapper); + assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback); + assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions); + } + + @Test + void simpleOutboundTemplate() { + SoapHeaderMapper headerMapper = mock(SoapHeaderMapper.class); + WebServiceMessageCallback requestCallback = msg -> { }; + Map uriVariableExpressions = new HashMap<>(); + uriVariableExpressions.put("foo", new LiteralExpression("bar")); + SourceExtractor sourceExtractor = mock(SourceExtractor.class); + WebServiceTemplate template = mock(WebServiceTemplate.class); + String uri = "foo"; + SimpleWebServiceOutboundGateway gateway = + Ws.simpleOutboundGateway(template) + .uri(uri) + .sourceExtractor(sourceExtractor) + .encodeUri(true) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions) + .extractPayload(false) + .get(); + assertThat(TestUtils.getPropertyValue(gateway, "headerMapper")).isSameAs(headerMapper); + assertThat(TestUtils.getPropertyValue(gateway, "requestCallback")).isSameAs(requestCallback); + assertThat(TestUtils.getPropertyValue(gateway, "uriVariableExpressions")).isEqualTo(uriVariableExpressions); + assertThat(TestUtils.getPropertyValue(gateway, "extractPayload", Boolean.class)).isFalse(); + } + + interface Both extends Marshaller, Unmarshaller { + + } + +} + diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index 8350dfb171..311cd3ad32 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -68,3 +68,9 @@ See <<./amqp.adoc#amqp-inbound-channel-adapter,AMQP Inbound Channel Adapter>> The `encodeUri` property on the `AbstractHttpRequestExecutingMessageHandler` has been deprecated in favor of newly introduced `encodingMode`. See `DefaultUriBuilderFactory.EncodingMode` JavaDocs and <<./http.adoc#http-uri-encoding,Controlling URI Encoding>> for more information. This also affects `WebFluxRequestExecutingMessageHandler`, respective Java DSL and XML configuration. + +[[x5.3-ws]] +=== Web Services Changes + +Java DSL support has been added for Web Service components. +See <<./ws.adoc#ws,Web Services Support>> for more information. diff --git a/src/reference/asciidoc/ws.adoc b/src/reference/asciidoc/ws.adoc index 72308dcee1..f5ee015774 100644 --- a/src/reference/asciidoc/ws.adoc +++ b/src/reference/asciidoc/ws.adoc @@ -169,6 +169,113 @@ Doing so might be useful, for example, when a custom transformer works against t Starting with version 5.0, the `web-service-template` reference attribute lets you inject a `WebServiceTemplate` with any possible custom properties. +[[webservices-dsl]] +=== Web Service Java DSL Support + +The equivalent configuration for the gateways shown in <> are shown in the following snippets: + +==== +[source, java] +---- +@Bean +IntegrationFlow inbound() { + return IntegrationFlows.from(Ws.simpleInboundGateway() + .id("simpleGateway")) + ... + .get(); +} +---- +==== + +==== +[source, java] +---- +@Bean +IntegrationFlow outboundMarshalled() { + return f -> f.handle(Ws.marshallingOutboundGateway() + .id("marshallingGateway") + .marshaller(someMarshaller()) + .unmarshaller(someUnmarshalller())) + ... +} +---- +==== + +==== +[source, java] +---- +@Bean +IntegrationFlow inboundMarshalled() { + return IntegrationFlows.from(Ws.marshallingInboundGateway() + .marshaller(someMarshaller()) + .unmarshaller(someUnmarshalller()) + .id("marshallingGateway")) + ... + .get(); +} +---- +==== + +Other properties can be set on the endpoint specs in a fluent manner (with the properties depending on whether or not an external `WebServiceTemplate` has been provided for outbound gateways). +Examples: + +==== +[source, java] +---- +.from(Ws.simpleInboundGateway() + .extractPayload(false)) +---- +==== + +==== +[source, java] +---- +.handle(Ws.simpleOutboundGateway(template) + .uri(uri) + .sourceExtractor(sourceExtractor) + .encodeUri(true) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions) + .extractPayload(false)) +) +---- +==== + +==== +[source, java] +---- +.handle(Ws.marshallingOutboundGateway() + .destinationProvider(destinationProvider) + .marshaller(marshaller) + .unmarshaller(unmarshaller) + .messageFactory(messageFactory) + .encodeUri(true) + .faultMessageResolver(faultMessageResolver) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .interceptors(interceptor) + .messageSenders(messageSender) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions)) +---- +==== + +==== +[source, java] +---- +.handle(Ws.marshallingOutboundGateway(template) + .uri(uri) + .encodeUri(true) + .headerMapper(headerMapper) + .ignoreEmptyResponses(true) + .requestCallback(requestCallback) + .uriVariableExpressions(uriVariableExpressions)) +) +---- +==== + [[outbound-uri]] === Outbound URI Configuration