Registered RendezvousChannel bean cannot be found within Spring Application Context

Tobias

In a Spring Boot application, we´re using a request-reply pattern by leveraging the RendezvousChannel from Spring Integration. When we receive a request, we create a uniquely named channel and register it within the Spring application context as follows:

RendezvousChannel rendezvousChannel = MessageChannels.rendezvous(uniqueId).get();
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) springContext;
SingletonBeanRegistry beanRegistry = configurableApplicationContext.getBeanFactory();
beanRegistry.registerSingleton(uniqueId, rendezvousChannel);

We then add this channel name to the request and do some work that takes some seconds. Then the response to this request arrives and is routed into the RendezvousChannel:

@Bean
public IntegrationFlow flow() {
    return IntegrationFlows.from(globalChannel)
            .route("payload['replyChannel']")
            .get();
}

This works great and we receive the response to the request as desired. But under load, when lots of temp. RendezvousChannels are created, the routing sometimes fails with:

org.springframework.messaging.MessagingException: failed to resolve channel name 'uniqueId'; 
nested exception is org.springframework.messaging.core.DestinationResolutionException: failed to look up MessageChannel with name 'uniqueId' in the BeanFactory.; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'uniqueId' available, failedMessage=GenericMessage...
at org.springframework.integration.router.AbstractMappingMessageRouter.resolveChannelForName(AbstractMappingMessageRouter.java:227)
at org.springframework.integration.router.AbstractMappingMessageRouter.addChannelFromString(AbstractMappingMessageRouter.java:258)
at org.springframework.integration.router.AbstractMappingMessageRouter.addToCollection(AbstractMappingMessageRouter.java:282)
at org.springframework.integration.router.AbstractMappingMessageRouter.determineTargetChannels(AbstractMappingMessageRouter.java:186)
at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:171)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:426)

Currently I´m not sure why this happens. Any ideas on this?

Artem Bilan

For request-reply scenarios we recommend to use a @MessagingGateway: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints-chapter.html#gateway

This one populates a TemporaryReplyChannel instance into the headers under the replyChannel key. Before sending to some outbound, external service you need to use something like this in your IntegrationFlow:

.enrichHeaders(h -> h.headerChannelsToString())

This way the mentioned TemporaryReplyChannel is stored in some specific HeaderChannelRegistry: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-transformation-chapter.html#header-channel-registry

After that you really can provide some transform() to pack a replyHeader into the payload according your requirements. For this purpose, by the way, we provide something like EmbeddedJsonHeadersMessageMapper, which can be used from the mentioned transform() as a plain POJO consumer.

When you receive a reply, you should ensure that at least required replyChannel property comes together with the actual reply payload. In this case you again can use EmbeddedJsonHeadersMessageMapper.toMessage() to remap embedded headers back to the MessageHeaders or you need to ensure the remapping by yourself. What is important that you have to populate a replyChannel header in this case. In the end you can just reply on the standard mechanism to send an output to the replyChannel from header. The mentioned above HeaderChannelRegistry will ensure resolution of the string id to the actual TemporaryReplyChannel instance meanwhile a gateway in the beginning will still wait for the value from that TemporaryReplyChannel.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

No Bean Found in Spring Boot application context

Spring application context reloading doesn't update bean registered by DelegatingFilterProxy

Kotlin Spring cannot register bean in application context

Get a bean (programmatically registered) from Spring context?

Spring Application context not found

Spring Boot application-The bean could not be registered

Spring Boot application-The bean could not be registered

What is Application context and bean factory in spring framework

Spring bean dependencies in the application context form a cycle

Spring SPEL error: SpelEvaluationException: EL1057E: No bean resolver registered in the context to resolve access to bean 'validatorService'

Basic Spring JDBC application, JdbcTemplate bean not found

No bean resolver registered in the context to resolve access to bean

Spring integration test with context hierarchy child context bean as application listener

Adding inner bean to Application Context throws No default constructor found execption

Adding a Pre-constructed Bean to a Spring Application Context

Spring application context has my bean but @autowired doesn't see it

Mocking a bean in a Spring context

Spring-integration gateway cannot be autowired, no qualifying bean found

Spring Boot application failed to start, bean could not be found

Spring Bean Not Found

XML Context based bean cannot perform constructor injection : No default constructor found

Spring cannot create bean

Cannot get spring bean?

No WebApplicationContext found: no ContextLoaderListener registered? in Spring 4 MVC

Getting Spring Application Context

Spring application context encryption

Spring application context is null

how do I create bean at application startup before loading spring context?

Spring Boot: class with @Service bean bean not found