use of com.sun.messaging.jmq.jmsserver.util.BrokerException 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.util.BrokerException in project openmq by eclipse-ee4j.
the class SFSHABrokerInfoMap method get.
/**
* Retrieves the HAClusteredBroker associated with the passed in broker id. If the id is not found in the hashtable, the
* store will be checked.
*
* @param key the brokerid to lookup
* @param update update against store
* @return the HAClusteredBroker object (or null if one can't be found)
*/
@Override
public Object get(Object key, boolean update) {
// always check against the backing store
Object o = super.get(key);
if (o == null || update) {
try {
HABrokerInfo m = Globals.getStore().getBrokerInfo((String) key);
if (m != null && o == null) {
HAClusteredBroker cb = new SFSHAClusteredBrokerImpl((String) key, m, parent);
put(key, cb);
parent.brokerChanged(ClusterReason.ADDED, cb.getBrokerName(), null, cb, cb.getBrokerSessionUID(), null);
o = cb;
}
if (m != null && update) {
((HAClusteredBrokerImpl) o).update(m);
}
} catch (BrokerException ex) {
Globals.getLogger().logStack(Logger.WARNING, "Exception while creating broker entry " + key, ex);
}
}
return o;
}
use of com.sun.messaging.jmq.jmsserver.util.BrokerException 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.util.BrokerException in project openmq by eclipse-ee4j.
the class BrokerConsumers method removeRemoteDeadMessage.
private boolean removeRemoteDeadMessage(int ackType, PacketReference ref, ConsumerUID cuid, ConsumerUID storedid, Map optionalProps) throws BrokerException {
if (ref == null) {
return true;
}
Destination d = ref.getDestination();
Queue[] qs = DL.getDMQ(ref.getPartitionedStore());
if (d == qs[0]) {
// already gone, ignore
return true;
}
// first pull out properties
String comment = null;
Exception ex = null;
Integer deliverCnt = null;
Integer reasonInt = null;
String deadbkr = null;
if (optionalProps != null) {
comment = (String) optionalProps.get(DMQ.UNDELIVERED_COMMENT);
ex = (Exception) optionalProps.get(DMQ.UNDELIVERED_EXCEPTION);
deliverCnt = (Integer) optionalProps.get(Destination.TEMP_CNT);
reasonInt = (Integer) optionalProps.get("REASON");
deadbkr = (String) optionalProps.get(DMQ.DEAD_BROKER);
}
RemoveReason rr = null;
if (ackType == ClusterBroadcast.MSG_UNDELIVERABLE) {
rr = RemoveReason.UNDELIVERABLE;
} else {
rr = RemoveReason.ERROR;
if (reasonInt != null) {
rr = RemoveReason.findReason(reasonInt.intValue());
}
}
if (comment == null) {
comment = "none";
}
if (ref.markDead(cuid, storedid, comment, ex, rr, (deliverCnt == null ? 0 : deliverCnt.intValue()), deadbkr)) {
try {
if (ref.isDead()) {
if (getDEBUG()) {
Globals.getLogger().log(logger.INFO, "Remove dead message " + ref + " for remote consumer " + cuid + " on destination " + d + " with reason " + rr);
}
try {
d.removeDeadMessage(ref);
} catch (Exception e) {
logger.log(logger.WARNING, "Unable to remove dead[" + rr + ", " + deadbkr + "] message " + ref + "[" + cuid + "]: " + e.getMessage(), e);
}
}
} finally {
ref.postAcknowledgedRemoval();
}
return true;
}
return false;
}
use of com.sun.messaging.jmq.jmsserver.util.BrokerException 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