diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java index 441b9dadf5..ef106522c3 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java @@ -100,7 +100,9 @@ public class AnnotationGatewayProxyFactoryBean extends GatewayProxyFactoryBean { } String errorChannel = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("errorChannel")); - setErrorChannelName(errorChannel); + if (StringUtils.hasText(errorChannel)) { + setErrorChannelName(errorChannel); + } String asyncExecutor = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("asyncExecutor")); if (asyncExecutor == null || AnnotationConstants.NULL.equals(asyncExecutor)) { @@ -146,11 +148,15 @@ public class AnnotationGatewayProxyFactoryBean extends GatewayProxyFactoryBean { String defaultRequestTimeout = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("defaultRequestTimeout")); - setDefaultRequestTimeout(Long.parseLong(defaultRequestTimeout)); + if (StringUtils.hasText(defaultRequestTimeout)) { + setDefaultRequestTimeout(Long.parseLong(defaultRequestTimeout)); + } String defaultReplyTimeout = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("defaultReplyTimeout")); - setDefaultReplyTimeout(Long.parseLong(defaultReplyTimeout)); + if (StringUtils.hasText(defaultReplyTimeout)) { + setDefaultReplyTimeout(Long.parseLong(defaultReplyTimeout)); + } super.onInit(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java b/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java index 8610d18fbb..231ef7a591 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java @@ -33,6 +33,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -53,6 +54,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; +import org.springframework.core.task.TaskExecutor; import org.springframework.integration.MessageDispatchingException; import org.springframework.integration.annotation.MessageEndpoint; import org.springframework.integration.annotation.MessagingGateway; @@ -501,6 +503,26 @@ public class IntegrationFlowTests { this.flow2WithPrototypeHandlerConsumer.getHandler()); } + @Autowired + @Qualifier("globalErrorChannelResolutionFunction") + private Consumer globalErrorChannelResolutionGateway; + + @Autowired + SubscribableChannel errorChannel; + + @Test + public void testGlobalErrorChannelResolutionFlow() throws InterruptedException { + CountDownLatch errorMessageLatch = new CountDownLatch(1); + MessageHandler errorMessageHandler = m -> errorMessageLatch.countDown(); + this.errorChannel.subscribe(errorMessageHandler); + + this.globalErrorChannelResolutionGateway.accept("foo"); + + assertThat(errorMessageLatch.await(10, TimeUnit.SECONDS)).isTrue(); + + this.errorChannel.unsubscribe(errorMessageHandler); + } + @MessagingGateway public interface ControlBusGateway { @@ -890,6 +912,16 @@ public class IntegrationFlowTests { return f -> f.handle(handler, e -> e.id("flow2WithPrototypeHandlerConsumer")); } + @Bean + public IntegrationFlow globalErrorChannelResolutionFlow(@Qualifier("taskScheduler") TaskExecutor taskExecutor) { + return IntegrationFlows.from(Consumer.class, "globalErrorChannelResolutionFunction") + .channel(c -> c.executor(taskExecutor)) + .handle((GenericHandler) (p, h) -> { + throw new RuntimeException("intentional"); + }) + .get(); + } + } @Service