All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.ws.tx.at.internal.BranchRecord Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.ws.tx.at.internal;

import com.sun.istack.logging.Logger;
import com.sun.xml.ws.tx.at.WSATHelper;
import com.sun.xml.ws.tx.at.WSATXAResource;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

/**
 * Encapsulates remote WS-AT participants as a branch for this superior
 * transaction.
 */
public class BranchRecord implements Externalizable {
  private static final long serialVersionUID = -8663994789749988958L;
  private static final int VERSION = 1;

  private Xid globalXid;
  private Map registeredResources;
  private String branchAliasSuffix = "BI_WSATGatewayRM"; //this should be different from the WSATGateway resource name prefix, and should keep it short.
  private boolean logged;
  private String txLogLocation;
  private static final Logger LOGGER = Logger.getLogger(BranchRecord.class);

    /**
   * Used for recovery (created by readObject) and Externalizable no-arg constructor
   */
  public BranchRecord() {
    this.registeredResources = new HashMap<>();
  }

  BranchRecord(Xid xid) {
    this.globalXid = xid;
    this.registeredResources = new HashMap<>();
  }

  /**
   * Adds the specified WS-AT resource to the gateway branch record.
   * @param xid Xid used for key
   * @param wsatResource WSATXAResource
   * @return RegisteredResource that contains (WSAT)XAResource provided
   */
  public synchronized RegisteredResource addSubordinate(Xid xid, WSATXAResource wsatResource) {
    debug("addSubordindate xid:"+xid+" wsatResource:"+wsatResource);
    RegisteredResource rr = new RegisteredResource(wsatResource);
    registeredResources.put(xid, rr);
    return rr;
  }

  /**
   * Returns the transaction branch name of the specified WS-AT resource in order to enlist the resource.
   * Each call will return a different value for the same wsatResource and
   *  so it should only be called once for each resource.
   * @param wsatResource WSATXAResource
   * @return String representing
   */
  synchronized String getBranchName(XAResource wsatResource) {
    int index = getResourceIndex(wsatResource);
    if (index == -1) {
      throw new IllegalStateException(
          "WS-AT resource not associated with transaction branch " + globalXid);
    }
    return index + branchAliasSuffix;
  }


    /**
     *  If persist of record was successfully logged
     * @param b boolean
     */
  void setLogged(boolean b) {
    this.logged = b;
  }

    /**
     * If persist of record was successfully logged
     * @return boolean
     */
  boolean isLogged() {
    return logged;
  }

  int prepare(Xid xid) throws XAException {
/*
    if (isPrimaryBranch(xid)) {
      // primary branch always returns RDONLY
      debug("prepare() xid=" + xid + " returning XA_RDONLY");
      return XAResource.XA_RDONLY;
    }
*/
    RegisteredResource rr = getRegisteredResource(xid);
    int vote = XAResource.XA_OK;
    try {
      vote = rr.prepare(xid);
    } catch (XAException xae) {
      switch(xae.errorCode) {
      case XAException.XA_RBROLLBACK:
        // throw rollback,  TM will call rollback
        throw xae;
//      case XAException.XA_HEURMIX:
//      case XAException.XA_HEURHAZ:
//        heuristic = true;
//        break;
      case XAException.XAER_NOTA:
        // possible timeout of subordinate, initiate rollback
        JTAHelper.throwXAException(XAException.XA_RBTIMEOUT, "Subordinate resource timeout.", xae);
        break;
      default:
        throw xae;
      }
    }

    return vote;
  }

  void rollback(Xid xid) throws XAException {
    if (isPrimaryBranch(xid)) {
      debug("rollback() xid=" + xid + " ignoring primary branch ");
    }
    RegisteredResource rr = getRegisteredResource(xid);
    try {
      rr.rollback(xid);
    } catch (XAException e) {
      switch (e.errorCode) {
      case XAException.XA_HEURMIX:
      case XAException.XA_HEURHAZ:
      case XAException.XA_HEURCOM:
        throw e;
      case XAException.XAER_NOTA:
        // ignore, assume completion
        break;
      default:
        throw e;
      }
    }
  }

  void commit(Xid xid, boolean onePhase) throws XAException {
    if (isPrimaryBranch(xid)) {
      debug("commit() xid=" + xid + " ignoring primary branch");
        //This happens in superior during migration recovery and so should not do a
        // JTAHelper.throwXAException(XAException.XAER_NOTA, "Primary branch RDONLY");
    }
    RegisteredResource rr = getRegisteredResource(xid);
    try {
      rr.commit(xid, onePhase);
    } catch (XAException e) {
      switch (e.errorCode) {
      case XAException.XA_HEURMIX:
      case XAException.XA_HEURHAZ:
      case XAException.XA_HEURRB:
        throw e;
      case XAException.XAER_NOTA:
        // ignore, assume completion
        break;
      default:
        throw e;
      }
    }
  }

  /**
   * Returns the branch index of the specified WS-AT resource
   *
   * @param wsatResource WSATXAResource
   * @return the branch index, or -1 if DNE.
   */
  private synchronized int getResourceIndex(XAResource wsatResource) {
    for (int i=0; i resourceIterator = registeredResources.values().iterator();
    while(resourceIterator.hasNext()) {
        resourceIterator.next().writeExternal(out);
    }
  }

  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

    // Version
    int version = in.readInt();
    if (version != VERSION) {
      throw new IOException("invalid OTSBranch version " + version);
    }

    // Global Xid
    int formatId = in.readInt();

    int len = in.readByte();
    byte[] gtrid = new byte[len];
    in.readFully(gtrid);

    len = in.readByte();
    byte[] bqual=null;
    if (len > -1) {
      bqual = new byte[len];
      in.readFully(bqual);
    }

    // globalXid = XIDFactory.createXID(formatId, gtrid, bqual);
    globalXid = new XidImpl(formatId, gtrid, bqual);

    // RegisteredResources
    int resourceNum = in.readInt();
    for (int i=0; i-->
            
    
            


© 2015 - 2024 Weber Informatics LLC | Privacy Policy