Announcement Announcement Module
Collapse
No announcement yet.
Upgrading M6 to R2 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Thanks! I'm understanding it better now I think (I am slow I know, but my second cup of coffee just kicked in).

    One thing that might make sense is if we add any non-@Header(s)-annotated parameters to an Object array in the case that there is more than one. That way, the gateway method acceptance criteria is more flexible, and if you need to somehow map the Object array to a single Object, it could always be accomplished downstream by a Transformer.

    Does that make sense?

    As far as your 2nd answer, I really do think you would get exactly what you need by using SimpleMessagingGateway there. Then, you can provide your own Messaging Mappers, and you can still pass plain Objects. The Messaging details are handled by SimpleMessagingGateway.

    In fact, if you look into GatewayProxyFactoryBean you will see that all it does is create a Map of SimpleMessagingGateway instances to use.

    Now, I think I can guess the answer to the other question. For those no-arg methods, are you passing an empty Object array?

    Thanks again for all of this feedback!
    -Mark

    Comment


    • #17
      Originally posted by Mark Fisher View Post
      I don't think the analogy of square/rectangle fits this example. Since we're talking about something vs. nothing, I would have expected you to argue that "square" is the same as "no square" with the only difference being that the 2nd one does not exist

      Seriously, on that same note, I really do not understand this assertion:


      From my perspective, Spring Integration is a documented-oriented Messaging framework where a Message cannot be empty. Therefore, if a method is going to generate a Message, it must have parameters. For that reason, if a method has a return value and no parameters, then that is treated as a "receive" call.

      What is the *payload* of the Message you create for the no-arg method invocation?
      Well, I think we are starting to philosophize here, but let me point you that if we have a square whose sides have a length of 0 I still can calculate its area as 0x0.

      Now if Spring Integration is what you say it is, and who better than you to define what it is, it's all very well, but I still point that your definition is just a subset of what a Messaging Infrastructure should be. And to speak in common grounds let me point that your definition is comprises only of the definition of a Document Message, thus missing the definitions of Command Message and Event Message, concepts that you are certainly more familiar than me.

      But as Candid said to the good Doctor Pangloss, "All that is very well, but let us cultivate our garden."

      Comment


      • #18
        But as Candid said to the good Doctor Pangloss, "All that is very well, but let us cultivate our garden."
        Ha!... and what troubles me is that we only have one more day before the 1.0 Final release to make this the best of all possible integration worlds.

        Point taken regarding the Command/Event Message. This is something I've been thinking about... and the GatewayProxyFactoryBean does currently have an excessive Document Message bias.

        I think creating the object array from the parameters does makes sense, and that would only leave the problem of a no-arg method being used for events. I need to think about that one. I guess something along the lines of your @Response annotation would work (or a boolean property within @Gateway). I do think that a no-arg method being used for receive is necessary as well (and is a sensible default).

        Comment


        • #19
          Well, I think I have to give credit to Voltaire for helping me making my point... So here are some more profound, Panglossian thoughts.

          The changes to allow a Object[] instead of a Object as the payload are quite minimal, and does not have any back compatibility issues. And it gives way more freedom and versatility to the implementations. However, caution is needed to maintain the order of the parameters, since in introspection you don't have information about the param names. You have to think carefully about the compatibility between this and the use of @Header in the params.

          The @Response annotation at the method level I think it's a good solution also, because also allows more versatility (you can have the methods you want, with or without params, going directly to the response queues), allowing also the "event message" style of no-arg to be sent as a request. Or actually extending the @Gateway (that I didn't know it existed!) with the boolean flag.

          I even have another suggestion along these lines, that comes from my own requirements but maybe it's useful in other situations. To annotate a method with @Header to include the Method signature as a pre-defined message header, like "internal.header.invokedmethod" (that's what I'm doing on my MessageCreator). Then again the use of @Header in the params can cause confusion here.

          Now this changes probably avoid the necessity of a optional, injectable MessageMapper at Gateway level, like the old "message-creator" attribute, but I still think that will give much more liberty and flexibility to the developers. Power to the people, man...

          Well, once again, thanks for your time. And your patience...

          Comment


          • #20
            Thanks again. This is great feedback. I was also experimenting yesterday with these types of changes. The one problem I was running into is that the "Method" object is passed to the constructor of MethodParameterMessageMapper.

            Interestingly, I was also thinking about some of the things you mentioned above (considering methodName), and then I realized what we really need is a MethodInvocationMessageMapper. The MethodInvocation provides the Method (then of course you can call getName()), and it provides the args[].

            I am hoping to do some refactoring of this for 1.0 if at all possible (today is the last chance). It may not be possible due to time constraints. In any case, I will create a JIRA issue and post the link in this thread.

            The most important thing is to get the functionality right, and so these changes may need to wait until 1.0.1. I will keep you posted.

            Regards,
            Mark

            Comment


            • #21
              Here are some thoughts. Please let me know what you think.

              The @Gateway annotation could have an optional ExchangeType enum (in-only, out-only, in-out), and if not provided it would use the default. The default would be the same as the current fixed logic, i.e.:

              X method1(Y); --> in-out
              void method2(X); --> in-only
              X method3(); --> out-only
              void method(); --> illegal by default

              Then, if you want to provide your own logic - say "methodName" becomes the Message payload for a no-arg (Event Message), then just provide the exchange:

              @Gateway(exchangeType=ExchangeType.IN_OUT)
              X methodName();

              Again, I think this will have to wait for post 1.0 final unfortunately, but if done along these lines it would be backwards compatible.

              Please let me know what you think.

              -Mark

              Comment


              • #22
                Well, first let me remind you that my opinions are somehow biased by my limited experience with SI and my specific use-case and the development I made around it. I look to things through a small window while you have to look at the big picture.

                That being said, if you have to maintain backward compatibility on the "types" of messages, your approach does the job. However, I think it's a overkill, because you're allowing definitions that simply don't make sense and can lead to troubles unless a lot of checking is done. Look at these examples:

                Code:
                @Gateway(exchangeType=ExchangeType.IN_ONLY)
                X methodName(Y);
                you are specifying a contradiction here, what will the framework do, ignore the exchange type or ignore the fact that the method *does* return something?

                Code:
                @Gateway(exchangeType=ExchangeType.OUT_ONLY)
                void methodName(Y);
                another contradiction, more checks to do.


                If you could do a more "generalist" approach, something like "concept over convention over configuration", you will have just

                1) everything is a in-out message
                2) unless it doesn't return nothing, which makes it a in-only
                3) unless otherwise marked as a out-only

                Like this you only have to check the situation 3), which it's easy because it's a consequence of being annotated and can be done in the same place (actually the only check to be made is that the method doesn't return void).

                The downside of this approach is that you loose back-compatibility on

                X method3(); --> out-only -- that should be annotated as out-only
                void method(); --> illegal by default -- that will be treated as a in-only, event-notification message

                Moving on, I think for the sake of "generalism" that every method that is being proxied by the Gateway should have it's name (or even better, it's signature) as a header of the message, and not making a special case of the Event Message by using it as the payload. Actually, my use-case depends on that header, which I'm creating now using my own in-message-mapper.

                But I think it makes sense if I'm proxying a method and wrapping it's parameters on a message, to always know to what method those parameters belong to. And that is clearly meta-data, and thus belongs to the header, not the payload.

                I'm assuming here, of course, that the payload will always be a Object[] with the params of the method, which again to me makes sense because if you introspect the method you'll see that both getParameterTypes() and getGenericParameterTypes() will, as they say in the docs, "Returns an array of length 0 if the underlying method takes no parameters". That way you'll cover the the "0, 1 or more params", and you avoid the use of @Header to classify params wich looks to me just a work-around to avoid the one-and-only-one param style.

                BTW, when I said elsewhere that the no-arg method is just a special case of a with-args method, I was refering precisely to the fact that the introspection always returns a array, even if it's length 0, and not a null.

                Well, these are my thoughts. However, I know for a fact that it is much more easy to spot possible problems in the work of others that doing the work to begin with, so please take my opinions with a "grain of salt".

                And if I can be of any help at any level, please just let me know.

                Comment


                • #23
                  Thanks again for more great feedback. The method signature header is a nice idea.

                  I appreciate the "small window" vs. "big picture" analogy. From my perspective though, the "big picture" really comes together as I see how people are using the framework. Discovering the details of each "small window" view contributes to the big picture. The difficult part is that what may seem like the most intuitive approach to one person (because of how he/she is using or trying to use it) may be opposed to someone else's intuition-driven assumptions. It's definitely helpful when users try to recognize the big picture as well in order to provide useful feedback. So, thanks for that!

                  My first intuition in this particular case was that a no-arg method would most naturally represent an out-only exchange. For full backwards compatibility that may need to stay that way, although in hindsight I do understand your assumptions and also like the consistency of it. I guess all we really need is a way to indicate what type of an exchange the no-arg method is. As you point out, the void returnValue makes it pretty easy to determine the response side. However, I guess it would be possible to have an ignored return value. For example, a boolean return, but you don't want to send a reply Message.

                  Anyways, I will open an issue for this and see what we can do for 1.0.1. I will link back to this thread from JIRA.

                  Thanks again.
                  -Mark

                  Comment


                  • #24
                    Thanks for that. If you need my support on something, being it coding or testing or simply commenting, please just let me know.

                    Cheers.

                    Comment


                    • #25
                      I just upgraded to RELEASE with no problem whatsoever, everything works exactly as with CR2. I just kept the two classes I've changed for my use-case

                      GatewayProxyFactoryBean - to allow "no-arg" in-msgs

                      MethodParameterMessageMapper
                      - to allow a call to a custom InboundMessageMapper
                      - to allow 0..* objects on the payload

                      Great work guys, I can't wait for 1.0.1!!!!!

                      Comment


                      • #26
                        Hello again.

                        Originally posted by Mark Fisher View Post
                        Anyways, I will open an issue for this and see what we can do for 1.0.1. I will link back to this thread from JIRA.
                        I just noticed that 1.0.1 is out and I wonder what's the status of the issues mentioned in this thread. At a first sight, there's no new developments.

                        You mentioned about open a JIRA, did you do it? Do you want me to do it?

                        Well, thanks again for your time and I promise you I won't bother you again with this. Not this year, anyway...

                        Comment

                        Working...
                        X