Announcement Announcement Module
No announcement yet.
Newbie question - remoting multiple methods on single service Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Newbie question - remoting multiple methods on single service

    I'm using spring integration would like to remote multiple methods on a single spring-managed service interface. As far as I can tell, the way to do this is using the service-activator but that only permits a single service method per interface. Is that the only options?

    Secondly, assuming I could expose multiple service methods on an interface, does each one need it's own channel or is there a way to 'share' channels for different method calls on a particular service and maybe differentiate the method call using a message header or something like that.


  • #2
    to share a channel you can use a filter or payloadtyperooter,headerrouter to start

    for gateway service i used shared channels as long as the reply payload matches the invocation

    public interface CriteriaGateway {
    	@Gateway(requestChannel = "criteria-requests",replyChannel="criteria-response")
    	Set<Brand> readBrands(Criteria<? extends Brand> criteria);
    @Gateway(requestChannel = "criteria-requests",replyChannel="criteria-response")
    	List<Tire> findTires(Criteria<Tire> criteria);
    @Gateway(requestChannel = "criteria-requests",replyChannel="criteria-response")
    	List<Rim> findRims(Criteria<Rim> criteria);


    • #3
      Thanks for the response,

      Are you using @Gateway for the service side (inbound) or client (outbound) side. I thought the gateway was only used for outbound invocations?

      Also, how do you then connect this to your messaging mechanism (RMI, JMS etc...).


      • #4
        i read data from another gateway like this :

        	Set<Brand> readBrands(Criteria<? extends Brand> criteria);
        <si:gateway id="criteria-gateway"
        		default-request-channel="criteria-requests" default-reply-channel="criteria-response"
        <si:transformer ref="criteria-transformer" input-channel="criteria-requests" output-channel="http-requests"/>
        <si:transformer input-channel="http-replies" output-channel="criteria-response"/>


        • #5
          I think you're describing the client (outbound) side.

          My issue is on the server (inbound) side, trying to execute multiple methods on a single interface. So far I've been using the service-activator to execute the method, but it only works for a single method. I don't see how I can use the <gateway> on the server side.

          Thinking about it, there's no way for the framework to know how to route the message to the appropriate method unless I provide a custom router which outputs to a unique service-activator (via a unique channel). It would be nice if the decision could be done by the service-activator, like allowing me to plug in a 'method-selector' or something like that.

          Looking at the current implementation of ServiceActivatingHandler, the methodName is passed in as a constructor arg (used to initialize a new instance of MethodInvokingMessageProcessor), so it would be difficult to do this as it is right now.


          • #6
            You can rely on payload-type matching to determine the method to be invoked. Generally we recommend using the "method" attribute on a <service-activator/> element, but you can leave it out. If you do leave it out, then the type of the payload will be matched against the method arguments. Although, seeing your example, it seems like you might need something else?


            • #7
              I should have also mentioned that payload-type matching also works if you do include "method" but have more than one method with the same name.


              • #8
                Does this work with methods with multiple arguments? I guess, more generally, how are multi-arg calls marshalled/unmarshalled into a single message? (In this case I'm using a gateway + rmi-outbound-gateway on the client and rmi-inbound-gateway + service-activator on the server)


                • #9
                  Are you using 1.0 or 2.0 Milestones? I'm asking, because the argument mapping is enhanced in 2.0.


                  • #10
                    I'm using 2.0M2


                    • #11
                      Also, docs say that the service invoked by the service activator must either have a single public method or method must be explicitly identified by the the 'method' attribute


                      • #12
                        Are you referring to JavaDoc or the Reference Manual? We need to update wherever that is mentioned. Here is a fairly detailed description of method mapping behavior in 2.0 M2:


                        • #13
                          I was referring to the Reference Manual at:


                          It says:

                          The configuration above assumes that "exampleHandler" either contains a single method annotated with the @ServiceActivator annotation or that it contains only one public method at all. To delegate to an explicitly defined method of any object, simply add the "method" attribute.
                          Thanks for the doc link.


                          • #14
                            My question regarding multi-arg methods was also referring to the out-bound calls. I'm used to integrating client/services using the RMI proxy for which I can invoke multi-arg methods remotely. I'm just wondering how, if at all, SI would bundle a multi-arg call into a generic message payload and then map to a method call at the server.

                            This doesn't seem like something SI could do, and looking at the mapping rules, it's not a described scenario, so how would I accomplish what I'd normally do with direct RMI, or am I missing something?


                            • #15
                              Well, this is a good question, and it raises an important distinction between Messaging and RPC-style Remoting. Our goal is to focus on a "document-based" Messaging paradigm with a single payload instance. That helps achieve the goal of loose-coupling, whereas RMI and other RPC approaches can lead to tight coupling where the client-side knows too much (method and expected arguments) about the server-side. The rationale is similar to the justification for SOAP messaging to have "standardized" on Document-style instead of RPC. From a design perspective, that might mean that you provide coarse-grained "service" methods in the integration layer, and then from within those invoke more fine-grained "internal" service methods.

                              That said, you *can* provide some fairly fine-grained mappings with Spring Integration 2.0. For example you can use some "Request" object and then access individual properties in the arg-binding expressions, like:
                              public void handleRequest(@Payload("person.lastName") String lastName, @Payload("") String city) {...}
                              I hope that explanation makes sense.