Package org.infinispan.loaders.manager

Source Code of org.infinispan.loaders.manager.CacheLoaderManagerImpl

package org.infinispan.loaders.manager;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.infinispan.context.Flag.*;
import static org.infinispan.factories.KnownComponentNames.CACHE_MARSHALLER;
import static org.infinispan.loaders.decorators.AbstractDelegatingStore.undelegateCacheLoader;

import java.util.*;

import javax.transaction.Transaction;
import javax.transaction.TransactionManager;

import org.infinispan.AdvancedCache;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.CacheLoaderConfiguration;
import org.infinispan.configuration.cache.LoadersConfiguration;
import org.infinispan.configuration.cache.CacheStoreConfiguration;
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContextContainer;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.annotations.ComponentName;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.factories.annotations.Stop;
import org.infinispan.interceptors.CacheLoaderInterceptor;
import org.infinispan.interceptors.CacheStoreInterceptor;
import org.infinispan.loaders.CacheLoaderException;
import org.infinispan.loaders.decorators.AsyncStore;
import org.infinispan.loaders.decorators.ChainingCacheStore;
import org.infinispan.loaders.decorators.ReadOnlyStore;
import org.infinispan.loaders.decorators.SingletonStore;
import org.infinispan.loaders.spi.CacheLoader;
import org.infinispan.loaders.spi.CacheStore;
import org.infinispan.commons.CacheConfigurationException;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.configuration.ConfigurationFor;
import org.infinispan.commons.marshall.StreamingMarshaller;
import org.infinispan.commons.util.InfinispanCollections;
import org.infinispan.commons.util.Util;
import org.infinispan.util.TimeService;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;

public class CacheLoaderManagerImpl implements CacheLoaderManager {

   Configuration configuration;
   LoadersConfiguration clmConfig;
   AdvancedCache<Object, Object> cache;
   StreamingMarshaller m;
   CacheLoader loader;
   InvocationContextContainer icc;
   TransactionManager transactionManager;
   private TimeService timeService;
   private static final Log log = LogFactory.getLog(CacheLoaderManagerImpl.class);

   @Inject
   public void inject(AdvancedCache<Object, Object> cache,
                      @ComponentName(CACHE_MARSHALLER) StreamingMarshaller marshaller,
                      Configuration configuration, InvocationContextContainer icc, TransactionManager transactionManager,
                      TimeService timeService) {
      this.cache = cache;
      this.m = marshaller;
      this.configuration = configuration;
      this.icc = icc;
      this.transactionManager = transactionManager;
      this.timeService = timeService;
   }

   @Override
   public CacheLoader getCacheLoader() {
      return loader;
   }

   @Override
   public final CacheStore getCacheStore() {
      if (loader != null && loader instanceof CacheStore) {
         return (CacheStore) loader;
      } else {
         return null;
      }
   }

   @Override
   public void purge() {
      CacheStore cs = getCacheStore();
      if (cs != null) try {
         cs.clear();
      } catch (CacheLoaderException e) {
         throw new CacheException("Unable to purge cache store", e);
      }
   }

   private void purgeLoaders(boolean force) throws Exception {
      CacheStore cs = getCacheStore();
      if (cs != null) {
         if ((cs instanceof ChainingCacheStore) && !force) {
            ((ChainingCacheStore) loader).purgeIfNecessary();
         } else {
            CacheLoaderConfiguration first = clmConfig.cacheLoaders().get(0);
            if (force || (first != null && first instanceof CacheStoreConfiguration && ((CacheStoreConfiguration)first).purgeOnStartup())) {
               cs.clear();
            }
         }
      }
   }

   @Override
   public boolean isUsingPassivation() {
      return isEnabled() ? clmConfig.passivation() : false;
   }

   @Override
   public boolean isShared() {
      return isEnabled() ? clmConfig.shared() : false;
   }

   @Override
   public boolean isFetchPersistentState() {
      return isEnabled() ? clmConfig.fetchPersistentState() : false;
   }

   @Override
   @Start(priority = 10)
   public void start() {
      clmConfig = configuration.loaders();
      if (clmConfig != null) {
         try {
            loader = createCacheLoader();
            Transaction xaTx = null;
            if (transactionManager != null) {
               xaTx = transactionManager.suspend();
            }
            try {
               if (loader != null) loader.start();
            } finally {
               if (transactionManager != null && xaTx != null) {
                  transactionManager.resume(xaTx);
               }
            }
            purgeLoaders(false);
         } catch (Exception e) {
            throw new CacheException("Unable to start cache loaders", e);
         }
      }
   }

   @Override
   public boolean isEnabled() {
      return clmConfig != null;
   }

   @Override
   public void disableCacheStore(String loaderType) {
      if (isEnabled()) {
         boolean disableInterceptors = false;
         ComponentRegistry cr = cache.getComponentRegistry();
         CacheLoaderInterceptor cli = cr.getComponent(CacheLoaderInterceptor.class);
         CacheStoreInterceptor csi = cr.getComponent(CacheStoreInterceptor.class);

         if (loader instanceof ChainingCacheStore) {
            ChainingCacheStore ccs = (ChainingCacheStore) loader;
            ccs.removeCacheLoader(loaderType);
            if (ccs.getStores().isEmpty()) disableInterceptors = true;
         } else {
            String loaderClassName = undelegateCacheLoader(loader).getClass().getName();
            if (loaderClassName.equals(loaderType)) {
               try {
                  log.debugf("Stopping and removing cache loader %s", loaderType);
                  loader.stop();
               } catch (Exception e) {
                  log.infof("Problems shutting down cache loader %s", loaderType, e);
               }
               disableInterceptors = true;
            }
         }

         if (disableInterceptors) {
            cli.disableInterceptor();
            csi.disableInterceptor();
            cache.removeInterceptor(cli.getClass());
            cache.removeInterceptor(csi.getClass());
            clmConfig = null;
         }
      }
   }

   @Override
   public <T extends CacheLoader> List<T> getCacheLoaders(Class<T> loaderClass) {
      List<T> loaders;
      if (loader instanceof ChainingCacheStore) {
         ChainingCacheStore ccs = (ChainingCacheStore) loader;
         loaders = ccs.getCacheLoaders(loaderClass);
      } else {
         CacheLoader cl = undelegateCacheLoader(loader);
         if (loaderClass.isInstance(cl)) {
            loaders = Collections.singletonList((T) cl);
         } else {
            loaders = Collections.emptyList();
         }
      }
      return loaders;
   }

   /**
    * Performs a preload on the cache based on the cache loader preload configs used when configuring the cache.
    */
   @Override
   @Start(priority = 56)
   public void preload() {
      if (loader != null) {
         if (clmConfig.preload()) {
            long start = 0;
            boolean debugTiming = log.isDebugEnabled();
            if (debugTiming) {
               start = timeService.time();
               log.debugf("Preloading transient state from cache loader %s", loader);
            }
            Set<InternalCacheEntry> state;
            try {
               state = loadState();
            } catch (CacheLoaderException e) {
               throw new CacheException("Unable to preload!", e);
            }

            List<Flag> flags = new ArrayList<Flag>(Arrays.asList(
                  CACHE_MODE_LOCAL, SKIP_OWNERSHIP_CHECK, IGNORE_RETURN_VALUES, SKIP_CACHE_STORE, SKIP_LOCKING));

            if (clmConfig.shared() || !(loader instanceof ChainingCacheStore)) {
               flags.add(SKIP_CACHE_STORE);
               if (!localIndexingEnabled())
                  flags.add(SKIP_INDEXING);
            } else {
               flags.add(SKIP_INDEXING);
            }

            AdvancedCache<Object, Object> flaggedCache = cache.getAdvancedCache()
                  .withFlags(flags.toArray(new Flag[flags.size()]));

            for (InternalCacheEntry e : state)
               flaggedCache.put(e.getKey(), e.getValue(), e.getMetadata());

            if (debugTiming) {
               log.debugf("Preloaded %s keys in %s", state.size(),
                          Util.prettyPrintTime(timeService.timeDuration(start, MILLISECONDS)));
            }
         }
      }
   }

   private boolean localIndexingEnabled() {
      return configuration.indexing().enabled() && configuration.indexing().indexLocalOnly();
   }

   private Set<InternalCacheEntry> loadState() throws CacheLoaderException {
      int ne = -1;
      if (configuration.eviction().strategy().isEnabled()) ne = configuration.eviction().maxEntries();
      Set<InternalCacheEntry> state;
      switch (ne) {
         case -1:
            state = loader.loadAll();
            break;
         case 0:
            state = InfinispanCollections.emptySet();
            break;
         default:
            state = loader.load(ne);
            break;
      }
      return state;
   }

   @Override
   @Stop
   public void stop() {
      if (loader != null) {
         try {
            loader.stop();
         } catch (CacheLoaderException e) {
            throw new CacheException(e);
         } finally {
            loader = null;
         }
      }
   }

   CacheLoader createCacheLoader() throws Exception {
      CacheLoader tmpLoader;
      // if we only have a single cache loader configured in the chaining cacheloader then
      // don't use a chaining cache loader at all.
      // also if we are using passivation then just directly use the first cache loader.
      if (clmConfig.usingChainingCacheLoader()) {
         // create chaining cache loader.
         ChainingCacheStore ccl = new ChainingCacheStore();
         tmpLoader = ccl;

         // only one cache loader may have fetchPersistentState to true.
         int numLoadersWithFetchPersistentState = 0;
         for (CacheLoaderConfiguration cfg : clmConfig.cacheLoaders()) {
            if (cfg instanceof CacheStoreConfiguration) {
               CacheStoreConfiguration scfg = (CacheStoreConfiguration) cfg;
               assertNotSingletonAndShared(scfg);
               if(scfg.fetchPersistentState()) numLoadersWithFetchPersistentState++;
            }
            if (numLoadersWithFetchPersistentState > 1)
               throw log.multipleCacheStoresWithFetchPersistentState();

            CacheLoader l = createCacheLoader(cfg, cache);
            ccl.addCacheLoader(l);
         }
      } else {
         if (!clmConfig.cacheLoaders().isEmpty()) {
            CacheLoaderConfiguration cfg = clmConfig.cacheLoaders().get(0);
            if (cfg instanceof CacheStoreConfiguration)
               assertNotSingletonAndShared((CacheStoreConfiguration) cfg);
            tmpLoader = createCacheLoader(cfg, cache);
         } else {
            return null;
         }
      }

      return tmpLoader;
   }

   CacheLoader createCacheLoader(CacheLoaderConfiguration cfg, AdvancedCache<Object, Object> cache) throws Exception {
      ConfigurationFor annotation = cfg.getClass().getAnnotation(ConfigurationFor.class);
      if (annotation == null) {
         throw log.loaderConfigurationDoesNotSpecifyLoaderClass(cfg.getClass().getName());
      }
      CacheLoader tmpLoader = (CacheLoader) Util.getInstance(annotation.value());

      if (tmpLoader != null) {
         if (cfg instanceof CacheStoreConfiguration) {
            CacheStore tmpStore = (CacheStore) tmpLoader;
            // async?
            CacheStoreConfiguration cfg2 = (CacheStoreConfiguration) cfg;
            if (cfg2.async().enabled()) {
               tmpStore = createAsyncStore(tmpStore);
               tmpLoader = tmpStore;
            }

            // read only?
            if (cfg2.ignoreModifications()) {
               tmpStore = new ReadOnlyStore(tmpStore);
               tmpLoader = tmpStore;
            }

            // singleton?
            if (cfg2.singletonStore().enabled()) {
               tmpStore = new SingletonStore(tmpStore, cache);
               tmpLoader = tmpStore;
            }
         }

         // load props
         tmpLoader.init(cfg, cache, m);
      }
      return tmpLoader;
   }

   /**
    * This method has been extract to enable overriding in tests
    */
   protected AsyncStore createAsyncStore(CacheStore tmpStore) {
      return new AsyncStore(tmpStore);
   }

   void assertNotSingletonAndShared(CacheStoreConfiguration cfg) {
      if (cfg.singletonStore().enabled() && clmConfig.shared())
         throw new CacheConfigurationException("Invalid cache loader configuration!!  If a cache loader is configured as a singleton, the cache loader cannot be shared in a cluster!");
   }
}
TOP

Related Classes of org.infinispan.loaders.manager.CacheLoaderManagerImpl

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.