Add IntegrationFlowDefinition.nullChannel() (#2555)

* Add `IntegrationFlowDefinition.nullChannel()`

When a `NullChannel` is used in the middle of the flow, it may be not so
obvious why our flow is stopped after accidentally added the next
endpoint

* For convenient add a terminal `nullChannel()` operator into the
`IntegrationFlowDefinition`

* * Add WARN about `NullChannel` subscription from the endpoints
This commit is contained in:
Artem Bilan
2018-09-17 11:31:26 -04:00
committed by Gary Russell
parent 6c379d7199
commit 585258373e
4 changed files with 50 additions and 3 deletions

View File

@@ -2961,6 +2961,17 @@ public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinit
return new PublisherIntegrationFlow<>(this.integrationComponents, publisher);
}
/**
* Add a {@value IntegrationContextUtils#NULL_CHANNEL_BEAN_NAME} bean into this flow
* definition as a terminal operator.
* @return The {@link IntegrationFlow} instance based on this definition.
* @since 5.1
*/
public IntegrationFlow nullChannel() {
return channel(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)
.get();
}
@SuppressWarnings("unchecked")
private <S extends ConsumerEndpointSpec<S, ? extends MessageHandler>> B register(S endpointSpec,
Consumer<S> endpointConfigurer) {

View File

@@ -25,6 +25,7 @@ import org.reactivestreams.Subscriber;
import org.springframework.context.Lifecycle;
import org.springframework.integration.channel.ExecutorChannelInterceptorAware;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.channel.ReactiveStreamsSubscribableChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.router.MessageRouter;
@@ -62,6 +63,10 @@ public class PollingConsumer extends AbstractPollingEndpoint implements Integrat
public PollingConsumer(PollableChannel inputChannel, MessageHandler handler) {
Assert.notNull(inputChannel, "inputChannel must not be null");
Assert.notNull(handler, "handler must not be null");
if (inputChannel instanceof NullChannel && logger.isWarnEnabled()) {
logger.warn("The polling from the NullChannel does not have any effects: " +
"it doesn't forward messages sent to it. A NullChannel is the end of the flow.");
}
this.inputChannel = inputChannel;
this.handler = handler;
if (this.inputChannel instanceof ExecutorChannelInterceptorAware) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2017 the original author or authors.
* Copyright 2016-2018 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.
@@ -25,6 +25,7 @@ import org.reactivestreams.Subscription;
import org.springframework.context.Lifecycle;
import org.springframework.integration.channel.MessageChannelReactiveUtils;
import org.springframework.integration.channel.MessagePublishingErrorHandler;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.router.MessageRouter;
import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
@@ -41,6 +42,7 @@ import reactor.core.publisher.BaseSubscriber;
/**
* @author Artem Bilan
*
* @since 5.0
*/
public class ReactiveStreamsConsumer extends AbstractEndpoint implements IntegrationConsumer {
@@ -72,6 +74,11 @@ public class ReactiveStreamsConsumer extends AbstractEndpoint implements Integra
Assert.notNull(inputChannel, "'inputChannel' must not be null");
Assert.notNull(subscriber, "'subscriber' must not be null");
if (inputChannel instanceof NullChannel && logger.isWarnEnabled()) {
logger.warn("The consuming from the NullChannel does not have any effects: " +
"it doesn't forward messages sent to it. A NullChannel is the end of the flow.");
}
this.publisher = MessageChannelReactiveUtils.toPublisher(inputChannel);
this.subscriber = subscriber;
this.lifecycleDelegate = subscriber instanceof Lifecycle ? (Lifecycle) subscriber : null;