Announcement Announcement Module
Collapse
No announcement yet.
Why MessageTransformingHandler requries a reply? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why MessageTransformingHandler requries a reply?

    Code:
    public MessageTransformingHandler(Transformer transformer) {
    	Assert.notNull(transformer, "transformer must not be null");
    	this.transformer = transformer;
    	this.setRequiresReply(true);
    }
    This is constructir of MessageTransformingHandler class. Is there any reason for this.setRequiresReply(true);?

    It looks like a bug, because now I cannot return null. But if you take a look at docs:

    If the return value is null, then no reply Message will be sent (effectively the same behavior as a Message Filter returning false). Otherwise, the return value will be sent as the payload of an outbound reply Message.
    Bug?

  • #2
    Nope, definitely not a bug.

    We had a long discussion prior to 2.0 release and we've decided that there is no reason for transformer to return null. By definition, transformer receives existing Message in order to transform it to another Message and since there is no notion of a null Message, transformer must never return null.

    Having said that i am more curious about your use case. Why do you want to return null?

    Comment


    • #3
      Than the docs are wrong, I am guessing?

      What I am trying to do is simple. Messages are comming from channel A. Some of them I do not care about (yeah, I saw it, fine, do not care, moving on...). Others I want to transform and send to channel B.

      Maybe I am doing something wrong here. Possible. I guess what I need is a combination of Filer + Transformer.

      Comment


      • #4
        Yes, you are trying to apply transformer on the use case that is handled by a different EIP pattern and that is a MessageFilter http://www.eaipatterns.com/Filter.html which is supported by Spring Integration http://static.springsource.org/sprin...single/#filter

        Back to the transformer, where do you believe the documentation is wring or unclear especially about the return value? Coud you include the link?

        Comment


        • #5
          The documentation excerpt he posted above is the one that is wrong. We did address this already for 2.0.2... in fact you did Oleg See here: https://jira.springsource.org/browse/INT-1731

          So, the updated documentation will be available with the next upcoming release.

          Thanks!
          -Mark

          Comment


          • #6
            Originally posted by oleg.zhurakousky View Post
            Yes, you are trying to apply transformer on the use case that is handled by a different EIP pattern and that is a MessageFilter http://www.eaipatterns.com/Filter.html which is supported by Spring Integration http://static.springsource.org/sprin...single/#filter
            I need both, Filter and Tranfromation. Since I cannot return null from transfomation, I have to add filter and another channel.
            Code:
            channel A -> Filter -> Channel B -> Transfomation -> Channel C
            I was trying to combine Filtering and Transformation in one step.

            Originally posted by oleg.zhurakousky View Post
            Back to the transformer, where do you believe the documentation is wring or unclear especially about the return value? Coud you include the link?
            There is a link and the quote in my original post. Link:http://static.springsource.org/sprin...sformer-config

            Quote with some context:
            The method that is used for transformation may expect either the Message type or the payload type of inbound Messages. It may also accept Message header values either individually or as a full map by using the @Header and @Headers parameter annotations respectively. The return value of the method can be any type. If the return value is itself a Message, that will be passed along to the transformer's output channel. If the return type is a Map, and the original Message payload was not a Map, the entries in that Map will be added to the Message headers of the original Message (the keys must be Strings). If the return value is null, then no reply Message will be sent (effectively the same behavior as a Message Filter returning false). Otherwise, the return value will be sent as the payload of an outbound reply Message.
            Bold is mine.

            Comment


            • #7
              Yeah, sorry, as Mark replied before you we had addressed it already for 2.0.2.

              Comment


              • #8
                My problem is described in https://jira.springsource.org/browse/INT-1731.

                I understand the agrument of separate concerns. But I do not see a good reason for hardcoding something in the framework codebase.

                I get it, you want to enforce what you (and many, many other people, including me) consider to be best practices. But in reality in this particular case it means one extra channel and extra component for me.

                What is wrong with default true? Is your opinion on this subject really that strong that you are ready to hardcode the value?
                Last edited by bolyuba; Feb 1st, 2011, 10:46 AM.

                Comment


                • #9
                  To give you a bit of context: The nature of my task is that my filtering logic depends on transformation. In some cases I will not be able to transform, i.e. I have to filter that message out.
                  Last edited by bolyuba; Feb 1st, 2011, 11:02 AM.

                  Comment


                  • #10
                    Well, yes our opinion is strong on this subject. As far as hard coding the value - the base class extends a boolean setting to allow the end user extend from this this class. It also allows us to control the semantics of framework components.
                    So MessageTransformingHandler is one of those specialized framework components that has pre-assembled behavior which is expected by other components. Here is the excerpt from the new documentation:
                    As of Spring Integration 2.0, a Message Transformer's transformation method can no longer return null. Returning null will result in an exception since a Message Transformer should always be expected to transform each source Message into a valid target Message. In other words, a Message Transformer should not be used as a Message Filter since there is a dedicated <filter> option for that.
                    However, if you do need this type of behavior (where a component might return NULL and that should not be considered an error), a service-activator could be used. Its requires-reply value is FALSE by default, but that can be set to TRUE in order to have Exceptions thrown for NULL return values as with the transformer.
                    You don't have to add channel explicitly since every time you define and input-channel that is not explicitly configured one will be created by the framework as a direct channel with that name.

                    You can also use chain to assemble processes as isolated units that themselves have input/output channels
                    Code:
                    <int:chain input-channel="inChannel" output-channel="outChanne">
                         <int:filter . . . />
                         <int:transformer . . . />
                    </int:chain>
                    As you can see from the above you don;t need to define input and/or output channels on the endpoints configured inside the chain.

                    Comment


                    • #11
                      Yeah, I have used the chain. Not that you should care in any way, but I still do not agree with the approach.

                      In you new docs you are suggesting a work around, are you not? I am talking about using service activator. For me service activator has a very distinct endpoint-like nature, while Filter and Transformation have a translator-like nature. The difference is small, but when I need transformation I would naturally try to use translator rather than endpoint.

                      When I see configuration for service activator, I expect it to connect me to some messaging system, I guess. But yeah, maybe it is just me .

                      Comment


                      • #12
                        ... while Filter and Transformation have a translator-like nature...
                        Not at all
                        Please read the definition of Filter - http://www.eaipatterns.com/Filter.html
                        It belongs to a Message Routing category (not the Message Transformation category). Filter is a guard. It has more security-like behavior and should never attempt to modify the message content.

                        Service Activator on the other hand is up to the end user. http://www.eaipatterns.com/MessagingAdapter.html
                        The pattern gives you an ability to provide access to whatever you call a service. It coud be as simple as a one line of java code and it could also be as complex as a Messaging Gateway that invokes another flow configured via Spring Integration. The bottom line it is entirely up to the end user how the service is implemented and how many task it performs (regardless of the separation of concern argument). So its not a workaround, but rather giving you a flexibility point.

                        Message Transformers have a dedicated role and that is to transform the message from one representation to another not to destroy the message.

                        When I see configuration for service activator, I expect it to connect me to some messaging system
                        That is actually a Messaging Gateway's responsibility http://www.eaipatterns.com/MessagingGateway.html
                        "How do you encapsulate access to the messaging system from the rest of the application"

                        Hope that helps

                        Comment


                        • #13
                          One more quick point

                          You can look at service-activator as a components that let's you do whatever it is you want where transformer is a specialized service-activator with predefined behavior.
                          However if you don't like or agree with predefined behavior use service-activator. It is definitely not a workaround.

                          Comment

                          Working...
                          X