Package org.hibernate.ogm.datastore.infinispan.impl

Source Code of org.hibernate.ogm.datastore.infinispan.impl.InfinispanDatastoreProvider

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2011-2013 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*/
package org.hibernate.ogm.datastore.infinispan.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.HibernateException;
import org.hibernate.ogm.datastore.infinispan.impl.configuration.InfinispanConfiguration;
import org.hibernate.ogm.datastore.spi.DatastoreProvider;
import org.hibernate.ogm.datastore.spi.DefaultDatastoreNames;
import org.hibernate.ogm.dialect.GridDialect;
import org.hibernate.ogm.dialect.infinispan.InfinispanDialect;
import org.hibernate.ogm.service.impl.LuceneBasedQueryParserService;
import org.hibernate.ogm.service.impl.QueryParserService;
import org.hibernate.ogm.util.impl.Log;
import org.hibernate.ogm.util.impl.LoggerFactory;
import org.hibernate.service.jndi.spi.JndiService;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.Startable;
import org.hibernate.service.spi.Stoppable;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.util.FileLookupFactory;

/**
* Provides access to Infinispan's CacheManager; one CacheManager is needed for all caches,
* it can be taken via JNDI or started by this ServiceProvider; in this case it will also
* be stopped when no longer needed.
*
* @author Sanne Grinovero
* @author Emmanuel Bernard <emmanuel@hibernate.org>
*/
public class InfinispanDatastoreProvider implements DatastoreProvider, Startable, Stoppable,
                          ServiceRegistryAwareService, Configurable {

  private static final Log log = LoggerFactory.make();

  private JtaPlatform jtaPlatform;
  private JndiService jndiService;
  private Map<String,Cache> caches;
  private boolean isCacheProvided;
  private boolean started = false;
  private EmbeddedCacheManager cacheManager;
  private final InfinispanConfiguration config = new InfinispanConfiguration();

  @Override
  public Class<? extends GridDialect> getDefaultDialect() {
    return InfinispanDialect.class;
  }

  @Override
  public Class<? extends QueryParserService> getDefaultQueryParserServiceType() {
    return LuceneBasedQueryParserService.class;
  }

  @Override
  public void start() {
    if ( started ) {
      // ServiceRegistry might invoke start multiple times, but always from the same initialization thread.
      //TODO remove the start flag: no longer needed after HHH-7147
      return;
    }
    try {
      String jndiProperty = config.getJndiName();
      if ( jndiProperty == null ) {
        cacheManager = createCustomCacheManager( config.getConfigurationName(), jtaPlatform );
        isCacheProvided = false;
      }
      else {
        log.tracef( "Retrieving Infinispan from JNDI at %1$s", jndiProperty );
        cacheManager = (EmbeddedCacheManager) jndiService.locate( jndiProperty );
        isCacheProvided = true;
      }
    }
    catch (RuntimeException e) {
      throw log.unableToInitializeInfinispan( e );
    }
    eagerlyInitializeCaches( cacheManager );
    //clear resources
    this.jtaPlatform = null;
    this.jndiService = null;
    this.started = true;
  }

  /**
   * Need to make sure all needed caches are started before state transfer happens.
   * This prevents this node to return undefined cache errors during replication
   * when other nodes join this one.
   * @param cacheManager
   */
  private void eagerlyInitializeCaches(EmbeddedCacheManager cacheManager) {
    caches = new ConcurrentHashMap<String, Cache>( 3 );
    putInLocalCache( cacheManager, DefaultDatastoreNames.ASSOCIATION_STORE );
    putInLocalCache( cacheManager, DefaultDatastoreNames.ENTITY_STORE );
    putInLocalCache( cacheManager, DefaultDatastoreNames.IDENTIFIER_STORE );
  }

  private void putInLocalCache(EmbeddedCacheManager cacheManager, String cacheName) {
    caches.put( cacheName, cacheManager.getCache( cacheName ) );
  }

  private EmbeddedCacheManager createCustomCacheManager(String cfgName, JtaPlatform platform) {
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    TransactionManagerLookupDelegator transactionManagerLookupDelegator = new TransactionManagerLookupDelegator( platform );
    try {
      InputStream configurationFile = FileLookupFactory.newInstance().lookupFileStrict( cfgName, contextClassLoader );
      try {
        cacheManager = new DefaultCacheManager( configurationFile, false );
        // override the named cache configuration defined in the configuration file to
        // inject the platform TransactionManager
        for (String cacheName : cacheManager.getCacheNames() ) {
          Configuration originalCfg = cacheManager.getCacheConfiguration( cacheName );
          Configuration newCfg = new ConfigurationBuilder()
            .read( originalCfg )
              .transaction()
                .transactionManagerLookup( transactionManagerLookupDelegator )
            .build();
          cacheManager.defineConfiguration( cacheName, newCfg );
        }
        cacheManager.start();
        return cacheManager;
      }
      finally {
        if ( configurationFile != null ) {
          configurationFile.close();
        }
      }
    }
    catch ( RuntimeException re ) {
      throw raiseConfigurationError( re, cfgName );
    }
    catch (IOException e) {
      throw raiseConfigurationError( e, cfgName );
    }
  }

  public EmbeddedCacheManager getEmbeddedCacheManager() {
    return cacheManager;
  }

  //prefer generic form over specific ones to prepare for flexible cache setting
  public Cache getCache(String name) {
    return caches.get( name );
  }

  @Override
  public void stop() {
    if ( !isCacheProvided && cacheManager != null ) {
      cacheManager.stop();
    }
  }

  private HibernateException raiseConfigurationError(Exception e, String cfgName) {
    return new HibernateException(
        "Could not start Infinispan CacheManager using as configuration file: " + cfgName, e
    );
  }

  @Override
  public void injectServices(ServiceRegistryImplementor serviceRegistry) {
    jtaPlatform = serviceRegistry.getService( JtaPlatform.class );
    jndiService = serviceRegistry.getService( JndiService.class );
  }

  @Override
  public void configure(Map configurationValues) {
    this.config.initConfiguration( configurationValues );
  }
}
TOP

Related Classes of org.hibernate.ogm.datastore.infinispan.impl.InfinispanDatastoreProvider

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.