use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class GetTransactionsHandler 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.INFO, this.getClass().getName() + ": " + "Getting transactions " + cmd_props);
}
int status = Status.OK;
String errMsg = null;
TransactionUID tid = null;
Long id = (Long) cmd_props.get(MessageType.JMQ_TRANSACTION_ID);
Boolean val = (Boolean) cmd_props.get(MessageType.JMQ_SHOW_PARTITION);
boolean showpartition = (val != null && val.booleanValue());
if (id != null) {
tid = new TransactionUID(id.longValue());
}
Vector v = new Vector();
try {
TransactionList tl = null;
Hashtable table = null;
if (tid != null) {
Object[] oo = TransactionList.getTransListAndState(tid, null, true, false);
if (oo == null) {
oo = TransactionList.getTransListAndRemoteState(tid);
}
if (oo == null) {
throw new BrokerException(rb.getKString(rb.X_TXN_NOT_FOUND, tid), Status.NOT_FOUND);
}
tl = (TransactionList) oo[0];
// Get info for one transaction
int type = UNKNOWN;
if (tl.isRemoteTransaction(tid)) {
type = REMOTE;
} else if (tl.isClusterTransaction(tid)) {
type = CLUSTER;
} else if (tl.isLocalTransaction(tid)) {
type = LOCAL;
}
table = getTransactionInfo(tl, tid, type, showpartition);
if (table != null) {
v.add(table);
}
} else {
TransactionList[] tls = DL.getTransactionList(null);
for (int i = 0; i < tls.length; i++) {
tl = tls[i];
// Get info for all transactions (-1 means get transactions
// no matter what the state).
TransactionUID ttid = null;
Vector transactions = tl.getTransactions(-1);
if (transactions != null) {
Enumeration e = transactions.elements();
while (e.hasMoreElements()) {
ttid = (TransactionUID) e.nextElement();
table = getTransactionInfo(tl, ttid, LOCAL, showpartition);
if (table != null) {
v.add(table);
}
}
}
transactions = tl.getClusterTransactions(-1);
if (transactions != null) {
Enumeration e = transactions.elements();
while (e.hasMoreElements()) {
ttid = (TransactionUID) e.nextElement();
table = getTransactionInfo(tl, ttid, CLUSTER, showpartition);
if (table != null) {
v.add(table);
}
}
}
transactions = tl.getRemoteTransactions(-1);
if (transactions != null) {
Enumeration e = transactions.elements();
while (e.hasMoreElements()) {
ttid = (TransactionUID) e.nextElement();
table = getTransactionInfo(tl, ttid, REMOTE, showpartition);
if (table != null) {
v.add(table);
}
}
}
}
}
} catch (Exception e) {
errMsg = e.getMessage();
status = Status.ERROR;
if (e instanceof BrokerException) {
status = ((BrokerException) e).getStatusCode();
}
}
if (tid != null && v.size() == 0) {
// Specified transaction did not exist
status = Status.NOT_FOUND;
errMsg = rb.getString(rb.E_NO_SUCH_TRANSACTION, tid);
}
// Write reply
Packet reply = new Packet(con.useDirectBuffers());
reply.setPacketType(PacketType.OBJECT_MESSAGE);
setProperties(reply, MessageType.GET_TRANSACTIONS_REPLY, status, errMsg);
// Add JMQQuantity property
try {
reply.getProperties().put(MessageType.JMQ_QUANTITY, Integer.valueOf(v.size()));
} catch (IOException | ClassNotFoundException e) {
// Programming error. No need to I18N
logger.logStack(Logger.WARNING, rb.E_INTERNAL_BROKER_ERROR, "Admin: GetTransactions: Could not extract properties from pkt", e);
}
// Always set the body even if vector is empty
setBodyObject(reply, v);
parent.sendReply(con, cmd_msg, reply);
return true;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class ClusterConsumerInfo method getGPacket.
public GPacket getGPacket(short protocol, int subtype, BrokerAddress broker) {
assert (consumers != null);
assert (protocol == ProtocolGlobals.G_NEW_INTEREST || protocol == ProtocolGlobals.G_INTEREST_UPDATE);
if (protocol == ProtocolGlobals.G_INTEREST_UPDATE) {
assert (// not effectively used ?
subtype == ProtocolGlobals.G_NEW_PRIMARY_INTEREST || subtype == ProtocolGlobals.G_REM_INTEREST || subtype == ProtocolGlobals.G_DURABLE_DETACH);
}
GPacket gp = GPacket.getInstance();
gp.setType(protocol);
gp.putProp("C", Integer.valueOf(consumers.size()));
if (broker != null && pendingMsgs != null && pendingMsgs.size() > 0) {
TransactionUID tid = null;
LinkedHashMap mm = null;
SysMessageID sysid = null;
StringBuilder sb = null;
StringBuilder sb45 = null;
StringBuilder oldsb = null;
Map m = (Map) pendingMsgs.get(broker);
if (m != null) {
oldsb = new StringBuilder();
Map.Entry pair = null;
Iterator itr0 = m.entrySet().iterator();
while (itr0.hasNext()) {
pair = (Map.Entry) itr0.next();
tid = (TransactionUID) pair.getKey();
mm = (LinkedHashMap) pair.getValue();
sb = new StringBuilder();
sb45 = new StringBuilder();
Map.Entry entry = null;
Iterator itr = mm.entrySet().iterator();
while (itr.hasNext()) {
entry = (Map.Entry) itr.next();
sysid = (SysMessageID) entry.getKey();
Integer deliverCnt = (Integer) entry.getValue();
sb.append(sysid).append(MID_DCT_SEPARATOR).append(deliverCnt == null ? 0 : deliverCnt).append(' ');
sb45.append(sysid).append(' ');
oldsb.append(sysid).append(' ');
}
if (sb.length() > 0) {
gp.putProp(PROP_PREFIX_PENDING_TID_MID_DCT + (tid == null ? "" : tid), String.valueOf(sb.toString()));
gp.putProp(PROP_PREFIX_PENDING_TID + (tid == null ? "" : tid), String.valueOf(sb45.toString()));
}
}
// To be removed when clustering the old protocol (< 500) broker no longer supported
gp.putProp(PROP_PENDING_MESSAGES, oldsb.toString());
}
}
if (cleanup) {
gp.putProp("cleanup", Boolean.TRUE);
}
if (c != null) {
c.marshalBrokerAddress(c.getSelfAddress(), gp);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
switch(protocol) {
case ProtocolGlobals.G_NEW_INTEREST:
try {
ClusterManager cm = Globals.getClusterManager();
int csize = 1;
if (cm != null) {
csize = cm.getConfigBrokerCount();
if (csize <= 0) {
csize = 1;
}
}
int i = 0;
Iterator itr = consumers.iterator();
while (itr.hasNext()) {
i++;
Consumer c = (Consumer) itr.next();
int prefetch = c.getPrefetchForRemote() / csize;
if (prefetch <= 0) {
prefetch = 1;
}
gp.putProp(c.getConsumerUID().longValue() + ":" + Consumer.PREFETCH, Integer.valueOf(prefetch));
writeConsumer(c, dos);
if (!(c instanceof Subscription)) {
continue;
}
ChangeRecordInfo cri = ((Subscription) c).getCurrentChangeRecordInfo(ProtocolGlobals.G_NEW_INTEREST);
if (cri == null) {
continue;
}
gp.putProp("shareccSeq" + i, cri.getSeq());
gp.putProp("shareccUUID" + i, cri.getUUID());
gp.putProp("shareccResetUUID" + i, cri.getResetUUID());
}
dos.flush();
bos.flush();
} catch (IOException e) {
/* Ignore */
}
gp.setPayload(ByteBuffer.wrap(bos.toByteArray()));
break;
case ProtocolGlobals.G_INTEREST_UPDATE:
gp.putProp("T", Integer.valueOf(subtype));
try {
Iterator itr = consumers.iterator();
while (itr.hasNext()) {
Consumer c = (Consumer) itr.next();
writeConsumerUID(c.getConsumerUID(), dos);
}
dos.flush();
bos.flush();
} catch (IOException e) {
/* Ignore */
}
gp.setPayload(ByteBuffer.wrap(bos.toByteArray()));
break;
}
return gp;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class CallbackDispatcher method processCommitAck.
private boolean processCommitAck(final BrokerAddress sender, final GPacket pkt) {
if (!ClusterMessageAckInfo.isAckAckAsync(pkt)) {
return false;
}
Integer acktype = ClusterMessageAckInfo.getAckAckType(pkt);
if (acktype == null || acktype.intValue() != ClusterGlobals.MB_MSG_CONSUMED) {
return false;
}
Long transactionID = ClusterMessageAckInfo.getAckAckTransactionID(pkt);
if (transactionID == null) {
return false;
}
if (ClusterMessageAckInfo.getAckAckStatus(pkt) != Status.OK) {
logger.log(logger.WARNING, br.getKString(br.W_CLUSTER_MSG_ACK_FAILED_FROM_HOME, sender, ClusterMessageAckInfo.toString(pkt)));
return true;
}
if (DEBUG_CLUSTER_TXN || DEBUG) {
logger.log(logger.INFO, "processCommitAck: Received " + ProtocolGlobals.getPacketTypeDisplayString(pkt.getType()) + " from " + sender + ": " + ClusterMessageAckInfo.toString(pkt));
}
if (fi.FAULT_INJECTION) {
ClusterMessageAckInfo.CHECKFAULT(new HashMap(), ClusterGlobals.MB_MSG_CONSUMED, transactionID, FaultInjection.MSG_REMOTE_ACK_P, FaultInjection.STAGE_3);
}
try {
final TransactionUID tuid = new TransactionUID(transactionID.longValue());
final UID ss = ClusterMessageAckInfo.getAckAckStoreSessionUID(pkt);
commitAckExecutor.execute(new Runnable() {
@Override
public void run() {
try {
BrokerAddress addr = sender;
if (ss != null) {
addr = (BrokerAddress) sender.clone();
addr.setStoreSessionUID(ss);
}
Object[] oo = TransactionList.getTransListAndState(tuid, null, true, false);
if (oo == null) {
logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.W_TXN_NOT_FOUND_ON_UPDATE_TXN_COMPLETION_FOR_BKR, tuid, addr));
return;
}
TransactionList tl = (TransactionList) oo[0];
tl.completeClusterTransactionBrokerState(tuid, TransactionState.COMMITTED, addr, true);
} catch (Throwable t) {
Object[] args = { tuid, sender + "[" + ClusterMessageAckInfo.toString(pkt) + "]", t.getMessage() };
String emsg = br.getKString(br.W_UNABLE_UPDATE_CLUSTER_TXN_COMPLETE_STATE, args);
if (t instanceof BrokerException) {
if (((BrokerException) t).getStatusCode() == Status.NOT_FOUND) {
if (DEBUG_CLUSTER_TXN || DEBUG) {
logger.log(logger.WARNING, emsg + " - already completed");
}
return;
}
}
logger.logStack(logger.WARNING, emsg, t);
}
}
});
} catch (Throwable t) {
if (stopThread) {
logger.log(logger.DEBUG, "Cluster shutdown, ignore event " + ClusterMessageAckInfo.toString(pkt) + " from " + sender);
} else {
logger.logStack(logger.WARNING, "Exception in submitting for processing " + ClusterMessageAckInfo.toString(pkt) + " from " + sender, t);
}
}
return true;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class AckHandler method handle.
/**
* Method to handle Acknowledgement messages
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
int size = msg.getMessageBodySize();
int ackcount = size / ACK_BLOCK_SIZE;
int mod = size % ACK_BLOCK_SIZE;
int status = Status.OK;
String reason = null;
if (DEBUG) {
logger.log(Logger.INFO, "AckHandler: processing packet " + msg.toString() + ", on connection " + con);
}
PartitionedStore pstore = con.getPartitionedStore();
TransactionList[] tls = DL.getTransactionList(pstore);
TransactionList translist = tls[0];
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
// for fault injection
ackProcessCnt++;
} else {
ackProcessCnt = 0;
}
if (ackcount == 0) {
logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: Empty Ack Message " + msg.getSysMessageID().toString());
reason = "Empty ack message";
status = Status.ERROR;
}
if (mod != 0) {
logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: Invalid Ack Message Size " + size + " for message " + msg.getSysMessageID().toString());
reason = "corrupted ack message";
status = Status.ERROR;
}
TransactionUID tid = null;
if (msg.getTransactionID() != 0) {
// HANDLE TRANSACTION
try {
tid = new TransactionUID(msg.getTransactionID());
} catch (Exception ex) {
logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: can not create transactionID for " + msg, ex);
status = Status.ERROR;
}
}
ArrayList<PacketReference> cleanList = new ArrayList<>();
try {
// cleanList
Hashtable props = null;
Throwable deadthr = null;
String deadcmt = null;
int deadrs = DEAD_REASON_UNDELIVERABLE;
int deliverCnt = 0;
boolean deliverCntUpdateOnly = false;
int ackType = ACKNOWLEDGE_REQUEST;
boolean JMQValidate = false;
try {
props = msg.getProperties();
Integer iackType = (props == null ? null : (Integer) props.get("JMQAckType"));
ackType = (iackType == null ? ACKNOWLEDGE_REQUEST : iackType.intValue());
Boolean validateFlag = (props == null ? null : (Boolean) props.get("JMQValidate"));
JMQValidate = validateFlag != null && validateFlag.booleanValue();
checkRequestType(ackType);
if (ackType == DEAD_REQUEST) {
deadthr = (Throwable) props.get("JMQException");
deadcmt = (String) props.get("JMQComment");
Integer val = (Integer) props.get("JMQDeadReason");
if (val != null) {
deadrs = val.intValue();
}
}
if (props != null) {
if (ackType == DEAD_REQUEST || ackType == UNDELIVERABLE_REQUEST || tid != null) {
// Client runtime retry count
Integer val = (Integer) props.get("JMSXDeliveryCount");
deliverCnt = (val == null ? -1 : val.intValue());
if (tid == null) {
if (deliverCnt >= 0) {
deliverCnt += 1;
}
}
}
if (ackType == UNDELIVERABLE_REQUEST) {
Boolean val = (Boolean) props.get("JMSXDeliveryCountUpdateOnly");
deliverCntUpdateOnly = val != null && val.booleanValue();
}
}
} catch (Exception ex) {
// assume not dead
logger.logStack(Logger.INFO, "Internal Error: bad protocol", ex);
ackType = ACKNOWLEDGE_REQUEST;
}
// OK .. handle Fault Injection
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqAckCount", Integer.valueOf(ackProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(tid != null));
fi.checkFaultAndExit(FaultInjection.FAULT_ACK_MSG_1, m, 2, false);
}
boolean remoteStatus = false;
StringBuilder remoteConsumerUIDs = null;
SysMessageID[] ids = null;
ConsumerUID[] cids = null;
try {
if (status == Status.OK) {
DataInputStream is = new DataInputStream(msg.getMessageBodyStream());
// pull out the messages into two lists
ids = new SysMessageID[ackcount];
cids = new ConsumerUID[ackcount];
for (int i = 0; i < ackcount; i++) {
long newid = is.readLong();
cids[i] = new ConsumerUID(newid);
cids[i].setConnectionUID(con.getConnectionUID());
ids[i] = new SysMessageID();
ids[i].readID(is);
}
if (JMQValidate) {
if (ackType == DEAD_REQUEST || ackType == UNDELIVERABLE_REQUEST) {
status = Status.BAD_REQUEST;
reason = "Can not use JMQValidate with ackType of " + ackType;
} else if (tid == null) {
status = Status.BAD_REQUEST;
reason = "Can not use JMQValidate with no tid ";
} else if (!validateMessages(translist, tid, ids, cids)) {
status = Status.NOT_FOUND;
reason = "Acknowledgement not processed";
}
} else if (ackType == DEAD_REQUEST) {
handleDeadMsgs(con, ids, cids, deadrs, deadthr, deadcmt, deliverCnt, cleanList);
} else if (ackType == UNDELIVERABLE_REQUEST) {
handleUndeliverableMsgs(con, ids, cids, cleanList, deliverCnt, deliverCntUpdateOnly);
} else {
if (tid != null) {
handleTransaction(translist, con, tid, ids, cids, deliverCnt);
} else {
handleAcks(con, ids, cids, msg.getSendAcknowledge(), cleanList);
}
}
}
} catch (Throwable thr) {
status = Status.ERROR;
if (thr instanceof BrokerException) {
status = ((BrokerException) thr).getStatusCode();
remoteStatus = ((BrokerException) thr).isRemote();
if (remoteStatus && ids != null && cids != null) {
remoteConsumerUIDs = new StringBuilder();
remoteConsumerUIDs.append(((BrokerException) thr).getRemoteConsumerUIDs());
remoteConsumerUIDs.append(' ');
String cidstr = null;
ArrayList remoteConsumerUIDa = new ArrayList();
for (int i = 0; i < ids.length; i++) {
PacketReference ref = DL.get(pstore, ids[i]);
Consumer c = Consumer.getConsumer(cids[i]);
if (c == null) {
continue;
}
ConsumerUID sid = c.getStoredConsumerUID();
if (sid == null || sid.equals(cids[i])) {
continue;
}
BrokerAddress ba = (ref == null ? null : ref.getBrokerAddress());
BrokerAddress rba = (BrokerAddress) ((BrokerException) thr).getRemoteBrokerAddress();
if (ref != null && ba != null && rba != null && ba.equals(rba)) {
cidstr = String.valueOf(c.getConsumerUID().longValue());
if (!remoteConsumerUIDa.contains(cidstr)) {
remoteConsumerUIDa.add(cidstr);
remoteConsumerUIDs.append(cidstr);
remoteConsumerUIDs.append(' ');
}
}
}
}
}
reason = thr.getMessage();
if (status == Status.ERROR) {
// something went wrong
logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "-------------------------------------------" + "Internal Error: Invalid Acknowledge Packet processing\n" + " " + (msg.getSendAcknowledge() ? " notifying client\n" : " can not notify the client") + com.sun.messaging.jmq.io.PacketUtil.dumpPacket(msg) + "--------------------------------------------", thr);
}
}
// OK .. handle Fault Injection
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqAckCount", Integer.valueOf(ackProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(tid != null));
fi.checkFaultAndExit(FaultInjection.FAULT_ACK_MSG_2, m, 2, false);
}
// send the reply (if necessary)
if (msg.getSendAcknowledge()) {
Packet pkt = new Packet(con.useDirectBuffers());
pkt.setPacketType(PacketType.ACKNOWLEDGE_REPLY);
pkt.setConsumerID(msg.getConsumerID());
Hashtable hash = new Hashtable();
hash.put("JMQStatus", Integer.valueOf(status));
if (reason != null) {
hash.put("JMQReason", reason);
}
if (remoteStatus) {
hash.put("JMQRemote", Boolean.TRUE);
if (remoteConsumerUIDs != null) {
hash.put("JMQRemoteConsumerIDs", remoteConsumerUIDs.toString());
}
}
if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
hash.put("JMQReqID", msg.getSysMessageID().toString());
}
pkt.setProperties(hash);
con.sendControlMessage(pkt);
}
// OK .. handle Fault Injection
if (!con.isAdminConnection() && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqAckCount", Integer.valueOf(ackProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(tid != null));
fi.checkFaultAndExit(FaultInjection.FAULT_ACK_MSG_3, m, 2, false);
}
} finally {
// we dont need to clear the memory up until after we reply
cleanUp(cleanList);
}
return true;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class RedeliverHandler method handle.
/**
* Method to handle DELIVER messages
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
Hashtable props = null;
try {
props = msg.getProperties();
} catch (Exception ex) {
logger.logStack(Logger.INFO, "Unable to retrieve " + " properties from redeliver message " + msg, ex);
props = new Hashtable();
}
boolean redeliver = false;
TransactionUID tid = null;
if (props != null) {
Boolean bool = (Boolean) props.get("JMQSetRedelivered");
if (bool != null) {
redeliver = bool.booleanValue();
}
Object txnid = props.get("JMQTransactionID");
if (txnid != null) {
if (txnid instanceof Integer) {
tid = new TransactionUID(((Integer) txnid).intValue());
} else {
tid = new TransactionUID(((Long) txnid).longValue());
}
}
if (tid == null) {
// for client < 4.1
long id = msg.getTransactionID();
if (id != 0) {
tid = new TransactionUID(id);
}
}
}
int size = msg.getMessageBodySize();
int ackcount = size / REDELIVER_BLOCK_SIZE;
int mod = size % REDELIVER_BLOCK_SIZE;
if (ackcount == 0) {
return true;
}
if (mod != 0) {
throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, "Invalid Redeliver Message Size: " + size + ". Not multiple of " + REDELIVER_BLOCK_SIZE));
}
if (DEBUG) {
logger.log(Logger.DEBUG, "RedeliverMessage: processing message {0} {1}", msg.toString(), con.getConnectionUID().toString());
}
DataInputStream is = new DataInputStream(msg.getMessageBodyStream());
ConsumerUID[] ids = new ConsumerUID[ackcount];
SysMessageID[] sysids = new SysMessageID[ackcount];
try {
for (int i = 0; i < ackcount; i++) {
ids[i] = new ConsumerUID(is.readLong());
sysids[i] = new SysMessageID();
sysids[i].readID(is);
}
redeliver(ids, sysids, con, tid, redeliver);
} catch (Exception ex) {
throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, "Invalid Redeliver Packet", ex), ex);
}
return true;
}
Aggregations