Announcement Announcement Module
No announcement yet.
Dynamically creating MessageChannels Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dynamically creating MessageChannels

    I have a situation where I would like to dynamically create MessageChannels at runtime based on external information. Specifically, I want to have a single channel per remote host where the available hosts are determined by host availability. This logic will (hopefully) be encapsulated within a router so client code can send to a single channel and have the Message wind up at the proper, available, host. In other words:

    Client ====> HostRouter --+-----> ChannelAdapter to host A
                              +-----> ChannelAdapter to host B
    Statically defined channel: ===> 
    Dynamic (runtime, programmatically defined) channel: ---->
    Really, all I'm talking about doing is manually creating new Channels, and endpoints programmatically, but making sure Spring Integration is aware of them. As far as I can tell, based on my experimentation, it looks like Integration assumes channel names returned from a Router is the name of a bean in the context.

    Is the correct approach to do something like make the Router implementation ApplicationContextAware and inject new beans after the container is started? Alternatively, is it better to be a BeanPostProcessor, create the channels at that point, and then make them unavailable if the host gets pulled from rotation?

    Any thoughts, recommendations, and insight is greatly appreciated.

    (As an aside, I tried to post some mock code from the Router method, inside a designated code block, to give a better example, but the forums kept telling me I was trying to post URLs. I also deselected "Automatically parse links in text," to no avail. It seems like the forums don't like the result of shift-2. Down with bad validation.)

  • #2
    Any subclass of AbstractChannelNameResolvingMessageRouter accepts a 'channelResolver' implementation. By default, it will use the BeanFactoryChannelResolver, and yes we removed the ChannelRegistry since the ApplicationContext acts as the registry for all statically defined channels now. However, providing your own 'channelResolver' to a router is the best way to provide something dynamic there.

    You may also want to look at the MapBasedChannelResolver if all you need to do is store channelNames as keys and have the MessageChannel instances available as values in that map.

    Hope that helps.


    • #3
      I think I'm still being dense about this.

      I get how to implement a channel resolver and a router. The question(s) I have are mostly about how to best apply that to the issue. In this case, my message payload has some information I want to use to inform routing. The problem is that the channels (and constituent adapters) may not yet exist. So what I want to do is:

      1. peek at the payload and come up with a list of potential places to send this message.
      2. if there is no channel for the most suitable destination, create it, an HttpInvokerOutboundGateway, and wire them together (using an adapter of some kind).
      3. add the newly created channel to the list of existing channels.

      I know how to do #1, but I guess I'm just being dense about how best to perform #2 and #3. The reference guide doesn't really describe programatically creating channels, adapters, and endpoints. I know that I need to use ChannelResolvers and a Router, but I'm just not sure how to wire these things together properly.

      Do I actually create the channel (ala new QueueChannel()), the invoker, the adapter (not sure what class this is), and insert them into a Map<String, MessageChannel> that's acting as the backing store for a MapBasedChannelResolver? Am I completely missing something? It feels like (and looks like, from reading through the source for SI) that channel creation and "registration" is slightly more complex than just this. I read through some of the implementation source for things like the outbound-channel-adapter config code, but that just confused me further.

      Sorry for being so dense about this and thanks in advance for your help!