/* * 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.server; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.TreeSet; import org.jboss.as.controller.ControlledProcessState; import org.jboss.as.controller.RunningModeControl; import org.jboss.as.repository.ContentRepository; import org.jboss.as.selfcontained.SelfContainedContentRepository; import org.jboss.as.server.deployment.ContentCleanerService; import org.jboss.as.server.deployment.DeploymentMountProvider; import org.jboss.as.server.logging.ServerLogger; import org.jboss.as.server.mgmt.domain.RemoteFileRepositoryService; import org.jboss.as.server.moduleservice.ExternalModuleService; import org.jboss.as.server.moduleservice.ModuleIndexService; import org.jboss.as.server.moduleservice.ServiceModuleLoader; import org.jboss.as.server.services.security.AbstractVaultReader; import org.jboss.as.server.suspend.SuspendController; import org.jboss.as.version.ProductConfig; import org.jboss.msc.service.Service; import org.jboss.msc.service.ServiceActivator; import org.jboss.msc.service.ServiceActivatorContext; import org.jboss.msc.service.ServiceContainer; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceRegistry; import org.jboss.msc.service.ServiceTarget; import org.jboss.msc.service.StartContext; import org.jboss.msc.service.StartException; import org.jboss.msc.service.StopContext; import org.jboss.msc.service.ValueService; import org.jboss.msc.value.ImmediateValue; import org.jboss.msc.value.Value; import org.jboss.threads.AsyncFuture; /** * The root service for an Application Server process. * * @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a> */ final class ApplicationServerService implements Service<AsyncFuture<ServiceContainer>> { private final List<ServiceActivator> extraServices; private final Bootstrap.Configuration configuration; private final RunningModeControl runningModeControl; private final ControlledProcessState processState; private final SuspendController suspendController; private final boolean standalone; private final boolean selfContained; private volatile FutureServiceContainer futureContainer; private volatile long startTime; ApplicationServerService(final List<ServiceActivator> extraServices, final Bootstrap.Configuration configuration, final ControlledProcessState processState, final SuspendController suspendController) { this.extraServices = extraServices; this.configuration = configuration; runningModeControl = configuration.getRunningModeControl(); startTime = configuration.getStartTime(); standalone = configuration.getServerEnvironment().isStandalone(); selfContained = configuration.getServerEnvironment().isSelfContained(); this.processState = processState; this.suspendController = suspendController; } @Override public synchronized void start(final StartContext context) throws StartException { //Moved to AbstractControllerService.start() //processState.setStarting(); final Bootstrap.Configuration configuration = this.configuration; final ServerEnvironment serverEnvironment = configuration.getServerEnvironment(); final ProductConfig config = serverEnvironment.getProductConfig(); final String prettyVersion = config.getPrettyVersionString(); ServerLogger.AS_ROOT_LOGGER.serverStarting(prettyVersion); if (System.getSecurityManager() != null) { ServerLogger.AS_ROOT_LOGGER.securityManagerEnabled(); } if (ServerLogger.CONFIG_LOGGER.isDebugEnabled()) { final Properties properties = System.getProperties(); final StringBuilder b = new StringBuilder(8192); b.append(ServerLogger.ROOT_LOGGER.configuredSystemPropertiesLabel()); for (String property : new TreeSet<String>(properties.stringPropertyNames())) { String propVal = property.toLowerCase(Locale.getDefault()).contains("password") ? "<redacted>" : properties.getProperty(property, "<undefined>"); b.append("\n\t").append(property).append(" = ").append(propVal); } ServerLogger.CONFIG_LOGGER.debug(b); ServerLogger.CONFIG_LOGGER.debugf(ServerLogger.ROOT_LOGGER.vmArgumentsLabel(getVMArguments())); if (ServerLogger.CONFIG_LOGGER.isTraceEnabled()) { b.setLength(0); final Map<String,String> env = System.getenv(); b.append(ServerLogger.ROOT_LOGGER.configuredSystemEnvironmentLabel()); for (String key : new TreeSet<String>(env.keySet())) { String envVal = key.toLowerCase(Locale.getDefault()).contains("password") ? "<redacted>" : env.get(key); b.append("\n\t").append(key).append(" = ").append(envVal); } ServerLogger.CONFIG_LOGGER.trace(b); } } final ServiceTarget serviceTarget = context.getChildTarget(); final ServiceController<?> myController = context.getController(); final ServiceContainer container = myController.getServiceContainer(); futureContainer = new FutureServiceContainer(); long startTime = this.startTime; if (startTime == -1) { startTime = System.currentTimeMillis(); } else { this.startTime = -1; } CurrentServiceContainer.setServiceContainer(context.getController().getServiceContainer()); final BootstrapListener bootstrapListener = new BootstrapListener(container, startTime, serviceTarget, futureContainer, prettyVersion, serverEnvironment.getServerTempDir()); bootstrapListener.getStabilityMonitor().addController(myController); // Install either a local or remote content repository if(standalone) { if ( selfContained ) { SelfContainedContentRepository.addService(serviceTarget); } else { ContentRepository.Factory.addService(serviceTarget, serverEnvironment.getServerContentDir(), serverEnvironment.getServerTempDir()); } } else { RemoteFileRepositoryService.addService(serviceTarget, serverEnvironment.getServerContentDir(), serverEnvironment.getServerTempDir()); } ContentCleanerService.addService(serviceTarget, ServerService.JBOSS_SERVER_SCHEDULED_EXECUTOR); DeploymentMountProvider.Factory.addService(serviceTarget); ServiceModuleLoader.addService(serviceTarget, configuration); ExternalModuleService.addService(serviceTarget); ModuleIndexService.addService(serviceTarget); final AbstractVaultReader vaultReader = loadVaultReaderService(); ServerLogger.AS_ROOT_LOGGER.debugf("Using VaultReader %s", vaultReader); ServerService.addService(serviceTarget, configuration, processState, bootstrapListener, runningModeControl, vaultReader, configuration.getAuditLogger(), configuration.getAuthorizer(), configuration.getSecurityIdentitySupplier(), suspendController); final ServiceActivatorContext serviceActivatorContext = new ServiceActivatorContext() { @Override public ServiceTarget getServiceTarget() { return serviceTarget; } @Override public ServiceRegistry getServiceRegistry() { return container; } }; for(ServiceActivator activator : extraServices) { activator.activate(serviceActivatorContext); } // TODO: decide the fate of these // Add server environment ServerEnvironmentService.addService(serverEnvironment, serviceTarget); //Add server path manager service ServerPathManagerService serverPathManagerService = new ServerPathManagerService(); ServerPathManagerService.addService(serviceTarget, serverPathManagerService, serverEnvironment); // Add product config service final Value<ProductConfig> productConfigValue = new ImmediateValue<ProductConfig>(config); serviceTarget.addService(Services.JBOSS_PRODUCT_CONFIG_SERVICE, new ValueService<ProductConfig>(productConfigValue)) .setInitialMode(ServiceController.Mode.ACTIVE) .install(); // BES 2011/06/11 -- moved this to AbstractControllerService.start() // processState.setRunning(); if (ServerLogger.AS_ROOT_LOGGER.isDebugEnabled()) { final long nanos = context.getElapsedTime(); ServerLogger.AS_ROOT_LOGGER.debugf(prettyVersion + " root service started in %d.%06d ms", Long.valueOf(nanos / 1000000L), Long.valueOf(nanos % 1000000L)); } } @Override public synchronized void stop(final StopContext context) { //Moved to AbstractControllerService.stop() //processState.setStopping(); CurrentServiceContainer.setServiceContainer(null); String prettyVersion = configuration.getServerEnvironment().getProductConfig().getPrettyVersionString(); ServerLogger.AS_ROOT_LOGGER.serverStopped(prettyVersion, Integer.valueOf((int) (context.getElapsedTime() / 1000000L))); BootstrapListener.deleteStartupMarker(configuration.getServerEnvironment().getServerTempDir()); } @Override public AsyncFuture<ServiceContainer> getValue() throws IllegalStateException, IllegalArgumentException { return futureContainer; } private String getVMArguments() { final StringBuilder result = new StringBuilder(1024); final RuntimeMXBean rmBean = ManagementFactory.getRuntimeMXBean(); final List<String> inputArguments = rmBean.getInputArguments(); for (String arg : inputArguments) { result.append(arg).append(" "); } return result.toString(); } private static AbstractVaultReader loadVaultReaderService() { final ServiceLoader<AbstractVaultReader> serviceLoader = ServiceLoader.load(AbstractVaultReader.class, ApplicationServerService.class.getClassLoader()); final Iterator<AbstractVaultReader> it = serviceLoader.iterator(); // TODO WFCORE-114 get rid of catching/suppressing errors once we have a complete impl in WFCORE ServiceConfigurationError sce = null; try { while (it.hasNext()) { return it.next(); } } catch (ServiceConfigurationError e) { sce = e; } if (sce != null) { ServerLogger.AS_ROOT_LOGGER.debugf(sce, "Cannot instantiate provider of service %s", AbstractVaultReader.class); } return null; } }