Search in sources :

Example 16 with Session

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");
    }
}
Also used : ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) Session(com.sun.messaging.jmq.jmsserver.core.Session)

Example 17 with Session

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;
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) Logger(com.sun.messaging.jmq.util.log.Logger) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) IOException(java.io.IOException) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) MaxConsecutiveRollbackException(com.sun.messaging.jmq.jmsserver.util.MaxConsecutiveRollbackException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Session(com.sun.messaging.jmq.jmsserver.core.Session)

Example 18 with Session

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;
}
Also used : Session(com.sun.messaging.jmq.jmsserver.core.Session)

Example 19 with 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;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) SessionUID(com.sun.messaging.jmq.jmsserver.core.SessionUID) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Session(com.sun.messaging.jmq.jmsserver.core.Session)

Example 20 with Session

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;
}
Also used : SessionUID(com.sun.messaging.jmq.jmsserver.core.SessionUID) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Session(com.sun.messaging.jmq.jmsserver.core.Session)

Aggregations

Session (com.sun.messaging.jmq.jmsserver.core.Session)28 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)11 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)10 SessionUID (com.sun.messaging.jmq.jmsserver.core.SessionUID)8 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)7 PacketReference (com.sun.messaging.jmq.jmsserver.core.PacketReference)7 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)7 Destination (com.sun.messaging.jmq.jmsserver.core.Destination)6 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)5 Iterator (java.util.Iterator)4 ProducerUID (com.sun.messaging.jmq.jmsserver.core.ProducerUID)3 ConsumerSpi (com.sun.messaging.jmq.jmsserver.plugin.spi.ConsumerSpi)3 AccessControlException (java.security.AccessControlException)3 Packet (com.sun.messaging.jmq.io.Packet)2 ReadWritePacket (com.sun.messaging.jmq.io.ReadWritePacket)2 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)2 Producer (com.sun.messaging.jmq.jmsserver.core.Producer)2 TransactionList (com.sun.messaging.jmq.jmsserver.data.TransactionList)2 ConnectionUID (com.sun.messaging.jmq.jmsserver.service.ConnectionUID)2 IMQConnection (com.sun.messaging.jmq.jmsserver.service.imq.IMQConnection)2