Search in sources :

Example 1 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class TransactionHandler method startTxnAndSendReply.

void startTxnAndSendReply(TransactionList translist, IMQConnection con, Packet msg, int status, boolean startNextTransaction, List conlist, JMQXid xid, TransactionUID id, Integer xaFlags, boolean sendReply) {
    // performance optimisation
    long nextTxnID = 0;
    String reason = null;
    if (startNextTransaction) {
        try {
            TransactionUID nextid = new TransactionUID();
            doStart(translist, nextid, conlist, con, AutoRollbackType.NOT_PREPARED, xid, false, 0, 0, xaFlags, PacketType.START_TRANSACTION, false, msg.getSysMessageID().toString());
            nextTxnID = nextid.longValue();
        } catch (Exception ex) {
            status = Status.ERROR;
            logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, ex.toString() + ": TUID=" + id + " Xid=" + xid, ex);
            reason = ex.getMessage();
            if (ex instanceof BrokerException) {
                status = ((BrokerException) ex).getStatusCode();
            }
        }
    }
    if (sendReply) {
        // chiaming
        sendReply(con, msg, PacketType.COMMIT_TRANSACTION_REPLY, status, id.longValue(), reason, null, null, nextTxnID);
    }
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) 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)

Example 2 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class TransactionHandler method retrieveConsumedRemoteMessages.

private HashMap[] retrieveConsumedRemoteMessages(TransactionList translist, TransactionUID id, boolean checkOnly) throws BrokerException {
    HashMap mcmap = translist.retrieveConsumedMessages(id);
    HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
    if (DEBUG_CLUSTER_TXN) {
        logger.log(logger.INFO, "retrieveConsumedRemoteMessages(" + translist + ",TID=" + id + ") retrieveConsumedMessages: " + mcmap);
    }
    if (mcmap == null || mcmap.size() == 0) {
        return null;
    }
    HashMap[] rets = new HashMap[2];
    HashMap<BrokerAddress, ArrayList[]> bmmap = new HashMap<>();
    HashMap<TransactionBroker, ArrayList<TransactionAcknowledgement>> tbmmap = new HashMap<>();
    ArrayList[] bmcll = null;
    ArrayList<TransactionAcknowledgement> tbmcl = null;
    boolean hasRemote = false;
    BrokerAddress myba = Globals.getMyAddress();
    UID tranpid = translist.getPartitionedStore().getPartitionID();
    UID refpid = null;
    ConsumerUID cuid = null, scuid = null;
    TransactionAcknowledgement ta = null;
    Iterator<Map.Entry> itr = mcmap.entrySet().iterator();
    Map.Entry pair = null;
    while (itr.hasNext()) {
        pair = itr.next();
        SysMessageID sysid = (SysMessageID) pair.getKey();
        if (sysid == null) {
            continue;
        }
        PacketReference ref = DL.get(null, sysid, false);
        if (checkRefRequeued(translist, id, ref, sysid)) {
            BrokerException bex = new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_MAYBE_REROUTED, sysid) + ", TUID=" + id, Status.GONE);
            bex.setRemote(true);
            StringBuilder buf = new StringBuilder();
            List interests = (List) pair.getValue();
            for (int i = 0; i < interests.size(); i++) {
                buf.append(String.valueOf(((ConsumerUID) interests.get(i)).longValue()));
                buf.append(' ');
            }
            bex.setRemoteConsumerUIDs(buf.toString());
            throw bex;
        }
        if (ref == null) {
            throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_REF_GONE, sysid) + ", TUID=" + id, Status.CONFLICT);
        }
        BrokerAddress ba = ref.getBrokerAddress();
        if (ba == null) {
            if (!DL.isPartitionMode()) {
                ba = myba;
            } else {
                refpid = ref.getPartitionedStore().getPartitionID();
                ba = (BrokerAddress) myba.clone();
                ba.setStoreSessionUID(refpid);
                if (!refpid.equals(tranpid)) {
                    hasRemote = true;
                }
            }
        } else if (!hasRemote) {
            hasRemote = true;
        }
        if (hasRemote && checkOnly) {
            return rets;
        }
        TransactionBroker tba = new TransactionBroker(ba);
        bmcll = bmmap.get(tba.getBrokerAddress());
        tbmcl = tbmmap.get(tba);
        if (bmcll == null) {
            bmcll = new ArrayList[2];
            bmcll[0] = new ArrayList();
            bmcll[1] = new ArrayList();
            bmmap.put(tba.getBrokerAddress(), bmcll);
        }
        if (tbmcl == null) {
            tbmcl = new ArrayList<>();
            tbmmap.put(tba, tbmcl);
        }
        List interests = (List) mcmap.get(sysid);
        for (int i = 0; i < interests.size(); i++) {
            cuid = (ConsumerUID) interests.get(i);
            bmcll[0].add(sysid);
            bmcll[1].add(cuid);
            scuid = (ConsumerUID) sToCmap.get(cuid);
            ta = new TransactionAcknowledgement(sysid, cuid, scuid);
            if (!scuid.shouldStore() || !ref.isPersistent()) {
                ta.setShouldStore(false);
            }
            tbmcl.add(ta);
        }
        if (DEBUG_CLUSTER_TXN) {
            logger.log(logger.INFO, "retrieveConsumedRemoteMessages() for broker " + tba + ": " + Arrays.toString(bmcll) + ", " + tbmcl);
        }
    }
    if (!hasRemote) {
        return null;
    }
    rets[0] = bmmap;
    rets[1] = tbmmap;
    return rets;
}
Also used : TransactionAcknowledgement(com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) ArrayList(java.util.ArrayList) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) UID(com.sun.messaging.jmq.util.UID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) 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)

Example 3 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class TransactionHandler method doRemotePrepare.

private ClusterTransaction doRemotePrepare(TransactionList translist, TransactionUID id, TransactionState nextState, TransactionWork txnWork) throws BrokerException {
    if (nextState.getState() != TransactionState.PREPARED) {
        throw new BrokerException("Unexpected state " + nextState + " for transactionID:" + id);
    }
    HashMap[] rets = retrieveConsumedRemoteMessages(translist, id, false);
    if (DEBUG_CLUSTER_TXN) {
        logger.log(logger.INFO, "doRemotePrepare(" + translist + ", " + id + "): retrievedConsumedRemoteMsgs:" + (rets == null ? "null" : rets[0] + ", " + rets[1]));
    }
    if (fi.FAULT_INJECTION) {
        if (fi.checkFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5, null)) {
            fi.unsetFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
            throw new BrokerException(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
        }
    }
    if (rets == null) {
        return null;
    }
    if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
        return null;
    }
    HashMap<BrokerAddress, ArrayList[]> bmmap = rets[0];
    TransactionBroker[] tranbas = (TransactionBroker[]) rets[1].keySet().toArray(new TransactionBroker[rets[1].size()]);
    BrokerAddress[] bas = bmmap.keySet().toArray(new BrokerAddress[bmmap.size()]);
    boolean persist = true;
    ClusterTransaction clusterTransaction = null;
    if (Globals.isNewTxnLogEnabled()) {
        // create a cluster transaction which will be logged
        clusterTransaction = new ClusterTransaction(id, nextState, txnWork, tranbas);
        translist.logClusterTransaction(id, nextState, tranbas, true, persist, clusterTransaction);
    } else {
        translist.logClusterTransaction(id, nextState, tranbas, true, persist);
    }
    if (DEBUG_CLUSTER_TXN) {
        StringBuilder buf = new StringBuilder();
        buf.append("Preparing transaction ").append(id).append(", brokers");
        for (TransactionBroker tranba : tranbas) {
            buf.append("\n\t").append(tranba);
        }
        logger.log(logger.INFO, buf.toString());
    }
    UID tranpid = null;
    if (Globals.getDestinationList().isPartitionMode()) {
        tranpid = translist.getPartitionedStore().getPartitionID();
        ArrayList<TransactionAcknowledgement> mcl = null;
        TransactionBroker tba = null;
        UID tbapid = null;
        TransactionAcknowledgement[] tas = null;
        TransactionList tl = null;
        for (int i = 0; i < tranbas.length; i++) {
            tba = tranbas[i];
            if (!tba.getBrokerAddress().equals(Globals.getMyAddress())) {
                continue;
            }
            tbapid = tba.getBrokerAddress().getStoreSessionUID();
            if (tbapid.equals(tranpid)) {
                continue;
            }
            mcl = (ArrayList<TransactionAcknowledgement>) rets[1].get(tba);
            tas = mcl.toArray(new TransactionAcknowledgement[mcl.size()]);
            tl = TransactionList.getTransListByPartitionID(tbapid);
            if (tl == null) {
                throw new BrokerException("Can't prepare transaction " + id + " because " + "transaction list for partition " + tbapid + " not found");
            }
            BrokerAddress home = (BrokerAddress) Globals.getMyAddress().clone();
            home.setStoreSessionUID(tranpid);
            tl.logLocalRemoteTransaction(id, nextState, tas, home, false, true, persist);
        }
    }
    // handle remote brokers
    ArrayList[] mcll = null;
    BrokerAddress ba = null;
    for (int i = 0; i < bas.length; i++) {
        ba = bas[i];
        if (ba == Globals.getMyAddress() || ba.equals(Globals.getMyAddress())) {
            continue;
        }
        mcll = bmmap.get(ba);
        try {
            Globals.getClusterBroadcast().acknowledgeMessage2P(ba, (SysMessageID[]) mcll[0].toArray(new SysMessageID[mcll[0].size()]), (ConsumerUID[]) mcll[1].toArray(new ConsumerUID[mcll[1].size()]), ClusterBroadcast.MSG_PREPARE, null, Long.valueOf(id.longValue()), tranpid, true, false);
        } catch (BrokerException e) {
            if (!(e instanceof BrokerDownException) && !(e instanceof AckEntryNotFoundException)) {
                throw e;
            }
            HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
            ArrayList remoteConsumerUIDa = new ArrayList();
            StringBuilder remoteConsumerUIDs = new StringBuilder();
            String uidstr = null;
            StringBuilder debugbuf = new StringBuilder();
            for (int j = 0; j < mcll[0].size(); j++) {
                SysMessageID sysid = (SysMessageID) mcll[0].get(j);
                ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
                ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
                if (suid == null || suid.equals(uid)) {
                    continue;
                }
                if (e.isRemote()) {
                    uidstr = String.valueOf(uid.longValue());
                    if (!remoteConsumerUIDa.contains(uidstr)) {
                        remoteConsumerUIDa.add(uidstr);
                        remoteConsumerUIDs.append(uidstr);
                        remoteConsumerUIDs.append(' ');
                        Consumer c = Consumer.getConsumer(uid);
                        if (c != null) {
                            c.recreationRequested();
                        } else {
                            logger.log(logger.WARNING, "Consumer " + uid + " not found in processing remote exception on preparing transaction " + id);
                        }
                    }
                }
                debugbuf.append("\n\t[").append(sysid).append(':').append(uid).append(']');
            }
            if (e.isRemote()) {
                e.setRemoteConsumerUIDs(remoteConsumerUIDs.toString());
                if (DEBUG_CLUSTER_TXN) {
                    logger.log(logger.INFO, "doRemotePrepare: JMQRemote Exception:remoteConsumerUIDs=" + remoteConsumerUIDs + ", remote broker " + ba);
                }
            }
            try {
                translist.updateState(id, TransactionState.FAILED, false, TransactionState.PREPARED, true);
            } catch (Exception ex) {
                logger.logStack(logger.WARNING, "Unable to update transaction " + id + " state to FAILED on PREPARE failure from " + ba + ": " + ex.getMessage() + debugbuf.toString(), ex);
                throw e;
            }
            if (e instanceof AckEntryNotFoundException) {
                mcll = ((AckEntryNotFoundException) e).getAckEntries();
            }
            for (int j = 0; j < mcll[0].size(); j++) {
                SysMessageID sysid = (SysMessageID) mcll[0].get(j);
                ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
                boolean remove = true;
                if (e instanceof BrokerDownException) {
                    ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
                    if (suid == null || suid.equals(uid)) {
                        if (DEBUG_CLUSTER_TXN) {
                            logger.log(logger.INFO, "doRemotePrepare: no remove txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
                        }
                        remove = false;
                    }
                }
                if (remove) {
                    try {
                        translist.removeAcknowledgement(id, sysid, uid, (e instanceof AckEntryNotFoundException));
                        if (DEBUG_CLUSTER_TXN) {
                            logger.log(logger.INFO, "doRemotePrepare: removed txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
                        }
                    } catch (Exception ex) {
                        logger.logStack(logger.WARNING, "Unable to remove transaction " + id + " ack [" + sysid + ":" + uid + "] on PREPARE failure from " + ba + ": " + ex.getMessage(), ex);
                    }
                }
            }
            logger.log(logger.WARNING, "Preparing transaction " + id + " failed from " + ba + ": " + e.getMessage() + debugbuf.toString());
            throw e;
        }
    }
    return clusterTransaction;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) ArrayList(java.util.ArrayList) ClusterTransaction(com.sun.messaging.jmq.jmsserver.data.ClusterTransaction) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException) TransactionAcknowledgement(com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) 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) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) UID(com.sun.messaging.jmq.util.UID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) SysMessageID(com.sun.messaging.jmq.io.SysMessageID)

Example 4 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID 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 5 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class DebugHandler method getDebugInfo.

public Hashtable getDebugInfo(String arg, String target, String targetType, Properties p) throws Exception {
    if (arg.equals("cxn")) {
        if (target == null) {
            return getAllCxnInfo(null);
        } else {
            ConnectionUID uid = new ConnectionUID(Long.parseLong(target));
            return getCxnInfo(uid);
        }
    } else if (arg.equals("config")) {
        return getConfig();
    } else if (arg.equals("memory")) {
        return getMemory();
    } else if (arg.equals("dst")) {
        if (target == null) {
            return DL.getAllDebugState();
        } else {
            boolean isQueue = false;
            if (targetType == null) {
                throw new Exception("topic or queue not " + "specified with -t [t|q]");
            } else if (targetType.equals("t")) {
                isQueue = false;
            } else if (targetType.equals("q")) {
                isQueue = true;
            } else {
                throw new Exception("Unknown -t argument " + targetType + " expected t or q");
            }
            DestinationUID uid = DestinationUID.getUID(target, isQueue);
            return getDestinationInfo(uid);
        }
    } else if (arg.equals("ses")) {
        if (target == null) {
            return Session.getAllDebugState();
        } else {
            SessionUID uid = new SessionUID(Long.parseLong(target));
            return getSession(uid);
        }
    } else if (arg.equals("prd")) {
        if (target == null) {
            return Producer.getAllDebugState();
        } else {
            ProducerUID uid = new ProducerUID(Long.parseLong(target));
            return getProducerInfo(uid);
        }
    } else if (arg.equals("con")) {
        if (target == null) {
            return Consumer.getAllDebugState();
        } else {
            ConsumerUID uid = new ConsumerUID(Long.parseLong(target));
            return getConInfo(uid);
        }
    } else if (arg.equals("svc")) {
        if (target == null) {
            logger.log(Logger.INFO, "XXX - target of null " + "not implemented for " + arg);
        } else {
            return getSvcInfo(target);
        }
    } else if (arg.equals("db")) {
        return getDBInfo();
    } else if (arg.equals("trans")) {
        if (target == null) {
            return getTransactionInfo(null);
        } else {
            TransactionUID uid = new TransactionUID(Long.parseLong(target));
            return getTransactionInfo(uid);
        }
    } else if (arg.equals("pool")) {
        if (target == null) {
            logger.log(Logger.INFO, "XXX - target of null " + "not implemented for " + arg);
        } else {
            return getThreadPoolInfo(target);
        }
    } else if (arg.equals("threads")) {
        return SupportUtil.getAllStackTracesAsMap();
    } else if (arg.equals("cls")) {
        return getClusterInfo();
    } else if (arg.equals("bkr")) {
        return getBrokerInfo();
    } else if (arg.equals("pkt")) {
        String full = p.getProperty("full");
        boolean fullDump = false;
        if (full != null && full.equalsIgnoreCase("True")) {
            fullDump = true;
        }
        return getPktInfo(target, targetType, fullDump);
    }
    logger.log(Logger.INFO, "Unknown dump arg " + arg);
    return null;
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) SessionUID(com.sun.messaging.jmq.jmsserver.core.SessionUID) ProducerUID(com.sun.messaging.jmq.jmsserver.core.ProducerUID) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID)

Aggregations

TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)71 TransactionList (com.sun.messaging.jmq.jmsserver.data.TransactionList)23 TransactionState (com.sun.messaging.jmq.jmsserver.data.TransactionState)22 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)19 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)18 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)15 JMQXid (com.sun.messaging.jmq.util.JMQXid)13 IOException (java.io.IOException)13 HashMap (java.util.HashMap)12 TransactionBroker (com.sun.messaging.jmq.jmsserver.data.TransactionBroker)10 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)10 ArrayList (java.util.ArrayList)10 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)8 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)7 TransactionAcknowledgement (com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement)7 ConnectionUID (com.sun.messaging.jmq.jmsserver.service.ConnectionUID)7 Iterator (java.util.Iterator)7 LinkedHashMap (java.util.LinkedHashMap)7 Map (java.util.Map)7 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)6