Search in sources :

Example 16 with TransactionImpl

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

the class DuplicateCacheTest method testDuplicateNonPersistent.

@Test
public void testDuplicateNonPersistent() throws Exception {
    createStorage();
    DuplicateIDCache cache = new DuplicateIDCacheImpl(new SimpleString("test"), 2000, journal, false);
    TransactionImpl tx = new TransactionImpl(journal);
    for (int i = 0; i < 5000; i++) {
        byte[] bytes = RandomUtil.randomBytes();
        cache.addToCache(bytes, tx);
    }
    tx.commit();
    for (int i = 0; i < 5000; i++) {
        byte[] bytes = RandomUtil.randomBytes();
        cache.addToCache(bytes, null);
    }
}
Also used : DuplicateIDCache(org.apache.activemq.artemis.core.postoffice.DuplicateIDCache) DuplicateIDCacheImpl(org.apache.activemq.artemis.core.postoffice.impl.DuplicateIDCacheImpl) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) Test(org.junit.Test)

Example 17 with TransactionImpl

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

the class DuplicateCacheTest method testDuplicate.

@Test
public void testDuplicate() throws Exception {
    createStorage();
    DuplicateIDCache cache = new DuplicateIDCacheImpl(new SimpleString("test"), 2000, journal, true);
    TransactionImpl tx = new TransactionImpl(journal);
    for (int i = 0; i < 5000; i++) {
        byte[] bytes = RandomUtil.randomBytes();
        cache.addToCache(bytes, tx);
    }
    tx.commit();
    tx = new TransactionImpl(journal);
    for (int i = 0; i < 5000; i++) {
        byte[] bytes = RandomUtil.randomBytes();
        cache.addToCache(bytes, tx);
    }
    tx.commit();
    byte[] id = RandomUtil.randomBytes();
    Assert.assertFalse(cache.contains(id));
    cache.addToCache(id, null);
    Assert.assertTrue(cache.contains(id));
    cache.deleteFromCache(id);
    final CountDownLatch latch = new CountDownLatch(1);
    OperationContextImpl.getContext().executeOnCompletion(new IOCallback() {

        @Override
        public void done() {
            latch.countDown();
        }

        @Override
        public void onError(int errorCode, String errorMessage) {
        }
    }, true);
    Assert.assertTrue(latch.await(1, TimeUnit.MINUTES));
    Assert.assertFalse(cache.contains(id));
}
Also used : DuplicateIDCache(org.apache.activemq.artemis.core.postoffice.DuplicateIDCache) DuplicateIDCacheImpl(org.apache.activemq.artemis.core.postoffice.impl.DuplicateIDCacheImpl) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) CountDownLatch(java.util.concurrent.CountDownLatch) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) Test(org.junit.Test)

Example 18 with TransactionImpl

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

the class PostOfficeImpl method checkDuplicateID.

private boolean checkDuplicateID(final Message message, final RoutingContext context, boolean rejectDuplicates, AtomicBoolean startedTX) throws Exception {
    // Check the DuplicateCache for the Bridge first
    Object bridgeDup = message.removeExtraBytesProperty(Message.HDR_BRIDGE_DUPLICATE_ID);
    if (bridgeDup != null) {
        // if the message is being sent from the bridge, we just ignore the duplicate id, and use the internal one
        byte[] bridgeDupBytes = (byte[]) bridgeDup;
        DuplicateIDCache cacheBridge = getDuplicateIDCache(BRIDGE_CACHE_STR.concat(context.getAddress(message).toString()));
        if (context.getTransaction() == null) {
            context.setTransaction(new TransactionImpl(storageManager));
            startedTX.set(true);
        }
        if (!cacheBridge.atomicVerify(bridgeDupBytes, context.getTransaction())) {
            context.getTransaction().rollback();
            startedTX.set(false);
            message.decrementRefCount();
            return false;
        }
    } else {
        // if used BridgeDuplicate, it's not going to use the regular duplicate
        // since this will would break redistribution (re-setting the duplicateId)
        byte[] duplicateIDBytes = message.getDuplicateIDBytes();
        DuplicateIDCache cache = null;
        boolean isDuplicate = false;
        if (duplicateIDBytes != null) {
            cache = getDuplicateIDCache(context.getAddress(message));
            isDuplicate = cache.contains(duplicateIDBytes);
            if (rejectDuplicates && isDuplicate) {
                ActiveMQServerLogger.LOGGER.duplicateMessageDetected(message);
                String warnMessage = "Duplicate message detected - message will not be routed. Message information:" + message.toString();
                if (context.getTransaction() != null) {
                    context.getTransaction().markAsRollbackOnly(new ActiveMQDuplicateIdException(warnMessage));
                }
                message.decrementRefCount();
                return false;
            }
        }
        if (cache != null && !isDuplicate) {
            if (context.getTransaction() == null) {
                // We need to store the duplicate id atomically with the message storage, so we need to create a tx for this
                context.setTransaction(new TransactionImpl(storageManager));
                startedTX.set(true);
            }
            cache.addToCache(duplicateIDBytes, context.getTransaction(), false);
        }
    }
    return true;
}
Also used : DuplicateIDCache(org.apache.activemq.artemis.core.postoffice.DuplicateIDCache) ActiveMQDuplicateIdException(org.apache.activemq.artemis.api.core.ActiveMQDuplicateIdException) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) SimpleString(org.apache.activemq.artemis.api.core.SimpleString)

Example 19 with TransactionImpl

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

the class PageSubscriptionImpl method ack.

@Override
public void ack(final PagedReference reference) throws Exception {
    // Need to do the ACK and counter atomically (inside a TX) or the counter could get out of sync
    Transaction tx = new TransactionImpl(this.store);
    ackTx(tx, reference);
    tx.commit();
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)

Example 20 with TransactionImpl

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

the class Redistributor method handle.

@Override
public synchronized HandleStatus handle(final MessageReference reference) throws Exception {
    if (!active) {
        return HandleStatus.BUSY;
    } else if (reference.getMessage().getGroupID() != null) {
        // we shouldn't redistribute with message groups return NO_MATCH so other messages can be delivered
        return HandleStatus.NO_MATCH;
    }
    final Transaction tx = new TransactionImpl(storageManager);
    final Pair<RoutingContext, Message> routingInfo = postOffice.redistribute(reference.getMessage(), queue, tx);
    if (routingInfo == null) {
        return HandleStatus.BUSY;
    }
    if (!reference.getMessage().isLargeMessage()) {
        postOffice.processRoute(routingInfo.getB(), routingInfo.getA(), false);
        ackRedistribution(reference, tx);
    } else {
        active = false;
        executor.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    postOffice.processRoute(routingInfo.getB(), routingInfo.getA(), false);
                    ackRedistribution(reference, tx);
                    synchronized (Redistributor.this) {
                        active = true;
                        count++;
                        queue.deliverAsync();
                    }
                } catch (Exception e) {
                    try {
                        tx.rollback();
                    } catch (Exception e2) {
                        // Nothing much we can do now
                        ActiveMQServerLogger.LOGGER.failedToRollback(e2);
                    }
                }
            }
        });
    }
    return HandleStatus.HANDLED;
}
Also used : RoutingContext(org.apache.activemq.artemis.core.server.RoutingContext) 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)

Aggregations

TransactionImpl (org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)31 Transaction (org.apache.activemq.artemis.core.transaction.Transaction)24 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)11 MessageReference (org.apache.activemq.artemis.core.server.MessageReference)11 Test (org.junit.Test)10 Queue (org.apache.activemq.artemis.core.server.Queue)9 Message (org.apache.activemq.artemis.api.core.Message)8 PageSubscriptionCounter (org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter)7 StorageManager (org.apache.activemq.artemis.core.persistence.StorageManager)7 ArrayList (java.util.ArrayList)6 HashMap (java.util.HashMap)6 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)5 PageSubscription (org.apache.activemq.artemis.core.paging.cursor.PageSubscription)5 DuplicateIDCache (org.apache.activemq.artemis.core.postoffice.DuplicateIDCache)5 BindingsTransactionImpl (org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl)5 Map (java.util.Map)4 ClientSession (org.apache.activemq.artemis.api.core.client.ClientSession)4 ClientSessionFactory (org.apache.activemq.artemis.api.core.client.ClientSessionFactory)4 LinkedList (java.util.LinkedList)3 NoSuchElementException (java.util.NoSuchElementException)3