Search in sources :

Example 46 with Queue

use of org.apache.activemq.artemis.core.server.Queue in project activemq-artemis by apache.

the class PostOfficeJournalLoader method initQueues.

@Override
public void initQueues(Map<Long, QueueBindingInfo> queueBindingInfosMap, List<QueueBindingInfo> queueBindingInfos) throws Exception {
    int duplicateID = 0;
    for (final QueueBindingInfo queueBindingInfo : queueBindingInfos) {
        queueBindingInfosMap.put(queueBindingInfo.getId(), queueBindingInfo);
        final Filter filter = FilterImpl.createFilter(queueBindingInfo.getFilterString());
        final boolean isTopicIdentification = FilterUtils.isTopicIdentification(filter);
        if (postOffice.getBinding(queueBindingInfo.getQueueName()) != null) {
            if (isTopicIdentification) {
                final long tx = storageManager.generateID();
                storageManager.deleteQueueBinding(tx, queueBindingInfo.getId());
                storageManager.commitBindings(tx);
                continue;
            } else {
                final SimpleString newName = queueBindingInfo.getQueueName().concat("-" + (duplicateID++));
                ActiveMQServerLogger.LOGGER.queueDuplicatedRenaming(queueBindingInfo.getQueueName().toString(), newName.toString());
                queueBindingInfo.replaceQueueName(newName);
            }
        }
        final QueueConfig.Builder queueConfigBuilder;
        if (queueBindingInfo.getAddress() == null) {
            queueConfigBuilder = QueueConfig.builderWith(queueBindingInfo.getId(), queueBindingInfo.getQueueName());
        } else {
            queueConfigBuilder = QueueConfig.builderWith(queueBindingInfo.getId(), queueBindingInfo.getQueueName(), queueBindingInfo.getAddress());
        }
        queueConfigBuilder.filter(filter).pagingManager(pagingManager).user(queueBindingInfo.getUser()).durable(true).temporary(false).autoCreated(queueBindingInfo.isAutoCreated()).purgeOnNoConsumers(queueBindingInfo.isPurgeOnNoConsumers()).maxConsumers(queueBindingInfo.getMaxConsumers()).exclusive(queueBindingInfo.isExclusive()).lastValue(queueBindingInfo.isLastValue()).routingType(RoutingType.getType(queueBindingInfo.getRoutingType()));
        final Queue queue = queueFactory.createQueueWith(queueConfigBuilder.build());
        queue.setConsumersRefCount(new QueueManagerImpl(((PostOfficeImpl) postOffice).getServer(), queueBindingInfo.getQueueName()));
        if (queueBindingInfo.getQueueStatusEncodings() != null) {
            for (QueueStatusEncoding encoding : queueBindingInfo.getQueueStatusEncodings()) {
                if (encoding.getStatus() == QueueStatus.PAUSED)
                    queue.reloadPause(encoding.getId());
            }
        }
        final Binding binding = new LocalQueueBinding(queue.getAddress(), queue, nodeManager.getNodeId());
        queues.put(queue.getID(), queue);
        postOffice.addBinding(binding);
        managementService.registerQueue(queue, queue.getAddress(), storageManager);
    }
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) GroupBinding(org.apache.activemq.artemis.core.server.group.impl.GroupBinding) QueueConfig(org.apache.activemq.artemis.core.server.QueueConfig) QueueStatusEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.QueueStatusEncoding) QueueBindingInfo(org.apache.activemq.artemis.core.persistence.QueueBindingInfo) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) Filter(org.apache.activemq.artemis.core.filter.Filter) Queue(org.apache.activemq.artemis.core.server.Queue) PostOfficeImpl(org.apache.activemq.artemis.core.postoffice.impl.PostOfficeImpl)

Example 47 with Queue

use of org.apache.activemq.artemis.core.server.Queue in project activemq-artemis by apache.

the class PostOfficeJournalLoader method handleAddMessage.

@Override
public void handleAddMessage(Map<Long, Map<Long, AddMessageRecord>> queueMap) throws Exception {
    for (Map.Entry<Long, Map<Long, AddMessageRecord>> entry : queueMap.entrySet()) {
        long queueID = entry.getKey();
        Map<Long, AddMessageRecord> queueRecords = entry.getValue();
        Queue queue = this.queues.get(queueID);
        if (queue == null) {
            if (queueRecords.values().size() != 0) {
                ActiveMQServerLogger.LOGGER.journalCannotFindQueueForMessage(queueID);
            }
            continue;
        }
        // Redistribution could install a Redistributor while we are still loading records, what will be an issue with
        // prepared ACKs
        // We make sure te Queue is paused before we reroute values.
        queue.pause();
        Collection<AddMessageRecord> valueRecords = queueRecords.values();
        long currentTime = System.currentTimeMillis();
        for (AddMessageRecord record : valueRecords) {
            long scheduledDeliveryTime = record.getScheduledDeliveryTime();
            if (scheduledDeliveryTime != 0 && scheduledDeliveryTime <= currentTime) {
                scheduledDeliveryTime = 0;
                record.getMessage().setScheduledDeliveryTime(0L);
            }
            if (scheduledDeliveryTime != 0) {
                record.getMessage().setScheduledDeliveryTime(scheduledDeliveryTime);
            }
            MessageReference ref = postOffice.reroute(record.getMessage(), queue, null);
            ref.setDeliveryCount(record.getDeliveryCount());
            if (scheduledDeliveryTime != 0) {
                record.getMessage().setScheduledDeliveryTime(0L);
            }
        }
    }
}
Also used : AddMessageRecord(org.apache.activemq.artemis.core.persistence.impl.journal.AddMessageRecord) AtomicLong(java.util.concurrent.atomic.AtomicLong) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) HashMap(java.util.HashMap) Map(java.util.Map) Queue(org.apache.activemq.artemis.core.server.Queue)

Example 48 with Queue

use of org.apache.activemq.artemis.core.server.Queue 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)

Example 49 with Queue

use of org.apache.activemq.artemis.core.server.Queue in project activemq-artemis by apache.

the class ScaleDownHandler method scaleDownSNF.

private long scaleDownSNF(final SimpleString address, final Set<Queue> queues, final ClientProducer producer) throws Exception {
    long messageCount = 0;
    final String propertyEnd;
    // If this SNF is towards our targetNodeId
    boolean queueOnTarget = address.toString().endsWith(targetNodeId);
    if (queueOnTarget) {
        propertyEnd = targetNodeId;
    } else {
        propertyEnd = address.toString().substring(address.toString().lastIndexOf("."));
    }
    Transaction tx = new TransactionImpl(storageManager);
    for (Queue queue : queues) {
        // using auto-closeable
        try (LinkedListIterator<MessageReference> messagesIterator = queue.browserIterator()) {
            // loop through every message of this queue
            while (messagesIterator.hasNext()) {
                MessageReference messageRef = messagesIterator.next();
                Message message = messageRef.getMessage().copy();
                /* Here we are taking messages out of a store-and-forward queue and sending them to the corresponding
                * address on the scale-down target server.  However, we have to take the existing _AMQ_ROUTE_TOsf.*
                * property and put its value into the _AMQ_ROUTE_TO property so the message is routed properly.
                */
                byte[] oldRouteToIDs = null;
                List<SimpleString> propertiesToRemove = new ArrayList<>();
                message.removeProperty(Message.HDR_ROUTE_TO_IDS.toString());
                for (SimpleString propName : message.getPropertyNames()) {
                    if (propName.startsWith(Message.HDR_ROUTE_TO_IDS)) {
                        if (propName.toString().endsWith(propertyEnd)) {
                            oldRouteToIDs = message.getBytesProperty(propName.toString());
                        }
                        propertiesToRemove.add(propName);
                    }
                }
                for (SimpleString propertyToRemove : propertiesToRemove) {
                    message.removeProperty(propertyToRemove.toString());
                }
                if (queueOnTarget) {
                    message.putBytesProperty(Message.HDR_ROUTE_TO_IDS.toString(), oldRouteToIDs);
                } else {
                    message.putBytesProperty(Message.HDR_SCALEDOWN_TO_IDS.toString(), oldRouteToIDs);
                }
                logger.debug("Scaling down message " + message + " from " + address + " to " + message.getAddress() + " on node " + targetNodeId);
                producer.send(message.getAddress(), message);
                messageCount++;
                messagesIterator.remove();
                ackMessageOnQueue(tx, queue, messageRef);
            }
        } catch (NoSuchElementException ignored) {
        // this could happen through paging browsing
        }
    }
    tx.commit();
    return messageCount;
}
Also used : ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) Message(org.apache.activemq.artemis.api.core.Message) ArrayList(java.util.ArrayList) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) Transaction(org.apache.activemq.artemis.core.transaction.Transaction) Queue(org.apache.activemq.artemis.core.server.Queue) NoSuchElementException(java.util.NoSuchElementException)

Example 50 with Queue

use of org.apache.activemq.artemis.core.server.Queue in project activemq-artemis by apache.

the class ScaleDownHandler method scaleDownMessages.

public long scaleDownMessages(ClientSessionFactory sessionFactory, SimpleString nodeId, String user, String password) throws Exception {
    long messageCount = 0;
    targetNodeId = nodeId != null ? nodeId.toString() : getTargetNodeId(sessionFactory);
    try (ClientSession session = sessionFactory.createSession(user, password, false, true, true, false, 0)) {
        ClientProducer producer = session.createProducer();
        // perform a loop per address
        for (SimpleString address : postOffice.getAddresses()) {
            logger.debug("Scaling down address " + address);
            Bindings bindings = postOffice.getBindingsForAddress(address);
            // It will get a list of queues on this address, ordered by the number of messages
            Set<Queue> queues = new TreeSet<>(new OrderQueueByNumberOfReferencesComparator());
            for (Binding binding : bindings.getBindings()) {
                if (binding instanceof LocalQueueBinding) {
                    Queue queue = ((LocalQueueBinding) binding).getQueue();
                    // as part of scale down we will cancel any scheduled message and pass it to theWhile we scan for the queues we will also cancel any scheduled messages and deliver them right away
                    queue.deliverScheduledMessages();
                    queues.add(queue);
                }
            }
            String sfPrefix = ((PostOfficeImpl) postOffice).getServer().getInternalNamingPrefix() + "sf.";
            if (address.toString().startsWith(sfPrefix)) {
                messageCount += scaleDownSNF(address, queues, producer);
            } else {
                messageCount += scaleDownRegularMessages(address, queues, session, producer);
            }
        }
    }
    return messageCount;
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) Bindings(org.apache.activemq.artemis.core.postoffice.Bindings) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) TreeSet(java.util.TreeSet) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) Queue(org.apache.activemq.artemis.core.server.Queue) PostOfficeImpl(org.apache.activemq.artemis.core.postoffice.impl.PostOfficeImpl)

Aggregations

Queue (org.apache.activemq.artemis.core.server.Queue)275 Test (org.junit.Test)193 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)128 ClientSession (org.apache.activemq.artemis.api.core.client.ClientSession)89 ClientProducer (org.apache.activemq.artemis.api.core.client.ClientProducer)85 ClientMessage (org.apache.activemq.artemis.api.core.client.ClientMessage)75 AmqpClient (org.apache.activemq.transport.amqp.client.AmqpClient)70 AmqpConnection (org.apache.activemq.transport.amqp.client.AmqpConnection)70 AmqpSession (org.apache.activemq.transport.amqp.client.AmqpSession)70 ClientConsumer (org.apache.activemq.artemis.api.core.client.ClientConsumer)64 AmqpReceiver (org.apache.activemq.transport.amqp.client.AmqpReceiver)59 AmqpMessage (org.apache.activemq.transport.amqp.client.AmqpMessage)56 ClientSessionFactory (org.apache.activemq.artemis.api.core.client.ClientSessionFactory)49 AmqpSender (org.apache.activemq.transport.amqp.client.AmqpSender)47 Session (javax.jms.Session)36 Connection (javax.jms.Connection)32 Configuration (org.apache.activemq.artemis.core.config.Configuration)31 ActiveMQServer (org.apache.activemq.artemis.core.server.ActiveMQServer)30 AddressSettings (org.apache.activemq.artemis.core.settings.impl.AddressSettings)27 TextMessage (javax.jms.TextMessage)25