GH-9709: Fix IntegrationFlow for input channel resolution

Fixes: #9709
Issue link: https://github.com/spring-projects/spring-integration/issues/9709

The Java DSL loses an `inputChannel` when existing channel is referenced by its name.
Then the target IntegrationFlow does not contain a bean reference for this channel and when we call its `getInputChannel()` we got something from middle of the flow.
However, that `inputChannel` is really expected to be an input for the flow.

* Fix `IntegrationFlowBeanPostProcessor` to get a bean by `MessageChannelReference` and populate it into `targetIntegrationComponents`
as we do for newly created `DirectChannel` if there is no bean for provided `MessageChannelReference`

# Conflicts:
#	spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java
This commit is contained in:
Artem Bilan
2024-12-10 16:34:29 -05:00
parent 1071c3c082
commit d8fb02306f
2 changed files with 17 additions and 6 deletions

View File

@@ -74,6 +74,7 @@ import org.springframework.integration.dsl.support.MessageChannelReference;
import org.springframework.integration.gateway.AnnotationGatewayProxyFactoryBean;
import org.springframework.integration.support.context.NamedComponent;
import org.springframework.lang.Nullable;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -181,11 +182,15 @@ public class IntegrationFlowBeanPostProcessor
}
else if (component instanceof MessageChannelReference messageChannelReference) {
String channelBeanName = messageChannelReference.name();
MessageChannel channelByName;
if (!this.beanFactory.containsBean(channelBeanName)) {
DirectChannel directChannel = new DirectChannel();
registerComponent(directChannel, channelBeanName, flowBeanName);
targetIntegrationComponents.put(directChannel, channelBeanName);
channelByName = new DirectChannel();
registerComponent(channelByName, channelBeanName, flowBeanName);
}
else {
channelByName = this.beanFactory.getBean(channelBeanName, MessageChannel.class);
}
targetIntegrationComponents.put(channelByName, channelBeanName);
}
else if (component instanceof SourcePollingChannelAdapterSpec spec) {
Map<Object, String> componentsToRegister = spec.getComponentsToRegister();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2021-2023 the original author or authors.
* Copyright 2021-2024 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.
@@ -202,11 +202,17 @@ public class IntegrationFlowCompositionTests {
.to(lastFlow);
}
@Bean
DirectChannel lastFlowInput() {
return new DirectChannel();
}
@Bean
IntegrationFlow lastFlow() {
return f -> f
return IntegrationFlow.from("lastFlowInput")
.<String, String>transform(p -> p + ", and last flow")
.channel(c -> c.queue("lastFlowResult"));
.channel(c -> c.queue("lastFlowResult"))
.get();
}
}