Fix NPEs in DSL Specs (#8597)

* 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`**

* * `acceptIfNotNull()` for `errorMessageStrategy` in the `FileTailInboundChannelAdapterFactoryBean`

* * Fix `Unmarshaller` population logic in the `MarshallingWsInboundGatewaySpec`
This commit is contained in:
Artem Bilan
2023-04-18 11:12:23 -04:00
committed by Gary Russell
parent 863795c11f
commit a45c3c5396
7 changed files with 101 additions and 60 deletions

View File

@@ -27,6 +27,8 @@ import org.springframework.integration.ws.SoapHeaderMapper;
* @param <E> 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<S, E> {
/**
* 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 abstract class BaseWsInboundGatewaySpec<
return _this();
}
@Override
protected E doGet() {
return assemble(create());
}
protected abstract E create();
protected E assemble(E gateway) {
return gateway;
}
}

View File

@@ -24,15 +24,18 @@ import org.springframework.oxm.Unmarshaller;
* The spec for a {@link MarshallingWebServiceInboundGateway}.
*
* @author Gary Russell
* @author Artem Bilan
*
* @since 5.3
*
*/
public class MarshallingWsInboundGatewaySpec extends BaseWsInboundGatewaySpec<MarshallingWsInboundGatewaySpec,
MarshallingWebServiceInboundGateway> {
public class MarshallingWsInboundGatewaySpec
extends BaseWsInboundGatewaySpec<MarshallingWsInboundGatewaySpec, MarshallingWebServiceInboundGateway> {
protected Marshaller gatewayMarshaller; // NOSONAR
protected Unmarshaller gatewayUnmarshaller; // NOSONAR
protected MarshallingWsInboundGatewaySpec() {
super(new MarshallingWebServiceInboundGateway());
}
/**
* Specify a marshaller to use.
@@ -40,29 +43,22 @@ public class MarshallingWsInboundGatewaySpec extends BaseWsInboundGatewaySpec<Ma
* @return the spec.
*/
public MarshallingWsInboundGatewaySpec marshaller(Marshaller marshaller) {
this.gatewayMarshaller = marshaller;
this.target.setMarshaller(marshaller);
if (marshaller instanceof Unmarshaller unmarshaller) {
return unmarshaller(unmarshaller);
}
return this;
}
/**
* Specify an unmarshaller to use. Required if the {@link #gatewayMarshaller} is not also
* Specify an unmarshaller to use. Required if the {@link #marshaller} is not also
* an {@link Unmarshaller}.
* @param unmarshaller the unmarshaller.
* @return the spec.
*/
public MarshallingWsInboundGatewaySpec unmarshaller(Unmarshaller unmarshaller) {
this.gatewayUnmarshaller = unmarshaller;
this.target.setUnmarshaller(unmarshaller);
return this;
}
@Override
protected MarshallingWebServiceInboundGateway create() {
if (this.gatewayUnmarshaller != null) {
return new MarshallingWebServiceInboundGateway(this.gatewayMarshaller, this.gatewayUnmarshaller);
}
else {
return new MarshallingWebServiceInboundGateway(this.gatewayMarshaller);
}
}
}

View File

@@ -22,30 +22,27 @@ import org.springframework.integration.ws.SimpleWebServiceInboundGateway;
* The spec for a {@link SimpleWebServiceInboundGateway}.
*
* @author Gary Russell
* @since 5.3
* @author Artem Bilan
*
* @since 5.3
*/
public class SimpleWsInboundGatewaySpec extends BaseWsInboundGatewaySpec<SimpleWsInboundGatewaySpec,
SimpleWebServiceInboundGateway> {
public class SimpleWsInboundGatewaySpec
extends BaseWsInboundGatewaySpec<SimpleWsInboundGatewaySpec, SimpleWebServiceInboundGateway> {
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;
}
}

View File

@@ -24,6 +24,7 @@ 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.DefaultSoapHeaderMapper;
import org.springframework.integration.ws.MarshallingWebServiceInboundGateway;
import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway;
import org.springframework.integration.ws.SimpleWebServiceInboundGateway;
@@ -71,10 +72,16 @@ public class WsDslTests {
@Test
void simpleInbound() {
SimpleWebServiceInboundGateway gateway = Ws.simpleInboundGateway()
.extractPayload(false)
.get();
DefaultSoapHeaderMapper testHeaderMapper = new DefaultSoapHeaderMapper();
SimpleWebServiceInboundGateway gateway =
Ws.simpleInboundGateway()
.extractPayload(false)
.headerMapper(testHeaderMapper)
.errorChannel("myErrorChannel")
.get();
assertThat(TestUtils.getPropertyValue(gateway, "extractPayload", Boolean.class)).isFalse();
assertThat(TestUtils.getPropertyValue(gateway, "headerMapper")).isSameAs(testHeaderMapper);
assertThat(TestUtils.getPropertyValue(gateway, "errorChannelName")).isEqualTo("myErrorChannel");
}
@Test