5 Replies Latest reply on Aug 21, 2008 10:29 AM by davinci25

    CXFSE with ServiceMixClient

    davinci25

      Dear Iona,

       

      We are using Fuse Servicemix 3.3.1.4 and are attempting to bridge a SOAP-webservice (originated from the first WSDL example) with a JMS-MQ (IBM-MQwebsphere 7.0).

       

      Our proposed solution is creating the following ESB.

       

      (See attached image Webservice1.jpeg)

       

       

       

      Or in short:

       

      incoming SOAPrequest>CXFBC>CXFSE>EIPCONTENTBASEDROUTING>JMS-MQCONNECTION-->WEBSPHERE.

       

      We create a connection between the CXFSE component and the EIP using the ServiceMixClient API:

       

      ...

       

      Destination destination = client.createDestination("service:esb/router");

       

      InOnly exchange = destination.createInOnlyExchange();

       

      NormalizedMessage message = exchange.getInMessage();

       

      message.setProperty("name", "endpoint");

       

      message.setContent(new DOMSource(doc));

       

      client.send(exchange);...

       

      Where are we going wrong here?

      The following error however occurs in the console window as a SOAPrequest is sent via the wsdl-first client.html.

       

       

      ERROR - CxfSeComponent                 - Error processing exchange InOnly[

      id: ID:210.223.14.4-11fc9c722e0-5:9

      status: Error

      role: consumer

      interface: Instruction

      service: router

      endpoint: endpoint

      operation: SendInstruction

      in: <?xml version="1.0" encoding="UTF-8"?>....etc

       

      ....

       

      java.lang.NullPointerException

      at org.apache.servicemix.cxfse.CxfSeEndpoint.process(CxfSeEndpoint.java:

      230)

      at org.apache.servicemix.common.AsyncBaseLifeCycle.doProcess(AsyncBaseLi

      feCycle.java:540)

      at org.apache.servicemix.common.AsyncBaseLifeCycle.processExchange(Async

      BaseLifeCycle.java:514)

      at org.apache.servicemix.common.BaseLifeCycle.onMessageExchange(BaseLife

      Cycle.java:46)

      at org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBoun

      d(DeliveryChannelImpl.java:610)

      at org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlo

      w.java:172)

      at org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.j

      ava:167)

      at org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.jav

      a:134)

      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec

      utor.java:885)

      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor

      .java:907)

      at java.lang.Thread.run(Thread.java:619)

      ERROR - CxfSeComponent                 - Error setting exchange status to ERROR

      javax.jbi.messaging.MessagingException: illegal call to send / sendSync

      at org.apache.servicemix.jbi.messaging.MessageExchangeImpl.handleSend(Me

      ssageExchangeImpl.java:614)

      at org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.doSend(Delive

      ryChannelImpl.java:385)

      at org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.send(Delivery

      ChannelImpl.java:431)

      at org.apache.servicemix.common.BaseLifeCycle.onMessageExchange(BaseLife

      Cycle.java:58)

      at org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBoun

      d(DeliveryChannelImpl.java:610)

      at org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlo

      w.java:172)

      at org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.j

      ava:167)

      at org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.jav

      a:134)

      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec

      utor.java:885)

      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor

      .java:907)

      at java.lang.Thread.run(Thread.java:619)

       

      Edited by: davinci25 on Aug 19, 2008 8:35 AM

       

      Edited by: davinci25 on Aug 19, 2008 8:41 AM

       

      Edited by: davinci25 on Aug 19, 2008 8:43 AM

        • 1. Re: CXFSE with ServiceMixClient
          davinci25

          We believe we have found the solution to our problem.

           

          It should be an InOnly message from our CXFSE to the EIP content-based-router. Therefor: It is reasonable to assume they should exchange the message synchronically?

           

          changing the code from

           

          client.send(exchange);

           

          TO:

           

          client.sendSync(exchange);

           

           

          Seems to have solved or at least hidden the error from outputting in the console.

          Any thoughts or comments to this are very welcome. Thank you.

          • 2. Re: CXFSE with ServiceMixClient
            gertv

            L.S.,

             

            Technically, there's no real relationship betweens sync/async and the MEP being used; it shouldn't matter if an exchange is being sent synchronously or asynchronously.  However...

             

            You are sending an InOnly exchange, which means that the CXF SE endpoint (as the consumer) is sending the InOnly exchange (status = ACTIVE) and the target component (the EIP component -> CBR) will send back the DONE status.

             

            Now, this is where things go wrong.  If you send this MessageExchange asynchronously, the InOnly DONE status will be received by the CxfSeEndpoint's process() method.  However, this method is not capable of handling this type of Exchange -- it's built to handle Provider exchanges, not Consumer exchanges.

             

            If you send the same MessageExchange synchronously, the ServiceMixClient will wait for the DONE status message to return before continuing.  This also means that the CxfSeEndpoint doesn't have to handle the DONE status message, the ServiceMixClient does that for you.

             

            I would suggest you raise JIRA issue for this so we can investigate if/how we can solve this, but I'm not sure we will be able to cover this use case elegantly without breaking anything else.

             

            Just a side question: does your CXF SE endpoint contain any kind of additional logic?  If it only sends the MessageExchange along to the EIP CBR, you might as well leave it out of the picture and connect the CXF BC to the EIP CBR directly.  If you need some intermediary Java code in between, you obviously need to keep in there.

             

            Regards,

             

            Gert

            • 3. Re: CXFSE with ServiceMixClient
              davinci25

              1. With the example first-wsdl-client (shipped with fuse servicemix) we aim to use a web browser to send SOAP-requests. After some configuration the client.html is able to put an In-Only string (our message) on to the ESB (See attached figure).

               

              2. From the CXF-BC the received SOAP-request is put on the ESB toward our service CXF-SE for further processing. (Remember that we have a specified method inside our wsdl-file which is exposing our service to the outside world.)

              This method is resided inside the CXF-SE component which will do the actual job and is triggered by the CXF-BC.

               

              3. The incoming message (from an ESB perspective) is in an xml format encased with various xml and soap tags. This however is not a familiar format from which our destination will be able to interoperate the message.

              To solve this we process it in a special transformation (a java class we have written) translating the message which our destination will understand. After the transformation the message is ready to be sent and our router is injected from the CXF-SE and here lies our problem. Is this approach something to strive for? What other options do we have available to solve our problem?

               

              Gert saw the problem clearly and answered it in a way which made it possible for us to grasp a fundamental aspect of servicemix.

               

               

               

              What we did not realize was the fact a CXF-SE component does not handle exchange responses in the way we thought. It all boils down to understanding the exchange process in Servicemix which we did not. Hopefully now with your help we have gained some insight and knowledge to this and have gained a better understand for how it is intended to works and what is happening behind the scenes.

              With luck others may read this and avoid our mistakes.

               

              Many thanks for your assistance and response in this matter Gert!

               

              Please do comment on our post and add thoughts and answers to our related questions above if you have the time.

              • 4. Re: CXFSE with ServiceMixClient
                gertv

                L.S.,

                 

                 

                Well, if we take a look at the enterprise integration patters, we could use a pipeline here.

                 

                If you slightly rework your CXF-SE SU (or use a Bean SU instead), you can use your Java transformator class to answer in InOut exchange: the 'in' message contains the original format, the 'out' message will contain the converted message.  This will give a nice, little transformation service on the ESB.

                 

                You can then tie everything together with a Camel pipeline: receive the InOnly request from the CXF-BC, send this as InOut to the transformation service and forward the transformation service's response to the JMS queue.

                 

                 

                Regards,

                 

                Gert

                • 5. Re: CXFSE with ServiceMixClient
                  davinci25

                  Yes, a Camel pipeline is certainly a neat solution solving the exchange related issues here. We should look into implementing this in our ESB.

                  Thank you for your quick response.