Announcement Announcement Module
Collapse
No announcement yet.
Override a "default" reply-channel Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Override a "default" reply-channel

    When setting up a reply-producing message handler, I had expected that I could set a reply-channel on the handler itself, which would serve as a "default" reply channel for any message sent to that handler. Then I expected that I could override that "default" by setting the "replyChannel" header on a message. However it turns out that the message header is only checked if the handler has no reply channel. This seems counterintuitive. Is there a reason it's like this? Is there another way to achieve what I'm trying to do? Basically, that's being able to set different reply channels for different messages, but also *not* set a reply channel for some messages and have them go to the "default" channel for the handler (nullChannel, in this case).

  • #2
    As an alternate point of view, since a goal of EIP and SI is decoupling of producers, consumers, and other components, what's the appropriate way to set things up if you have several inbound adapters and several outbound adapters, and some (not all) of the inbound adapters want replies and some (not all) of the outbound adapters can produce replies?

    Comment


    • #3
      Hi!
      This seems counterintuitive
      No, it's OK. If you set an 'outbound-channel' on the endpoint you expect your Message will continue to trevel independently of it's reply channel in the Headers. But when your logic ends and you know by protocol you should return reply you just rely on 'reply channel' header and remove your last 'outbound-channel'.
      You should look at this as encapsulation: imagine your Message was travel before through a lot of systems. Now you are getting it and should make some logic and in the end should return some reply. After some time it have been decided to improve logic of your system. So, it will be enough just to decouple your endpoints via additional 'outbound-channel'. But for calling system you're still a black box.
      Now imagine what will happen if you will reply independently of 'outbound-channel': your reply-message will return just after first endpoint.

      set different reply channels for different messages, but also *not* set a reply channel for some messages
      It's easy:
      HTML Code:
      <channel id="someChannel">
      	<dispatcher load-balancer="none"/>
      </channel>
      
      <bridge input-channel="someChannel"/>
      
      <bridge input-channel="someChannel" output-channel="defaultChannel"/>
      In this case the first <bridge> relies *only* on reply-channel header. If there is no one, AbstractReplyProducingMessageHandler thorws ChannelResolutionException.
      Thanks to UnicastingDispatcher on the 'someChannel' and disabled loadBalancingStrategy failure of first handler (in our case first <bridge>) will dispatch the Message to the second <bridge>.

      Is it what are you looking for?

      Take care,
      Artem
      Last edited by Artem Bilan; Nov 19th, 2012, 02:23 AM.

      Comment


      • #4
        And just to add to what Artem already said;
        In SI we have a notion of "adapters" and "gateways" where 'adapters' are for one-way communication (no reply) and 'gateways' are bi-directional (produce reply)

        Comment


        • #5
          Artem, thanks for another detailed answer. I'm not sure I'm following this one completely. I need to reread it a couple of times. But are you saying that with the following config, if I send one message that has a replyChannel header and one message that doesn't to "someChannel", that this setup will cause the one message to go back to its reply channel and the other to go on to "defaultChannel"? That seems like magic. Where can I find documentation on that?

          Originally posted by Cleric View Post
          HTML Code:
          <channel id="someChannel">
          	<dispatcher load-balancer="none"/>
          </channel>
          
          <bridge input-channel="someChannel"/>
          
          <bridge input-channel="someChannel" output-channel="defaultChannel"/>

          Comment


          • #6
            Originally posted by oleg.zhurakousky View Post
            And just to add to what Artem already said;
            In SI we have a notion of "adapters" and "gateways" where 'adapters' are for one-way communication (no reply) and 'gateways' are bi-directional (produce reply)
            Hi Oleg. I get the general difference between adapters and gateways. What I don't quite get yet is that when you bring a message into the system, it may or may not have a reply channel. And somewhere down the line, it's going to go to either an outbound adapter, which doesn't care about the reply channel, or an outbound gateway, which does. What I want--at least I think I want this--is that when a message with a reply channel goes to an outbound gateway, then the reply should go back to the message's reply channel. But in any other case--no reply channel in the message or going to an outbound adapter--just don't worry about replying. I'm not seeing how to do that yet. It's possible, though, that I'm wrong about what I want, and I'd be happy for someone to point out to me why it would be a bad idea and how to rectify the situation.

            Comment


            • #7
              Where can I find documentation on that?
              http://static.springsource.org/sprin...-directchannel
              However my solution is coming from experience

              Comment


              • #8
                Oh, I see. You're saying that by having multiple subscribers to a channel and disabling load balancing, it will always try each subscriber in order until it finds one that successfully processes the message. Is that right? I don't think that's what I'm looking for. I don't want it sending the messages to multiple places like that. I think maybe you haven't completely understood my question. Let me try to break it down more simply: the core of the problem is that I'm sending messages to an outbound-gateway. Gateways produce replies. Some messages have a reply channel, and some don't. How do I make it work?

                Comment


                • #9
                  One option is to add a <header-enricher> upstream from the gateway that sets "nullChannel" as the replyChannel header if no replyChannel header exists. That will satisfy the gateway since there will always be a channel to send to, but it won't alter the behavior for messages that do have a "real" replyChannel header.

                  We could possibly consider adding a boolean flag for gateways (or any reply-producing handler type) so that they would suppress the Exception in cases where no replyChannel is available. However, IMO the fail-on-no-reply behavior is still the correct default (considering the alternative can lead to unexpectedly lost messages).

                  Comment


                  • #10
                    Originally posted by Mark Fisher View Post
                    One option is to add a <header-enricher> upstream from the gateway that sets "nullChannel" as the replyChannel header if no replyChannel header exists. That will satisfy the gateway since there will always be a channel to send to, but it won't alter the behavior for messages that do have a "real" replyChannel header.
                    I started thinking along these lines a while after reading Artem's replies and the docs he linked. That would appropriately collocate the requirement for a reply channel near the component that requires it. It helped when I realized that header enrichers don't overwrite existing values by default! (Yes, I'm really just learning my way around )

                    Originally posted by Mark Fisher View Post
                    We could possibly consider adding a boolean flag for gateways (or any reply-producing handler type) so that they would suppress the Exception in cases where no replyChannel is available. However, IMO the fail-on-no-reply behavior is still the correct default (considering the alternative can lead to unexpectedly lost messages).
                    I definitely agree that failure should be the default behavior. Further, from my point of view, and admitting my general naivete regarding "how things work" in general with SI, a boolean flag doesn't seem quite consistent. It's very specific, and it would seem odd to find a "don't worry about replies" setting on a reply-producing component. Instead, I think I'd favor a reply-channel-precedence setting with possible settings of "handler" or "message" that would tell the handler where to check first for a reply channel. That's more open-ended, allowing for possible extension in the future by adding new accepted values. It also solves my problem very satisfactorily by letting me set it to "message" to get the "default reply channel" behavior I had initially expected would happen.

                    Comment

                    Working...
                    X