summaryrefslogtreecommitdiff
path: root/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java')
-rw-r--r--trunk/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java537
1 files changed, 0 insertions, 537 deletions
diff --git a/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java b/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
deleted file mode 100644
index 6763c72ecd..0000000000
--- a/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.client;
-
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-import org.apache.qpid.QpidException;
-import org.apache.qpid.dtx.XidImpl;
-import org.apache.qpid.transport.*;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is an implementation of javax.njms.XAResource.
- */
-public class XAResourceImpl implements XAResource
-{
- /**
- * this XAResourceImpl's logger
- */
- private static final Logger _logger = LoggerFactory.getLogger(XAResourceImpl.class);
-
- /**
- * Reference to the associated XASession
- */
- private XASessionImpl _xaSession = null;
-
- /**
- * The XID of this resource
- */
- private Xid _xid;
-
- //--- constructor
-
- /**
- * Create an XAResource associated with a XASession
- *
- * @param xaSession The session XAresource
- */
- protected XAResourceImpl(XASessionImpl xaSession)
- {
- _xaSession = xaSession;
- }
-
- //--- The XAResource
- /**
- * Commits the global transaction specified by xid.
- *
- * @param xid A global transaction identifier
- * @param b If true, use a one-phase commit protocol to commit the work done on behalf of xid.
- * @throws XAException An error has occurred. An error has occurred. Possible XAExceptions are XA_HEURHAZ,
- * XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
- */
- public void commit(Xid xid, boolean b) throws XAException
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("commit tx branch with xid: ", xid);
- }
- Future<XaResult> future =
- _xaSession.getQpidSession().dtxCommit(convertXid(xid), b ? Option.ONE_PHASE : Option.NONE);
-
- // now wait on the future for the result
- XaResult result = null;
- try
- {
- result = future.get();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode());
- }
- checkStatus(result.getStatus());
- }
-
- /**
- * Ends the work performed on behalf of a transaction branch.
- * The resource manager disassociates the XA resource from the transaction branch specified
- * and lets the transaction complete.
- * <ul>
- * <li> If TMSUSPEND is specified in the flags, the transaction branch is temporarily suspended in an incomplete state.
- * The transaction context is in a suspended state and must be resumed via the start method with TMRESUME specified.
- * <li> If TMFAIL is specified, the portion of work has failed. The resource manager may mark the transaction as rollback-only
- * <li> If TMSUCCESS is specified, the portion of work has completed successfully.
- * /ul>
- *
- * @param xid A global transaction identifier that is the same as the identifier used previously in the start method
- * @param flag One of TMSUCCESS, TMFAIL, or TMSUSPEND.
- * @throws XAException An error has occurred. An error has occurred. Possible XAException values are XAER_RMERR,
- * XAER_RMFAILED, XAER_NOTA, XAER_INVAL, XAER_PROTO, or XA_RB*.
- */
- public void end(Xid xid, int flag) throws XAException
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("end tx branch with xid: ", xid);
- }
- switch (flag)
- {
- case(XAResource.TMSUCCESS):
- break;
- case(XAResource.TMFAIL):
- break;
- case(XAResource.TMSUSPEND):
- break;
- default:
- throw new XAException(XAException.XAER_INVAL);
- }
- _xaSession.flushAcknowledgments();
- Future<XaResult> future = _xaSession.getQpidSession()
- .dtxEnd(convertXid(xid),
- flag == XAResource.TMFAIL ? Option.FAIL : Option.NONE,
- flag == XAResource.TMSUSPEND ? Option.SUSPEND : Option.NONE);
- // now wait on the future for the result
- XaResult result = null;
- try
- {
- result = future.get();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode());
- }
- checkStatus(result.getStatus());
- }
-
-
- /**
- * Tells the resource manager to forget about a heuristically completed transaction branch.
- *
- * @param xid String(xid.getGlobalTransactionId() A global transaction identifier
- * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL,
- * XAER_NOTA, XAER_INVAL, or XAER_PROTO.
- */
- public void forget(Xid xid) throws XAException
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("forget tx branch with xid: ", xid);
- }
- _xaSession.getQpidSession().dtxForget(convertXid(xid));
- try
- {
- _xaSession.getQpidSession().sync();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode());
- }
- }
-
-
- /**
- * Obtains the current transaction timeout value set for this XAResource instance.
- * If XAResource.setTransactionTimeout was not used prior to invoking this method,
- * the return value is the default timeout i.e. 0;
- * otherwise, the value used in the previous setTransactionTimeout call is returned.
- *
- * @return The transaction timeout value in seconds.
- * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
- */
- public int getTransactionTimeout() throws XAException
- {
- int result = 0;
- if (_xid != null)
- {
- Future<GetTimeoutResult> future =
- _xaSession.getQpidSession().dtxGetTimeout(convertXid(_xid));
- try
- {
- result = (int) future.get().getTimeout();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode());
- }
- }
- return result;
- }
-
- /**
- * This method is called to determine if the resource manager instance represented
- * by the target object is the same as the resouce manager instance represented by
- * the parameter xaResource.
- *
- * @param xaResource An XAResource object whose resource manager instance is to
- * be compared with the resource manager instance of the target object
- * @return <code>true</code> if it's the same RM instance; otherwise <code>false</code>.
- * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
- */
- public boolean isSameRM(XAResource xaResource) throws XAException
- {
- // TODO : get the server identity of xaResource and compare it with our own one
- return false;
- }
-
- /**
- * Prepare for a transaction commit of the transaction specified in <code>Xid</code>.
- *
- * @param xid A global transaction identifier.
- * @return A value indicating the resource manager's vote on the outcome of the transaction.
- * The possible values are: XA_RDONLY or XA_OK.
- * @throws XAException An error has occurred. Possible exception values are: XAER_RMERR or XAER_NOTA
- */
- public int prepare(Xid xid) throws XAException
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("prepare ", xid);
- }
- Future<XaResult> future = _xaSession.getQpidSession().dtxPrepare(convertXid(xid));
- XaResult result = null;
- try
- {
- result = future.get();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode());
- }
- DtxXaStatus status = result.getStatus();
- int outcome = XAResource.XA_OK;
- switch (status)
- {
- case XA_OK:
- break;
- case XA_RDONLY:
- outcome = XAResource.XA_RDONLY;
- break;
- default:
- checkStatus(status);
- }
- return outcome;
- }
-
- /**
- * Obtains a list of prepared transaction branches.
- * <p/>
- * The transaction manager calls this method during recovery to obtain the list of transaction branches
- * that are currently in prepared or heuristically completed states.
- *
- * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS.
- * TMNOFLAGS must be used when no other flags are set in the parameter.
- * @return zero or more XIDs of the transaction branches that are currently in a prepared or heuristically
- * completed state.
- * @throws XAException An error has occurred. Possible value is XAER_INVAL.
- */
- public Xid[] recover(int flag) throws XAException
- {
- // the flag is ignored
- Future<RecoverResult> future = _xaSession.getQpidSession().dtxRecover();
- RecoverResult res = null;
- try
- {
- res = future.get();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr( e.getExceptions().get(0).getErrorCode());
- }
- Xid[] result = new Xid[res.getInDoubt().size()];
- int i = 0;
- for (Object obj : res.getInDoubt())
- {
- org.apache.qpid.transport.Xid xid = (org.apache.qpid.transport.Xid) obj;
- result[i] = new XidImpl(xid.getBranchId(), (int) xid.getFormat(), xid.getGlobalId());
- i++;
- }
- return result;
- }
-
- /**
- * Informs the resource manager to roll back work done on behalf of a transaction branch
- *
- * @param xid A global transaction identifier.
- * @throws XAException An error has occurred.
- */
- public void rollback(Xid xid) throws XAException
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("rollback tx branch with xid: ", xid);
- }
-
- Future<XaResult> future = _xaSession.getQpidSession().dtxRollback(convertXid(xid));
- // now wait on the future for the result
- XaResult result = null;
- try
- {
- result = future.get();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr( e.getExceptions().get(0).getErrorCode());
- }
- checkStatus(result.getStatus());
- }
-
- /**
- * Sets the current transaction timeout value for this XAResource instance.
- * Once set, this timeout value is effective until setTransactionTimeout is
- * invoked again with a different value.
- * To reset the timeout value to the default value used by the resource manager, set the value to zero.
- *
- * @param timeout The transaction timeout value in seconds.
- * @return true if transaction timeout value is set successfully; otherwise false.
- * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL.
- */
- public boolean setTransactionTimeout(int timeout) throws XAException
- {
- boolean result = false;
- if (_xid != null)
- {
- try
- {
- _xaSession.getQpidSession()
- .dtxSetTimeout(XidImpl.convert(_xid), timeout);
- }
- catch (QpidException e)
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Cannot convert Xid into String format ", e);
- }
- throw new XAException(XAException.XAER_PROTO);
- }
- result = true;
- }
- return result;
- }
-
- /**
- * Starts work on behalf of a transaction branch specified in xid.
- * <ul>
- * <li> If TMJOIN is specified, an exception is thrown as it is not supported
- * <li> If TMRESUME is specified, the start applies to resuming a suspended transaction specified in the parameter xid.
- * <li> If neither TMJOIN nor TMRESUME is specified and the transaction specified by xid has previously been seen by the
- * resource manager, the resource manager throws the XAException exception with XAER_DUPID error code.
- * </ul>
- *
- * @param xid A global transaction identifier to be associated with the resource
- * @param flag One of TMNOFLAGS, TMJOIN, or TMRESUME
- * @throws XAException An error has occurred. Possible exceptions
- * are XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
- */
- public void start(Xid xid, int flag) throws XAException
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("start tx branch with xid: ", xid);
- }
- switch (flag)
- {
- case(XAResource.TMNOFLAGS):
- break;
- case(XAResource.TMJOIN):
- break;
- case(XAResource.TMRESUME):
- break;
- default:
- throw new XAException(XAException.XAER_INVAL);
- }
- Future<XaResult> future = _xaSession.getQpidSession()
- .dtxStart(convertXid(xid),
- flag == XAResource.TMJOIN ? Option.JOIN : Option.NONE,
- flag == XAResource.TMRESUME ? Option.RESUME : Option.NONE);
- // now wait on the future for the result
- XaResult result = null;
- try
- {
- result = future.get();
- }
- catch (SessionException e)
- {
- // we need to restore the qpid session that has been closed
- _xaSession.createSession();
- // we should get a single exception
- convertExecutionErrorToXAErr(e.getExceptions().get(0).getErrorCode());
- // TODO: The amqp spec does not allow to make the difference
- // between an already known XID and a wrong arguments (join and resume are set)
- // TODO: make sure amqp addresses that
- }
- checkStatus(result.getStatus());
- _xid = xid;
- }
-
- //------------------------------------------------------------------------
- // Private methods
- //------------------------------------------------------------------------
-
- /**
- * Check xa method outcome and, when required, convert the status into the corresponding xa exception
- * @param status method status code
- * @throws XAException corresponding XA Exception when required
- */
- private void checkStatus(DtxXaStatus status) throws XAException
- {
- switch (status)
- {
- case XA_OK:
- // Do nothing this ok
- break;
- case XA_RBROLLBACK:
- // The tx has been rolled back for an unspecified reason.
- throw new XAException(XAException.XA_RBROLLBACK);
- case XA_RBTIMEOUT:
- // The transaction branch took too long.
- throw new XAException(XAException.XA_RBTIMEOUT);
- case XA_HEURHAZ:
- // The transaction branch may have been heuristically completed.
- throw new XAException(XAException.XA_HEURHAZ);
- case XA_HEURCOM:
- // The transaction branch has been heuristically committed.
- throw new XAException(XAException.XA_HEURCOM);
- case XA_HEURRB:
- // The transaction branch has been heuristically rolled back.
- throw new XAException(XAException.XA_HEURRB);
- case XA_HEURMIX:
- // The transaction branch has been heuristically committed and rolled back.
- throw new XAException(XAException.XA_HEURMIX);
- case XA_RDONLY:
- // The transaction branch was read-only and has been committed.
- throw new XAException(XAException.XA_RDONLY);
- default:
- // this should not happen
- if (_logger.isDebugEnabled())
- {
- _logger.debug("got unexpected status value: ", status);
- }
- //A resource manager error has occured in the transaction branch.
- throw new XAException(XAException.XAER_RMERR);
- }
- }
-
- /**
- * Convert execution error to xa exception.
- * @param error the execution error code
- * @throws XAException
- */
- private void convertExecutionErrorToXAErr(ExecutionErrorCode error) throws XAException
- {
- switch (error)
- {
- case NOT_ALLOWED:
- // The XID already exists.
- throw new XAException(XAException.XAER_DUPID);
- case NOT_FOUND:
- // The XID is not valid.
- throw new XAException(XAException.XAER_NOTA);
- case ILLEGAL_STATE:
- // Routine was invoked in an inproper context.
- throw new XAException(XAException.XAER_PROTO);
- case NOT_IMPLEMENTED:
- // the command is not implemented
- throw new XAException(XAException.XAER_RMERR);
- case COMMAND_INVALID:
- // Invalid call
- throw new XAException(XAException.XAER_INVAL);
- default:
- // this should not happen
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Got unexpected error: " + error);
- }
- //A resource manager error has occured in the transaction branch.
- throw new XAException(XAException.XAER_RMERR);
- }
- }
-
- /**
- * convert a generic xid into qpid format
- * @param xid xid to be converted
- * @return the qpid formated xid
- * @throws XAException when xid is null or when it cannot be converted.
- */
- private org.apache.qpid.transport.Xid convertXid(Xid xid) throws XAException
- {
- if (xid == null)
- {
- // Invalid arguments were given.
- throw new XAException(XAException.XAER_INVAL);
- }
- try
- {
- return XidImpl.convert(xid);
- }
- catch (QpidException e)
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Cannot convert Xid into String format ", e);
- }
- //A resource manager error has occured in the transaction branch.
- throw new XAException(XAException.XAER_RMERR);
- }
- }
-
-}