package org.jboss.as.clustering.infinispan.cs.deployment; import java.lang.reflect.Constructor; import java.util.List; import org.jboss.as.clustering.infinispan.InfinispanLogger; import org.jboss.as.clustering.infinispan.InfinispanMessages; import org.jboss.as.clustering.infinispan.cs.factory.DeployedCacheStoreFactory; import org.jboss.as.clustering.infinispan.cs.factory.DeployedCacheStoreFactoryService; import org.jboss.as.server.deployment.Attachments; import org.jboss.as.server.deployment.DeploymentPhaseContext; import org.jboss.as.server.deployment.DeploymentUnit; import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.as.server.deployment.DeploymentUnitProcessor; import org.jboss.as.server.deployment.ServicesAttachment; import org.jboss.modules.Module; import org.jboss.modules.ModuleClassLoader; import org.jboss.msc.service.Service; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.StartContext; import org.jboss.msc.service.StopContext; import org.jboss.msc.value.InjectedValue; public abstract class AbstractCacheStoreExtensionProcessor<T> implements DeploymentUnitProcessor { @Override public void deploy(DeploymentPhaseContext ctx) throws DeploymentUnitProcessingException { DeploymentUnit deploymentUnit = ctx.getDeploymentUnit(); Module module = deploymentUnit.getAttachment(Attachments.MODULE); ServicesAttachment servicesAttachment = deploymentUnit.getAttachment(Attachments.SERVICES); if (module != null && servicesAttachment != null) addServices(ctx, servicesAttachment, module); } @Override public void undeploy(DeploymentUnit deploymentUnit) { // Deploy only adds services, so no need to do anything here // since these services are automatically removed. } private void addServices(DeploymentPhaseContext ctx, ServicesAttachment servicesAttachment, Module module) { Class<T> serviceClass = getServiceClass(); List<String> implementationNames = servicesAttachment.getServiceImplementations(serviceClass.getName()); ModuleClassLoader classLoader = module.getClassLoader(); for (String serviceClassName : implementationNames) { try { Class<? extends T> clazz = classLoader.loadClass(serviceClassName).asSubclass(serviceClass); Constructor<? extends T> ctor = clazz.getConstructor(); T instance = ctor.newInstance(); installService(ctx, serviceClassName, instance); } catch (Exception e) { InfinispanMessages.MESSAGES.unableToInstantiateClass(serviceClassName); } } } public final void installService(DeploymentPhaseContext ctx, String implementationClassName, T instance) { AbstractExtensionManagerService<T> service = createService(implementationClassName, instance); ServiceName extensionServiceName = ServiceName.JBOSS.append(service.getServiceTypeName(), implementationClassName.replaceAll("\\.", "_")); InfinispanLogger.ROOT_LOGGER.installDeployedCacheStore(implementationClassName); ServiceBuilder<T> serviceBuilder = ctx.getServiceTarget().addService(extensionServiceName, service); serviceBuilder.setInitialMode(ServiceController.Mode.ACTIVE); serviceBuilder.addDependency(DeployedCacheStoreFactoryService.SERVICE_NAME, DeployedCacheStoreFactory.class, service.getDeployedCacheStoreFactory()); serviceBuilder.install(); } public abstract Class<T> getServiceClass(); public abstract AbstractExtensionManagerService<T> createService(String serviceName, T instance); protected static abstract class AbstractExtensionManagerService<T> implements Service<T> { protected final T extension; protected final String className; protected InjectedValue<DeployedCacheStoreFactory> deployedCacheStoreFactory = new InjectedValue<>(); protected AbstractExtensionManagerService(String className, T extension) { this.extension = extension; this.className = className; } @Override public void start(StartContext context) { InfinispanLogger.ROOT_LOGGER.deployedStoreStarted(className); deployedCacheStoreFactory.getValue().addInstance(extension); } @Override public void stop(StopContext context) { InfinispanLogger.ROOT_LOGGER.deployedStoreStopped(className); deployedCacheStoreFactory.getValue().removeInstance(extension); } public InjectedValue<DeployedCacheStoreFactory> getDeployedCacheStoreFactory() { return deployedCacheStoreFactory; } public abstract String getServiceTypeName(); } }