Search in sources :

Example 6 with Pair

use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.

the class JournalImpl method checkControlFile.

/**
 * @throws Exception
 */
private void checkControlFile() throws Exception {
    ArrayList<String> dataFiles = new ArrayList<>();
    ArrayList<String> newFiles = new ArrayList<>();
    ArrayList<Pair<String, String>> renames = new ArrayList<>();
    SequentialFile controlFile = AbstractJournalUpdateTask.readControlFile(fileFactory, dataFiles, newFiles, renames);
    if (controlFile != null) {
        for (String dataFile : dataFiles) {
            SequentialFile file = fileFactory.createSequentialFile(dataFile);
            if (file.exists()) {
                file.delete();
            }
        }
        for (String newFile : newFiles) {
            SequentialFile file = fileFactory.createSequentialFile(newFile);
            if (file.exists()) {
                final String originalName = file.getFileName();
                final String newName = originalName.substring(0, originalName.lastIndexOf(".cmp"));
                file.renameTo(newName);
            }
        }
        for (Pair<String, String> rename : renames) {
            SequentialFile fileTmp = fileFactory.createSequentialFile(rename.getA());
            SequentialFile fileTo = fileFactory.createSequentialFile(rename.getB());
            // delete a valid file depending on where the crash occurred during the control file delete
            if (fileTmp.exists()) {
                fileTo.delete();
                fileTmp.renameTo(rename.getB());
            }
        }
        controlFile.delete();
    }
    cleanupTmpFiles(".cmp");
    cleanupTmpFiles(".tmp");
    return;
}
Also used : SequentialFile(org.apache.activemq.artemis.core.io.SequentialFile) ArrayList(java.util.ArrayList) Pair(org.apache.activemq.artemis.api.core.Pair)

Example 7 with Pair

use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.

the class ActiveMQServerImpl method loadJournals.

private JournalLoadInformation[] loadJournals() throws Exception {
    JournalLoader journalLoader = activation.createJournalLoader(postOffice, pagingManager, storageManager, queueFactory, nodeManager, managementService, groupingHandler, configuration, parentServer);
    JournalLoadInformation[] journalInfo = new JournalLoadInformation[2];
    List<QueueBindingInfo> queueBindingInfos = new ArrayList<>();
    List<GroupingInfo> groupingInfos = new ArrayList<>();
    List<AddressBindingInfo> addressBindingInfos = new ArrayList<>();
    journalInfo[0] = storageManager.loadBindingJournal(queueBindingInfos, groupingInfos, addressBindingInfos);
    recoverStoredConfigs();
    Map<Long, AddressBindingInfo> addressBindingInfosMap = new HashMap<>();
    journalLoader.initAddresses(addressBindingInfosMap, addressBindingInfos);
    Map<Long, QueueBindingInfo> queueBindingInfosMap = new HashMap<>();
    journalLoader.initQueues(queueBindingInfosMap, queueBindingInfos);
    journalLoader.handleGroupingBindings(groupingInfos);
    Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap = new HashMap<>();
    HashSet<Pair<Long, Long>> pendingLargeMessages = new HashSet<>();
    List<PageCountPending> pendingNonTXPageCounter = new LinkedList<>();
    journalInfo[1] = storageManager.loadMessageJournal(postOffice, pagingManager, resourceManager, queueBindingInfosMap, duplicateIDMap, pendingLargeMessages, pendingNonTXPageCounter, journalLoader);
    journalLoader.handleDuplicateIds(duplicateIDMap);
    for (Pair<Long, Long> msgToDelete : pendingLargeMessages) {
        ActiveMQServerLogger.LOGGER.deletingPendingMessage(msgToDelete);
        LargeServerMessage msg = storageManager.createLargeMessage();
        msg.setMessageID(msgToDelete.getB());
        msg.setPendingRecordID(msgToDelete.getA());
        msg.setDurable(true);
        msg.deleteFile();
    }
    if (pendingNonTXPageCounter.size() != 0) {
        try {
            journalLoader.recoverPendingPageCounters(pendingNonTXPageCounter);
        } catch (Throwable e) {
            ActiveMQServerLogger.LOGGER.errorRecoveringPageCounter(e);
        }
    }
    journalLoader.cleanUp();
    return journalInfo;
}
Also used : PageCountPending(org.apache.activemq.artemis.core.persistence.impl.PageCountPending) GroupingInfo(org.apache.activemq.artemis.core.persistence.GroupingInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) Pair(org.apache.activemq.artemis.api.core.Pair) ConcurrentHashSet(org.apache.activemq.artemis.utils.collections.ConcurrentHashSet) HashSet(java.util.HashSet) QueueBindingInfo(org.apache.activemq.artemis.core.persistence.QueueBindingInfo) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) LinkedList(java.util.LinkedList) JournalLoadInformation(org.apache.activemq.artemis.core.journal.JournalLoadInformation) AddressBindingInfo(org.apache.activemq.artemis.core.persistence.AddressBindingInfo) LargeServerMessage(org.apache.activemq.artemis.core.server.LargeServerMessage)

Example 8 with Pair

use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.

the class QueueImpl method locateTargetBinding.

private Pair<String, Binding> locateTargetBinding(SimpleString queueSuffix, Message copyMessage, long oldQueueID) {
    String targetNodeID = null;
    Binding targetBinding = null;
    for (Map.Entry<SimpleString, Binding> entry : postOffice.getAllBindings().entrySet()) {
        Binding binding = entry.getValue();
        // we only care about the remote queue bindings
        if (binding instanceof RemoteQueueBinding) {
            RemoteQueueBinding remoteQueueBinding = (RemoteQueueBinding) binding;
            // does this remote queue binding point to the same queue as the message?
            if (oldQueueID == remoteQueueBinding.getRemoteQueueID()) {
                // get the name of this queue so we can find the corresponding remote queue binding pointing to the scale down target node
                SimpleString oldQueueName = remoteQueueBinding.getRoutingName();
                // parse the queue name of the remote queue binding to determine the node ID
                String temp = remoteQueueBinding.getQueue().getName().toString();
                targetNodeID = temp.substring(temp.lastIndexOf(".") + 1);
                logger.debug("Message formerly destined for " + oldQueueName + " with ID: " + oldQueueID + " on address " + copyMessage.getAddressSimpleString() + " on node " + targetNodeID);
                // now that we have the name of the queue we need to look through all the bindings again to find the new remote queue binding
                for (Map.Entry<SimpleString, Binding> entry2 : postOffice.getAllBindings().entrySet()) {
                    binding = entry2.getValue();
                    // again, we only care about the remote queue bindings
                    if (binding instanceof RemoteQueueBinding) {
                        remoteQueueBinding = (RemoteQueueBinding) binding;
                        temp = remoteQueueBinding.getQueue().getName().toString();
                        targetNodeID = temp.substring(temp.lastIndexOf(".") + 1);
                        if (oldQueueName.equals(remoteQueueBinding.getRoutingName()) && targetNodeID.equals(queueSuffix.toString())) {
                            targetBinding = remoteQueueBinding;
                            if (logger.isDebugEnabled()) {
                                logger.debug("Message now destined for " + remoteQueueBinding.getRoutingName() + " with ID: " + remoteQueueBinding.getRemoteQueueID() + " on address " + copyMessage.getAddress() + " on node " + targetNodeID);
                            }
                            break;
                        } else {
                            logger.debug("Failed to match: " + remoteQueueBinding);
                        }
                    }
                }
            }
        }
    }
    return new Pair<>(targetNodeID, targetBinding);
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) RemoteQueueBinding(org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) Map(java.util.Map) HashMap(java.util.HashMap) RemoteQueueBinding(org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding) Pair(org.apache.activemq.artemis.api.core.Pair)

Example 9 with Pair

use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.

the class ScaleDownHandler method scaleDownDuplicateIDs.

public void scaleDownDuplicateIDs(Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap, ClientSessionFactory sessionFactory, SimpleString managementAddress, String user, String password) throws Exception {
    try (ClientSession session = sessionFactory.createSession(user, password, true, false, false, false, 0);
        ClientProducer producer = session.createProducer(managementAddress)) {
        // todo - https://issues.jboss.org/browse/HORNETQ-1336
        for (Map.Entry<SimpleString, List<Pair<byte[], Long>>> entry : duplicateIDMap.entrySet()) {
            ClientMessage message = session.createMessage(false);
            List<Pair<byte[], Long>> list = entry.getValue();
            String[] array = new String[list.size()];
            for (int i = 0; i < list.size(); i++) {
                Pair<byte[], Long> pair = list.get(i);
                array[i] = new String(pair.getA());
            }
            ManagementHelper.putOperationInvocation(message, ResourceNames.BROKER, "updateDuplicateIdCache", entry.getKey().toString(), array);
            producer.send(message);
        }
    }
}
Also used : SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) ArrayList(java.util.ArrayList) List(java.util.List) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) HashMap(java.util.HashMap) Map(java.util.Map) Pair(org.apache.activemq.artemis.api.core.Pair)

Example 10 with Pair

use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.

the class ScaleDownHandler method scaleDownTransactions.

public void scaleDownTransactions(ClientSessionFactory sessionFactory, ResourceManager resourceManager, String user, String password) throws Exception {
    ClientSession session = sessionFactory.createSession(user, password, true, false, false, false, 0);
    ClientSession queueCreateSession = sessionFactory.createSession(user, password, false, true, true, false, 0);
    List<Xid> preparedTransactions = resourceManager.getPreparedTransactions();
    Map<String, Long> queueIDs = new HashMap<>();
    for (Xid xid : preparedTransactions) {
        logger.debug("Scaling down transaction: " + xid);
        Transaction transaction = resourceManager.getTransaction(xid);
        session.start(xid, XAResource.TMNOFLAGS);
        List<TransactionOperation> allOperations = transaction.getAllOperations();
        // Get the information of the Prepared TXs so it could replay the TXs
        Map<Message, Pair<List<Long>, List<Long>>> queuesToSendTo = new HashMap<>();
        for (TransactionOperation operation : allOperations) {
            if (operation instanceof PostOfficeImpl.AddOperation) {
                PostOfficeImpl.AddOperation addOperation = (PostOfficeImpl.AddOperation) operation;
                List<MessageReference> refs = addOperation.getRelatedMessageReferences();
                for (MessageReference ref : refs) {
                    Message message = ref.getMessage();
                    Queue queue = ref.getQueue();
                    long queueID;
                    String queueName = queue.getName().toString();
                    if (queueIDs.containsKey(queueName)) {
                        queueID = queueIDs.get(queueName);
                    } else {
                        queueID = createQueueIfNecessaryAndGetID(queueCreateSession, queue, message.getAddressSimpleString());
                        // store it so we don't have to look it up every time
                        queueIDs.put(queueName, queueID);
                    }
                    Pair<List<Long>, List<Long>> queueIds = queuesToSendTo.get(message);
                    if (queueIds == null) {
                        queueIds = new Pair<List<Long>, List<Long>>(new ArrayList<Long>(), new ArrayList<Long>());
                        queuesToSendTo.put(message, queueIds);
                    }
                    queueIds.getA().add(queueID);
                }
            } else if (operation instanceof RefsOperation) {
                RefsOperation refsOperation = (RefsOperation) operation;
                List<MessageReference> refs = refsOperation.getReferencesToAcknowledge();
                for (MessageReference ref : refs) {
                    Message message = ref.getMessage();
                    Queue queue = ref.getQueue();
                    long queueID;
                    String queueName = queue.getName().toString();
                    if (queueIDs.containsKey(queueName)) {
                        queueID = queueIDs.get(queueName);
                    } else {
                        queueID = createQueueIfNecessaryAndGetID(queueCreateSession, queue, message.getAddressSimpleString());
                        // store it so we don't have to look it up every time
                        queueIDs.put(queueName, queueID);
                    }
                    Pair<List<Long>, List<Long>> queueIds = queuesToSendTo.get(message);
                    if (queueIds == null) {
                        queueIds = new Pair<List<Long>, List<Long>>(new ArrayList<Long>(), new ArrayList<Long>());
                        queuesToSendTo.put(message, queueIds);
                    }
                    queueIds.getA().add(queueID);
                    queueIds.getB().add(queueID);
                }
            }
        }
        ClientProducer producer = session.createProducer();
        for (Map.Entry<Message, Pair<List<Long>, List<Long>>> entry : queuesToSendTo.entrySet()) {
            List<Long> ids = entry.getValue().getA();
            ByteBuffer buffer = ByteBuffer.allocate(ids.size() * 8);
            for (Long id : ids) {
                buffer.putLong(id);
            }
            Message message = entry.getKey();
            message.putBytesProperty(Message.HDR_ROUTE_TO_IDS.toString(), buffer.array());
            ids = entry.getValue().getB();
            if (ids.size() > 0) {
                buffer = ByteBuffer.allocate(ids.size() * 8);
                for (Long id : ids) {
                    buffer.putLong(id);
                }
                message.putBytesProperty(Message.HDR_ROUTE_TO_ACK_IDS.toString(), buffer.array());
            }
            producer.send(message.getAddressSimpleString().toString(), message);
        }
        session.end(xid, XAResource.TMSUCCESS);
        session.prepare(xid);
    }
}
Also used : ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) Message(org.apache.activemq.artemis.api.core.Message) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) ArrayList(java.util.ArrayList) List(java.util.List) Queue(org.apache.activemq.artemis.core.server.Queue) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) Pair(org.apache.activemq.artemis.api.core.Pair) PostOfficeImpl(org.apache.activemq.artemis.core.postoffice.impl.PostOfficeImpl) TransactionOperation(org.apache.activemq.artemis.core.transaction.TransactionOperation) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) ByteBuffer(java.nio.ByteBuffer) Xid(javax.transaction.xa.Xid) Transaction(org.apache.activemq.artemis.core.transaction.Transaction) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Pair (org.apache.activemq.artemis.api.core.Pair)29 ArrayList (java.util.ArrayList)16 HashMap (java.util.HashMap)12 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)12 List (java.util.List)6 Map (java.util.Map)6 SequentialFile (org.apache.activemq.artemis.core.io.SequentialFile)5 JournalFile (org.apache.activemq.artemis.core.journal.impl.JournalFile)5 HashSet (java.util.HashSet)4 TransportConfiguration (org.apache.activemq.artemis.api.core.TransportConfiguration)4 JournalImpl (org.apache.activemq.artemis.core.journal.impl.JournalImpl)4 Test (org.junit.Test)4 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ActiveMQBuffer (org.apache.activemq.artemis.api.core.ActiveMQBuffer)3 Message (org.apache.activemq.artemis.api.core.Message)3 PreparedTransactionInfo (org.apache.activemq.artemis.core.journal.PreparedTransactionInfo)3 RecordInfo (org.apache.activemq.artemis.core.journal.RecordInfo)3 LargeServerMessage (org.apache.activemq.artemis.core.server.LargeServerMessage)3 PersistedBindings (org.apache.activemq.artemis.jms.persistence.config.PersistedBindings)3 PersistedType (org.apache.activemq.artemis.jms.persistence.config.PersistedType)3