use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class RedeliverHandler method redeliver.
public void redeliver(ConsumerUID[] ids, SysMessageID[] sysids, IMQConnection con, TransactionUID tid, boolean redeliver) throws BrokerException, IOException {
SysMessageID sysid = null;
// really should only have one
Set sessions = new HashSet();
// but client to broker protocol doesnt specify
HashMap cToM = new HashMap();
HashMap noConsumerMap = new HashMap();
HashMap storedIDToConsumerUIDMap = new HashMap();
for (int i = 0; i < ids.length; i++) {
ConsumerUID id = ids[i];
id.setConnectionUID(con.getConnectionUID());
sysid = sysids[i];
PacketReference ref = DL.get(null, sysid, false);
if (ref == null || ref.isInvalid()) {
continue;
}
Session s = Session.getSession(id);
Consumer c = null;
if (s != null) {
if (!sessions.contains(s)) {
s.pause("redeliver");
sessions.add(s);
}
c = (Consumer) s.getConsumerOnSession(id);
}
if (c == null) {
// ok, make sure the consumer has really gone away
// if not, something is really wrong
// otherwise ...
// consumer has gone away but session is still
// valid ->
c = Consumer.getConsumer(id);
if (c != null) {
logger.log(Logger.WARNING, "Internal Error " + " consumer with id of " + id + " is unavailable " + " on session " + s + "[conuid,sess conuid] =" + "[" + con.getConnectionUID().longValue() + "," + (s == null ? 0 : s.getConnectionUID().longValue()) + "] consumer session is : " + c.getSessionUID());
continue;
} else {
if (s != null && s.isClientAck(id) && !s.isTransacted() && redeliver && tid == null) {
ConsumerUID storedID = s.getStoredIDForDetatchedConsumer(id);
if (storedID != null && !storedID.equals(id)) {
storedIDToConsumerUIDMap.put(id, storedID);
SortedSet refset = (SortedSet) noConsumerMap.get(id);
if (refset == null) {
refset = new TreeSet(new RefCompare());
noConsumerMap.put(id, refset);
}
ref.removeInDelivery(storedID);
refset.add(ref);
}
}
// the consumer for this message has been
// closed before the redeliver was requested
// (this means the message has not been acked and
// the session is open)
// we dont need to deliver this message, ignore it
logger.log(Logger.DEBUG, " consumer with id of " + id + " is unavailable " + " on session " + s + "[conuid,sess conuid] =" + "[" + con.getConnectionUID().longValue() + "," + (s == null ? 0 : s.getConnectionUID().longValue()) + "] it has been closed");
continue;
}
}
// for client < 4.1, need check 'redeliver' as well
if (redeliver && (tid != null || s.isTransacted())) {
if (tid == null) {
tid = s.getCurrentTransactionID();
}
TransactionList[] tls = Globals.getDestinationList().getTransactionList(con.getPartitionedStore());
TransactionList translist = tls[0];
if (translist != null) {
if (checkRemovedConsumedMessage(ref, id, tid, translist, true)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Ignore redeliver request for [" + sysid + ":" + id + "], removed with transaction (rerouted)" + tid);
}
continue;
}
if (checkRemovedConsumedMessage(ref, id, tid, translist, false)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Ignore redeliver request for [" + sysid + ":" + id + "], removed with transaction " + tid);
}
continue;
}
}
}
Set set = (Set) cToM.get(c);
if (set == null) {
set = new LinkedHashSet();
cToM.put(c, set);
}
if (!set.contains(ref)) {
ref.removeInDelivery((c.getStoredConsumerUID() == null ? c.getConsumerUID() : c.getStoredConsumerUID()));
set.add(ref);
} else if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Ignore duplicated redeliver request [" + sysid + ":" + id + "]");
}
if (redeliver) {
ref.consumed(c.getStoredConsumerUID(), s.isDupsOK(c.getConsumerUID()), false);
} else {
ref.removeDelivered(c.getStoredConsumerUID(), false);
}
}
Iterator itr = cToM.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
Consumer c = (Consumer) entry.getKey();
Set msgs = (Set) entry.getValue();
c.pause("start redeliver");
c.routeMessages(msgs, true);
c.resume("end redeliver");
}
// help gc
cToM.clear();
if (noConsumerMap.size() > 0) {
try {
logger.log(logger.DEBUG, "REDELIVER unacked for closed consumers: " + noConsumerMap);
TransactionHandler.redeliverUnackedNoConsumer(noConsumerMap, storedIDToConsumerUIDMap, redeliver, null, null);
} catch (Exception e) {
logger.logStack(logger.WARNING, "Exception in redelivering unacked messages for closed consumers", e);
}
}
itr = sessions.iterator();
while (itr.hasNext()) {
Session s = (Session) itr.next();
s.resume("redeliver");
}
}
use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class TransactionHandler method makeDeadIfMaxRollbacked.
/**
* @return non-null if moved to DMQ
*/
public static String makeDeadIfMaxRollbacked(PacketReference ref, Consumer consumer, TransactionUID tid, int maxRollbacks) {
if (ref == null) {
return null;
}
if (consumer.addRollbackCnt(ref.getSysMessageID(), maxRollbacks)) {
return null;
}
Session sess = Session.getSession(consumer.getSessionUID());
if (sess == null) {
return null;
}
Logger logger = Globals.getLogger();
String deadComment = null;
Destination d = ref.getDestination();
Object[] args = { ref.toString() + "[" + (d == null ? "null" : d.getUniqueName()) + "]", Consumer.MSG_MAX_CONSECUTIVE_ROLLBACKS, consumer };
String emsg = Globals.getBrokerResources().getKString(BrokerResources.W_MAX_ROLLBACKS_MOVING_MSG_TO_DMQ, args);
logger.log(logger.WARNING, emsg);
PacketReference deadref = null;
try {
try {
deadref = (PacketReference) sess.handleDead(consumer.getConsumerUID(), ref.getSysMessageID(), RemoveReason.UNDELIVERABLE, null, emsg, Consumer.MSG_MAX_CONSECUTIVE_ROLLBACKS);
deadComment = Globals.getBrokerResources().getKString(BrokerResources.W_MAX_ROLLBACKS_MOVED_MSG_TO_DMQ, args);
logger.log(logger.WARNING, deadComment);
} catch (Throwable e) {
logger.logStack(logger.ERROR, Globals.getBrokerResources().getKString(BrokerResources.X_MVTO_DMQ, ref + (d == null ? "null" : d.getUniqueName()) + ", " + consumer + "]"), e);
}
if (deadref != null) {
d = deadref.getDestination();
try {
if (deadref.isDead()) {
d.removeDeadMessage(deadref);
} else {
d.removeMessage(deadref.getSysMessageID(), RemoveReason.ACKNOWLEDGED);
}
} catch (Exception ex) {
String[] egs = { deadref.toString() + "[" + (d == null ? "null" : d.getUniqueName()) + ", " + consumer + "]", ex.getMessage() };
emsg = Globals.getBrokerResources().getKString(BrokerResources.X_CLEANUP_MSG_AFTER_MVTO_DMQ, egs);
if (DEBUG) {
logger.logStack(Logger.INFO, emsg, ex);
} else {
logger.log(Logger.INFO, emsg);
}
}
}
} finally {
if (deadref != null) {
deadref.postAcknowledgedRemoval();
}
}
return deadComment;
}
use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class SessionHandler method createSession.
public Session createSession(int stype, String creator, IMQConnection con, boolean isIndemp) throws BrokerException {
Session session = null;
if (isIndemp) {
session = Session.getSession(creator);
}
if (session == null) {
session = Session.createSession(con.getConnectionUID(), creator, coreLifecycle);
session.setAckType(stype);
con.attachSession(session);
}
return session;
}
use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class SessionHandler method handle.
/**
* Method to handle Session(add or delete) messages
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
int status = Status.OK;
String reason = null;
// return props
Hashtable hash = new Hashtable();
boolean isIndemp = msg.getIndempotent();
try {
Hashtable props = msg.getProperties();
Session session = null;
if (msg.getPacketType() == PacketType.CREATE_SESSION) {
Integer ack = (props == null ? null : (Integer) props.get("JMQAckMode"));
// if we dont know, treat like client ack
int stype = (ack == null ? Session.NONE : ack.intValue());
session = createSession(stype, msg.getSysMessageID().toString(), con, isIndemp);
hash.put("JMQSessionID", Long.valueOf(session.getSessionUID().longValue()));
} else {
assert msg.getPacketType() == PacketType.DESTROY_SESSION;
Long lsessionid = (Long) props.get("JMQSessionID");
if (lsessionid == null) {
throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, "protocol error, no session"));
}
SessionUID sessionID = new SessionUID(lsessionid.longValue());
closeSession(sessionID, con, isIndemp);
}
} catch (Exception ex) {
boolean log = false;
reason = ex.getMessage();
if (ex instanceof BrokerException) {
status = ((BrokerException) ex).getStatusCode();
log = false;
} else {
status = Status.ERROR;
log = true;
}
if (log) {
logger.logStack(Logger.INFO, Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, " session "), ex);
} else {
logger.log(Logger.INFO, ex.getMessage());
}
}
hash.put("JMQStatus", Integer.valueOf(status));
if (reason != null) {
hash.put("JMQReason", reason);
}
if (msg.getSendAcknowledge()) {
Packet pkt = new Packet(con.useDirectBuffers());
// correlation ID
pkt.setConsumerID(msg.getConsumerID());
pkt.setPacketType(msg.getPacketType() + 1);
pkt.setProperties(hash);
con.sendControlMessage(pkt);
}
return true;
}
use of com.sun.messaging.jmq.jmsserver.core.Session in project openmq by eclipse-ee4j.
the class StartStopHandler method handle.
/**
* Method to handle Start and Stop messages
*/
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
Hashtable props = null;
try {
props = msg.getProperties();
} catch (Exception ex) {
throw new RuntimeException("Can not load props", ex);
}
Long lsid = (props == null ? null : (Long) props.get("JMQSessionID"));
SessionUID suid = (lsid == null ? null : new SessionUID(lsid.longValue()));
int status = Status.OK;
String reason = null;
switch(msg.getPacketType()) {
case PacketType.START:
if (suid != null) {
boolean bad = false;
Session s = Session.getSession(suid);
if (s != null && !s.getConnectionUID().equals(con.getConnectionUID())) {
bad = true;
}
// wrong thing
if (s == null) {
status = Status.ERROR;
String[] args = { "" + suid, "START-SESSION", con.toString() };
reason = Globals.getBrokerResources().getKString(BrokerResources.W_RECEIVED_UNKNOWN_SESSIONID, args);
logger.log(Logger.WARNING, reason);
} else if (bad) {
status = Status.ERROR;
String[] args = { "" + suid, "START-SESSION", con.toString(), s.getConnectionUID().toString() };
reason = Globals.getBrokerResources().getKString(BrokerResources.W_RECEIVED_BAD_SESSIONID, args);
logger.log(Logger.WARNING, reason);
} else {
s.resume("START_STOP");
}
} else {
con.startConnection();
}
break;
case PacketType.STOP:
if (suid != null) {
boolean bad = false;
Session s = Session.getSession(suid);
if (s != null && !s.getConnectionUID().equals(con.getConnectionUID())) {
bad = true;
}
// wrong thing
if (s == null) {
status = Status.ERROR;
String[] args = { "" + suid, "STOP-SESSION", con.toString() };
reason = Globals.getBrokerResources().getKString(BrokerResources.W_RECEIVED_UNKNOWN_SESSIONID, args);
logger.log(Logger.WARNING, reason);
} else if (bad) {
status = Status.ERROR;
String[] args = { "" + suid, "STOP-SESSION", con.toString(), s.getConnectionUID().toString() };
reason = Globals.getBrokerResources().getKString(BrokerResources.W_RECEIVED_BAD_SESSIONID, args);
logger.log(Logger.WARNING, reason);
} else {
s.pause("START_STOP");
}
} else {
con.stopConnection();
}
Packet pkt = new Packet(con.useDirectBuffers());
pkt.setPacketType(PacketType.STOP_REPLY);
pkt.setConsumerID(msg.getConsumerID());
if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
hash.put("JMQReqID", msg.getSysMessageID().toString());
}
hash.put("JMQStatus", Integer.valueOf(status));
if (reason != null) {
hash.put("JMQReason", reason);
}
pkt.setProperties(hash);
con.sendControlMessage(pkt);
break;
}
return true;
}
Aggregations