use of com.sun.messaging.jmq.jmsserver.core.MessageDeliveryTimeInfo in project openmq by eclipse-ee4j.
the class ProtocolImpl method processMessage.
/**
* route, store and forward a message
*/
@Override
public void processMessage(IMQConnection con, Packet msg) throws BrokerException, SelectorFormatException, IOException {
DataHandler handler = (DataHandler) pr.getHandler(PacketType.MESSAGE);
Destination d = null;
PacketReference ref = null;
Set s = null;
boolean route = false;
boolean isadmin = con.isAdminConnection();
List<MessageDeliveryTimeInfo> deliveryDelayReadyList = new ArrayList<>();
try {
Destination[] ds = DL.getDestination(con.getPartitionedStore(), msg.getDestination(), msg.getIsQueue());
d = ds[0];
if (d == null) {
throw new BrokerException("Unknown Destination:" + msg.getDestination());
}
Producer pausedProducer = handler.checkFlow(msg, con);
boolean transacted = (msg.getTransactionID() != 0);
if (DEBUG) {
logger.log(Logger.INFO, "ProtocolImpl.PROCESS MESSAGE[" + msg + "]TID=" + msg.getTransactionID() + " to destination " + d + ", on conn=@" + con.hashCode() + "[" + con.getConnectionUID() + ", " + con + "]");
}
// OK generate a ref. This checks message size and
// will be needed for later operations
ref = handler.createReference(msg, d.getDestinationUID(), con, isadmin);
// dont bother calling route if there are no messages
//
// to improve performance, we route and later forward
route = handler.queueMessage(d, ref, transacted);
s = handler.routeMessage(con.getPartitionedStore(), transacted, ref, route, d, deliveryDelayReadyList);
// handle producer flow control
handler.pauseProducer(d, pausedProducer, con);
} catch (BrokerException ex) {
int status = ex.getStatusCode();
if (status == Status.ERROR && ref != null && d != null) {
handler.cleanupOnError(d, ref);
}
// rethrow
throw ex;
}
if (route && s != null) {
try {
handler.forwardMessage(d, ref, s);
} catch (Exception e) {
Object[] emsg = { ref, d.getDestinationUID(), s };
logger.logStack(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.X_ROUTE_PRODUCED_MSG_FAIL, emsg), e);
}
}
if (deliveryDelayReadyList.size() > 0) {
MessageDeliveryTimeInfo di = null;
Iterator<MessageDeliveryTimeInfo> itr = deliveryDelayReadyList.iterator();
while (itr.hasNext()) {
di = itr.next();
di.setDeliveryReady();
}
}
}
use of com.sun.messaging.jmq.jmsserver.core.MessageDeliveryTimeInfo in project openmq by eclipse-ee4j.
the class DataHandler method handle.
/**
* Method to handle normal/admin data messages
*/
protected boolean handle(IMQConnection con, Packet msg, boolean isadmin) throws BrokerException {
// used for fault injection
Hashtable props = null;
if (!isadmin && fi.FAULT_INJECTION) {
// for fault injection
msgProcessCnt++;
try {
props = msg.getProperties();
} catch (Exception ex) {
props = new Properties();
}
} else {
msgProcessCnt = 0;
}
boolean ack = msg.getSendAcknowledge();
long cid = msg.getConsumerID();
String refid = (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) ? msg.getSysMessageID().toString() : "";
boolean isIndemp = msg.getIndempotent();
String reason = null;
List failedrefs = null;
int status = Status.OK;
HashMap routedSet = null;
List<MessageDeliveryTimeInfo> deliveryDelayReadyList = new ArrayList<>();
boolean route = false;
Producer pausedProducer = null;
boolean transacted = false;
try {
pausedProducer = checkFlow(msg, con);
transacted = (msg.getTransactionID() != 0);
// OK .. handle Fault Injection
if (!isadmin && fi.FAULT_INJECTION) {
Map m = new HashMap();
if (props != null) {
m.putAll(props);
}
m.put("mqMsgCount", Integer.valueOf(msgProcessCnt));
m.put("mqIsTransacted", Boolean.valueOf(transacted));
fi.checkFaultAndExit(FaultInjection.FAULT_SEND_MSG_1, m, 2, false);
if (fi.checkFault(FaultInjection.FAULT_SEND_MSG_1_EXCEPTION, m)) {
fi.unsetFault(FaultInjection.FAULT_SEND_MSG_1_EXCEPTION);
throw new BrokerException("FAULT INJECTION: " + FaultInjection.FAULT_SEND_MSG_1_EXCEPTION);
}
if (fi.checkFaultAndSleep(FaultInjection.FAULT_SEND_MSG_1_SLEEP, m, true)) {
fi.unsetFault(FaultInjection.FAULT_SEND_MSG_1_SLEEP);
}
if (fi.checkFaultAndSleep(FaultInjection.FAULT_SEND_MSG_1_SLEEP_EXCEPTION, m, true)) {
fi.unsetFault(FaultInjection.FAULT_SEND_MSG_1_SLEEP_EXCEPTION);
throw new BrokerException("FAULT INJECTION: " + FaultInjection.FAULT_SEND_MSG_1_SLEEP_EXCEPTION);
}
}
DestinationUID realduid = DestinationUID.getUID(msg.getDestination(), msg.getIsQueue());
if (DEBUG) {
logger.log(Logger.INFO, "DataHandler:Received JMS Message[" + msg.toString() + " : " + realduid + "]TID=" + msg.getTransactionID() + " on connection " + con + ", isadmin=" + isadmin);
}
// get the list of "real" destination UIDs (this will be one if the
// destination if not a wildcard and 0 or more if it is
List[] dds = DL.findMatchingIDs(con.getPartitionedStore(), realduid);
List duids = dds[0];
boolean packetUsed = false;
if (duids.size() == 0) {
// nothing to do
route = false;
} else {
Iterator itr = duids.iterator();
while (itr.hasNext()) {
PacketReference ref = null;
Exception lastthr = null;
boolean isLast = false;
DestinationUID duid = (DestinationUID) itr.next();
isLast = !itr.hasNext();
Destination[] ds = DL.getDestination(con.getPartitionedStore(), duid);
Destination d = ds[0];
try {
if (d == null) {
throw new BrokerException("Unknown Destination:" + msg.getDestination());
}
if (realduid.isWildcard() && d.isTemporary()) {
logger.log(Logger.DEBUG, "L10N-XXX: Wildcard production with destination name of " + realduid + " to temporary destination " + d.getUniqueName() + " is not supported, ignoring");
continue;
}
if (realduid.isWildcard() && d.isInternal()) {
logger.log(Logger.DEBUG, "L10N-XXX: Wildcard production with destination name of " + realduid + " to internal destination " + d.getUniqueName() + " is not supported, ignoring");
continue;
}
if (realduid.isWildcard() && d.isDMQ()) {
logger.log(Logger.DEBUG, "L10N-XXX: Wildcard production with destination name of " + realduid + " to the DeadMessageQueue" + d.getUniqueName() + " is not supported, ignoring");
continue;
}
if (pausedProducer != null) {
pauseProducer(d, duid, pausedProducer, con);
pausedProducer = null;
}
if (packetUsed) {
// create a new Packet for the message
// we need a new sysmsgid with it
Packet newp = new Packet();
newp.fill(msg);
newp.generateSequenceNumber(true);
newp.generateTimestamp(true);
newp.prepareToSend();
newp.generateSequenceNumber(false);
newp.generateTimestamp(false);
msg = newp;
}
packetUsed = true;
// OK generate a ref. This checks message size and
// will be needed for later operations
ref = createReference(msg, duid, con, isadmin);
// dont bother calling route if there are no messages
//
// to improve performance, we route and later forward
route |= queueMessage(d, ref, transacted);
// ok ...
if (isLast && route && ack && !ref.isPersistent()) {
sendAcknowledge(refid, cid, status, con, reason, props, transacted);
ack = false;
}
Set s = routeMessage(con.getPartitionedStore(), transacted, ref, route, d, deliveryDelayReadyList);
if (s != null && !s.isEmpty()) {
if (routedSet == null) {
routedSet = new HashMap();
}
routedSet.put(ref, s);
}
// handle producer flow control
pauseProducer(d, duid, pausedProducer, con);
} catch (Exception ex) {
if (ref != null) {
if (failedrefs == null) {
failedrefs = new ArrayList();
}
failedrefs.add(ref);
}
lastthr = ex;
logger.log(Logger.DEBUG, BrokerResources.W_MESSAGE_STORE_FAILED, con.toString(), ex);
} finally {
if (pausedProducer != null) {
pauseProducer(d, duid, pausedProducer, con);
pausedProducer = null;
}
if (isLast && lastthr != null) {
throw lastthr;
}
}
}
// while
}
} catch (BrokerException ex) {
// dont log on dups if indemponent
int loglevel = (isIndemp && ex.getStatusCode() == Status.NOT_MODIFIED) ? Logger.DEBUG : Logger.WARNING;
logger.log(loglevel, BrokerResources.W_MESSAGE_STORE_FAILED, con.toString(), ex);
reason = ex.getMessage();
// LKS - we may want an improved error message in the wildcard case
status = ex.getStatusCode();
} catch (IOException ex) {
logger.log(Logger.WARNING, BrokerResources.W_MESSAGE_STORE_FAILED, con.toString(), ex);
reason = ex.getMessage();
status = Status.ERROR;
} catch (SecurityException ex) {
logger.log(Logger.WARNING, BrokerResources.W_MESSAGE_STORE_FAILED, con.toString(), ex);
reason = ex.getMessage();
status = Status.FORBIDDEN;
} catch (OutOfMemoryError err) {
logger.logStack(Logger.WARNING, BrokerResources.W_MESSAGE_STORE_FAILED, con.toString() + ":" + msg.getPacketSize(), err);
reason = err.getMessage();
status = Status.ERROR;
} catch (Exception ex) {
logger.logStack(Logger.WARNING, BrokerResources.W_MESSAGE_STORE_FAILED, con.toString(), ex);
reason = ex.getMessage();
status = Status.ERROR;
}
if (status == Status.ERROR && failedrefs != null) {
// make sure we remove the message
//
// NOTE: we only want to remove the last failure (its too late
// for the rest). In the non-wildcard case, this will be the
// only entry. In the wildcard cause, it will be the one that had an issue
Iterator itr = failedrefs.iterator();
while (itr.hasNext()) {
PacketReference ref = (PacketReference) itr.next();
Destination[] ds = DL.getDestination(con.getPartitionedStore(), ref.getDestinationUID());
Destination d = ds[0];
if (d != null) {
cleanupOnError(d, ref);
}
}
}
if (ack) {
sendAcknowledge(refid, cid, status, con, reason, props, transacted);
}
if (route && routedSet != null) {
Iterator<Map.Entry> itr = routedSet.entrySet().iterator();
Map.Entry pair = null;
while (itr.hasNext()) {
pair = itr.next();
PacketReference pktref = (PacketReference) pair.getKey();
DestinationUID duid = pktref.getDestinationUID();
Set s = (Set) pair.getValue();
Destination[] ds = DL.getDestination(con.getPartitionedStore(), duid);
Destination dest = ds[0];
if (dest == null) {
Object[] emsg = { pktref, s, duid };
logger.log(logger.WARNING, br.getKString(br.W_ROUTE_PRODUCED_MSG_DEST_NOT_FOUND, emsg));
continue;
}
try {
forwardMessage(dest, pktref, s);
} catch (Exception e) {
Object[] emsg = { pktref, duid, s };
logger.logStack(logger.WARNING, br.getKString(br.X_ROUTE_PRODUCED_MSG_FAIL, emsg), e);
}
}
}
if (deliveryDelayReadyList.size() > 0) {
MessageDeliveryTimeInfo di = null;
Iterator<MessageDeliveryTimeInfo> itr = deliveryDelayReadyList.iterator();
while (itr.hasNext()) {
di = itr.next();
di.setDeliveryReady();
}
}
// someone else will free
return isadmin;
}
use of com.sun.messaging.jmq.jmsserver.core.MessageDeliveryTimeInfo in project openmq by eclipse-ee4j.
the class DataHandler method routeMessage.
public Set routeMessage(PartitionedStore storep, boolean transacted, PacketReference ref, boolean route, Destination d, List<MessageDeliveryTimeInfo> readylist) throws BrokerException, SelectorFormatException {
String reason = null;
int status = Status.OK;
Set s = null;
MessageDeliveryTimeInfo di = ref.getDeliveryTimeInfo();
// if transacted, just store, dont route
if (transacted) {
try {
TransactionList[] tls = DL.getTransactionList(storep);
TransactionList tl = tls[0];
tl.addMessage(ref);
} catch (Exception ex) {
String emsg = br.getKString(br.X_PROCESS_PRODUCED_MESSAGE_FAIL, ref + "[TID=" + ref.getTransactionID() + ", " + di + "]", ex.getMessage());
ref.destroy();
logger.logStack((BrokerStateHandler.isShuttingDown() ? Logger.DEBUG : Logger.WARNING), emsg, ex);
reason = emsg;
status = Status.ERROR;
throw new BrokerException(reason, status);
}
} else {
if (route) {
if (di != null && di.getOnTimerState() != null) {
d.routeNewMessageWithDeliveryDelay(ref);
readylist.add(di);
} else {
s = d.routeNewMessage(ref);
}
}
}
return s;
}
use of com.sun.messaging.jmq.jmsserver.core.MessageDeliveryTimeInfo in project openmq by eclipse-ee4j.
the class TransactionHandler method doCommit.
/**
* Commit a transaction. This method is invoked from two places: 1) From TransactionHandler.handle() when handling a
* client COMMIT packet. This is the common case. 2) From the admin handler when an admin commit request has been issued
* on a PREPARED XA transaction.
*
* @param id The TransactionUID to commit
* @param xid The Xid of the transaction to commit. Required if transaction is an XA transaction. Must be null if it is
* not an XA transaction.
* @param xaFlags xaFlags passed on COMMIT operation. Used only if an XA transaction.
* @param ts Current TransactionState of this transaction.
* @param conlist List of transactions on this connection. Will be null if commit is trigger by an admin request.
* @param sendReply True to have method send a Status.OK reply while processing transaction. This should be "true" for
* client initiated commits, "false" for admin initiated commits.
* @param con Connection client commit packet came in on or, for admin, the connection the admin request came in on.
* @param msg Client commit packet. Should be "null" for admin initiated commits.
*
* @throws BrokerException on an error. The method will have logged a message to the broker log.
*/
public void doCommit(TransactionList translist, TransactionUID id, JMQXid xid, Integer xaFlags, TransactionState ts, List conlist, boolean sendReply, IMQConnection con, Packet msg, boolean startNextTransaction) throws BrokerException {
int status = Status.OK;
HashMap cmap = null;
HashMap sToCmap = null;
List plist = null;
PartitionedStore pstore = translist.getPartitionedStore();
// local, or cluster
int transactionType = BaseTransaction.UNDEFINED_TRANSACTION_TYPE;
if (fi.checkFault(FaultInjection.FAULT_TXN_COMMIT_1_EXCEPTION, null)) {
fi.unsetFault(FaultInjection.FAULT_TXN_COMMIT_1_EXCEPTION);
throw new BrokerException(FaultInjection.FAULT_TXN_COMMIT_1_EXCEPTION);
}
// let acks get handled at a lower level since the
// lower level methods assumes only 1 ack per message
plist = translist.retrieveSentMessages(id);
cmap = translist.retrieveConsumedMessages(id);
sToCmap = translist.retrieveStoredConsumerUIDs(id);
cacheSetState(id, ts, con);
// remove from our active connection list
if (conlist != null) {
conlist.remove(id);
}
try {
Globals.getStore().txnLogSharedLock.lock();
TransactionWork txnWork = null;
if (Globals.isNewTxnLogEnabled()) {
txnWork = getTransactionWork2(translist.getPartitionedStore(), plist, cmap, sToCmap);
}
// Update transaction state
try {
int s;
if (xid == null) {
// Plain JMS transaction.
s = TransactionState.COMMITTED;
} else {
// XA Transaction.
s = ts.nextState(PacketType.COMMIT_TRANSACTION, xaFlags);
}
// After this call, returned base transaction will either be:
// a) null (for single phase LOCAL transaction)
// b) a prepared XA LOCAL transaction
// c) a prepared (XA or not) CLUSTER transaction
// currently, all cluster transactions are 2 phase
BaseTransaction baseTransaction = doRemoteCommit(translist, id, xaFlags, ts, s, msg, txnWork, con);
if (Globals.isNewTxnLogEnabled()) {
if (ts.getState() == TransactionState.PREPARED) {
// commit called (from client) on 2-phase transaction
transactionType = BaseTransaction.LOCAL_TRANSACTION_TYPE;
if (translist.isClusterTransaction(id)) {
transactionType = BaseTransaction.CLUSTER_TRANSACTION_TYPE;
}
logTxnCompletion(translist.getPartitionedStore(), id, TransactionState.COMMITTED, transactionType);
} else if ((baseTransaction != null && baseTransaction.getState() == TransactionState.PREPARED)) {
transactionType = baseTransaction.getType();
logTxnCompletion(translist.getPartitionedStore(), id, TransactionState.COMMITTED, transactionType);
} else {
// one phase commit, log all work here
transactionType = BaseTransaction.LOCAL_TRANSACTION_TYPE;
LocalTransaction localTxn = new LocalTransaction(id, TransactionState.COMMITTED, xid, txnWork);
logTxn(translist.getPartitionedStore(), localTxn);
}
} else {
// System.out.println("isFastLogTransactions=false ");
}
if (fi.FAULT_INJECTION) {
fi.checkFaultAndThrowBrokerException(FaultInjection.FAULT_TXN_COMMIT_1_1, null);
}
if (ts.getState() == TransactionState.PREPARED || (baseTransaction != null && baseTransaction.getState() == TransactionState.PREPARED)) {
translist.updateState(id, s, true);
} else {
// 1-phase commit
if (ts.getType() != AutoRollbackType.NEVER && Globals.isMinimumPersistLevel2()) {
translist.updateStateCommitWithWork(id, s, true);
} else {
translist.updateState(id, s, true);
}
}
if (fi.FAULT_INJECTION) {
checkFIAfterDB(PacketType.COMMIT_TRANSACTION);
fi.checkFaultAndExit(FaultInjection.FAULT_TXN_COMMIT_1_5, null, 2, false);
}
startTxnAndSendReply(translist, con, msg, status, startNextTransaction, conlist, xid, id, xaFlags, sendReply);
} catch (BrokerException ex) {
logger.logStack(((ex instanceof AckEntryNotFoundException) ? Logger.WARNING : Logger.ERROR), ex.toString() + ": TUID=" + id + " Xid=" + xid, ex);
throw ex;
}
try {
/*
* Can't really call the JMX notification code at the end of doCommit() because the call to
* translist.removeTransactionID(id) removes the MBean.
*/
Agent agent = Globals.getAgent();
if (agent != null) {
agent.notifyTransactionCommit(id);
}
} catch (Exception e) {
logger.log(Logger.WARNING, "JMX agent notify transaction committed failed:" + e.getMessage());
}
// OK .. handle producer transaction
int pLogRecordByteCount = 0;
ArrayList pLogMsgList = null;
for (int i = 0; plist != null && i < plist.size(); i++) {
SysMessageID sysid = (SysMessageID) plist.get(i);
PacketReference ref = DL.get(pstore, sysid);
if (ref == null) {
logger.log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_MSG_REMOVED_BEFORE_SENDER_COMMIT, sysid));
continue;
}
// handle forwarding the message
try {
if (Globals.txnLogEnabled()) {
if (pLogMsgList == null) {
pLogMsgList = new ArrayList();
}
// keep track for producer txn log
pLogRecordByteCount += ref.getSize();
pLogMsgList.add(ref.getPacket().getBytes());
}
Destination[] ds = DL.getDestination(pstore, ref.getDestinationUID());
Destination d = ds[0];
if (fi.FAULT_INJECTION) {
fi.checkFaultAndExit(FaultInjection.FAULT_TXN_COMMIT_1_6, null, 2, false);
}
MessageDeliveryTimeInfo di = ref.getDeliveryTimeInfo();
if (di != null) {
d.routeCommittedMessageWithDeliveryTime(ref);
} else {
Set s = d.routeNewMessage(ref);
d.forwardMessage(s, ref);
}
} catch (Exception ex) {
logger.logStack((BrokerStateHandler.isShuttingDown() ? Logger.DEBUG : Logger.ERROR), ex.getMessage() + "[" + sysid + "]TUID=" + id, ex);
}
}
boolean processDone = true;
// handle consumer transaction
int cLogRecordCount = 0;
ArrayList cLogDstList = null;
ArrayList cLogMsgList = null;
ArrayList cLogIntList = null;
HashMap<TransactionBroker, Object> remoteNotified = new HashMap<>();
if (cmap != null && cmap.size() > 0) {
Iterator itr = cmap.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
SysMessageID sysid = (SysMessageID) entry.getKey();
// CANT just pull from connection
if (sysid == null) {
continue;
}
PacketReference ref = DL.get(null, sysid);
if (ref == null || ref.isDestroyed() || ref.isInvalid()) {
// already been deleted .. ignore
continue;
}
PartitionedStore refpstore = ref.getPartitionedStore();
Destination[] ds = DL.getDestination(refpstore, ref.getDestinationUID());
Destination dst = ds[0];
if (dst == null) {
if (ref.isDestroyed() || ref.isInvalid()) {
continue;
}
}
List interests = (List) entry.getValue();
for (int i = 0; i < interests.size(); i++) {
ConsumerUID intid = (ConsumerUID) interests.get(i);
ConsumerUID sid = (ConsumerUID) sToCmap.get(intid);
if (sid == null) {
sid = intid;
}
try {
Session s = Session.getSession(intid);
if (s != null) {
Consumer c = Consumer.getConsumer(intid);
if (c != null) {
c.messageCommitted(sysid);
}
PacketReference r1 = null;
if (fi.FAULT_INJECTION && fi.checkFault(FaultInjection.FAULT_TXN_COMMIT_1_7_1, null)) {
Globals.getConnectionManager().getConnection(s.getConnectionUID()).destroyConnection(true, GoodbyeReason.OTHER, "Fault injection of closing connection");
}
r1 = (PacketReference) s.ackMessage(intid, sysid, id, translist, remoteNotified, true);
try {
s.postAckMessage(intid, sysid, true);
if (r1 != null) {
if (fi.FAULT_INJECTION) {
fi.checkFaultAndExit(FaultInjection.FAULT_TXN_COMMIT_1_7, null, 2, false);
}
if (dst != null) {
dst.removeMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED);
}
} else {
s = Session.getSession(intid);
}
} finally {
if (r1 != null) {
r1.postAcknowledgedRemoval();
}
}
}
if (s == null) {
// with the stored UID
try {
if (ref.acknowledged(intid, sid, true, true, id, translist, remoteNotified, true)) {
try {
if (dst != null) {
dst.removeMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED);
}
} finally {
ref.postAcknowledgedRemoval();
}
}
} catch (BrokerException ex) {
// XXX improve internal error
logger.log(Logger.WARNING, "Internal error", ex);
}
}
if (Globals.txnLogEnabled()) {
if (cLogDstList == null) {
cLogDstList = new ArrayList();
cLogMsgList = new ArrayList();
cLogIntList = new ArrayList();
}
// ignore non-durable subscriber
if (dst == null || (!dst.isQueue() && !sid.shouldStore())) {
continue;
}
cLogRecordCount++;
cLogDstList.add(dst.getUniqueName());
cLogMsgList.add(sysid);
cLogIntList.add(sid);
}
} catch (Exception ex) {
processDone = false;
String[] args = { "[" + sysid + ":" + intid + ", " + dst + "]ref=" + ref.getSysMessageID(), id.toString(), con.getConnectionUID().toString() };
String emsg = Globals.getBrokerResources().getKString(BrokerResources.W_PROCCESS_COMMITTED_ACK, args);
logger.logStack(Logger.WARNING, emsg + "\n" + com.sun.messaging.jmq.io.PacketUtil.dumpPacket(msg) + "--------------------------------------------", ex);
}
}
}
}
if (Globals.isNewTxnLogEnabled()) {
// notify that transaction work has been written to message store
loggedCommitWrittenToMessageStore(translist.getPartitionedStore(), id, transactionType);
}
if (fi.FAULT_INJECTION) {
checkFIAfterDB(PacketType.COMMIT_TRANSACTION);
fi.checkFaultAndExit(FaultInjection.FAULT_TXN_COMMIT_2_1, null, 2, false);
}
// OK .. now remove the acks .. and free up the id for ues
// XXX Fixed 6383878, memory leaks because txn ack can never be removed
// from the store if the txn is removed before the ack; this is due
// to the fack that in 4.0 when removing the ack, the method check
// to see if the txn still exits in the cache. This temporary fix
// will probably break some HA functionality and need to be revisited.
translist.removeTransaction(id, (!processDone || (cmap.size() > 0 && BrokerStateHandler.isShuttingDown())));
if (conlist == null) {
// from admin
logger.log(logger.WARNING, BrokerResources.W_ADMIN_COMMITTED_TXN, id, ((xid == null) ? "null" : xid.toString()));
}
// log to txn log if enabled
try {
if (pLogRecordByteCount > 0 && cLogRecordCount > 0) {
// Log all msgs and acks for producing and consuming txn
ByteArrayOutputStream bos = new ByteArrayOutputStream((pLogRecordByteCount) + (cLogRecordCount * (32 + SysMessageID.ID_SIZE + 8)) + 16);
DataOutputStream dos = new DataOutputStream(bos);
// Transaction ID (8 bytes)
dos.writeLong(id.longValue());
// Msgs produce section
// Number of msgs (4 bytes)
dos.writeInt(pLogMsgList.size());
Iterator itr = pLogMsgList.iterator();
while (itr.hasNext()) {
// Message
dos.write((byte[]) itr.next());
}
// Msgs consume section
// 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);
ConsumerUID intid = (ConsumerUID) cLogIntList.get(i);
// ConsumerUID
dos.writeLong(intid.longValue());
}
dos.close();
bos.close();
((TxnLoggingStore) pstore).logTxn(TransactionLogType.PRODUCE_AND_CONSUME_TRANSACTION, bos.toByteArray());
} else if (pLogRecordByteCount > 0) {
// Log all msgs for producing txn
ByteBuffer bbuf = ByteBuffer.allocate(pLogRecordByteCount + 12);
// Transaction ID (8 bytes)
bbuf.putLong(id.longValue());
// Number of msgs (4 bytes)
bbuf.putInt(pLogMsgList.size());
Iterator itr = pLogMsgList.iterator();
while (itr.hasNext()) {
// Message
bbuf.put((byte[]) itr.next());
}
((TxnLoggingStore) pstore).logTxn(TransactionLogType.PRODUCE_TRANSACTION, bbuf.array());
} else if (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(id.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);
ConsumerUID intid = (ConsumerUID) cLogIntList.get(i);
// ConsumerUID
dos.writeLong(intid.longValue());
}
dos.close();
bos.close();
((TxnLoggingStore) pstore).logTxn(TransactionLogType.CONSUME_TRANSACTION, bos.toByteArray());
}
} catch (IOException ex) {
logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Got exception while writing to transaction log", ex);
throw new BrokerException("Got exception while writing to transaction log", ex);
}
} finally {
// release lock
Globals.getStore().txnLogSharedLock.unlock();
}
}
use of com.sun.messaging.jmq.jmsserver.core.MessageDeliveryTimeInfo in project openmq by eclipse-ee4j.
the class TransactionLogReplayer method rerouteMessage.
private void rerouteMessage(Packet pkt, SysMessageID mid, Destination dst) throws BrokerException {
// TO DO
// This should use existing routing
logger.log(Logger.FORCE, BrokerResources.I_RECONSTRUCT_MSG_TXNLOG, mid, dst + " [reroute]");
PacketReference pr = PacketReference.createReferenceWithDestination(msgStore.parent, pkt, dst, null);
if (pr.isExpired()) {
String msg = "not routing expired message on transaction log replay " + mid;
logger.log(Logger.INFO, msg);
return;
}
try {
dst.queueMessage(pr, false);
MessageDeliveryTimeInfo di = pr.getDeliveryTimeInfo();
if (di == null || di.getOnTimerState() == null) {
dst.routeNewMessage(pr);
} else {
di.setDeliveryReady();
}
} catch (SelectorFormatException e) {
// shouldn't happens
throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.E_ROUTE_RECONSTRUCTED_MSG_FAILED, mid), e);
}
}
Aggregations