use of com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore in project openmq by eclipse-ee4j.
the class Subscription method initSubscriptions.
public static void initSubscriptions() {
Logger logger = Globals.getLogger();
logger.log(Logger.DEBUG, "Initializing consumers");
synchronized (Subscription.class) {
if (loaded) {
return;
}
loaded = true;
}
// before we do anything else, make sure we dont have any
// unexpected exceptions
LoadException load_ex = null;
try {
load_ex = Globals.getStore().getLoadConsumerException();
} catch (Exception ex) {
// nothing to do
logger.logStack(Logger.DEBUG, "Error loading consumer exception ", ex);
}
if (load_ex != null) {
// some messages could not be loaded
LoadException processing = load_ex;
while (processing != null) {
ConsumerUID cuid = (ConsumerUID) processing.getKey();
Consumer con = (Consumer) processing.getValue();
if (cuid == null && con == null) {
logger.log(Logger.WARNING, "LoadConsumerException: " + "Both key and value are corrupted");
continue;
}
if (cuid == null) {
// store with valid key
try {
Globals.getStore().storeInterest(con, true);
} catch (Exception ex) {
logger.log(Logger.WARNING, BrokerResources.W_CON_RECREATE_FAILED, con.getConsumerUID(), ex);
}
} else {
// nothing we can do, remove it
logger.log(Logger.WARNING, BrokerResources.W_CON_CORRUPT_REMOVE, cuid.toString());
try {
Consumer c = new Consumer(cuid);
Globals.getStore().removeInterest(c, false);
} catch (Exception ex) {
logger.logStack(Logger.DEBUG, "Error removing " + "corrupt consumer " + cuid, ex);
}
}
// end if
processing = processing.getNextException();
}
// end while
}
try {
Consumer[] cons = Globals.getStore().getAllInterests();
for (int i = 0; i < cons.length; i++) {
Consumer c = cons[i];
if (c == null) {
continue;
}
// at this point, we only store subscriptions
assert c instanceof Subscription;
Subscription s = (Subscription) c;
String clientID = s.getClientID();
if (clientID != null && clientID.length() == 0) {
clientID = null;
}
String durableName = s.getDurableName();
logger.log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_LOAD_STORED_DURA, getDSubLogString(clientID, durableName)) + "[" + s.getDestinationUID() + "]");
String key = getDSubKey(clientID, durableName);
if (durableList.get(key) != null) {
logger.log(Logger.WARNING, BrokerResources.E_INTERNAL_BROKER_ERROR, "The loaded durable subscription " + s + getDSubLogString(clientID, durableName) + " from store already exists " + durableList.get(key) + ", replace");
}
durableList.put(key, s);
DestinationUID duid = s.getDestinationUID();
DestinationList DL = Globals.getDestinationList();
LinkedHashSet dset = null;
Map<PartitionedStore, LinkedHashSet<Destination>> dmap = null;
if (duid.isWildcard()) {
wildcardConsumers.add(c.getConsumerUID());
dmap = DL.findMatchingDestinationMap(null, duid);
Iterator<LinkedHashSet<Destination>> itr = dmap.values().iterator();
while (itr.hasNext()) {
dset = itr.next();
if (dset == null) {
continue;
}
Iterator<Destination> itr1 = dset.iterator();
while (itr1.hasNext()) {
Destination d = itr1.next();
if (d == null) {
continue;
}
if (DEBUG) {
logger.log(logger.INFO, "Add loaded durable subscription " + s + " to destination " + d);
}
d.addConsumer(s, false);
}
}
} else {
Destination[] ds = DL.getDestination(null, duid.getName(), (duid.isQueue() ? DestType.DEST_TYPE_QUEUE : DestType.DEST_TYPE_TOPIC), true, true);
for (int j = 0; j < ds.length; j++) {
if (ds[j] == null) {
continue;
}
if (DEBUG) {
logger.log(logger.INFO, "Add loaded durable subscription " + s + " to destination " + ds[j]);
}
ds[j].addConsumer(s, false);
}
}
}
} catch (Exception ex) {
logger.logStack(Logger.ERROR, BrokerResources.E_LOAD_DURABLES, ex);
}
}
use of com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore in project openmq by eclipse-ee4j.
the class RRConnToPartitionStrategy method chooseStorePartition.
@Override
public PartitionedStore chooseStorePartition(List<ConnToPartitionStrategyContext> pscs) throws BrokerException {
if (pscs == null || pscs.size() == 0) {
return null;
}
Collections.sort(pscs, new Comparator<ConnToPartitionStrategyContext>() {
@Override
public int compare(ConnToPartitionStrategyContext o1, ConnToPartitionStrategyContext o2) {
long v1 = o1.getPartitionedStore().getPartitionID().longValue();
long v2 = o2.getPartitionedStore().getPartitionID().longValue();
if (v1 < v2) {
return -1;
}
if (v1 > v2) {
return 1;
}
return 0;
}
});
PartitionedStore ps = null;
synchronized (this) {
if (lastid == 0L) {
ps = pscs.get(0).getPartitionedStore();
lastid = ps.getPartitionID().longValue();
return ps;
}
Iterator<ConnToPartitionStrategyContext> itr = pscs.iterator();
while (itr.hasNext()) {
ps = itr.next().getPartitionedStore();
long id = ps.getPartitionID().longValue();
if (id > lastid) {
lastid = id;
return ps;
}
}
ps = pscs.get(0).getPartitionedStore();
lastid = ps.getPartitionID().longValue();
return ps;
}
}
use of com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore 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.persist.api.PartitionedStore 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.persist.api.PartitionedStore in project openmq by eclipse-ee4j.
the class MultibrokerRouter method handleJMSMsg.
@Override
public void handleJMSMsg(Packet p, Map<ConsumerUID, Integer> consumers, BrokerAddress sender, boolean sendMsgDeliveredAck) throws BrokerException {
Map<ConsumerUID, Integer> deliveryCnts = consumers;
boolean hasflowcontrol = true;
ArrayList<Consumer> targetVector = new ArrayList<>();
ArrayList ignoreVector = new ArrayList();
// PART
PartitionedStore pstore = Globals.getStore().getPrimaryPartition();
Iterator<Map.Entry<ConsumerUID, Integer>> itr = consumers.entrySet().iterator();
Map.Entry<ConsumerUID, Integer> entry = null;
while (itr.hasNext()) {
entry = itr.next();
ConsumerUID uid = entry.getKey();
Consumer interest = Consumer.getConsumer(uid);
if (interest != null && interest.isValid()) {
// we need the interest for updating the ref
targetVector.add(interest);
ConsumerUID suid = interest.getStoredConsumerUID();
if ((suid == null || suid.equals(uid)) && interest.getSubscription() == null) {
hasflowcontrol = false;
}
} else {
ignoreVector.add(uid);
}
}
if (targetVector.isEmpty()) {
sendIgnoreAck(p.getSysMessageID(), null, sender, ignoreVector);
return;
}
boolean exists = false;
// PART
PacketReference ref = DL.get(null, p.getSysMessageID());
if (ref != null) {
BrokerAddress addr = ref.getBrokerAddress();
if (addr == null || !addr.equals(sender)) {
if (DEBUG) {
logger.log(Logger.INFO, "Remote message " + ref.getSysMessageID() + " home broker " + addr + " changed to " + sender);
}
DL.remoteCheckMessageHomeChange(ref, sender);
if (addr == null) {
Object[] args = { ref.getSysMessageID(), sender, targetVector };
logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_IGNORE_REMOTE_MSG_SENT_FROM, args));
ignoreVector.addAll(targetVector);
targetVector.clear();
sendIgnoreAck(p.getSysMessageID(), ref, sender, ignoreVector);
return;
}
}
}
List dsts = null;
// PART
ref = DL.get(null, p.getSysMessageID());
boolean acquiredWriteLock = false;
try {
if (ref != null) {
ref.acquireDestroyRemoteWriteLock();
acquiredWriteLock = true;
if (ref.isInvalid() || ref.isDestroyed()) {
ref.clearDestroyRemoteWriteLock();
acquiredWriteLock = false;
// PART
ref = DL.get(null, p.getSysMessageID());
if (ref != null) {
ref.acquireDestroyRemoteWriteLock();
acquiredWriteLock = true;
}
}
}
if (ref != null) {
if (ref.getBrokerAddress() == null) {
ref.clearDestroyRemoteWriteLock();
acquiredWriteLock = false;
Object[] args = { ref.getSysMessageID(), sender, targetVector };
logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_IGNORE_REMOTE_MSG_SENT_FROM, args));
ignoreVector.addAll(targetVector);
targetVector.clear();
sendIgnoreAck(p.getSysMessageID(), ref, sender, ignoreVector);
return;
} else {
exists = true;
ref.setBrokerAddress(sender);
if (p.getRedelivered()) {
ref.overrideRedeliver();
}
}
} else {
// PART
ref = PacketReference.createReference(pstore, p, null);
ref.setBrokerAddress(sender);
}
// consumer
if (sendMsgDeliveredAck) {
for (int i = 0; i < targetVector.size(); i++) {
Consumer c = targetVector.get(i);
// ref.addMessageDeliveredAck(c.getStoredConsumerUID());
ref.addMessageDeliveredAck(c.getConsumerUID());
}
}
try {
if (ref.getDestinationUID().isWildcard()) {
List[] dss = DL.findMatchingIDs(pstore, ref.getDestinationUID());
dsts = dss[0];
} else {
// ok, autocreate the destination if necessary
Destination[] ds = DL.getDestination(pstore, ref.getDestinationUID().getName(), ref.getDestinationUID().isQueue() ? DestType.DEST_TYPE_QUEUE : DestType.DEST_TYPE_TOPIC, true, true);
Destination d = ds[0];
if (d != null) {
dsts = new ArrayList();
dsts.add(d.getDestinationUID());
}
}
if (dsts == null || dsts.isEmpty()) {
ignoreVector.addAll(targetVector);
targetVector.clear();
} else {
if (!exists && !targetVector.isEmpty()) {
ref.setNeverStore(true);
// OK .. we dont need to route .. its already happened
ref.storeRemoteInterests(targetVector, deliveryCnts);
itr = dsts.iterator();
while (itr.hasNext()) {
DestinationUID did = (DestinationUID) itr.next();
Destination[] ds = DL.getDestination(pstore, did);
Destination d = ds[0];
if (DEBUG) {
logger.log(logger.INFO, "Route remote message " + ref + " sent from " + sender + " to destination(s) " + did + " for consumer(s) " + targetVector + " hasflowcontrol=" + hasflowcontrol + ", enforcelimit=" + ENFORCE_REMOTE_DEST_LIMIT);
}
// add to message count
d.acquireQueueRemoteLock();
try {
PacketReference newref = d.getMessage(p.getSysMessageID());
if (newref != null) {
ignoreVector.addAll(targetVector);
targetVector.clear();
Object[] args = { p.getSysMessageID(), "" + d.getDestinationUID(), sender, newref + "[" + newref.getBrokerAddress() + "]" };
logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_REMOTE_NEW_MSG_ROUTED_ALREADY, args));
break;
}
d.queueMessage(ref, false, ENFORCE_REMOTE_DEST_LIMIT);
} finally {
d.clearQueueRemoteLock();
}
}
} else if (exists) {
ref.addRemoteInterests(targetVector);
}
}
} catch (Exception ex) {
Object[] args = { "" + ref, sender, targetVector };
String emsg = Globals.getBrokerResources().getKString(BrokerResources.W_EXCEPTION_PROCESS_REMOTE_MSG, args);
if (!(ex instanceof BrokerException)) {
logger.logStack(logger.WARNING, emsg, ex);
} else {
BrokerException be = (BrokerException) ex;
int status = be.getStatusCode();
if (status != Status.RESOURCE_FULL && status != Status.ENTITY_TOO_LARGE) {
logger.logStack(logger.WARNING, emsg, ex);
} else {
Object[] args1 = { sender, targetVector };
emsg = Globals.getBrokerResources().getKString(BrokerResources.W_PROCESS_REMOTE_MSG_DST_LIMIT, args1);
int level = Logger.DEBUG;
if (!loggedFullDestsOnHandleJMSMsg.contains(ref.getDestinationUID())) {
level = Logger.WARNING;
loggedFullDestsOnHandleJMSMsg.add(ref.getDestinationUID());
}
logger.log(level, emsg + (level == Logger.DEBUG ? ": " + ex.getMessage() : ""));
}
}
}
} finally {
if (ref != null && acquiredWriteLock) {
ref.clearDestroyRemoteWriteLock();
}
}
// Now deliver the message...
StringBuilder debugString = new StringBuilder();
debugString.append('\n');
int i;
for (i = 0; i < targetVector.size(); i++) {
Consumer interest = targetVector.get(i);
if (!interest.routeMessage(ref, false)) {
// it disappeard on us, take care of it
try {
if (ref.acknowledged(interest.getConsumerUID(), interest.getStoredConsumerUID(), true, false)) {
try {
if (dsts == null) {
continue;
}
itr = dsts.iterator();
while (itr.hasNext()) {
DestinationUID did = (DestinationUID) itr.next();
Destination[] ds = DL.getDestination(pstore, did);
Destination d = ds[0];
d.removeRemoteMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED, ref);
}
} finally {
ref.postAcknowledgedRemoval();
}
}
} catch (Exception ex) {
logger.log(logger.INFO, "Internal error processing ack", ex);
} finally {
ref.removeRemoteConsumerUID(interest.getStoredConsumerUID(), interest.getConsumerUID());
}
}
if (DEBUG) {
debugString.append("\t" + interest.getConsumerUID() + "\n");
}
}
if (DEBUG) {
logger.log(logger.DEBUGHIGH, "MessageBus: Delivering message to : {0}", debugString.toString());
}
sendIgnoreAck(p.getSysMessageID(), ref, sender, ignoreVector);
}
Aggregations