Search in sources :

Example 11 with SysMessageID

use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.

the class MigrateStoreHandler 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) {
    boolean noop = true;
    int status = Status.OK;
    String errMsg = "";
    if (DEBUG) {
        logger.log(Logger.INFO, this.getClass().getName() + ": " + "Request migrate this broker''s store: " + cmd_props);
    }
    String brokerID = (String) cmd_props.get(MessageType.JMQ_BROKER_ID);
    String partition = (String) cmd_props.get(MessageType.JMQ_MIGRATESTORE_PARTITION);
    if (partition == null) {
        if (brokerID != null) {
            logger.log(Logger.INFO, BrokerResources.I_ADMIN_MIGRATESTORE_TO, brokerID);
        } else {
            logger.log(Logger.INFO, BrokerResources.I_ADMIN_MIGRATESTORE);
        }
    } else {
        logger.log(Logger.INFO, "XXXAdmin request migrate this broker's store partition " + partition + " to broker " + brokerID);
    }
    HAMonitorService hamonitor = Globals.getHAMonitorService();
    if (hamonitor != null && hamonitor.inTakeover()) {
        status = Status.NOT_MODIFIED;
        errMsg = rb.getString(rb.E_CANNOT_PROCEED_TAKEOVER_IN_PROCESS);
        logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
    }
    if (status == Status.OK) {
        if (partition == null && Globals.getHAEnabled()) {
            status = Status.NOT_MODIFIED;
            errMsg = rb.getKString(rb.E_OPERATION_NOT_SUPPORTED_IN_HA, MessageType.getString(MessageType.MIGRATESTORE_BROKER));
            logger.log(Logger.ERROR, errMsg);
        }
    }
    if (status == Status.OK) {
        if (Globals.isJMSRAManagedBroker()) {
            status = Status.NOT_MODIFIED;
            errMsg = "Can not process migration store request because this broker's life cycle is JMSRA managed";
            logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
        }
    }
    UID partitionID = null;
    if (status == Status.OK) {
        if (partition != null) {
            try {
                long v = Long.parseLong(partition);
                partitionID = new UID(v);
            } catch (Exception e) {
                partitionID = null;
                status = Status.NOT_MODIFIED;
                errMsg = "XXXCan not process migration partition " + partition + " request because unable to parse " + partition + ": " + e;
                logger.log(Logger.ERROR, errMsg);
            }
        }
    }
    if (status == Status.OK) {
        if (partitionID != null && brokerID == null) {
            status = Status.NOT_MODIFIED;
            errMsg = "XXXCan not process migration partition " + partitionID + " request because brokerID not specified";
            logger.log(Logger.ERROR, errMsg);
        }
    }
    if (status == Status.OK) {
        if (partitionID != null && !(DL.isPartitionMode() && DL.isPartitionMigratable())) {
            status = Status.NOT_MODIFIED;
            errMsg = "XXXCan not process migration partition " + partitionID + " request because partition mode not enabled";
            logger.log(Logger.ERROR, errMsg);
        }
    }
    if (status == Status.OK) {
        if (partitionID != null) {
            DestinationList dl = DL.getDestinationList(partitionID);
            if (dl == null) {
                status = Status.NOT_MODIFIED;
                errMsg = "XXXCan not process migration partition " + partitionID + " request because partition " + partitionID + " not found";
                logger.log(Logger.ERROR, errMsg);
            } else if (dl.getPartitionedStore().isPrimaryPartition()) {
                status = Status.NOT_MODIFIED;
                errMsg = "XXXCan not process migration partition " + partitionID + " request because partition " + partitionID + " is the primary partition";
                logger.log(Logger.ERROR, errMsg);
            }
        }
    }
    if (status == Status.OK) {
        if (brokerID == null) {
            try {
                brokerID = getBrokerID();
            } catch (Throwable t) {
                status = Status.NOT_MODIFIED;
                errMsg = "Unable to get a connected broker to takeover this broker's store: " + t.getMessage();
                if ((t instanceof OperationNotAllowedException) && ((OperationNotAllowedException) t).getOperation().equals(MessageType.getString(MessageType.MIGRATESTORE_BROKER))) {
                    logger.log(logger.ERROR, errMsg);
                } else {
                    logger.logStack(logger.ERROR, errMsg, t);
                }
            }
        }
    }
    if (status != Status.OK) {
        sendReply(con, cmd_msg, brokerID, null, errMsg, status, null);
        return true;
    }
    try {
        BrokerStateHandler.setExclusiveRequestLock(ExclusiveRequest.MIGRATE_STORE);
    } catch (Throwable t) {
        status = Status.PRECONDITION_FAILED;
        if (t instanceof BrokerException) {
            status = ((BrokerException) t).getStatusCode();
        }
        errMsg = MessageType.getString(MessageType.MIGRATESTORE_BROKER) + ": " + Status.getString(status) + " - " + t.getMessage();
        logger.log(Logger.ERROR, errMsg);
        status = Status.NOT_MODIFIED;
    }
    try {
        if (partitionID != null) {
            migratePartition(con, cmd_msg, partitionID, brokerID);
            return true;
        }
        Long syncTimeout = null;
        final BrokerStateHandler bsh = Globals.getBrokerStateHandler();
        if (status == Status.OK) {
            try {
                syncTimeout = (Long) cmd_props.get(MessageType.JMQ_MIGRATESTORE_SYNC_TIMEOUT);
                ClusterManager cm = Globals.getClusterManager();
                BrokerMQAddress self = (BrokerMQAddress) cm.getMQAddress();
                BrokerMQAddress master = (cm.getMasterBroker() == null ? null : (BrokerMQAddress) cm.getMasterBroker().getBrokerURL());
                if (self.equals(master)) {
                    throw new BrokerException(rb.getKString(rb.E_CHANGE_MASTER_BROKER_FIRST, MessageType.getString(MessageType.MIGRATESTORE_BROKER)), Status.NOT_ALLOWED);
                }
            } catch (Throwable t) {
                status = Status.PRECONDITION_FAILED;
                if (t instanceof BrokerException) {
                    status = ((BrokerException) t).getStatusCode();
                }
                errMsg = MessageType.getString(MessageType.MIGRATESTORE_BROKER) + ": " + Status.getString(status) + " - " + t.getMessage();
                logger.log(Logger.ERROR, errMsg);
                status = Status.NOT_MODIFIED;
            }
        }
        SysMessageID replyMessageID = null;
        String replyStatusStr = null;
        try {
            // shutdown if !noop
            String hostport = null;
            if (status == Status.OK) {
                try {
                    noop = false;
                    hostport = bsh.takeoverME(brokerID, syncTimeout, con);
                } catch (BrokerException ex) {
                    status = ex.getStatusCode();
                    if (status == Status.BAD_REQUEST || status == Status.NOT_ALLOWED || status == Status.NOT_MODIFIED || status == Status.UNAVAILABLE || status == Status.PRECONDITION_FAILED) {
                        status = Status.PRECONDITION_FAILED;
                        if (ex instanceof OperationNotAllowedException) {
                            if (((OperationNotAllowedException) ex).getOperation().equals(MessageType.getString(MessageType.MIGRATESTORE_BROKER))) {
                                status = Status.NOT_MODIFIED;
                                noop = true;
                            }
                        }
                        errMsg = Globals.getBrokerResources().getKString(BrokerResources.E_FAIL_MIGRATESTORE_NOT_MIGRATED, ex.getMessage());
                        if (noop) {
                            logger.log(Logger.ERROR, errMsg);
                        } else {
                            logger.logStack(Logger.ERROR, errMsg, ex);
                        }
                    } else {
                        status = Status.EXPECTATION_FAILED;
                        errMsg = Globals.getBrokerResources().getKString(BrokerResources.E_FAIL_TAKEOVERME, brokerID, ex.getMessage());
                        logger.logStack(Logger.ERROR, errMsg, ex);
                    }
                }
            }
            if (status == Status.OK) {
                try {
                    Globals.getClusterBroadcast().stopClusterIO(false, true, null);
                } catch (Throwable t) {
                    logger.logStack(Logger.WARNING, "Failed to stop cluster IO", t);
                }
            }
            List ret = sendReply(con, cmd_msg, brokerID, hostport, errMsg, status, null);
            replyMessageID = (SysMessageID) ret.get(0);
            replyStatusStr = (String) ret.get(1);
        } finally {
            final SysMessageID mid = replyMessageID;
            final String statusStr = replyStatusStr;
            if (!noop) {
                try {
                    if (con instanceof IMQBasicConnection) {
                        IMQBasicConnection ipCon = (IMQBasicConnection) con;
                        ipCon.flushControl(1000);
                    }
                    try {
                        Globals.getServiceManager().stopNewConnections(ServiceType.NORMAL);
                    } catch (Exception e) {
                        logger.logStack(logger.WARNING, rb.getKString(rb.W_STOP_SERVICE_FAIL, ServiceType.getServiceTypeString(ServiceType.NORMAL), e.getMessage()), e);
                    }
                    try {
                        Globals.getServiceManager().stopNewConnections(ServiceType.ADMIN);
                    } catch (Exception e) {
                        logger.logStack(logger.WARNING, rb.getKString(rb.W_STOP_SERVICE_FAIL, ServiceType.getServiceTypeString(ServiceType.ADMIN), e.getMessage()), e);
                    }
                    BrokerStateHandler.setShuttingDown(true);
                    bsh.prepareShutdown(false, true);
                    waitForHandlersToComplete(20);
                    if (mid == null) {
                        logger.log(Logger.INFO, BrokerResources.I_ADMIN_SHUTDOWN_REQUEST);
                        bsh.initiateShutdown("admin", 0, false, 0, true);
                        return true;
                    }
                    final String waitstr = rb.getKString(rb.I_WAIT_ADMIN_RECEIVE_REPLY, MessageType.getString(MessageType.MIGRATESTORE_BROKER_REPLY) + "[" + statusStr + "]");
                    final long totalwait = Globals.getConfig().getIntProperty(MAX_WAIT_ADMIN_CLIENT_PROP, DEFAULT_MAX_WAIT_ADMIN_CLIENT) * 1000L;
                    final IMQConnection conn = con;
                    Executors.newSingleThreadExecutor().execute(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                long waited = 0L;
                                while (conn.getConnectionState() < Connection.STATE_CLEANED && waited < totalwait) {
                                    logger.log(logger.INFO, waitstr);
                                    try {
                                        Thread.sleep(500);
                                        waited += 500L;
                                    } catch (Exception e) {
                                    /* ignore */
                                    }
                                }
                                logger.log(Logger.INFO, BrokerResources.I_ADMIN_SHUTDOWN_REQUEST);
                                bsh.initiateShutdown("admin-migratestore-shutdown", 0, false, 0, true);
                            } catch (Throwable t) {
                                bsh.initiateShutdown("admin-migratestore-shutdown::[" + t.toString() + "]", 0, false, 0, true);
                            }
                        }
                    });
                } catch (Throwable t) {
                    bsh.initiateShutdown("admin-migratestore-shutdown:[" + t.toString() + "]", 0, false, 0, true);
                }
            }
        }
    } finally {
        BrokerStateHandler.unsetExclusiveRequestLock(ExclusiveRequest.MIGRATE_STORE);
    }
    return true;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) BrokerStateHandler(com.sun.messaging.jmq.jmsserver.BrokerStateHandler) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection) OperationNotAllowedException(com.sun.messaging.jmq.jmsserver.util.OperationNotAllowedException) OperationNotAllowedException(com.sun.messaging.jmq.jmsserver.util.OperationNotAllowedException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) BrokerMQAddress(com.sun.messaging.jmq.jmsserver.core.BrokerMQAddress) UID(com.sun.messaging.jmq.util.UID) IMQConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQConnection) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 12 with SysMessageID

use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.

the class BrokerConsumers method removeConsumer.

public void removeConsumer(com.sun.messaging.jmq.jmsserver.core.ConsumerUID uid, Map<TransactionUID, LinkedHashMap<SysMessageID, Integer>> pendingMsgs, boolean cleanup) throws BrokerException {
    if (getDEBUG()) {
        logger.log(logger.INFO, "BrokerConsumers.removeConsumer(" + uid + ", " + pendingMsgs + ", " + cleanup + ")");
    }
    Consumer c = null;
    synchronized (removeConsumerLock) {
        c = (Consumer) consumers.remove(uid);
    }
    if (c == null && !cleanup) {
        return;
    }
    Destination d = null;
    if (c != null) {
        c.pause("MultiBroker - removing consumer");
        // remove it from the destination
        Destination[] ds = DL.getDestination(null, c.getDestinationUID());
        // PART
        d = ds[0];
        // quit listening for busy events
        Object listener = listeners.remove(uid);
        if (listener != null) {
            c.removeEventListener(listener);
        }
        // remove it from the active list
        activeConsumers.remove(c);
    }
    Set destroySet = new LinkedHashSet();
    LinkedHashSet openacks = new LinkedHashSet();
    Map<PartitionedStore, LinkedHashSet> openmsgmp = new LinkedHashMap<>();
    Map<TransactionUID, Set<AckEntry>> mypending = new LinkedHashMap<>();
    boolean haspendingtxn = false;
    // we sent the messages directly and must explicitly ack
    synchronized (deliveredMessages) {
        if (c != null) {
            cleanupList.put(uid, c.getParentList());
        }
        Map cparentmp = (Map) cleanupList.get(uid);
        if (getDEBUG()) {
            logger.log(logger.INFO, "BrokerConsumers.removeConsumer:" + uid + ", pending=" + pendingMsgs + ", cleanup=" + cleanup + ", cparentmp=" + cparentmp);
        }
        Iterator itr = deliveredMessages.values().iterator();
        while (itr.hasNext()) {
            AckEntry e = (AckEntry) itr.next();
            if (!e.getConsumerUID().equals(uid)) {
                continue;
            }
            if (pendingMsgs != null) {
                Iterator<Map.Entry<TransactionUID, LinkedHashMap<SysMessageID, Integer>>> itr1 = pendingMsgs.entrySet().iterator();
                Map.Entry<TransactionUID, LinkedHashMap<SysMessageID, Integer>> pair = null;
                TransactionUID tid = null;
                LinkedHashMap<SysMessageID, Integer> sysiddcts = null;
                Set<AckEntry> ackentries = null;
                boolean found = false;
                Integer deliverCnt = null;
                while (itr1.hasNext()) {
                    pair = itr1.next();
                    tid = pair.getKey();
                    sysiddcts = pair.getValue();
                    deliverCnt = sysiddcts.get(e.getSysMessageID());
                    if (deliverCnt != null) {
                        if (tid != null && tid.longValue() == 0L) {
                            updateConsumed(e, deliverCnt, false);
                            continue;
                        }
                        if (cleanup || e.getTUID() != null) {
                            updateConsumed(e, deliverCnt, false);
                            break;
                        }
                        found = true;
                        ackentries = mypending.get(tid);
                        if (ackentries == null) {
                            ackentries = new LinkedHashSet();
                            mypending.put(tid, ackentries);
                        }
                        if (tid != null && !haspendingtxn) {
                            haspendingtxn = true;
                        }
                        ackentries.add(e);
                        updateConsumed(e, deliverCnt, false);
                        break;
                    }
                }
                if (found) {
                    continue;
                }
            }
            if (e.getTUID() != null) {
                continue;
            }
            if (getDEBUG()) {
                logger.log(logger.DEBUG, "BrokerConsumers.removeConsumer:" + uid + ", remove AckEntry=" + e + ", c=" + c);
            }
            itr.remove();
            if (cleanup) {
                updateConsumed(e, Integer.valueOf(1), true);
            }
            if (c != null) {
                if (c.isFalconRemote()) {
                    e.acknowledged(false);
                } else {
                    PacketReference ref = e.getReference();
                    if (ref != null) {
                        ref.removeInDelivery(e.getStoredConsumerUID());
                        destroySet.add(ref);
                    }
                }
                continue;
            }
            PacketReference ref = e.getReference();
            if (ref != null) {
                ref.removeInDelivery(e.getStoredConsumerUID());
            }
            openacks.add(e);
        }
        itr = openacks.iterator();
        while (itr.hasNext()) {
            AckEntry e = (AckEntry) itr.next();
            if (cparentmp == null || cparentmp.size() == 0) {
                e.acknowledged(false);
            } else {
                PacketReference ref = e.getReference();
                if (ref != null) {
                    PartitionedStore ps = null;
                    if (!ref.getDestinationUID().isQueue()) {
                        ps = new NoPersistPartitionedStoreImpl(e.getStoredConsumerUID());
                    } else {
                        ps = ref.getPartitionedStore();
                    }
                    LinkedHashSet set = openmsgmp.get(ps);
                    if (set == null) {
                        set = new LinkedHashSet();
                        openmsgmp.put(ps, set);
                    }
                    set.add(ref);
                }
            }
        }
        if (cparentmp != null && cparentmp.size() > 0 && openmsgmp.size() > 0) {
            itr = openmsgmp.entrySet().iterator();
            PartitionedStore ps = null;
            Prioritized pl = null;
            Map.Entry pair = null;
            while (itr.hasNext()) {
                pair = (Map.Entry) itr.next();
                ps = (PartitionedStore) pair.getKey();
                pl = (Prioritized) cparentmp.get(ps);
                if (pl != null) {
                    pl.addAllOrdered((Set) pair.getValue());
                } else {
                    logger.log(logger.WARNING, "Message(s) " + cparentmp.get(ps) + "[" + ps + "] parentlist not found on removing consumer " + uid);
                }
            }
        }
        if (cleanup || pendingMsgs == null) {
            cleanupList.remove(uid);
            pendingConsumerUIDs.remove(uid);
        } else if (mypending.size() > 0) {
            pendingConsumerUIDs.put(uid, mypending);
        }
    }
    if (c != null) {
        c.destroyConsumer(destroySet, false, false);
        if (d != null) {
            d.removeConsumer(uid, false);
        }
    }
    List<Set<AckEntry>> l = null;
    synchronized (pendingConsumerUIDs) {
        l = new ArrayList<>(mypending.values());
    }
    Set<AckEntry> entries = null;
    Iterator<Set<AckEntry>> itr = l.iterator();
    while (itr.hasNext()) {
        entries = itr.next();
        AckEntry entry = null;
        Iterator<AckEntry> itr1 = entries.iterator();
        while (itr1.hasNext()) {
            entry = itr1.next();
            entry.pendingStarted();
        }
    }
    if (haspendingtxn) {
        notifyPendingCheckTimer();
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Destination(com.sun.messaging.jmq.jmsserver.core.Destination) Prioritized(com.sun.messaging.jmq.util.lists.Prioritized) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) LinkedHashMap(java.util.LinkedHashMap) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) Iterator(java.util.Iterator) PartitionedStore(com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) NoPersistPartitionedStoreImpl(com.sun.messaging.jmq.jmsserver.persist.api.NoPersistPartitionedStoreImpl) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Example 13 with SysMessageID

use of com.sun.messaging.jmq.io.SysMessageID 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 14 with SysMessageID

use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.

the class ClusterConsumerInfo method getPendingMessages.

/**
 * @return null if empty
 */
public Map<TransactionUID, LinkedHashMap<SysMessageID, Integer>> getPendingMessages() {
    assert (pkt != null);
    LinkedHashMap<TransactionUID, LinkedHashMap<SysMessageID, Integer>> m = new LinkedHashMap<>();
    String key = null, val = null;
    String tidstr = null;
    TransactionUID tid = null;
    LinkedHashMap<SysMessageID, Integer> sysiddcnts = null;
    Iterator itr = pkt.propsKeySet().iterator();
    while (itr.hasNext()) {
        key = (String) itr.next();
        tid = null;
        if (key.startsWith(PROP_PREFIX_PENDING_TID_MID_DCT)) {
            tidstr = key.substring(PROP_PREFIX_PENDING_TID_MID_DCT.length());
            if (tidstr.length() > 0) {
                tid = new TransactionUID(Long.parseLong(tidstr));
            }
            val = (String) pkt.getProp(key);
            if (val == null || val.length() == 0) {
                continue;
            }
            sysiddcnts = parsePendingMsgs(val);
            if (m.get(tid) != null) {
                throw new RuntimeException("Unexpected " + PROP_PREFIX_PENDING_TID_MID_DCT + " content: duplicated entries(" + m.get(tid) + ", " + sysiddcnts + ") for " + tid + ", " + m);
            }
            m.put(tid, sysiddcnts);
        }
    }
    if (m.size() > 0) {
        return m;
    }
    // check 4.5 patch protocol
    key = null;
    val = null;
    tidstr = null;
    tid = null;
    sysiddcnts = null;
    itr = pkt.propsKeySet().iterator();
    while (itr.hasNext()) {
        key = (String) itr.next();
        tid = null;
        if (key.startsWith(PROP_PREFIX_PENDING_TID)) {
            tidstr = key.substring(PROP_PREFIX_PENDING_TID.length());
            if (tidstr.length() > 0) {
                tid = new TransactionUID(Long.parseLong(tidstr));
            }
            val = (String) pkt.getProp(key);
            if (val == null || val.length() == 0) {
                continue;
            }
            sysiddcnts = parsePendingMsgs(val);
            if (m.get(tid) != null) {
                throw new RuntimeException("Unexpected " + PROP_PREFIX_PENDING_TID + " content: duplicated entries(" + m.get(tid) + ", " + sysiddcnts + ") for " + tid + ", " + m);
            }
            m.put(tid, sysiddcnts);
        }
    }
    if (m.size() > 0) {
        return m;
    }
    // check 4.5 protocol
    val = (String) pkt.getProp(PROP_PENDING_MESSAGES);
    if (val == null || val.length() == 0) {
        return null;
    }
    sysiddcnts = parsePendingMsgs(val);
    m.put(null, sysiddcnts);
    return m;
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) SysMessageID(com.sun.messaging.jmq.io.SysMessageID)

Example 15 with SysMessageID

use of com.sun.messaging.jmq.io.SysMessageID in project openmq by eclipse-ee4j.

the class ClusterMessageAckInfo method getReplyGPacket.

public GPacket getReplyGPacket(int status, String reason, ArrayList[] aes) {
    assert (pkt != null);
    GPacket gp = GPacket.getInstance();
    gp.setType(ProtocolGlobals.G_MESSAGE_ACK_REPLY);
    gp.putProp("X", pkt.getProp("X"));
    gp.putProp("T", Integer.valueOf(getAckType()));
    if (pkt.getProp("C") != null) {
        gp.putProp("C", pkt.getProp("C"));
    }
    if (pkt.getProp("messageBrokerSession") != null) {
        gp.putProp("messageBrokerSession", pkt.getProp("messageBrokerSession"));
    }
    if (pkt.getProp("messageStoreSession") != null) {
        gp.putProp("messageStoreSession", pkt.getProp("messageStoreSession"));
    }
    if (pkt.getProp("transactionID") != null) {
        gp.putProp("transactionID", pkt.getProp("transactionID"));
    }
    if (pkt.getProp("ackackAsync") != null) {
        gp.putProp("ackackAsync", pkt.getProp("ackackAsync"));
    }
    gp.putProp("S", Integer.valueOf(status));
    if (reason != null) {
        gp.putProp("reason", reason);
    }
    if (aes == null) {
        if (pkt.getPayload() != null) {
            gp.setPayload(ByteBuffer.wrap(pkt.getPayload().array()));
        }
        return gp;
    }
    gp.putProp("notfound", Integer.valueOf(aes[0].size()));
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        for (int i = 0; i < aes[0].size(); i++) {
            ((SysMessageID) aes[0].get(i)).writeID(dos);
            ClusterConsumerInfo.writeConsumerUID((com.sun.messaging.jmq.jmsserver.core.ConsumerUID) aes[1].get(i), dos);
        }
        dos.flush();
        bos.flush();
        byte[] buf = bos.toByteArray();
        gp.setPayload(ByteBuffer.wrap(buf));
    } catch (Exception e) {
        Globals.getLogger().logStack(Globals.getLogger().WARNING, e.getMessage(), e);
    }
    return gp;
}
Also used : SysMessageID(com.sun.messaging.jmq.io.SysMessageID) GPacket(com.sun.messaging.jmq.io.GPacket) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException)

Aggregations

SysMessageID (com.sun.messaging.jmq.io.SysMessageID)70 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)31 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)27 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)19 PacketReference (com.sun.messaging.jmq.jmsserver.core.PacketReference)18 Destination (com.sun.messaging.jmq.jmsserver.core.Destination)15 TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)15 HashMap (java.util.HashMap)15 IOException (java.io.IOException)14 ArrayList (java.util.ArrayList)14 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)12 Iterator (java.util.Iterator)12 Map (java.util.Map)12 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)10 TransactionAcknowledgement (com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement)10 AckEntryNotFoundException (com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException)10 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)9 DestinationList (com.sun.messaging.jmq.jmsserver.core.DestinationList)9 List (java.util.List)9 Packet (com.sun.messaging.jmq.io.Packet)8