org.mule.util.queue.PersistentXaTransactionContext.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.util.queue.PersistentXaTransactionContext.java

Source

/*
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */
package org.mule.util.queue;

import org.mule.util.journal.queue.XaQueueTxJournalEntry;
import org.mule.util.journal.queue.XaTxQueueTransactionJournal;
import org.mule.util.xa.ResourceManagerException;

import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;

import javax.transaction.xa.Xid;

import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;

/**
 * Implementation of {@link org.mule.util.queue.XaQueueTransactionContext} for persistent queues using XA transactions
 */
public class PersistentXaTransactionContext implements XaQueueTransactionContext {
    private final XaTxQueueTransactionJournal transactionJournal;
    private final QueueProvider queueProvider;
    private Xid xid;

    public PersistentXaTransactionContext(XaTxQueueTransactionJournal simpleTxQueueTransactionJournal,
            QueueProvider queueProvider, Xid xid) {
        this.transactionJournal = simpleTxQueueTransactionJournal;
        this.queueProvider = queueProvider;
        this.xid = xid;
    }

    public boolean offer(QueueStore queue, Serializable item, long offerTimeout) throws InterruptedException {
        this.transactionJournal.logAdd(xid, queue, item);
        return true;
    }

    public void untake(QueueStore queue, Serializable item) throws InterruptedException {
        this.transactionJournal.logAddFirst(xid, queue, item);
    }

    public void clear(QueueStore queue) throws InterruptedException {
        synchronized (queue) {
            while (poll(queue, 100) != null)
                ;
        }
    }

    public Serializable poll(QueueStore queue, long pollTimeout) throws InterruptedException {
        synchronized (queue) {
            Serializable value = queue.peek();
            if (value == null) {
                return null;
            }
            this.transactionJournal.logRemove(xid, queue, value);
            return queue.poll(pollTimeout);
        }
    }

    public Serializable peek(QueueStore queue) throws InterruptedException {
        return queue.peek();
    }

    public int size(QueueStore queue) {
        final AtomicInteger addSize = new AtomicInteger(0);
        CollectionUtils.forAllDo(this.transactionJournal.getLogEntriesForTx(xid), new Closure() {
            @Override
            public void execute(Object value) {
                if (((XaQueueTxJournalEntry) value).isAdd() || ((XaQueueTxJournalEntry) value).isAddFirst()) {
                    addSize.incrementAndGet();
                }
            }
        });
        return queue.getSize() + addSize.get();
    }

    @Override
    public void doCommit() throws ResourceManagerException {
        try {
            Collection<XaQueueTxJournalEntry> logEntries = this.transactionJournal.getLogEntriesForTx(xid);
            for (XaQueueTxJournalEntry entry : logEntries) {
                if (entry.isAdd()) {
                    queueProvider.getQueue(entry.getQueueName()).putNow(entry.getValue());
                } else if (entry.isAddFirst()) {
                    queueProvider.getQueue(entry.getQueueName()).untake(entry.getValue());
                }
            }
            this.transactionJournal.logCommit(xid);
        } catch (Exception e) {
            throw new ResourceManagerException(e);
        }
    }

    @Override
    public void doRollback() throws ResourceManagerException {
        Collection<XaQueueTxJournalEntry> logEntries = this.transactionJournal.getLogEntriesForTx(xid);
        for (XaQueueTxJournalEntry entry : logEntries) {
            if (entry.isRemove()) {
                try {
                    queueProvider.getQueue(entry.getQueueName()).putNow(entry.getValue());
                } catch (InterruptedException e) {
                    throw new ResourceManagerException(e);
                }
            }
        }
        this.transactionJournal.logRollback(xid);
    }

    @Override
    public void doPrepare() throws ResourceManagerException {
        this.transactionJournal.logPrepare(xid);
    }

}