Search in sources :

Example 41 with BrokerException

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

the class RollbackCommitHandler method handle.

/**
 * Handle the incomming administration message.
 *
 * @param con The Connection the message came in on.
 * @param cmd_msg The administration message
 * @param cmd_props The properties from the administration message
 */
@Override
public boolean handle(IMQConnection con, Packet cmd_msg, Hashtable cmd_props) {
    if (DEBUG) {
        logger.log(Logger.DEBUG, this.getClass().getName() + ": " + "Rollback/Commit transaction " + cmd_props);
    }
    // Get the admin request message type
    int requestType = ((Integer) cmd_props.get(MessageType.JMQ_MESSAGE_TYPE)).intValue();
    int status = Status.OK;
    String errMsg = null;
    TransactionUID tid = null;
    TransactionState ts = null;
    TransactionHandler thandler = null;
    // Get the packet handler that handles transaction packets
    if (parent.adminPktRtr != null) {
        thandler = (TransactionHandler) parent.adminPktRtr.getHandler(PacketType.ROLLBACK_TRANSACTION);
    }
    Long id = (Long) cmd_props.get(MessageType.JMQ_TRANSACTION_ID);
    // only applies to rollback request
    Boolean v = (Boolean) cmd_props.get(MessageType.JMQ_PROCESS_ACTIVE_CONSUMERS);
    boolean processActiveConsumers = (v != null && v.booleanValue());
    HAMonitorService hamonitor = Globals.getHAMonitorService();
    if (hamonitor != null && hamonitor.inTakeover()) {
        status = Status.ERROR;
        errMsg = rb.getString(rb.E_CANNOT_PROCEED_TAKEOVER_IN_PROCESS);
        logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
    }
    if (id != null) {
        tid = new TransactionUID(id.longValue());
    } else {
        status = Status.BAD_REQUEST;
    }
    if (status == Status.OK) {
        TransactionList[] tls = DL.getTransactionList(null);
        TransactionList tl = null;
        for (int i = 0; i < tls.length; i++) {
            tl = tls[i];
            ts = tl.retrieveState(tid);
            if (ts == null) {
                continue;
            }
            break;
        }
        if (ts == null) {
            // Specified transaction did not exist
            status = Status.NOT_FOUND;
            errMsg = rb.getString(rb.E_NO_SUCH_TRANSACTION, tid);
        } else if (requestType == MessageType.COMMIT_TRANSACTION && ts.getState() != TransactionState.PREPARED) {
            status = Status.PRECONDITION_FAILED;
            errMsg = rb.getString(rb.E_TRANSACTION_NOT_PREPARED, tid);
        } else if (requestType == MessageType.ROLLBACK_TRANSACTION && (ts.getState() < TransactionState.STARTED || ts.getState() > TransactionState.PREPARED)) {
            status = Status.PRECONDITION_FAILED;
            errMsg = rb.getString(rb.E_INVALID_TXN_STATE_FOR_ROLLBACK, tid);
        } else {
            JMQXid xid = tl.UIDToXid(tid);
            if (xid == null && (!(Globals.getHAEnabled() && ts.getState() == TransactionState.PREPARED))) {
                /*
                     * Need to pick the right error message: If (action is ROLLBACK and state is one of {STARTED, FAILED, INCOMPLETE,
                     * COMPLETE}) "Rollback of non-XA transaction 123456789 in non-PREPARED state is not supported." else
                     * "Could not find Xid for 123456789"
                     */
                if (requestType == MessageType.ROLLBACK_TRANSACTION && (ts.getState() >= TransactionState.STARTED && ts.getState() < TransactionState.PREPARED)) {
                    errMsg = rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Rollback of non-XA transaction " + tid + " in non-PREPARED state is not supported.");
                } else {
                    errMsg = rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not find Xid for " + tid);
                }
                status = Status.ERROR;
            } else if (thandler == null) {
                errMsg = rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not locate TransactionHandler");
                status = Status.ERROR;
            } else {
                if (requestType == MessageType.ROLLBACK_TRANSACTION) {
                    if (DEBUG) {
                        logger.log(Logger.DEBUG, "Rolling back " + tid + " in state " + ts);
                    }
                    try {
                        if (processActiveConsumers) {
                            logger.log(logger.INFO, rb.getKString(rb.I_ADMIN_REDELIVER_MSGS_ON_TXN_ROLLBACK, tid));
                            try {
                                thandler.redeliverUnacked(tl, tid, true, true, true, -1, false);
                            } catch (Exception e) {
                                logger.logStack(logger.WARNING, rb.getKString(rb.X_ADMIN_REDELIVER_MSG_ON_TXN_ROLLBACK, tid, e.getMessage()), e);
                            }
                        }
                        thandler.doRollback(tl, tid, xid, null, ts, null, con, RollbackReason.ADMIN);
                    } catch (BrokerException e) {
                        status = Status.ERROR;
                        errMsg = e.getMessage();
                    }
                } else if (requestType == MessageType.COMMIT_TRANSACTION) {
                    if (DEBUG) {
                        logger.log(Logger.DEBUG, "Committing " + tid + " in state " + ts);
                    }
                    try {
                        thandler.doCommit(tl, tid, xid, Integer.valueOf(XAResource.TMNOFLAGS), ts, null, false, con, null);
                    } catch (BrokerException e) {
                        status = Status.ERROR;
                        errMsg = e.getMessage();
                    }
                } else {
                    // Should never happen.
                    return super.handle(con, cmd_msg, cmd_props);
                }
            }
        }
    }
    sendReply(con, cmd_msg, requestType + 1, status, errMsg);
    return true;
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) JMQXid(com.sun.messaging.jmq.util.JMQXid) HAMonitorService(com.sun.messaging.jmq.jmsserver.cluster.api.ha.HAMonitorService) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionHandler(com.sun.messaging.jmq.jmsserver.data.handlers.TransactionHandler)

Example 42 with BrokerException

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

the class SFSHABrokerInfoMap method get.

/**
 * Retrieves the HAClusteredBroker associated with the passed in broker id. If the id is not found in the hashtable, the
 * store will be checked.
 *
 * @param key the brokerid to lookup
 * @param update update against store
 * @return the HAClusteredBroker object (or null if one can't be found)
 */
@Override
public Object get(Object key, boolean update) {
    // always check against the backing store
    Object o = super.get(key);
    if (o == null || update) {
        try {
            HABrokerInfo m = Globals.getStore().getBrokerInfo((String) key);
            if (m != null && o == null) {
                HAClusteredBroker cb = new SFSHAClusteredBrokerImpl((String) key, m, parent);
                put(key, cb);
                parent.brokerChanged(ClusterReason.ADDED, cb.getBrokerName(), null, cb, cb.getBrokerSessionUID(), null);
                o = cb;
            }
            if (m != null && update) {
                ((HAClusteredBrokerImpl) o).update(m);
            }
        } catch (BrokerException ex) {
            Globals.getLogger().logStack(Logger.WARNING, "Exception while creating broker entry " + key, ex);
        }
    }
    return o;
}
Also used : HABrokerInfo(com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HAClusteredBroker(com.sun.messaging.jmq.jmsserver.cluster.api.ha.HAClusteredBroker)

Example 43 with BrokerException

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

the class BrokerConsumers method acknowledgeMessageFromRemote2P.

public void acknowledgeMessageFromRemote2P(int ackType, SysMessageID[] sysids, com.sun.messaging.jmq.jmsserver.core.ConsumerUID[] cuids, Map optionalProps, Long txnID, com.sun.messaging.jmq.jmsserver.core.BrokerAddress txnHomeBroker) throws BrokerException {
    if (txnID == null) {
        throw new BrokerException("Internal Error: call with null txnID");
    }
    // handle 2-phase remote ack
    TransactionUID tid = new TransactionUID(txnID.longValue());
    if (ackType == ClusterBroadcast.MSG_PREPARE) {
        PartitionedStore refpstore = null;
        TransactionAcknowledgement ta = null;
        ArrayList<TransactionAcknowledgement> tltas = null;
        TransactionAcknowledgement[] tas = null;
        HashMap<TransactionList, ArrayList<TransactionAcknowledgement>> tltasmap = new HashMap<>();
        TransactionList tl = null;
        AckEntry entry = null, value = null;
        StringBuilder dbuf = new StringBuilder();
        AckEntryNotFoundException ae = null;
        synchronized (deliveredMessages) {
            for (int i = 0; i < sysids.length; i++) {
                entry = new AckEntry(sysids[i], cuids[i], null);
                value = (AckEntry) deliveredMessages.get(entry);
                if (value == null) {
                    // XXX
                    String emsg = "[" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " not found, maybe rerouted";
                    if (ae == null) {
                        ae = new AckEntryNotFoundException(emsg);
                    }
                    ae.addAckEntry(sysids[i], cuids[i]);
                    logger.log(logger.WARNING, "[" + sysids[i] + ":" + cuids[i] + "] not found for preparing remote transaction " + tid + ", maybe rerouted");
                    continue;
                }
                if (value.getTUID() != null) {
                    String emsg = "[" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + "  has been rerouted";
                    if (ae == null) {
                        ae = new AckEntryNotFoundException(emsg);
                    }
                    ae.addAckEntry(sysids[i], cuids[i]);
                    logger.log(logger.WARNING, "[" + sysids[i] + ":" + cuids[i] + "] for preparing remote transaction " + tid + " conflict with transaction " + value.getTUID());
                    continue;
                }
                PacketReference ref = value.getReference();
                if (ref == null) {
                    deliveredMessages.remove(entry);
                    String emsg = "Unable to prepare [" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " because the message has been removed";
                    if (ae == null) {
                        ae = new AckEntryNotFoundException(emsg);
                    }
                    ae.addAckEntry(sysids[i], cuids[i]);
                    logger.log(logger.WARNING, emsg);
                    continue;
                }
                com.sun.messaging.jmq.jmsserver.core.ConsumerUID scuid = value.getStoredConsumerUID();
                ta = new TransactionAcknowledgement(sysids[i], cuids[i], scuid);
                if (!scuid.shouldStore() || !ref.isPersistent()) {
                    ta.setShouldStore(false);
                }
                if (!Globals.getDestinationList().isPartitionMode()) {
                    TransactionList[] tls = DL.getTransactionList(Globals.getStore().getPrimaryPartition());
                    tl = tls[0];
                } else {
                    refpstore = ref.getPartitionedStore();
                    TransactionList[] tls = Globals.getDestinationList().getTransactionList(refpstore);
                    tl = tls[0];
                    if (tl == null) {
                        deliveredMessages.remove(entry);
                        String emsg = "Unable to prepare [" + sysids[i] + ":" + cuids[i] + "]TID=" + tid + " because transaction list for partition " + refpstore + " not found";
                        if (ae == null) {
                            ae = new AckEntryNotFoundException(emsg);
                        }
                        ae.addAckEntry(sysids[i], cuids[i]);
                        logger.log(logger.WARNING, emsg);
                        continue;
                    }
                }
                tltas = tltasmap.get(tl);
                if (tltas == null) {
                    tltas = new ArrayList<>();
                    tltasmap.put(tl, tltas);
                }
                tltas.add(ta);
                if (getDEBUG()) {
                    dbuf.append("\n\t[" + ta + "]" + tl);
                }
            }
            if (ae != null) {
                throw ae;
            }
            Iterator<Map.Entry<TransactionList, ArrayList<TransactionAcknowledgement>>> itr = tltasmap.entrySet().iterator();
            Map.Entry<TransactionList, ArrayList<TransactionAcknowledgement>> pair = null;
            while (itr.hasNext()) {
                pair = itr.next();
                tl = pair.getKey();
                tltas = pair.getValue();
                tas = tltas.toArray(new TransactionAcknowledgement[tltas.size()]);
                TransactionState ts = new TransactionState(AutoRollbackType.NOT_PREPARED, 0L, true);
                ts.setState(TransactionState.PREPARED);
                if (getDEBUG()) {
                    logger.log(logger.INFO, "Preparing remote transaction " + tid + " for [" + tltas + "]" + tl + " from " + txnHomeBroker);
                }
                tl.logRemoteTransaction(tid, ts, tas, txnHomeBroker, false, true, true);
            }
            for (int i = 0; i < sysids.length; i++) {
                entry = new AckEntry(sysids[i], cuids[i], null);
                value = (AckEntry) deliveredMessages.get(entry);
                value.setTUID(tid);
            }
        }
        Iterator<TransactionList> itr = tltasmap.keySet().iterator();
        while (itr.hasNext()) {
            tl = itr.next();
            tl.pendingStartedForRemotePreparedTransaction(tid);
        }
        notifyPendingCheckTimer();
        if (getDEBUG()) {
            logger.log(logger.INFO, "Prepared remote transaction " + tid + " from " + txnHomeBroker + dbuf.toString());
        }
        return;
    }
    if (ackType == ClusterBroadcast.MSG_ROLLEDBACK) {
        if (getDEBUG()) {
            logger.log(logger.INFO, "Rolling back remote transaction " + tid + " from " + txnHomeBroker);
        }
        List<Object[]> list = TransactionList.getTransListsAndRemoteTranStates(tid);
        if (list == null) {
            if (getDEBUG()) {
                logger.log(logger.INFO, "Rolling back non-prepared remote transaction " + tid + " from " + txnHomeBroker);
            }
            List<AckEntry> entries = null;
            synchronized (deliveredMessages) {
                entries = getPendingConsumerUID(tid);
                Iterator<AckEntry> itr = entries.iterator();
                AckEntry e = null;
                while (itr.hasNext()) {
                    e = itr.next();
                    if (deliveredMessages.get(e) == null) {
                        itr.remove();
                        continue;
                    }
                    if (consumers.get(e.getConsumerUID()) != null) {
                        itr.remove();
                        continue;
                    }
                }
                if (e != null) {
                    deliveredMessages.remove(e);
                    cleanupPendingConsumerUID(e.getConsumerUID(), e.getSysMessageID());
                }
            }
            if (entries.size() == 0) {
                logger.log(logger.INFO, br.getKString(br.I_ROLLBACK_REMOTE_TXN_NOT_FOUND, tid, txnHomeBroker));
                return;
            }
            Iterator<AckEntry> itr = entries.iterator();
            while (itr.hasNext()) {
                AckEntry e = itr.next();
                SysMessageID sysid = e.getSysMessageID();
                com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = e.getConsumerUID();
                com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = e.getStoredConsumerUID();
                if (suid == null) {
                    suid = cuid;
                }
                // PART
                PacketReference ref = DL.get(null, sysid);
                if (ref == null) {
                    if (getDEBUG()) {
                        logger.log(logger.INFO, "[" + sysid + ":" + cuid + "] reference not found in rolling back remote non-prepared transaction " + tid);
                    }
                    continue;
                }
                ref.removeInDelivery(suid);
                ref.getDestination().forwardOrphanMessage(ref, suid);
            }
            return;
        }
        // if list == null
        TransactionList tl = null;
        Object[] oo = null;
        for (int li = 0; li < list.size(); li++) {
            oo = list.get(li);
            tl = (TransactionList) oo[0];
            if (!tl.updateRemoteTransactionState(tid, TransactionState.ROLLEDBACK, false, false, true)) {
                return;
            }
            if (tl.getRecoveryRemoteTransactionAcks(tid) != null) {
                rollbackRecoveryRemoteTransaction(tl, tid, txnHomeBroker);
            }
            RemoteTransactionAckEntry tae = tl.getRemoteTransactionAcks(tid);
            if (tae == null) {
                logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_NO_NONRECOVERY_TXNACK_TO_ROLLBACK, tid));
            } else if (tae.processed()) {
                logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_NO_MORE_TXNACK_TO_ROLLBACK, tid));
            } else if (!tae.isLocalRemote()) {
                TransactionAcknowledgement[] tas = tae.getAcks();
                Set s = new LinkedHashSet();
                AckEntry entry = null, value = null;
                for (int i = 0; i < tas.length; i++) {
                    SysMessageID sysid = tas[i].getSysMessageID();
                    com.sun.messaging.jmq.jmsserver.core.ConsumerUID uid = tas[i].getConsumerUID();
                    com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = tas[i].getStoredConsumerUID();
                    if (suid == null) {
                        suid = uid;
                    }
                    synchronized (deliveredMessages) {
                        entry = new AckEntry(sysid, uid, null);
                        value = (AckEntry) deliveredMessages.get(entry);
                        if (value == null) {
                            if (getDEBUG()) {
                                logger.log(logger.INFO, "[" + sysid + ":" + uid + "] not found in rolling back remote transaction " + tid);
                            }
                            continue;
                        }
                        if (value.getTUID() == null || !value.getTUID().equals(tid)) {
                            if (getDEBUG()) {
                                logger.log(logger.INFO, "[" + sysid + ":" + uid + "] with TUID=" + value.getTUID() + ", in confict for rolling back remote transaction " + tid);
                            }
                            continue;
                        }
                        if (consumers.get(uid) == null) {
                            deliveredMessages.remove(entry);
                            cleanupPendingConsumerUID(uid, sysid);
                            s.add(tas[i]);
                        } else {
                            value.setTUID(null);
                        }
                    }
                }
                Iterator itr = s.iterator();
                while (itr.hasNext()) {
                    TransactionAcknowledgement ta = (TransactionAcknowledgement) itr.next();
                    SysMessageID sysid = ta.getSysMessageID();
                    com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = ta.getConsumerUID();
                    com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = ta.getStoredConsumerUID();
                    if (suid == null) {
                        suid = cuid;
                    }
                    // PART
                    PacketReference ref = DL.get(null, sysid);
                    if (ref == null) {
                        if (getDEBUG()) {
                            logger.log(logger.INFO, "[" + sysid + ":" + cuid + "] reference not found in rolling back remote transaction " + tid);
                        }
                        continue;
                    }
                    ref.removeInDelivery(suid);
                    ref.getDestination().forwardOrphanMessage(ref, suid);
                }
            }
            try {
                tl.removeRemoteTransactionAck(tid);
            } catch (Exception e) {
                logger.log(logger.WARNING, "Unable to remove transaction ack for rolledback transaction " + tid + ": " + e.getMessage());
            }
            try {
                tl.removeRemoteTransactionID(tid, true);
            } catch (Exception e) {
                logger.log(logger.WARNING, "Unable to remove rolledback remote transaction " + tid + ": " + e.getMessage());
            }
        }
        // for
        return;
    }
    int cLogRecordCount = 0;
    ArrayList cLogDstList = null;
    ArrayList cLogMsgList = null;
    ArrayList cLogIntList = null;
    if (ackType == ClusterBroadcast.MSG_ACKNOWLEDGED) {
        if (getDEBUG()) {
            logger.log(logger.INFO, "Committing remote transaction " + tid + " from " + txnHomeBroker);
        }
        List<Object[]> list = TransactionList.getTransListsAndRemoteTranStates(tid);
        if (list == null) {
            throw new BrokerException("Committing remote transaction " + tid + " not found", Status.NOT_FOUND);
        }
        TransactionList tl = null;
        Object[] oo = null;
        for (int li = 0; li < list.size(); li++) {
            oo = list.get(li);
            tl = (TransactionList) oo[0];
            if (!tl.updateRemoteTransactionState(tid, TransactionState.COMMITTED, (sysids == null), true, true)) {
                if (getDEBUG()) {
                    logger.log(logger.INFO, "Remote transaction " + tid + " already committed, from " + txnHomeBroker);
                }
                continue;
            }
            boolean done = true;
            if (tl.getRecoveryRemoteTransactionAcks(tid) != null) {
                done = commitRecoveryRemoteTransaction(tl, tid, txnHomeBroker);
            }
            RemoteTransactionAckEntry tae = tl.getRemoteTransactionAcks(tid);
            if (tae == null) {
                logger.log(logger.INFO, "No non-recovery transaction acks to process for committing remote transaction " + tid);
            } else if (tae.processed()) {
                logger.log(logger.INFO, "No more transaction acks to process for committing remote transaction " + tid);
            } else if (!tae.isLocalRemote()) {
                boolean found = false;
                TransactionAcknowledgement[] tas = tae.getAcks();
                for (int i = 0; i < tas.length; i++) {
                    SysMessageID sysid = tas[i].getSysMessageID();
                    com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = tas[i].getConsumerUID();
                    if (sysids != null && !found) {
                        if (sysid.equals(sysids[0]) && cuid.equals(cuids[0])) {
                            found = true;
                        }
                    }
                    String dstName = null;
                    if (Globals.txnLogEnabled()) {
                        if (cLogDstList == null) {
                            cLogDstList = new ArrayList();
                            cLogMsgList = new ArrayList();
                            cLogIntList = new ArrayList();
                        }
                        PacketReference ref = DL.get(null, sysid);
                        if (ref != null && !ref.isDestroyed() && !ref.isInvalid()) {
                            Destination[] ds = DL.getDestination(ref.getPartitionedStore(), ref.getDestinationUID());
                            Destination dst = ds[0];
                            dstName = dst.getUniqueName();
                        }
                    }
                    if (acknowledgeMessageFromRemote(ackType, sysid, cuid, optionalProps)) {
                        if (dstName != null) {
                            // keep track for consumer txn log
                            com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = tas[i].getStoredConsumerUID();
                            if (suid == null) {
                                suid = cuid;
                            }
                            cLogRecordCount++;
                            cLogDstList.add(dstName);
                            cLogMsgList.add(sysid);
                            cLogIntList.add(suid);
                        }
                    } else {
                        done = false;
                    }
                }
                // notify that message acks have been written to store
                if (Globals.isNewTxnLogEnabled()) {
                    if (DL.isPartitionMode()) {
                        throw new BrokerException("Partition mode not supported if newTxnLog enabled");
                    }
                    ((TxnLoggingStore) Globals.getStore().getPrimaryPartition()).loggedCommitWrittenToMessageStore(tid, BaseTransaction.REMOTE_TRANSACTION_TYPE);
                }
                if (sysids != null && !found) {
                    logger.log(logger.ERROR, "Internal Error: [" + sysids[0] + ":" + cuids[0] + "] not found in remote transaction " + tid);
                    done = false;
                }
            }
            // tae != null
            if (done) {
                try {
                    tl.removeRemoteTransactionAck(tid);
                } catch (Exception e) {
                    logger.logStack(logger.WARNING, "Unable to remove transaction ack for committed remote transaction " + tid, e);
                }
                try {
                    tl.removeRemoteTransactionID(tid, true);
                } catch (Exception e) {
                    logger.logStack(logger.WARNING, "Unable to remove committed remote transaction " + tid, e);
                }
            } else if (Globals.getHAEnabled()) {
                throw new BrokerException("Remote transaction processing incomplete, TUID=" + tid);
            }
        }
        // log to txn log if enabled
        try {
            if (Globals.txnLogEnabled() && (cLogRecordCount > 0)) {
                // Log all acks for consuming txn
                ByteArrayOutputStream bos = new ByteArrayOutputStream((cLogRecordCount * (32 + SysMessageID.ID_SIZE + 8)) + 12);
                DataOutputStream dos = new DataOutputStream(bos);
                // Transaction ID (8 bytes)
                dos.writeLong(tid.longValue());
                // Number of acks (4 bytes)
                dos.writeInt(cLogRecordCount);
                for (int i = 0; i < cLogRecordCount; i++) {
                    String dst = (String) cLogDstList.get(i);
                    // Destination
                    dos.writeUTF(dst);
                    SysMessageID sysid = (SysMessageID) cLogMsgList.get(i);
                    // SysMessageID
                    sysid.writeID(dos);
                    long intid = ((com.sun.messaging.jmq.jmsserver.core.ConsumerUID) cLogIntList.get(i)).longValue();
                    // ConsumerUID
                    dos.writeLong(intid);
                }
                dos.close();
                bos.close();
                // PART
                ((TxnLoggingStore) Globals.getStore().getPrimaryPartition()).logTxn(TransactionLogType.CONSUME_TRANSACTION, bos.toByteArray());
            }
        } catch (IOException ex) {
            logger.logStack(Logger.ERROR, Globals.getBrokerResources().E_INTERNAL_BROKER_ERROR, "Got exception while writing to transaction log", ex);
            throw new BrokerException("Internal Error: Got exception while writing to transaction log", ex);
        }
        return;
    }
    throw new BrokerException("acknowledgeMessageFromRemotePriv:Unexpected ack type:" + ackType);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) ArrayList(java.util.ArrayList) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TxnLoggingStore(com.sun.messaging.jmq.jmsserver.persist.api.TxnLoggingStore) Destination(com.sun.messaging.jmq.jmsserver.core.Destination) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) DataOutputStream(java.io.DataOutputStream) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) Iterator(java.util.Iterator) PartitionedStore(com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore) TransactionAcknowledgement(com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ConsumerAlreadyAddedException(com.sun.messaging.jmq.jmsserver.util.ConsumerAlreadyAddedException) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) IOException(java.io.IOException) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) SysMessageID(com.sun.messaging.jmq.io.SysMessageID)

Example 44 with BrokerException

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

the class BrokerConsumers method removeRemoteDeadMessage.

private boolean removeRemoteDeadMessage(int ackType, PacketReference ref, ConsumerUID cuid, ConsumerUID storedid, Map optionalProps) throws BrokerException {
    if (ref == null) {
        return true;
    }
    Destination d = ref.getDestination();
    Queue[] qs = DL.getDMQ(ref.getPartitionedStore());
    if (d == qs[0]) {
        // already gone, ignore
        return true;
    }
    // first pull out properties
    String comment = null;
    Exception ex = null;
    Integer deliverCnt = null;
    Integer reasonInt = null;
    String deadbkr = null;
    if (optionalProps != null) {
        comment = (String) optionalProps.get(DMQ.UNDELIVERED_COMMENT);
        ex = (Exception) optionalProps.get(DMQ.UNDELIVERED_EXCEPTION);
        deliverCnt = (Integer) optionalProps.get(Destination.TEMP_CNT);
        reasonInt = (Integer) optionalProps.get("REASON");
        deadbkr = (String) optionalProps.get(DMQ.DEAD_BROKER);
    }
    RemoveReason rr = null;
    if (ackType == ClusterBroadcast.MSG_UNDELIVERABLE) {
        rr = RemoveReason.UNDELIVERABLE;
    } else {
        rr = RemoveReason.ERROR;
        if (reasonInt != null) {
            rr = RemoveReason.findReason(reasonInt.intValue());
        }
    }
    if (comment == null) {
        comment = "none";
    }
    if (ref.markDead(cuid, storedid, comment, ex, rr, (deliverCnt == null ? 0 : deliverCnt.intValue()), deadbkr)) {
        try {
            if (ref.isDead()) {
                if (getDEBUG()) {
                    Globals.getLogger().log(logger.INFO, "Remove dead message " + ref + " for remote consumer " + cuid + " on destination " + d + " with reason " + rr);
                }
                try {
                    d.removeDeadMessage(ref);
                } catch (Exception e) {
                    logger.log(logger.WARNING, "Unable to remove dead[" + rr + ", " + deadbkr + "] message " + ref + "[" + cuid + "]: " + e.getMessage(), e);
                }
            }
        } finally {
            ref.postAcknowledgedRemoval();
        }
        return true;
    }
    return false;
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) RemoveReason(com.sun.messaging.jmq.jmsserver.util.lists.RemoveReason) Queue(com.sun.messaging.jmq.jmsserver.core.Queue) ConsumerAlreadyAddedException(com.sun.messaging.jmq.jmsserver.util.ConsumerAlreadyAddedException) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) IOException(java.io.IOException) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException)

Example 45 with BrokerException

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

the class MultibrokerRouter method handleJMSMsg.

@Override
public void handleJMSMsg(Packet p, Map<ConsumerUID, Integer> consumers, BrokerAddress sender, boolean sendMsgDeliveredAck) throws BrokerException {
    Map<ConsumerUID, Integer> deliveryCnts = consumers;
    boolean hasflowcontrol = true;
    ArrayList<Consumer> targetVector = new ArrayList<>();
    ArrayList ignoreVector = new ArrayList();
    // PART
    PartitionedStore pstore = Globals.getStore().getPrimaryPartition();
    Iterator<Map.Entry<ConsumerUID, Integer>> itr = consumers.entrySet().iterator();
    Map.Entry<ConsumerUID, Integer> entry = null;
    while (itr.hasNext()) {
        entry = itr.next();
        ConsumerUID uid = entry.getKey();
        Consumer interest = Consumer.getConsumer(uid);
        if (interest != null && interest.isValid()) {
            // we need the interest for updating the ref
            targetVector.add(interest);
            ConsumerUID suid = interest.getStoredConsumerUID();
            if ((suid == null || suid.equals(uid)) && interest.getSubscription() == null) {
                hasflowcontrol = false;
            }
        } else {
            ignoreVector.add(uid);
        }
    }
    if (targetVector.isEmpty()) {
        sendIgnoreAck(p.getSysMessageID(), null, sender, ignoreVector);
        return;
    }
    boolean exists = false;
    // PART
    PacketReference ref = DL.get(null, p.getSysMessageID());
    if (ref != null) {
        BrokerAddress addr = ref.getBrokerAddress();
        if (addr == null || !addr.equals(sender)) {
            if (DEBUG) {
                logger.log(Logger.INFO, "Remote message " + ref.getSysMessageID() + " home broker " + addr + " changed to " + sender);
            }
            DL.remoteCheckMessageHomeChange(ref, sender);
            if (addr == null) {
                Object[] args = { ref.getSysMessageID(), sender, targetVector };
                logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_IGNORE_REMOTE_MSG_SENT_FROM, args));
                ignoreVector.addAll(targetVector);
                targetVector.clear();
                sendIgnoreAck(p.getSysMessageID(), ref, sender, ignoreVector);
                return;
            }
        }
    }
    List dsts = null;
    // PART
    ref = DL.get(null, p.getSysMessageID());
    boolean acquiredWriteLock = false;
    try {
        if (ref != null) {
            ref.acquireDestroyRemoteWriteLock();
            acquiredWriteLock = true;
            if (ref.isInvalid() || ref.isDestroyed()) {
                ref.clearDestroyRemoteWriteLock();
                acquiredWriteLock = false;
                // PART
                ref = DL.get(null, p.getSysMessageID());
                if (ref != null) {
                    ref.acquireDestroyRemoteWriteLock();
                    acquiredWriteLock = true;
                }
            }
        }
        if (ref != null) {
            if (ref.getBrokerAddress() == null) {
                ref.clearDestroyRemoteWriteLock();
                acquiredWriteLock = false;
                Object[] args = { ref.getSysMessageID(), sender, targetVector };
                logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_IGNORE_REMOTE_MSG_SENT_FROM, args));
                ignoreVector.addAll(targetVector);
                targetVector.clear();
                sendIgnoreAck(p.getSysMessageID(), ref, sender, ignoreVector);
                return;
            } else {
                exists = true;
                ref.setBrokerAddress(sender);
                if (p.getRedelivered()) {
                    ref.overrideRedeliver();
                }
            }
        } else {
            // PART
            ref = PacketReference.createReference(pstore, p, null);
            ref.setBrokerAddress(sender);
        }
        // consumer
        if (sendMsgDeliveredAck) {
            for (int i = 0; i < targetVector.size(); i++) {
                Consumer c = targetVector.get(i);
                // ref.addMessageDeliveredAck(c.getStoredConsumerUID());
                ref.addMessageDeliveredAck(c.getConsumerUID());
            }
        }
        try {
            if (ref.getDestinationUID().isWildcard()) {
                List[] dss = DL.findMatchingIDs(pstore, ref.getDestinationUID());
                dsts = dss[0];
            } else {
                // ok, autocreate the destination if necessary
                Destination[] ds = DL.getDestination(pstore, ref.getDestinationUID().getName(), ref.getDestinationUID().isQueue() ? DestType.DEST_TYPE_QUEUE : DestType.DEST_TYPE_TOPIC, true, true);
                Destination d = ds[0];
                if (d != null) {
                    dsts = new ArrayList();
                    dsts.add(d.getDestinationUID());
                }
            }
            if (dsts == null || dsts.isEmpty()) {
                ignoreVector.addAll(targetVector);
                targetVector.clear();
            } else {
                if (!exists && !targetVector.isEmpty()) {
                    ref.setNeverStore(true);
                    // OK .. we dont need to route .. its already happened
                    ref.storeRemoteInterests(targetVector, deliveryCnts);
                    itr = dsts.iterator();
                    while (itr.hasNext()) {
                        DestinationUID did = (DestinationUID) itr.next();
                        Destination[] ds = DL.getDestination(pstore, did);
                        Destination d = ds[0];
                        if (DEBUG) {
                            logger.log(logger.INFO, "Route remote message " + ref + " sent from " + sender + " to destination(s) " + did + " for consumer(s) " + targetVector + " hasflowcontrol=" + hasflowcontrol + ", enforcelimit=" + ENFORCE_REMOTE_DEST_LIMIT);
                        }
                        // add to message count
                        d.acquireQueueRemoteLock();
                        try {
                            PacketReference newref = d.getMessage(p.getSysMessageID());
                            if (newref != null) {
                                ignoreVector.addAll(targetVector);
                                targetVector.clear();
                                Object[] args = { p.getSysMessageID(), "" + d.getDestinationUID(), sender, newref + "[" + newref.getBrokerAddress() + "]" };
                                logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_REMOTE_NEW_MSG_ROUTED_ALREADY, args));
                                break;
                            }
                            d.queueMessage(ref, false, ENFORCE_REMOTE_DEST_LIMIT);
                        } finally {
                            d.clearQueueRemoteLock();
                        }
                    }
                } else if (exists) {
                    ref.addRemoteInterests(targetVector);
                }
            }
        } catch (Exception ex) {
            Object[] args = { "" + ref, sender, targetVector };
            String emsg = Globals.getBrokerResources().getKString(BrokerResources.W_EXCEPTION_PROCESS_REMOTE_MSG, args);
            if (!(ex instanceof BrokerException)) {
                logger.logStack(logger.WARNING, emsg, ex);
            } else {
                BrokerException be = (BrokerException) ex;
                int status = be.getStatusCode();
                if (status != Status.RESOURCE_FULL && status != Status.ENTITY_TOO_LARGE) {
                    logger.logStack(logger.WARNING, emsg, ex);
                } else {
                    Object[] args1 = { sender, targetVector };
                    emsg = Globals.getBrokerResources().getKString(BrokerResources.W_PROCESS_REMOTE_MSG_DST_LIMIT, args1);
                    int level = Logger.DEBUG;
                    if (!loggedFullDestsOnHandleJMSMsg.contains(ref.getDestinationUID())) {
                        level = Logger.WARNING;
                        loggedFullDestsOnHandleJMSMsg.add(ref.getDestinationUID());
                    }
                    logger.log(level, emsg + (level == Logger.DEBUG ? ": " + ex.getMessage() : ""));
                }
            }
        }
    } finally {
        if (ref != null && acquiredWriteLock) {
            ref.clearDestroyRemoteWriteLock();
        }
    }
    // Now deliver the message...
    StringBuilder debugString = new StringBuilder();
    debugString.append('\n');
    int i;
    for (i = 0; i < targetVector.size(); i++) {
        Consumer interest = targetVector.get(i);
        if (!interest.routeMessage(ref, false)) {
            // it disappeard on us, take care of it
            try {
                if (ref.acknowledged(interest.getConsumerUID(), interest.getStoredConsumerUID(), true, false)) {
                    try {
                        if (dsts == null) {
                            continue;
                        }
                        itr = dsts.iterator();
                        while (itr.hasNext()) {
                            DestinationUID did = (DestinationUID) itr.next();
                            Destination[] ds = DL.getDestination(pstore, did);
                            Destination d = ds[0];
                            d.removeRemoteMessage(ref.getSysMessageID(), RemoveReason.ACKNOWLEDGED, ref);
                        }
                    } finally {
                        ref.postAcknowledgedRemoval();
                    }
                }
            } catch (Exception ex) {
                logger.log(logger.INFO, "Internal error processing ack", ex);
            } finally {
                ref.removeRemoteConsumerUID(interest.getStoredConsumerUID(), interest.getConsumerUID());
            }
        }
        if (DEBUG) {
            debugString.append("\t" + interest.getConsumerUID() + "\n");
        }
    }
    if (DEBUG) {
        logger.log(logger.DEBUGHIGH, "MessageBus: Delivering message to : {0}", debugString.toString());
    }
    sendIgnoreAck(p.getSysMessageID(), ref, sender, ignoreVector);
}
Also used : Destination(com.sun.messaging.jmq.jmsserver.core.Destination) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ArrayList(java.util.ArrayList) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) ArrayList(java.util.ArrayList) List(java.util.List) PartitionedStore(com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) IOException(java.io.IOException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

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