Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2006, Red Hat Middleware LLC, and individual contributors
   * as indicated by the @author tags. 
   * See the copyright.txt in the distribution for a full listing 
   * of individual contributors.
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
   * of the GNU Lesser General Public License, v. 2.1.
  * This program is distributed in the hope that it will be useful, but WITHOUT A
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
  * You should have received a copy of the GNU Lesser General Public License,
  * v.2.1 along with this distribution; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
  * 
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
 package com.arjuna.wst11.messaging.engines;
 
 import  org.jboss.ws.api.addressing.MAP;
 
The participant completion coordinator state engine

Author(s):
kevin
 
 {
    
The coordinator id.
 
     private final String id ;
    
The instance identifier.
 
     private final InstanceIdentifier instanceIdentifier ;
    
The participant endpoint reference.
 
     private final W3CEndpointReference participant ;
    
The associated coordinator
 
     private BAParticipantManager coordinator ;
    
The current state.
 
     private State state ;
    
The failure state which preceded state ended during close/cancel or null if no failure occurred.
 
     private State failureState;
    
The flag indicating that this coordinator has been recovered from the log.
 
     private boolean recovered ;

    
Construct the initial engine for the coordinator.

Parameters:
id The coordinator id.
participant The participant endpoint reference.
 
     public ParticipantCompletionCoordinatorEngine(final String idfinal W3CEndpointReference participant)
     {
         this(idparticipant.false) ;
     }

    
Construct the engine for the coordinator in a specified state and register it.

Parameters:
id The coordinator id.
participant The participant endpoint reference.
state The initial state.
 
     public ParticipantCompletionCoordinatorEngine(final String idfinal W3CEndpointReference participant,
         final State statefinal boolean recovered)
     {
         this. = id ;
         this. = new InstanceIdentifier(id) ;
         this. = participant ;
        this. = state ;
        this. = null;
        this. = recovered;
        // unrecovered participants are always activated
        // we only need to reactivate recovered participants which were successfully COMPLETED or which began
        // CLOSING. any others will only have been saved because of a heuristic outcome. we can safely drop
        // them since we implement presumed abort.
        if (!recovered || state == . || state == .) {
            ParticipantCompletionCoordinatorProcessor.getProcessor().activateCoordinator(thisid) ;
        }
    }

    
Set the coordinator

Parameters:
coordinator
    public void setCoordinator(final BAParticipantManager coordinator)
    {
        this. = coordinator ;
    }

    
Handle the cancelled event.

Parameters:
cancelled The cancelled notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Ended Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended
    public void cancelled(final NotificationType cancelledfinal MAP mapfinal ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
                ended() ;
            }
        }
    }

    
Handle the closed event.

Parameters:
closed The closed notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Ended Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended
    public void closed(final NotificationType closedfinal MAP mapfinal ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
                ended() ;
            }
        }
    }

    
Handle the compensated event.

Parameters:
compensated The compensated notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Ended Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended
    public void compensated(final NotificationType compensatedfinal MAP mapfinal ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
                ended() ;
            }
        }
    }

    
Handle the completed event.

Parameters:
completed The completed notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Completed Canceling -> Completed Completed -> Completed Closing -> Closing (resend Close) Compensating -> (resend Compensate) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended
    public void completed(final NotificationType completedfinal MAP map,
        final ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if (current == . || current == .)
            {
                changeState(.) ;
            }
        }
        if (current == .)
        {
            executeCompleted() ;
        }
        else if (current == .)
        {
            sendClose() ;
        }
        else if ((current == .) || (current == .))
        {
            sendCompensate() ;
        }
    }

    
Handle the exit event.

Parameters:
exit The exit notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Exiting Canceling -> Exiting Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting Ended -> Ended (resend Exited)
    public void exit(final NotificationType exitfinal MAP mapfinal ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if ((current == .) || (current == .))
            {
                changeState(.) ;
            }
        }
        if ((current == .) || (current == .))
        {
            executeExit() ;
        }
        else if (current == .)
        {
            sendExited() ;
        }
    }

    
Handle the fail event.

Parameters:
fail The fail exception.
map The addressing context.
arjunaContext The arjuna context. Active -> Failing-Active Canceling -> Failing-Canceling Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Failing-Compensating Failing-Active -> Failing-Active Failing-Canceling -> Failing-Canceling Failing-Compensating -> Failing-Compensating NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (resend Failed) In fact we only execute the transition to FAILING_ACTIVE and in this case we send a message to the coordinator by calling executeFail. This propagates the failure back thorugh the activityy hierarchy to the relevant participant and also marks the acivity as ABORT_ONLY. In the other failure cases we do not change to a FAILING_XXX state but instead go straight to ENDED and save the failing state in a field failureState. In these cases there will be a coordinator close/cancel/compensate thread waiting on the change to state FAILING_XXX. The change to FAILING_XXX will wake it up and, if the state is still FAILING_XXX, return a fault to the coordinator, However, the failing thread also sends a failed response and then call ended. This means the state might be transitioned to ENDED before the coordinator thread is scheduled. So, we have to avoid this race by going straight to ENDED and saving a failureState which the coordinator thread can check. The failureState also avoids another race condition for these (non-ACTIVE) cases. It means we don't have to send a message to the coordinator to notify the failure. We would need to do this after the state change as we need to exclude threads handling resent messages. However, the waiting coordinator thread is woken by the state change and so it might complete and remove the activity before the message is sent causing a NoSuchActivity exception in this thread. Settign the failureState ensures that the failure is detected cleanly by any waiting coordinator thread. Fortuitously, this also avoids problems during recovery. During recovery we have no link to our coordinator available since there is no activity hierarchy in the current context. So, communicating failures via the failureState is the only way to ensure that the recovreed coordinator sees a failure. There is a further wrinkle here too. If a recovered coordinator times out waiting for a response we need to leave the engine in place when we ditch the recovered coordinator and then reestablish a link to it next time we recreate the coordinator. We cannot afford to miss a failure during this interval but the] engine must transition to ENDED after handling the failure. Saving the failure state ensures that the next time the coordinator calls cancel, compensate or close it receives a fault indicating a failure rather than just detecting that the pariticpant has ended.
    public void fail(final ExceptionType failfinal MAP map,
        final ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
            }
            else if (current == .)
            {
                 = .;
                ended();
            }
            else if (current == .)
            {
                 = .;
                ended();
            }
        }
        if (current == .)
        {
            executeFail(fail.getExceptionIdentifier()) ;
        }
        else if ((current == .) || (current == .) ||
                (current == .))
        {
            sendFailed() ;
        }
    }

    
Handle the cannot complete event.

Parameters:
cannotComplete The cannotComplete exception.
map The addressing context.
arjunaContext The arjuna context. Active -> NotCompleting Canceling -> NotCompleting Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting Exiting -> Exiting (invalid state) Ended -> Ended (resend NotCompleted)
    public void cannotComplete(final NotificationType cannotCompletefinal MAP map,
        final ArjunaContext arjunaContext)
    {
        final State current ;
        synchronized(this)
        {
            current =  ;
            if ((current == .) || ( == .))
            {
                changeState(.) ;
            }
        }
        if ((current == .) || (current == .))
        {
            executeCannotComplete() ;
        }
        else if (current == .)
        {
            sendNotCompleted() ;
        }
    }
    
Handle the getStatus event.

Parameters:
getStatus The getStatus notification.
map The addressing context.
arjunaContext The arjuna context.
    public void getStatus(final NotificationType getStatusfinal MAP mapfinal ArjunaContext arjunaContext)
    {
	final State current ;
	synchronized(this)
	{
	    current =  ;
	}
        sendStatus(current) ;
    }

    
Handle the status event.

Parameters:
status The status.
map The addressing context.
arjunaContext The arjuna context.
    public void status(final StatusType statusfinal MAP mapfinal ArjunaContext arjunaContext)
    {
        // TODO - is this correct?
        final State current ;
	    synchronized(this)
	    {
	        current =  ;
	    }
        sendStatus(current) ;
    }

    
Handle the get status event.

Returns:
The state.
    public synchronized State getStatus()
    {
        return  ;
    }

    
Handle the cancel event.

Returns:
The state. Active -> Canceling Canceling -> Canceling Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
    public State cancel()
    {
        State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
                changeState(.) ;
            }
        }
        if ((current == .) || (current == .))
        {
            sendCancel() ;
            current = waitForState(., TransportTimer.getTransportTimeout()) ;
        }
        // if we reached ended via a failure then make sure we return the failure state so that the coordinator
        // sees the failure
        if (current == . &&  != null) {
            return ;
        }
        
        return current ;
    }

    
Handle the compensate event.

Returns:
The state. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Compensating Closing -> Closing (invalid state) Compensating -> Compensating Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
    public State compensate()
    {
        State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
                changeState(.) ;
            }
        }
        if ((current == .) || (current == .))
        {
            sendCompensate() ;
            waitForState(., TransportTimer.getTransportTimeout()) ;
        }
        synchronized(this) {
            if ( != .) {
                // if this is a recovered participant then ended will not have
                // deactivated the entry so that this (recovery) thread can
                // detect it and update its log entry. so we need to deactivate
                // the entry here.
                if () {
                    ParticipantCompletionCoordinatorProcessor.getProcessor().deactivateCoordinator(this) ;
                }
                if ( == . &&  != null) {
                    return ;
                }
                return ;
            }  else {
                // timeout -- leave participant in place as this TX will get retried later
                return .;
            }
        }
    }

    
Handle the close event.

Returns:
The state. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Closing Closing -> Closing Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
    public State close()
    {
        State current ;
        synchronized(this)
        {
            current =  ;
            if (current == .)
            {
                changeState(.) ;
            }
        }
        if ((current == .) || (current == .))
        {
            sendClose() ;
            waitForState(., TransportTimer.getTransportTimeout()) ;
        }
        synchronized(this) {
            if ( != .) {
                // if this is a recovered participant then ended will not have
                // deactivated the entry so that this (recovery) thread can
                // detect it and update its log entry. so we need to deactivate
                // the entry here.
                if () {
                    ParticipantCompletionCoordinatorProcessor.getProcessor().deactivateCoordinator(this) ;
                }
                if ( == . &&  != null) {
                    return ;
                }
                return ;
            }  else {
                // timeout -- leave participant in place as this TX will get retried later
                return .;
            }
        }
    }

    
Handle the soap fault event.

Parameters:
soapFault The soap fault.
map The addressing context.
arjunaContext The arjuna context.
    public void soapFault(final SoapFault soapFaultfinal MAP mapfinal ArjunaContext arjunaContext)
    {
	ended() ;
	try
	{
	    // TODO - we cannot do this with JaxWS. need to log something
	}
	catch (final Throwable th) {} // ignore
    }

    
Send the close message.
    private void sendClose()
    {
        final MAP map = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendClose(map) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending Close"th) ;
            }
        }
    }

    
Send the compensate message.
    private void sendCompensate()
    {
        final MAP map = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendCompensate(map) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending Compensate"th) ;
            }
        }
    }

    
Send the cancel message.
    private void sendCancel()
    {
        final MAP map = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendCancel(map) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending Cancel"th) ;
            }
        }
    }

    
Send the exited message.
    private void sendExited()
    {
        final MAP map  = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendExited(map) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending Exited"th) ;
            }
        }
    }

    
Send the faulted message.
    private void sendFailed()
    {
        final MAP map = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendFailed(map) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending Faulted"th) ;
            }
        }
    }

    
Send the not completed message.
    private void sendNotCompleted()
    {
        final MAP map = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendNotCompleted(map) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending NotCompleted"th) ;
            }
        }
    }

    
Send the status message.

Parameters:
state The state.
    private void sendStatus(final State state)
    {
        final MAP map = createContext() ;
        try
        {
            ParticipantCompletionParticipantClient.getClient().sendStatus(mapstate.getValue()) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception while sending Status"th) ;
            }
        }
    }

    
Get the coordinator id.

Returns:
The coordinator id.
    public String getId()
    {
        return  ;
    }

    
Get the participant endpoint reference

Returns:
The participant endpoint reference
    {
        return  ;
    }

    
Get the associated coordinator.

Returns:
The associated coordinator.
    {
        return ;
    }

    
check whether this participant's details have been recovered from the log

Returns:
true if the participant is recovered otherwise false
    public boolean isRecovered()
    {
        return ;
    }
    
    
Change the state and notify any listeners.

Parameters:
state The new state.
    private synchronized void changeState(final State state)
    {
        if (this. != state)
        {
            this. = state ;
            notifyAll() ;
        }
    }

    
Wait for the state to change from the specified state.

Parameters:
origState The original state.
delay The maximum time to wait for (in milliseconds).
Returns:
The current state.
    private State waitForState(final State origStatefinal long delay)
    {
        final long end = System.currentTimeMillis() + delay ;
        synchronized(this)
        {
            while( == origState)
            {
                final long remaining = end - System.currentTimeMillis() ;
                if (remaining <= 0)
                {
                    break ;
                }
                try
                {
                    wait(remaining) ;
                }
                catch (final InterruptedException ie) {} // ignore
            }
            return  ;
        }
    }

    
Execute the completed transition.
    private void executeCompleted()
    {
        try
        {
            .completed() ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from coordinator completed"th) ;
            }
        }
    }

    
Execute the exit transition.
    private void executeExit()
    {
        try
        {
            .exit() ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from coordinator exit"th) ;
            }
            return ;
        }
        sendExited() ;
        ended() ;
    }

    
Executing the fail transition.

Throws:
com.arjuna.webservices.SoapFault for SOAP errors.
java.io.IOException for transport errors.
    private void executeFail(QName fail)
    {
        try
        {
            .fail(fail) ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from coordinator fault"th) ;
            }
            return ;
        }
        sendFailed() ;
        ended() ;
    }

    
Executing the cannot complete transition.

Throws:
SoapFault for SOAP errors.
    private void executeCannotComplete()
    {
        try
        {
            .cannotComplete() ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from coordinator error"th) ;
            }
            return ;
        }
        sendNotCompleted() ;
        ended() ;
    }
    
End the current coordinator.
    private void ended()
    {
        changeState(.) ;
        // participants which have not been recovered from the log can be deactivated now.
        // participants which have been recovered are left for the recovery thread to deactivate.
        // this is because the recovery thread may have timed out waiting for a response to
        // a close/cancel message and gone on to complete its scan and suspend. the next scan
        // will detect this activated participant and note that it has completed. if a crash
        // happens in between the recovery thread can safely recreate and reactivate the
        // participant and resend the commit since the commit/committed exchange is idempotent.
        
        if (!) {
            ParticipantCompletionCoordinatorProcessor.getProcessor().deactivateCoordinator(this) ;
        }
    }

    
Create a context for the outgoing message.

Returns:
The addressing context.
    private MAP createContext()
    {
        final String messageId = MessageId.getMessageId() ;
        return AddressingHelper.createNotificationContext(messageId);
    }
New to GrepCode? Check out our FAQ X