use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class ProtocolImpl method resumeSession.
/**
* Resume a session
* <P>
* Packet:<B>START</b>
* </p>
*
* @param uid session to resume
*/
@Override
public void resumeSession(SessionUID uid) throws BrokerException {
Session ses = Session.getSession(uid);
if (ses == null) {
throw new BrokerException("No session for " + uid);
}
ses.resume("PROTOCOL");
}
use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class AckHandler method handleTransaction.
public void handleTransaction(TransactionList translist, IMQConnection con, TransactionUID tid, SysMessageID[] ids, ConsumerUID[] cids, int deliverCnt) throws BrokerException {
for (int i = 0; i < ids.length; i++) {
Consumer consumer = null;
try {
// lookup the session by consumerUID
Session s = Session.getSession(cids[i]);
// look up the consumer by consumerUID
consumer = Consumer.getConsumer(cids[i]);
if (consumer == null) {
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.I_ACK_FAILED_NO_CONSUMER, cids[i]) + "[TID=" + tid + "]", Status.NOT_FOUND);
}
// try and find the stored consumerUID
ConsumerUID sid = consumer.getStoredConsumerUID();
// if we still dont have a session, attempt to find one
if (s == null) {
SessionUID suid = consumer.getSessionUID();
s = Session.getSession(suid);
}
if (s == null) {
if (BrokerStateHandler.isShutdownStarted()) {
throw new BrokerException(BrokerResources.I_ACK_FAILED_BROKER_SHUTDOWN);
}
throw new BrokerException(br.getKString(br.I_ACK_FAILED_NO_SESSION, "[" + ids[i] + ", " + cids[i] + "]TID=" + tid));
}
if (DEBUG) {
logger.log(logger.INFO, "handleTransaction.addAck[" + i + ", " + ids.length + "]:tid=" + tid + ", sysid=" + ids[i] + ", cid=" + cids[i] + ", sid=" + sid + " on connection " + con);
}
boolean isxa = translist.addAcknowledgement(tid, ids[i], cids[i], sid);
BrokerAddress addr = (BrokerAddress) s.ackInTransaction(cids[i], ids[i], tid, isxa, deliverCnt);
if (addr != null && addr != Globals.getMyAddress()) {
translist.setAckBrokerAddress(tid, ids[i], cids[i], addr);
}
if (fi.FAULT_INJECTION) {
if (fi.checkFault(fi.FAULT_TXN_ACK_1_5, null)) {
fi.unsetFault(fi.FAULT_TXN_ACK_1_5);
TransactionAckExistException tae = new TransactionAckExistException("FAULT:" + fi.FAULT_TXN_ACK_1_5, Status.GONE);
tae.setRemoteConsumerUIDs(String.valueOf(cids[i].longValue()));
tae.setRemote(true);
consumer.recreationRequested();
throw tae;
}
}
} catch (Exception ex) {
String emsg = "[" + ids[i] + ", " + cids[i] + "]TUID=" + tid;
if ((ex instanceof BrokerException) && ((BrokerException) ex).getStatusCode() != Status.ERROR) {
logger.log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.E_TRAN_ACK_PROCESSING_FAILED, emsg, ex.getMessage()), ex);
} else {
logger.log(Logger.ERROR, Globals.getBrokerResources().getKString(BrokerResources.E_TRAN_ACK_PROCESSING_FAILED, emsg, ex.getMessage()), ex);
}
int state = -1;
JMQXid xid = null;
try {
TransactionState ts = translist.retrieveState(tid);
if (ts != null) {
state = ts.getState();
xid = ts.getXid();
}
translist.updateState(tid, TransactionState.FAILED, true);
} catch (Exception e) {
if (!(e instanceof UnknownTransactionException)) {
String[] args = { TransactionState.toString(state), TransactionState.toString(TransactionState.FAILED), tid.toString(), (xid == null ? "null" : xid.toString()) };
logger.log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_UPDATE_TRAN_STATE_FAIL, args));
}
}
if (ex instanceof TransactionAckExistException) {
PacketReference ref = DL.get(null, ids[i]);
if (ref != null && (ref.isOverrided() || ref.isOverriding())) {
((BrokerException) ex).overrideStatusCode(Status.GONE);
((BrokerException) ex).setRemoteConsumerUIDs(String.valueOf(cids[i].longValue()));
((BrokerException) ex).setRemote(true);
consumer.recreationRequested();
}
}
if (ex instanceof BrokerException) {
throw (BrokerException) ex;
}
throw new BrokerException("Internal Error: Unable to " + " complete processing acknowledgements in a tranaction: " + ex, ex);
}
}
}
use of com.sun.messaging.jmq.jmsserver.core.Session 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.Session in project openmq by eclipse-ee4j.
the class ConsumerHandler method handle.
/**
* Method to handle Consumer(add or delete) messages
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
boolean sessionPaused = false;
boolean conPaused = false;
Hashtable props = null;
try {
props = msg.getProperties();
} catch (Exception ex) {
logger.logStack(Logger.WARNING, "Unable to retrieve " + " properties from consumer message " + msg, ex);
}
if (props == null) {
props = new Hashtable();
}
Long lsessionid = (Long) props.get("JMQSessionID");
Session session = null;
String err_reason = null;
Boolean blockprop = (Boolean) props.get("JMQBlock");
Consumer newc = null;
assert blockprop == null || msg.getPacketType() == PacketType.DELETE_CONSUMER : msg;
boolean blockprop_bool = (blockprop != null && blockprop.booleanValue());
boolean isIndemp = msg.getIndempotent();
// OK ... set up the reply packet
Packet pkt = new Packet(con.useDirectBuffers());
// correlation ID
pkt.setConsumerID(msg.getConsumerID());
Hashtable hash = new Hashtable();
pkt.setPacketType(msg.getPacketType() + 1);
int status = Status.OK;
String warning = BrokerResources.W_ADD_CONSUMER_FAILED;
ConsumerUID uid = null;
Integer oldid = null;
Subscription sub = null;
try {
DL.acquirePartitionLock(true);
try {
con.suspend();
conPaused = true;
if (msg.getPacketType() == PacketType.ADD_CONSUMER) {
if (DEBUG) {
logger.log(Logger.INFO, "ConsumerHandler: " + "[Received AddConsumer message {0}]", msg.toString());
}
pkt.setPacketType(PacketType.ADD_CONSUMER_REPLY);
if (lsessionid == null) {
if (DEBUG) {
logger.log(Logger.INFO, "ConsumerHandler: not Raptor consumer packet (no session id)");
}
// assign session same # as consumer
SessionUID sessionID = new SessionUID(con.getConnectionUID().longValue());
// single threaded .. we dont have to worry about
// someone else creating it
session = con.getSession(sessionID);
if (session == null) {
session = Session.createSession(sessionID, con.getConnectionUID(), null, coreLifecycle);
con.attachSession(session);
}
} else {
SessionUID sessionID = new SessionUID(lsessionid.longValue());
session = con.getSession(sessionID);
if (session == null) {
throw new BrokerException("Internal Error: client set invalid" + " sessionUID " + sessionID + " session does not exist");
}
}
if (blockprop_bool) {
// turn off all processing
session.pause("Consumer - Block flag");
sessionPaused = true;
}
/* XXX-LKS KLUDGE FOR 2.0 compatibility */
// for now, we just pass the consumer ID back on the old
// packet .. I need to revisit this in the future
// old consumer ID
oldid = (Integer) props.get("JMQConsumerID");
if (oldid != null) {
hash.put("JMQOldConsumerID", oldid);
}
Integer inttype = (Integer) props.get("JMQDestType");
int type = (inttype == null ? -1 : inttype.intValue());
if (type == -1) {
throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, "Client is not sending DestType, " + "unable to add interest"));
}
boolean queue = DestType.isQueue(type);
String destination = (String) props.get("JMQDestination");
String selector = (String) props.get("JMQSelector");
// JMS spec
if (selector != null && selector.trim().length() == 0) {
selector = null;
}
boolean mqshare = false;
// JMS2.0
boolean jmsshare = false;
boolean nolocal = false;
Boolean b = (Boolean) props.get("JMQNoLocal");
if (b != null && b.booleanValue()) {
nolocal = true;
}
b = (Boolean) props.get("JMQShare");
if (b != null && b.booleanValue()) {
mqshare = true;
}
// JMS2.0
b = (Boolean) props.get("JMQJMSShare");
if (b != null && b.booleanValue()) {
jmsshare = true;
}
String durablename = (String) props.get("JMQDurableName");
// JMS2.0
String subscriptionName = (String) props.get("JMQSharedSubscriptionName");
String clientid = getClientID(props, con);
Boolean reconnect = (Boolean) props.get("JMQReconnect");
Integer size = (Integer) props.get("JMQSize");
if (mqshare && jmsshare) {
String emsg = "Client protocol error: both JMQShare and JMQJMSShare set to true";
Globals.getLogger().log(Logger.ERROR, emsg);
throw new BrokerException(emsg);
}
boolean shared = (mqshare || jmsshare);
boolean durable = false;
if (durablename != null) {
if (subscriptionName != null) {
Object[] args = { Subscription.getDSubLogString(clientid, durablename), "" + destination, subscriptionName };
logger.log(Logger.INFO, br.getKString(br.I_ADD_CONSUMER_IGNORE_SUBSCRIPTION_NAME, args));
}
subscriptionName = durablename;
durable = true;
}
if (DestType.isTemporary(type)) {
if (durable) {
String emsg = br.getKString(br.X_INVALID_DEST_DURA_CONSUMER, "" + destination, "" + subscriptionName);
logger.log(Logger.ERROR, emsg);
throw new BrokerException(emsg, br.X_INVALID_DEST_DURA_CONSUMER, null, Status.PRECONDITION_FAILED);
}
if (shared) {
String emsg = br.getKString(br.X_INVALID_DEST_SHARE_CONSUMER, "" + destination, "" + subscriptionName);
logger.log(Logger.ERROR, emsg);
throw new BrokerException(emsg, br.X_INVALID_DEST_SHARE_CONSUMER, null, Status.PRECONDITION_FAILED);
}
}
ConsumerParameters pm = new ConsumerParameters();
pm.isqueue = queue;
pm.destination = destination;
pm.selector = selector;
pm.clientid = clientid;
pm.subscriptionName = subscriptionName;
pm.durable = durable;
pm.shared = shared;
pm.jmsshare = jmsshare;
pm.nolocal = nolocal;
checkSubscriptionName(pm);
checkClientID(pm);
checkNoLocal(pm);
if (reconnect != null && reconnect.booleanValue()) {
Globals.getLogger().log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "JMQReconnect not implemented");
}
// see if we are a wildcard destination
DestinationUID dest_uid = null;
Destination d = null;
if (DestinationUID.isWildcard(destination)) {
// dont create a destination
dest_uid = DestinationUID.getUID(destination, DestType.isQueue(type));
} else {
Destination[] ds = null;
while (true) {
ds = DL.getDestination(con.getPartitionedStore(), destination, type, true, /* autocreate if possible */
!con.isAdminConnection());
// PART
d = ds[0];
if (d == null) {
break;
}
if (d.isAutoCreated()) {
warning = BrokerResources.W_ADD_AUTO_CONSUMER_FAILED;
}
try {
d.incrementRefCount();
} catch (BrokerException ex) {
// was destroyed in process
continue;
} catch (IllegalStateException ex) {
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_SHUTTING_DOWN_BROKER), BrokerResources.X_SHUTTING_DOWN_BROKER, ex, Status.ERROR);
}
// we got one
break;
}
if (d == null) {
// unable to autocreate destination
status = Status.NOT_FOUND;
// XXX error
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_DESTINATION_NOT_FOUND, destination), BrokerResources.X_DESTINATION_NOT_FOUND, null, Status.NOT_FOUND);
}
dest_uid = d.getDestinationUID();
}
if (jmsshare && mqshare) {
Object[] args = { "JMS", (!durable ? Subscription.getNDSubLongLogString(clientid, dest_uid, selector, subscriptionName, nolocal) : Subscription.getDSubLogString(clientid, subscriptionName)), "" + destination, "JMQShare" };
logger.log(Logger.INFO, br.getKString(br.I_ADD_SHARE_CONSUMER_IGNORE_CLIENT_FLAG, args));
mqshare = false;
}
Consumer c = null;
try {
// LKS
Consumer[] retc = _createConsumer(dest_uid, con, session, selector, clientid, subscriptionName, durable, shared, jmsshare, nolocal, (size == null ? -1 : size.intValue()), msg.getSysMessageID().toString(), isIndemp, true);
c = retc[0];
newc = retc[1];
sub = (Subscription) retc[2];
if (c.getPrefetch() != -1 || size != null) {
hash.put("JMQSize", c.getPrefetch());
}
} catch (SelectorFormatException ex) {
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.W_SELECTOR_PARSE, "" + selector), BrokerResources.W_SELECTOR_PARSE, ex, Status.BAD_REQUEST);
} catch (OutOfLimitsException ex) {
if (d != null && d.isQueue()) {
String[] args = { dest_uid.getName(), String.valueOf(d.getActiveConsumerCount()), String.valueOf(d.getFailoverConsumerCount()) };
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_S_QUEUE_ATTACH_FAILED, args), BrokerResources.X_S_QUEUE_ATTACH_FAILED, ex, Status.CONFLICT);
} else {
// durable
String[] args = { Subscription.getDSubLogString(clientid, durablename), dest_uid.getName(), String.valueOf(ex.getLimit()) };
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_S_DUR_ATTACH_FAILED, args), BrokerResources.X_S_DUR_ATTACH_FAILED, ex, Status.CONFLICT);
}
} finally {
if (d != null) {
d.decrementRefCount();
}
}
// add the consumer to the session
Integer acktype = (Integer) props.get("JMQAckMode");
if (acktype != null) {
c.getConsumerUID().setAckType(acktype.intValue());
}
uid = c.getConsumerUID();
if (props.get("JMQOldConsumerID") != null) {
Object[] args = { uid + (sub == null ? "" : "[" + sub + "]"), "" + dest_uid, props.get("JMQOldConsumerID") };
logger.log(Logger.INFO, br.getKString(br.I_CREATED_NEW_CONSUMER_FOR_OLD, args));
}
} else {
// removing Interest
if (DEBUG) {
logger.log(Logger.INFO, "ConsumerHandler: " + "[Received DestroyConsumer message {0}]", msg.toString());
}
warning = BrokerResources.W_DESTROY_CONSUMER_FAILED;
pkt.setPacketType(PacketType.DELETE_CONSUMER_REPLY);
String durableName = (String) props.get("JMQDurableName");
String clientID = getClientID(props, con);
Long cid = (Long) props.get("JMQConsumerID");
uid = (cid == null ? null : new ConsumerUID(cid.longValue()));
if (lsessionid != null) {
// passed on in
SessionUID sessionID = new SessionUID(lsessionid.longValue());
session = con.getSession(sessionID);
} else {
session = Session.getSession(uid);
}
if (session == null && durableName == null && !isIndemp) {
if (con.getConnectionState() < Connection.STATE_CLEANED) {
logger.log(Logger.ERROR, br.getKString(br.E_UNEXPECTED_EXCEPTION, br.getKString(br.E_DELETE_CONSUMER_NO_SESSION, (lsessionid == null ? "" : lsessionid), uid + "") + "\n" + com.sun.messaging.jmq.io.PacketUtil.dumpPacket(msg)));
Session.dumpAll();
}
}
// retrieve the LastDelivered property
Integer bodytype = (Integer) props.get("JMQBodyType");
int btype = (bodytype == null ? 0 : bodytype.intValue());
SysMessageID lastid = null;
boolean lastidInTransaction = false;
if (btype == PacketType.SYSMESSAGEID) {
int size = msg.getMessageBodySize();
if (size == 0) {
logger.log(Logger.INFO, "Warning, bad body in destroy consumer");
} else {
DataInputStream is = new DataInputStream(msg.getMessageBodyStream());
lastid = new SysMessageID();
lastid.readID(is);
Boolean val = (Boolean) props.get("JMQLastDeliveredIDInTransaction");
lastidInTransaction = (val != null && val.booleanValue());
}
}
if (DEBUG && lastid != null) {
logger.log(Logger.INFO, "ConsumerHandler: destroy consumer with lastID [" + lastid + ", " + lastidInTransaction + "]" + DL.get(con.getPartitionedStore(), lastid) + " for consumer " + uid);
}
Boolean rAll = (Boolean) props.get("JMQRedeliverAll");
boolean redeliverAll = rAll != null && rAll.booleanValue();
if (!sessionPaused && session != null) {
sessionPaused = true;
session.pause("Consumer removeconsumer");
}
destroyConsumer(con, session, uid, durableName, clientID, lastid, lastidInTransaction, redeliverAll, isIndemp);
}
} finally {
DL.releasePartitionLock(true);
}
} catch (BrokerException ex) {
status = ex.getStatusCode();
String consumid = null;
String destination = null;
try {
destination = (String) props.get("JMQDestination");
if (destination == null && msg.getPacketType() != PacketType.ADD_CONSUMER) {
destination = "";
}
if (oldid != null) {
consumid = oldid.toString();
} else {
consumid = "";
}
} catch (Exception ex1) {
}
String[] args = { consumid, con.getRemoteConnectionString(), destination };
err_reason = ex.getMessage();
if (ex.getStatusCode() == Status.PRECONDITION_FAILED || ex.getStatusCode() == Status.CONFLICT) {
logger.log(Logger.WARNING, warning, args, ex);
} else if (ex.getStatusCode() == Status.BAD_REQUEST) {
// Probably a bad selector
logger.log(Logger.WARNING, warning, args, ex);
if (ex.getCause() != null) {
logger.log(Logger.INFO, ex.getCause().toString());
}
} else {
if (isIndemp && msg.getPacketType() == PacketType.DELETE_CONSUMER) {
logger.logStack(Logger.DEBUG, "Reprocessing Indempotent message for " + "{0} on destination {2} from {1}", args, ex);
status = Status.OK;
err_reason = null;
} else {
logger.logStack(Logger.WARNING, warning, args, ex);
}
}
} catch (IOException ex) {
logger.logStack(Logger.WARNING, "Unable to process " + " consumer request " + msg, ex);
err_reason = ex.getMessage();
assert false;
} catch (SecurityException ex) {
status = Status.FORBIDDEN;
err_reason = ex.getMessage();
String destination = null;
String consumid = null;
try {
destination = (String) props.get("JMQDestination");
if (oldid != null) {
consumid = oldid.toString();
}
} catch (Exception ex1) {
}
logger.log(Logger.WARNING, warning, destination, consumid, ex);
} finally {
if (conPaused) {
con.resume();
}
}
hash.put("JMQStatus", Integer.valueOf(status));
if (err_reason != null) {
hash.put("JMQReason", err_reason);
}
if (uid != null) {
hash.put("JMQConsumerID", Long.valueOf(uid.longValue()));
}
if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
hash.put("JMQReqID", msg.getSysMessageID().toString());
}
pkt.setProperties(hash);
con.sendControlMessage(pkt);
if (sessionPaused) {
session.resume("Consumer - session was paused");
}
if (sub != null) {
sub.resume("Consumer - added to sub");
}
if (newc != null) {
newc.resume("Consumer - new consumer");
}
return true;
}
use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class ProducerHandler method handle.
/**
* Method to handle Producers
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
Packet reply = new Packet(con.useDirectBuffers());
reply.setPacketType(msg.getPacketType() + 1);
reply.setConsumerID(msg.getConsumerID());
boolean isIndemp = msg.getIndempotent();
int status = Status.OK;
String reason = null;
Hashtable props = null;
try {
props = msg.getProperties();
} catch (Exception ex) {
throw new RuntimeException("Can not load props", ex);
}
Hashtable returnprop = new Hashtable();
Destination d = null;
try {
if (msg.getPacketType() == PacketType.ADD_PRODUCER) {
String dest = (String) props.get("JMQDestination");
Integer type = (Integer) props.get("JMQDestType");
if (!con.isAdminConnection() && MemoryGlobals.getMEM_DISALLOW_PRODUCERS()) {
status = Status.ERROR;
reason = "Low memory";
logger.log(Logger.WARNING, BrokerResources.W_LOW_MEM_REJECT_PRODUCER);
throw new BrokerException(reason, status);
}
Long lsessionid = (Long) props.get("JMQSessionID");
if (lsessionid != null) {
// 3.5 protocol
SessionUID sessionID = new SessionUID(lsessionid.longValue());
// single threaded .. we dont have to worry about
// someone else creating it
Session session = con.getSession(sessionID);
if (session == null) {
throw new BrokerException("Internal Error: client sent " + "invalid sessionUID w/ ADD_PRODUCER " + sessionID + " session does not exist");
}
}
Destination[] ds = null;
DestinationUID duid = null;
if (dest != null && !DestinationUID.isWildcard(dest) && type != null) {
while (true) {
ds = DL.getDestination(con.getPartitionedStore(), dest, type.intValue(), true, !con.isAdminConnection());
d = ds[0];
if (d != null) {
try {
d.incrementRefCount();
} catch (BrokerException ex) {
// try again
continue;
} catch (IllegalStateException ex) {
throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_SHUTTING_DOWN_BROKER), BrokerResources.X_SHUTTING_DOWN_BROKER, ex, Status.ERROR);
}
}
// got a lock on the dest
break;
}
if (d == null) {
logger.log(Logger.DEBUG, "Unable to add " + "producer to " + dest + " :" + DestType.toString(type.intValue()) + " destination can not be autocreated ");
reason = "can not create destination";
status = Status.NOT_FOUND;
throw new BrokerException(reason, status);
}
duid = d.getDestinationUID();
} else if (dest == null || type == null) {
reason = "no destination passed [dest,type] = [" + dest + "," + type + "]";
status = Status.ERROR;
throw new BrokerException(reason, status);
} else {
duid = DestinationUID.getUID(dest, DestType.isQueue(type.intValue()));
}
String info = msg.getSysMessageID().toString();
Producer p = addProducer(duid, con, info, isIndemp);
ProducerUID pid = p.getProducerUID();
assert pid != null;
// LKS - XXX - REVISIT - WHAT ABOUT FLOW CONTROL
boolean active = d == null || d.isProducerActive(pid);
returnprop.put("JMQProducerID", Long.valueOf(pid.longValue()));
returnprop.put("JMQDestinationID", duid.toString());
if (d == null) {
returnprop.put("JMQBytes", Long.valueOf(-1));
returnprop.put("JMQSize", Integer.valueOf(-1));
} else if (active) {
returnprop.put("JMQBytes", Long.valueOf(d.getBytesProducerFlow()));
returnprop.put("JMQSize", Integer.valueOf(d.getSizeProducerFlow()));
} else {
returnprop.put("JMQBytes", Long.valueOf(0));
returnprop.put("JMQSize", Integer.valueOf(0));
}
} else {
assert msg.getPacketType() == PacketType.DELETE_PRODUCER;
Long pid_l = (Long) props.get("JMQProducerID");
ProducerUID pid = new ProducerUID(pid_l == null ? 0 : pid_l.longValue());
removeProducer(pid, isIndemp, con, "Producer closed requested:\n\tconnection: " + con.getConnectionUID() + "\n\tproducerID: " + pid + "\n\trequest sysmsgid message: " + msg.getSysMessageID());
}
} catch (BrokerException ex) {
status = ex.getStatusCode();
reason = ex.getMessage();
logger.log(Logger.INFO, reason);
} catch (Exception ex) {
logger.logStack(Logger.INFO, BrokerResources.E_INTERNAL_BROKER_ERROR, "producer message ", ex);
reason = ex.getMessage();
status = Status.ERROR;
} finally {
if (d != null) {
d.decrementRefCount();
}
}
returnprop.put("JMQStatus", Integer.valueOf(status));
if (reason != null) {
returnprop.put("JMQReason", reason);
}
if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
returnprop.put("JMQReqID", msg.getSysMessageID().toString());
}
reply.setProperties(returnprop);
con.sendControlMessage(reply);
return true;
}
Aggregations