6 Replies Latest reply on Nov 9, 2013 11:45 AM by kconner

    Unresponsive EPR when using ServiceInvoker from Action class

    khuevu

      Hi all,

      I am doing a POC on invoking multiple services and aggregate the result and return synchronously.

      I have the following esb, in which, two services "google", "bing" are declared, which have inVM listeners. They just return the simple text "GOOGLE SEARCH" and "BING SEARCH" respectively. The aggregator service invokes the 2 services using the custom action class.

       

       

       <services>
      
       <service category="extra" description="Blah blah" invmScope="GLOBAL" name="google">
         <actions mep="RequestResponse">
          <action class="org.jboss.soa.esb.actions.routing.http.HttpRouter" name="routeToBackendService1">
           <property name="method" value="GET"/>
           <property name="endpointUrl" value="http://localhost:8000/google.html"/>
          </action>
      
           <action class="org.jboss.soa.esb.actions.SystemPrintln" name="printGoogle">
           <property name="message" value="Google Response"/>
          </action>
      
         </actions>
        </service>
      
        <service category="extra" description="Blah blah" invmScope="GLOBAL" name="bing">
         <actions mep="RequestResponse">
          <action class="org.jboss.soa.esb.actions.routing.http.HttpRouter" name="routeToBackendService2">
           <property name="method" value="GET"/>
           <property name="endpointUrl" value="http://localhost:8000/bing.html"/>
          </action>
      
           <action class="org.jboss.soa.esb.actions.SystemPrintln" name="printBing">
           <property name="message" value="BIng Response"/>
          </action>
         </actions>
        </service>
      
        <service category="Aggregation"
         description="This service to handle portingService requests"
         invmScope="GLOBAL" name="aggregation">
         <listeners>
          <http-gateway name="HTTP" urlPattern="aggregate/*">
           <property name="synchronousTimeout" value="60000"/>
          </http-gateway>
         </listeners>
         <actions mep="RequestResponse">
          <action class="org.jboss.soa.esb.actions.SystemPrintln" name="printRequest">
           <property name="message" value="ORIGINAL Request"/>
          </action>
      
          <action class="org.test.esb.AggregateServiceInvoker" name="aggregateTest">
           <property name="destinations">
            <route-to service-category="extra" service-name="google"/>
            <route-to service-category="extra" service-name="bing"/>
           </property>
          </action>
      
         </actions>
        </service>
      
       </services>
      

       

       

       

      My AggregateServiceInvoker class:

       

       

      public class AggregateServiceInvoker extends AbstractActionPipelineProcessor {
      
          private ConfigTree configTree;
          private List<ServiceInvoker> invokers; 
      
          private long timeout;
      
          public AggregateServiceInvoker(ConfigTree configTree) {
              this.configTree = configTree;
          }
      
          @Override
          public void initialise() throws ActionLifecycleException {
              //recipient list
              timeout = configTree.getLongAttribute("time-out", 30000L);
              ConfigTree[] destList = configTree.getChildren("route-to");
              invokers = new ArrayList<ServiceInvoker>();
      
              for (ConfigTree conf : destList) {
                  String category = conf.getAttribute("service-category");
                  String name = conf.getAttribute("service-name");
                  System.out.println("Category: " + category + " name: " + name);
                  //Service service = new Service(category, name);
      
                  ServiceInvoker invoker;
                  try {
                      invoker = new ServiceInvoker(category, name);
                      invokers.add(invoker);
                  } catch (MessageDeliverException e) {
                      throw new ActionLifecycleException(e);
                  }
      
              }
          }
      
          @Override
          public Message process(Message message) throws ActionProcessingException {
      
              System.out.println(configTree.toXml());
      
              System.out.println(message.getBody());
              for (ServiceInvoker invoker : invokers) {
                  try {
                      System.out.println("Invoking service: " + invoker.getServiceName());
                      Message m1 = invoker.deliverSync(message, timeout);
                      System.out.println("COMPLETED");
      
                  } catch (FaultMessageException | MessageDeliverException
                          | RegistryException e) {
      
                      e.printStackTrace();
                  }
              }
      
              System.out.println("AFTER : " + message.getBody());
              return message;
          }
      
      }
      

       

      When I test by sending request to: http://localhost:8080/test-aggregation/http/aggregate/ahh

      It always fails to return the first service. With a Unresponsive EPR: InVMEpr:

       

       

       

      10:13:25,770 INFO  [STDOUT] body: [ objects: {org.jboss.soa.esb.message.defaultEntry=[B@18590ff4} ]
      10:13:25,770 INFO  [STDOUT] Invoking service: google
      10:13:25,779 INFO  [STDOUT] Google Response: 
      10:13:25,780 INFO  [STDOUT] [GOOGLE SEARCH].
      
      
      
      
      10:13:55,777 INFO  [ServiceInvoker] Unresponsive EPR: InVMEpr [ PortReference < <wsa:Address invm://6578747261242424242424242424242424676f6f676c65/false?false#10000/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/invm/>, <wsa:ReferenceProperties jbossesb:passByValue : false/> > ] for message: header: [ To: InVMEpr [ PortReference < <wsa:Address invm://4167677265676174696f6e2424242424242424242424246167677265676174696f6e/false?false#10000/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/invm/>, <wsa:ReferenceProperties jbossesb:passByValue : false/> > ] ReplyTo: InVMEpr [ PortReference < <wsa:Address invm://thread-186-4/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/invm/>, <wsa:ReferenceProperties jbossesb:passByValue : false/>, <wsa:ReferenceProperties jbossesb:temporaryEPR : true/> > ] MessageID: 16e3db91-f1e6-4a21-8cb6-82d306a1ad1f ]
      10:13:55,778 INFO  [ServiceInvoker] Delivering message [header: [ To: InVMEpr [ PortReference < <wsa:Address invm://4167677265676174696f6e2424242424242424242424246167677265676174696f6e/false?false#10000/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/invm/>, <wsa:ReferenceProperties jbossesb:passByValue : false/> > ] ReplyTo: InVMEpr [ PortReference < <wsa:Address invm://thread-186-4/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/invm/>, <wsa:ReferenceProperties jbossesb:passByValue : false/>, <wsa:ReferenceProperties jbossesb:temporaryEPR : true/> > ] MessageID: 16e3db91-f1e6-4a21-8cb6-82d306a1ad1f ]] to DLQ.
      10:13:55,794 INFO  [InquiryHelper] uddi:juddi.apache.org:eb6eb036-98f5-4fa1-8fd5-ce4fa853faba is modified Mon May 20 09:30:51 SGT 2013 1369013451516
      10:13:55,933 ERROR [STDERR] org.jboss.soa.esb.listeners.message.ResponseTimeoutException: No response received for service [extra:google].
      10:13:55,935 ERROR [STDERR]     at org.jboss.soa.esb.client.ServiceInvoker.post(ServiceInvoker.java:462)
      10:13:55,935 ERROR [STDERR]     at org.jboss.soa.esb.client.ServiceInvoker.deliverSync(ServiceInvoker.java:221)
      10:13:55,935 ERROR [STDERR]     at org.khuevu.test.esb.AggregateServiceInvoker.process(Unknown Source)
      10:13:55,936 ERROR [STDERR]     at org.jboss.soa.esb.listeners.message.ActionProcessingPipeline.processPipeline(ActionProcessingPipeline.java:667)
      10:13:55,936 ERROR [STDERR]     at org.jboss.soa.esb.listeners.message.ActionProcessingPipeline.processPipeline(ActionProcessingPipeline.java:614)
      10:13:55,936 ERROR [STDERR]     at org.jboss.soa.esb.listeners.message.ActionProcessingPipeline.process(ActionProcessingPipeline.java:442)
      10:13:55,936 ERROR [STDERR]     at org.jboss.soa.esb.listeners.message.MessageAwareListener$TransactionalRunner.run(MessageAwareListener.java:587)
      10:13:55,937 ERROR [STDERR]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      10:13:55,938 ERROR [STDERR]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      10:13:55,938 ERROR [STDERR]     at java.lang.Thread.run(Thread.java:722)
      10:13:55,938 INFO  [STDOUT] Invoking service: bing
      10:13:55,957 INFO  [STDOUT] BIng Response: 
      10:13:55,957 INFO  [STDOUT] [BING SEARCH ].
      10:13:55,958 INFO  [STDOUT] COMPLETED:     with message length: 
      10:13:55,958 INFO  [STDOUT] AFTER : body: [ objects: {org.jboss.soa.esb.http.HttpResponse#response=org.jboss.soa.esb.http.HttpResponse@5bdd48cf, org.jboss.soa.esb.message.defaultEntry=BING SEARCH } ]
      

       

      The second service is invoked without any problem.

      The first service is invoked and completed but fail to return to the current context.

      Strang things are:

      - Response from Google Service is already returned to client (displayed in the browser) before the ERROR occurs.

      - In the action class code, I didn't append any of the response message to the return message, but response from BIng Service is automatically appended ? (AFTER: body...)

       

      Any suggestion would be greatly appreciated.

       

      Thank you,

       

      Khue.

        • 1. Re: Unresponsive EPR when using ServiceInvoker from Action class
          khuevu

          Hi,

          I have figured out the problem.

          I need to clone the message before deliver to the ServiceInvoker.

          • 2. Re: Unresponsive EPR when using ServiceInvoker from Action class
            nishbmishra

            Hi Khuevu,

             

            I am seeing something Similar, Can you tell me what exactly did you do?

            What do you mean by Clone the message. I am new To JBoss ESB and I am using Version 4.10

            • 3. Re: Unresponsive EPR when using ServiceInvoker from Action class
              khuevu

              Hi Nish,

               

              By cloning the message I mean making a copy of the original message, send this message via ServiceInvoker instead of the original message.

              For some reason (not documented) a jboss esb message can only be used for one request response cycle, you can't reuse it to invoke another service.

               

              Hope it help,

              Khue

              • 4. Re: Unresponsive EPR when using ServiceInvoker from Action class
                kconner

                By cloning the message I mean making a copy of the original message, send this message via ServiceInvoker instead of the original message.

                Cloning should not be necessary in order to reuse the message however you do need to understand the behaviour of invm invocations.  By default the invm courier uses pass-by-reference meaning that a shallow copy of the message is passed to the receiving service (only the Call is cloned) and it is possible for the service to modify the body/properties etc of the original message before returning, thereby affecting the second invocation.  Looking at your code pass-by-reference may not be what you want as you are modifying the contents of the message in each service.  Enabling pass-by-value in your service definitions, which you should really do as you are modifying the message contents, will cause the invm transport to send a deep copy of the message however this still does not explain why your first service invocation fails.

                For some reason (not documented) a jboss esb message can only be used for one request response cycle, you can't reuse it to invoke another service.

                It looks like there is something else going on here as that statement is generally not true, you can reuse the message safely providing that you understand the invm semantics.  You should be able find out more information by enabling DEBUG logging.

                • 5. Re: Unresponsive EPR when using ServiceInvoker from Action class
                  joe_boy12

                  I have seen this too - if you use original message in deliverSynch - the response is always sent to reployToEPR and never returns to M1 and later trhrows (after 30 sec I guess) as UnReponsiveEPR error.

                  • 6. Re: Unresponsive EPR when using ServiceInvoker from Action class
                    kconner

                    If you choose to reuse the original message then you must clear the ReplyTo Epr if you are going to make a call to deliverSynch, otherwise you will two callers trying to receive the same response.  This is a race condition and only one (randomly) will receive the response.

                     

                    Clearing the ReplyTo EPR (possibly also FaultTo EPR depending on your application) will allow the ServiceInvoker to create its own EPR.