Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 330   Methods: 25
NCLOC: 240   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ClusteredCacheLoader.java 50% 67.5% 56% 60.9%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.loader;
 8   
 9    import net.jcip.annotations.ThreadSafe;
 10    import org.apache.commons.logging.Log;
 11    import org.apache.commons.logging.LogFactory;
 12    import org.jboss.cache.Fqn;
 13    import org.jboss.cache.Modification;
 14    import org.jboss.cache.NodeSPI;
 15    import org.jboss.cache.RegionManager;
 16    import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
 17    import org.jboss.cache.lock.StripedLock;
 18    import org.jboss.cache.marshall.MethodCall;
 19    import org.jboss.cache.marshall.MethodCallFactory;
 20    import org.jboss.cache.marshall.MethodDeclarations;
 21    import org.jgroups.Address;
 22    import org.jgroups.blocks.GroupRequest;
 23   
 24    import java.io.ObjectInputStream;
 25    import java.io.ObjectOutputStream;
 26    import java.util.Collections;
 27    import java.util.Iterator;
 28    import java.util.List;
 29    import java.util.Map;
 30    import java.util.Set;
 31   
 32    /**
 33    * A cache loader that consults other members in the cluster for values. Does
 34    * not propagate update methods since replication should take care of this. A
 35    * <code>timeout</code> property is required, a <code>long</code> that
 36    * specifies in milliseconds how long to wait for results before returning a
 37    * null.
 38    *
 39    * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 40    */
 41    @ThreadSafe
 42    public class ClusteredCacheLoader extends AbstractCacheLoader
 43    {
 44    private static Log log = LogFactory.getLog(ClusteredCacheLoader.class);
 45    private StripedLock lock = new StripedLock();
 46    private ClusteredCacheLoaderConfig config;
 47   
 48    /**
 49    * Sets the configuration.
 50    * A property <code>timeout</code> is used as the timeout value.
 51    */
 52  24 public void setConfig(IndividualCacheLoaderConfig base)
 53    {
 54  24 if (base instanceof ClusteredCacheLoaderConfig)
 55    {
 56  0 this.config = (ClusteredCacheLoaderConfig) base;
 57    }
 58    else
 59    {
 60  24 config = new ClusteredCacheLoaderConfig(base);
 61    }
 62    }
 63   
 64  24 public IndividualCacheLoaderConfig getConfig()
 65    {
 66  24 return config;
 67    }
 68   
 69  80010 public Set getChildrenNames(Fqn fqn) throws Exception
 70    {
 71  0 if (!cache.getInvocationContext().isOriginLocal()) return Collections.emptySet();
 72  80010 lock.acquireLock(fqn, true);
 73  80010 try
 74    {
 75  80010 MethodCall call = MethodCallFactory.create(MethodDeclarations.getChildrenNamesMethodLocal, fqn);
 76  80010 Object resp = callRemote(call);
 77  80010 return (Set) resp;
 78    }
 79    finally
 80    {
 81  80010 lock.releaseLock(fqn);
 82    }
 83    }
 84   
 85  120054 private Object callRemote(MethodCall call) throws Exception
 86    {
 87  0 if (log.isTraceEnabled()) log.trace("cache=" + cache.getLocalAddress() + "; calling with " + call);
 88  120054 List<Address> mbrs = cache.getMembers();
 89  120054 MethodCall clusteredGet = MethodCallFactory.create(MethodDeclarations.clusteredGetMethod, call, false);
 90  120054 List resps = cache.getRPCManager().callRemoteMethods(mbrs, clusteredGet, GroupRequest.GET_FIRST, true, config.getTimeout());
 91  120054 if (resps == null)
 92    {
 93  0 if (log.isInfoEnabled()) log.info("No replies to call " + call + ". Perhaps we're alone in the cluster?");
 94  0 return null;
 95    }
 96    else
 97    {
 98    // test for and remove exceptions
 99  120054 Iterator i = resps.iterator();
 100  120053 Object result = null;
 101  120054 while (i.hasNext())
 102    {
 103  120054 Object o = i.next();
 104  120054 if (o instanceof Exception)
 105    {
 106  14 if (log.isDebugEnabled())
 107  0 log.debug("Found remote exception among responses - removing from responses list", (Exception) o);
 108    }
 109  120040 else if (o != null)
 110    {
 111    // keep looping till we find a FOUND answer.
 112  120040 List<Boolean> clusteredGetResp = (List<Boolean>) o;
 113    // found?
 114  120040 if (clusteredGetResp.get(0))
 115    {
 116  120032 result = clusteredGetResp.get(1);
 117  120032 break;
 118    }
 119    }
 120  0 else if (!cache.getConfiguration().isUseRegionBasedMarshalling())
 121    {
 122  0 throw new IllegalStateException("Received unexpected null response to " + clusteredGet);
 123    }
 124    // else region was inactive on peer;
 125    // keep looping to see if anyone else responded
 126    }
 127   
 128  0 if (log.isTraceEnabled()) log.trace("got responses " + resps);
 129  120054 return result;
 130    }
 131    }
 132   
 133  40034 public Map get(Fqn name) throws Exception
 134    {
 135  40034 return get0(name);
 136    }
 137   
 138  40034 protected Map get0(Fqn name) throws Exception
 139    {
 140    // DON'T make a remote call if this is a remote call in the first place - leads to deadlocks - JBCACHE-1103
 141  0 if (!cache.getInvocationContext().isOriginLocal()) return Collections.emptyMap();
 142  40034 lock.acquireLock(name, true);
 143  40034 try
 144    {
 145  40034 MethodCall call = MethodCallFactory.create(MethodDeclarations.getDataMapMethodLocal, name);
 146  40034 Object resp = callRemote(call);
 147  40034 return (Map) resp;
 148    }
 149    finally
 150    {
 151  40034 lock.releaseLock(name);
 152    }
 153    }
 154   
 155  10 public boolean exists(Fqn name) throws Exception
 156    {
 157    // DON'T make a remote call if this is a remote call in the first place - leads to deadlocks - JBCACHE-1103
 158  0 if (!cache.getInvocationContext().isOriginLocal()) return false;
 159   
 160  10 lock.acquireLock(name, false);
 161  10 try
 162    {
 163  10 MethodCall call = MethodCallFactory.create(MethodDeclarations.existsMethod, name);
 164  10 Object resp = callRemote(call);
 165   
 166  10 return resp != null && (Boolean) resp;
 167    }
 168    finally
 169    {
 170  10 lock.releaseLock(name);
 171    }
 172    }
 173   
 174  80152 public Object put(Fqn name, Object key, Object value) throws Exception
 175    {
 176  80152 if (cache.getInvocationContext().isOriginLocal())
 177    {
 178  40076 lock.acquireLock(name, true);
 179  40076 try
 180    {
 181  40076 NodeSPI n = cache.peek(name, false);
 182  40076 if (n == null)
 183    {
 184  0 MethodCall call = MethodCallFactory.create(MethodDeclarations.getKeyValueMethodLocal, name, key, true);
 185  0 return callRemote(call);
 186    }
 187    else
 188    {
 189    // dont bother with a remote call
 190  40076 return n.getDirect(key);
 191    }
 192    }
 193    finally
 194    {
 195  40076 lock.releaseLock(name);
 196    }
 197    }
 198    else
 199    {
 200  40076 log.trace("Call originated remotely. Not bothering to try and do a clustered get() for this put(). Returning null.");
 201  40076 return null;
 202    }
 203    }
 204   
 205    /**
 206    * Does nothing; replication handles put.
 207    */
 208  0 public void put(Fqn name, Map attributes) throws Exception
 209    {
 210    }
 211   
 212    /**
 213    * Does nothing; replication handles put.
 214    */
 215  0 public void put(List<Modification> modifications) throws Exception
 216    {
 217    }
 218   
 219    /**
 220    * Fetches the remove value, does not remove. Replication handles
 221    * removal.
 222    */
 223  0 public Object remove(Fqn name, Object key) throws Exception
 224    {
 225  0 if (cache.getInvocationContext().isOriginLocal())
 226    {
 227  0 lock.acquireLock(name, true);
 228  0 try
 229    {
 230  0 NodeSPI n = cache.peek(name, true);
 231  0 if (n == null)
 232    {
 233  0 MethodCall call = MethodCallFactory.create(MethodDeclarations.getKeyValueMethodLocal, name, key, true);
 234  0 return callRemote(call);
 235    }
 236    else
 237    {
 238    // dont bother with a remote call
 239  0 return n.getDirect(key);
 240    }
 241    }
 242    finally
 243    {
 244  0 lock.releaseLock(name);
 245    }
 246    }
 247    else
 248    {
 249  0 log.trace("Call originated remotely. Not bothering to try and do a clustered get() for this remove(). Returning null.");
 250  0 return null;
 251    }
 252    }
 253   
 254    /**
 255    * Does nothing; replication handles removal.
 256    */
 257  0 public void remove(Fqn name) throws Exception
 258    {
 259    // do nothing
 260    }
 261   
 262    /**
 263    * Does nothing; replication handles removal.
 264    */
 265  0 public void removeData(Fqn name) throws Exception
 266    {
 267    }
 268   
 269    /**
 270    * Does nothing.
 271    */
 272  0 public void prepare(Object tx, List modifications, boolean one_phase) throws Exception
 273    {
 274    }
 275   
 276    /**
 277    * Does nothing.
 278    */
 279  0 public void commit(Object tx) throws Exception
 280    {
 281    }
 282   
 283    /**
 284    * Does nothing.
 285    */
 286  0 public void rollback(Object tx)
 287    {
 288    }
 289   
 290  0 public void loadEntireState(ObjectOutputStream os) throws Exception
 291    {
 292    //intentional no-op
 293    }
 294   
 295  0 public void loadState(Fqn subtree, ObjectOutputStream os) throws Exception
 296    {
 297    // intentional no-op
 298    }
 299   
 300  12 public void storeEntireState(ObjectInputStream is) throws Exception
 301    {
 302    // intentional no-op
 303    }
 304   
 305  0 public void storeState(Fqn subtree, ObjectInputStream is) throws Exception
 306    {
 307    // intentional no-op
 308    }
 309   
 310  12 public void setRegionManager(RegionManager manager)
 311    {
 312    }
 313   
 314  24 public void create() throws Exception
 315    {
 316    }
 317   
 318  24 public void start() throws Exception
 319    {
 320    }
 321   
 322  24 public void stop()
 323    {
 324    }
 325   
 326  24 public void destroy()
 327    {
 328    }
 329   
 330    }