Coverage report

  %line %branch
org.apache.jcs.auxiliary.remote.RemoteCacheNoWaitFacade
0% 
0% 

 1  
 package org.apache.jcs.auxiliary.remote;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.IOException;
 23  
 import java.io.Serializable;
 24  
 import java.util.ArrayList;
 25  
 import java.util.Arrays;
 26  
 import java.util.HashSet;
 27  
 import java.util.List;
 28  
 import java.util.Set;
 29  
 
 30  
 import org.apache.commons.logging.Log;
 31  
 import org.apache.commons.logging.LogFactory;
 32  
 import org.apache.jcs.auxiliary.AuxiliaryCache;
 33  
 import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
 34  
 import org.apache.jcs.engine.CacheConstants;
 35  
 import org.apache.jcs.engine.behavior.ICacheElement;
 36  
 import org.apache.jcs.engine.behavior.ICacheType;
 37  
 import org.apache.jcs.engine.behavior.ICompositeCacheManager;
 38  
 import org.apache.jcs.engine.stats.StatElement;
 39  
 import org.apache.jcs.engine.stats.Stats;
 40  
 import org.apache.jcs.engine.stats.behavior.IStatElement;
 41  
 import org.apache.jcs.engine.stats.behavior.IStats;
 42  
 
 43  
 /**
 44  
  * Used to provide access to multiple services under nowait protection. Factory should construct
 45  
  * NoWaitFacade to give to the composite cache out of caches it constructs from the varies manager
 46  
  * to lateral services.
 47  
  * <p>
 48  
  * Typically, we only connect to one remote server per facade.  We use a list of one RemoteCacheNoWait.
 49  
  */
 50  
 public class RemoteCacheNoWaitFacade
 51  
     implements AuxiliaryCache
 52  
 {
 53  
     private static final long serialVersionUID = -4529970797620747110L;
 54  
 
 55  0
     private final static Log log = LogFactory.getLog( RemoteCacheNoWaitFacade.class );
 56  
 
 57  
     /** The connection to a remote server, or a zombie. */
 58  
     public RemoteCacheNoWait[] noWaits;
 59  
 
 60  
     private String cacheName;
 61  
 
 62  
     /** holds failover and cluster information */
 63  
     protected RemoteCacheAttributes remoteCacheAttributes;
 64  
 
 65  
     private ICompositeCacheManager cacheMgr;
 66  
 
 67  
     /**
 68  
      * Gets the remoteCacheAttributes attribute of the RemoteCacheNoWaitFacade object
 69  
      * <p>
 70  
      * @return The remoteCacheAttributes value
 71  
      */
 72  
     public RemoteCacheAttributes getRemoteCacheAttributes()
 73  
     {
 74  0
         return remoteCacheAttributes;
 75  
     }
 76  
 
 77  
     /**
 78  
      * Sets the remoteCacheAttributes attribute of the RemoteCacheNoWaitFacade object.
 79  
      * <p>
 80  
      * @param rca The new remoteCacheAttributes value
 81  
      */
 82  
     public void setRemoteCacheAttributes( RemoteCacheAttributes rca )
 83  
     {
 84  0
         this.remoteCacheAttributes = rca;
 85  0
     }
 86  
 
 87  
     /**
 88  
      * Constructs with the given remote cache, and fires events to any listeners.
 89  
      * <p>
 90  
      * @param noWaits
 91  
      * @param rca
 92  
      * @param cacheMgr
 93  
      */
 94  
     public RemoteCacheNoWaitFacade( RemoteCacheNoWait[] noWaits, RemoteCacheAttributes rca,
 95  
                                    ICompositeCacheManager cacheMgr )
 96  0
     {
 97  0
         if ( log.isDebugEnabled() )
 98  
         {
 99  0
             log.debug( "CONSTRUCTING NO WAIT FACADE" );
 100  
         }
 101  0
         this.noWaits = noWaits;
 102  0
         this.remoteCacheAttributes = rca;
 103  0
         this.cacheName = rca.getCacheName();
 104  0
         this.cacheMgr = cacheMgr;
 105  0
     }
 106  
 
 107  
     /**
 108  
      * Put an element in the cache.
 109  
      * <p>
 110  
      * @param ce
 111  
      * @throws IOException
 112  
      */
 113  
     public void update( ICacheElement ce )
 114  
         throws IOException
 115  
     {
 116  0
         if ( log.isDebugEnabled() )
 117  
         {
 118  0
             log.debug( "updating through cache facade, noWaits.length = " + noWaits.length );
 119  
         }
 120  0
         int i = 0;
 121  
         try
 122  
         {
 123  0
             for ( ; i < noWaits.length; i++ )
 124  
             {
 125  0
                 noWaits[i].update( ce );
 126  
                 // an initial move into a zombie will lock this to primary
 127  
                 // recovery. will not discover other servers until primary
 128  
                 // reconnect
 129  
                 // and subsequent error
 130  
             }
 131  
         }
 132  0
         catch ( Exception ex )
 133  
         {
 134  0
             log.error( ex );
 135  
             // can handle failover here? Is it safe to try the others?
 136  
             // check to see it the noWait is now a zombie
 137  
             // if it is a zombie, then move to the next in the failover list
 138  
             // will need to keep them in order or a count
 139  0
             failover( i );
 140  
             // should start a failover thread
 141  
             // should probably only failover if there is only one in the noWait
 142  
             // list
 143  
             // should start a background thread to set the original as the
 144  
             // primary
 145  
             // if we are in failover state
 146  0
         }
 147  0
     }
 148  
 
 149  
     /**
 150  
      * Synchronously reads from the remote cache.
 151  
      * <p>
 152  
      * @param key
 153  
      * @return Either an ICacheElement or null if it is not found.
 154  
      */
 155  
     public ICacheElement get( Serializable key )
 156  
     {
 157  0
         for ( int i = 0; i < noWaits.length; i++ )
 158  
         {
 159  
             try
 160  
             {
 161  0
                 Object obj = noWaits[i].get( key );
 162  0
                 if ( obj != null )
 163  
                 {
 164  0
                     return (ICacheElement) obj;
 165  
                 }
 166  
             }
 167  0
             catch ( Exception ex )
 168  
             {
 169  0
                 log.debug( "Failed to get." );
 170  0
             }
 171  0
             return null;
 172  
         }
 173  0
         return null;
 174  
     }
 175  
 
 176  
     /**
 177  
      * Gets the set of keys of objects currently in the group.
 178  
      * <p>
 179  
      * @param group
 180  
      * @return
 181  
      * @throws IOException
 182  
      */
 183  
     public Set getGroupKeys( String group )
 184  
         throws IOException
 185  
     {
 186  0
         HashSet allKeys = new HashSet();
 187  0
         for ( int i = 0; i < noWaits.length; i++ )
 188  
         {
 189  0
             AuxiliaryCache aux = noWaits[i];
 190  0
             if ( aux != null )
 191  
             {
 192  0
                 allKeys.addAll( aux.getGroupKeys( group ) );
 193  
             }
 194  
         }
 195  0
         return allKeys;
 196  
     }
 197  
 
 198  
     /**
 199  
      * Adds a remove request to the remote cache.
 200  
      * <p>
 201  
      * @param key
 202  
      * @return wether or not it was removed, right now it return false.
 203  
      */
 204  
     public boolean remove( Serializable key )
 205  
     {
 206  
         try
 207  
         {
 208  0
             for ( int i = 0; i < noWaits.length; i++ )
 209  
             {
 210  0
                 noWaits[i].remove( key );
 211  
             }
 212  
         }
 213  0
         catch ( Exception ex )
 214  
         {
 215  0
             log.error( ex );
 216  0
         }
 217  0
         return false;
 218  
     }
 219  
 
 220  
     /**
 221  
      * Adds a removeAll request to the lateral cache.
 222  
      */
 223  
     public void removeAll()
 224  
     {
 225  
         try
 226  
         {
 227  0
             for ( int i = 0; i < noWaits.length; i++ )
 228  
             {
 229  0
                 noWaits[i].removeAll();
 230  
             }
 231  
         }
 232  0
         catch ( Exception ex )
 233  
         {
 234  0
             log.error( ex );
 235  0
         }
 236  0
     }
 237  
 
 238  
     /** Adds a dispose request to the lateral cache. */
 239  
     public void dispose()
 240  
     {
 241  
         try
 242  
         {
 243  0
             for ( int i = 0; i < noWaits.length; i++ )
 244  
             {
 245  0
                 noWaits[i].dispose();
 246  
             }
 247  
         }
 248  0
         catch ( Exception ex )
 249  
         {
 250  0
             log.error( "Problem in dispose.", ex );
 251  0
         }
 252  0
     }
 253  
 
 254  
     /**
 255  
      * No lateral invocation.
 256  
      * @return The size value
 257  
      */
 258  
     public int getSize()
 259  
     {
 260  0
         return 0;
 261  
         // cache.getSize();
 262  
     }
 263  
 
 264  
     /**
 265  
      * Gets the cacheType attribute of the RemoteCacheNoWaitFacade object.
 266  
      * <p>
 267  
      * @return The cacheType value
 268  
      */
 269  
     public int getCacheType()
 270  
     {
 271  0
         return ICacheType.REMOTE_CACHE;
 272  
     }
 273  
 
 274  
     /**
 275  
      * Gets the cacheName attribute of the RemoteCacheNoWaitFacade object.
 276  
      * <p>
 277  
      * @return The cacheName value
 278  
      */
 279  
     public String getCacheName()
 280  
     {
 281  0
         return remoteCacheAttributes.getCacheName();
 282  
     }
 283  
 
 284  
     /**
 285  
      * Gets the status attribute of the RemoteCacheNoWaitFacade object
 286  
      * <p>
 287  
      * Return ALIVE if any are alive.
 288  
      * <p>
 289  
      * @return The status value
 290  
      */
 291  
     public int getStatus()
 292  
     {
 293  0
         for ( int i = 0; i < noWaits.length; i++ )
 294  
         {
 295  0
             if ( noWaits[i].getStatus() == CacheConstants.STATUS_ALIVE )
 296  
             {
 297  0
                 return CacheConstants.STATUS_ALIVE;
 298  
             }
 299  
         }
 300  0
         return 0;
 301  
     }
 302  
 
 303  
     /**
 304  
      * String form of some of the configuratin information for the remote cache.
 305  
      * <p>
 306  
      * @return Some info for logging.
 307  
      */
 308  
     public String toString()
 309  
     {
 310  0
         return "RemoteCacheNoWaitFacade: " + cacheName + ", rca = " + remoteCacheAttributes;
 311  
     }
 312  
 
 313  
     /**
 314  
      * Begin the failover process if this is a local cache. Clustered remote caches do not failover.
 315  
      * <p>
 316  
      * @param i The no wait in error.
 317  
      */
 318  
     protected void failover( int i )
 319  
     {
 320  0
         if ( log.isDebugEnabled() )
 321  
         {
 322  0
             log.info( "in failover for " + i );
 323  
         }
 324  
 
 325  0
         if ( remoteCacheAttributes.getRemoteType() == RemoteCacheAttributes.LOCAL )
 326  
         {
 327  0
             if ( noWaits[i].getStatus() == CacheConstants.STATUS_ERROR )
 328  
             {
 329  
                 // start failover, primary recovery process
 330  0
                 RemoteCacheFailoverRunner runner = new RemoteCacheFailoverRunner( this, cacheMgr );
 331  
                 // If the returned monitor is null, it means it's already
 332  
                 // started elsewhere.
 333  0
                 if ( runner != null )
 334  
                 {
 335  0
                     runner.notifyError();
 336  0
                     Thread t = new Thread( runner );
 337  0
                     t.setDaemon( true );
 338  0
                     t.start();
 339  
                 }
 340  0
             }
 341  
             else
 342  
             {
 343  0
                 if ( log.isInfoEnabled() )
 344  
                 {
 345  0
                     log.info( "The noWait is not in error" );
 346  
                 }
 347  
             }
 348  
         }
 349  0
     }
 350  
 
 351  
     /**
 352  
      * @return Returns the AuxiliaryCacheAttributes.
 353  
      */
 354  
     public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
 355  
     {
 356  0
         return this.remoteCacheAttributes;
 357  
     }
 358  
 
 359  
     /**
 360  
      * getStats
 361  
      * @return String
 362  
      */
 363  
     public String getStats()
 364  
     {
 365  0
         return getStatistics().toString();
 366  
     }
 367  
 
 368  
     /*
 369  
      * (non-Javadoc)
 370  
      * @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
 371  
      */
 372  
     public IStats getStatistics()
 373  
     {
 374  0
         IStats stats = new Stats();
 375  0
         stats.setTypeName( "Remote Cache No Wait Facade" );
 376  
 
 377  0
         ArrayList elems = new ArrayList();
 378  
 
 379  0
         IStatElement se = null;
 380  
 
 381  0
         if ( noWaits != null )
 382  
         {
 383  0
             se = new StatElement();
 384  0
             se.setName( "Number of No Waits" );
 385  0
             se.setData( "" + noWaits.length );
 386  0
             elems.add( se );
 387  
 
 388  0
             for ( int i = 0; i < noWaits.length; i++ )
 389  
             {
 390  
                 // get the stats from the super too
 391  
                 // get as array, convert to list, add list to our outer list
 392  0
                 IStats sStats = noWaits[i].getStatistics();
 393  0
                 IStatElement[] sSEs = sStats.getStatElements();
 394  0
                 List sL = Arrays.asList( sSEs );
 395  0
                 elems.addAll( sL );
 396  
             }
 397  
         }
 398  
 
 399  
         // get an array and put them in the Stats object
 400  0
         IStatElement[] ses = (IStatElement[]) elems.toArray( new StatElement[0] );
 401  0
         stats.setStatElements( ses );
 402  
 
 403  0
         return stats;
 404  
     }
 405  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.