/* * 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.runtime.core.util.journal.queue; import static org.mule.runtime.api.util.Preconditions.checkArgument; import org.mule.runtime.core.util.journal.JournalEntry; import org.mule.runtime.core.util.journal.JournalEntrySerializer; import org.mule.runtime.core.util.journal.TransactionCompletePredicate; import org.mule.runtime.core.util.journal.TransactionJournal; import org.mule.runtime.core.util.queue.QueueStore; import com.google.common.collect.Multimap; import java.io.Serializable; import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Base implementation for a queue transaction journal. * * @param <T> type of transaction identifier * @param <K> type of the actual journal entry which must extend {@link org.mule.runtime.core.util.journal.JournalEntry} */ public abstract class AbstractQueueTransactionJournal<T, K extends JournalEntry<T>> { protected transient Logger logger = LoggerFactory.getLogger(getClass()); private TransactionJournal<T, K> logFile; public AbstractQueueTransactionJournal(String logFilesDirectory, JournalEntrySerializer journalEntrySerializer, Integer maximumFileSizeInMegabytes) { checkArgument(maximumFileSizeInMegabytes == null || maximumFileSizeInMegabytes > 0, "Maximum tx log file size needs to be greater than zero"); this.logFile = new TransactionJournal(logFilesDirectory, new TransactionCompletePredicate() { @Override public boolean isTransactionComplete(JournalEntry journalEntry) { AbstractQueueTxJournalEntry abstractQueueTxJournalEntry = (AbstractQueueTxJournalEntry) journalEntry; return abstractQueueTxJournalEntry.isCommit() || abstractQueueTxJournalEntry.isRollback(); } }, journalEntrySerializer, maximumFileSizeInMegabytes); } public void logAdd(T txId, QueueStore queue, Serializable value) { if (logger.isDebugEnabled()) { logger.debug("Logging queue add operation for tx " + txId); } logFile.logUpdateOperation(createUpdateJournalEntry(txId, AbstractQueueTxJournalEntry.Operation.ADD.getByteRepresentation(), queue.getName(), value)); } public void logAddFirst(T txId, QueueStore queue, Serializable item) { if (logger.isDebugEnabled()) { logger.debug("Logging queue add first operation for tx " + txId); } logFile.logUpdateOperation(createUpdateJournalEntry(txId, AbstractQueueTxJournalEntry.Operation.ADD_FIRST.getByteRepresentation(), queue.getName(), item)); } public void logRemove(T txId, QueueStore queue, Serializable value) { if (logger.isDebugEnabled()) { logger.debug("Logging queue remove operation for tx " + txId); } logFile .logUpdateOperation(createUpdateJournalEntry(txId, AbstractQueueTxJournalEntry.Operation.REMOVE.getByteRepresentation(), queue.getName(), value)); } public void logCommit(T txId) { if (logger.isDebugEnabled()) { logger.debug("Logging queue commit operation for tx " + txId); } logFile.logCheckpointOperation(createCheckpointJournalEntry(txId, AbstractQueueTxJournalEntry.Operation.COMMIT .getByteRepresentation())); } /** * Creates a {@link org.mule.runtime.core.util.journal.JournalEntry} for an update operation in the queue. * * @param txId transaction identifier * @param operation operation done over the queue * @param queueName queueName of the queue in which the operation has been done * @param serialize value of the operation * @return a new {@link org.mule.runtime.core.util.journal.JournalEntry} */ protected abstract K createUpdateJournalEntry(T txId, byte operation, String queueName, Serializable serialize); /** * Creates a checkpoint {@link org.mule.runtime.core.util.journal.JournalEntry}. * * @param txId transaction identifier * @param operation checkpoint operation * @return a new {@link org.mule.runtime.core.util.journal.JournalEntry} */ protected abstract K createCheckpointJournalEntry(T txId, byte operation); public void logRollback(T txId) { if (logger.isDebugEnabled()) { logger.debug("Logging queue rollback operation for tx " + txId); } logFile.logCheckpointOperation(createCheckpointJournalEntry(txId, AbstractQueueTxJournalEntry.Operation.ROLLBACK .getByteRepresentation())); } public synchronized void close() { logFile.close(); } public synchronized void clear() { logFile.clear(); } public Multimap<T, K> getAllLogEntries() { return logFile.getAllLogEntries(); } public Collection<K> getLogEntriesForTx(T txId) { return logFile.getLogEntriesForTx(txId); } protected TransactionJournal<T, K> getJournal() { return logFile; } }