use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class TransactionHandler method sortPreprocessRetrievedMessages.
private HashMap sortPreprocessRetrievedMessages(Map cmap, Map sToCmap, boolean processActiveConsumers, int maxRollbacks, boolean dmqOnMaxRollbacks, TransactionUID tid) throws BrokerException {
HashMap sendMap = new HashMap();
// loop through the transaction ack list
if (cmap != null && cmap.size() > 0) {
Iterator itr = cmap.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
SysMessageID sysid = (SysMessageID) entry.getKey();
// CANT just pull from connection
if (sysid == null) {
continue;
}
PacketReference ref = DL.get(null, sysid, false);
if (ref == null || ref.isDestroyed() || ref.isInvalid()) {
// already been deleted .. ignore
if (DEBUG) {
logger.log(logger.INFO, "redeliverUnacked:tid=" + tid + ": ref=" + ref + " already deleted");
}
continue;
}
if (ref.isOverrided()) {
continue;
}
// now get the interests and stick each message
// in a list specific to the consumer
// the list is automatically sorted
List interests = (List) entry.getValue();
for (int i = 0; i < interests.size(); i++) {
ConsumerUID intid = (ConsumerUID) interests.get(i);
ConsumerUID stored = (ConsumerUID) sToCmap.get(intid);
if (stored == null) {
stored = intid;
}
if (processActiveConsumers && !dmqOnMaxRollbacks) {
Consumer cs = Consumer.getConsumer(intid);
if (cs != null) {
if (!cs.addRollbackCnt(ref.getSysMessageID(), maxRollbacks)) {
Object[] args = { ref, cs, tid };
String emsg = br.getKString(br.X_MAX_ROLLBACKS_MSG_NO_ROLLBACK, args);
logger.log(logger.ERROR, emsg);
throw new MaxConsecutiveRollbackException(emsg);
}
}
}
SortedSet ss = (SortedSet) sendMap.get(intid);
if (ss == null) {
ss = new TreeSet(new RefCompare());
sendMap.put(intid, ss);
}
ref.removeInDelivery(stored);
ss.add(ref);
}
}
}
return sendMap;
}
use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class TransactionHandler method retrieveConsumedRemoteMessages.
private HashMap[] retrieveConsumedRemoteMessages(TransactionList translist, TransactionUID id, boolean checkOnly) throws BrokerException {
HashMap mcmap = translist.retrieveConsumedMessages(id);
HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "retrieveConsumedRemoteMessages(" + translist + ",TID=" + id + ") retrieveConsumedMessages: " + mcmap);
}
if (mcmap == null || mcmap.size() == 0) {
return null;
}
HashMap[] rets = new HashMap[2];
HashMap<BrokerAddress, ArrayList[]> bmmap = new HashMap<>();
HashMap<TransactionBroker, ArrayList<TransactionAcknowledgement>> tbmmap = new HashMap<>();
ArrayList[] bmcll = null;
ArrayList<TransactionAcknowledgement> tbmcl = null;
boolean hasRemote = false;
BrokerAddress myba = Globals.getMyAddress();
UID tranpid = translist.getPartitionedStore().getPartitionID();
UID refpid = null;
ConsumerUID cuid = null, scuid = null;
TransactionAcknowledgement ta = null;
Iterator<Map.Entry> itr = mcmap.entrySet().iterator();
Map.Entry pair = null;
while (itr.hasNext()) {
pair = itr.next();
SysMessageID sysid = (SysMessageID) pair.getKey();
if (sysid == null) {
continue;
}
PacketReference ref = DL.get(null, sysid, false);
if (checkRefRequeued(translist, id, ref, sysid)) {
BrokerException bex = new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_MAYBE_REROUTED, sysid) + ", TUID=" + id, Status.GONE);
bex.setRemote(true);
StringBuilder buf = new StringBuilder();
List interests = (List) pair.getValue();
for (int i = 0; i < interests.size(); i++) {
buf.append(String.valueOf(((ConsumerUID) interests.get(i)).longValue()));
buf.append(' ');
}
bex.setRemoteConsumerUIDs(buf.toString());
throw bex;
}
if (ref == null) {
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_REF_GONE, sysid) + ", TUID=" + id, Status.CONFLICT);
}
BrokerAddress ba = ref.getBrokerAddress();
if (ba == null) {
if (!DL.isPartitionMode()) {
ba = myba;
} else {
refpid = ref.getPartitionedStore().getPartitionID();
ba = (BrokerAddress) myba.clone();
ba.setStoreSessionUID(refpid);
if (!refpid.equals(tranpid)) {
hasRemote = true;
}
}
} else if (!hasRemote) {
hasRemote = true;
}
if (hasRemote && checkOnly) {
return rets;
}
TransactionBroker tba = new TransactionBroker(ba);
bmcll = bmmap.get(tba.getBrokerAddress());
tbmcl = tbmmap.get(tba);
if (bmcll == null) {
bmcll = new ArrayList[2];
bmcll[0] = new ArrayList();
bmcll[1] = new ArrayList();
bmmap.put(tba.getBrokerAddress(), bmcll);
}
if (tbmcl == null) {
tbmcl = new ArrayList<>();
tbmmap.put(tba, tbmcl);
}
List interests = (List) mcmap.get(sysid);
for (int i = 0; i < interests.size(); i++) {
cuid = (ConsumerUID) interests.get(i);
bmcll[0].add(sysid);
bmcll[1].add(cuid);
scuid = (ConsumerUID) sToCmap.get(cuid);
ta = new TransactionAcknowledgement(sysid, cuid, scuid);
if (!scuid.shouldStore() || !ref.isPersistent()) {
ta.setShouldStore(false);
}
tbmcl.add(ta);
}
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "retrieveConsumedRemoteMessages() for broker " + tba + ": " + Arrays.toString(bmcll) + ", " + tbmcl);
}
}
if (!hasRemote) {
return null;
}
rets[0] = bmmap;
rets[1] = tbmmap;
return rets;
}
use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class TransactionHandler method doRemotePrepare.
private ClusterTransaction doRemotePrepare(TransactionList translist, TransactionUID id, TransactionState nextState, TransactionWork txnWork) throws BrokerException {
if (nextState.getState() != TransactionState.PREPARED) {
throw new BrokerException("Unexpected state " + nextState + " for transactionID:" + id);
}
HashMap[] rets = retrieveConsumedRemoteMessages(translist, id, false);
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare(" + translist + ", " + id + "): retrievedConsumedRemoteMsgs:" + (rets == null ? "null" : rets[0] + ", " + rets[1]));
}
if (fi.FAULT_INJECTION) {
if (fi.checkFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5, null)) {
fi.unsetFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
throw new BrokerException(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
}
}
if (rets == null) {
return null;
}
if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
return null;
}
HashMap<BrokerAddress, ArrayList[]> bmmap = rets[0];
TransactionBroker[] tranbas = (TransactionBroker[]) rets[1].keySet().toArray(new TransactionBroker[rets[1].size()]);
BrokerAddress[] bas = bmmap.keySet().toArray(new BrokerAddress[bmmap.size()]);
boolean persist = true;
ClusterTransaction clusterTransaction = null;
if (Globals.isNewTxnLogEnabled()) {
// create a cluster transaction which will be logged
clusterTransaction = new ClusterTransaction(id, nextState, txnWork, tranbas);
translist.logClusterTransaction(id, nextState, tranbas, true, persist, clusterTransaction);
} else {
translist.logClusterTransaction(id, nextState, tranbas, true, persist);
}
if (DEBUG_CLUSTER_TXN) {
StringBuilder buf = new StringBuilder();
buf.append("Preparing transaction ").append(id).append(", brokers");
for (TransactionBroker tranba : tranbas) {
buf.append("\n\t").append(tranba);
}
logger.log(logger.INFO, buf.toString());
}
UID tranpid = null;
if (Globals.getDestinationList().isPartitionMode()) {
tranpid = translist.getPartitionedStore().getPartitionID();
ArrayList<TransactionAcknowledgement> mcl = null;
TransactionBroker tba = null;
UID tbapid = null;
TransactionAcknowledgement[] tas = null;
TransactionList tl = null;
for (int i = 0; i < tranbas.length; i++) {
tba = tranbas[i];
if (!tba.getBrokerAddress().equals(Globals.getMyAddress())) {
continue;
}
tbapid = tba.getBrokerAddress().getStoreSessionUID();
if (tbapid.equals(tranpid)) {
continue;
}
mcl = (ArrayList<TransactionAcknowledgement>) rets[1].get(tba);
tas = mcl.toArray(new TransactionAcknowledgement[mcl.size()]);
tl = TransactionList.getTransListByPartitionID(tbapid);
if (tl == null) {
throw new BrokerException("Can't prepare transaction " + id + " because " + "transaction list for partition " + tbapid + " not found");
}
BrokerAddress home = (BrokerAddress) Globals.getMyAddress().clone();
home.setStoreSessionUID(tranpid);
tl.logLocalRemoteTransaction(id, nextState, tas, home, false, true, persist);
}
}
// handle remote brokers
ArrayList[] mcll = null;
BrokerAddress ba = null;
for (int i = 0; i < bas.length; i++) {
ba = bas[i];
if (ba == Globals.getMyAddress() || ba.equals(Globals.getMyAddress())) {
continue;
}
mcll = bmmap.get(ba);
try {
Globals.getClusterBroadcast().acknowledgeMessage2P(ba, (SysMessageID[]) mcll[0].toArray(new SysMessageID[mcll[0].size()]), (ConsumerUID[]) mcll[1].toArray(new ConsumerUID[mcll[1].size()]), ClusterBroadcast.MSG_PREPARE, null, Long.valueOf(id.longValue()), tranpid, true, false);
} catch (BrokerException e) {
if (!(e instanceof BrokerDownException) && !(e instanceof AckEntryNotFoundException)) {
throw e;
}
HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
ArrayList remoteConsumerUIDa = new ArrayList();
StringBuilder remoteConsumerUIDs = new StringBuilder();
String uidstr = null;
StringBuilder debugbuf = new StringBuilder();
for (int j = 0; j < mcll[0].size(); j++) {
SysMessageID sysid = (SysMessageID) mcll[0].get(j);
ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
if (suid == null || suid.equals(uid)) {
continue;
}
if (e.isRemote()) {
uidstr = String.valueOf(uid.longValue());
if (!remoteConsumerUIDa.contains(uidstr)) {
remoteConsumerUIDa.add(uidstr);
remoteConsumerUIDs.append(uidstr);
remoteConsumerUIDs.append(' ');
Consumer c = Consumer.getConsumer(uid);
if (c != null) {
c.recreationRequested();
} else {
logger.log(logger.WARNING, "Consumer " + uid + " not found in processing remote exception on preparing transaction " + id);
}
}
}
debugbuf.append("\n\t[").append(sysid).append(':').append(uid).append(']');
}
if (e.isRemote()) {
e.setRemoteConsumerUIDs(remoteConsumerUIDs.toString());
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare: JMQRemote Exception:remoteConsumerUIDs=" + remoteConsumerUIDs + ", remote broker " + ba);
}
}
try {
translist.updateState(id, TransactionState.FAILED, false, TransactionState.PREPARED, true);
} catch (Exception ex) {
logger.logStack(logger.WARNING, "Unable to update transaction " + id + " state to FAILED on PREPARE failure from " + ba + ": " + ex.getMessage() + debugbuf.toString(), ex);
throw e;
}
if (e instanceof AckEntryNotFoundException) {
mcll = ((AckEntryNotFoundException) e).getAckEntries();
}
for (int j = 0; j < mcll[0].size(); j++) {
SysMessageID sysid = (SysMessageID) mcll[0].get(j);
ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
boolean remove = true;
if (e instanceof BrokerDownException) {
ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
if (suid == null || suid.equals(uid)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare: no remove txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
}
remove = false;
}
}
if (remove) {
try {
translist.removeAcknowledgement(id, sysid, uid, (e instanceof AckEntryNotFoundException));
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare: removed txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
}
} catch (Exception ex) {
logger.logStack(logger.WARNING, "Unable to remove transaction " + id + " ack [" + sysid + ":" + uid + "] on PREPARE failure from " + ba + ": " + ex.getMessage(), ex);
}
}
}
logger.log(logger.WARNING, "Preparing transaction " + id + " failed from " + ba + ": " + e.getMessage() + debugbuf.toString());
throw e;
}
}
return clusterTransaction;
}
use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class TransactionHandler method releaseRemoteForActiveConsumer.
public static void releaseRemoteForActiveConsumer(PacketReference ref, ConsumerUID intid, TransactionUID tid, TransactionList translist) {
Consumer c = Consumer.getConsumer(intid);
if (c == null) {
return;
}
if (ref == null || ref.isLocal()) {
return;
}
SysMessageID sysid = ref.getSysMessageID();
BrokerAddress addr = null;
try {
addr = translist.getAckBrokerAddress(tid, sysid, intid);
} catch (BrokerException e) {
if (DEBUG) {
Object[] args = { "null", tid, sysid, "[" + intid + ", " + c.getStoredConsumerUID() + "]", e.getMessage() };
Globals.getLogger().log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.X_NOTIFY_RELEASE_REMOTE_MSG_ACTIVE_CONSUMER, args));
Globals.getLogger().log(Logger.INFO, e.getMessage());
}
return;
}
try {
Object[] args = { addr, tid, sysid, "[" + intid + ", " + c.getStoredConsumerUID() + "]" };
Globals.getLogger().log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_NOTIFY_RELEASE_REMOTE_MSG_ACTIVE_CONSUMER, args));
HashMap prop = new HashMap();
prop.put(ClusterBroadcast.RB_RELEASE_MSG_ACTIVE, tid.toString());
Globals.getClusterBroadcast().acknowledgeMessage(addr, sysid, intid, ClusterBroadcast.MSG_IGNORED, prop, false);
} catch (BrokerException e) {
Object[] args = { addr, tid, sysid, "[" + intid + ", " + c.getStoredConsumerUID() + "]", e.getMessage() };
Globals.getLogger().log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.X_NOTIFY_RELEASE_REMOTE_MSG_ACTIVE_CONSUMER, args));
}
}
use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class TransactionHandler method redeliverUnackedNoConsumer.
/**
* @param sendMap consumerUID to PacketReferences map
* @param sToCmap consumerUID to stored ConsumerUID map
* @param redeliver whether set redeliver flag
* @param tid null if not for transaction rollback
* @param translist null if tid is null
*/
public static void redeliverUnackedNoConsumer(HashMap sendMap, HashMap sToCmap, boolean redeliver, TransactionUID tid, TransactionList translist) throws BrokerException {
Logger logger = Globals.getLogger();
Iterator sitr = sendMap.entrySet().iterator();
while (sitr.hasNext()) {
Map.Entry entry = (Map.Entry) sitr.next();
ConsumerUID intid = (ConsumerUID) entry.getKey();
ConsumerUID storedID = (ConsumerUID) sToCmap.get(intid);
SortedSet ss = (SortedSet) entry.getValue();
Iterator itr = ss.iterator();
while (itr.hasNext()) {
PacketReference ref = (PacketReference) itr.next();
SysMessageID sysid = ref.getSysMessageID();
if (!ref.isLocal()) {
if (tid != null && translist != null) {
translist.removeOrphanAck(tid, sysid, storedID, intid);
}
try {
ref.acquireDestroyRemoteReadLock();
try {
if (ref.isLastRemoteConsumerUID(storedID, intid)) {
if (ref.acknowledged(intid, storedID, !(intid.isNoAck() || intid.isDupsOK()), false, tid, translist, null, false)) {
try {
Destination d = ref.getDestination();
if (d != null) {
d.removeRemoteMessage(sysid, RemoveReason.ACKNOWLEDGED, ref);
} else {
if (DEBUG || DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Destination " + ref.getDestinationUID() + " not found on cleanup remote message [" + intid + "," + storedID + "," + ref + "]" + " for rollback transaction " + tid + " for inactive consumer");
}
}
} finally {
ref.postAcknowledgedRemoval();
}
}
}
} finally {
ref.clearDestroyRemoteReadLock();
}
} catch (Exception ex) {
logger.logStack((DEBUG_CLUSTER_TXN ? Logger.WARNING : Logger.DEBUG), "Unable to cleanup remote message " + "[" + intid + "," + storedID + "," + sysid + "]" + " on rollback transaction " + tid + " for inactive consumer.", ex);
}
BrokerAddress addr = null;
if (tid != null && translist != null) {
addr = translist.getAckBrokerAddress(tid, sysid, intid);
} else {
addr = ref.getBrokerAddress();
}
try {
HashMap prop = new HashMap();
if (tid != null) {
prop.put(ClusterBroadcast.RB_RELEASE_MSG_INACTIVE, tid.toString());
} else {
prop.put(ClusterBroadcast.RC_RELEASE_MSG_INACTIVE, "");
}
Globals.getClusterBroadcast().acknowledgeMessage(addr, sysid, intid, ClusterBroadcast.MSG_IGNORED, prop, false);
} catch (BrokerException e) {
Globals.getLogger().log(Logger.WARNING, "Unable to notify " + addr + " for remote message " + "[" + intid + ", " + storedID + ", " + ", " + sysid + "]" + " in " + (tid != null ? ("rollback transaction " + tid) : ("recover")) + " for inactive consumer.");
}
itr.remove();
continue;
}
}
if (storedID == null || intid == storedID) {
// non-durable subscriber, ignore
sitr.remove();
continue;
}
if (ss.isEmpty()) {
if (DEBUG) {
logger.log(Logger.INFO, "redeliverUnackedNoConsuemr: " + "empty local message set for consumer " + intid + "[storedID=" + storedID + "]");
}
continue;
}
// see if we are a queue
if (storedID == PacketReference.getQueueUID()) {
// queue message on
// queues are complex ->
PacketReference ref = (PacketReference) ss.first();
if (ref == null) {
if (DEBUG) {
logger.log(Logger.INFO, "Internal Error: " + " null reterence");
}
continue;
}
if (!redeliver) {
ref.removeDelivered(storedID, false);
}
Destination d = ref.getDestination();
if (d == null) {
if (DEBUG) {
logger.log(Logger.INFO, "Destination " + ref.getDestinationUID() + " not found for reference: " + ref);
}
continue;
}
// this puts it on the pending list
try {
d.forwardOrphanMessages(ss, storedID);
sitr.remove();
} catch (Exception ex) {
logger.log(Logger.INFO, "Internal Error: " + "Unable to re-queue message " + " to queue " + d, ex);
}
} else {
// durable
// ok - requeue the message on the subscription
Consumer cs = Consumer.getConsumer(storedID);
if (cs == null) {
if (DEBUG) {
logger.log(Logger.INFO, "Internal Error: " + " unknown consumer " + storedID);
}
continue;
}
if (!ss.isEmpty() && cs.routeMessages(ss, true)) {
// successful
sitr.remove();
}
}
}
if (DEBUG && sendMap.size() > 0) {
logger.log(Logger.INFO, tid + ":after all processing, " + sendMap.size() + " inactive consumers remaining");
}
}
Aggregations