Announcement Announcement Module
No announcement yet.
Calling a service activator after a channel adapter Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Calling a service activator after a channel adapter


    Is there any simpler way to call a service activator after an output channel adapter than the following code?

    (Use of case: Sending a one-way message to JMS queue and then audit that the message has been successfully posted on the queue)

    <publish-subscribe-channel id="channel1" />
    <jms:output-channel-adapter ... input-channel="channel1" order="1" />
    <service-activator ... input-channel="channel1" order="2" />
    This code looks like there is a split of the flow on channel1, which isn't really the case as one is executed after the other, and expected in a specific order.

    Wouldn't it make sense to have such a syntax ?

    <channel id="channelBeforeJms" />
    <channel id="channelAfterJms" />
    <jms:output-channel-adapter ... input-channel="channelBeforeJms" output-channel="channelAfterJms" />
    <service-activator ... input-channel="channelAfterJms" />
    This looks to me a little bit clearer. But I don't know if this makes sense EIP-wise...

    I also thought of using a gateway, but the JMS outbound gateway is expecting a JMS response which is then posted in the reply-channel.
    Why not allow a similar behavior than the file outbound gateway which posts in the reply-channel the input message once the message has been successfully written on the disk?
    So the JMS outbound gateway would post the input message in the reply-channel once the message has been successfully posted on the JMS destination.

    What do you think?
    Any other nice solution?


  • #2
    Nobody got inspired by my question?


    • #3
      I am not sure how you can do this audit "after" putting it on outbound-channel-adapter, but I will put a wiretap on channel1, and do this just before sending it to the destination.


      • #4
        If I audit before sending it, if the send fails, I have audited something wrong.

        In the same direction of your suggestion, a channel interceptor with a postSend implementation would be an option, but I don't intend to do just the audit after the JMS send, the flow keeps going afterwards. And I don't want to do a "trick" or "workaround" for such a simple flow.
        Sending a JMS message to notify an external system should not be imperatively the end of a flow. The flow could continue without expecting any JMS reply.

        Should I open a JIRA to modify the "jms-outbound-gateway" so it can be configured to not expect imperatively a JMS answer, but instead set the output mesasge to be the input message once the JMS has been successfully posted?


        • #5
          Originally posted by plecesne View Post
          Should I open a JIRA to modify the "jms-outbound-gateway" so it can be configured to not expect imperatively a JMS answer, but instead set the output mesasge to be the input message once the JMS has been successfully posted?
          I don't think that is the expected behavior from a gateway.

          Most of the times, you will use jms to send message asynchronously over a queue, and there would be some listener (some external entity) to that queue.
          Now, if you just want to drop the message and not expecting a reply, you can use message-driven-channel-adapter or an outbound-channel-adapter

          If you are expecting a reply, you will like to use an outbound-gateway.

          As for your initial problem of auditing, can you describe the use case a bit more, as in are you expecting a response or not, async / sync, what kinda queue etc?


          • #6
            First of all, thank you for your interest in my problem.

            Here's a more detailed use case of what I would like to do:
            1. Reading a message from a JMS queue (Use of a message-driven-channel-adapter, no problem so far)
            2. Transforming the mesasge into another format (Use of a POJO transformer).
            3. Posting the transformed message on a JMS queue, without expecting any reply (Use of ???????????).
              Note: the message will be read and processed by another system, but no reply is ever expected.
            4. Calling a service to audit in database that the JMS was correctly sent (Use of a POJO service-activator) and the content of the message sent.
              Note: I don't need to ensure that the message was processed by the recipient, just to ensure that the message was successfully posted on the JMS queue.
            5. Calling another service to store the message on the file system (Use of a file channel-adapter)

            The issue remains between 3. and 4. :
            - The gateway expects a JMS reply, which is not what I want (no reply is expected)
            - The channel adapter (be it message-driven or not) has no output-channel to move to step 4 once the send has been done.

            The only workaround I found is the "order" attribute as I presented in the first message of this post (which isn't an elegant solution as I explained up there).

            Is this clearer?



            • #7
              I have almost similar use case in my current application. here is how I will do this (of course there would be better ways! )

              id="jmsIn" connection-factory="connectionFactory" message-converter="pubSubConverter"
              destination-resolver="jmsDestinationResolver" destination="queueDestination"
              channel="pubsubContextActivatorChannel" />
              Using the pubSubConverter I am unmarshalling the response coming from queueDestination.

              2. Since the message is to be audited after putting on the queue, I will put a wiretap around this channel, and there I will send it to queue. Something like:
              <channel id="pubsubContextActivatorChannel">
              			<wire-tap channel="toJMSChannel" />
              3. Then, an activator on toJMSChannel for converting to whatever format, and passing it to exampleChannel:
              <service-activator ref="convertToJMS"
              		method="whatever" input-channel="toJMSChannel"
              		output-channel="exampleChannel" />
              	<jms:outbound-channel-adapter id="jmsOut" destination="outQueue" channel="exampleChannel"/>
              4. Lastly, after this has completed, I will audit:
              <service-activator ref="auditBean"
              		method="writeToDBnFile" input-channel="pubsubContextActivatorChannel"
              		output-channel="finalChannel" />
              If I use direct channels everywhere, this all would happen in the same thread, and the audit / writing to file would happen only after the message been sent to queue. Again, there might be better ways of doing this.


              • #8

                Indeed, the wiretap would definitely work too.

                But this solution has the same drawbacks as mine: it looks to me more like a workaround than a real proper solution : The wiretap is defined in EIP patterns as used for "testing, monitoring or troubleshooting" which is not the case here: the JMS sending is definitely a full and central part of the flow here.

                What I don't understand is why the JMS gateway could not behave like the File gateway. Here is an extract of SI reference manual about the behaviour of the File gateway, which is exactly what I would need for the JMS gateway:

                In cases where you want to continue processing messages based on the written File you can use the outbound-gateway instead. It plays a very similar role as the outbound-channel-adapter. However after writing the File, it will also send it to the reply channel as the payload of a Message.


                • #9

                  I am new to Spring Integration and I have a need to do exactly what plecesne asked in this thread. I understand this thread was created back in 2010 and it is now 2013 and I am wondering whether there is now a de-facto way of continuing a message flow after a JMS outbound-channel-adapter call? or is there an alternative or a work-around still required for this?

                  Thanks in advance.



                  • #10

                    continuing a message flow after a JMS outbound-channel-adapter call?
                    How about to use PublishSubscribeChannel?
                    HTML Code:
                    <publish-subscribe-channel id="someChannel"/>
                    <jms:outbound-channel-adapter channel="someChannel" destination="someDestination" order="1"/>
                    <service-activator input-channel="someChannel" output-channel="someOtherChannel" order="2"
                            ref="someService" method="someMethod"/>
                    In this case you Message will be send to the JMS first and further it will continue travel to the service-activator after successful delivery to the JMS Destination.

                    Of course, there is an another solution: Recipient-List-Router.



                    • #11
                      Hi Cleric,

                      Thanks for your reply. We have configured our message flows to use the publish-subscribe-channel method as suggested which now allows us to continue the message flow after an jms:outbound-channel-adapter call.



                      • #12
                        Can you please advise me the steps involved in setting up the message driven channel adapater to Tibco EMS Topic?