Skip to content

Commit 07040b3

Browse files
artembilangaryrussell
authored andcommitted
GH-2799: Fix AnnGateProxyFB for empty errChannel
Fixes #2799 **Cherry-pick to 5.1.x & 5.0.x** When `AnnotationGatewayProxyFactoryBean` is used for the one-way (`void`) POJI method invocation and downstream processing is based on an `ExecutorChannel`, the default `errorChannel` value from the annotation is resolved to the empty string with is set to the target gateway proxy and can not be resolved to the target bean eventually in the `MessagePublishingErrorHandler` in case of exception * Check `errorChannel` attribute for empty string and don't set it into the `errorChannelName`. This way the `MessagePublishingErrorHandler` will resolve to the global `errorChannel` as expected.
1 parent be66bc9 commit 07040b3

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ protected void onInit() {
9595
setDefaultReplyChannelName(defaultReplyChannel);
9696

9797
String errorChannel = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("errorChannel"));
98-
setErrorChannelName(errorChannel);
98+
if (StringUtils.hasText(errorChannel)) {
99+
setErrorChannelName(errorChannel);
100+
}
99101

100102
String asyncExecutor = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("asyncExecutor"));
101103
if (asyncExecutor == null || AnnotationConstants.NULL.equals(asyncExecutor)) {
@@ -141,11 +143,15 @@ else if (StringUtils.hasText(asyncExecutor)) {
141143

142144
String defaultRequestTimeout =
143145
beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("defaultRequestTimeout"));
144-
setDefaultRequestTimeout(Long.parseLong(defaultRequestTimeout));
146+
if (StringUtils.hasText(defaultRequestTimeout)) {
147+
setDefaultRequestTimeout(Long.parseLong(defaultRequestTimeout));
148+
}
145149

146150
String defaultReplyTimeout =
147151
beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("defaultReplyTimeout"));
148-
setDefaultReplyTimeout(Long.parseLong(defaultReplyTimeout));
152+
if (StringUtils.hasText(defaultReplyTimeout)) {
153+
setDefaultReplyTimeout(Long.parseLong(defaultReplyTimeout));
154+
}
149155

150156
super.onInit();
151157
}

spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.concurrent.TimeUnit;
3434
import java.util.concurrent.atomic.AtomicBoolean;
3535
import java.util.concurrent.atomic.AtomicReference;
36+
import java.util.function.Consumer;
3637
import java.util.function.Function;
3738

3839
import org.aopalliance.aop.Advice;
@@ -52,6 +53,7 @@
5253
import org.springframework.context.annotation.ComponentScan;
5354
import org.springframework.context.annotation.Configuration;
5455
import org.springframework.context.annotation.Scope;
56+
import org.springframework.core.task.TaskExecutor;
5557
import org.springframework.integration.MessageDispatchingException;
5658
import org.springframework.integration.MessageRejectedException;
5759
import org.springframework.integration.annotation.MessageEndpoint;
@@ -491,6 +493,26 @@ public void testPrototypeIsNotOverridden() {
491493
this.flow2WithPrototypeHandlerConsumer.getHandler());
492494
}
493495

496+
@Autowired
497+
@Qualifier("globalErrorChannelResolutionFunction")
498+
private Consumer<String> globalErrorChannelResolutionGateway;
499+
500+
@Autowired
501+
SubscribableChannel errorChannel;
502+
503+
@Test
504+
public void testGlobalErrorChannelResolutionFlow() throws InterruptedException {
505+
CountDownLatch errorMessageLatch = new CountDownLatch(1);
506+
MessageHandler errorMessageHandler = m -> errorMessageLatch.countDown();
507+
this.errorChannel.subscribe(errorMessageHandler);
508+
509+
this.globalErrorChannelResolutionGateway.accept("foo");
510+
511+
assertThat(errorMessageLatch.await(10, TimeUnit.SECONDS)).isTrue();
512+
513+
this.errorChannel.unsubscribe(errorMessageHandler);
514+
}
515+
494516
@MessagingGateway
495517
public interface ControlBusGateway {
496518

@@ -882,6 +904,16 @@ public IntegrationFlow flow2WithPrototypeHandler(
882904
return f -> f.handle(handler, e -> e.id("flow2WithPrototypeHandlerConsumer"));
883905
}
884906

907+
@Bean
908+
public IntegrationFlow globalErrorChannelResolutionFlow(@Qualifier("taskScheduler") TaskExecutor taskExecutor) {
909+
return IntegrationFlows.from(Consumer.class, "globalErrorChannelResolutionFunction")
910+
.channel(c -> c.executor(taskExecutor))
911+
.handle((GenericHandler<?>) (p, h) -> {
912+
throw new RuntimeException("intentional");
913+
})
914+
.get();
915+
}
916+
885917
}
886918

887919
@Service

0 commit comments

Comments
 (0)