package com.kryptnostic.rhizome.pods.hazelcast;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Maps;
import com.google.common.collect.Multiset;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.QueueConfig;
import com.hazelcast.config.SerializerConfig;
import com.hazelcast.nio.serialization.Serializer;
import com.kryptnostic.rhizome.mapstores.SelfRegisteringMapStore;
import com.kryptnostic.rhizome.mapstores.SelfRegisteringQueueStore;
@Configuration
public class RegistryBasedHazelcastInstanceConfigurationPod extends BaseHazelcastInstanceConfigurationPod {
private static final Logger logger = LoggerFactory
.getLogger( RegistryBasedHazelcastInstanceConfigurationPod.class );
private static final ConcurrentMap<Class<?>, Serializer> serializerRegistry = Maps
.newConcurrentMap();
private static final ConcurrentMap<String, SelfRegisteringMapStore<?, ?>> mapRegistry = Maps
.newConcurrentMap();
private static final ConcurrentMap<String, SelfRegisteringQueueStore<?>> queueRegistry = Maps
.newConcurrentMap();
@Override
protected Collection<SerializerConfig> getSerializerConfigs() {
final Multiset<Integer> typeIds = HashMultiset.create();
Set<SerializerConfig> configs = serializerRegistry.entrySet()
.stream()
.peek( e -> typeIds.add( e.getValue().getTypeId() ) )
.map( e -> new SerializerConfig().setTypeClass( e.getKey() ).setImplementation( e.getValue() ) )
.collect( Collectors.toSet() );
logger.info("Detected the following serializer configurations at startup {}." , configs );
typeIds.entrySet()
.stream()
.filter( e -> e.getCount() > 1 )
.forEach( e -> logger.warn( "Found {} duplicate serializers for type id: {}",
e.getCount(),
e.getElement() ) );
return configs;
}
@Override
protected Map<String, MapConfig> getMapConfigs() {
return Maps.transformEntries( mapRegistry, ( k, v ) -> v.getMapConfig() );
}
@Override
protected Map<String, QueueConfig> getQueueConfigs() {
return Maps.transformEntries( queueRegistry, ( k, v ) -> v.getQueueConfig() );
}
/*
* The following three methods use @Autowired instead of @Inject, since that functionality is not provided by the
* spec :-/
*/
@Autowired(
required = false )
public void registerMapStores( Set<SelfRegisteringMapStore<?, ?>> mapStores ) {
if ( mapStores.isEmpty() ) {
logger.warn( "No map stores were configured." );
}
for ( SelfRegisteringMapStore<?, ?> s : mapStores ) {
register( s.getMapConfig().getName(), s );
}
}
@Autowired(
required = false )
public void registerQueueStores( Set<SelfRegisteringQueueStore<?>> queueStores ) {
if ( queueStores.isEmpty() ) {
logger.warn( "No queue stores were configured." );
}
for ( SelfRegisteringQueueStore<?> s : queueStores ) {
queueRegistry.put( s.getQueueConfig().getName(), s );
}
}
@Autowired(
required = false )
public void register( Set<SelfRegisteringStreamSerializer<?>> serializers ) {
if ( serializers.isEmpty() ) {
logger.warn( "No serializers were configured." );
}
for ( SelfRegisteringStreamSerializer<?> s : serializers ) {
serializerRegistry.put( s.getClazz(), s );
}
}
public static void register( String queueName, SelfRegisteringQueueStore<?> queueStore ) {
Preconditions.checkNotNull( queueStore, "Cannot register null queue-store." );
queueRegistry.put( queueName, queueStore );
}
public static void register( String mapName, SelfRegisteringMapStore<?, ?> mapStore ) {
Preconditions.checkNotNull( mapStore, "Cannot register null map-store." );
mapRegistry.put( mapName, mapStore );
}
public static void register( Class<?> hzSerializableClass, Serializer serializer ) {
Preconditions.checkNotNull( serializer, "Cannot register null serializer." );
serializerRegistry.put( hzSerializableClass, serializer );
}
}