From da32ce9ce54ca2d548808f649cff34e00e068c44 Mon Sep 17 00:00:00 2001 From: abilan Date: Fri, 14 Apr 2023 15:17:14 -0400 Subject: [PATCH 1/3] Fix NPEs in DSL Specs The `BaseWsInboundGatewaySpec` and `TailAdapterSpec` don't override super methods and when we call them we fail with NPE since `target` was not populated. * Fix `BaseWsInboundGatewaySpec` and its inheritors to populate the `target` from their ctors. * Remove redundant methods from `BaseWsInboundGatewaySpec` hierarchy * Propagate `AbstractWebServiceInboundGateway` properties directly to the target from the `BaseWsInboundGatewaySpec` inheritors * Override `MessageProducerSpec` methods in the `TailAdapterSpec` to populate respective option into the `FileTailInboundChannelAdapterFactoryBean` * Expose more missed options for producer endpoint in the `FileTailInboundChannelAdapterFactoryBean` **Cherry-pick to `6.0.x` & `5.5.x`** --- .../integration/dsl/MessagingGatewaySpec.java | 2 +- ...eTailInboundChannelAdapterFactoryBean.java | 22 +++++++++ .../integration/file/dsl/TailAdapterSpec.java | 47 ++++++++++++++----- .../integration/file/dsl/FileTests.java | 8 +++- .../ws/dsl/BaseWsInboundGatewaySpec.java | 19 ++------ .../dsl/MarshallingWsInboundGatewaySpec.java | 27 ++++------- .../ws/dsl/SimpleWsInboundGatewaySpec.java | 21 ++++----- .../integration/ws/dsl/WsDslTests.java | 13 +++-- 8 files changed, 97 insertions(+), 62 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/MessagingGatewaySpec.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/MessagingGatewaySpec.java index 23915e3265c..ed696e27f14 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/MessagingGatewaySpec.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/MessagingGatewaySpec.java @@ -35,7 +35,7 @@ public abstract class MessagingGatewaySpec, G extends MessagingGatewaySupport> extends IntegrationComponentSpec { - public MessagingGatewaySpec(@Nullable G gateway) { + public MessagingGatewaySpec(G gateway) { this.target = gateway; } diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java index 35c86db47ec..221aa5d56e4 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java @@ -29,6 +29,7 @@ import org.springframework.integration.file.tail.ApacheCommonsFileTailingMessageProducer; import org.springframework.integration.file.tail.FileTailingMessageProducerSupport; import org.springframework.integration.file.tail.OSDelegatingFileTailingMessageProducer; +import org.springframework.integration.support.ErrorMessageStrategy; import org.springframework.lang.Nullable; import org.springframework.messaging.MessageChannel; import org.springframework.scheduling.TaskScheduler; @@ -84,6 +85,12 @@ public class FileTailInboundChannelAdapterFactoryBean extends AbstractFactoryBea private ApplicationEventPublisher applicationEventPublisher; + private long sendTimeout; + + private boolean shouldTrack; + + private ErrorMessageStrategy errorMessageStrategy; + public void setNativeOptions(String nativeOptions) { if (StringUtils.hasText(nativeOptions)) { this.nativeOptions = nativeOptions; @@ -166,6 +173,18 @@ public void setPhase(int phase) { this.phase = phase; } + public void setSendTimeout(long sendTimeout) { + this.sendTimeout = sendTimeout; + } + + public void setShouldTrack(boolean shouldTrack) { + this.shouldTrack = shouldTrack; + } + + public void setErrorMessageStrategy(ErrorMessageStrategy errorMessageStrategy) { + this.errorMessageStrategy = errorMessageStrategy; + } + @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; @@ -242,6 +261,9 @@ protected FileTailingMessageProducerSupport createInstance() { adapter.setOutputChannel(this.outputChannel); adapter.setErrorChannel(this.errorChannel); adapter.setBeanName(this.beanName); + adapter.setSendTimeout(this.sendTimeout); + adapter.setShouldTrack(this.shouldTrack); + adapter.setErrorMessageStrategy(this.errorMessageStrategy); BeanFactory beanFactory = getBeanFactory(); JavaUtils.INSTANCE .acceptIfNotNull(this.taskExecutor, adapter::setTaskExecutor) diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/TailAdapterSpec.java b/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/TailAdapterSpec.java index 17c03d141c4..8b89122a7e2 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/TailAdapterSpec.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/TailAdapterSpec.java @@ -23,6 +23,7 @@ import org.springframework.integration.dsl.MessageProducerSpec; import org.springframework.integration.file.config.FileTailInboundChannelAdapterFactoryBean; import org.springframework.integration.file.tail.FileTailingMessageProducerSupport; +import org.springframework.integration.support.ErrorMessageStrategy; import org.springframework.lang.Nullable; import org.springframework.messaging.MessageChannel; import org.springframework.scheduling.TaskScheduler; @@ -40,12 +41,6 @@ public class TailAdapterSpec extends MessageProducerSpec the target {@link AbstractWebServiceInboundGateway} implementation type. * * @author Gary Russell + * @author Artem Bilan + * * @since 5.3 * */ @@ -35,10 +37,10 @@ public abstract class BaseWsInboundGatewaySpec< extends MessagingGatewaySpec { /** - * Construct an instance. + * Construct an instance based on the provided {@link AbstractWebServiceInboundGateway}. */ - protected BaseWsInboundGatewaySpec() { - super(null); + protected BaseWsInboundGatewaySpec(E gateway) { + super(gateway); } /** @@ -51,15 +53,4 @@ public S headerMapper(SoapHeaderMapper 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/MarshallingWsInboundGatewaySpec.java b/spring-integration-ws/src/main/java/org/springframework/integration/ws/dsl/MarshallingWsInboundGatewaySpec.java index 9bdafa5047f..7c771dca49d 100644 --- 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 @@ -24,15 +24,18 @@ * The spec for a {@link MarshallingWebServiceInboundGateway}. * * @author Gary Russell + * @author Artem Bilan + * * @since 5.3 * */ -public class MarshallingWsInboundGatewaySpec extends BaseWsInboundGatewaySpec { +public class MarshallingWsInboundGatewaySpec + extends BaseWsInboundGatewaySpec { - protected Marshaller gatewayMarshaller; // NOSONAR - protected Unmarshaller gatewayUnmarshaller; // NOSONAR + protected MarshallingWsInboundGatewaySpec() { + super(new MarshallingWebServiceInboundGateway()); + } /** * Specify a marshaller to use. @@ -40,29 +43,19 @@ public class MarshallingWsInboundGatewaySpec extends BaseWsInboundGatewaySpec { +public class SimpleWsInboundGatewaySpec + extends BaseWsInboundGatewaySpec { - protected boolean extractPayload = true; // NOSONAR + protected SimpleWsInboundGatewaySpec() { + super(new SimpleWebServiceInboundGateway()); + } /** * 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; + this.target.setExtractPayload(extract); return this; } - @Override - protected SimpleWebServiceInboundGateway create() { - SimpleWebServiceInboundGateway gateway = new SimpleWebServiceInboundGateway(); - gateway.setExtractPayload(this.extractPayload); - return gateway; - } - } 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 index 9c2c8ce2462..269f9a7b88d 100644 --- 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 @@ -24,6 +24,7 @@ import org.springframework.expression.Expression; import org.springframework.expression.common.LiteralExpression; import org.springframework.integration.test.util.TestUtils; +import org.springframework.integration.ws.DefaultSoapHeaderMapper; import org.springframework.integration.ws.MarshallingWebServiceInboundGateway; import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway; import org.springframework.integration.ws.SimpleWebServiceInboundGateway; @@ -71,10 +72,16 @@ void marshallingInbound() { @Test void simpleInbound() { - SimpleWebServiceInboundGateway gateway = Ws.simpleInboundGateway() - .extractPayload(false) - .getObject(); + DefaultSoapHeaderMapper testHeaderMapper = new DefaultSoapHeaderMapper(); + SimpleWebServiceInboundGateway gateway = + Ws.simpleInboundGateway() + .extractPayload(false) + .headerMapper(testHeaderMapper) + .errorChannel("myErrorChannel") + .getObject(); assertThat(TestUtils.getPropertyValue(gateway, "extractPayload", Boolean.class)).isFalse(); + assertThat(TestUtils.getPropertyValue(gateway, "headerMapper")).isSameAs(testHeaderMapper); + assertThat(TestUtils.getPropertyValue(gateway, "errorChannelName")).isEqualTo("myErrorChannel"); } @Test From 5fe05f86c1d5c2cff4535a07028ba96d640ba6d8 Mon Sep 17 00:00:00 2001 From: abilan Date: Fri, 14 Apr 2023 15:32:03 -0400 Subject: [PATCH 2/3] * `acceptIfNotNull()` for `errorMessageStrategy` in the `FileTailInboundChannelAdapterFactoryBean` --- .../file/config/FileTailInboundChannelAdapterFactoryBean.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java index 221aa5d56e4..47b9aa7c51e 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileTailInboundChannelAdapterFactoryBean.java @@ -263,7 +263,6 @@ protected FileTailingMessageProducerSupport createInstance() { adapter.setBeanName(this.beanName); adapter.setSendTimeout(this.sendTimeout); adapter.setShouldTrack(this.shouldTrack); - adapter.setErrorMessageStrategy(this.errorMessageStrategy); BeanFactory beanFactory = getBeanFactory(); JavaUtils.INSTANCE .acceptIfNotNull(this.taskExecutor, adapter::setTaskExecutor) @@ -275,6 +274,7 @@ protected FileTailingMessageProducerSupport createInstance() { .acceptIfNotNull(this.applicationEventPublisher, adapter::setApplicationEventPublisher) .acceptIfNotNull(this.outputChannelName, adapter::setOutputChannelName) .acceptIfNotNull(this.errorChannelName, adapter::setErrorChannelName) + .acceptIfNotNull(this.errorMessageStrategy, adapter::setErrorMessageStrategy) .acceptIfNotNull(beanFactory, adapter::setBeanFactory); adapter.afterPropertiesSet(); this.tailAdapter = adapter; From 1b256a57327fe941838bc2bf60bb0155947957ef Mon Sep 17 00:00:00 2001 From: abilan Date: Fri, 14 Apr 2023 16:28:29 -0400 Subject: [PATCH 3/3] * Fix `Unmarshaller` population logic in the `MarshallingWsInboundGatewaySpec` --- .../integration/ws/dsl/MarshallingWsInboundGatewaySpec.java | 3 +++ 1 file changed, 3 insertions(+) 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 index 7c771dca49d..af47be5dd99 100644 --- 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 @@ -44,6 +44,9 @@ protected MarshallingWsInboundGatewaySpec() { */ public MarshallingWsInboundGatewaySpec marshaller(Marshaller marshaller) { this.target.setMarshaller(marshaller); + if (marshaller instanceof Unmarshaller unmarshaller) { + return unmarshaller(unmarshaller); + } return this; }