use of com.sun.messaging.jmq.util.UID in project openmq by eclipse-ee4j.
the class TransactionHandler method retrieveConsumedRemoteMessages.
private HashMap[] retrieveConsumedRemoteMessages(TransactionList translist, TransactionUID id, boolean checkOnly) throws BrokerException {
HashMap mcmap = translist.retrieveConsumedMessages(id);
HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "retrieveConsumedRemoteMessages(" + translist + ",TID=" + id + ") retrieveConsumedMessages: " + mcmap);
}
if (mcmap == null || mcmap.size() == 0) {
return null;
}
HashMap[] rets = new HashMap[2];
HashMap<BrokerAddress, ArrayList[]> bmmap = new HashMap<>();
HashMap<TransactionBroker, ArrayList<TransactionAcknowledgement>> tbmmap = new HashMap<>();
ArrayList[] bmcll = null;
ArrayList<TransactionAcknowledgement> tbmcl = null;
boolean hasRemote = false;
BrokerAddress myba = Globals.getMyAddress();
UID tranpid = translist.getPartitionedStore().getPartitionID();
UID refpid = null;
ConsumerUID cuid = null, scuid = null;
TransactionAcknowledgement ta = null;
Iterator<Map.Entry> itr = mcmap.entrySet().iterator();
Map.Entry pair = null;
while (itr.hasNext()) {
pair = itr.next();
SysMessageID sysid = (SysMessageID) pair.getKey();
if (sysid == null) {
continue;
}
PacketReference ref = DL.get(null, sysid, false);
if (checkRefRequeued(translist, id, ref, sysid)) {
BrokerException bex = new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_MAYBE_REROUTED, sysid) + ", TUID=" + id, Status.GONE);
bex.setRemote(true);
StringBuilder buf = new StringBuilder();
List interests = (List) pair.getValue();
for (int i = 0; i < interests.size(); i++) {
buf.append(String.valueOf(((ConsumerUID) interests.get(i)).longValue()));
buf.append(' ');
}
bex.setRemoteConsumerUIDs(buf.toString());
throw bex;
}
if (ref == null) {
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_REF_GONE, sysid) + ", TUID=" + id, Status.CONFLICT);
}
BrokerAddress ba = ref.getBrokerAddress();
if (ba == null) {
if (!DL.isPartitionMode()) {
ba = myba;
} else {
refpid = ref.getPartitionedStore().getPartitionID();
ba = (BrokerAddress) myba.clone();
ba.setStoreSessionUID(refpid);
if (!refpid.equals(tranpid)) {
hasRemote = true;
}
}
} else if (!hasRemote) {
hasRemote = true;
}
if (hasRemote && checkOnly) {
return rets;
}
TransactionBroker tba = new TransactionBroker(ba);
bmcll = bmmap.get(tba.getBrokerAddress());
tbmcl = tbmmap.get(tba);
if (bmcll == null) {
bmcll = new ArrayList[2];
bmcll[0] = new ArrayList();
bmcll[1] = new ArrayList();
bmmap.put(tba.getBrokerAddress(), bmcll);
}
if (tbmcl == null) {
tbmcl = new ArrayList<>();
tbmmap.put(tba, tbmcl);
}
List interests = (List) mcmap.get(sysid);
for (int i = 0; i < interests.size(); i++) {
cuid = (ConsumerUID) interests.get(i);
bmcll[0].add(sysid);
bmcll[1].add(cuid);
scuid = (ConsumerUID) sToCmap.get(cuid);
ta = new TransactionAcknowledgement(sysid, cuid, scuid);
if (!scuid.shouldStore() || !ref.isPersistent()) {
ta.setShouldStore(false);
}
tbmcl.add(ta);
}
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "retrieveConsumedRemoteMessages() for broker " + tba + ": " + Arrays.toString(bmcll) + ", " + tbmcl);
}
}
if (!hasRemote) {
return null;
}
rets[0] = bmmap;
rets[1] = tbmmap;
return rets;
}
use of com.sun.messaging.jmq.util.UID in project openmq by eclipse-ee4j.
the class TransactionHandler method doRemotePrepare.
private ClusterTransaction doRemotePrepare(TransactionList translist, TransactionUID id, TransactionState nextState, TransactionWork txnWork) throws BrokerException {
if (nextState.getState() != TransactionState.PREPARED) {
throw new BrokerException("Unexpected state " + nextState + " for transactionID:" + id);
}
HashMap[] rets = retrieveConsumedRemoteMessages(translist, id, false);
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare(" + translist + ", " + id + "): retrievedConsumedRemoteMsgs:" + (rets == null ? "null" : rets[0] + ", " + rets[1]));
}
if (fi.FAULT_INJECTION) {
if (fi.checkFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5, null)) {
fi.unsetFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
throw new BrokerException(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
}
}
if (rets == null) {
return null;
}
if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
return null;
}
HashMap<BrokerAddress, ArrayList[]> bmmap = rets[0];
TransactionBroker[] tranbas = (TransactionBroker[]) rets[1].keySet().toArray(new TransactionBroker[rets[1].size()]);
BrokerAddress[] bas = bmmap.keySet().toArray(new BrokerAddress[bmmap.size()]);
boolean persist = true;
ClusterTransaction clusterTransaction = null;
if (Globals.isNewTxnLogEnabled()) {
// create a cluster transaction which will be logged
clusterTransaction = new ClusterTransaction(id, nextState, txnWork, tranbas);
translist.logClusterTransaction(id, nextState, tranbas, true, persist, clusterTransaction);
} else {
translist.logClusterTransaction(id, nextState, tranbas, true, persist);
}
if (DEBUG_CLUSTER_TXN) {
StringBuilder buf = new StringBuilder();
buf.append("Preparing transaction ").append(id).append(", brokers");
for (TransactionBroker tranba : tranbas) {
buf.append("\n\t").append(tranba);
}
logger.log(logger.INFO, buf.toString());
}
UID tranpid = null;
if (Globals.getDestinationList().isPartitionMode()) {
tranpid = translist.getPartitionedStore().getPartitionID();
ArrayList<TransactionAcknowledgement> mcl = null;
TransactionBroker tba = null;
UID tbapid = null;
TransactionAcknowledgement[] tas = null;
TransactionList tl = null;
for (int i = 0; i < tranbas.length; i++) {
tba = tranbas[i];
if (!tba.getBrokerAddress().equals(Globals.getMyAddress())) {
continue;
}
tbapid = tba.getBrokerAddress().getStoreSessionUID();
if (tbapid.equals(tranpid)) {
continue;
}
mcl = (ArrayList<TransactionAcknowledgement>) rets[1].get(tba);
tas = mcl.toArray(new TransactionAcknowledgement[mcl.size()]);
tl = TransactionList.getTransListByPartitionID(tbapid);
if (tl == null) {
throw new BrokerException("Can't prepare transaction " + id + " because " + "transaction list for partition " + tbapid + " not found");
}
BrokerAddress home = (BrokerAddress) Globals.getMyAddress().clone();
home.setStoreSessionUID(tranpid);
tl.logLocalRemoteTransaction(id, nextState, tas, home, false, true, persist);
}
}
// handle remote brokers
ArrayList[] mcll = null;
BrokerAddress ba = null;
for (int i = 0; i < bas.length; i++) {
ba = bas[i];
if (ba == Globals.getMyAddress() || ba.equals(Globals.getMyAddress())) {
continue;
}
mcll = bmmap.get(ba);
try {
Globals.getClusterBroadcast().acknowledgeMessage2P(ba, (SysMessageID[]) mcll[0].toArray(new SysMessageID[mcll[0].size()]), (ConsumerUID[]) mcll[1].toArray(new ConsumerUID[mcll[1].size()]), ClusterBroadcast.MSG_PREPARE, null, Long.valueOf(id.longValue()), tranpid, true, false);
} catch (BrokerException e) {
if (!(e instanceof BrokerDownException) && !(e instanceof AckEntryNotFoundException)) {
throw e;
}
HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
ArrayList remoteConsumerUIDa = new ArrayList();
StringBuilder remoteConsumerUIDs = new StringBuilder();
String uidstr = null;
StringBuilder debugbuf = new StringBuilder();
for (int j = 0; j < mcll[0].size(); j++) {
SysMessageID sysid = (SysMessageID) mcll[0].get(j);
ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
if (suid == null || suid.equals(uid)) {
continue;
}
if (e.isRemote()) {
uidstr = String.valueOf(uid.longValue());
if (!remoteConsumerUIDa.contains(uidstr)) {
remoteConsumerUIDa.add(uidstr);
remoteConsumerUIDs.append(uidstr);
remoteConsumerUIDs.append(' ');
Consumer c = Consumer.getConsumer(uid);
if (c != null) {
c.recreationRequested();
} else {
logger.log(logger.WARNING, "Consumer " + uid + " not found in processing remote exception on preparing transaction " + id);
}
}
}
debugbuf.append("\n\t[").append(sysid).append(':').append(uid).append(']');
}
if (e.isRemote()) {
e.setRemoteConsumerUIDs(remoteConsumerUIDs.toString());
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare: JMQRemote Exception:remoteConsumerUIDs=" + remoteConsumerUIDs + ", remote broker " + ba);
}
}
try {
translist.updateState(id, TransactionState.FAILED, false, TransactionState.PREPARED, true);
} catch (Exception ex) {
logger.logStack(logger.WARNING, "Unable to update transaction " + id + " state to FAILED on PREPARE failure from " + ba + ": " + ex.getMessage() + debugbuf.toString(), ex);
throw e;
}
if (e instanceof AckEntryNotFoundException) {
mcll = ((AckEntryNotFoundException) e).getAckEntries();
}
for (int j = 0; j < mcll[0].size(); j++) {
SysMessageID sysid = (SysMessageID) mcll[0].get(j);
ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
boolean remove = true;
if (e instanceof BrokerDownException) {
ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
if (suid == null || suid.equals(uid)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare: no remove txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
}
remove = false;
}
}
if (remove) {
try {
translist.removeAcknowledgement(id, sysid, uid, (e instanceof AckEntryNotFoundException));
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "doRemotePrepare: removed txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
}
} catch (Exception ex) {
logger.logStack(logger.WARNING, "Unable to remove transaction " + id + " ack [" + sysid + ":" + uid + "] on PREPARE failure from " + ba + ": " + ex.getMessage(), ex);
}
}
}
logger.log(logger.WARNING, "Preparing transaction " + id + " failed from " + ba + ": " + e.getMessage() + debugbuf.toString());
throw e;
}
}
return clusterTransaction;
}
use of com.sun.messaging.jmq.util.UID in project openmq by eclipse-ee4j.
the class ClusterImpl method processLinkInit.
/**
* Process the Packet.LINK_INIT packet.
*/
protected static LinkInfo processLinkInit(Packet p) throws Exception {
String hostName = null;
String instName = null;
String brokerID = null;
UID brokerSessionUID = null;
UID storeSessionUID = null;
boolean ha = false;
int port = 0;
BrokerAddressImpl remote = null;
ByteArrayInputStream bis = new ByteArrayInputStream(p.getPacketBody());
DataInputStream dis = new DataInputStream(bis);
int clusterVersion = dis.readInt();
hostName = dis.readUTF();
instName = dis.readUTF();
port = dis.readInt();
BrokerAddressImpl configServer = null;
boolean hasConfigServer = false;
String cfgHostName = null;
String cfgInstName = null;
int cfgPort = 0;
hasConfigServer = dis.readBoolean();
if (hasConfigServer) {
cfgHostName = dis.readUTF();
cfgInstName = dis.readUTF();
cfgPort = dis.readInt();
}
Properties props = new Properties();
int nprops = dis.readInt();
for (int i = 0; i < nprops; i++) {
String prop = dis.readUTF();
String value = dis.readUTF();
props.setProperty(prop, value);
}
if (clusterVersion >= ProtocolGlobals.VERSION_400) {
ha = dis.readBoolean();
if (dis.readBoolean()) {
brokerID = dis.readUTF();
}
brokerSessionUID = new UID(dis.readLong());
if (ha) {
storeSessionUID = new UID(dis.readLong());
} else {
try {
if (dis.readBoolean()) {
storeSessionUID = new UID(dis.readLong());
}
} catch (Exception e) {
}
}
}
if (hasConfigServer) {
if (ha) {
throw new BrokerException(br.getKString(br.E_CLUSTER_HA_NOT_SUPPORT_MASTERBROKER));
}
configServer = new BrokerAddressImpl(cfgHostName, cfgInstName, cfgPort, ha, null, null, null);
}
remote = new BrokerAddressImpl(hostName, instName, port, ha, brokerID, brokerSessionUID, storeSessionUID);
remote.setClusterVersion(clusterVersion);
LinkInfo li = new LinkInfo(remote, configServer, props);
if (clusterVersion < 0) {
int type = clusterVersion;
li.setServiceRequestType(type);
}
return li;
}
use of com.sun.messaging.jmq.util.UID in project openmq by eclipse-ee4j.
the class ClusterImpl method getLinkInitPkt.
private Packet getLinkInitPkt(Integer service) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try {
if (service == null) {
dos.writeInt(self.getClusterVersion());
} else {
dos.writeInt(service.intValue());
}
dos.writeUTF(self.getHostName());
dos.writeUTF(self.getInstanceName());
dos.writeInt(self.getPort());
BrokerAddressImpl cs = (BrokerAddressImpl) getConfiguredConfigServer();
dos.writeBoolean(cs != null);
if (cs != null) {
dos.writeUTF(cs.getHostName());
dos.writeUTF(cs.getInstanceName());
dos.writeInt(cs.getPort());
}
dos.writeInt(matchProps.size());
for (Enumeration e = matchProps.propertyNames(); e.hasMoreElements(); ) {
String prop = (String) e.nextElement();
dos.writeUTF(prop);
dos.writeUTF(matchProps.getProperty(prop));
}
dos.writeBoolean(Globals.getHAEnabled());
dos.writeBoolean(self.getBrokerID() != null);
if (self.getBrokerID() != null) {
dos.writeUTF(self.getBrokerID());
}
dos.writeLong(self.getBrokerSessionUID().longValue());
if (Globals.getHAEnabled()) {
dos.writeLong(self.getStoreSessionUID().longValue());
} else {
UID uid = self.getStoreSessionUID();
dos.writeBoolean((uid != null));
if (uid != null) {
dos.writeLong(uid.longValue());
}
}
dos.flush();
bos.flush();
} catch (Exception e) {
/* Ignore */
}
byte[] buf = bos.toByteArray();
Packet p = new Packet();
p.setPacketType(Packet.LINK_INIT);
p.setPacketBody(buf);
p.setDestId(0);
return p;
}
use of com.sun.messaging.jmq.util.UID in project openmq by eclipse-ee4j.
the class PacketReference method acknowledged.
/**
* If this method return true, caller is responsible to call postAcknowledgedRemoval()
*
* @param ackack whether client requested ackack
*
* If the ack is a remote non-transacted ack, waits for remote ack reply only if sync == true {@literal &&} notIgnored {@literal &&} ackack
*/
public boolean acknowledged(ConsumerUID intid, ConsumerUID storedid, boolean sync, boolean notIgnored, TransactionUID tuid, TransactionList translist, HashMap<TransactionBroker, Object> remoteNotified, boolean ackack) throws BrokerException, IOException {
Long txn = (tuid == null ? null : Long.valueOf(tuid.longValue()));
try {
if (destroyed || invalid) {
// destroyed
return true;
}
removeInDelivery(storedid);
ConsumerMessagePair cmp = getAck(storedid);
// something went wrong, ignore
if (cmp == null) {
// nothing to do
Globals.getLogger().log(Logger.ERROR, "Internal Error: Received Unknown ack " + intid + " for message " + getSysMessageID());
Globals.getLogger().log(Logger.ERROR, "AckInfo" + ackInfo.toString());
boolean rm = false;
synchronized (this) {
rm = (ackCnt + deadCnt) >= interestCnt;
}
if (!isLocal() && rm) {
acquireDestroyRemoteReadLock();
synchronized (this) {
rm = (ackCnt + deadCnt) >= interestCnt;
}
if (!rm) {
clearDestroyRemoteReadLock();
}
}
return rm;
}
// acked so do nothing
if (cmp.setState(ACKED)) {
if (cmp.isStored()) {
boolean acked = false;
if (Globals.getStore().isJDBCStore()) {
acked = pstore.hasMessageBeenAcked(destination, msgid);
}
if (!acked) {
try {
// This test may fail to spot that this really is
// the last ack because another thread processing an
// ack for the same message may not have yet
// incremented ackCnt.
// However, it should not return a false positive so
// should be safe
boolean isLastAck = false;
synchronized (this) {
isLastAck = (ackCnt + 1 + deadCnt) >= interestCnt;
}
pstore.updateInterestState(destination, msgid, storedid, PartitionedStore.INTEREST_STATE_ACKNOWLEDGED, Destination.PERSIST_SYNC && sync, tuid, isLastAck);
} catch (Exception ex) {
if (ex instanceof BrokerException && ((BrokerException) ex).getStatusCode() != Status.NOT_ALLOWED && ((BrokerException) ex).getStatusCode() != Status.NOT_FOUND) {
Globals.getLogger().log(Logger.WARNING, "Update consumer " + storedid + " state failed for message " + msgid + ": " + ex.getMessage());
throw ex;
} else {
Globals.getLogger().log(Logger.DEBUGHIGH, "Update consumer " + storedid + " state failed for message " + msgid + ": " + ex.getMessage());
}
}
}
}
if (!isLocal()) {
// not local
if (notIgnored) {
if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
Globals.getClusterBroadcast().acknowledgeMessage(getBrokerAddress(), getSysMessageID(), intid, ClusterBroadcast.MSG_ACKNOWLEDGED, null, false);
} else if (txn == null) {
Globals.getClusterBroadcast().acknowledgeMessage(getBrokerAddress(), getSysMessageID(), intid, ClusterBroadcast.MSG_ACKNOWLEDGED, null, (sync && ackack));
} else {
BrokerAddress raddr = getBrokerAddress();
TransactionBroker traddr = new TransactionBroker(raddr);
if (remoteNotified.get(traddr) == null) {
SysMessageID[] mysysids = { this.getSysMessageID() };
ConsumerUID[] myintids = { intid };
try {
UID txnss = translist.getPartitionedStore().getPartitionID();
Globals.getClusterBroadcast().acknowledgeMessage2P(raddr, mysysids, myintids, ClusterBroadcast.MSG_ACKNOWLEDGED, null, txn, txnss, true, !commit2pwait);
remoteNotified.put(traddr, String.valueOf(""));
if (commit2pwait) {
translist.completeClusterTransactionBrokerState(tuid, TransactionState.COMMITTED, raddr, true);
}
} catch (Exception e) {
if (e instanceof BrokerDownException) {
remoteNotified.put(traddr, String.valueOf(""));
}
if (DEBUG_CLUSTER_TXN) {
Globals.getLogger().logStack(Logger.WARNING, "Notify commit transaction [" + this.getSysMessageID() + ", " + intid + "]TUID=" + txn + " got response: " + e.toString(), e);
} else {
Globals.getLogger().log(Logger.WARNING, "Notify commit transaction [" + this.getSysMessageID() + ", " + intid + "]TUID=" + txn + " got response: " + e.toString(), e);
}
}
// catch
}
// if
}
} else {
try {
Globals.getClusterBroadcast().acknowledgeMessage(getBrokerAddress(), getSysMessageID(), intid, ClusterBroadcast.MSG_IGNORED, null, false);
} catch (BrokerException e) {
Globals.getLogger().log(Logger.DEBUG, e.getMessage());
}
}
}
} else {
Consumer c = Consumer.getConsumer(intid);
if (c == null || !c.isValid() || !isLocal()) {
// do we want to add a debug level message here
// got it while cleaning up
// this can only happen on topics and is a
// non-fatal error
// fixing the timing problem through synchronization
// adds too much overhead <- same to !isLocal case
boolean rm = false;
synchronized (this) {
rm = ((ackCnt + deadCnt) >= interestCnt);
}
if (!isLocal() && rm) {
acquireDestroyRemoteReadLock();
synchronized (this) {
rm = ((ackCnt + deadCnt) >= interestCnt);
}
if (!rm) {
clearDestroyRemoteReadLock();
}
}
return rm;
} else {
Exception e = new Exception("double ack " + cmp);
e.fillInStackTrace();
Globals.getLogger().logStack(Logger.ERROR, "Received ack twice " + " on " + msgid + " for " + intid + " state is = " + cmp, e);
boolean rm = false;
synchronized (this) {
rm = ((ackCnt + deadCnt) >= interestCnt);
}
if (!isLocal() && rm) {
acquireDestroyRemoteReadLock();
synchronized (this) {
rm = ((ackCnt + deadCnt) >= interestCnt);
}
if (!rm) {
clearDestroyRemoteReadLock();
}
}
return rm;
}
}
boolean rm = false;
synchronized (this) {
ackCnt++;
rm = ((ackCnt + deadCnt) >= interestCnt);
}
if (!isLocal() && rm) {
acquireDestroyRemoteReadLock();
synchronized (this) {
rm = ((ackCnt + deadCnt) >= interestCnt);
}
if (!rm) {
clearDestroyRemoteReadLock();
}
}
return rm;
} catch (Throwable thr) {
if (thr instanceof BrokerDownException) {
Globals.getLogger().log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_UNABLE_PROCESS_REMOTE_ACK_BECAUSE, "[" + msgid + "]" + intid + ":" + storedid, thr.getMessage()));
} else {
Globals.getLogger().logStack(Logger.ERROR, "Error in processing ack" + " on " + msgid + " for " + intid, thr);
}
if (thr instanceof BrokerException) {
throw (BrokerException) thr;
}
throw new BrokerException("Unable to process ack", thr);
}
}
Aggregations