Search in sources :

Example 16 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class QueueImpl method deleteReference.

@Override
public synchronized boolean deleteReference(final long messageID) throws Exception {
    boolean deleted = false;
    Transaction tx = new TransactionImpl(storageManager);
    try (LinkedListIterator<MessageReference> iter = iterator()) {
        while (iter.hasNext()) {
            MessageReference ref = iter.next();
            if (ref.getMessage().getMessageID() == messageID) {
                incDelivering(ref);
                acknowledge(tx, ref);
                iter.remove();
                refRemoved(ref);
                deleted = true;
                break;
            }
        }
        if (!deleted) {
            // Look in scheduled deliveries
            deleted = scheduledDeliveryHandler.removeReferenceWithID(messageID) != null ? true : false;
        }
        tx.commit();
        return deleted;
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) BindingsTransactionImpl(org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl) MessageReference(org.apache.activemq.artemis.core.server.MessageReference)

Example 17 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class QueueImpl method move.

private void move(final Transaction originalTX, final SimpleString address, final Binding binding, final MessageReference ref, final boolean rejectDuplicate, final AckReason reason) throws Exception {
    Transaction tx;
    if (originalTX != null) {
        tx = originalTX;
    } else {
        // if no TX we create a new one to commit at the end
        tx = new TransactionImpl(storageManager);
    }
    Message copyMessage = makeCopy(ref, reason == AckReason.EXPIRED);
    copyMessage.setAddress(address);
    postOffice.route(copyMessage, tx, false, rejectDuplicate, binding);
    acknowledge(tx, ref, reason);
    if (originalTX == null) {
        tx.commit();
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) Message(org.apache.activemq.artemis.api.core.Message) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) BindingsTransactionImpl(org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl)

Example 18 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class QueueImpl method deleteQueue.

@Override
public void deleteQueue(boolean removeConsumers) throws Exception {
    synchronized (this) {
        if (this.queueDestroyed)
            return;
        this.queueDestroyed = true;
    }
    Transaction tx = new BindingsTransactionImpl(storageManager);
    try {
        deleteAllReferences();
        destroyPaging();
        postOffice.removeBinding(name, tx, true);
        if (removeConsumers) {
            for (ConsumerHolder consumerHolder : consumerList) {
                consumerHolder.consumer.disconnect();
            }
        }
        if (isDurable()) {
            storageManager.deleteQueueBinding(tx.getID(), getID());
            tx.setContainsPersistent();
        }
        if (slowConsumerReaperFuture != null) {
            slowConsumerReaperFuture.cancel(false);
        }
        tx.commit();
    } catch (Exception e) {
        tx.rollback();
        throw e;
    } finally {
        if (factory != null) {
            factory.queueRemoved(this);
        }
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) BindingsTransactionImpl(org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) NoSuchElementException(java.util.NoSuchElementException)

Example 19 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction 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 20 with Transaction

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

Aggregations

Transaction (org.apache.activemq.artemis.core.transaction.Transaction)52 TransactionImpl (org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)24 MessageReference (org.apache.activemq.artemis.core.server.MessageReference)14 Test (org.junit.Test)14 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)13 Xid (javax.transaction.xa.Xid)12 Queue (org.apache.activemq.artemis.core.server.Queue)11 ArrayList (java.util.ArrayList)10 Message (org.apache.activemq.artemis.api.core.Message)10 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)9 Map (java.util.Map)8 StorageManager (org.apache.activemq.artemis.core.persistence.StorageManager)8 HashMap (java.util.HashMap)7 PageSubscriptionCounter (org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter)7 PageSubscription (org.apache.activemq.artemis.core.paging.cursor.PageSubscription)6 BindingsTransactionImpl (org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl)6 AtomicLong (java.util.concurrent.atomic.AtomicLong)5 List (java.util.List)4 NoSuchElementException (java.util.NoSuchElementException)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4