/* * 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.queue.objectstore; import org.mule.runtime.api.store.ObjectStoreException; import org.mule.runtime.core.util.queue.objectstore.xa.AbstractTransactionContext; import org.mule.runtime.core.util.xa.ResourceManagerException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; /** * @deprecated this class will be removed in Mule 4.0 in favor of the new queue implementation */ @Deprecated public class QueueTransactionContext extends AbstractTransactionContext { private final TransactionalQueueManager transactionalQueueManager; private Map<QueueInfo, List<Serializable>> added; private Map<QueueInfo, List<Serializable>> removed; public QueueTransactionContext(TransactionalQueueManager transactionalQueueManager) { super(); this.transactionalQueueManager = transactionalQueueManager; } public boolean offer(QueueInfo queue, Serializable item, long offerTimeout) throws InterruptedException, ObjectStoreException { readOnly = false; if (queue.canTakeFromStore()) { queue.writeToObjectStore(item); return true; } initializeAdded(); List<Serializable> queueAdded = lookupAddedQueue(queue); // wait for enough room if (queue.offer(null, queueAdded.size(), offerTimeout)) { queueAdded.add(item); return true; } else { return false; } } public void untake(QueueInfo queue, Serializable item) throws InterruptedException, ObjectStoreException { readOnly = false; if (queue.canTakeFromStore()) { queue.writeToObjectStore(item); } initializeAdded(); List<Serializable> queueAdded = lookupAddedQueue(queue); queueAdded.add(item); } public void clear(QueueInfo queue) throws InterruptedException { this.readOnly = false; if (queue.canTakeFromStore()) { queue.clear(); } this.initializeRemoved(); List<Serializable> queueRemoved = this.lookupRemovedQueue(queue); for (Serializable discardedItem = queue.poll(timeout); discardedItem != null; discardedItem = queue.poll(timeout)) { queueRemoved.add(discardedItem); } if (this.added != null) { List<Serializable> queueAdded = this.lookupAddedQueue(queue); if (!CollectionUtils.isEmpty(queueAdded)) { queueRemoved.addAll(queueAdded); queueAdded.clear(); } } } public Serializable poll(QueueInfo queue, long pollTimeout) throws InterruptedException, ObjectStoreException { readOnly = false; if (added != null) { List<Serializable> queueAdded = added.get(queue); if (queueAdded != null && queueAdded.size() > 0) { return queueAdded.remove(queueAdded.size() - 1); } } if (queue.canTakeFromStore()) { // TODO: verify that the queue is transactional too return queue.takeNextItemFromStore(timeout); } Serializable key; Serializable value = null; try { key = queue.poll(pollTimeout); } catch (InterruptedException e) { if (!transactionalQueueManager.getMuleContext().isStopping()) { throw e; } // if disposing, ignore return null; } if (key != null) { if (removed == null) { removed = new HashMap<QueueInfo, List<Serializable>>(); } List<Serializable> queueRemoved = removed.get(queue); if (queueRemoved == null) { queueRemoved = new ArrayList<Serializable>(); removed.put(queue, queueRemoved); } value = transactionalQueueManager.doLoad(queue, key); if (value != null) { queueRemoved.add(key); } } return value; } public Serializable peek(QueueInfo queue) throws InterruptedException, ObjectStoreException { readOnly = false; if (added != null) { List<Serializable> queueAdded = added.get(queue); if (queueAdded != null) { return queueAdded.get(queueAdded.size() - 1); } } Serializable o = queue.peek(); if (o != null) { o = transactionalQueueManager.doLoad(queue, o); } return o; } public int size(QueueInfo queue) { int sz = queue.getSize(); if (added != null) { List<Serializable> queueAdded = added.get(queue); if (queueAdded != null) { sz += queueAdded.size(); } } return sz; } @Override public void doCommit() throws ResourceManagerException { try { if (added != null) { for (Map.Entry<QueueInfo, List<Serializable>> entry : added.entrySet()) { QueueInfo queue = entry.getKey(); List<Serializable> queueAdded = entry.getValue(); if (queueAdded != null && queueAdded.size() > 0) { for (Serializable object : queueAdded) { Serializable id = transactionalQueueManager.doStore(queue, object); queue.putNow(id); } } } } if (removed != null) { for (Map.Entry<QueueInfo, List<Serializable>> entry : removed.entrySet()) { QueueInfo queue = entry.getKey(); List<Serializable> queueRemoved = entry.getValue(); if (queueRemoved != null && queueRemoved.size() > 0) { for (Serializable id : queueRemoved) { transactionalQueueManager.doRemove(queue, id); } } } } } catch (Exception e) { throw new ResourceManagerException(e); } finally { added = null; removed = null; } } @Override public void doRollback() throws ResourceManagerException { if (removed != null) { for (Map.Entry<QueueInfo, List<Serializable>> entry : removed.entrySet()) { QueueInfo queue = entry.getKey(); List<Serializable> queueRemoved = entry.getValue(); if (queueRemoved != null && queueRemoved.size() > 0) { for (Serializable id : queueRemoved) { queue.putNow(id); } } } } added = null; removed = null; } protected void initializeAdded() { if (added == null) { added = new HashMap<QueueInfo, List<Serializable>>(); } } protected void initializeRemoved() { if (this.removed == null) { this.removed = new HashMap<QueueInfo, List<Serializable>>(); } } protected List<Serializable> lookupAddedQueue(QueueInfo queue) { List<Serializable> queueAdded = added.get(queue); if (queueAdded == null) { queueAdded = new ArrayList<Serializable>(); added.put(queue, queueAdded); } return queueAdded; } protected List<Serializable> lookupRemovedQueue(QueueInfo queue) { List<Serializable> queueRemoved = this.removed.get(queue); if (queueRemoved == null) { queueRemoved = new ArrayList<Serializable>(); this.removed.put(queue, queueRemoved); } return queueRemoved; } }