Package org.mule.util.queue

Source Code of org.mule.util.queue.TransactionalQueueManager

/*
* $Id: TransactionalQueueManager.java 22180 2011-06-15 12:48:29Z dirk.olmes $
* --------------------------------------------------------------------------------------
* 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.api.MuleContext;
import org.mule.api.context.MuleContextAware;
import org.mule.api.store.ListableObjectStore;
import org.mule.api.store.ObjectStore;
import org.mule.api.store.ObjectStoreException;
import org.mule.util.UUID;
import org.mule.util.xa.AbstractTransactionContext;
import org.mule.util.xa.AbstractXAResourceManager;
import org.mule.util.xa.ResourceManagerException;
import org.mule.util.xa.ResourceManagerSystemException;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.transaction.xa.XAResource;

/**
* The Transactional Queue Manager is responsible for creating and Managing
* transactional Queues. Queues can also be persistent by setting a persistence
* strategy on the manager. Default straties are provided for Memory, Jounaling,
* Cache and File.
*/
public class TransactionalQueueManager extends AbstractXAResourceManager implements QueueManager, MuleContextAware
{
    private Map<String, QueueInfo> queues = new HashMap<String, QueueInfo>();

    private QueueConfiguration defaultQueueConfiguration;
    private MuleContext muleContext;
    private Set<ListableObjectStore> stores = new HashSet<ListableObjectStore>();

    @Override
    public synchronized QueueSession getQueueSession()
    {
        return new TransactionalQueueSession(this, this);
    }

    @Override
    public synchronized void setDefaultQueueConfiguration(QueueConfiguration config)
    {
        this.defaultQueueConfiguration = config;
        addStore(config.objectStore);
    }

    @Override
    public synchronized void setQueueConfiguration(String queueName, QueueConfiguration config)
    {
        getQueue(queueName).setConfig(config);
        addStore(config.objectStore);
    }

    protected synchronized QueueInfo getQueue(String name)
    {
        QueueInfo q = queues.get(name);
        if (q == null)
        {
            q = new QueueInfo(name, defaultQueueConfiguration);
            queues.put(name, q);
        }
        return q;
    }

    @Override
    protected void doStart() throws ResourceManagerSystemException
    {
        findAllStores();
        for (ListableObjectStore store: stores)
        {
            try
            {
                store.open();
            }
            catch (ObjectStoreException e)
            {
                throw new ResourceManagerSystemException(e);
            }
        }
    }

    @Override
    protected boolean shutdown(int mode, long timeoutMSecs)
    {
        findAllStores();
        for (ListableObjectStore store: stores)
        {
            try
            {
                store.close();
            }
            catch (ObjectStoreException e)
            {
                // TODO BL-405 what to do with this exception? Looking at the call graph of this method it seems that it's never called from any production code (i.e. when shutting down MuleContext)
                logger.error("Error closing persistent store", e);
            }
        }

        // Clear queues on shutdown to avoid duplicate entries on warm restarts (MULE-3678)
        synchronized (this)
        {
            queues.clear();
        }
        return super.shutdown(mode, timeoutMSecs);
    }

    @Override
    protected void recover() throws ResourceManagerSystemException
    {
        findAllStores();
        for (ListableObjectStore store: stores)
        {
            try
            {
                List<Serializable> keys = store.allKeys();
                for (Serializable key : keys)
                {
                    QueueKey queueKey = (QueueKey) key;
                    getQueue(queueKey.queueName).putNow(queueKey.id);
                }
            }
            catch (Exception e)
            {
                throw new ResourceManagerSystemException(e);
            }
        }
    }

    @Override
    protected AbstractTransactionContext createTransactionContext(Object session)
    {
        return new QueueTransactionContext(this);
    }

    @Override
    protected void doBegin(AbstractTransactionContext context)
    {
        // Nothing special to do
    }

    @Override
    protected int doPrepare(AbstractTransactionContext context)
    {
        return XAResource.XA_OK;
    }

    @Override
    protected void doCommit(AbstractTransactionContext context) throws ResourceManagerException
    {
        QueueTransactionContext ctx = (QueueTransactionContext) context;
        try
        {
            if (ctx.added != null)
            {
                for (Map.Entry<QueueInfo, List<Serializable>> entry : ctx.added.entrySet())
                {
                    QueueInfo queue = entry.getKey();
                    List<Serializable> queueAdded = entry.getValue();
                    if (queueAdded != null && queueAdded.size() > 0)
                    {
                        for (Serializable object : queueAdded)
                        {
                            Serializable id = doStore(queue, object);
                            queue.putNow(id);
                        }
                    }
                }
            }
            if (ctx.removed != null)
            {
                for (Map.Entry<QueueInfo, List<Serializable>> entry : ctx.removed.entrySet())
                {
                    QueueInfo queue = entry.getKey();
                    List<Serializable> queueRemoved = entry.getValue();
                    if (queueRemoved != null && queueRemoved.size() > 0)
                    {
                        for (Serializable id : queueRemoved)
                        {
                            doRemove(queue, id);
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            throw new ResourceManagerException(e);
        }
        finally
        {
            ctx.added = null;
            ctx.removed = null;
        }
    }

    protected Serializable doStore(QueueInfo queue, Serializable object) throws ObjectStoreException
    {
        ObjectStore<Serializable> store = queue.getStore();

        String id = UUID.getUUID();
        Serializable key = new QueueKey(queue.getName(), id);
        store.store(key, object);
        return id;
    }

    protected void doRemove(QueueInfo queue, Serializable id) throws ObjectStoreException
    {
        ObjectStore<Serializable> store = queue.getStore();

        Serializable key = new QueueKey(queue.getName(), id);
        store.remove(key);
    }

    protected Serializable doLoad(QueueInfo queue, Serializable id) throws ObjectStoreException
    {
        ObjectStore<Serializable> store = queue.getStore();

        Serializable key = new QueueKey(queue.getName(), id);
        return store.retrieve(key);
    }

    @Override
    protected void doRollback(AbstractTransactionContext context) throws ResourceManagerException
    {
        QueueTransactionContext ctx = (QueueTransactionContext) context;
        if (ctx.removed != null)
        {
            for (Map.Entry<QueueInfo, List<Serializable>> entry : ctx.removed.entrySet())
            {
                QueueInfo queue = entry.getKey();
                List<Serializable> queueRemoved = entry.getValue();
                if (queueRemoved != null && queueRemoved.size() > 0)
                {
                    for (Serializable id : queueRemoved)
                    {
                        queue.putNow(id);
                    }
                }
            }
        }
        ctx.added = null;
        ctx.removed = null;
    }

    protected synchronized void findAllStores()
    {
        if (muleContext != null)
        {
            for (ListableObjectStore store: muleContext.getRegistry().lookupByType(ListableObjectStore.class).values())
            {
                addStore(store);
            }
        }
    }

    @Override
    public void setMuleContext(MuleContext context)
    {
        this.muleContext = context;
    }

    public MuleContext getMuleContext()
    {
        return muleContext;
    }

    public void setPersistentObjectStore(Object o)
    {
        System.out.println(o.getClass());  
    }

    private void addStore(ListableObjectStore<?> store)
    {
        stores.add(store);
    }
}
TOP

Related Classes of org.mule.util.queue.TransactionalQueueManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.