6 Replies Latest reply on Oct 1, 2008 4:17 AM by adinn

    Compensate and Cancel

    gllambi

      Hi, I'm a bit new with WS-BA, so sorry if this is a very easy question to answer.

      I've got two services A and B and want to reach this scenario:
      * A is in active state
      * B has completed and is waiting for the coordinator message (close or compensate)

      Then I want is to cancel an activity and compensate the other one. The problem is that I can't have different services in different states because both of them belong to the same BATransaction and when I do BAManager.completed() both leave the active State. Is there a way to complete only one activity?

      This is a pseudocode of what I've got:

      UserBusinessActivity uba = UserBusinessActivityFactory.userBusinessActivity();
      uba.begin();
      
      callServiceA(); //Internally enlist participantA
      
      callServiceB(); //Internally enlist participantB
      


      public void callServiceA(){
      
      BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();
      ParticipantA participantA = new ParticipantA();
      
      // enlist the Participant for this service
      BAParticipantManager participantManagerA = null;
      
      participantManagerA = activityManager.enlistForBusinessAgreementWithParticipantCompletion(participantA, new Uid().toString());
      }
      
      public void callBackServiceA(){
      
      participantManagerA.completed();
      
      }
      

      public void callServiceB(){
      
      BusinessActivityManager activityManager = BusinessActivityManagerFactory.businessActivityManager();
      ParticipantB participantB = new ParticipantB();
      
      // enlist the Participant for this service
      BAParticipantManager participantManagerB = null;
      
      participantManagerB = activityManager.enlistForBusinessAgreementWithParticipantCompletion(participantB, new Uid().toString());
      }
      
      public void callBackServiceB(){
      
      participantManagerB.completed();
      
      }
      
      


      Thank you very much!
      Guzman

        • 1. Re: Compensate and Cancel
          adinn

           


          * A is in active state
          * B has completed and is waiting for the coordinator message (close or compensate)
          . . .
          Then I want is to cancel an activity and compensate the other one.


          Hmm, you seem a bit confused about what happens where. The client cannot cancel or close an activity when a participant is active. This can only be done when all participants are in state completed. If the client tries to close the activity in this situation it will get an error.

          Also, when the client cancels a completed activity the coordinator is required to send a compensate message to each participant. That's what a cancel operation means. It is a request to the coordinator to tell each participant to compensate the changes it made when the activity was completed. It is up to each participant to decide what it does when it is told to compensate but the coordinator cannot send different messages to each participant.

          Here is a summary of how things can progress.

          When the client completes the activity the coordinator tells each participant registered for coordinator completion to complete.

          When the client closes the activity the coordinator tells each completed participant to close.

          When the client cancels the activity the coordinator tells each completed participant to compensate.

          If a participant uses participant completion then it must call the participant manager complete method before the client calls close or compensate. The close or cancel call will fail if this has not already happened.

          So, if a participant uses participant completion then it must know when to call complete. How this is decided depends upon the web service protocol. For example, the participant may complete when a 'confirm' request is sent.


          • 2. Re: Compensate and Cancel
            gllambi

            First of all, thank you very much for your explanation.

            "adinn" wrote:

            Hmm, you seem a bit confused about what happens where. The client cannot cancel or close an activity when a participant is active. This can only be done when all participants are in state completed. If the client tries to close the activity in this situation it will get an error.


            You are right, I've got a bit confused, mainly because I started reading the WS-BA spec and then started using XTS. In the spec they use compensate for what XTS uses cancel. Maybe if the method is renamed to compensate the mapping between the spec and XTS would be easier. Just an opinion, don't get it wrong :)


            The client cannot cancel or close an activity when a participant is active


            If I didn't understand well, the spec allows a participant to cancel the activity. This event can only occur when the activity is active. The next state after this event is cancelling and then ended. This is the behavior I wanted to do with XTS. Is this possible?

            Thank you
            Guzman

            • 3. Re: Compensate and Cancel
              adinn

               


              You are right, I've got a bit confused, mainly because I started reading the WS-BA spec and then started using XTS. In the spec they use compensate for what XTS uses cancel. Maybe if the method is renamed to compensate the mapping between the spec and XTS would be easier. Just an opinion, don't get it wrong :)


              Err, apologies, it is not just you who is getting confused -- I have been looking at the WS-AT code for too long and managed to mess up part of my explanation. It is mostly correct. The bit I got wrong concerns what happens when the client cancels an activity while participants have not completed.

              A client can cancel a business activity while some or all participants are active i.e. before they have completed. If any of the participants has not completed then the coordinator tells them to cancel the activity. If the participants have completed then the coordinator tells them to compensate the activity.

              Note that if the client tries to close an activity while some of the participants are active the close will fail.


              If I didn't understand well, the spec allows a participant to cancel the activity. This event can only occur when the activity is active.


              Afraid not. You need to be careful how you read the event diagrams. The participant does not initiate the cancel event. The lines from state Active and Completing to state canceling are labelled as 'Coordinator Initiated'. In other words the coordinator tells the participant to cancel. The coordinator only does this when the client asks it to. So, the cancel method on UserBusinessActivity is what drives this state change. You will notice thatt there is no method on BAParticipantManager called cancel. Thsi is because the participant is not allowed to cause this transition.


              In the spec they use compensate for what XTS uses cancel


              No, they don't. They use Cancel to refer to a message which goes from coordinator to participant. They also use Compensate to refer to a message from coordinator to participant. Both of these messages are driven by a cancel being sent from the client to the coordinator. The coordinator send Cancel to a participant which has not yet completed (i.e. one which is either in state Active or Completing) It sends Compensate to a participant which has completed (i.e. is in state Completing).

              The spec does not actually describe the communications which occur between client and coordinator but they are critical to understanding the whole of BA. The client can send complete, close and cancel to the coordinator. The coordinator replies to the client with closed, completed or cancelled, depending upon what how the participants respond.

              When it is processing a message from the client the coordinator may send complete, close, cancel or compensate messages to the participants. Which message it sends depends upon the state of the participant and the outcome of messages to other participants. The response to these messages is sent back automatically by the BA implementation. It calls the complete, cancel, close or compensate methods of the BAWithXXXCompletionParticipant object you supplied in the enlist call. Depending upon what your code returns it will send the appropriate responses. The registerd participant is passive i.e. it gets called by the BA implementation when necessary.

              Your web service can only initiate a few of the state changes in the BA state diagrams. These are the ones for which methods exist on class BAParticipantManager -- the tyep of the object returned by the enlist callHere are the choices available to you:

              If you want to exit a business activity then you can call the BAParticipantManager method exit(). After this call the participant will not be told to close or compensate or cancel.

              If your participant has registered for the ParticipantCompletion protocol the you can call the BAParticipantManager method completed() to transition from active to completed. You can only do this when the participant is active and have to do this in order for the close operation to work.

              If the participant wants to indicate that it cannot perform its part in the business activity it can call the BAParticipantManager method cannotComplete(). It can only do this while it is active and must roll back any changes it has provisionally made and refuse to perform any further web service requests in the business activity.

              If the participant wants to indicate an error has occurred in its part of the business activity it can call the BAParticipantManager method fail(). It can do this when it is active, cancelling or compensating i.e. before completing or during processing of a cancel or a compensate call. The state of the participant is left undetermined after this call. It is provided to allow the participant to notify the coordinator that something has gone wrong.


              • 4. Re: Compensate and Cancel
                gllambi

                 

                "adinn" wrote:

                No, they don't. They use Cancel to refer to a message which goes from coordinator to participant. They also use Compensate to refer to a message from coordinator to participant. Both of these messages are driven by a cancel being sent from the client to the coordinator. The coordinator send Cancel to a participant which has not yet completed (i.e. one which is either in state Active or Completing) It sends Compensate to a participant which has completed (i.e. is in state Completing).


                So, when the client calls the cancel method the coordinator decides which message is sent to the participant. Ok!


                If you want to exit a business activity then you can call the BAParticipantManager method exit(). After this call the participant will not be told to close or compensate or cancel.


                Maybe I should open a new thread with this question. How can a single participant exit from the BATransaction? If I use BAParticipantManager method exit() it exits all the participants from the transaction, isn't it?

                Thanks
                Guzman


                • 5. Re: Compensate and Cancel
                  gllambi

                   


                  I've got two services A and B and want to reach this scenario:
                  * A is in active state
                  * B has completed and is waiting for the coordinator message (close or compensate)


                  With all the chat I forgot the main thread purpose :) ... How can I reach this scenario? I can't figure out how to tell the coordinator that only one participant has completed (Message completed from active state) as both belong to the same BATransaction (same BATransactionID). Is there a way to identify the BAParticipantManager?

                  Thanks again!

                  • 6. Re: Compensate and Cancel
                    adinn

                     


                    Maybe I should open a new thread with this question. How can a single participant exit from the BATransaction? If I use BAParticipantManager method exit() it exits all the participants from the transaction, isn't it?


                    No, let's stick to this thread. The BAParticipantManager does what it says -- it manages a single participant.. So, if your web service calls exit() then that participant is no longer involved in the business activity and the coordinator will not tell it to complete, close or cancel. Any other participants will remain in the activity.


                    With all the chat I forgot the main thread purpose :) ... How can I reach this scenario? I can't figure out how to tell the coordinator that only one participant has completed (Message completed from active state) as both belong to the same BATransaction (same BATransactionID). Is there a way to identify the BAParticipantManager?


                    Your web service is handed back a BAParticipantManager when you enlist it as a participant. If you do not want service A to complete when the client completes the activity then the web service needs to call BAParticipantManager method exit() before the client calls complete or close. But the web service needs to cooperate with the client to do this.

                    For example, service A could enlist itself when it is sent an order() request. Assuming that it is enlisted for BAWithParticipantCompletion it could call completed (the BAParticipantManager method) when the client sends it a confirmOrder request. It could call exit when the client sends it a cancelOrder request. Once the client has sent either confirmOrder or cancelOrder it can safely call close because service A will either be in state completed or will have exited.

                    For this to be transactional you would have to make sure that the client does not make any persistent changes when order() is called. This allows it to call exit without modifying any persistent state if it is sent a cancelOrder() request. If it is sent confirmOrder() then it has to make its changes persistent before calling completed. It also has to write undo information in case it gets told to compensate later on. When a close call is posted the close method of the registered participant can delete the undo information. When a compensate call is posted the participant compensate method can undo the original changes and delete the undo information.