Coverage Report - org.mule.util.queue.TransactionalQueueManager
 
Classes in this File Line Coverage Branch Coverage Complexity
TransactionalQueueManager
0%
0/110
0%
0/50
0
TransactionalQueueManager$QueueTransactionContext
0%
0/48
0%
0/28
0
 
 1  
 /*
 2  
  * $Id: TransactionalQueueManager.java 19191 2010-08-25 21:05:23Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.util.queue;
 12  
 
 13  
 import org.mule.api.MuleContext;
 14  
 import org.mule.api.context.MuleContextAware;
 15  
 import org.mule.util.queue.QueuePersistenceStrategy.Holder;
 16  
 import org.mule.util.xa.AbstractTransactionContext;
 17  
 import org.mule.util.xa.AbstractXAResourceManager;
 18  
 import org.mule.util.xa.ResourceManagerException;
 19  
 import org.mule.util.xa.ResourceManagerSystemException;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.util.ArrayList;
 23  
 import java.util.HashMap;
 24  
 import java.util.LinkedList;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 
 28  
 import javax.transaction.xa.XAResource;
 29  
 
 30  
 import org.apache.commons.logging.Log;
 31  
 import org.apache.commons.logging.LogFactory;
 32  
 
 33  
 /**
 34  
  * The Transactional Queue Manager is responsible for creating and Managing
 35  
  * transactional Queues. Queues can also be persistent by setting a persistence
 36  
  * strategy on the manager. Default straties are provided for Memory, Jounaling,
 37  
  * Cache and File.
 38  
  */
 39  0
 public class TransactionalQueueManager extends AbstractXAResourceManager implements QueueManager, MuleContextAware
 40  
 {
 41  
 
 42  0
     private static Log logger = LogFactory.getLog(TransactionalQueueManager.class);
 43  
 
 44  0
     private Map<String, QueueInfo> queues = new HashMap<String, QueueInfo>();
 45  
 
 46  0
     private QueuePersistenceStrategy memoryPersistenceStrategy = new MemoryPersistenceStrategy();
 47  
     private QueuePersistenceStrategy persistenceStrategy;
 48  
 
 49  0
     private QueueConfiguration defaultQueueConfiguration = new QueueConfiguration(false);
 50  
     private MuleContext muleContext;
 51  
 
 52  
     public void setMuleContext(MuleContext context)
 53  
     {
 54  0
         this.muleContext = context;
 55  0
     }
 56  
 
 57  
     public MuleContext getMuleContext()
 58  
     {
 59  0
         return muleContext;
 60  
     }
 61  
 
 62  
     public synchronized QueueSession getQueueSession()
 63  
     {
 64  0
         return new TransactionalQueueSession(this, this);
 65  
     }
 66  
 
 67  
     public synchronized void setDefaultQueueConfiguration(QueueConfiguration config)
 68  
     {
 69  0
         this.defaultQueueConfiguration = config;
 70  0
     }
 71  
 
 72  
     public synchronized void setQueueConfiguration(String queueName, QueueConfiguration config)
 73  
     {
 74  0
         getQueue(queueName).config = config;
 75  0
     }
 76  
 
 77  
     protected synchronized QueueInfo getQueue(String name)
 78  
     {
 79  0
         QueueInfo q = queues.get(name);
 80  0
         if (q == null)
 81  
         {
 82  0
             q = new QueueInfo();
 83  0
             q.name = name;
 84  0
             q.list = new LinkedList();
 85  0
             q.config = defaultQueueConfiguration;
 86  0
             queues.put(name, q);
 87  
         }
 88  0
         return q;
 89  
     }
 90  
 
 91  
     protected Log getLogger()
 92  
     {
 93  0
         return logger;
 94  
     }
 95  
 
 96  
     protected void doStart() throws ResourceManagerSystemException
 97  
     {
 98  0
         if (persistenceStrategy != null)
 99  
         {
 100  
             try
 101  
             {
 102  0
                 persistenceStrategy.open();
 103  
             }
 104  0
             catch (IOException e)
 105  
             {
 106  0
                 throw new ResourceManagerSystemException(e);
 107  0
             }
 108  
         }
 109  0
     }
 110  
 
 111  
     protected boolean shutdown(int mode, long timeoutMSecs)
 112  
     {
 113  
         try
 114  
         {
 115  0
             if (persistenceStrategy != null)
 116  
             {
 117  0
                 persistenceStrategy.close();
 118  
             }
 119  
         }
 120  0
         catch (IOException e)
 121  
         {
 122  
             // TODO MULE-863: What should we really do?
 123  0
             logger.error("Error closing persistent store", e);
 124  0
         }
 125  
         // Clear queues on shutdown to avoid duplicate entries on warm restarts (MULE-3678)
 126  0
         synchronized (this)
 127  
         {
 128  0
             queues.clear();
 129  0
         }
 130  0
         return super.shutdown(mode, timeoutMSecs);
 131  
     }
 132  
 
 133  
     protected void recover() throws ResourceManagerSystemException
 134  
     {
 135  0
         if (persistenceStrategy != null)
 136  
         {
 137  
             try
 138  
             {
 139  0
                 List msgs = persistenceStrategy.restore();
 140  0
                 for (Object msg : msgs)
 141  
                 {
 142  0
                     Holder h = (Holder) msg;
 143  0
                     getQueue(h.getQueue()).putNow(h.getId());
 144  0
                 }
 145  
             }
 146  0
             catch (Exception e)
 147  
             {
 148  0
                 throw new ResourceManagerSystemException(e);
 149  0
             }
 150  
         }
 151  0
     }
 152  
 
 153  
     protected AbstractTransactionContext createTransactionContext(Object session)
 154  
     {
 155  0
         return new QueueTransactionContext();
 156  
     }
 157  
 
 158  
     protected void doBegin(AbstractTransactionContext context)
 159  
     {
 160  
         // Nothing special to do
 161  0
     }
 162  
 
 163  
     protected int doPrepare(AbstractTransactionContext context)
 164  
     {
 165  0
         return XAResource.XA_OK;
 166  
     }
 167  
 
 168  
     protected void doCommit(AbstractTransactionContext context) throws ResourceManagerException
 169  
     {
 170  0
         QueueTransactionContext ctx = (QueueTransactionContext) context;
 171  
         try
 172  
         {
 173  0
             if (ctx.added != null)
 174  
             {
 175  0
                 for (Object o : ctx.added.entrySet())
 176  
                 {
 177  0
                     Map.Entry entry = (Map.Entry) o;
 178  0
                     QueueInfo queue = (QueueInfo) entry.getKey();
 179  0
                     List queueAdded = (List) entry.getValue();
 180  0
                     if (queueAdded != null && queueAdded.size() > 0)
 181  
                     {
 182  0
                         for (Object object : queueAdded)
 183  
                         {
 184  0
                             Object id = doStore(queue, object);
 185  0
                             queue.putNow(id);
 186  0
                         }
 187  
                     }
 188  0
                 }
 189  
             }
 190  0
             if (ctx.removed != null)
 191  
             {
 192  0
                 for (Object o : ctx.removed.entrySet())
 193  
                 {
 194  0
                     Map.Entry entry = (Map.Entry) o;
 195  0
                     QueueInfo queue = (QueueInfo) entry.getKey();
 196  0
                     List queueRemoved = (List) entry.getValue();
 197  0
                     if (queueRemoved != null && queueRemoved.size() > 0)
 198  
                     {
 199  0
                         for (Object id : queueRemoved)
 200  
                         {
 201  0
                             doRemove(queue, id);
 202  
                         }
 203  
                     }
 204  0
                 }
 205  
             }
 206  
         }
 207  0
         catch (Exception e)
 208  
         {
 209  
             // throw new ResourceManagerException("Could not commit
 210  
             // transaction", e);
 211  
             // TODO: add an i18n Message
 212  0
             throw new ResourceManagerException(e);
 213  
         }
 214  
         finally
 215  
         {
 216  0
             ctx.added = null;
 217  0
             ctx.removed = null;
 218  0
         }
 219  0
     }
 220  
 
 221  
     protected Object doStore(QueueInfo queue, Object object) throws IOException
 222  
     {
 223  0
         QueuePersistenceStrategy ps = (queue.config.persistent)
 224  
                         ? persistenceStrategy : memoryPersistenceStrategy;
 225  0
         Object id = ps.store(queue.name, object);
 226  0
         return id;
 227  
     }
 228  
 
 229  
     protected void doRemove(QueueInfo queue, Object id) throws IOException
 230  
     {
 231  0
         QueuePersistenceStrategy ps = (queue.config.persistent)
 232  
                         ? persistenceStrategy : memoryPersistenceStrategy;
 233  0
         ps.remove(queue.name, id);
 234  0
     }
 235  
 
 236  
     protected Object doLoad(QueueInfo queue, Object id) throws IOException
 237  
     {
 238  0
         QueuePersistenceStrategy ps = (queue.config.persistent)
 239  
                         ? persistenceStrategy : memoryPersistenceStrategy;
 240  0
         Object obj = ps.load(queue.name, id);
 241  0
         return obj;
 242  
     }
 243  
 
 244  
     protected void doRollback(AbstractTransactionContext context) throws ResourceManagerException
 245  
     {
 246  0
         QueueTransactionContext ctx = (QueueTransactionContext) context;
 247  0
         if (ctx.removed != null)
 248  
         {
 249  0
             for (Object o : ctx.removed.entrySet())
 250  
             {
 251  0
                 Map.Entry entry = (Map.Entry) o;
 252  0
                 QueueInfo queue = (QueueInfo) entry.getKey();
 253  0
                 List queueRemoved = (List) entry.getValue();
 254  0
                 if (queueRemoved != null && queueRemoved.size() > 0)
 255  
                 {
 256  0
                     for (Object id : queueRemoved)
 257  
                     {
 258  0
                         queue.putNow(id);
 259  
                     }
 260  
                 }
 261  0
             }
 262  
         }
 263  0
         ctx.added = null;
 264  0
         ctx.removed = null;
 265  0
     }
 266  
 
 267  0
     protected class QueueTransactionContext extends AbstractTransactionContext
 268  
     {
 269  
         protected Map added;
 270  
         protected Map removed;
 271  
 
 272  
         @SuppressWarnings("unchecked")
 273  
         public boolean offer(QueueInfo queue, Object item, long timeout) throws InterruptedException
 274  
         {
 275  0
             readOnly = false;
 276  0
             if (added == null)
 277  
             {
 278  0
                 added = new HashMap();
 279  
             }
 280  0
             List queueAdded = (List) added.get(queue);
 281  0
             if (queueAdded == null)
 282  
             {
 283  0
                 queueAdded = new ArrayList();
 284  0
                 added.put(queue, queueAdded);
 285  
             }
 286  
             // wait for enough room
 287  0
             if (queue.offer(null, queueAdded.size(), timeout))
 288  
             {
 289  0
                 queueAdded.add(item);
 290  0
                 return true;
 291  
             }
 292  
             else
 293  
             {
 294  0
                 return false;
 295  
             }
 296  
         }
 297  
 
 298  
         @SuppressWarnings("unchecked")
 299  
         public Object poll(QueueInfo queue, long timeout) throws IOException, InterruptedException
 300  
         {
 301  0
             readOnly = false;
 302  0
             if (added != null)
 303  
             {
 304  0
                 List queueAdded = (List)added.get(queue);
 305  0
                 if (queueAdded != null)
 306  
                 {
 307  0
                     return queueAdded.remove(queueAdded.size() - 1);
 308  
                 }
 309  
             }
 310  
             Object o;
 311  
             try
 312  
             {
 313  0
                 o = queue.poll(timeout);
 314  
             }
 315  0
             catch (InterruptedException e)
 316  
             {
 317  0
                 if (muleContext.isStopping())
 318  
                 {
 319  0
                     throw e;
 320  
                 }
 321  
                 // if disposing, ignore
 322  0
                 return null;
 323  0
             }
 324  0
             if (o != null)
 325  
             {
 326  0
                 if (removed == null)
 327  
                 {
 328  0
                     removed = new HashMap();
 329  
                 }
 330  0
                 List queueRemoved = (List) removed.get(queue);
 331  0
                 if (queueRemoved == null)
 332  
                 {
 333  0
                     queueRemoved = new ArrayList();
 334  0
                     removed.put(queue, queueRemoved);
 335  
                 }
 336  0
                 queueRemoved.add(o);
 337  0
                 o = doLoad(queue, o);
 338  
             }
 339  0
             return o;
 340  
         }
 341  
 
 342  
         public Object peek(QueueInfo queue) throws IOException, InterruptedException
 343  
         {
 344  0
             readOnly = false;
 345  0
             if (added != null)
 346  
             {
 347  0
                 List queueAdded = (List) added.get(queue);
 348  0
                 if (queueAdded != null)
 349  
                 {
 350  0
                     return queueAdded.get(queueAdded.size() - 1);
 351  
                 }
 352  
             }
 353  0
             Object o = queue.peek();
 354  0
             if (o != null)
 355  
             {
 356  0
                 o = doLoad(queue, o);
 357  
             }
 358  0
             return o;
 359  
         }
 360  
 
 361  
         public int size(QueueInfo queue)
 362  
         {
 363  0
             int sz = queue.list.size();
 364  0
             if (added != null)
 365  
             {
 366  0
                 List queueAdded = (List) added.get(queue);
 367  0
                 if (queueAdded != null)
 368  
                 {
 369  0
                     sz += queueAdded.size();
 370  
                 }
 371  
             }
 372  0
             return sz;
 373  
         }
 374  
 
 375  
     }
 376  
 
 377  
     public QueuePersistenceStrategy getPersistenceStrategy()
 378  
     {
 379  0
         return persistenceStrategy;
 380  
     }
 381  
 
 382  
     public void setPersistenceStrategy(QueuePersistenceStrategy persistenceStrategy)
 383  
     {
 384  0
         if (operationMode != OPERATION_MODE_STOPPED)
 385  
         {
 386  0
             throw new IllegalStateException();
 387  
         }
 388  0
         this.persistenceStrategy = persistenceStrategy;
 389  0
     }
 390  
 
 391  
     public QueuePersistenceStrategy getMemoryPersistenceStrategy()
 392  
     {
 393  0
         return memoryPersistenceStrategy;
 394  
     }
 395  
 
 396  
     public void setMemoryPersistenceStrategy(QueuePersistenceStrategy memoryPersistenceStrategy)
 397  
     {
 398  0
         if (operationMode != OPERATION_MODE_STOPPED)
 399  
         {
 400  0
             throw new IllegalStateException();
 401  
         }
 402  0
         this.memoryPersistenceStrategy = memoryPersistenceStrategy;
 403  0
     }
 404  
 
 405  
 }