/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.clustering.infinispan.subsystem; import java.util.List; import java.util.Map.Entry; import java.util.ServiceLoader; import javax.management.MBeanServer; import org.infinispan.configuration.global.GlobalAuthorizationConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfiguration; import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.configuration.global.GlobalRoleConfigurationBuilder; import org.infinispan.configuration.global.GlobalStateConfigurationBuilder; import org.infinispan.configuration.global.ShutdownHookBehavior; import org.infinispan.configuration.global.ThreadPoolConfiguration; import org.infinispan.configuration.internal.PrivateGlobalConfigurationBuilder; import org.infinispan.marshall.core.Ids; import org.infinispan.security.AuditLogger; import org.infinispan.security.PrincipalRoleMapper; import org.infinispan.security.impl.ClusterRoleMapper; import org.infinispan.security.impl.NullAuditLogger; import org.infinispan.server.commons.service.Builder; import org.infinispan.server.commons.service.InjectedValueDependency; import org.infinispan.server.commons.service.ValueDependency; import org.infinispan.server.infinispan.spi.service.CacheContainerServiceName; import org.infinispan.server.infinispan.spi.service.CacheServiceNameFactory; import org.infinispan.server.jgroups.spi.ProtocolStackConfiguration; import org.infinispan.server.jgroups.spi.RelayConfiguration; import org.jboss.as.clustering.infinispan.ChannelTransport; import org.jboss.as.clustering.infinispan.InfinispanLogger; import org.jboss.as.clustering.infinispan.MBeanServerProvider; import org.jboss.as.clustering.infinispan.io.SimpleExternalizer; import org.jboss.as.clustering.infinispan.subsystem.EmbeddedCacheManagerConfigurationService.AuthorizationConfiguration; import org.jboss.as.clustering.infinispan.subsystem.EmbeddedCacheManagerConfigurationService.GlobalStateLocationConfiguration; import org.jboss.as.clustering.infinispan.subsystem.EmbeddedCacheManagerConfigurationService.TransportConfiguration; import org.jboss.as.controller.services.path.PathManager; import org.jboss.as.controller.services.path.PathManagerService; import org.jboss.as.jmx.MBeanServerService; import org.jboss.as.server.Services; import org.jboss.marshalling.ModularClassResolver; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoadException; import org.jboss.modules.ModuleLoader; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceTarget; import org.jboss.msc.service.ValueService; import org.jboss.msc.value.InjectedValue; import org.jboss.msc.value.Value; /** * @author Paul Ferraro */ public class CacheContainerConfigurationBuilder implements Builder<GlobalConfiguration>, Value<GlobalConfiguration> { private final InjectedValue<ModuleLoader> loader = new InjectedValue<>(); private final InjectedValue<MBeanServer> server = new InjectedValue<>(); private final String name; private boolean statisticsEnabled; private ModuleIdentifier module; private AuthorizationConfigurationBuilder authorization = null; private ValueDependency<TransportConfiguration> transport = null; private GlobalStateLocationConfigurationBuilder globalStateLocation = null; private final InjectedValue<ThreadPoolConfiguration> asyncOperationsThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> expirationThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> listenerThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> persistenceThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> remoteCommandThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> stateTransferThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> transportThreadPool = new InjectedValue<>(); private final InjectedValue<ThreadPoolConfiguration> replicationQueueThreadPool = new InjectedValue<>(); private final InjectedValue<PathManager> pathManager = new InjectedValue<>(); public CacheContainerConfigurationBuilder(String name) { this.name = name; } @Override public ServiceName getServiceName() { return CacheContainerServiceName.CONFIGURATION.getServiceName(this.name); } @Override public ServiceBuilder<GlobalConfiguration> build(ServiceTarget target) { ServiceBuilder<GlobalConfiguration> builder = target.addService(this.getServiceName(), new ValueService<>(this)) .addDependency(Services.JBOSS_SERVICE_MODULE_LOADER, ModuleLoader.class, this.loader) .addDependency(MBeanServerService.SERVICE_NAME, MBeanServer.class, this.server) .addDependency(ThreadPoolResource.ASYNC_OPERATIONS.getServiceName(this.name), ThreadPoolConfiguration.class, this.asyncOperationsThreadPool) .addDependency(ThreadPoolResource.LISTENER.getServiceName(this.name), ThreadPoolConfiguration.class, this.listenerThreadPool) .addDependency(ThreadPoolResource.REMOTE_COMMAND.getServiceName(this.name), ThreadPoolConfiguration.class, this.remoteCommandThreadPool) .addDependency(ThreadPoolResource.STATE_TRANSFER.getServiceName(this.name), ThreadPoolConfiguration.class, this.stateTransferThreadPool) .addDependency(ThreadPoolResource.PERSISTENCE.getServiceName(this.name), ThreadPoolConfiguration.class, this.persistenceThreadPool) .addDependency(ThreadPoolResource.TRANSPORT.getServiceName(this.name), ThreadPoolConfiguration.class, this.transportThreadPool) .addDependency(ScheduledThreadPoolResource.EXPIRATION.getServiceName(this.name), ThreadPoolConfiguration.class, this.expirationThreadPool) .addDependency(ScheduledThreadPoolResource.REPLICATION_QUEUE.getServiceName(this.name), ThreadPoolConfiguration.class, this.replicationQueueThreadPool) ; if (this.transport != null) { this.transport.register(builder); } if (this.globalStateLocation != null) { builder.addDependency(PathManagerService.SERVICE_NAME, PathManager.class, this.pathManager); } return builder.setInitialMode(ServiceController.Mode.ON_DEMAND); } @Override public GlobalConfiguration getValue() { GlobalConfigurationBuilder builder = new GlobalConfigurationBuilder(); ModuleLoader moduleLoader = this.loader.getValue(); builder.serialization().classResolver(ModularClassResolver.getInstance(moduleLoader)); ClassLoader loader; try { loader = (this.module != null) ? moduleLoader.loadModule(this.module).getClassLoader() : CacheContainerConfiguration.class.getClassLoader(); builder.classLoader(loader); int id = Ids.MAX_ID; for (SimpleExternalizer<?> externalizer: ServiceLoader.load(SimpleExternalizer.class, loader)) { InfinispanLogger.ROOT_LOGGER.debugf("Cache container %s will use an externalizer for %s", this.name, externalizer.getTargetClass().getName()); builder.serialization().addAdvancedExternalizer(id++, externalizer); } } catch (ModuleLoadException e) { throw new IllegalStateException(e); } builder.shutdown().hookBehavior(ShutdownHookBehavior.DONT_REGISTER); AuthorizationConfiguration authorization = (this.authorization != null) ? this.authorization.getValue() : null; GlobalAuthorizationConfigurationBuilder authorizationBuilder = builder.security().authorization(); if (authorization != null) { authorizationBuilder.enable(); if (authorization.getAuditLogger() != null) { try { authorizationBuilder.auditLogger(Class.forName(authorization.getAuditLogger(), true, loader).asSubclass(AuditLogger.class).newInstance()); } catch (Exception e) { throw new IllegalStateException(e); } } else { authorizationBuilder.auditLogger(new NullAuditLogger()); } if (authorization.getPrincipalMapper() != null) { try { authorizationBuilder.principalRoleMapper(Class.forName(authorization.getPrincipalMapper(), true, loader).asSubclass(PrincipalRoleMapper.class).newInstance()); } catch (Exception e) { throw new IllegalStateException(e); } } else { authorizationBuilder.principalRoleMapper(new ClusterRoleMapper()); } for(Entry<String, List<String>> role : authorization.getRoles().entrySet()) { GlobalRoleConfigurationBuilder roleBuilder = authorizationBuilder.role(role.getKey()); for(String perm : role.getValue()) { roleBuilder.permission(perm); } } } TransportConfiguration transport = (this.transport != null) ? this.transport.getValue() : null; if (transport != null) { org.infinispan.configuration.global.TransportConfigurationBuilder transportBuilder = builder.transport() .clusterName(this.name) .transport(new ChannelTransport(transport.getChannel(), transport.getChannelFactory())) .distributedSyncTimeout(transport.getLockTimeout()) ; // Topology is retrieved from the channel ProtocolStackConfiguration stack = transport.getChannelFactory().getProtocolStackConfiguration(); org.infinispan.server.jgroups.spi.TransportConfiguration.Topology topology = stack.getTransport().getTopology(); if (topology != null) { transportBuilder.siteId(topology.getSite()).rackId(topology.getRack()).machineId(topology.getMachine()); } transportBuilder.transportThreadPool().read(this.transportThreadPool.getValue()); transportBuilder.remoteCommandThreadPool().read(this.remoteCommandThreadPool.getValue()); RelayConfiguration relay = stack.getRelay(); if (relay != null) { builder.site().localSite(relay.getSiteName()); } } GlobalStateLocationConfiguration statePersistence = (this.globalStateLocation != null) ? this.globalStateLocation.getValue() : null; if (statePersistence != null) { GlobalStateConfigurationBuilder statePersistenceBuilder = builder.globalState().enable(); String persistentLocation = pathManager.getValue().resolveRelativePathEntry(statePersistence.getPersistencePath(), statePersistence.getPersistenceRelativeTo()); statePersistenceBuilder.persistentLocation(persistentLocation); String temporaryLocation = pathManager.getValue().resolveRelativePathEntry(statePersistence.getPersistencePath(), statePersistence.getPersistenceRelativeTo()); statePersistenceBuilder.temporaryLocation(temporaryLocation); } builder.asyncThreadPool().read(this.asyncOperationsThreadPool.getValue()); builder.expirationThreadPool().read(this.expirationThreadPool.getValue()); builder.listenerThreadPool().read(this.listenerThreadPool.getValue()); builder.stateTransferThreadPool().read(this.stateTransferThreadPool.getValue()); builder.persistenceThreadPool().read(this.persistenceThreadPool.getValue()); builder.replicationQueueThreadPool().read(this.replicationQueueThreadPool.getValue()); builder.globalJmxStatistics() .enabled(this.statisticsEnabled) .cacheManagerName(this.name) .mBeanServerLookup(new MBeanServerProvider(this.server.getValue())) .jmxDomain(CacheContainerServiceName.CACHE_CONTAINER.getServiceName(CacheServiceNameFactory.DEFAULT_CACHE).getParent().getCanonicalName()) .allowDuplicateDomains(true); builder.addModule(PrivateGlobalConfigurationBuilder.class).serverMode(true); return builder.build(); } public CacheContainerConfigurationBuilder setModule(ModuleIdentifier module) { this.module = module; return this; } public CacheContainerConfigurationBuilder setStatisticsEnabled(boolean statisticsEnabled) { this.statisticsEnabled = statisticsEnabled; return this; } public TransportConfigurationBuilder setTransport() { TransportConfigurationBuilder builder = new TransportConfigurationBuilder(this.name); this.transport = new InjectedValueDependency<>(builder, TransportConfiguration.class); return builder; } public AuthorizationConfigurationBuilder setAuthorization() { this.authorization = new AuthorizationConfigurationBuilder(); return this.authorization; } public GlobalStateLocationConfigurationBuilder setGlobalState() { this.globalStateLocation = new GlobalStateLocationConfigurationBuilder(); return this.globalStateLocation; } }