Search in sources :

Example 41 with DestinationUID

use of com.sun.messaging.jmq.jmsserver.core.DestinationUID 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;
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) MessageDeliveryTimeInfo(com.sun.messaging.jmq.jmsserver.core.MessageDeliveryTimeInfo) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) Producer(com.sun.messaging.jmq.jmsserver.core.Producer)

Example 42 with DestinationUID

use of com.sun.messaging.jmq.jmsserver.core.DestinationUID in project openmq by eclipse-ee4j.

the class DestinationHandler method handle.

/**
 * Method to handle Destination (create or delete) messages
 */
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
    int status = Status.OK;
    String reason = null;
    // XXX - REVISIT 2/25/00 racer
    // do we need to create a reply packet each time ?
    Packet pkt = new Packet(con.useDirectBuffers());
    pkt.setConsumerID(msg.getConsumerID());
    Hashtable hash = new Hashtable();
    Hashtable props = null;
    try {
        props = msg.getProperties();
    } catch (Exception ex) {
        assert false;
        logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Unable to create/destroy destination - no properties", ex);
        throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, "Can not handle create/destroy destination"));
    }
    String destination = (String) props.get("JMQDestination");
    Integer inttype = (Integer) props.get("JMQDestType");
    int type = (inttype == null) ? 0 : inttype.intValue();
    pkt.setPacketType(msg.getPacketType() + 1);
    if (msg.getPacketType() == PacketType.CREATE_DESTINATION) {
        if (DEBUG) {
            logger.log(Logger.DEBUGHIGH, "ConsumerHandler: handle() [ Received AddDestination message {0}]", msg.toString());
        }
        assert destination != null;
        assert inttype != null;
        if (con.isAdminConnection()) {
            type |= DestType.DEST_ADMIN | DestType.DEST_LOCAL | DestType.DEST_AUTO;
        }
        assert pkt.getPacketType() == PacketType.CREATE_DESTINATION_REPLY;
        try {
            Destination d = null;
            if (DestType.isTemporary(type)) {
                // deal w/ versioning .. only store
                // 3.5 or later
                boolean storeTemps = con.getConnectionUID().getCanReconnect();
                long reconnectTime = con.getReconnectInterval();
                Destination[] ds = DL.createTempDestination(con.getPartitionedStore(), destination, type, con.getConnectionUID(), storeTemps, reconnectTime);
                d = ds[0];
                if (con.getConnectionUID().equals(d.getConnectionUID())) {
                    con.attachTempDestination(d.getDestinationUID());
                }
            } else if (destination.startsWith(Globals.INTERNAL_PREFIX)) {
            // do nothing
            } else if (DestinationUID.isWildcard(destination)) {
                pkt.setWildcard(true);
            // dont create a destination
            } else {
                Destination[] ds = DL.getDestination(con.getPartitionedStore(), destination, type, true, !con.isAdminConnection());
                d = ds[0];
            }
            hash.put("JMQDestType", Integer.valueOf(type));
            hash.put("JMQDestUID", destination);
            /*
                 * Set XML Schema validation properties
                 */
            hash.put("JMQValidateXMLSchema", Boolean.valueOf(isXMLSchemaValidationOn(d)));
            String uris = getXMLSchemaURIList(d);
            if (uris != null) {
                hash.put("JMQXMLSchemaURIList", uris);
            }
            hash.put("JMQReloadXMLSchemaOnFailure", Boolean.valueOf(getReloadXMLSchemaOnFailure(d)));
        } catch (BrokerException ex) {
            status = ex.getStatusCode();
            reason = ex.getMessage();
            if (status != Status.CONFLICT) {
                logger.log(Logger.WARNING, BrokerResources.W_CREATE_DEST_FAILED, destination, ex);
            } else if (DEBUG) {
                logger.log(Logger.DEBUG, BrokerResources.W_CREATE_DEST_FAILED, destination, ex);
            }
        } catch (IOException ex) {
            status = Status.ERROR;
            reason = ex.getMessage();
            logger.log(Logger.WARNING, BrokerResources.W_CREATE_DEST_FAILED, destination, ex);
        }
    } else {
        // removing Interest
        assert msg.getPacketType() == PacketType.DESTROY_DESTINATION;
        assert pkt.getPacketType() == PacketType.DESTROY_DESTINATION_REPLY;
        Destination d = null;
        try {
            DestinationUID rmuid = DestinationUID.getUID(destination, DestType.isQueue(type));
            if (destination == null) {
                throw new BrokerException(Globals.getBrokerResources().getString(BrokerResources.X_INTERNAL_EXCEPTION, "protocol error,  destination is null"), Status.NOT_FOUND);
            }
            Destination[] ds = DL.getDestination(con.getPartitionedStore(), rmuid);
            d = ds[0];
            assert d != null;
            DL.removeDestination(con.getPartitionedStore(), rmuid, true, Globals.getBrokerResources().getString(BrokerResources.M_CLIENT_REQUEST, con.getConnectionUID()));
            con.detachTempDestination(rmuid);
        } catch (BrokerException ex) {
            status = ex.getStatusCode();
            reason = ex.getMessage();
            logger.log(Logger.WARNING, BrokerResources.W_DESTROY_DEST_FAILED, destination, ex);
        } catch (IOException ex) {
            status = Status.ERROR;
            reason = ex.getMessage();
            logger.log(Logger.WARNING, BrokerResources.W_DESTROY_DEST_FAILED, destination, ex);
        }
    }
    hash.put("JMQStatus", Integer.valueOf(status));
    if (reason != null) {
        hash.put("JMQReason", reason);
    }
    if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
        hash.put("JMQReqID", msg.getSysMessageID().toString());
    }
    pkt.setProperties(hash);
    con.sendControlMessage(pkt);
    return true;
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID)

Example 43 with DestinationUID

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

Example 44 with DestinationUID

use of com.sun.messaging.jmq.jmsserver.core.DestinationUID in project openmq by eclipse-ee4j.

the class ProducerHandler method addProducer.

public Producer addProducer(DestinationUID duid, IMQConnection con, String id, boolean isIndemp) throws BrokerException {
    Producer p = null;
    if (isIndemp) {
        p = (Producer) Producer.getProducer(id);
    }
    if (p == null) {
        p = Producer.createProducer(duid, con.getConnectionUID(), id, con.getPartitionedStore());
        assert p != null;
        con.addProducer(p);
        // Add to all destinations
        List[] ll = DL.findMatchingIDs(con.getPartitionedStore(), duid);
        List l = ll[0];
        Iterator itr = l.iterator();
        DestinationUID realuid = null;
        Destination[] ds = null;
        Destination d = null;
        while (itr.hasNext()) {
            realuid = (DestinationUID) itr.next();
            ds = DL.getDestination(con.getPartitionedStore(), realuid);
            d = ds[0];
            if (duid.isWildcard() && d.isTemporary()) {
                logger.log(Logger.DEBUG, "L10N-XXX: Wildcard production with destination name of " + duid + " to temporary destination " + d.getUniqueName() + " is not supported, ignoring");
                continue;
            }
            if (duid.isWildcard() && d.isInternal()) {
                logger.log(Logger.DEBUG, "L10N-XXX: Wildcard production with destination name of " + duid + " to internal destination " + d.getUniqueName() + " is not supported, ignoring");
                continue;
            }
            if (duid.isWildcard() && d.isDMQ()) {
                logger.log(Logger.DEBUG, "L10N-XXX: Wildcard production with destination name of " + duid + " to the DeadMessageQueue" + d.getUniqueName() + " is not supported, ignoring");
                continue;
            }
            d.addProducer(p);
        }
    }
    return p;
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) Producer(com.sun.messaging.jmq.jmsserver.core.Producer) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList)

Example 45 with DestinationUID

use of com.sun.messaging.jmq.jmsserver.core.DestinationUID in project openmq by eclipse-ee4j.

the class TransactionHandler method doRollback.

/**
 * Rollback a transaction. This method is invoked from two places: 1) From TransactionHandler.handle() when handling a
 * client ROLLBACK packet. This is the common case. 2) From the admin handler when an admin rollback 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 con Connection client commit packet came in on or, for admin, the connection the admin request came in on.
 *
 * @throws BrokerException on an error. The method will have logged a message to the broker log.
 */
public void doRollback(TransactionList translist, TransactionUID id, JMQXid xid, Integer xaFlags, TransactionState ts, List conlist, IMQConnection con, RollbackReason rbreason) throws BrokerException {
    int s;
    int oldstate = ts.getState();
    PartitionedStore pstore = translist.getPartitionedStore();
    // Update transaction state
    try {
        if (xid == null) {
            // Plain JMS transaction.
            s = TransactionState.ROLLEDBACK;
        } else {
            // XA Transaction.
            if (rbreason == RollbackReason.ADMIN || rbreason == RollbackReason.CONNECTION_CLEANUP) {
                if (ts.getState() == TransactionState.STARTED) {
                    ts = translist.updateState(id, TransactionState.FAILED, TransactionState.STARTED, true);
                    String[] args = { rbreason.toString(), id.toString() + "[" + TransactionState.toString(oldstate) + "]XID=", xid.toString() };
                    if (rbreason != RollbackReason.ADMIN && (DEBUG || DEBUG_CLUSTER_TXN || logger.getLevel() <= Logger.DEBUG)) {
                        logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_FORCE_ENDED_TXN, args));
                    }
                }
            }
            s = ts.nextState(PacketType.ROLLBACK_TRANSACTION, xaFlags);
        }
    } catch (BrokerException ex) {
        if (ex.getStatusCode() == Status.CONFLICT) {
            logger.log(Logger.ERROR, ex.toString());
        } else {
            logger.log(Logger.ERROR, ex.toString() + ": TUID=" + id + " Xid=" + xid);
        }
        throw ex;
    }
    ts = translist.updateState(id, s, true);
    if (Globals.isNewTxnLogEnabled() && oldstate == TransactionState.PREPARED) {
        int transactionType = BaseTransaction.LOCAL_TRANSACTION_TYPE;
        if (translist.isClusterTransaction(id)) {
            transactionType = BaseTransaction.CLUSTER_TRANSACTION_TYPE;
        }
        logTxnCompletion(pstore, id, TransactionState.ROLLEDBACK, transactionType);
    }
    if (fi.FAULT_INJECTION) {
        checkFIAfterDB(PacketType.ROLLBACK_TRANSACTION);
    }
    boolean processDone = true;
    List list = new ArrayList(translist.retrieveSentMessages(id));
    for (int i = 0; i < list.size(); i++) {
        SysMessageID sysid = (SysMessageID) list.get(i);
        if (DEBUG) {
            logger.log(Logger.INFO, "Removing " + sysid + " because of rollback");
        }
        PacketReference ref = DL.get(null, sysid);
        if (ref == null) {
            continue;
        }
        DestinationUID duid = ref.getDestinationUID();
        Destination[] ds = DL.getDestination(ref.getPartitionedStore(), duid);
        Destination d = ds[0];
        if (d != null) {
            Destination.RemoveMessageReturnInfo ret = d.removeMessageWithReturnInfo(sysid, RemoveReason.ROLLBACK);
            if (ret.storermerror) {
                processDone = false;
            }
        }
    }
    // remove from our active connection list
    if (conlist != null) {
        conlist.remove(id);
    }
    // re-queue any orphan messages
    // how we handle the orphan messages depends on a couple
    // of things:
    // - has the session closed ?
    // if the session has closed the messages are "orphan"
    // - otherwise, the messages are still "in play" and
    // we dont do anything with them
    // 
    Map m = translist.getOrphanAck(id);
    if (m != null) {
        Iterator itr = m.entrySet().iterator();
        while (itr.hasNext()) {
            Map.Entry me = (Map.Entry) itr.next();
            SysMessageID sysid = (SysMessageID) me.getKey();
            PacketReference ref = DL.get(null, sysid, false);
            if (ref == null) {
                if (DEBUG) {
                    logger.log(Logger.INFO, "Process transaction rollback " + id + ": orphan message already removed " + sysid);
                }
                continue;
            }
            Destination dst = ref.getDestination();
            Map sids = (Map) me.getValue();
            if (sids == null) {
                continue;
            }
            Iterator siditr = sids.entrySet().iterator();
            while (siditr.hasNext()) {
                Map.Entry se = (Map.Entry) siditr.next();
                ConsumerUID sid = (ConsumerUID) se.getKey();
                if (ref.isLocal()) {
                    if (dst != null) {
                        dst.forwardOrphanMessage(ref, sid);
                    } else {
                        if (DEBUG) {
                            logger.log(Logger.INFO, "Process transaction rollback " + id + ": orphan consumed message destination already removed " + sysid);
                        }
                    }
                    continue;
                }
                List cids = (List) se.getValue();
                if (cids == null) {
                    continue;
                }
                Iterator ciditr = cids.iterator();
                while (ciditr.hasNext()) {
                    ConsumerUID cid = (ConsumerUID) ciditr.next();
                    try {
                        ref.acquireDestroyRemoteReadLock();
                        try {
                            if (ref.isLastRemoteConsumerUID(sid, cid)) {
                                if (ref.acknowledged(cid, sid, !(cid.isNoAck() || cid.isDupsOK()), false, id, translist, null, false)) {
                                    try {
                                        if (dst != null) {
                                            dst.removeRemoteMessage(sysid, RemoveReason.ACKNOWLEDGED, ref);
                                        } else {
                                            logger.log(Logger.INFO, "Process transaction rollback " + id + ": orphan consumed remote message destination already removed " + sysid);
                                        }
                                    } finally {
                                        ref.postAcknowledgedRemoval();
                                    }
                                }
                            }
                        } finally {
                            ref.clearDestroyRemoteReadLock();
                        }
                    } catch (Exception ex) {
                        logger.logStack((DEBUG_CLUSTER_TXN ? Logger.WARNING : Logger.DEBUG), "Unable to cleanup orphaned remote message " + "[" + cid + "," + sid + "," + sysid + "]" + " on rollback transaction " + id, ex);
                    }
                    BrokerAddress addr = translist.getAckBrokerAddress(id, sysid, cid);
                    try {
                        HashMap prop = new HashMap();
                        prop.put(ClusterBroadcast.RB_RELEASE_MSG_ORPHAN, id.toString());
                        Globals.getClusterBroadcast().acknowledgeMessage(addr, sysid, cid, ClusterBroadcast.MSG_IGNORED, prop, false);
                    } catch (BrokerException e) {
                        Globals.getLogger().log(Logger.WARNING, "Unable to notify " + addr + " for orphaned remote message " + "[" + cid + ", " + sid + ", " + ", " + sysid + "]" + " in rollback transaction " + id);
                    }
                }
            }
        }
    }
    // OK .. now remove the acks
    translist.removeTransactionAck(id, true);
    /*
         * Can't really call the JMX notification code at the end of doRollback() because the call to
         * translist.removeTransactionID(id) removes the MBean.
         */
    Agent agent = Globals.getAgent();
    if (agent != null) {
        agent.notifyTransactionRollback(id);
    }
    try {
        ts.setState(s);
        cacheSetState(id, ts, con);
        doRemoteRollback(translist, id, s);
        translist.removeTransaction(id, !processDone);
        if (rbreason == RollbackReason.ADMIN || rbreason == RollbackReason.CONNECTION_CLEANUP) {
            String[] args = { rbreason.toString(), id.toString() + "[" + TransactionState.toString(oldstate) + "]", (xid == null ? "null" : xid.toString()) };
            if (rbreason == RollbackReason.CONNECTION_CLEANUP) {
                if (DEBUG || DEBUG_CLUSTER_TXN || logger.getLevel() <= Logger.DEBUG) {
                    logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.W_FORCE_ROLLEDBACK_TXN, args));
                }
            } else {
                logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_FORCE_ROLLEDBACK_TXN, args));
            }
        }
    } catch (BrokerException ex) {
        logger.logStack(logger.ERROR, br.getKString(br.X_REMOVE_TRANSACTION, id, ex.getMessage()), ex);
        ex.setStackLogged();
        throw ex;
    }
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) Agent(com.sun.messaging.jmq.jmsserver.management.agent.Agent) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) ArrayList(java.util.ArrayList) 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) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) Iterator(java.util.Iterator) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) List(java.util.List) ArrayList(java.util.ArrayList) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) Map(java.util.Map) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) PartitionedStore(com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore)

Aggregations

DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)61 Destination (com.sun.messaging.jmq.jmsserver.core.Destination)25 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)20 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)20 Iterator (java.util.Iterator)18 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)16 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)16 PacketReference (com.sun.messaging.jmq.jmsserver.core.PacketReference)10 Producer (com.sun.messaging.jmq.jmsserver.core.Producer)9 ArrayList (java.util.ArrayList)9 Packet (com.sun.messaging.jmq.io.Packet)8 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)8 IOException (java.io.IOException)8 ProducerUID (com.sun.messaging.jmq.jmsserver.core.ProducerUID)6 PartitionedStore (com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore)6 HashMap (java.util.HashMap)6 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)5 DestinationList (com.sun.messaging.jmq.jmsserver.core.DestinationList)5 Session (com.sun.messaging.jmq.jmsserver.core.Session)5 SessionUID (com.sun.messaging.jmq.jmsserver.core.SessionUID)5