org.infinispan.hibernate.cache.v53.InfinispanRegionFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of infinispan-hibernate-cache-v53 Show documentation
Show all versions of infinispan-hibernate-cache-v53 Show documentation
Infinispan Hibernate 5.3 Cache module
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.infinispan.hibernate.cache.v53;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.AbstractRegionFactory;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.CacheTransactionSynchronization;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.support.RegionNameQualifier;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry;
import org.infinispan.AdvancedCache;
import org.infinispan.commands.module.ModuleCommandFactory;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.parsing.ConfigurationBuilderHolder;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.hibernate.cache.commons.DataType;
import org.infinispan.hibernate.cache.commons.DefaultCacheManagerProvider;
import org.infinispan.hibernate.cache.commons.InfinispanBaseRegion;
import org.infinispan.hibernate.cache.commons.TimeSource;
import org.infinispan.hibernate.cache.commons.util.CacheCommandFactory;
import org.infinispan.hibernate.cache.commons.util.Caches;
import org.infinispan.hibernate.cache.commons.util.InfinispanMessageLogger;
import org.infinispan.hibernate.cache.spi.EmbeddedCacheManagerProvider;
import org.infinispan.hibernate.cache.spi.InfinispanProperties;
import org.infinispan.hibernate.cache.v53.impl.ClusteredTimestampsRegionImpl;
import org.infinispan.hibernate.cache.v53.impl.DomainDataRegionImpl;
import org.infinispan.hibernate.cache.v53.impl.QueryResultsRegionImpl;
import org.infinispan.hibernate.cache.v53.impl.Sync;
import org.infinispan.hibernate.cache.v53.impl.TimestampsRegionImpl;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.transaction.TransactionMode;
/**
* A {@link RegionFactory} for Infinispan-backed cache
* regions.
*
* @author Chris Bredesen
* @author Galder Zamarreño
* @since 3.5
*/
public class InfinispanRegionFactory implements RegionFactory, TimeSource, InfinispanProperties {
private static final InfinispanMessageLogger log = InfinispanMessageLogger.Provider.getLog( InfinispanRegionFactory.class );
/**
* Defines custom mapping for regionName -> cacheName and also DataType.key -> cacheName
* (for the case that you want to change the cache configuration for whole type)
*/
protected final Map baseConfigurations = new HashMap<>();
/**
* Defines configuration properties applied on top of configuration set in any file, by regionName or DataType.key
*/
protected final Map configOverrides = new HashMap<>();
private CacheKeysFactory cacheKeysFactory;
private final Map dataTypeConfigurations = new HashMap<>();
private EmbeddedCacheManager manager;
private List regions = new ArrayList<>();
private SessionFactoryOptions settings;
private Boolean globalStats;
/**
* Create a new instance using the default configuration.
*/
public InfinispanRegionFactory() {
}
/**
* Create a new instance using conifguration properties in props
.
*
* @param props Environmental properties; currently unused.
*/
@SuppressWarnings("UnusedParameters")
public InfinispanRegionFactory(Properties props) {
this();
}
@Override
public DomainDataRegion buildDomainDataRegion(DomainDataRegionConfig regionConfig, DomainDataRegionBuildingContext buildingContext) {
log.debugf("Building domain data region [%s] entities=%s collections=%s naturalIds=%s",
regionConfig.getRegionName(),
regionConfig.getEntityCaching(),
regionConfig.getCollectionCaching(),
regionConfig.getNaturalIdCaching()
);
// TODO: data type is probably deprecated, but we need it for backwards-compatible configuration
DataType dataType;
int entities = regionConfig.getEntityCaching().size();
int collections = regionConfig.getCollectionCaching().size();
int naturalIds = regionConfig.getNaturalIdCaching().size();
if (entities > 0 && collections == 0 && naturalIds == 0) {
dataType = regionConfig.getEntityCaching().stream()
.allMatch(c -> !c.isMutable()) ? DataType.IMMUTABLE_ENTITY : DataType.ENTITY;
} else if (entities == 0 && collections > 0 && naturalIds == 0) {
dataType = DataType.COLLECTION;
} else if (entities == 0 && collections == 0 && naturalIds > 0) {
dataType = DataType.NATURAL_ID;
} else {
// some mix, let's use entity
dataType = DataType.ENTITY;
}
AdvancedCache cache = getCache(qualify(regionConfig.getRegionName()), regionConfig.getRegionName(), dataType, Collections.emptyList());
DomainDataRegionImpl region = new DomainDataRegionImpl(cache, regionConfig, this, getCacheKeysFactory());
startRegion(region);
return region;
}
@Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, SessionFactoryImplementor sessionFactory) {
log.debugf("Building query results cache region [%s]", regionName);
List legacyUnqualifiedNames = regionName.equals(RegionFactory.DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME) ?
AbstractRegionFactory.LEGACY_QUERY_RESULTS_REGION_UNQUALIFIED_NAMES : Collections.emptyList();
AdvancedCache cache = getCache(qualify(regionName), regionName, DataType.QUERY, legacyUnqualifiedNames);
QueryResultsRegionImpl region = new QueryResultsRegionImpl(cache, regionName, this);
startRegion(region);
return region;
}
@Override
public TimestampsRegion buildTimestampsRegion(String regionName, SessionFactoryImplementor sessionFactory) {
log.debugf("Building timestamps cache region [%s]", regionName);
List legacyUnqualifiedNames = regionName.equals(RegionFactory.DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME) ?
AbstractRegionFactory.LEGACY_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAMES : Collections.emptyList();
final AdvancedCache cache = getCache(qualify(regionName), regionName, DataType.TIMESTAMPS, legacyUnqualifiedNames);
TimestampsRegionImpl region = createTimestampsRegion(cache, regionName);
startRegion(region);
return region;
}
protected TimestampsRegionImpl createTimestampsRegion(
AdvancedCache cache, String regionName) {
if ( Caches.isClustered(cache) ) {
return new ClusteredTimestampsRegionImpl(cache, regionName, this);
} else {
return new TimestampsRegionImpl(cache, regionName, this);
}
}
public Configuration getPendingPutsCacheConfiguration() {
return dataTypeConfigurations.get(DataType.PENDING_PUTS);
}
protected CacheKeysFactory getCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return false;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.TRANSACTIONAL;
}
@Override
public String qualify(String regionName) {
return RegionNameQualifier.INSTANCE.qualify(regionName, settings);
}
@Override
public CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session) {
return new Sync(this);
}
@Override
public long nextTimestamp() {
return System.currentTimeMillis();
}
public void setCacheManager(EmbeddedCacheManager manager) {
this.manager = manager;
}
public EmbeddedCacheManager getCacheManager() {
return manager;
}
@Override
public void start(SessionFactoryOptions settings, Map configValues) throws CacheException {
log.debug( "Starting Infinispan region factory" );
// determine the CacheKeysFactory to use...
this.cacheKeysFactory = determineCacheKeysFactory( settings, configValues );
try {
this.settings = settings;
for (Object k : configValues.keySet()) {
final String key = (String) k;
int prefixLoc;
if ((prefixLoc = key.indexOf( PREFIX )) != -1) {
parseProperty( prefixLoc, key, extractProperty(key, configValues));
}
}
String globalStatsStr = extractProperty(INFINISPAN_GLOBAL_STATISTICS_PROP, configValues);
if ( globalStatsStr != null ) {
globalStats = Boolean.parseBoolean(globalStatsStr);
}
if (configValues.containsKey(INFINISPAN_USE_SYNCHRONIZATION_PROP)) {
log.propertyUseSynchronizationDeprecated();
}
StandardServiceRegistry serviceRegistry = settings.getServiceRegistry();
manager = createCacheManager(toProperties(configValues), serviceRegistry);
defineDataTypeCacheConfigurations(serviceRegistry);
}
catch (CacheException ce) {
throw ce;
}
catch (Throwable t) {
throw log.unableToStart(t);
}
}
private Properties toProperties(Map