Skip to content

Commit 626ba7a

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 b4273dd commit 626ba7a

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
@@ -100,7 +100,9 @@ protected void onInit() {
100100
}
101101

102102
String errorChannel = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("errorChannel"));
103-
setErrorChannelName(errorChannel);
103+
if (StringUtils.hasText(errorChannel)) {
104+
setErrorChannelName(errorChannel);
105+
}
104106

105107
String asyncExecutor = beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("asyncExecutor"));
106108
if (asyncExecutor == null || AnnotationConstants.NULL.equals(asyncExecutor)) {
@@ -146,11 +148,15 @@ else if (StringUtils.hasText(asyncExecutor)) {
146148

147149
String defaultRequestTimeout =
148150
beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("defaultRequestTimeout"));
149-
setDefaultRequestTimeout(Long.parseLong(defaultRequestTimeout));
151+
if (StringUtils.hasText(defaultRequestTimeout)) {
152+
setDefaultRequestTimeout(Long.parseLong(defaultRequestTimeout));
153+
}
150154

151155
String defaultReplyTimeout =
152156
beanFactory.resolveEmbeddedValue(this.gatewayAttributes.getString("defaultReplyTimeout"));
153-
setDefaultReplyTimeout(Long.parseLong(defaultReplyTimeout));
157+
if (StringUtils.hasText(defaultReplyTimeout)) {
158+
setDefaultReplyTimeout(Long.parseLong(defaultReplyTimeout));
159+
}
154160

155161
super.onInit();
156162
}

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
@@ -25,6 +25,7 @@
2525
import java.util.concurrent.TimeUnit;
2626
import java.util.concurrent.atomic.AtomicBoolean;
2727
import java.util.concurrent.atomic.AtomicReference;
28+
import java.util.function.Consumer;
2829
import java.util.function.Function;
2930
import java.util.function.Supplier;
3031

@@ -45,6 +46,7 @@
4546
import org.springframework.context.annotation.ComponentScan;
4647
import org.springframework.context.annotation.Configuration;
4748
import org.springframework.context.annotation.Scope;
49+
import org.springframework.core.task.TaskExecutor;
4850
import org.springframework.integration.MessageDispatchingException;
4951
import org.springframework.integration.annotation.MessageEndpoint;
5052
import org.springframework.integration.annotation.MessagingGateway;
@@ -493,6 +495,26 @@ public void testPrototypeIsNotOverridden() {
493495
.isNotSameAs(this.flow1WithPrototypeHandlerConsumer.getHandler());
494496
}
495497

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

@@ -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)