Announcement Announcement Module
No announcement yet.
SubscribableChannel test helper? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • SubscribableChannel test helper?

    Does it exist something like muleClient in spring integration?

    I would like to client.getResponse(subscribableChannel, timeout) so I can easily unit test fetching messages from channels.

    At the moment I'm doing this (that is wrong in so many ways and wont probably work in a queued channel at all) :

    expectedChannel.subscribe(new MessageHandler() {
    public void handleMessage(Message<?> message) throws MessagingException {
    assertThat(message, hasPayload(payload));

    inputChannel.send(MessageBuilder.withPayload(paylo ad).build());
    try {
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block

  • #2
    Just use QueueChannel. Than you can executed receive() on it. Is that what you are looking for?


    • #3
      I was looking for something like this (a receive with timeout for SuscribableChannel).

      That should help to have tests without sleeps at the end.


      • #4
        Well you don't need any sleep since QueueChannel.receive() also comes with timeout. For example:
        QueueChannel channel = context.getBean(...);
        Message<?> message = channel.receive(10000); //will wait for message for up to 10 seconds before returning null
        Also, you can look at MessagingTemplate which has a lot of send/receive type methods:

        Also the gateway is yet another approach which allows you completely POJO way of dealing with request/reply message flows:


        • #5
          I'm not keen, at the moment, to change to QueueChannel. I want to test the orchestration itself, not just a service, so the MessagingTemplate sounds like the way to go. Looking at the documentation it looks awesome, except for something that puzzles me out :
          public Message<?> receive(final PollableChannel<?> channel) { ... }

          receive only works with PollableChannel ?


          • #6

            Yes, receive() only works with PollableChannel since by definition only PollableChannel has capabilities to buffer messages while still maintaining the semantics of P2P messaging contract (for each message there can only beone consumer). This means its is holding messages until a consumer asks for it. The flip side of it are the SubscribableChannels which DO NOT buffer messages. The SubscribableChannel work together with MessageDispatcher to dispatch arriving messages according to the message exchange contract represented by a particular SubscribableChannel (P2P or Pub/Sub). The P2P type channel (e.g., DirectChannel, ExecutorChannel etc.) will require that there should be a subscriber consuming messages otherwise you'll see MessagingException telling you that "dispatcher has no subscribers" where with Pub/Sub channels (e.g., PublishSubscribeChannel) each Message wil be dispatch to as many subscribers as present. If 0 the message will be discarded etc.
            So the bottom line is:
            You poll from PollableChannel
            You subscribe from SubscribableChannel

            I understand you come from the Mule background and trying to look at Spring Integration as something similar. Similar we might be but not identical. If you go through the Enterprise Integration Patterns (which we treat as specification for Spring Integration) you may notice how misrepresented some of the EIP concepts are in Mule. That is one of the reason why we have more and more people and organizations migrating from Mule to Spring Integration

            You may also be interested in this case study form a large internet company
            Last edited by oleg.zhurakousky; Dec 21st, 2011, 08:31 AM.


            • #7
              another quick point...

              From a *producer's* perspective, every MessageChannel looks the same (they all have a "send" method), but on the consuming side there are two main EIP components: PollingConsumer and EventDrivenConsumer. Our two categories of channel implementations mirror those (PollableChannel and SubscribableChannel being the two sub-interfaces extending MessageChannel where the former provides receive() and the latter provides subscribe(handler)). Therefore, in a MessagingTemplate, an explicit RECEIVE call means you are effectively playing the role of a PollingConsumer. In the typical Spring Integration application configuration, you would only have things like <router> or <service-activator> connected to *some* <channel>. THEN, the proper consumer type is automatically instantiated based on whether that channel is pollable or subscribable.

              I would like to encourage you to look at the <gateway> which Oleg linked to above. That allows you to work with "just an interface" and the details of the downstream flow (whether sync, async, scatter/gather vs. linear pipeline, etc) are all hidden behind that interface so you can do simple operations that can be request/reply or one-way depending on the method signature.

              Finally, if you really do want to add a PollableChannel (to buffer messages as Oleg mentions and therefore provide the receive() method), you can add a <bridge> from a subscribable channel to a pollable one.

              Hope this helps.


              • #8
                Thanks Oleg!

                I'm pretty aware of the EAI patters, and I do recon the differences of the messaging patterns. Anyway that was a very good explanation, thank you!

                From my point of view, neither MessagingTemplate or the MuleClient implements any kind of pattern, and I just was hoping that there was an equivalent of the client in Spring Integration.

                As MessagingTemplate resides on the spring integration 'core' I do totally understand that you don't want to 'pollute' it with non completely necessary stuff, like this, that will be probably only useful (Although quite a lot) for testing.

                But I do feel that this kind of test tools, even if they don't reside in the core, are quite needed, all unit tests found in the samples repository won't actually test orchestration and if they do, they will just use pollable channels that only cover a minimum fraction of the needs of an integration architect.


                • #9

                  To look at how to test you can look at what we do in our test packages. My be that will give you some ppointers.


                  • #10
                    Gateway sounds to me like a way to test a service itself, not the whole orchestration, am I right?

                    Anyway thanks Mark and Oleg, it's very refreshing to see your quick and good replies.


                    • #11
                      Gateway sounds to me like a way to test a service itself, not the whole orchestration, am I right?

                      Anyway thanks Mark and Oleg, it's very refreshing to see your quick and good replies.


                      • #12
                        Not necessarily. I guess I am missing exactly what you are trying to do, so may be you can explain.

                        You can also go through our extensive library of samples where Gateway is used in many of them. May be that will answer some of your questions.


                        • #13
                          ...But I do feel that this kind of test tools, even if they don't reside in the core, are quite needed,
                          There is an abstract class in spring-integration-test (2.1.RC1) that does (I think) exactly what you want - it abstracts the channel type and you provide a handler, regardless. See

                           * Convenience class for testing Spring Integration request-response message scenarios. Users 
                           * create subclasses to execute on or more {@link RequestResponseScenario} tests. each scenario defines:
                           * <ul>
                           * <li>An inputChannelName</li>
                           * <li>An outputChannelName</li>
                           * <li>A payload or message to send as a request message on the inputChannel</li>
                           * <li>A handler to validate the response received on the outputChannel</li>
                           * </ul>
                           * @author David Turanski
                          public abstract class AbstractRequestResponseScenarioTests {
                          You extend this class - there are some examples of how to use it in src/test/java in that project. See MessageScenariosTests.

                          Last edited by Gary Russell; Dec 21st, 2011, 10:13 AM.


                          • #14
                            Gary thats great!

                            That's exactly what I was looking for, thank you very much to all of you.