use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class MigrateStoreHandler 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) {
boolean noop = true;
int status = Status.OK;
String errMsg = "";
if (DEBUG) {
logger.log(Logger.INFO, this.getClass().getName() + ": " + "Request migrate this broker''s store: " + cmd_props);
}
String brokerID = (String) cmd_props.get(MessageType.JMQ_BROKER_ID);
String partition = (String) cmd_props.get(MessageType.JMQ_MIGRATESTORE_PARTITION);
if (partition == null) {
if (brokerID != null) {
logger.log(Logger.INFO, BrokerResources.I_ADMIN_MIGRATESTORE_TO, brokerID);
} else {
logger.log(Logger.INFO, BrokerResources.I_ADMIN_MIGRATESTORE);
}
} else {
logger.log(Logger.INFO, "XXXAdmin request migrate this broker's store partition " + partition + " to broker " + brokerID);
}
HAMonitorService hamonitor = Globals.getHAMonitorService();
if (hamonitor != null && hamonitor.inTakeover()) {
status = Status.NOT_MODIFIED;
errMsg = rb.getString(rb.E_CANNOT_PROCEED_TAKEOVER_IN_PROCESS);
logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
}
if (status == Status.OK) {
if (partition == null && Globals.getHAEnabled()) {
status = Status.NOT_MODIFIED;
errMsg = rb.getKString(rb.E_OPERATION_NOT_SUPPORTED_IN_HA, MessageType.getString(MessageType.MIGRATESTORE_BROKER));
logger.log(Logger.ERROR, errMsg);
}
}
if (status == Status.OK) {
if (Globals.isJMSRAManagedBroker()) {
status = Status.NOT_MODIFIED;
errMsg = "Can not process migration store request because this broker's life cycle is JMSRA managed";
logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
}
}
UID partitionID = null;
if (status == Status.OK) {
if (partition != null) {
try {
long v = Long.parseLong(partition);
partitionID = new UID(v);
} catch (Exception e) {
partitionID = null;
status = Status.NOT_MODIFIED;
errMsg = "XXXCan not process migration partition " + partition + " request because unable to parse " + partition + ": " + e;
logger.log(Logger.ERROR, errMsg);
}
}
}
if (status == Status.OK) {
if (partitionID != null && brokerID == null) {
status = Status.NOT_MODIFIED;
errMsg = "XXXCan not process migration partition " + partitionID + " request because brokerID not specified";
logger.log(Logger.ERROR, errMsg);
}
}
if (status == Status.OK) {
if (partitionID != null && !(DL.isPartitionMode() && DL.isPartitionMigratable())) {
status = Status.NOT_MODIFIED;
errMsg = "XXXCan not process migration partition " + partitionID + " request because partition mode not enabled";
logger.log(Logger.ERROR, errMsg);
}
}
if (status == Status.OK) {
if (partitionID != null) {
DestinationList dl = DL.getDestinationList(partitionID);
if (dl == null) {
status = Status.NOT_MODIFIED;
errMsg = "XXXCan not process migration partition " + partitionID + " request because partition " + partitionID + " not found";
logger.log(Logger.ERROR, errMsg);
} else if (dl.getPartitionedStore().isPrimaryPartition()) {
status = Status.NOT_MODIFIED;
errMsg = "XXXCan not process migration partition " + partitionID + " request because partition " + partitionID + " is the primary partition";
logger.log(Logger.ERROR, errMsg);
}
}
}
if (status == Status.OK) {
if (brokerID == null) {
try {
brokerID = getBrokerID();
} catch (Throwable t) {
status = Status.NOT_MODIFIED;
errMsg = "Unable to get a connected broker to takeover this broker's store: " + t.getMessage();
if ((t instanceof OperationNotAllowedException) && ((OperationNotAllowedException) t).getOperation().equals(MessageType.getString(MessageType.MIGRATESTORE_BROKER))) {
logger.log(logger.ERROR, errMsg);
} else {
logger.logStack(logger.ERROR, errMsg, t);
}
}
}
}
if (status != Status.OK) {
sendReply(con, cmd_msg, brokerID, null, errMsg, status, null);
return true;
}
try {
BrokerStateHandler.setExclusiveRequestLock(ExclusiveRequest.MIGRATE_STORE);
} catch (Throwable t) {
status = Status.PRECONDITION_FAILED;
if (t instanceof BrokerException) {
status = ((BrokerException) t).getStatusCode();
}
errMsg = MessageType.getString(MessageType.MIGRATESTORE_BROKER) + ": " + Status.getString(status) + " - " + t.getMessage();
logger.log(Logger.ERROR, errMsg);
status = Status.NOT_MODIFIED;
}
try {
if (partitionID != null) {
migratePartition(con, cmd_msg, partitionID, brokerID);
return true;
}
Long syncTimeout = null;
final BrokerStateHandler bsh = Globals.getBrokerStateHandler();
if (status == Status.OK) {
try {
syncTimeout = (Long) cmd_props.get(MessageType.JMQ_MIGRATESTORE_SYNC_TIMEOUT);
ClusterManager cm = Globals.getClusterManager();
BrokerMQAddress self = (BrokerMQAddress) cm.getMQAddress();
BrokerMQAddress master = (cm.getMasterBroker() == null ? null : (BrokerMQAddress) cm.getMasterBroker().getBrokerURL());
if (self.equals(master)) {
throw new BrokerException(rb.getKString(rb.E_CHANGE_MASTER_BROKER_FIRST, MessageType.getString(MessageType.MIGRATESTORE_BROKER)), Status.NOT_ALLOWED);
}
} catch (Throwable t) {
status = Status.PRECONDITION_FAILED;
if (t instanceof BrokerException) {
status = ((BrokerException) t).getStatusCode();
}
errMsg = MessageType.getString(MessageType.MIGRATESTORE_BROKER) + ": " + Status.getString(status) + " - " + t.getMessage();
logger.log(Logger.ERROR, errMsg);
status = Status.NOT_MODIFIED;
}
}
SysMessageID replyMessageID = null;
String replyStatusStr = null;
try {
// shutdown if !noop
String hostport = null;
if (status == Status.OK) {
try {
noop = false;
hostport = bsh.takeoverME(brokerID, syncTimeout, con);
} catch (BrokerException ex) {
status = ex.getStatusCode();
if (status == Status.BAD_REQUEST || status == Status.NOT_ALLOWED || status == Status.NOT_MODIFIED || status == Status.UNAVAILABLE || status == Status.PRECONDITION_FAILED) {
status = Status.PRECONDITION_FAILED;
if (ex instanceof OperationNotAllowedException) {
if (((OperationNotAllowedException) ex).getOperation().equals(MessageType.getString(MessageType.MIGRATESTORE_BROKER))) {
status = Status.NOT_MODIFIED;
noop = true;
}
}
errMsg = Globals.getBrokerResources().getKString(BrokerResources.E_FAIL_MIGRATESTORE_NOT_MIGRATED, ex.getMessage());
if (noop) {
logger.log(Logger.ERROR, errMsg);
} else {
logger.logStack(Logger.ERROR, errMsg, ex);
}
} else {
status = Status.EXPECTATION_FAILED;
errMsg = Globals.getBrokerResources().getKString(BrokerResources.E_FAIL_TAKEOVERME, brokerID, ex.getMessage());
logger.logStack(Logger.ERROR, errMsg, ex);
}
}
}
if (status == Status.OK) {
try {
Globals.getClusterBroadcast().stopClusterIO(false, true, null);
} catch (Throwable t) {
logger.logStack(Logger.WARNING, "Failed to stop cluster IO", t);
}
}
List ret = sendReply(con, cmd_msg, brokerID, hostport, errMsg, status, null);
replyMessageID = (SysMessageID) ret.get(0);
replyStatusStr = (String) ret.get(1);
} finally {
final SysMessageID mid = replyMessageID;
final String statusStr = replyStatusStr;
if (!noop) {
try {
if (con instanceof IMQBasicConnection) {
IMQBasicConnection ipCon = (IMQBasicConnection) con;
ipCon.flushControl(1000);
}
try {
Globals.getServiceManager().stopNewConnections(ServiceType.NORMAL);
} catch (Exception e) {
logger.logStack(logger.WARNING, rb.getKString(rb.W_STOP_SERVICE_FAIL, ServiceType.getServiceTypeString(ServiceType.NORMAL), e.getMessage()), e);
}
try {
Globals.getServiceManager().stopNewConnections(ServiceType.ADMIN);
} catch (Exception e) {
logger.logStack(logger.WARNING, rb.getKString(rb.W_STOP_SERVICE_FAIL, ServiceType.getServiceTypeString(ServiceType.ADMIN), e.getMessage()), e);
}
BrokerStateHandler.setShuttingDown(true);
bsh.prepareShutdown(false, true);
waitForHandlersToComplete(20);
if (mid == null) {
logger.log(Logger.INFO, BrokerResources.I_ADMIN_SHUTDOWN_REQUEST);
bsh.initiateShutdown("admin", 0, false, 0, true);
return true;
}
final String waitstr = rb.getKString(rb.I_WAIT_ADMIN_RECEIVE_REPLY, MessageType.getString(MessageType.MIGRATESTORE_BROKER_REPLY) + "[" + statusStr + "]");
final long totalwait = Globals.getConfig().getIntProperty(MAX_WAIT_ADMIN_CLIENT_PROP, DEFAULT_MAX_WAIT_ADMIN_CLIENT) * 1000L;
final IMQConnection conn = con;
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
try {
long waited = 0L;
while (conn.getConnectionState() < Connection.STATE_CLEANED && waited < totalwait) {
logger.log(logger.INFO, waitstr);
try {
Thread.sleep(500);
waited += 500L;
} catch (Exception e) {
/* ignore */
}
}
logger.log(Logger.INFO, BrokerResources.I_ADMIN_SHUTDOWN_REQUEST);
bsh.initiateShutdown("admin-migratestore-shutdown", 0, false, 0, true);
} catch (Throwable t) {
bsh.initiateShutdown("admin-migratestore-shutdown::[" + t.toString() + "]", 0, false, 0, true);
}
}
});
} catch (Throwable t) {
bsh.initiateShutdown("admin-migratestore-shutdown:[" + t.toString() + "]", 0, false, 0, true);
}
}
}
} finally {
BrokerStateHandler.unsetExclusiveRequestLock(ExclusiveRequest.MIGRATE_STORE);
}
return true;
}
use of com.sun.messaging.jmq.io.SysMessageID 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.io.SysMessageID 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.io.SysMessageID in project openmq by eclipse-ee4j.
the class ClusterConsumerInfo method getPendingMessages.
/**
* @return null if empty
*/
public Map<TransactionUID, LinkedHashMap<SysMessageID, Integer>> getPendingMessages() {
assert (pkt != null);
LinkedHashMap<TransactionUID, LinkedHashMap<SysMessageID, Integer>> m = new LinkedHashMap<>();
String key = null, val = null;
String tidstr = null;
TransactionUID tid = null;
LinkedHashMap<SysMessageID, Integer> sysiddcnts = null;
Iterator itr = pkt.propsKeySet().iterator();
while (itr.hasNext()) {
key = (String) itr.next();
tid = null;
if (key.startsWith(PROP_PREFIX_PENDING_TID_MID_DCT)) {
tidstr = key.substring(PROP_PREFIX_PENDING_TID_MID_DCT.length());
if (tidstr.length() > 0) {
tid = new TransactionUID(Long.parseLong(tidstr));
}
val = (String) pkt.getProp(key);
if (val == null || val.length() == 0) {
continue;
}
sysiddcnts = parsePendingMsgs(val);
if (m.get(tid) != null) {
throw new RuntimeException("Unexpected " + PROP_PREFIX_PENDING_TID_MID_DCT + " content: duplicated entries(" + m.get(tid) + ", " + sysiddcnts + ") for " + tid + ", " + m);
}
m.put(tid, sysiddcnts);
}
}
if (m.size() > 0) {
return m;
}
// check 4.5 patch protocol
key = null;
val = null;
tidstr = null;
tid = null;
sysiddcnts = null;
itr = pkt.propsKeySet().iterator();
while (itr.hasNext()) {
key = (String) itr.next();
tid = null;
if (key.startsWith(PROP_PREFIX_PENDING_TID)) {
tidstr = key.substring(PROP_PREFIX_PENDING_TID.length());
if (tidstr.length() > 0) {
tid = new TransactionUID(Long.parseLong(tidstr));
}
val = (String) pkt.getProp(key);
if (val == null || val.length() == 0) {
continue;
}
sysiddcnts = parsePendingMsgs(val);
if (m.get(tid) != null) {
throw new RuntimeException("Unexpected " + PROP_PREFIX_PENDING_TID + " content: duplicated entries(" + m.get(tid) + ", " + sysiddcnts + ") for " + tid + ", " + m);
}
m.put(tid, sysiddcnts);
}
}
if (m.size() > 0) {
return m;
}
// check 4.5 protocol
val = (String) pkt.getProp(PROP_PENDING_MESSAGES);
if (val == null || val.length() == 0) {
return null;
}
sysiddcnts = parsePendingMsgs(val);
m.put(null, sysiddcnts);
return m;
}
use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.
the class ClusterMessageAckInfo method getReplyGPacket.
public GPacket getReplyGPacket(int status, String reason, ArrayList[] aes) {
assert (pkt != null);
GPacket gp = GPacket.getInstance();
gp.setType(ProtocolGlobals.G_MESSAGE_ACK_REPLY);
gp.putProp("X", pkt.getProp("X"));
gp.putProp("T", Integer.valueOf(getAckType()));
if (pkt.getProp("C") != null) {
gp.putProp("C", pkt.getProp("C"));
}
if (pkt.getProp("messageBrokerSession") != null) {
gp.putProp("messageBrokerSession", pkt.getProp("messageBrokerSession"));
}
if (pkt.getProp("messageStoreSession") != null) {
gp.putProp("messageStoreSession", pkt.getProp("messageStoreSession"));
}
if (pkt.getProp("transactionID") != null) {
gp.putProp("transactionID", pkt.getProp("transactionID"));
}
if (pkt.getProp("ackackAsync") != null) {
gp.putProp("ackackAsync", pkt.getProp("ackackAsync"));
}
gp.putProp("S", Integer.valueOf(status));
if (reason != null) {
gp.putProp("reason", reason);
}
if (aes == null) {
if (pkt.getPayload() != null) {
gp.setPayload(ByteBuffer.wrap(pkt.getPayload().array()));
}
return gp;
}
gp.putProp("notfound", Integer.valueOf(aes[0].size()));
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
for (int i = 0; i < aes[0].size(); i++) {
((SysMessageID) aes[0].get(i)).writeID(dos);
ClusterConsumerInfo.writeConsumerUID((com.sun.messaging.jmq.jmsserver.core.ConsumerUID) aes[1].get(i), dos);
}
dos.flush();
bos.flush();
byte[] buf = bos.toByteArray();
gp.setPayload(ByteBuffer.wrap(buf));
} catch (Exception e) {
Globals.getLogger().logStack(Globals.getLogger().WARNING, e.getMessage(), e);
}
return gp;
}
Aggregations