/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.infinispan.persistencestrategy.impl; import org.hibernate.ogm.datastore.infinispan.logging.impl.Log; import org.hibernate.ogm.datastore.infinispan.logging.impl.LoggerFactory; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.common.externalizer.impl.ExternalizerIds; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.common.externalizer.impl.RowKeyExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.kind.externalizer.impl.AssociationKeyExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.kind.externalizer.impl.EntityKeyExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.kind.externalizer.impl.EntityKeyMetadataExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.kind.externalizer.impl.IdSourceKeyExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.table.externalizer.impl.PersistentAssociationKeyExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.table.externalizer.impl.PersistentEntityKeyExternalizer; import org.hibernate.ogm.datastore.infinispan.persistencestrategy.table.externalizer.impl.PersistentIdSourceKeyExternalizer; import org.infinispan.commons.marshall.AdvancedExternalizer; import org.infinispan.configuration.global.GlobalConfiguration; import org.infinispan.configuration.global.SerializationConfigurationBuilder; import org.infinispan.manager.EmbeddedCacheManager; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Helpers to ensure registration of all custom Externalizers we need for Hibernate OGM / Infinispan. * * @author Sanne Grinovero */ public final class ExternalizersIntegration { private static final Log log = LoggerFactory.getLogger(); private static final Map<Integer, AdvancedExternalizer<?>> ogmExternalizers = initializeOgmExternalizers(); private ExternalizersIntegration() { // to not be created } private static Map<Integer, AdvancedExternalizer<?>> initializeOgmExternalizers() { Map<Integer, AdvancedExternalizer<?>> m = new HashMap<>(); //Register here any new Externalizer that we might need: addExternalizerToMap( m, AssociationKeyExternalizer.INSTANCE ); addExternalizerToMap( m, EntityKeyExternalizer.INSTANCE ); addExternalizerToMap( m, EntityKeyMetadataExternalizer.INSTANCE ); addExternalizerToMap( m, IdSourceKeyExternalizer.INSTANCE ); addExternalizerToMap( m, PersistentAssociationKeyExternalizer.INSTANCE ); addExternalizerToMap( m, PersistentEntityKeyExternalizer.INSTANCE ); addExternalizerToMap( m, PersistentIdSourceKeyExternalizer.INSTANCE ); addExternalizerToMap( m, RowKeyExternalizer.INSTANCE ); return Collections.unmodifiableMap( m ); } private static void addExternalizerToMap(Map<Integer, AdvancedExternalizer<?>> m, AdvancedExternalizer<?> instance) { Integer id = instance.getId(); assert id != null; //The range of ids assigned to Hibernate OGM by the Infinispan team needs to be strictly verified; //see http://infinispan.org/docs/9.0.x/user_guide/user_guide.html#preassigned_externalizer_id_ranges //and please use org.hibernate.ogm.datastore.infinispan.persistencestrategy.common.externalizer.impl.ExternalizerIds assert id.intValue() >= 1400 && id.intValue() < 1500 : "Externalizer out of the assigned range for Hibernate OGM"; AdvancedExternalizer<?> previous = m.put( instance.getId(), instance ); assert previous == null : "Clash in Externalizer Id! They need to be strictly unique."; } /** * Registers all custom Externalizer implementations that Hibernate OGM needs into an Infinispan CacheManager * configuration. * * @see ExternalizerIds * @param cfg the Serialization section of a GlobalConfiguration builder */ public static void registerOgmExternalizers(SerializationConfigurationBuilder cfg) { for ( AdvancedExternalizer<?> advancedExternalizer : ogmExternalizers.values() ) { cfg.addAdvancedExternalizer( advancedExternalizer ); } } /** * Registers all custom Externalizer implementations that Hibernate OGM needs into a running * Infinispan CacheManager configuration. * This is only safe to do when Caches from this CacheManager haven't been started yet, * or the ones already started do not contain any data needing these. * * @see ExternalizerIds * @param globalCfg the Serialization section of a GlobalConfiguration builder */ public static void registerOgmExternalizers(GlobalConfiguration globalCfg) { Map<Integer, AdvancedExternalizer<?>> externalizerMap = globalCfg.serialization().advancedExternalizers(); externalizerMap.putAll( ogmExternalizers ); } /** * Verify that all OGM custom externalizers are present. * N.B. even if some Externalizer is only needed in specific configuration, * it is not safe to start a CacheManager without one as the same CacheManager * might be used, or have been used in the past, to store data using a different * configuration. * * @see ExternalizerIds * @see AdvancedExternalizer * @param externalCacheManager the provided CacheManager to validate */ public static void validateExternalizersPresent(EmbeddedCacheManager externalCacheManager) { Map<Integer, AdvancedExternalizer<?>> externalizerMap = externalCacheManager .getCacheManagerConfiguration() .serialization() .advancedExternalizers(); for ( AdvancedExternalizer<?> ogmExternalizer : ogmExternalizers.values() ) { final Integer externalizerId = ogmExternalizer.getId(); AdvancedExternalizer<?> registeredExternalizer = externalizerMap.get( externalizerId ); if ( registeredExternalizer == null ) { throw log.externalizersNotRegistered( externalizerId, ogmExternalizer.getClass() ); } else if ( !registeredExternalizer.getClass().equals( ogmExternalizer ) ) { if ( registeredExternalizer.getClass().toString().equals( ogmExternalizer.getClass().toString() ) ) { // same class name, yet different Class definition! throw log.registeredExternalizerNotLoadedFromOGMClassloader( registeredExternalizer.getClass() ); } else { throw log.externalizerIdNotMatchingType( externalizerId, registeredExternalizer, ogmExternalizer ); } } } } }