Package com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna

Source Code of com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.ServerTopLevelAction

/*
* 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.
*/
/*
* Copyright (C) 1998, 1999, 2000, 2001,
*
* Hewlett Packard Arjuna Labs,
* Newcastle upon Tyne,
* Tyne and Wear,
* UK.
*
* $Id: ServerTopLevelAction.java 2342 2006-03-30 13:06:17Z  $
*/

package com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna;

import com.arjuna.orbportability.*;

import com.arjuna.ats.internal.arjuna.thread.ThreadActionData;

import com.arjuna.ats.arjuna.common.*;
import com.arjuna.ats.arjuna.coordinator.*;

import com.arjuna.ats.jts.*;
import com.arjuna.ats.jts.exceptions.ExceptionCodes;
import com.arjuna.ats.jts.logging.*;

import com.arjuna.ats.internal.jts.ORBManager;
import com.arjuna.ats.internal.jts.OTSImpleManager;
import com.arjuna.ats.internal.jts.orbspecific.interposition.ServerControl;
import com.arjuna.ats.internal.jts.orbspecific.interposition.coordinator.ServerTransaction;
import com.arjuna.ats.internal.jts.interposition.resources.arjuna.*;

import com.arjuna.common.util.logging.*;

import org.omg.CosTransactions.*;
import org.omg.CORBA.CompletionStatus;

import org.omg.CosTransactions.HeuristicHazard;
import org.omg.CosTransactions.HeuristicMixed;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.UNKNOWN;
import org.omg.CORBA.INVALID_TRANSACTION;
import org.omg.CORBA.TRANSACTION_ROLLEDBACK;

/**
* This looks like an atomic action, but is not actually derived from
* BasicAction or Transaction. This is because of the way in which the
* OTS creates and manipulates transactions.
*
* As with Transaction, we only create actions here, and do not associated
* these contexts with any thread. We do the association later.
*
* If we were to do the creation via a suitably modified current interface
* then the thread association would be done for us automatically, and we
* would not have to call resume at all.
*
* This is a top-level action proxy.
*
* @message com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror {0} caught exception: {1}
*/

/*
* NOTE: all calls to pushAction in this and related classes are to do
* with AIT abstract records. Some of them rely on being able to call
* BasicAction.Current to determine what the current transaction is and
* if we do not do thread-to-transaction association here then this all
* breaks. There is no other reason for this. So, what we need to do
* is remove this dependency by fixing the AIT records. This dependency
* has a knock-on effect on certain optimisations we can make (e.g.,
* local interpositon - see ServerControl.)
*/

public class ServerTopLevelAction extends ServerResource implements org.omg.CosTransactions.ResourceOperations
{

    /**
     * @message com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.ipfailed {0} - could not register interposed hierarchy!
     */

public ServerTopLevelAction (ServerControl control)
    {
  super(control);

  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.CONSTRUCTORS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::ServerTopLevelAction ( "+_theUid+" )");
  }

  _theResource = null;
  _resourceRef = getReference();

  /*
   * Now attempt to do interposition registration.
   */

  if (_resourceRef != null)
  {
      /*
       * Would like to be able to attach a thread filter
       * to this object if process-filters aren't supported.
       * However, currently this won't work as we can't have
       * two different filter types working at the same
       * time.
       *
       *    ATTACH_THREAD_FILTER_(_theResource);
       */

      Coordinator realCoordinator = _theControl.originalCoordinator();

      if (!(_valid = registerResource(realCoordinator)))
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.ipfailed",
                new Object[] {"ServerTopLevelAction"});
    }

    /*
     * Failed to register. Valid is set, and the interposition
     * controller will now deal with this.
     */
      }

      realCoordinator = null;
  }
  else
      _valid = false;
    }

public Resource getReference ()
    {
  if ((_resourceRef == null) && _valid)
  {
      if (_theControl != null)
      {
    _theResource = new org.omg.CosTransactions.ResourcePOATie(this);

    ORBManager.getPOA().objectIsReady(_theResource);

    _resourceRef = org.omg.CosTransactions.ResourceHelper.narrow(ORBManager.getPOA().corbaReference(_theResource));
      }
      else
    _valid = false;
  }

  return _resourceRef;
    }

/*
* Will only be called by the remote top-level transaction.
*/

public org.omg.CosTransactions.Vote prepare () throws HeuristicMixed, HeuristicHazard, SystemException
    {
  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::prepare for "+_theUid);
  }

  if (_theControl == null)
  {
      throw new INVALID_TRANSACTION(ExceptionCodes.SERVERAA_NO_CONTROL, CompletionStatus.COMPLETED_NO);
  }

  if (_theControl.isWrapper())
  {
      destroyResource()// won't necessarily get another invocation!
      return Vote.VoteReadOnly;
  }

  ServerTransaction theTransaction = (ServerTransaction) _theControl.getImplHandle();

  //  ThreadActionData.pushAction(theTransaction); // unnecessary if context goes with all calls.

  int result = TwoPhaseOutcome.PREPARE_NOTOK;

  /*
   * Transaction may have locally timed out and been rolled back.
   */

  int s = theTransaction.status();

  if ((s == ActionStatus.RUNNING) || (s == ActionStatus.ABORT_ONLY))
      result = theTransaction.doPrepare();
  else
  {
      switch (s)
      {
      case ActionStatus.COMMITTING:
      case ActionStatus.COMMITTED:
      case ActionStatus.H_COMMIT:
    result = TwoPhaseOutcome.PREPARE_OK;
    break;
      case ActionStatus.H_MIXED:
    result = TwoPhaseOutcome.HEURISTIC_MIXED;
    break;
      case ActionStatus.H_HAZARD:
    result = TwoPhaseOutcome.HEURISTIC_HAZARD;
    break;
      }
  }

  ThreadActionData.popAction();

  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::prepare for "+_theUid+" : "+TwoPhaseOutcome.stringForm(result));
  }

  /*
   * If prepare failed, then rollback now.
   */

  if (result == TwoPhaseOutcome.PREPARE_NOTOK)
  {
      try
      {
    rollback();
      }
      catch (HeuristicCommit ex1)
      {
    result = TwoPhaseOutcome.HEURISTIC_COMMIT;
      }
      catch (HeuristicMixed ex2)
      {
    result = TwoPhaseOutcome.HEURISTIC_MIXED;
      }
      catch (HeuristicHazard ex3)
      {
    result = TwoPhaseOutcome.HEURISTIC_HAZARD;
      }
      catch (SystemException ex4)
      {
    result = TwoPhaseOutcome.HEURISTIC_HAZARD;
      }
  }

  switch (result)
  {
  case TwoPhaseOutcome.INVALID_TRANSACTION:
      throw new INVALID_TRANSACTION(ExceptionCodes.INVALID_ACTION, CompletionStatus.COMPLETED_NO);
  case TwoPhaseOutcome.PREPARE_OK:
      return Vote.VoteCommit;
  case TwoPhaseOutcome.PREPARE_NOTOK:
      destroyResource()// won't necessarily get another invocation!

      return Vote.VoteRollback;
  case TwoPhaseOutcome.PREPARE_READONLY:
      destroyResource()// won't necessarily get another invocation!

      // what is we subsequently rollback?

      return Vote.VoteReadOnly;
  case TwoPhaseOutcome.HEURISTIC_MIXED:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicMixed()// will eventually get forget
  case TwoPhaseOutcome.HEURISTIC_HAZARD:
  default:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicHazard();
  }
    }

public void rollback () throws HeuristicCommit, HeuristicMixed, HeuristicHazard, SystemException
    {
  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::rollback for "+_theUid);
  }

  if (_theControl == null)
  {
      throw new INVALID_TRANSACTION(ExceptionCodes.SERVERAA_NO_CONTROL, CompletionStatus.COMPLETED_NO);
  }

  if (_theControl.isWrapper())
  {
      destroyResource();
      return;
  }

  ServerTransaction theTransaction = (ServerTransaction) _theControl.getImplHandle();

  //  ThreadActionData.pushAction(theTransaction);

  int actionStatus = theTransaction.status();

  if (actionStatus == ActionStatus.PREPARED)
  {
      /*
       * This will also call any after_completions on
       * registered synchronizations.
       */

      actionStatus = theTransaction.doPhase2Abort();
  }
  else
  {
      if ((actionStatus == ActionStatus.RUNNING) ||
                (actionStatus == ActionStatus.ABORT_ONLY))
      {
    try
    {
        /*
         * Have to do this because of the way PI works
         * with thread-context association.
         */

        if (!valid())
      theTransaction.doPhase2Abort()// must rollback
        else
      theTransaction.rollback();

        actionStatus = ActionStatus.ABORTED;
    }
    catch (SystemException ex)
    {
        actionStatus = ActionStatus.ABORTED;

        throw ex;
    }
    finally
    {
        destroyResource();
    }
      }
  }

  ThreadActionData.popAction();

  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::rollback for "+_theUid+" : "+ActionStatus.stringForm(actionStatus));
  }

  switch (actionStatus)
  {
  case ActionStatus.PREPARED:
      throw new INVALID_TRANSACTION(ExceptionCodes.INVALID_ACTION, CompletionStatus.COMPLETED_NO);
  case ActionStatus.ABORTED:
  case ActionStatus.H_ROLLBACK:
      destroyResource();
      break;
  case ActionStatus.COMMITTED:
  case ActionStatus.H_COMMIT:
      destroyResource();
      throw new HeuristicCommit();
  case ActionStatus.H_MIXED:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicMixed();
  case ActionStatus.H_HAZARD:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicHazard();
  default:
      destroyResource();
      break;
  }
    }

public void commit () throws NotPrepared, HeuristicRollback, HeuristicMixed, HeuristicHazard, SystemException
    {
  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::commit for "+_theUid);
  }

  if (_theControl == null)
  {
      throw new INVALID_TRANSACTION(ExceptionCodes.SERVERAA_NO_CONTROL, CompletionStatus.COMPLETED_NO);
  }

  if (_theControl.isWrapper())
  {
      destroyResource();
      return;
  }

  ServerTransaction theTransaction = (ServerTransaction) _theControl.getImplHandle();

  //  ThreadActionData.pushAction(theTransaction);

  int actionStatus = theTransaction.status();
  boolean notPrepared = false;

  if (actionStatus == ActionStatus.PREPARED)
  {
      /*
       * This will also call any after_completions on
       * registered synchronizations.
       */

      actionStatus = theTransaction.doPhase2Commit();
  }
  else
  {
      if (actionStatus == ActionStatus.RUNNING)
      {
    if (jtsLogger.logger.isDebugEnabled())
    {
        jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                   com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::commit for "+_theUid+" : NotPrepared");
    }

    notPrepared = true;
      }
  }

  ThreadActionData.popAction();

  if (notPrepared)
      throw new NotPrepared();

  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
           com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::commit for "+_theUid+" : "+ActionStatus.stringForm(actionStatus));
  }

  switch (actionStatus)
  {
  case ActionStatus.PREPARED:
      throw new INVALID_TRANSACTION(ExceptionCodes.SERVERAA_NO_CONTROL, CompletionStatus.COMPLETED_NO);
  case ActionStatus.COMMITTED:
  case ActionStatus.H_COMMIT:
      destroyResource();
      break;
  case ActionStatus.ABORTED:
  case ActionStatus.H_ROLLBACK:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicRollback();
  case ActionStatus.H_MIXED:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicMixed();
  case ActionStatus.H_HAZARD:
      if (TxControl.getMaintainHeuristics())
    destroyResource();
      throw new HeuristicHazard();
  default:
      destroyResource();
      break;
  }
    }

public void forget () throws SystemException
    {
  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::forget for "+_theUid);
  }

  boolean forgot = true;

  if (_theControl != null)
      forgot = _theControl.forgetHeuristics();

  destroyResource()// causes the removal of the transaction state.

  if (!forgot)
      throw new BAD_OPERATION();
    }

    /**
     * @message com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.notx {0} - no transaction!
     */

public void commit_one_phase () throws HeuristicHazard, SystemException
    {
  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::commit_one_phase for "+_theUid);
  }

  if (_theControl == null)
  {
      throw new INVALID_TRANSACTION(ExceptionCodes.SERVERAA_NO_CONTROL, CompletionStatus.COMPLETED_NO);
  }

  if (_theControl.isWrapper())
  {
      destroyResource();
      return;
  }

  ServerTransaction theTransaction = (ServerTransaction) _theControl.getImplHandle();

  if (theTransaction == null)
  {
      if (jtsLogger.loggerI18N.isWarnEnabled())
      {
    jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.notx",
            new Object[] {"ServerTopLevelAction.commit_one_phase"});
      }

      throw new INVALID_TRANSACTION(ExceptionCodes.NO_TRANSACTION, CompletionStatus.COMPLETED_NO);
  }

  //  ThreadActionData.pushAction(theTransaction);

  try
  {
      /*
       * This will commit and do any before/after_completion calls
       * on registered synchronizations.
       */

      theTransaction.doCommit(true);
  }
  catch (HeuristicHazard e1)
  {
      /*
       * Is a heuristic, then don't remove the
       * transaction information.
       */

      ThreadActionData.popAction();

      throw e1;
  }
  catch (TRANSACTION_ROLLEDBACK e4)
  {
      ThreadActionData.popAction();

      throw e4;
  }
  catch (INVALID_TRANSACTION e5)
  {
      ThreadActionData.popAction();

      throw e5;
  }
  catch (SystemException e6)
  {
      ThreadActionData.popAction();

      throw e6;
  }
  catch (Exception e7)
  {
      ThreadActionData.popAction();

      throw new UNKNOWN(e7.toString());
  }
  finally
  {
      destroyResource();
  }

  ThreadActionData.popAction();

  destroyResource();
    }

public String type ()
    {
  return "/Resources/Arjuna/ServerTopLevelAction";
    }

protected ServerTopLevelAction ()
    {
  if (jtsLogger.logger.isDebugEnabled())
  {
      jtsLogger.logger.debug(DebugLevel.CONSTRUCTORS, VisibilityLevel.VIS_PROTECTED,
                 com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ServerTopLevelAction::ServerTopLevelAction ()");
  }

  _theResource = null;
  _resourceRef = null;
    }

protected synchronized void destroyResource ()
    {
  if (!_destroyed)
  {
      try
      {
    if (Interposition.destroy(get_uid()))
        _destroyed = true;
      }
      catch (Exception e)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.destroyResource", e});
    }
      }

      try
      {
    if (_theResource != null)
    {
        ORBManager.getPOA().shutdownObject(_theResource);
        _theResource = null;
    }
      }
      catch (Exception e)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.destroyResource", e});
    }
      }
  }

  tidyup();
    }

    /**
     * @message com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.nocoord {0} - no coordinator to use!
     */

protected boolean registerResource (Coordinator theCoordinator)
    {
  boolean result = false;

  if (theCoordinator != null)
  {
      try
      {
    /*
     * Register resource and pass RecoveryCoordinator reference
     * to the interposed transaction to save and restore.
     */

    RecoveryCoordinator recoveryCoord = theCoordinator.register_resource(_resourceRef);

    if (!_theControl.isWrapper())
    {
        ServerTransaction tx = (ServerTransaction) _theControl.getImplHandle();

        if (tx != null)
        {
      tx.setRecoveryCoordinator(recoveryCoord);

      result = true;
        }
        else
      result = false;
    }
    else
        result = true;
      }
      catch (ClassCastException classCastException)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.registerResource", classCastException});
    }
      }
      catch (Inactive ine)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.registerResource", ine});
    }
      }
      catch (TRANSACTION_ROLLEDBACK ex1)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.registerResource", ex1});
    }
      }
      catch (INVALID_TRANSACTION ex2)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.registerResource", ex2});
    }
      }
      catch (Exception e)
      {
    if (jtsLogger.loggerI18N.isWarnEnabled())
    {
        jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.generror",
                new Object[] {"ServerTopLevelAction.registerResource", e}, e);
    }
      }
  }
  else
  {
      if (jtsLogger.loggerI18N.isWarnEnabled())
      {
    jtsLogger.loggerI18N.warn("com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.nocoord",
            new Object[] {"ServerTopLevelAction.registerResource"});
      }
  }

  return result;
    }

protected org.omg.CosTransactions.ResourcePOATie _theResource;
protected Resource                               _resourceRef;

}
TOP

Related Classes of com.arjuna.ats.internal.jts.orbspecific.interposition.resources.arjuna.ServerTopLevelAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.