Search in sources :

Example 6 with BrokerException

use of com.sun.messaging.jmq.jmsserver.util.BrokerException in project openmq by eclipse-ee4j.

the class TransactionHandler method releaseRemoteForActiveConsumer.

public static void releaseRemoteForActiveConsumer(PacketReference ref, ConsumerUID intid, TransactionUID tid, TransactionList translist) {
    Consumer c = Consumer.getConsumer(intid);
    if (c == null) {
        return;
    }
    if (ref == null || ref.isLocal()) {
        return;
    }
    SysMessageID sysid = ref.getSysMessageID();
    BrokerAddress addr = null;
    try {
        addr = translist.getAckBrokerAddress(tid, sysid, intid);
    } catch (BrokerException e) {
        if (DEBUG) {
            Object[] args = { "null", tid, sysid, "[" + intid + ", " + c.getStoredConsumerUID() + "]", e.getMessage() };
            Globals.getLogger().log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.X_NOTIFY_RELEASE_REMOTE_MSG_ACTIVE_CONSUMER, args));
            Globals.getLogger().log(Logger.INFO, e.getMessage());
        }
        return;
    }
    try {
        Object[] args = { addr, tid, sysid, "[" + intid + ", " + c.getStoredConsumerUID() + "]" };
        Globals.getLogger().log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_NOTIFY_RELEASE_REMOTE_MSG_ACTIVE_CONSUMER, args));
        HashMap prop = new HashMap();
        prop.put(ClusterBroadcast.RB_RELEASE_MSG_ACTIVE, tid.toString());
        Globals.getClusterBroadcast().acknowledgeMessage(addr, sysid, intid, ClusterBroadcast.MSG_IGNORED, prop, false);
    } catch (BrokerException e) {
        Object[] args = { addr, tid, sysid, "[" + intid + ", " + c.getStoredConsumerUID() + "]", e.getMessage() };
        Globals.getLogger().log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.X_NOTIFY_RELEASE_REMOTE_MSG_ACTIVE_CONSUMER, args));
    }
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress)

Example 7 with BrokerException

use of com.sun.messaging.jmq.jmsserver.util.BrokerException in project openmq by eclipse-ee4j.

the class TransactionHandler method preRollback.

/**
 * A Tuxedo TM instance that is different from the TM instance that has the current thread control of the transaction
 * may call xa_rollback on STARTED state when timeout the transaction
 *
 * @param id The TransactionUID
 * @param xid required if XA transaction and must be null if no XA
 * @param xaFlags used only if XA transaction.
 * @param ts current TransactionState of this transaction
 */
public void preRollback(TransactionList translist, TransactionUID id, JMQXid xid, Integer xaFlags, TransactionState ts) throws BrokerException {
    if (xid != null && ts.getState() == TransactionState.STARTED) {
        int oldstate = TransactionState.STARTED;
        BrokerException ex;
        try {
            ts.nextState(PacketType.ROLLBACK_TRANSACTION, xaFlags);
            return;
        } catch (BrokerException e) {
            ex = e;
            logger.log(logger.ERROR, e.getMessage());
        }
        translist.updateState(id, TransactionState.FAILED, TransactionState.STARTED, true);
        String[] args = { "ROLLBACK", id.toString() + "[" + TransactionState.toString(oldstate) + "]XID=", xid.toString() };
        logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_FORCE_ENDED_TXN, args));
        throw ex;
    }
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException)

Example 8 with BrokerException

use of com.sun.messaging.jmq.jmsserver.util.BrokerException in project openmq by eclipse-ee4j.

the class TransactionHandler method redeliverUnackedNoConsumer.

/**
 * @param sendMap consumerUID to PacketReferences map
 * @param sToCmap consumerUID to stored ConsumerUID map
 * @param redeliver whether set redeliver flag
 * @param tid null if not for transaction rollback
 * @param translist null if tid is null
 */
public static void redeliverUnackedNoConsumer(HashMap sendMap, HashMap sToCmap, boolean redeliver, TransactionUID tid, TransactionList translist) throws BrokerException {
    Logger logger = Globals.getLogger();
    Iterator sitr = sendMap.entrySet().iterator();
    while (sitr.hasNext()) {
        Map.Entry entry = (Map.Entry) sitr.next();
        ConsumerUID intid = (ConsumerUID) entry.getKey();
        ConsumerUID storedID = (ConsumerUID) sToCmap.get(intid);
        SortedSet ss = (SortedSet) entry.getValue();
        Iterator itr = ss.iterator();
        while (itr.hasNext()) {
            PacketReference ref = (PacketReference) itr.next();
            SysMessageID sysid = ref.getSysMessageID();
            if (!ref.isLocal()) {
                if (tid != null && translist != null) {
                    translist.removeOrphanAck(tid, sysid, storedID, intid);
                }
                try {
                    ref.acquireDestroyRemoteReadLock();
                    try {
                        if (ref.isLastRemoteConsumerUID(storedID, intid)) {
                            if (ref.acknowledged(intid, storedID, !(intid.isNoAck() || intid.isDupsOK()), false, tid, translist, null, false)) {
                                try {
                                    Destination d = ref.getDestination();
                                    if (d != null) {
                                        d.removeRemoteMessage(sysid, RemoveReason.ACKNOWLEDGED, ref);
                                    } else {
                                        if (DEBUG || DEBUG_CLUSTER_TXN) {
                                            logger.log(logger.INFO, "Destination " + ref.getDestinationUID() + " not found on cleanup remote message [" + intid + "," + storedID + "," + ref + "]" + " for rollback transaction " + tid + " for inactive consumer");
                                        }
                                    }
                                } finally {
                                    ref.postAcknowledgedRemoval();
                                }
                            }
                        }
                    } finally {
                        ref.clearDestroyRemoteReadLock();
                    }
                } catch (Exception ex) {
                    logger.logStack((DEBUG_CLUSTER_TXN ? Logger.WARNING : Logger.DEBUG), "Unable to cleanup remote message " + "[" + intid + "," + storedID + "," + sysid + "]" + " on rollback transaction " + tid + " for inactive consumer.", ex);
                }
                BrokerAddress addr = null;
                if (tid != null && translist != null) {
                    addr = translist.getAckBrokerAddress(tid, sysid, intid);
                } else {
                    addr = ref.getBrokerAddress();
                }
                try {
                    HashMap prop = new HashMap();
                    if (tid != null) {
                        prop.put(ClusterBroadcast.RB_RELEASE_MSG_INACTIVE, tid.toString());
                    } else {
                        prop.put(ClusterBroadcast.RC_RELEASE_MSG_INACTIVE, "");
                    }
                    Globals.getClusterBroadcast().acknowledgeMessage(addr, sysid, intid, ClusterBroadcast.MSG_IGNORED, prop, false);
                } catch (BrokerException e) {
                    Globals.getLogger().log(Logger.WARNING, "Unable to notify " + addr + " for remote message " + "[" + intid + ", " + storedID + ", " + ", " + sysid + "]" + " in " + (tid != null ? ("rollback transaction " + tid) : ("recover")) + " for inactive consumer.");
                }
                itr.remove();
                continue;
            }
        }
        if (storedID == null || intid == storedID) {
            // non-durable subscriber, ignore
            sitr.remove();
            continue;
        }
        if (ss.isEmpty()) {
            if (DEBUG) {
                logger.log(Logger.INFO, "redeliverUnackedNoConsuemr: " + "empty local message set for consumer " + intid + "[storedID=" + storedID + "]");
            }
            continue;
        }
        // see if we are a queue
        if (storedID == PacketReference.getQueueUID()) {
            // queue message on
            // queues are complex ->
            PacketReference ref = (PacketReference) ss.first();
            if (ref == null) {
                if (DEBUG) {
                    logger.log(Logger.INFO, "Internal Error: " + " null reterence");
                }
                continue;
            }
            if (!redeliver) {
                ref.removeDelivered(storedID, false);
            }
            Destination d = ref.getDestination();
            if (d == null) {
                if (DEBUG) {
                    logger.log(Logger.INFO, "Destination " + ref.getDestinationUID() + " not found for reference: " + ref);
                }
                continue;
            }
            // this puts it on the pending list
            try {
                d.forwardOrphanMessages(ss, storedID);
                sitr.remove();
            } catch (Exception ex) {
                logger.log(Logger.INFO, "Internal Error: " + "Unable to re-queue message " + " to queue " + d, ex);
            }
        } else {
            // durable
            // ok - requeue the message on the subscription
            Consumer cs = Consumer.getConsumer(storedID);
            if (cs == null) {
                if (DEBUG) {
                    logger.log(Logger.INFO, "Internal Error: " + " unknown consumer " + storedID);
                }
                continue;
            }
            if (!ss.isEmpty() && cs.routeMessages(ss, true)) {
                // successful
                sitr.remove();
            }
        }
    }
    if (DEBUG && sendMap.size() > 0) {
        logger.log(Logger.INFO, tid + ":after all processing, " + sendMap.size() + " inactive consumers remaining");
    }
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) 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) Logger(com.sun.messaging.jmq.util.log.Logger) SortedSet(java.util.SortedSet) 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) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) Iterator(java.util.Iterator) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) Map(java.util.Map) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap)

Example 9 with BrokerException

use of com.sun.messaging.jmq.jmsserver.util.BrokerException in project openmq by eclipse-ee4j.

the class TransactionHandler method handle.

/**
 * Method to handle Transaction Messages
 */
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
    long messagetid = 0;
    TransactionUID id = null;
    TransactionState ts = null;
    JMQXid xid = null;
    Integer xaFlags = null;
    boolean redeliverMsgs = false;
    boolean startNextTransaction = false;
    boolean setRedeliverFlag = true;
    boolean isIndemp = msg.getIndempotent();
    boolean replay = false;
    boolean jmqonephase = false;
    Boolean jmqonephaseFlag = null;
    Hashtable props = null;
    String reason = null;
    TransactionList[] tls = Globals.getDestinationList().getTransactionList(con.getPartitionedStore());
    TransactionList translist = tls[0];
    try {
        props = msg.getProperties();
        if (props == null) {
            props = new Hashtable();
        }
    } catch (Exception ex) {
        logger.logStack(Logger.WARNING, "Unable to retrieve " + " properties from transaction message " + msg, ex);
        props = new Hashtable();
    }
    // performance optimisation:
    // start a new transaction immediately after commit or rollback and return
    // transactionID in message ack.
    // The client then does not need to make a separate call to startTransaction.
    Boolean startNextTransactionBool = (Boolean) props.get("JMQStartNextTransaction");
    startNextTransaction = startNextTransactionBool != null && startNextTransactionBool.booleanValue();
    Boolean redeliverMsgBool = (Boolean) props.get("JMQRedeliver");
    redeliverMsgs = redeliverMsgBool != null && redeliverMsgBool.booleanValue();
    Boolean b = (Boolean) props.get("JMQUpdateConsumed");
    boolean updateConsumed = b != null && b.booleanValue();
    Boolean redeliverFlag = (Boolean) props.get("JMQSetRedelivered");
    setRedeliverFlag = redeliverFlag == null || redeliverFlag.booleanValue();
    Integer maxRollbackFlag = (Integer) props.get("JMQMaxRollbacks");
    int maxRollbacks = (maxRollbackFlag == null ? -1 : maxRollbackFlag.intValue());
    /**
     * if dmqOnMaxRollbacks false, and max rollbacks reached, return error to client without rollback and without redelivery
     * any consumed messages
     */
    Boolean dmqOnMaxRollbacksFlag = (Boolean) props.get("JMQDMQOnMaxRollbacks");
    boolean dmqOnMaxRollbacks = dmqOnMaxRollbacksFlag != null && dmqOnMaxRollbacksFlag.booleanValue();
    if (maxRollbacks <= 0) {
        dmqOnMaxRollbacks = !(Consumer.MSG_MAX_CONSECUTIVE_ROLLBACKS <= 0);
    }
    jmqonephaseFlag = (Boolean) props.get("JMQXAOnePhase");
    jmqonephase = jmqonephaseFlag != null && jmqonephaseFlag.booleanValue();
    if (DEBUG) {
        logger.log(Logger.DEBUG, PacketType.getString(msg.getPacketType()) + ": " + "TUID=" + id + ", JMQRedeliver=" + redeliverMsgBool + (jmqonephaseFlag == null ? "" : ", JMQXAOnePhase=" + jmqonephase));
    }
    List conlist = (List) con.getClientData(IMQConnection.TRANSACTION_LIST);
    if (conlist == null) {
        conlist = new ArrayList();
        con.addClientData(IMQConnection.TRANSACTION_LIST, conlist);
    }
    // If there is a message body, then it should contain an Xid.
    ByteBuffer body = msg.getMessageBodyByteBuffer();
    if (body != null) {
        JMQByteBufferInputStream bbis = new JMQByteBufferInputStream(body);
        try {
            xid = JMQXid.read(new DataInputStream(bbis));
            startNextTransaction = false;
        } catch (IOException e) {
            logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Could not decode xid from packet: " + e + " Ignoring " + PacketType.getString(msg.getPacketType()));
            reason = e.getMessage();
            sendReply(con, msg, msg.getPacketType() + 1, Status.BAD_REQUEST, 0, reason);
            return true;
        }
    }
    // Get XAFlags. Note, not all packets will have this -- that's OK.
    xaFlags = (Integer) props.get("JMQXAFlags");
    // tidMap maps an old style transaction identifier to a TransactionUID.
    // In iMQ2.0 the transaction identifier in the packet was an int
    // generated by the client and only unique on the connection.
    // In Falcon it is a long that is unique accross the cluster.
    // So for 2.0 clients we allocate a TransactionUID and map the old
    // style identifier to it.
    // 
    // Get tidMap
    HashMap tidMap = null;
    synchronized (con) {
        tidMap = (HashMap) con.getClientData(IMQConnection.TRANSACTION_IDMAP);
        if (tidMap == null) {
            tidMap = new HashMap();
            con.addClientData(IMQConnection.TRANSACTION_IDMAP, tidMap);
        }
    }
    // Go ahead and get the value of "JMQTransactionID" from the packet.
    // may not be used in all cases.
    messagetid = getJMQTransactionID(props);
    if (fi.FAULT_INJECTION) {
        checkFIBeforeProcess(msg.getPacketType());
    }
    boolean translistResolved = false;
    // else wrap the one specified in the packet
    if (msg.getPacketType() == PacketType.START_TRANSACTION && (xaFlags == null || TransactionState.isFlagSet(XAResource.TMNOFLAGS, xaFlags))) {
        if (isIndemp) {
            // deal with indemp flag
            Object[] rets = TransactionList.getTransactionByCreator(msg.getSysMessageID().toString());
            if (rets == null) {
                id = new TransactionUID();
            } else {
                translist = (TransactionList) rets[0];
                id = (TransactionUID) rets[1];
                replay = true;
            }
        } else {
            id = new TransactionUID();
        }
        translistResolved = true;
    } else if (msg.getPacketType() == PacketType.RECOVER_TRANSACTION) {
        if (messagetid != 0) {
            // Recovering a specific transaction.
            id = new TransactionUID(messagetid);
        }
        xid = null;
    } else {
        // If only Xid was specified need to lookup TransactionUID
        if (messagetid == 0 && xid != null) {
            Object[] rets = TransactionList.mapXidToTid(xid, con);
            if (rets != null) {
                translist = (TransactionList) rets[0];
                id = (TransactionUID) rets[1];
                messagetid = id.longValue();
                translistResolved = true;
            } else {
                // Hmmm...haven't seen this Xid before.
                // XXX I18N
                logger.log(Logger.WARNING, PacketType.getString(msg.getPacketType()) + ": Ignoring unknown XID=" + xid + " broker will " + (msg.getSendAcknowledge() ? "notify the client" : " not notify the client"));
                if (msg.getSendAcknowledge()) {
                    reason = "Uknown XID " + xid;
                    sendReply(con, msg, msg.getPacketType() + 1, Status.NOT_FOUND, 0, reason);
                }
                return true;
            }
        } else if (messagetid != 0) {
            if (con.getClientProtocolVersion() == PacketType.VERSION1) {
                // Map old style to new
                synchronized (tidMap) {
                    id = (TransactionUID) tidMap.get(Long.valueOf(messagetid));
                }
            } else {
                // Wrap new style
                id = new TransactionUID(messagetid);
            }
        }
        // Get the state of the transaction
        if (id == null) {
            logger.log(Logger.INFO, "InternalError: " + "Transaction ID was not passed by " + "the jms api on a method that reqires an " + "existing transaction ");
            sendReply(con, msg, msg.getPacketType() + 1, Status.ERROR, 0, "Internal Error: bad MQ protocol," + " missing TransactionID");
            return true;
        }
        if (translistResolved) {
            if (translist == null) {
                String emsg = "XXXNo transaction list found to process " + PacketType.getString(msg.getPacketType()) + " for transaction " + id + "[" + xid + "]";
                logger.log(Logger.WARNING, emsg);
                if (msg.getSendAcknowledge()) {
                    reason = emsg;
                    sendReply(con, msg, msg.getPacketType() + 1, Status.GONE, 0, reason);
                }
                return true;
            }
            ts = translist.retrieveState(id);
        } else {
            Object[] oo = TransactionList.getTransListAndState(id, con, false, false);
            if (oo != null) {
                translist = (TransactionList) oo[0];
                ts = (TransactionState) oo[1];
            }
        }
        if (ts == null) {
            if (isIndemp && (msg.getPacketType() == PacketType.ROLLBACK_TRANSACTION || msg.getPacketType() == PacketType.COMMIT_TRANSACTION)) {
                if (msg.getSendAcknowledge()) {
                    sendReply(con, msg, msg.getPacketType() + 1, Status.OK, id.longValue(), reason);
                    return true;
                }
                if (fi.FAULT_INJECTION) {
                    checkFIAfterProcess(msg.getPacketType());
                    checkFIAfterReply(msg.getPacketType());
                }
            } else {
                ts = cacheGetState(id, con);
                if (ts != null) {
                    // XXX l10n
                    logger.log(Logger.ERROR, "Transaction ID " + id + " has already been resolved. Ignoring request: " + PacketType.getString(msg.getPacketType()) + ". Last state of this transaction: " + ts.toString() + " broker will " + (msg.getSendAcknowledge() ? "notify the client" : " not notify the client"));
                } else {
                    logger.log((BrokerStateHandler.isShuttingDown() ? Logger.DEBUG : Logger.WARNING), Globals.getBrokerResources().getKString((msg.getSendAcknowledge() ? BrokerResources.W_UNKNOWN_TRANSACTIONID_NOTIFY_CLIENT : BrokerResources.W_UNKNOWN_TRANSACTIONID_NONOTIFY_CLIENT), "" + id + "(" + messagetid + ")" + (xid == null ? "" : "XID=" + xid), PacketType.getString(msg.getPacketType())) + "\n" + com.sun.messaging.jmq.io.PacketUtil.dumpPacket(msg));
                }
                // Only send reply if A bit is set
                if (msg.getSendAcknowledge()) {
                    reason = "Unknown transaction " + id;
                    sendReply(con, msg, msg.getPacketType() + 1, Status.NOT_FOUND, id.longValue(), reason);
                }
                return true;
            }
        }
    }
    if (DEBUG) {
        logger.log(Logger.INFO, this.getClass().getName() + ": " + PacketType.getString(msg.getPacketType()) + ": " + "TUID=" + id + " XAFLAGS=" + TransactionState.xaFlagToString(xaFlags) + (jmqonephaseFlag == null ? "" : " JMQXAOnePhase=" + jmqonephase) + " State=" + ts + " Xid=" + xid);
    }
    // we have in the transaction table.
    if (xid != null && ts != null) {
        if (ts.getXid() == null || !xid.equals(ts.getXid())) {
            // This should never happen
            logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Transaction Xid mismatch. " + PacketType.getString(msg.getPacketType()) + " Packet has tuid=" + id + " xid=" + xid + ", transaction table has tuid=" + id + " xid=" + ts.getXid() + ". Using values from table.");
            xid = ts.getXid();
        }
    }
    if (xid == null && ts != null && ts.getXid() != null && msg.getPacketType() != PacketType.RECOVER_TRANSACTION) {
        // Client forgot to put Xid in packet.
        xid = ts.getXid();
        logger.log(Logger.WARNING, BrokerResources.E_INTERNAL_BROKER_ERROR, "Transaction Xid " + xid + " not found in " + PacketType.getString(msg.getPacketType()) + " packet for tuid " + id + ". Will use " + xid);
    }
    int status = Status.OK;
    // retrieve new 4.0 properties
    AutoRollbackType type = null;
    long lifetime = 0;
    boolean sessionLess = false;
    Integer typeValue = (Integer) props.get("JMQAutoRollback");
    Long lifetimeValue = (Long) props.get("JMQLifetime");
    Boolean sessionLessValue = (Boolean) props.get("JMQSessionLess");
    if (typeValue != null) {
        type = AutoRollbackType.getType(typeValue.intValue());
    }
    if (lifetimeValue != null) {
        lifetime = lifetimeValue.longValue();
    }
    if (sessionLessValue != null) {
        sessionLess = sessionLessValue.booleanValue();
    } else {
        sessionLess = xid != null;
    }
    switch(msg.getPacketType()) {
        case PacketType.START_TRANSACTION:
            {
                try {
                    doStart(translist, id, conlist, con, type, xid, sessionLess, lifetime, messagetid, xaFlags, msg.getPacketType(), replay, msg.getSysMessageID().toString());
                } catch (Exception ex) {
                    status = Status.ERROR;
                    logger.logStack(Logger.ERROR, ex.toString() + ": TUID=" + id + " Xid=" + xid, ex);
                    reason = ex.getMessage();
                    if (ex instanceof BrokerException) {
                        status = ((BrokerException) ex).getStatusCode();
                    }
                }
                sendReply(con, msg, PacketType.START_TRANSACTION_REPLY, status, id.longValue(), reason);
                break;
            }
        case PacketType.END_TRANSACTION:
            try {
                // if the noop flag is set the we don't want to actually
                // process the XA_END. See bug 12364646 and XAResourceImpl.end()
                Boolean jmqnoop = (Boolean) props.get("JMQNoOp");
                if (jmqnoop == null || jmqnoop == false) {
                    doEnd(translist, msg.getPacketType(), xid, xaFlags, ts, id);
                }
            } catch (Exception ex) {
                status = Status.ERROR;
                reason = ex.getMessage();
                if (ex instanceof BrokerException) {
                    status = ((BrokerException) ex).getStatusCode();
                }
            }
            sendReply(con, msg, msg.getPacketType() + 1, status, id.longValue(), reason);
            break;
        case PacketType.PREPARE_TRANSACTION:
            BrokerException bex = null;
            HashMap tmpp = null;
            try {
                doPrepare(translist, id, xaFlags, ts, msg.getPacketType(), jmqonephase, null, con);
            } catch (Exception ex) {
                status = Status.ERROR;
                if ((!(ex instanceof BrokerDownException) && !(ex instanceof AckEntryNotFoundException)) || DEBUG_CLUSTER_TXN) {
                    logger.logStack(Logger.ERROR, ex.toString() + ": TUID=" + id + " Xid=" + xid, ex);
                } else {
                    logger.log(((ex instanceof AckEntryNotFoundException) ? Logger.WARNING : Logger.ERROR), ex.toString() + ": TUID=" + id + " Xid=" + xid);
                }
                reason = ex.getMessage();
                if (ex instanceof BrokerException) {
                    status = ((BrokerException) ex).getStatusCode();
                    bex = (BrokerException) ex;
                }
                if (ts.getState() == TransactionState.FAILED) {
                    tmpp = new HashMap();
                    tmpp.put("JMQPrepareStateFAILED", Boolean.TRUE);
                }
            }
            sendReply(con, msg, msg.getPacketType() + 1, status, id.longValue(), reason, bex, tmpp, 0L);
            break;
        case PacketType.RECOVER_TRANSACTION:
            Vector v = null;
            if (id != null) {
                // Check if specified transaction is in PREPARED state
                v = new Vector();
                ts = translist.retrieveState(id);
                if (ts.getState() == TransactionState.PREPARED) {
                    v.add(id);
                }
            } else {
                // and nothing on ENDRSCAN or NOFLAGS
                if (xaFlags == null || !TransactionState.isFlagSet(XAResource.TMSTARTRSCAN, xaFlags)) {
                    Hashtable hash = new Hashtable();
                    hash.put("JMQQuantity", Integer.valueOf(0));
                    sendReplyBody(con, msg, PacketType.RECOVER_TRANSACTION_REPLY, Status.OK, hash, null);
                    break;
                }
                // Get list of transactions in PENDING state and marshal
                // the Xid's to a byte array.
                v = translist.getTransactions(TransactionState.PREPARED);
            }
            int nIDs = v.size();
            int nWritten = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream(nIDs * JMQXid.size());
            DataOutputStream dos = new DataOutputStream(bos);
            for (int n = 0; n < nIDs; n++) {
                TransactionUID tuid = (TransactionUID) v.get(n);
                TransactionState _ts = translist.retrieveState(tuid);
                if (_ts == null) {
                    // Should never happen
                    logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Could not find state for TUID " + tuid);
                    continue;
                }
                JMQXid _xid = _ts.getXid();
                if (_xid != null) {
                    try {
                        _xid.write(dos);
                        nWritten++;
                    } catch (Exception e) {
                        logger.log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "Could not write Xid " + _xid + " to message body: " + e.toString());
                    }
                }
            }
            Hashtable hash = new Hashtable();
            hash.put("JMQQuantity", Integer.valueOf(nWritten));
            if (id != null) {
                hash.put("JMQTransactionID", Long.valueOf(id.longValue()));
            }
            // Send reply with serialized Xids as the body
            sendReplyBody(con, msg, PacketType.RECOVER_TRANSACTION_REPLY, Status.OK, hash, bos.toByteArray());
            break;
        case PacketType.COMMIT_TRANSACTION:
            try {
                // doCommit will send reply if successful
                if (xaFlags != null && jmqonephase) {
                    Integer newxaFlags = Integer.valueOf(xaFlags.intValue() & ~XAResource.TMONEPHASE);
                    doCommit(translist, id, xid, newxaFlags, ts, conlist, true, con, msg);
                } else {
                    doCommit(translist, id, xid, xaFlags, ts, conlist, true, con, msg, startNextTransaction);
                }
            } catch (BrokerException ex) {
                // doCommit has already logged error
                status = ex.getStatusCode();
                reason = ex.getMessage();
                if (msg.getSendAcknowledge()) {
                    HashMap tmppp = null;
                    if (!jmqonephase && TransactionState.isFlagSet(XAResource.TMONEPHASE, xaFlags)) {
                        if (ts.getState() == TransactionState.FAILED) {
                            tmppp = new HashMap();
                            tmppp.put("JMQPrepareStateFAILED", Boolean.TRUE);
                        }
                    }
                    sendReply(con, msg, msg.getPacketType() + 1, status, id.longValue(), reason, ex, tmppp, 0L);
                } else {
                    if (fi.FAULT_INJECTION) {
                        checkFIAfterProcess(msg.getPacketType());
                        checkFIAfterReply(msg.getPacketType());
                    }
                }
            }
            break;
        case PacketType.ROLLBACK_TRANSACTION:
            {
                BrokerException maxrbex = null;
                try {
                    preRollback(translist, id, xid, xaFlags, ts);
                    try {
                        // if redeliverMsgs is true, we want to redeliver
                        // to both active and inactive consumers
                        boolean processActiveConsumers = redeliverMsgs;
                        redeliverUnacked(translist, id, processActiveConsumers, setRedeliverFlag, updateConsumed, maxRollbacks, dmqOnMaxRollbacks);
                    } catch (BrokerException ex) {
                        if (ex instanceof MaxConsecutiveRollbackException) {
                            maxrbex = ex;
                        } else {
                            logger.logStack(Logger.ERROR, "REDELIVER: " + ex.toString() + ": TUID=" + id + " Xid=" + xid, ex);
                        }
                        reason = ex.getMessage();
                        status = ex.getStatusCode();
                    }
                    if (!(maxrbex != null && !dmqOnMaxRollbacks)) {
                        try {
                            if (fi.checkFault(fi.FAULT_TXN_ROLLBACK_1_5_EXCEPTION, null)) {
                                // fi.unsetFault(fi.FAULT_TXN_ROLLBACK_1_5_EXCEPTION);
                                throw new BrokerException(fi.FAULT_TXN_ROLLBACK_1_5_EXCEPTION);
                            }
                            doRollback(translist, id, xid, xaFlags, ts, conlist, con, RollbackReason.APPLICATION);
                        } catch (BrokerException ex) {
                            if (!ex.isStackLogged()) {
                                logger.logStack(logger.WARNING, ex.getMessage(), ex);
                            } else {
                                logger.log(logger.WARNING, br.getKString(br.X_ROLLBACK_TXN, id, ex.getMessage()));
                            }
                            // doRollback has already logged error
                            if (maxrbex == null) {
                                reason = ex.getMessage();
                                status = ex.getStatusCode();
                            }
                        }
                    }
                } catch (BrokerException ex) {
                    reason = ex.getMessage();
                    status = ex.getStatusCode();
                }
                // performance optimisation
                // start next transaction and return transaction id
                long nextTxnID = 0;
                if (startNextTransaction) {
                    try {
                        TransactionUID nextid = new TransactionUID();
                        doStart(translist, nextid, conlist, con, type, xid, sessionLess, lifetime, 0, xaFlags, PacketType.START_TRANSACTION, replay, msg.getSysMessageID().toString());
                        nextTxnID = nextid.longValue();
                    } catch (Exception ex) {
                        logger.logStack(Logger.ERROR, ex.toString() + ": TUID=" + id + " Xid=" + xid, ex);
                        if (maxrbex == null) {
                            status = Status.ERROR;
                            reason = ex.getMessage();
                            if (ex instanceof BrokerException) {
                                status = ((BrokerException) ex).getStatusCode();
                            }
                        }
                    }
                }
                if (msg.getSendAcknowledge()) {
                    sendReply(con, msg, msg.getPacketType() + 1, status, id.longValue(), reason, null, null, nextTxnID);
                } else {
                    if (fi.FAULT_INJECTION) {
                        checkFIAfterProcess(msg.getPacketType());
                        checkFIAfterReply(msg.getPacketType());
                    }
                }
                break;
            }
    }
    return true;
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) DataOutputStream(java.io.DataOutputStream) ArrayList(java.util.ArrayList) MaxConsecutiveRollbackException(com.sun.messaging.jmq.jmsserver.util.MaxConsecutiveRollbackException) JMQByteBufferInputStream(com.sun.messaging.jmq.io.JMQByteBufferInputStream) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) List(java.util.List) ArrayList(java.util.ArrayList) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) AutoRollbackType(com.sun.messaging.jmq.jmsserver.data.AutoRollbackType) Vector(java.util.Vector) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException) Hashtable(java.util.Hashtable) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) JMQXid(com.sun.messaging.jmq.util.JMQXid) DataInputStream(java.io.DataInputStream) ByteBuffer(java.nio.ByteBuffer) 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) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID)

Example 10 with BrokerException

use of com.sun.messaging.jmq.jmsserver.util.BrokerException in project openmq by eclipse-ee4j.

the class TransactionHandler method calculateStoredRouting.

private boolean calculateStoredRouting(PartitionedStore pstore, TransactionWorkMessage twm) throws BrokerException {
    PacketReference ref = twm.getPacketReference();
    Destination[] ds = DL.getDestination(pstore, twm.getDestUID());
    Destination dest = ds[0];
    ConsumerUID[] storedInterests = null;
    if (dest == null) {
        String msg = "Could not find destination for " + twm.getDestUID() + " refDest= " + ref.getDestinationName();
        logger.log(Logger.ERROR, msg);
        throw new BrokerException(msg);
    }
    try {
        storedInterests = dest.calculateStoredInterests(ref);
        twm.setStoredInterests(storedInterests);
    } catch (SelectorFormatException sfe) {
        throw new BrokerException("Could not route transacted message on commit", sfe);
    }
    if (storedInterests == null) {
        if (DEBUG_CLUSTER_TXN) {
            logger.log(Logger.INFO, Thread.currentThread().getName() + " stored routing = null " + twm + " persist=" + ref.isPersistent());
        }
        return false;
    } else {
        if (DEBUG_CLUSTER_TXN) {
            for (int i = 0; i < storedInterests.length; i++) {
                logger.log(Logger.INFO, Thread.currentThread().getName() + " stored routing " + storedInterests[i] + " " + twm);
            }
        }
    }
    return true;
}
Also used : SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) Destination(com.sun.messaging.jmq.jmsserver.core.Destination) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference)

Aggregations

BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)290 IOException (java.io.IOException)72 Destination (com.sun.messaging.jmq.jmsserver.core.Destination)33 PacketReference (com.sun.messaging.jmq.jmsserver.core.PacketReference)31 SizeString (com.sun.messaging.jmq.util.SizeString)31 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)29 Iterator (java.util.Iterator)26 ArrayList (java.util.ArrayList)25 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)24 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)23 HashMap (java.util.HashMap)22 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)21 TransactionList (com.sun.messaging.jmq.jmsserver.data.TransactionList)21 LoadException (com.sun.messaging.jmq.jmsserver.persist.api.LoadException)21 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)18 List (java.util.List)18 Packet (com.sun.messaging.jmq.io.Packet)16 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)16 TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)16 ConsumerAlreadyAddedException (com.sun.messaging.jmq.jmsserver.util.ConsumerAlreadyAddedException)15