}
throw ex;
}
dUID = DestinationUID.getUID(p.getDestination(), p.getIsQueue());
PacketReference pr = PacketReference.createReference(p, dUID, null);
// mark already stored and make packet a SoftReference to
// prevent running out of memory if dest has lots of msgs
pr.setLoaded();
logger.log(Logger.DEBUG,"Loading message " + pr.getSysMessageID()
+ " on " + pr.getDestinationUID());
// check transactions
TransactionUID tid = pr.getTransactionID();
if (tid != null) {
// see if in transaction list
if (txns.contains(tid)) {
// open transaction
TransactionState ts = Globals.getTransactionList()
.retrieveState(pr.getTransactionID());
if (ts != null &&
ts.getState() != TransactionState.ROLLEDBACK &&
ts.getState() != TransactionState.COMMITTED) {
// in transaction ...
logger.log(Logger.DEBUG, "Processing open transacted message " +
pr.getSysMessageID() + " on " + tid +
"["+TransactionState.toString(ts.getState())+"]");
openMessages.put(pr.getSysMessageID(), tid);
} else if (ts != null && ts.getState() == TransactionState.ROLLEDBACK) {
pr.destroy();
continue;
} else {
}
}
}
packetlistAdd(pr.getSysMessageID(), pr.getDestinationUID());
Set l = null;
if ((l = (Set)m.get(dUID)) == null) {
l = new TreeSet(new RefCompare());
m.put(dUID, l);
}
l.add(pr);
}
// OK, handle determining how to queue the messages
// first add all messages
Iterator dsts = m.entrySet().iterator();
while (dsts.hasNext()) {
Map.Entry entry = (Map.Entry)dsts.next();
DestinationUID dst = (DestinationUID) entry.getKey();
Set l = (Set)entry.getValue();
Destination d = Destination.getDestination(dst);
if (d == null) { // create it
try {
d = Destination.getDestination(dst.getName(),
(dst.isQueue()? DestType.DEST_TYPE_QUEUE:
DestType.DEST_TYPE_TOPIC) , true, true);
} catch (IOException ex) {
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_CANT_LOAD_DEST, d.getName()));
}
} else {
synchronized(d) {
if (d.isLoaded()) {
// Destination has already been loaded so just called
// initialize() to update the size and bytes variables
d.initialize();
}
d.load(l);
}
}
logger.log(Logger.INFO,
BrokerResources.I_LOADING_DST,
d.getName(), String.valueOf(l.size()));
// now we're sorted, process
Iterator litr = l.iterator();
try {
while (litr.hasNext()) {
PacketReference pr = (PacketReference)litr.next();
try {
// ok allow overrun
boolean el = d.destMessages.getEnforceLimits();
d.destMessages.enforceLimits(false);
pr.lock();
d.putMessage(pr, AddReason.LOADED, true);
// turn off overrun
d.destMessages.enforceLimits(el);
} catch (IllegalStateException ex) {
// thats ok, we already exists
String args[] = { pr.getSysMessageID().toString(),
pr.getDestinationUID().toString(),
ex.getMessage() };
logger.logStack(Logger.WARNING,
BrokerResources.W_CAN_NOT_LOAD_MSG,
args, ex);
continue;
} catch (OutOfLimitsException ex) {
String args[] = { pr.getSysMessageID().toString(),
pr.getDestinationUID().toString(),
ex.getMessage() };
logger.logStack(Logger.WARNING,
BrokerResources.W_CAN_NOT_LOAD_MSG,
args, ex);
continue;
}
}
// then resort the destination
d.sort(new RefCompare());
} catch (Exception ex) {
}
}
// now route
dsts = m.entrySet().iterator();
while (dsts.hasNext()) {
Map.Entry entry = (Map.Entry)dsts.next();
DestinationUID dst = (DestinationUID) entry.getKey();
Set l = (Set)entry.getValue();
Destination d = Destination.getDestination(dst);
// now we're sorted, process
Iterator litr = l.iterator();
try {
while (litr.hasNext()) {
PacketReference pr = (PacketReference)litr.next();
TransactionUID tuid = (TransactionUID)openMessages.get(pr.getSysMessageID());
if (tuid != null) {
Globals.getTransactionList().addMessage(tuid,
pr.getSysMessageID(), true);
pr.unlock();
continue;
}
ConsumerUID[] consumers = Globals.getStore().
getConsumerUIDs(dst, pr.getSysMessageID());
if (consumers == null) consumers = new ConsumerUID[0];
if (consumers.length == 0 &&
Globals.getStore().hasMessageBeenAcked(dst, pr.getSysMessageID())) {
logger.log(Logger.INFO,
Globals.getBrokerResources().getString(
BrokerResources.W_TAKEOVER_MSG_ALREADY_ACKED,
pr.getSysMessageID()));
d.unputMessage(pr, RemoveReason.ACKNOWLEDGED);
pr.destroy();
pr.unlock();
continue;
}
if (consumers.length > 0) {
pr.setStoredWithInterest(true);
} else {
pr.setStoredWithInterest(false);
}
int states[] = null;
if (consumers.length == 0) {
// route the message, it depends on the type of
// message
try {
consumers = d.routeLoadedTransactionMessage(pr);
} catch (Exception ex) {
logger.log(Logger.INFO,"Internal Error "
+ "loading/routing transacted message, "
+ "throwing out message " +
pr.getSysMessageID(), ex);
}
states = new int[consumers.length];
for (int i=0; i < states.length; i ++)
states[i] = Store.INTEREST_STATE_ROUTED;
try {
Globals.getStore().storeInterestStates(
d.getDestinationUID(),
pr.getSysMessageID(),
consumers, states, true, null);
pr.setStoredWithInterest(true);
} catch (Exception ex) {
// message already routed
StringBuffer debuf = new StringBuffer();
for (int i = 0; i < consumers.length; i++) {
if (i > 0) debuf.append(", ");
debuf.append(consumers[i]);
}
logger.log(logger.WARNING,
BrokerResources.W_TAKEOVER_MSG_ALREADY_ROUTED,
pr.getSysMessageID(), debuf.toString(), ex);
}
} else {
states = new int[consumers.length];
for (int i = 0; i < consumers.length; i ++) {
states[i] = Globals.getStore().getInterestState(
dst, pr.getSysMessageID(), consumers[i]);
}
}
pr.update(consumers, states, false);
// OK deal w/ transsactions
// LKS - XXX
ExpirationInfo ei = pr.getExpiration();
if (ei != null && d.expireReaper != null) {
d.expireReaper.addExpiringMessage(ei);
}
List consumerList = new ArrayList(Arrays.asList(
consumers));
// OK ... see if we are in txn
Iterator citr = consumerList.iterator();
while (citr.hasNext()) {
logger.log(Logger.DEBUG," Message "
+ pr.getSysMessageID() + " has "
+ consumerList.size() + " consumers ");
ConsumerUID cuid = (ConsumerUID)citr.next();
String key = pr.getSysMessageID() +
":" + cuid;
TransactionList tl = Globals.getTransactionList();
TransactionUID tid = (TransactionUID) ackLookup.get(key);
if (DEBUG) {
logger.log(logger.INFO, "loadTakeoverMsgs: lookup "+key+" found tid="+tid);
}
if (tid != null) {
boolean remote = false;
TransactionState ts = tl.retrieveState(tid);
if (ts == null) {
ts = tl.getRemoteTransactionState(tid);
remote = true;
}
if (DEBUG) {
logger.log(logger.INFO, "tid="+tid+" has state="+
TransactionState.toString(ts.getState()));
}
if (ts != null &&
ts.getState() != TransactionState.ROLLEDBACK &&
ts.getState() != TransactionState.COMMITTED) {
// in transaction ...
if (DEBUG) {
logger.log(Logger.INFO,
"loadTakeoverMsgs: Open transaction ack ["+key +"]"+
(remote?"remote":"")+", TUID="+tid);
}
if (!remote) {
try {
tl.addAcknowledgement(tid, pr.getSysMessageID(),
cuid, cuid, true, false);
} catch (TransactionAckExistException e) {
//can happen if takeover tid's remote txn after restart
//then txn ack would have already been loaded
logger.log(Logger.INFO,
Globals.getBrokerResources().getKString(
BrokerResources.I_TAKINGOVER_TXN_ACK_ALREADY_EXIST,
"["+pr.getSysMessageID()+"]"+cuid+":"+cuid,
tid+"["+TransactionState.toString(ts.getState())+"]"));
}
tl.addOrphanAck(tid, pr.getSysMessageID(), cuid);
}
citr.remove();
logger.log(Logger.INFO,"Processing open ack " +
pr.getSysMessageID() + ":" + cuid + " on " + tid);
continue;
} else if (ts != null &&
ts.getState() == TransactionState.COMMITTED) {
logger.log(Logger.INFO, "Processing committed ack "+
pr.getSysMessageID() + ":"+cuid + " on " +tid);
if (pr.acknowledged(cuid, cuid, false, true)) {
d.unputMessage(pr, RemoveReason.ACKNOWLEDGED);
pr.destroy();
continue;
}
citr.remove();
continue;
}
}
}
// route msgs not in transaction
if (DEBUG) {
StringBuffer buf = new StringBuffer();
ConsumerUID cid = null;
for (int j = 0; j <consumerList.size(); j++) {
cid = (ConsumerUID)consumerList.get(j);
buf.append(cid);
buf.append(" ");
}
logger.log(Logger.INFO, "non-transacted: Routing Message "
+ pr.getSysMessageID() + " to "
+ consumerList.size() + " consumers:"+buf.toString());
}
pr.unlock();
d.routeLoadedMessage(pr, consumerList);
if (d.destReaper != null) {
d.destReaper.cancel();
d.destReaper = null;
}