use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class DebugHandler method getDebugInfo.
public Hashtable getDebugInfo(String arg, String target, String targetType, Properties p) throws Exception {
if (arg.equals("cxn")) {
if (target == null) {
return getAllCxnInfo(null);
} else {
ConnectionUID uid = new ConnectionUID(Long.parseLong(target));
return getCxnInfo(uid);
}
} else if (arg.equals("config")) {
return getConfig();
} else if (arg.equals("memory")) {
return getMemory();
} else if (arg.equals("dst")) {
if (target == null) {
return DL.getAllDebugState();
} else {
boolean isQueue = false;
if (targetType == null) {
throw new Exception("topic or queue not " + "specified with -t [t|q]");
} else if (targetType.equals("t")) {
isQueue = false;
} else if (targetType.equals("q")) {
isQueue = true;
} else {
throw new Exception("Unknown -t argument " + targetType + " expected t or q");
}
DestinationUID uid = DestinationUID.getUID(target, isQueue);
return getDestinationInfo(uid);
}
} else if (arg.equals("ses")) {
if (target == null) {
return Session.getAllDebugState();
} else {
SessionUID uid = new SessionUID(Long.parseLong(target));
return getSession(uid);
}
} else if (arg.equals("prd")) {
if (target == null) {
return Producer.getAllDebugState();
} else {
ProducerUID uid = new ProducerUID(Long.parseLong(target));
return getProducerInfo(uid);
}
} else if (arg.equals("con")) {
if (target == null) {
return Consumer.getAllDebugState();
} else {
ConsumerUID uid = new ConsumerUID(Long.parseLong(target));
return getConInfo(uid);
}
} else if (arg.equals("svc")) {
if (target == null) {
logger.log(Logger.INFO, "XXX - target of null " + "not implemented for " + arg);
} else {
return getSvcInfo(target);
}
} else if (arg.equals("db")) {
return getDBInfo();
} else if (arg.equals("trans")) {
if (target == null) {
return getTransactionInfo(null);
} else {
TransactionUID uid = new TransactionUID(Long.parseLong(target));
return getTransactionInfo(uid);
}
} else if (arg.equals("pool")) {
if (target == null) {
logger.log(Logger.INFO, "XXX - target of null " + "not implemented for " + arg);
} else {
return getThreadPoolInfo(target);
}
} else if (arg.equals("threads")) {
return SupportUtil.getAllStackTracesAsMap();
} else if (arg.equals("cls")) {
return getClusterInfo();
} else if (arg.equals("bkr")) {
return getBrokerInfo();
} else if (arg.equals("pkt")) {
String full = p.getProperty("full");
boolean fullDump = false;
if (full != null && full.equalsIgnoreCase("True")) {
fullDump = true;
}
return getPktInfo(target, targetType, fullDump);
}
logger.log(Logger.INFO, "Unknown dump arg " + arg);
return null;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class RollbackCommitHandler method handle.
/**
* Handle the incomming administration message.
*
* @param con The Connection the message came in on.
* @param cmd_msg The administration message
* @param cmd_props The properties from the administration message
*/
@Override
public boolean handle(IMQConnection con, Packet cmd_msg, Hashtable cmd_props) {
if (DEBUG) {
logger.log(Logger.DEBUG, this.getClass().getName() + ": " + "Rollback/Commit transaction " + cmd_props);
}
// Get the admin request message type
int requestType = ((Integer) cmd_props.get(MessageType.JMQ_MESSAGE_TYPE)).intValue();
int status = Status.OK;
String errMsg = null;
TransactionUID tid = null;
TransactionState ts = null;
TransactionHandler thandler = null;
// Get the packet handler that handles transaction packets
if (parent.adminPktRtr != null) {
thandler = (TransactionHandler) parent.adminPktRtr.getHandler(PacketType.ROLLBACK_TRANSACTION);
}
Long id = (Long) cmd_props.get(MessageType.JMQ_TRANSACTION_ID);
// only applies to rollback request
Boolean v = (Boolean) cmd_props.get(MessageType.JMQ_PROCESS_ACTIVE_CONSUMERS);
boolean processActiveConsumers = (v != null && v.booleanValue());
HAMonitorService hamonitor = Globals.getHAMonitorService();
if (hamonitor != null && hamonitor.inTakeover()) {
status = Status.ERROR;
errMsg = rb.getString(rb.E_CANNOT_PROCEED_TAKEOVER_IN_PROCESS);
logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
}
if (id != null) {
tid = new TransactionUID(id.longValue());
} else {
status = Status.BAD_REQUEST;
}
if (status == Status.OK) {
TransactionList[] tls = DL.getTransactionList(null);
TransactionList tl = null;
for (int i = 0; i < tls.length; i++) {
tl = tls[i];
ts = tl.retrieveState(tid);
if (ts == null) {
continue;
}
break;
}
if (ts == null) {
// Specified transaction did not exist
status = Status.NOT_FOUND;
errMsg = rb.getString(rb.E_NO_SUCH_TRANSACTION, tid);
} else if (requestType == MessageType.COMMIT_TRANSACTION && ts.getState() != TransactionState.PREPARED) {
status = Status.PRECONDITION_FAILED;
errMsg = rb.getString(rb.E_TRANSACTION_NOT_PREPARED, tid);
} else if (requestType == MessageType.ROLLBACK_TRANSACTION && (ts.getState() < TransactionState.STARTED || ts.getState() > TransactionState.PREPARED)) {
status = Status.PRECONDITION_FAILED;
errMsg = rb.getString(rb.E_INVALID_TXN_STATE_FOR_ROLLBACK, tid);
} else {
JMQXid xid = tl.UIDToXid(tid);
if (xid == null && (!(Globals.getHAEnabled() && ts.getState() == TransactionState.PREPARED))) {
/*
* Need to pick the right error message: If (action is ROLLBACK and state is one of {STARTED, FAILED, INCOMPLETE,
* COMPLETE}) "Rollback of non-XA transaction 123456789 in non-PREPARED state is not supported." else
* "Could not find Xid for 123456789"
*/
if (requestType == MessageType.ROLLBACK_TRANSACTION && (ts.getState() >= TransactionState.STARTED && ts.getState() < TransactionState.PREPARED)) {
errMsg = rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Rollback of non-XA transaction " + tid + " in non-PREPARED state is not supported.");
} else {
errMsg = rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not find Xid for " + tid);
}
status = Status.ERROR;
} else if (thandler == null) {
errMsg = rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not locate TransactionHandler");
status = Status.ERROR;
} else {
if (requestType == MessageType.ROLLBACK_TRANSACTION) {
if (DEBUG) {
logger.log(Logger.DEBUG, "Rolling back " + tid + " in state " + ts);
}
try {
if (processActiveConsumers) {
logger.log(logger.INFO, rb.getKString(rb.I_ADMIN_REDELIVER_MSGS_ON_TXN_ROLLBACK, tid));
try {
thandler.redeliverUnacked(tl, tid, true, true, true, -1, false);
} catch (Exception e) {
logger.logStack(logger.WARNING, rb.getKString(rb.X_ADMIN_REDELIVER_MSG_ON_TXN_ROLLBACK, tid, e.getMessage()), e);
}
}
thandler.doRollback(tl, tid, xid, null, ts, null, con, RollbackReason.ADMIN);
} catch (BrokerException e) {
status = Status.ERROR;
errMsg = e.getMessage();
}
} else if (requestType == MessageType.COMMIT_TRANSACTION) {
if (DEBUG) {
logger.log(Logger.DEBUG, "Committing " + tid + " in state " + ts);
}
try {
thandler.doCommit(tl, tid, xid, Integer.valueOf(XAResource.TMNOFLAGS), ts, null, false, con, null);
} catch (BrokerException e) {
status = Status.ERROR;
errMsg = e.getMessage();
}
} else {
// Should never happen.
return super.handle(con, cmd_msg, cmd_props);
}
}
}
}
sendReply(con, cmd_msg, requestType + 1, status, errMsg);
return true;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class BrokerConsumers method removeConsumer.
public void removeConsumer(com.sun.messaging.jmq.jmsserver.core.ConsumerUID uid, Map<TransactionUID, LinkedHashMap<SysMessageID, Integer>> pendingMsgs, boolean cleanup) throws BrokerException {
if (getDEBUG()) {
logger.log(logger.INFO, "BrokerConsumers.removeConsumer(" + uid + ", " + pendingMsgs + ", " + cleanup + ")");
}
Consumer c = null;
synchronized (removeConsumerLock) {
c = (Consumer) consumers.remove(uid);
}
if (c == null && !cleanup) {
return;
}
Destination d = null;
if (c != null) {
c.pause("MultiBroker - removing consumer");
// remove it from the destination
Destination[] ds = DL.getDestination(null, c.getDestinationUID());
// PART
d = ds[0];
// quit listening for busy events
Object listener = listeners.remove(uid);
if (listener != null) {
c.removeEventListener(listener);
}
// remove it from the active list
activeConsumers.remove(c);
}
Set destroySet = new LinkedHashSet();
LinkedHashSet openacks = new LinkedHashSet();
Map<PartitionedStore, LinkedHashSet> openmsgmp = new LinkedHashMap<>();
Map<TransactionUID, Set<AckEntry>> mypending = new LinkedHashMap<>();
boolean haspendingtxn = false;
// we sent the messages directly and must explicitly ack
synchronized (deliveredMessages) {
if (c != null) {
cleanupList.put(uid, c.getParentList());
}
Map cparentmp = (Map) cleanupList.get(uid);
if (getDEBUG()) {
logger.log(logger.INFO, "BrokerConsumers.removeConsumer:" + uid + ", pending=" + pendingMsgs + ", cleanup=" + cleanup + ", cparentmp=" + cparentmp);
}
Iterator itr = deliveredMessages.values().iterator();
while (itr.hasNext()) {
AckEntry e = (AckEntry) itr.next();
if (!e.getConsumerUID().equals(uid)) {
continue;
}
if (pendingMsgs != null) {
Iterator<Map.Entry<TransactionUID, LinkedHashMap<SysMessageID, Integer>>> itr1 = pendingMsgs.entrySet().iterator();
Map.Entry<TransactionUID, LinkedHashMap<SysMessageID, Integer>> pair = null;
TransactionUID tid = null;
LinkedHashMap<SysMessageID, Integer> sysiddcts = null;
Set<AckEntry> ackentries = null;
boolean found = false;
Integer deliverCnt = null;
while (itr1.hasNext()) {
pair = itr1.next();
tid = pair.getKey();
sysiddcts = pair.getValue();
deliverCnt = sysiddcts.get(e.getSysMessageID());
if (deliverCnt != null) {
if (tid != null && tid.longValue() == 0L) {
updateConsumed(e, deliverCnt, false);
continue;
}
if (cleanup || e.getTUID() != null) {
updateConsumed(e, deliverCnt, false);
break;
}
found = true;
ackentries = mypending.get(tid);
if (ackentries == null) {
ackentries = new LinkedHashSet();
mypending.put(tid, ackentries);
}
if (tid != null && !haspendingtxn) {
haspendingtxn = true;
}
ackentries.add(e);
updateConsumed(e, deliverCnt, false);
break;
}
}
if (found) {
continue;
}
}
if (e.getTUID() != null) {
continue;
}
if (getDEBUG()) {
logger.log(logger.DEBUG, "BrokerConsumers.removeConsumer:" + uid + ", remove AckEntry=" + e + ", c=" + c);
}
itr.remove();
if (cleanup) {
updateConsumed(e, Integer.valueOf(1), true);
}
if (c != null) {
if (c.isFalconRemote()) {
e.acknowledged(false);
} else {
PacketReference ref = e.getReference();
if (ref != null) {
ref.removeInDelivery(e.getStoredConsumerUID());
destroySet.add(ref);
}
}
continue;
}
PacketReference ref = e.getReference();
if (ref != null) {
ref.removeInDelivery(e.getStoredConsumerUID());
}
openacks.add(e);
}
itr = openacks.iterator();
while (itr.hasNext()) {
AckEntry e = (AckEntry) itr.next();
if (cparentmp == null || cparentmp.size() == 0) {
e.acknowledged(false);
} else {
PacketReference ref = e.getReference();
if (ref != null) {
PartitionedStore ps = null;
if (!ref.getDestinationUID().isQueue()) {
ps = new NoPersistPartitionedStoreImpl(e.getStoredConsumerUID());
} else {
ps = ref.getPartitionedStore();
}
LinkedHashSet set = openmsgmp.get(ps);
if (set == null) {
set = new LinkedHashSet();
openmsgmp.put(ps, set);
}
set.add(ref);
}
}
}
if (cparentmp != null && cparentmp.size() > 0 && openmsgmp.size() > 0) {
itr = openmsgmp.entrySet().iterator();
PartitionedStore ps = null;
Prioritized pl = null;
Map.Entry pair = null;
while (itr.hasNext()) {
pair = (Map.Entry) itr.next();
ps = (PartitionedStore) pair.getKey();
pl = (Prioritized) cparentmp.get(ps);
if (pl != null) {
pl.addAllOrdered((Set) pair.getValue());
} else {
logger.log(logger.WARNING, "Message(s) " + cparentmp.get(ps) + "[" + ps + "] parentlist not found on removing consumer " + uid);
}
}
}
if (cleanup || pendingMsgs == null) {
cleanupList.remove(uid);
pendingConsumerUIDs.remove(uid);
} else if (mypending.size() > 0) {
pendingConsumerUIDs.put(uid, mypending);
}
}
if (c != null) {
c.destroyConsumer(destroySet, false, false);
if (d != null) {
d.removeConsumer(uid, false);
}
}
List<Set<AckEntry>> l = null;
synchronized (pendingConsumerUIDs) {
l = new ArrayList<>(mypending.values());
}
Set<AckEntry> entries = null;
Iterator<Set<AckEntry>> itr = l.iterator();
while (itr.hasNext()) {
entries = itr.next();
AckEntry entry = null;
Iterator<AckEntry> itr1 = entries.iterator();
while (itr1.hasNext()) {
entry = itr1.next();
entry.pendingStarted();
}
}
if (haspendingtxn) {
notifyPendingCheckTimer();
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class BrokerConsumers method acknowledgeMessageFromRemote2P.
public void acknowledgeMessageFromRemote2P(int ackType, SysMessageID[] sysids, com.sun.messaging.jmq.jmsserver.core.ConsumerUID[] cuids, Map optionalProps, Long txnID, com.sun.messaging.jmq.jmsserver.core.BrokerAddress txnHomeBroker) throws BrokerException {
if (txnID == null) {
throw new BrokerException("Internal Error: call with null txnID");
}
// handle 2-phase remote ack
TransactionUID tid = new TransactionUID(txnID.longValue());
if (ackType == ClusterBroadcast.MSG_PREPARE) {
PartitionedStore refpstore = null;
TransactionAcknowledgement ta = null;
ArrayList<TransactionAcknowledgement> tltas = null;
TransactionAcknowledgement[] tas = null;
HashMap<TransactionList, ArrayList<TransactionAcknowledgement>> tltasmap = new HashMap<>();
TransactionList tl = null;
AckEntry entry = null, value = null;
StringBuilder dbuf = new StringBuilder();
AckEntryNotFoundException ae = null;
synchronized (deliveredMessages) {
for (int i = 0; i < sysids.length; i++) {
entry = new AckEntry(sysids[i], cuids[i], null);
value = (AckEntry) deliveredMessages.get(entry);
if (value == null) {
// XXX
String emsg = "[" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " not found, maybe rerouted";
if (ae == null) {
ae = new AckEntryNotFoundException(emsg);
}
ae.addAckEntry(sysids[i], cuids[i]);
logger.log(logger.WARNING, "[" + sysids[i] + ":" + cuids[i] + "] not found for preparing remote transaction " + tid + ", maybe rerouted");
continue;
}
if (value.getTUID() != null) {
String emsg = "[" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " has been rerouted";
if (ae == null) {
ae = new AckEntryNotFoundException(emsg);
}
ae.addAckEntry(sysids[i], cuids[i]);
logger.log(logger.WARNING, "[" + sysids[i] + ":" + cuids[i] + "] for preparing remote transaction " + tid + " conflict with transaction " + value.getTUID());
continue;
}
PacketReference ref = value.getReference();
if (ref == null) {
deliveredMessages.remove(entry);
String emsg = "Unable to prepare [" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " because the message has been removed";
if (ae == null) {
ae = new AckEntryNotFoundException(emsg);
}
ae.addAckEntry(sysids[i], cuids[i]);
logger.log(logger.WARNING, emsg);
continue;
}
com.sun.messaging.jmq.jmsserver.core.ConsumerUID scuid = value.getStoredConsumerUID();
ta = new TransactionAcknowledgement(sysids[i], cuids[i], scuid);
if (!scuid.shouldStore() || !ref.isPersistent()) {
ta.setShouldStore(false);
}
if (!Globals.getDestinationList().isPartitionMode()) {
TransactionList[] tls = DL.getTransactionList(Globals.getStore().getPrimaryPartition());
tl = tls[0];
} else {
refpstore = ref.getPartitionedStore();
TransactionList[] tls = Globals.getDestinationList().getTransactionList(refpstore);
tl = tls[0];
if (tl == null) {
deliveredMessages.remove(entry);
String emsg = "Unable to prepare [" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " because transaction list for partition " + refpstore + " not found";
if (ae == null) {
ae = new AckEntryNotFoundException(emsg);
}
ae.addAckEntry(sysids[i], cuids[i]);
logger.log(logger.WARNING, emsg);
continue;
}
}
tltas = tltasmap.get(tl);
if (tltas == null) {
tltas = new ArrayList<>();
tltasmap.put(tl, tltas);
}
tltas.add(ta);
if (getDEBUG()) {
dbuf.append("\n\t[" + ta + "]" + tl);
}
}
if (ae != null) {
throw ae;
}
Iterator<Map.Entry<TransactionList, ArrayList<TransactionAcknowledgement>>> itr = tltasmap.entrySet().iterator();
Map.Entry<TransactionList, ArrayList<TransactionAcknowledgement>> pair = null;
while (itr.hasNext()) {
pair = itr.next();
tl = pair.getKey();
tltas = pair.getValue();
tas = tltas.toArray(new TransactionAcknowledgement[tltas.size()]);
TransactionState ts = new TransactionState(AutoRollbackType.NOT_PREPARED, 0L, true);
ts.setState(TransactionState.PREPARED);
if (getDEBUG()) {
logger.log(logger.INFO, "Preparing remote transaction " + tid + " for [" + tltas + "]" + tl + " from " + txnHomeBroker);
}
tl.logRemoteTransaction(tid, ts, tas, txnHomeBroker, false, true, true);
}
for (int i = 0; i < sysids.length; i++) {
entry = new AckEntry(sysids[i], cuids[i], null);
value = (AckEntry) deliveredMessages.get(entry);
value.setTUID(tid);
}
}
Iterator<TransactionList> itr = tltasmap.keySet().iterator();
while (itr.hasNext()) {
tl = itr.next();
tl.pendingStartedForRemotePreparedTransaction(tid);
}
notifyPendingCheckTimer();
if (getDEBUG()) {
logger.log(logger.INFO, "Prepared remote transaction " + tid + " from " + txnHomeBroker + dbuf.toString());
}
return;
}
if (ackType == ClusterBroadcast.MSG_ROLLEDBACK) {
if (getDEBUG()) {
logger.log(logger.INFO, "Rolling back remote transaction " + tid + " from " + txnHomeBroker);
}
List<Object[]> list = TransactionList.getTransListsAndRemoteTranStates(tid);
if (list == null) {
if (getDEBUG()) {
logger.log(logger.INFO, "Rolling back non-prepared remote transaction " + tid + " from " + txnHomeBroker);
}
List<AckEntry> entries = null;
synchronized (deliveredMessages) {
entries = getPendingConsumerUID(tid);
Iterator<AckEntry> itr = entries.iterator();
AckEntry e = null;
while (itr.hasNext()) {
e = itr.next();
if (deliveredMessages.get(e) == null) {
itr.remove();
continue;
}
if (consumers.get(e.getConsumerUID()) != null) {
itr.remove();
continue;
}
}
if (e != null) {
deliveredMessages.remove(e);
cleanupPendingConsumerUID(e.getConsumerUID(), e.getSysMessageID());
}
}
if (entries.size() == 0) {
logger.log(logger.INFO, br.getKString(br.I_ROLLBACK_REMOTE_TXN_NOT_FOUND, tid, txnHomeBroker));
return;
}
Iterator<AckEntry> itr = entries.iterator();
while (itr.hasNext()) {
AckEntry e = itr.next();
SysMessageID sysid = e.getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = e.getConsumerUID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = e.getStoredConsumerUID();
if (suid == null) {
suid = cuid;
}
// PART
PacketReference ref = DL.get(null, sysid);
if (ref == null) {
if (getDEBUG()) {
logger.log(logger.INFO, "[" + sysid + ":" + cuid + "] reference not found in rolling back remote non-prepared transaction " + tid);
}
continue;
}
ref.removeInDelivery(suid);
ref.getDestination().forwardOrphanMessage(ref, suid);
}
return;
}
// if list == null
TransactionList tl = null;
Object[] oo = null;
for (int li = 0; li < list.size(); li++) {
oo = list.get(li);
tl = (TransactionList) oo[0];
if (!tl.updateRemoteTransactionState(tid, TransactionState.ROLLEDBACK, false, false, true)) {
return;
}
if (tl.getRecoveryRemoteTransactionAcks(tid) != null) {
rollbackRecoveryRemoteTransaction(tl, tid, txnHomeBroker);
}
RemoteTransactionAckEntry tae = tl.getRemoteTransactionAcks(tid);
if (tae == null) {
logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_NO_NONRECOVERY_TXNACK_TO_ROLLBACK, tid));
} else if (tae.processed()) {
logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_NO_MORE_TXNACK_TO_ROLLBACK, tid));
} else if (!tae.isLocalRemote()) {
TransactionAcknowledgement[] tas = tae.getAcks();
Set s = new LinkedHashSet();
AckEntry entry = null, value = null;
for (int i = 0; i < tas.length; i++) {
SysMessageID sysid = tas[i].getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID uid = tas[i].getConsumerUID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = tas[i].getStoredConsumerUID();
if (suid == null) {
suid = uid;
}
synchronized (deliveredMessages) {
entry = new AckEntry(sysid, uid, null);
value = (AckEntry) deliveredMessages.get(entry);
if (value == null) {
if (getDEBUG()) {
logger.log(logger.INFO, "[" + sysid + ":" + uid + "] not found in rolling back remote transaction " + tid);
}
continue;
}
if (value.getTUID() == null || !value.getTUID().equals(tid)) {
if (getDEBUG()) {
logger.log(logger.INFO, "[" + sysid + ":" + uid + "] with TUID=" + value.getTUID() + ", in confict for rolling back remote transaction " + tid);
}
continue;
}
if (consumers.get(uid) == null) {
deliveredMessages.remove(entry);
cleanupPendingConsumerUID(uid, sysid);
s.add(tas[i]);
} else {
value.setTUID(null);
}
}
}
Iterator itr = s.iterator();
while (itr.hasNext()) {
TransactionAcknowledgement ta = (TransactionAcknowledgement) itr.next();
SysMessageID sysid = ta.getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = ta.getConsumerUID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = ta.getStoredConsumerUID();
if (suid == null) {
suid = cuid;
}
// PART
PacketReference ref = DL.get(null, sysid);
if (ref == null) {
if (getDEBUG()) {
logger.log(logger.INFO, "[" + sysid + ":" + cuid + "] reference not found in rolling back remote transaction " + tid);
}
continue;
}
ref.removeInDelivery(suid);
ref.getDestination().forwardOrphanMessage(ref, suid);
}
}
try {
tl.removeRemoteTransactionAck(tid);
} catch (Exception e) {
logger.log(logger.WARNING, "Unable to remove transaction ack for rolledback transaction " + tid + ": " + e.getMessage());
}
try {
tl.removeRemoteTransactionID(tid, true);
} catch (Exception e) {
logger.log(logger.WARNING, "Unable to remove rolledback remote transaction " + tid + ": " + e.getMessage());
}
}
// for
return;
}
int cLogRecordCount = 0;
ArrayList cLogDstList = null;
ArrayList cLogMsgList = null;
ArrayList cLogIntList = null;
if (ackType == ClusterBroadcast.MSG_ACKNOWLEDGED) {
if (getDEBUG()) {
logger.log(logger.INFO, "Committing remote transaction " + tid + " from " + txnHomeBroker);
}
List<Object[]> list = TransactionList.getTransListsAndRemoteTranStates(tid);
if (list == null) {
throw new BrokerException("Committing remote transaction " + tid + " not found", Status.NOT_FOUND);
}
TransactionList tl = null;
Object[] oo = null;
for (int li = 0; li < list.size(); li++) {
oo = list.get(li);
tl = (TransactionList) oo[0];
if (!tl.updateRemoteTransactionState(tid, TransactionState.COMMITTED, (sysids == null), true, true)) {
if (getDEBUG()) {
logger.log(logger.INFO, "Remote transaction " + tid + " already committed, from " + txnHomeBroker);
}
continue;
}
boolean done = true;
if (tl.getRecoveryRemoteTransactionAcks(tid) != null) {
done = commitRecoveryRemoteTransaction(tl, tid, txnHomeBroker);
}
RemoteTransactionAckEntry tae = tl.getRemoteTransactionAcks(tid);
if (tae == null) {
logger.log(logger.INFO, "No non-recovery transaction acks to process for committing remote transaction " + tid);
} else if (tae.processed()) {
logger.log(logger.INFO, "No more transaction acks to process for committing remote transaction " + tid);
} else if (!tae.isLocalRemote()) {
boolean found = false;
TransactionAcknowledgement[] tas = tae.getAcks();
for (int i = 0; i < tas.length; i++) {
SysMessageID sysid = tas[i].getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = tas[i].getConsumerUID();
if (sysids != null && !found) {
if (sysid.equals(sysids[0]) && cuid.equals(cuids[0])) {
found = true;
}
}
String dstName = null;
if (Globals.txnLogEnabled()) {
if (cLogDstList == null) {
cLogDstList = new ArrayList();
cLogMsgList = new ArrayList();
cLogIntList = new ArrayList();
}
PacketReference ref = DL.get(null, sysid);
if (ref != null && !ref.isDestroyed() && !ref.isInvalid()) {
Destination[] ds = DL.getDestination(ref.getPartitionedStore(), ref.getDestinationUID());
Destination dst = ds[0];
dstName = dst.getUniqueName();
}
}
if (acknowledgeMessageFromRemote(ackType, sysid, cuid, optionalProps)) {
if (dstName != null) {
// keep track for consumer txn log
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = tas[i].getStoredConsumerUID();
if (suid == null) {
suid = cuid;
}
cLogRecordCount++;
cLogDstList.add(dstName);
cLogMsgList.add(sysid);
cLogIntList.add(suid);
}
} else {
done = false;
}
}
// notify that message acks have been written to store
if (Globals.isNewTxnLogEnabled()) {
if (DL.isPartitionMode()) {
throw new BrokerException("Partition mode not supported if newTxnLog enabled");
}
((TxnLoggingStore) Globals.getStore().getPrimaryPartition()).loggedCommitWrittenToMessageStore(tid, BaseTransaction.REMOTE_TRANSACTION_TYPE);
}
if (sysids != null && !found) {
logger.log(logger.ERROR, "Internal Error: [" + sysids[0] + ":" + cuids[0] + "] not found in remote transaction " + tid);
done = false;
}
}
// tae != null
if (done) {
try {
tl.removeRemoteTransactionAck(tid);
} catch (Exception e) {
logger.logStack(logger.WARNING, "Unable to remove transaction ack for committed remote transaction " + tid, e);
}
try {
tl.removeRemoteTransactionID(tid, true);
} catch (Exception e) {
logger.logStack(logger.WARNING, "Unable to remove committed remote transaction " + tid, e);
}
} else if (Globals.getHAEnabled()) {
throw new BrokerException("Remote transaction processing incomplete, TUID=" + tid);
}
}
// log to txn log if enabled
try {
if (Globals.txnLogEnabled() && (cLogRecordCount > 0)) {
// Log all acks for consuming txn
ByteArrayOutputStream bos = new ByteArrayOutputStream((cLogRecordCount * (32 + SysMessageID.ID_SIZE + 8)) + 12);
DataOutputStream dos = new DataOutputStream(bos);
// Transaction ID (8 bytes)
dos.writeLong(tid.longValue());
// Number of acks (4 bytes)
dos.writeInt(cLogRecordCount);
for (int i = 0; i < cLogRecordCount; i++) {
String dst = (String) cLogDstList.get(i);
// Destination
dos.writeUTF(dst);
SysMessageID sysid = (SysMessageID) cLogMsgList.get(i);
// SysMessageID
sysid.writeID(dos);
long intid = ((com.sun.messaging.jmq.jmsserver.core.ConsumerUID) cLogIntList.get(i)).longValue();
// ConsumerUID
dos.writeLong(intid);
}
dos.close();
bos.close();
// PART
((TxnLoggingStore) Globals.getStore().getPrimaryPartition()).logTxn(TransactionLogType.CONSUME_TRANSACTION, bos.toByteArray());
}
} catch (IOException ex) {
logger.logStack(Logger.ERROR, Globals.getBrokerResources().E_INTERNAL_BROKER_ERROR, "Got exception while writing to transaction log", ex);
throw new BrokerException("Internal Error: Got exception while writing to transaction log", ex);
}
return;
}
throw new BrokerException("acknowledgeMessageFromRemotePriv:Unexpected ack type:" + ackType);
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class ClusterConsumerInfo method getPendingMessages.
/**
* @return null if empty
*/
public Map<TransactionUID, LinkedHashMap<SysMessageID, Integer>> getPendingMessages() {
assert (pkt != null);
LinkedHashMap<TransactionUID, LinkedHashMap<SysMessageID, Integer>> m = new LinkedHashMap<>();
String key = null, val = null;
String tidstr = null;
TransactionUID tid = null;
LinkedHashMap<SysMessageID, Integer> sysiddcnts = null;
Iterator itr = pkt.propsKeySet().iterator();
while (itr.hasNext()) {
key = (String) itr.next();
tid = null;
if (key.startsWith(PROP_PREFIX_PENDING_TID_MID_DCT)) {
tidstr = key.substring(PROP_PREFIX_PENDING_TID_MID_DCT.length());
if (tidstr.length() > 0) {
tid = new TransactionUID(Long.parseLong(tidstr));
}
val = (String) pkt.getProp(key);
if (val == null || val.length() == 0) {
continue;
}
sysiddcnts = parsePendingMsgs(val);
if (m.get(tid) != null) {
throw new RuntimeException("Unexpected " + PROP_PREFIX_PENDING_TID_MID_DCT + " content: duplicated entries(" + m.get(tid) + ", " + sysiddcnts + ") for " + tid + ", " + m);
}
m.put(tid, sysiddcnts);
}
}
if (m.size() > 0) {
return m;
}
// check 4.5 patch protocol
key = null;
val = null;
tidstr = null;
tid = null;
sysiddcnts = null;
itr = pkt.propsKeySet().iterator();
while (itr.hasNext()) {
key = (String) itr.next();
tid = null;
if (key.startsWith(PROP_PREFIX_PENDING_TID)) {
tidstr = key.substring(PROP_PREFIX_PENDING_TID.length());
if (tidstr.length() > 0) {
tid = new TransactionUID(Long.parseLong(tidstr));
}
val = (String) pkt.getProp(key);
if (val == null || val.length() == 0) {
continue;
}
sysiddcnts = parsePendingMsgs(val);
if (m.get(tid) != null) {
throw new RuntimeException("Unexpected " + PROP_PREFIX_PENDING_TID + " content: duplicated entries(" + m.get(tid) + ", " + sysiddcnts + ") for " + tid + ", " + m);
}
m.put(tid, sysiddcnts);
}
}
if (m.size() > 0) {
return m;
}
// check 4.5 protocol
val = (String) pkt.getProp(PROP_PENDING_MESSAGES);
if (val == null || val.length() == 0) {
return null;
}
sysiddcnts = parsePendingMsgs(val);
m.put(null, sysiddcnts);
return m;
}
Aggregations