/* */ package org.jboss.jms.tx;
/* */
/* */ import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
/* */ import java.util.ArrayList;
/* */ import java.util.Collection;
/* */ import java.util.Collections;
/* */ import java.util.Iterator;
/* */ import java.util.List;
/* */ import java.util.Map.Entry;
/* */ import java.util.Set;
/* */ import javax.jms.JMSException;
/* */ import javax.jms.JMSSecurityException;
/* */ import javax.transaction.xa.XAException;
/* */ import javax.transaction.xa.Xid;
/* */ import org.jboss.jms.delegate.ConnectionDelegate;
/* */ import org.jboss.jms.delegate.DeliveryInfo;
/* */ import org.jboss.jms.delegate.SessionDelegate;
/* */ import org.jboss.jms.exception.MessagingTransactionRolledBackException;
/* */ import org.jboss.jms.exception.MessagingXAException;
/* */ import org.jboss.jms.message.JBossMessage;
/* */ import org.jboss.jms.message.MessageProxy;
/* */ import org.jboss.logging.Logger;
/* */
/* */ public class ResourceManager
/* */ {
/* 70 */ private boolean trace = log.isTraceEnabled();
/* */
/* 72 */ private ConcurrentHashMap transactions = new ConcurrentHashMap();
/* */ private int serverID;
/* 78 */ private static final Logger log = Logger.getLogger(ResourceManager.class);
/* */
/* */ ResourceManager(int serverID)
/* */ {
/* 84 */ this.serverID = serverID;
/* */ }
/* */
/* */ public int getServerID()
/* */ {
/* 91 */ return this.serverID;
/* */ }
/* */
/* */ public void merge(ResourceManager other)
/* */ {
/* 99 */ this.transactions.putAll(other.transactions);
/* */ }
/* */
/* */ public ClientTransaction removeTx(Object xid)
/* */ {
/* 107 */ return removeTxInternal(xid);
/* */ }
/* */
/* */ public LocalTx createLocalTx()
/* */ {
/* 115 */ ClientTransaction tx = new ClientTransaction();
/* */
/* 117 */ LocalTx xid = getNextTxId();
/* */
/* 119 */ this.transactions.put(xid, tx);
/* */
/* 121 */ return xid;
/* */ }
/* */
/* */ public void addMessage(Object xid, String sessionId, JBossMessage m)
/* */ {
/* 132 */ if (this.trace) log.trace("addding message " + m + " for xid " + xid);
/* */
/* 134 */ ClientTransaction tx = getTxInternal(xid);
/* */
/* 136 */ tx.addMessage(sessionId, m);
/* */ }
/* */
/* */ public void handleFailover(int newServerID, String oldSessionID, String newSessionID)
/* */ {
/* 144 */ for (Iterator i = this.transactions.values().iterator(); i.hasNext(); )
/* */ {
/* 146 */ ClientTransaction tx = (ClientTransaction)i.next();
/* */
/* 148 */ tx.handleFailover(newServerID, oldSessionID, newSessionID);
/* */ }
/* */ }
/* */
/* */ public List getDeliveriesForSession(String sessionID)
/* */ {
/* 157 */ List ackInfos = new ArrayList();
/* */
/* 159 */ for (Iterator i = this.transactions.values().iterator(); i.hasNext(); )
/* */ {
/* 161 */ ClientTransaction tx = (ClientTransaction)i.next();
/* */
/* 163 */ List acks = tx.getDeliveriesForSession(sessionID);
/* */
/* 165 */ ackInfos.addAll(acks);
/* */ }
/* */
/* 168 */ return ackInfos;
/* */ }
/* */
/* */ public void addAck(Object xid, String sessionId, DeliveryInfo ackInfo)
/* */ throws JMSException
/* */ {
/* 180 */ if (this.trace) log.trace("adding " + ackInfo + " to transaction " + xid);
/* */
/* 182 */ ClientTransaction tx = getTxInternal(xid);
/* */
/* 184 */ if (tx == null)
/* */ {
/* 186 */ throw new JMSException("There is no transaction with id " + xid);
/* */ }
/* */
/* 189 */ tx.addAck(sessionId, ackInfo);
/* */ }
/* */
/* */ public void commitLocal(LocalTx xid, ConnectionDelegate connection) throws JMSException
/* */ {
/* 194 */ if (this.trace) log.trace("committing " + xid);
/* */
/* 196 */ ClientTransaction tx = getTxInternal(xid);
/* */
/* 199 */ if (tx == null)
/* */ {
/* 201 */ throw new javax.jms.IllegalStateException("Cannot find transaction " + xid);
/* */ }
/* */
/* 204 */ TransactionRequest request = new TransactionRequest(0, null, tx);
/* */ try
/* */ {
/* 209 */ connection.sendTransaction(request, false);
/* */
/* 213 */ if (removeTxInternal(xid) == null)
/* */ {
/* 215 */ throw new javax.jms.IllegalStateException("Cannot find xid to remove " + xid);
/* */ }
/* */
/* */ }
/* */ catch (JMSSecurityException e)
/* */ {
/* 221 */ throw e;
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 226 */ rollbackLocal(xid);
/* */
/* 228 */ JMSException e = new MessagingTransactionRolledBackException(t.getMessage());
/* 229 */ e.initCause(t);
/* 230 */ throw e;
/* */ }
/* */ }
/* */
/* */ public void rollbackLocal(Object xid) throws JMSException
/* */ {
/* 236 */ if (this.trace) log.trace("rolling back local xid " + xid);
/* */
/* 238 */ ClientTransaction ts = removeTxInternal(xid);
/* */
/* 240 */ if (ts == null)
/* */ {
/* 242 */ throw new javax.jms.IllegalStateException("Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 247 */ ts.clearMessages();
/* */
/* 251 */ redeliverMessages(ts);
/* */ }
/* */
/* */ public ClientTransaction getTx(Object xid)
/* */ {
/* 257 */ return getTxInternal(xid);
/* */ }
/* */
/* */ public int size()
/* */ {
/* 263 */ return this.transactions.size();
/* */ }
/* */
/* */ public boolean checkForAcksInSession(String sessionId)
/* */ {
/* 269 */ Iterator iter = this.transactions.entrySet().iterator();
/* */
/* 271 */ while (iter.hasNext())
/* */ {
/* 273 */ Map.Entry entry = (Map.Entry)iter.next();
/* */
/* 275 */ ClientTransaction tx = (ClientTransaction)entry.getValue();
/* */
/* 277 */ if (tx.getState() == 2)
/* */ {
/* 279 */ List dels = tx.getDeliveriesForSession(sessionId);
/* */
/* 281 */ if (!dels.isEmpty())
/* */ {
/* 285 */ return true;
/* */ }
/* */ }
/* */ }
/* 289 */ return false;
/* */ }
/* */
/* */ Xid startTx(Xid xid)
/* */ throws XAException
/* */ {
/* 298 */ if (this.trace) log.trace("starting " + xid);
/* */
/* 300 */ ClientTransaction state = getTxInternal(xid);
/* */
/* 302 */ if (state != null)
/* */ {
/* 304 */ throw new MessagingXAException(-8, "Transaction already exists with xid " + xid);
/* */ }
/* */
/* 307 */ this.transactions.put(xid, new ClientTransaction());
/* */
/* 309 */ return xid;
/* */ }
/* */
/* */ void endTx(Xid xid, boolean success) throws XAException
/* */ {
/* 314 */ if (this.trace) log.trace("ending " + xid + ", success=" + success);
/* */
/* 316 */ ClientTransaction state = getTxInternal(xid);
/* */
/* 318 */ if (state == null)
/* */ {
/* 320 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 323 */ state.setState(1);
/* */ }
/* */
/* */ int prepare(Xid xid, ConnectionDelegate connection) throws XAException
/* */ {
/* 328 */ if (this.trace) log.trace("preparing " + xid);
/* */
/* 330 */ ClientTransaction state = getTxInternal(xid);
/* */
/* 332 */ if (state == null)
/* */ {
/* 334 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 337 */ TransactionRequest request = new TransactionRequest(2, xid, state);
/* */
/* 340 */ sendTransactionXA(request, connection);
/* */
/* 342 */ state.setState(2);
/* */
/* 344 */ if (this.trace) log.trace("State is now: " + state.getState());
/* */
/* 346 */ return 0;
/* */ }
/* */
/* */ void commit(Xid xid, boolean onePhase, ConnectionDelegate connection) throws XAException
/* */ {
/* 351 */ if (this.trace) log.trace("commiting xid " + xid + ", onePhase=" + onePhase);
/* */
/* 353 */ ClientTransaction tx = removeTxInternal(xid);
/* */
/* 355 */ if (this.trace) log.trace("got tx: " + tx + " state " + tx.getState());
/* */
/* 357 */ if (onePhase)
/* */ {
/* 360 */ if (tx == null)
/* */ {
/* 362 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 365 */ TransactionRequest request = new TransactionRequest(0, null, tx);
/* */
/* 368 */ request.state = tx;
/* */
/* 370 */ sendTransactionXA(request, connection);
/* */ }
/* */ else
/* */ {
/* 374 */ if (tx != null)
/* */ {
/* 376 */ if (tx.getState() != 2)
/* */ {
/* 378 */ throw new MessagingXAException(-6, "commit called for transaction, but it is not prepared");
/* */ }
/* */
/* */ }
/* */
/* 388 */ TransactionRequest request = new TransactionRequest(3, xid, null);
/* */
/* 391 */ request.xid = xid;
/* */
/* 393 */ sendTransactionXA(request, connection);
/* */ }
/* */
/* 396 */ if (tx != null)
/* */ {
/* 398 */ tx.setState(3);
/* */ }
/* */ }
/* */
/* */ void rollback(Xid xid, ConnectionDelegate connection) throws XAException
/* */ {
/* 404 */ if (this.trace) log.trace("rolling back xid " + xid);
/* */
/* 406 */ ClientTransaction tx = removeTxInternal(xid);
/* */
/* 408 */ if (tx == null)
/* */ {
/* 410 */ throw new java.lang.IllegalStateException("Cannot find xid to remove " + xid);
/* */ }
/* */
/* 417 */ TransactionRequest request = null;
/* */
/* 420 */ if (tx != null)
/* */ {
/* 422 */ tx.clearMessages();
/* */ }
/* */
/* 425 */ if ((tx == null) || (tx.getState() == 2))
/* */ {
/* 429 */ request = new TransactionRequest(4, xid, tx);
/* */
/* 431 */ if (this.trace) log.trace("Sending rollback to server, tx:" + tx);
/* */
/* 433 */ sendTransactionXA(request, connection);
/* */ }
/* 439 */ else if (tx == null)
/* */ {
/* 441 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 449 */ if (this.trace) log.trace("Redelivering messages, tx:" + tx);
/* */
/* */ try
/* */ {
/* 453 */ if (tx != null)
/* */ {
/* 455 */ redeliverMessages(tx);
/* */
/* 457 */ tx.setState(4);
/* */ }
/* */
/* */ }
/* */ catch (JMSException e)
/* */ {
/* 463 */ log.error("Failed to redeliver", e);
/* */ }
/* */ }
/* */
/* */ Xid joinTx(Xid xid)
/* */ throws XAException
/* */ {
/* 470 */ if (this.trace) log.trace("joining " + xid);
/* */
/* 472 */ ClientTransaction state = getTxInternal(xid);
/* */
/* 474 */ if (state == null)
/* */ {
/* 476 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 479 */ return xid;
/* */ }
/* */
/* */ Xid resumeTx(Xid xid)
/* */ throws XAException
/* */ {
/* 486 */ if (this.trace) log.trace("resuming " + xid);
/* */
/* 488 */ ClientTransaction state = getTxInternal(xid);
/* */
/* 490 */ if (state == null)
/* */ {
/* 492 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 495 */ return xid;
/* */ }
/* */
/* */ Xid suspendTx(Xid xid) throws XAException
/* */ {
/* 500 */ if (this.trace) log.trace("suspending " + xid);
/* */
/* 502 */ ClientTransaction state = getTxInternal(xid);
/* */
/* 504 */ if (state == null)
/* */ {
/* 506 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + xid);
/* */ }
/* */
/* 509 */ return xid;
/* */ }
/* */
/* */ Xid convertTx(LocalTx localTx, Xid xid) throws XAException
/* */ {
/* 514 */ if (this.trace) log.trace("converting " + localTx + " to " + xid);
/* */
/* 518 */ ClientTransaction newTx = getTxInternal(xid);
/* */
/* 520 */ if (newTx != null)
/* */ {
/* 522 */ throw new MessagingXAException(-8, "Transaction already exists:" + xid);
/* */ }
/* */
/* 527 */ ClientTransaction local = removeTxInternal(localTx);
/* */
/* 529 */ if (local == null)
/* */ {
/* 531 */ throw new MessagingXAException(-4, "Cannot find transaction with xid:" + localTx);
/* */ }
/* */
/* 536 */ this.transactions.put(xid, local);
/* */
/* 538 */ return xid;
/* */ }
/* */
/* */ Xid[] recover(int flags, ConnectionDelegate conn)
/* */ throws XAException
/* */ {
/* 544 */ if (this.trace) log.trace("calling recover with flags: " + flags);
/* */
/* 546 */ if (flags == 16777216)
/* */ {
/* */ try
/* */ {
/* 550 */ Xid[] txs = conn.getPreparedTransactions();
/* */
/* 552 */ if (this.trace) log.trace("Got " + txs.length + " transactions from server");
/* */
/* 555 */ for (int i = 0; i < txs.length; i++)
/* */ {
/* 558 */ if (this.transactions.containsKey(txs[i]))
/* */ continue;
/* 560 */ ClientTransaction tx = new ClientTransaction();
/* */
/* 562 */ tx.setState(2);
/* */
/* 564 */ this.transactions.put(txs[i], tx);
/* */ }
/* */
/* 568 */ return txs;
/* */ }
/* */ catch (JMSException e)
/* */ {
/* 572 */ throw new MessagingXAException(-7, "Failed to get prepared transactions");
/* */ }
/* */
/* */ }
/* */
/* 577 */ return new Xid[0];
/* */ }
/* */
/* */ private ClientTransaction getTxInternal(Object xid)
/* */ {
/* 585 */ if (this.trace) log.trace("getting transaction for " + xid);
/* */
/* 587 */ return (ClientTransaction)this.transactions.get(xid);
/* */ }
/* */
/* */ private ClientTransaction removeTxInternal(Object xid)
/* */ {
/* 592 */ return (ClientTransaction)this.transactions.remove(xid);
/* */ }
/* */
/* */ private void redeliverMessages(ClientTransaction ts)
/* */ throws JMSException
/* */ {
/* 602 */ List sessionStates = ts.getSessionStates();
/* */
/* 606 */ Collections.reverse(sessionStates);
/* */
/* 608 */ for (Iterator i = sessionStates.iterator(); i.hasNext(); )
/* */ {
/* 610 */ ClientTransaction.SessionTxState state = (ClientTransaction.SessionTxState)i.next();
/* */
/* 612 */ List acks = state.getAcks();
/* */
/* 614 */ if (!acks.isEmpty())
/* */ {
/* 616 */ DeliveryInfo info = (DeliveryInfo)acks.get(0);
/* */
/* 618 */ MessageProxy mp = info.getMessageProxy();
/* */
/* 620 */ SessionDelegate del = mp.getSessionDelegate();
/* */
/* 622 */ del.redeliver(acks);
/* */ }
/* */ }
/* */ }
/* */
/* */ private synchronized LocalTx getNextTxId()
/* */ {
/* 629 */ return new LocalTx();
/* */ }
/* */
/* */ private void sendTransactionXA(TransactionRequest request, ConnectionDelegate connection)
/* */ throws XAException
/* */ {
/* */ try
/* */ {
/* 637 */ connection.sendTransaction(request, false);
/* */ }
/* */ catch (JMSSecurityException security)
/* */ {
/* 641 */ MessagingXAException xaEx = new MessagingXAException(100, "A security exception happend!", security);
/* 642 */ log.error(xaEx, xaEx);
/* 643 */ throw xaEx;
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 659 */ throw new MessagingXAException(4, "A Throwable was caught in sending the transaction", t);
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.jms.tx.ResourceManager
* JD-Core Version: 0.6.0
*/