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