13 Replies Latest reply on May 30, 2008 1:05 PM by jeffdelong

    Problems Resuming BA Transaction in SOA-P Business Process

    jeffdelong

      I have taken the NightOut demo to run as an orchestrated business process usingWS BusinessActivity. To do this I:

      1) Modified the BasicClient to call a single Web server call edNightOut, which is deployed on the ESB as a jPDL process NightOutBAProcess, which is deployed as an ESB hosted web service NightOutBAProcessServiceWS.

      2) NightOutBAProcessServiceWS consist of the following actions:
      a) SmooksTransformer action to covert XML data to Java object (Reservation).
      b) WSBATxAction to start a userBusinessActivity and place the txContext in the ESBMessage. WSBATxAction is based on Pavel Kadlec's contribution (discussed in another forum thread).
      c) BpmProcessor action with StartProcessInstanceCommand to start the NightOutBAProcess, and copy context variables including the txContext, as well as business data from the SOAPMessage (number of seats, etc.)
      c) SOAPProcessor action to provide web service interface / WSDL mapping.

      3) jBPM context variables are used to maintain initial business request data in a Reservation object (number of seats to reserve, etc.), status of responses from services (e.g., restaurantStatus, theatreStatus, taxiStatus) and txContext.

      4) RestaurantBA, TheaterBA, and TaxiBA web services are proxied as ESB Services using SOAPClient. OGNL is used by the SOAClient action to map Reservation attributes to the SOAP message parameters.

      5) ESBActionHandler copies the reservation object and txContext onto the ESBMessage and invokes the Restaurant, Theater, and Taxi ESB services.

      6) WSBATXActions are incorporated in the Restaurant, Theatre, and Taxi ESB services to resume the userBusinessActivity (i.e., set it on the current thread). They use the txContext that is on the ESBMessage.

      7) The SOAPClient invokes the appropriate web service.

      8) The xxxStatus context variables are then used to determine the process flow.

      8) UBA complete/cancel/close are also implemented as with the WSBATXAction, where the action invokes the appropriate action on the UserBusinessActivity using the txContext.

      The problem I am having is that when the web services are invoked (e.g., RestaurantBA), I get a null pointer exception:

      19:37:03,826 ERROR [SOAPFaultHelperJAXWS] SOAP request exception
      java.lang.NullPointerException
      at com.jboss.jbosstm.xts.demo.services.theatre.TheatreServiceBA.bookSeats(TheatreServiceBA.java:83)

      Which is

      transactionId = activityManager.currentTransaction().toString();

      The following is from the console immediately before the exception.


      19:37:03,771 INFO [WSBATxAction] Associating WS-Transaction 'BusinessActivityIdentifier: urn:7f000001:da1f:483d910a:12e9a' with current thread
      19:37:03,771 INFO [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
      19:37:03,771 INFO [STDOUT] requestMap is: {bookSeats.how_many=1}
      19:37:03,771 INFO [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
      19:37:03,772 INFO [STDOUT] Message structure:
      19:37:03,772 INFO [STDOUT] [ message: [ JBOSS_XML ]
      header: [ To: JMSEpr [ PortReference < <wsa:Address jms://127.0.0.1:1099/queue/Restaurant/>, <wsa:ReferenceProperties jbossesb:java.naming.factory.initial : org.jnp.interfaces.NamingContextFactory/>, <wsa:ReferenceProperties jbossesb:java.naming.provider.url : localhost/>, <wsa:ReferenceProperties jbossesb:destination-type : queue/>, <wsa:ReferenceProperties jbossesb:specification-version : 1.1/>, <wsa:ReferenceProperties jbossesb:connection-factory : ConnectionFactory/>, <wsa:ReferenceProperties jbossesb:persistent : true/>, <wsa:ReferenceProperties jbossesb:acknowledge-mode : AUTO_ACKNOWLEDGE/>, <wsa:ReferenceProperties jbossesb:transacted : false/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/jms/> > ] ReplyTo: EPR: PortReference < <wsa:Address logical:JBossESB-Internal#JBpmCallbackService/>, <wsa:ReferenceProperties jbossesb:esbToBpmVars : />, <wsa:ReferenceProperties jbossesb:jbpmTokenId : 84/>, <wsa:ReferenceProperties jbossesb:jbpmNodeId : 91/>, <wsa:ReferenceProperties jbossesb:jbpmProcessInstId : 25/>, <wsa:ReferenceProperties jbossesb:jbpmProcessNodeVersionCounter91_84 : 0/>, <wsa:ReferenceProperties jbossesb:type : urn:jboss/esb/epr/type/logical/> > MessageID: ID:JBM-49508 RelatesTo: jms:correlationID#5f38b038-a636-4ca6-aac2-390a42ce6c3e ]
      context: [ ]
      body: [ objects: {org.jboss.soa.esb.message.defaultEntry={bookSeats.how_many=1}, Reservation=org.jboss.nightout.Reservation@10d6f2f, txContext=<?xml version="1.0" encoding="UTF-8"?><wscoor:CoordinationContextType xmlns:wscoor="http://schemas.xmlsoap.org/ws/2004/10/wscoor"><wscoor:Identifier>urn:7f000001:da1f:483d910a:12e9a</wscoor:Identifier><wscoor:CoordinationType>http://schemas.xmlsoap.org/ws/2004/10/wsba/AtomicOutcome</wscoor:CoordinationType><wscoor:RegistrationService><wsa:Address xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://localhost:8080/xts/soap/RegistrationCoordinator</wsa:Address><wsa:ReferenceParameters xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"><wsarj:InstanceIdentifier xmlns:wsarj="http://schemas.arjuna.com/ws/2005/10/wsarj">7f000001:da1f:483d910a:12e9a</wsarj:InstanceIdentifier></wsa:ReferenceParameters></wscoor:RegistrationService></wscoor:CoordinationContextType>} ]
      fault: [ ]
      attachments: [ Named:{}, Unnamed:[] ]
      properties: [ {org.jboss.soa.esb.message.time.dod=Wed May 28 19:37:03 MDT 2008, org.jboss.soa.esb.message.time.dob=Deferred serialized value: fe9806, org.jboss.soa.esb.message.source=Deferred serialized value: aedf8f, org.jboss.soa.esb.message.transport.type=Deferred serialized value: d73f47, javax.jms.message.redelivered=false} ] ]
      19:37:03,826 ERROR [SOAPFaultHelperJAXWS] SOAP request exception
      java.lang.NullPointerException
      at com.jboss.jbosstm.xts.demo.services.theatre.TheatreServiceBA.bookSeats


      Thanks,

      Jeff

        • 1. Re: Problems Resuming BA Transaction in SOA-P Business Proce
          adinn

           


          The problem I am having is that when the web services are invoked (e.g., RestaurantBA), I get a null pointer exception:

          19:37:03,826 ERROR [SOAPFaultHelperJAXWS] SOAP request exception
          java.lang.NullPointerException
          at com.jboss.jbosstm.xts.demo.services.theatre.TheatreServiceBA.bookSeats(TheatreServiceBA.java:83)

          Which is

          transactionId = activityManager.currentTransaction().toString();


          I think you need to fire up a debugger to resolve this. First off, it would be worth checking whether activityManager is null or currentTransaction() returns null. I would guess it is the latter.

          If you look at the implementation you will see that currentTransaction() invokes the context manager to fetch a ThreadLocal value. In the normal demo this ThreadLocal is set by the context manager under a call to resume() invoked from the JaxBaseHeaderContextProcessor.handleInboundMessage(). If you are sure that your handler is being invoked when the SOAP message comes and that it is correctly resuming the business activity then my next guess is that the handler is running in a different thread to the web service call. The debugger is your friend.

          Also, I am interested to know why have you chosen to pass the context in the message body rather than as a header? After all, it is metadata rather than message (i.e. call argument) data. The demo uses a header for the context and, in particular, marks this header with the mustUnderstand attribute. This ensures that body processing will be aborted if the service is not configured to recognise and clear the context header. I notice that you do appear to have a 'context' header but it is empty.


          • 2. Re: Problems Resuming BA Transaction in SOA-P Business Proce
            jeffdelong

            So instead of having the ESB action resume the transaction, I should have the ESB action copy the txContext from the ESB header to the SOAPHeader. Then let the JaxBaseHeaderContextProcessor resume the transaction.

            • 3. Re: Problems Resuming BA Transaction in SOA-P Business Proce
              jeffdelong

              I think I see the issue now. You said

              this ThreadLocal is set by the context manager under a call to resume() invoked from the JaxBaseHeaderContextProcessor.handleInboundMessage(). If you are sure that your handler is being invoked when the SOAP message comes


              My ESB action is not creating a JaxWSHeaderContextProcessor handler like the BasicClient does:

              Handler handler = new JaxWSHeaderContextProcessor();
               List<Handler> handlers = Collections.singletonList(handler);
               bindingProvider.getBinding().setHandlerChain(handlers);
              


              Problem is that the web service invocation is being done in the out-of-the-box ESB SOAPClient action. I am not sure I can make this work without modifying it (or creating my own JAXWS client).

              • 4. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                adinn

                 


                So instead of having the ESB action resume the transaction, I should have the ESB action copy the txContext from the ESB header to the SOAPHeader. Then let the JaxBaseHeaderContextProcessor resume the transaction.


                Well, I am not exactly clear about the details of how you are invoking the web service. You say that the web services are 'proxied' using the SOAPClient. I need to know a bit more about how this 'proxying' works.

                Here is a description of how things work using normal JaxRPC or JaxWS invocations. There are two versions of class JaxBaseHeaderContextProcessor in packages com.arjuna.mw.wst.client and com.arjuna.mw.wst.server. They are both actually abstract classes, each of them being specialised either as JaxWSHeaderContextProcessor or JaxRPCHeaderContextProcessor depending upon which remote invocation protocol you are using. One handler is configured as a handler on the JaxRPC/WS client side, the other on the server side. Between them these two handlers do the work of writing/reading the tx context to/from the SOAP message header and suspending/resuming the associated transaction at the caller/server end.

                Now, if your proxy mechanism actually employs a JaxRPC/JaxWS invocation or can be configured to use handlers as per such an invocation then you can save yoursefl the work of writing/reading the context and managing the transadtion merely by attaching these predefined handlers. If not then what you have aded to replicate this behaviour is probably the way to go.

                One thing to note thought is that the handlers expect to be executed in the same thread as the client method which invokes the remote method and the server thread which executes. They rely upon the context being stashed/found in a ThreadLocal. It sounds like this will also be true of your code because it uses the context manger to save the context from the ESB data and then look it up later when it tries to get the current transaction in the server endpoint implementation. If your proxying mechanism is executing the server code in a different thread to the one where your code is deserialisng the context from the ESB message then this may account for why you are getting the null pointer exception.

                • 5. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                  jeffdelong

                  You said

                  Now, if your proxy mechanism actually employs a JaxRPC/JaxWS invocation or can be configured to use handlers as per such an invocation then you can save yoursefl the work of writing/reading the context and managing the transadtion merely by attaching these predefined handlers. If not then what you have aded to replicate this behaviour is probably the way to go.


                  THE ESB SOAPClient cannot currently be configured to use handlers (well I should confirm this with Tom F), so I will need to add it myself in my action class.

                  • 6. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                    jeffdelong

                    Hum, not so easy to do since SOAPClient creates the SOAP Message.

                    • 7. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                      kconner

                      Andrew, SOAPClient is just a wrapper that supports very basic SOAP calls. It doesn't support handlers so we would have to serialise the coordination context within our codebase, similar to the XTS handlers.

                      We could possibly do this using a smooks transformation of the populated SOAP message.

                      • 8. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                        jeffdelong

                        Kevin,

                        So the serialized txContext is in the ESBMessage (you can see it in the console output in my first post). I grab it when I start the transaction, and add it as a jBPM context variable when the process is started through the ESB BpmProcessor action. Then I have the ESB action handler copy it to the ESB message. It seems like I just need to copy this from the ESB Message to the SOAPMessage. Correct? However I cannot see how to get it into the SOAPMessage header using SOAPClient. I can't see anywhere in the SoapUI classes where there is a SOAPMessage that I can copy it to, even if I were to modify the SoapUI classes.

                        Not sure how I would apply a Smooks transformation either. Thoughts?

                        Jeff

                        • 9. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                          jeffdelong

                          I see where SOAPClient supports a Smooks tranformation. So perhaps I can create a Smooks transformation that takes the


                          <?xml version="1.0" encoding="UTF-8"?><wscoor:CoordinationContextType xmlns:wscoor="http://schemas.xmlsoap.org/ws/2004/10/wscoor"><wscoor:Identifier>urn:7f000001:da1f:483d910a:12e9a</wscoor:Identifier><wscoor:CoordinationType>http://schemas.xmlsoap.org/ws/2004/10/wsba/AtomicOutcome</wscoor:CoordinationType><wscoor:RegistrationService><wsa:Address xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://localhost:8080/xts/soap/RegistrationCoordinator</wsa:Address><wsa:ReferenceParameters xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"><wsarj:InstanceIdentifier xmlns:wsarj="http://schemas.arjuna.com/ws/2005/10/wsarj">7f000001:da1f:483d910a:12e9a</wsarj:InstanceIdentifier></wsa:ReferenceParameters></wscoor:RegistrationService></wscoor:CoordinationContextType>}


                          that is in the message body and moves it to the SOAPHeader?

                          • 10. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                            jeffdelong

                            I wrote custom ESB actions to invoke the individual web services, added the JaxWSHeaderContextProcessor as a handler, and got the demo working as part of a long running jBPM business process. I.e. two of the services are successful, the third is not, so the process calls cancel, and the other services compensate. Very cool.

                            Thanks for all the help.

                            • 11. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                              jeffdelong

                              I am seeing the following with the Taxi service when the process cancels the business activity. This message is repeated over and over.

                              Compensation not supported by ths implementation!
                              id:BusinessActivityIdentifier: urn:7f000001:a42d:48401bb5:36a. Compensate called on participant: class com.jboss.jbosstm.xts.demo.services.taxi.TaxiParticipantBA
                              Compensation not supported by ths implementation!
                              id:BusinessActivityIdentifier: urn:7f000001:a42d:48401bb5:36a. Compensate called on participant: class com.jboss.jbosstm.xts.demo.services.taxi.TaxiParticipantBA
                              Compensation not supported by ths implementation!


                              I tried setting the transactionTimeout to 30 seconds, but it still continues to repeat. Is there any way to avoid this other than to add compensation to the Taxi service?

                              Thanks,

                              Jeff

                              • 12. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                                jhalliday

                                oops, that's my fault. Change the implementation of compensate to

                                public void compensate () throws FaultedException, WrongStateException, SystemException

                                and have it throw FaultedException instead.

                                Basically XTS regards faulted as 'this error is permanent, give up and don't retry', whilst SystemException is regarded as potentially temporal and thus you'll get retry behaviour.

                                • 13. Re: Problems Resuming BA Transaction in SOA-P Business Proce
                                  jeffdelong

                                  Thanks, that change fixed the continual retry.