org.infinispan.cdi.InfinispanExtensionEmbedded Maven / Gradle / Ivy
package org.infinispan.cdi;
import org.infinispan.AdvancedCache;
import org.infinispan.Cache;
import org.infinispan.cdi.event.cachemanager.CacheManagerEventBridge;
import org.infinispan.cdi.util.BeanBuilder;
import org.infinispan.cdi.util.Beans;
import org.infinispan.cdi.util.ContextualLifecycle;
import org.infinispan.cdi.util.ContextualReference;
import org.infinispan.cdi.util.DefaultLiteral;
import org.infinispan.cdi.util.Reflections;
import org.infinispan.cdi.util.defaultbean.DefaultBean;
import org.infinispan.cdi.util.defaultbean.DefaultBeanHolder;
import org.infinispan.cdi.util.defaultbean.Installed;
import org.infinispan.cdi.util.logging.EmbeddedLog;
import org.infinispan.commons.logging.LogFactory;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessBean;
import javax.enterprise.inject.spi.ProcessProducer;
import javax.enterprise.inject.spi.Producer;
import javax.enterprise.util.TypeLiteral;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
/**
* The Infinispan CDI extension for embedded caches
*
* @author Pete Muir
* @author Kevin Pollet (C) 2011 SERLI
*/
public class InfinispanExtensionEmbedded implements Extension {
private static final EmbeddedLog logger = LogFactory.getLog(InfinispanExtensionEmbedded.class, EmbeddedLog.class);
private final Set configurations;
private volatile boolean registered = false;
private final Object registerLock = new Object();
private Set> installedEmbeddedCacheManagers = new HashSet>();
public InfinispanExtensionEmbedded() {
new ConfigurationBuilder(); // Attempt to initialize a core class
this.configurations = new HashSet();
}
void processProducers(@Observes ProcessProducer, ?> event, BeanManager beanManager) {
final ConfigureCache annotation = event.getAnnotatedMember().getAnnotation(ConfigureCache.class);
if (annotation != null) {
configurations.add(new ConfigurationHolder(
(Producer)event.getProducer(),
annotation.value(),
Reflections.getQualifiers(beanManager, event.getAnnotatedMember().getAnnotations())
));
}
}
// This is a work around for CDI Uber Jar deployment. When Weld scans the classpath it pick up DefaultCacheManager
// (this is an implementation, not an interface, so it gets instantiated). As a result we get duplicated classes
// in CDI BeanManager.
@SuppressWarnings("unused")
void removeDuplicatedRemoteCacheManager(@Observes ProcessAnnotatedType bean) {
if(DefaultCacheManager.class.getCanonicalName().equals(bean.getAnnotatedType().getJavaClass().getCanonicalName())) {
logger.info("removing duplicated DefaultCacheManager" + bean.getAnnotatedType());
bean.veto();
}
}
@SuppressWarnings("unchecked")
void registerCacheBeans(@Observes AfterBeanDiscovery event, final BeanManager beanManager) {
for (final ConfigurationHolder holder : configurations) {
// register a AdvancedCache producer for each
Bean> b = new BeanBuilder(beanManager)
.readFromType(beanManager.createAnnotatedType(AdvancedCache.class))
.qualifiers(Beans.buildQualifiers(holder.getQualifiers()))
.addType(new TypeLiteral>() {}.getType())
.addType(new TypeLiteral>() {}.getType())
.beanLifecycle(new ContextualLifecycle>() {
@Override
public AdvancedCache, ?> create(Bean> bean,
CreationalContext> creationalContext) {
return new ContextualReference(beanManager, AdvancedCacheProducer.class).create(Reflections.>cast(creationalContext)).get().getAdvancedCache(holder.getName(), holder.getQualifiers());
}
@Override
public void destroy(Bean> bean, AdvancedCache, ?> instance,
CreationalContext> creationalContext) {
// No-op, Infinispan manages the lifecycle
}
}).create();
event.addBean(b);
}
}
void registerInputCacheCustomBean(@Observes AfterBeanDiscovery event, BeanManager beanManager) {
@SuppressWarnings("serial")
TypeLiteral> typeLiteral = new TypeLiteral>() {};
event.addBean(new BeanBuilder>(beanManager)
.readFromType(beanManager.createAnnotatedType(typeLiteral.getRawType()))
.addType(typeLiteral.getType()).qualifiers(new InputLiteral())
.beanLifecycle(new ContextualLifecycle>() {
@Override
public Cache create(Bean> bean,
CreationalContext> creationalContext) {
return ContextInputCache.get();
}
@Override
public void destroy(Bean> bean, Cache instance,
CreationalContext> creationalContext) {
}
}).create());
}
public void observeDefaultEmbeddedCacheManagerInstalled(@Observes @Installed DefaultBeanHolder bean) {
if (bean.getBean().getTypes().contains(EmbeddedCacheManager.class)) {
installedEmbeddedCacheManagers.add(bean.getBean().getQualifiers());
}
}
public Set getInstalledEmbeddedCacheManagers(BeanManager beanManager) {
Set installedCacheManagers = new HashSet();
for (Set qualifiers : installedEmbeddedCacheManagers) {
Bean> b = beanManager.resolve(beanManager.getBeans(EmbeddedCacheManager.class, qualifiers.toArray(Reflections.EMPTY_ANNOTATION_ARRAY)));
EmbeddedCacheManager cm = (EmbeddedCacheManager) beanManager.getReference(b, EmbeddedCacheManager.class, beanManager.createCreationalContext(b));
installedCacheManagers.add(new InstalledCacheManager(cm, qualifiers.contains(DefaultLiteral.INSTANCE)));
}
return installedCacheManagers;
}
public void observeEmbeddedCacheManagerBean(@Observes ProcessBean> processBean) {
if (processBean.getBean().getTypes().contains(EmbeddedCacheManager.class) && !processBean.getAnnotated().isAnnotationPresent(DefaultBean.class)) {
// Install any non-default EmbeddedCacheManager producers. We handle default ones separately, to ensure we only pick them up if installed
installedEmbeddedCacheManagers.add(processBean.getBean().getQualifiers());
}
}
public void registerCacheConfigurations(CacheManagerEventBridge eventBridge, Instance cacheManagers, BeanManager beanManager) {
if (!registered) {
synchronized (registerLock) {
if (!registered) {
final CreationalContext ctx = beanManager.createCreationalContext(null);
final EmbeddedCacheManager defaultCacheManager = cacheManagers.select(DefaultLiteral.INSTANCE).get();
for (ConfigurationHolder oneConfigurationHolder : configurations) {
final String cacheName = oneConfigurationHolder.getName();
final Configuration cacheConfiguration = oneConfigurationHolder.getProducer().produce(ctx);
final Set cacheQualifiers = oneConfigurationHolder.getQualifiers();
// if a specific cache manager is defined for this cache we use it
final Instance specificCacheManager = cacheManagers.select(cacheQualifiers.toArray(new Annotation[cacheQualifiers.size()]));
final EmbeddedCacheManager cacheManager = specificCacheManager.isUnsatisfied() ? defaultCacheManager : specificCacheManager.get();
// the default configuration is registered by the default cache manager producer
if (!cacheName.trim().isEmpty()) {
if (cacheConfiguration != null) {
cacheManager.defineConfiguration(cacheName, cacheConfiguration);
logger.cacheConfigurationDefined(cacheName, cacheManager);
} else if (!cacheManager.getCacheNames().contains(cacheName)) {
cacheManager.defineConfiguration(cacheName, cacheManager.getDefaultCacheConfiguration());
logger.cacheConfigurationDefined(cacheName, cacheManager);
}
}
// register cache manager observers
eventBridge.registerObservers(cacheQualifiers, cacheName, cacheManager);
}
// only set registered to true at the end to keep other threads waiting until we have finished registration
registered = true;
}
}
}
}
static class ConfigurationHolder {
private final Producer producer;
private final Set qualifiers;
private final String name;
ConfigurationHolder(Producer producer, String name, Set qualifiers) {
this.producer = producer;
this.name = name;
this.qualifiers = qualifiers;
}
public Producer getProducer() {
return producer;
}
public String getName() {
return name;
}
public Set getQualifiers() {
return qualifiers;
}
}
public static class InstalledCacheManager {
final EmbeddedCacheManager cacheManager;
final boolean isDefault;
InstalledCacheManager(EmbeddedCacheManager cacheManager, boolean aDefault) {
this.cacheManager = cacheManager;
isDefault = aDefault;
}
public EmbeddedCacheManager getCacheManager() {
return cacheManager;
}
public boolean isDefault() {
return isDefault;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy