org.infinispan.cdi.remote.InfinispanExtensionRemote Maven / Gradle / Ivy
The newest version!
package org.infinispan.cdi.remote;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.spi.AfterBeanDiscovery;
import jakarta.enterprise.inject.spi.Annotated;
import jakarta.enterprise.inject.spi.AnnotatedMember;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.Extension;
import jakarta.enterprise.inject.spi.InjectionPoint;
import jakarta.enterprise.inject.spi.InjectionTarget;
import jakarta.enterprise.inject.spi.ProcessInjectionTarget;
import jakarta.enterprise.inject.spi.ProcessProducer;
import jakarta.enterprise.inject.spi.Producer;
import jakarta.enterprise.util.AnnotationLiteral;
import org.infinispan.cdi.common.util.AnyLiteral;
import org.infinispan.cdi.common.util.BeanBuilder;
import org.infinispan.cdi.common.util.ContextualLifecycle;
import org.infinispan.cdi.common.util.DefaultLiteral;
import org.infinispan.cdi.common.util.Reflections;
import org.infinispan.cdi.remote.logging.RemoteLog;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.commons.logging.LogFactory;
public class InfinispanExtensionRemote implements Extension {
private static final RemoteLog LOGGER = LogFactory.getLog(InfinispanExtensionRemote.class, RemoteLog.class);
private final Map> remoteCacheInjectionPoints;
private Producer> remoteCacheProducer;
public InfinispanExtensionRemote() {
new ConfigurationBuilder(); // Attempt to initialize a hotrod client class
this.remoteCacheInjectionPoints = new HashMap>();
}
void processProducers(@Observes ProcessProducer, ?> event) {
AnnotatedMember> member = event.getAnnotatedMember();
if (RemoteCacheProducer.class.equals(member.getDeclaringType().getBaseType())) {
remoteCacheProducer = (Producer>) event.getProducer();
}
}
void saveRemoteInjectionPoints(@Observes ProcessInjectionTarget event, BeanManager beanManager) {
final InjectionTarget injectionTarget = event.getInjectionTarget();
for (InjectionPoint injectionPoint : injectionTarget.getInjectionPoints()) {
final Annotated annotated = injectionPoint.getAnnotated();
final Type type = annotated.getBaseType();
final Class> rawType = Reflections.getRawType(annotated.getBaseType());
final Set qualifiers = Reflections.getQualifiers(beanManager, annotated.getAnnotations());
if (rawType.equals(RemoteCache.class) && qualifiers.isEmpty()) {
qualifiers.add(new AnnotationLiteral() {
});
addRemoteCacheInjectionPoint(type, qualifiers);
} else if (!annotated.isAnnotationPresent(Remote.class)
&& Reflections.getMetaAnnotation(annotated, Remote.class) != null
&& rawType.isAssignableFrom(RemoteCache.class)) {
addRemoteCacheInjectionPoint(type, qualifiers);
}
}
}
private void addRemoteCacheInjectionPoint(Type type, Set qualifiers) {
final Set currentQualifiers = remoteCacheInjectionPoints.get(type);
if (currentQualifiers == null) {
remoteCacheInjectionPoints.put(type, qualifiers);
} else {
currentQualifiers.addAll(qualifiers);
}
}
@SuppressWarnings("unchecked")
void registerBeans(@Observes AfterBeanDiscovery event, final BeanManager beanManager) {
if (beanManager.getBeans(RemoteCacheManager.class).isEmpty()) {
LOGGER.addDefaultRemoteCacheManager();
event.addBean(createDefaultRemoteCacheManagerBean(beanManager));
}
for (Map.Entry> entry : remoteCacheInjectionPoints.entrySet()) {
event.addBean(new BeanBuilder(beanManager)
.readFromType(beanManager.createAnnotatedType(Reflections.getRawType(entry.getKey())))
.addType(entry.getKey())
.addQualifiers(entry.getValue())
.passivationCapable(true)
.id(InfinispanExtensionRemote.class.getSimpleName() + "#" + RemoteCache.class.getSimpleName())
.beanLifecycle(new ContextualLifecycle>() {
@Override
public RemoteCache, ?> create(Bean> bean, CreationalContext> ctx) {
return remoteCacheProducer.produce(ctx);
}
@Override
public void destroy(Bean> bean, RemoteCache, ?> instance, CreationalContext> ctx) {
remoteCacheProducer.dispose(instance);
}
}).create());
}
}
/**
* The default remote cache manager can be overridden by creating a producer which produces the new default remote
* cache manager. The remote cache manager produced must have the scope {@link ApplicationScoped} and the
* {@linkplain jakarta.enterprise.inject.Default Default} qualifier.
*
* @param beanManager
* @return a custom bean
*/
private Bean createDefaultRemoteCacheManagerBean(BeanManager beanManager) {
return new BeanBuilder(beanManager)
.beanClass(InfinispanExtensionRemote.class)
.addTypes(Object.class, RemoteCacheManager.class)
.scope(ApplicationScoped.class)
.qualifiers(DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE)
.passivationCapable(true)
.id(InfinispanExtensionRemote.class.getSimpleName() + "#" + RemoteCacheManager.class.getSimpleName())
.beanLifecycle(new ContextualLifecycle() {
@Override
public RemoteCacheManager create(Bean bean,
CreationalContext creationalContext) {
return new RemoteCacheManager();
}
@Override
public void destroy(Bean bean, RemoteCacheManager instance,
CreationalContext creationalContext) {
instance.stop();
}
}).create();
}
}