use of com.sun.messaging.jmq.jmsserver.data.TransactionList in project openmq by eclipse-ee4j.
the class RaptorProtocol method sendClusterTransactionInfo.
// Caller must ensure this is the transaction home broker
private void sendClusterTransactionInfo(TransactionUID tid, BrokerAddress to, Long xid) {
TransactionList tl = null;
TransactionState ts = null;
Object[] oo = TransactionList.getTransListAndState(tid, null, true, false);
if (oo != null) {
tl = (TransactionList) oo[0];
ts = (TransactionState) oo[1];
}
BrokerAddress[] parties = null;
BrokerAddress[] waitfor = null;
TransactionBroker[] brokers = null;
if (ts != null) {
try {
brokers = tl.getClusterTransactionBrokers(tid);
} catch (Exception e) {
logger.log(logger.WARNING, "Can't retrieve cluster transaction brokers:" + e.getMessage());
}
if (brokers == null) {
logger.log(logger.WARNING, "No cluster transaction brokers information for TID=" + tid);
} else {
parties = new BrokerAddress[brokers.length];
ArrayList waits = new ArrayList();
for (int i = 0; i < brokers.length; i++) {
parties[i] = brokers[i].getBrokerAddress();
if (!brokers[i].isCompleted()) {
waits.add(brokers[i].getBrokerAddress());
}
}
if (waits.size() > 0) {
waitfor = (BrokerAddress[]) waits.toArray(new BrokerAddress[waits.size()]);
}
}
}
UID tranpid = null;
if (tl != null && Globals.getDestinationList().isPartitionMode()) {
tranpid = tl.getPartitionedStore().getPartitionID();
}
ClusterTxnInfoInfo ii = ClusterTxnInfoInfo.newInstance(Long.valueOf(tid.longValue()), (ts == null ? TransactionState.NULL : ts.getState()), parties, waitfor, Globals.getMyAddress(), true, tranpid, c, xid);
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_SEND_CLUSTER_TXN_INFO, to.toString(), ii.toString()));
}
try {
c.unicast(to, ii.getGPacket());
} catch (Exception e) {
String[] args = { ii.toString(), to.toString(), e.getMessage() };
logger.log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_SEND_CLUSTER_TXN_INFO_FAIL, args));
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionList 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.TransactionList in project openmq by eclipse-ee4j.
the class AckHandler method handle.
/**
* Method to handle Acknowledgement messages
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
int size = msg.getMessageBodySize();
int ackcount = size / ACK_BLOCK_SIZE;
int mod = size % ACK_BLOCK_SIZE;
int status = Status.OK;
String reason = null;
if (DEBUG) {
logger.log(Logger.INFO, "AckHandler: processing packet " + msg.toString() + ", on connection " + con);
}
PartitionedStore pstore = con.getPartitionedStore();
TransactionList[] tls = DL.getTransactionList(pstore);
TransactionList translist = tls[0];
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
// for fault injection
ackProcessCnt++;
} else {
ackProcessCnt = 0;
}
if (ackcount == 0) {
logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: Empty Ack Message " + msg.getSysMessageID().toString());
reason = "Empty ack message";
status = Status.ERROR;
}
if (mod != 0) {
logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: Invalid Ack Message Size " + size + " for message " + msg.getSysMessageID().toString());
reason = "corrupted ack message";
status = Status.ERROR;
}
TransactionUID tid = null;
if (msg.getTransactionID() != 0) {
// HANDLE TRANSACTION
try {
tid = new TransactionUID(msg.getTransactionID());
} catch (Exception ex) {
logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: can not create transactionID for " + msg, ex);
status = Status.ERROR;
}
}
ArrayList<PacketReference> cleanList = new ArrayList<>();
try {
// cleanList
Hashtable props = null;
Throwable deadthr = null;
String deadcmt = null;
int deadrs = DEAD_REASON_UNDELIVERABLE;
int deliverCnt = 0;
boolean deliverCntUpdateOnly = false;
int ackType = ACKNOWLEDGE_REQUEST;
boolean JMQValidate = false;
try {
props = msg.getProperties();
Integer iackType = (props == null ? null : (Integer) props.get("JMQAckType"));
ackType = (iackType == null ? ACKNOWLEDGE_REQUEST : iackType.intValue());
Boolean validateFlag = (props == null ? null : (Boolean) props.get("JMQValidate"));
JMQValidate = validateFlag != null && validateFlag.booleanValue();
checkRequestType(ackType);
if (ackType == DEAD_REQUEST) {
deadthr = (Throwable) props.get("JMQException");
deadcmt = (String) props.get("JMQComment");
Integer val = (Integer) props.get("JMQDeadReason");
if (val != null) {
deadrs = val.intValue();
}
}
if (props != null) {
if (ackType == DEAD_REQUEST || ackType == UNDELIVERABLE_REQUEST || tid != null) {
// Client runtime retry count
Integer val = (Integer) props.get("JMSXDeliveryCount");
deliverCnt = (val == null ? -1 : val.intValue());
if (tid == null) {
if (deliverCnt >= 0) {
deliverCnt += 1;
}
}
}
if (ackType == UNDELIVERABLE_REQUEST) {
Boolean val = (Boolean) props.get("JMSXDeliveryCountUpdateOnly");
deliverCntUpdateOnly = val != null && val.booleanValue();
}
}
} catch (Exception ex) {
// assume not dead
logger.logStack(Logger.INFO, "Internal Error: bad protocol", ex);
ackType = ACKNOWLEDGE_REQUEST;
}
// OK .. handle Fault Injection
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqAckCount", Integer.valueOf(ackProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(tid != null));
fi.checkFaultAndExit(FaultInjection.FAULT_ACK_MSG_1, m, 2, false);
}
boolean remoteStatus = false;
StringBuilder remoteConsumerUIDs = null;
SysMessageID[] ids = null;
ConsumerUID[] cids = null;
try {
if (status == Status.OK) {
DataInputStream is = new DataInputStream(msg.getMessageBodyStream());
// pull out the messages into two lists
ids = new SysMessageID[ackcount];
cids = new ConsumerUID[ackcount];
for (int i = 0; i < ackcount; i++) {
long newid = is.readLong();
cids[i] = new ConsumerUID(newid);
cids[i].setConnectionUID(con.getConnectionUID());
ids[i] = new SysMessageID();
ids[i].readID(is);
}
if (JMQValidate) {
if (ackType == DEAD_REQUEST || ackType == UNDELIVERABLE_REQUEST) {
status = Status.BAD_REQUEST;
reason = "Can not use JMQValidate with ackType of " + ackType;
} else if (tid == null) {
status = Status.BAD_REQUEST;
reason = "Can not use JMQValidate with no tid ";
} else if (!validateMessages(translist, tid, ids, cids)) {
status = Status.NOT_FOUND;
reason = "Acknowledgement not processed";
}
} else if (ackType == DEAD_REQUEST) {
handleDeadMsgs(con, ids, cids, deadrs, deadthr, deadcmt, deliverCnt, cleanList);
} else if (ackType == UNDELIVERABLE_REQUEST) {
handleUndeliverableMsgs(con, ids, cids, cleanList, deliverCnt, deliverCntUpdateOnly);
} else {
if (tid != null) {
handleTransaction(translist, con, tid, ids, cids, deliverCnt);
} else {
handleAcks(con, ids, cids, msg.getSendAcknowledge(), cleanList);
}
}
}
} catch (Throwable thr) {
status = Status.ERROR;
if (thr instanceof BrokerException) {
status = ((BrokerException) thr).getStatusCode();
remoteStatus = ((BrokerException) thr).isRemote();
if (remoteStatus && ids != null && cids != null) {
remoteConsumerUIDs = new StringBuilder();
remoteConsumerUIDs.append(((BrokerException) thr).getRemoteConsumerUIDs());
remoteConsumerUIDs.append(' ');
String cidstr = null;
ArrayList remoteConsumerUIDa = new ArrayList();
for (int i = 0; i < ids.length; i++) {
PacketReference ref = DL.get(pstore, ids[i]);
Consumer c = Consumer.getConsumer(cids[i]);
if (c == null) {
continue;
}
ConsumerUID sid = c.getStoredConsumerUID();
if (sid == null || sid.equals(cids[i])) {
continue;
}
BrokerAddress ba = (ref == null ? null : ref.getBrokerAddress());
BrokerAddress rba = (BrokerAddress) ((BrokerException) thr).getRemoteBrokerAddress();
if (ref != null && ba != null && rba != null && ba.equals(rba)) {
cidstr = String.valueOf(c.getConsumerUID().longValue());
if (!remoteConsumerUIDa.contains(cidstr)) {
remoteConsumerUIDa.add(cidstr);
remoteConsumerUIDs.append(cidstr);
remoteConsumerUIDs.append(' ');
}
}
}
}
}
reason = thr.getMessage();
if (status == Status.ERROR) {
// something went wrong
logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "-------------------------------------------" + "Internal Error: Invalid Acknowledge Packet processing\n" + " " + (msg.getSendAcknowledge() ? " notifying client\n" : " can not notify the client") + com.sun.messaging.jmq.io.PacketUtil.dumpPacket(msg) + "--------------------------------------------", thr);
}
}
// OK .. handle Fault Injection
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqAckCount", Integer.valueOf(ackProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(tid != null));
fi.checkFaultAndExit(FaultInjection.FAULT_ACK_MSG_2, m, 2, false);
}
// send the reply (if necessary)
if (msg.getSendAcknowledge()) {
Packet pkt = new Packet(con.useDirectBuffers());
pkt.setPacketType(PacketType.ACKNOWLEDGE_REPLY);
pkt.setConsumerID(msg.getConsumerID());
Hashtable hash = new Hashtable();
hash.put("JMQStatus", Integer.valueOf(status));
if (reason != null) {
hash.put("JMQReason", reason);
}
if (remoteStatus) {
hash.put("JMQRemote", Boolean.TRUE);
if (remoteConsumerUIDs != null) {
hash.put("JMQRemoteConsumerIDs", remoteConsumerUIDs.toString());
}
}
if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
hash.put("JMQReqID", msg.getSysMessageID().toString());
}
pkt.setProperties(hash);
con.sendControlMessage(pkt);
}
// OK .. handle Fault Injection
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqAckCount", Integer.valueOf(ackProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(tid != null));
fi.checkFaultAndExit(FaultInjection.FAULT_ACK_MSG_3, m, 2, false);
}
} finally {
// we dont need to clear the memory up until after we reply
cleanUp(cleanList);
}
return true;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionList in project openmq by eclipse-ee4j.
the class DataHandler method routeMessage.
public Set routeMessage(PartitionedStore storep, boolean transacted, PacketReference ref, boolean route, Destination d, List<MessageDeliveryTimeInfo> readylist) throws BrokerException, SelectorFormatException {
String reason = null;
int status = Status.OK;
Set s = null;
MessageDeliveryTimeInfo di = ref.getDeliveryTimeInfo();
// if transacted, just store, dont route
if (transacted) {
try {
TransactionList[] tls = DL.getTransactionList(storep);
TransactionList tl = tls[0];
tl.addMessage(ref);
} catch (Exception ex) {
String emsg = br.getKString(br.X_PROCESS_PRODUCED_MESSAGE_FAIL, ref + "[TID=" + ref.getTransactionID() + ", " + di + "]", ex.getMessage());
ref.destroy();
logger.logStack((BrokerStateHandler.isShuttingDown() ? Logger.DEBUG : Logger.WARNING), emsg, ex);
reason = emsg;
status = Status.ERROR;
throw new BrokerException(reason, status);
}
} else {
if (route) {
if (di != null && di.getOnTimerState() != null) {
d.routeNewMessageWithDeliveryDelay(ref);
readylist.add(di);
} else {
s = d.routeNewMessage(ref);
}
}
}
return s;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionList in project openmq by eclipse-ee4j.
the class QBrowseHandler method getQBrowseList.
public ArrayList getQBrowseList(Destination d, String selectorstr) throws BrokerException, SelectorFormatException {
Collection msgs = null;
if (selectorstr == null) {
msgs = d.getAll((Filter) null).values();
} else {
SelectorFilter f = new SelectorFilter(selectorstr);
Map m = d.getAll(f);
msgs = m.values();
}
// sort the messages
ArrayList sorted = new ArrayList(msgs);
Collections.sort(sorted, new RefCompare());
TransactionList[] tls = DL.getTransactionList(d.getPartitionedStore());
TransactionList tlist = tls[0];
// remove any expired messages or messages in open txn
Iterator itr = sorted.iterator();
while (itr.hasNext()) {
PacketReference p = (PacketReference) itr.next();
if (p.isExpired()) {
itr.remove();
}
if (!p.isDeliveryDue()) {
itr.remove();
}
if (p.getTransactionID() != null) {
// look up txn
TransactionState ts = tlist.retrieveState(p.getTransactionID());
if (ts != null && ts.getState() != TransactionState.COMMITTED) {
// open txn, remove
itr.remove();
}
}
// check in takeover processing
if (p.checkLock(false) == null) {
itr.remove();
}
}
ArrayList returnmsgs = new ArrayList();
itr = sorted.iterator();
while (itr.hasNext()) {
PacketReference p = (PacketReference) itr.next();
if (p == null) {
continue;
}
returnmsgs.add(p.getSysMessageID());
}
return returnmsgs;
}
Aggregations