/* * JBoss, Home of Professional Open Source. * Copyright 2010, 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.deployment; import java.util.HashSet; import java.util.Set; import org.jboss.as.controller.capability.CapabilityServiceSupport; import org.jboss.as.controller.registry.ImmutableManagementResourceRegistration; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.Resource; import org.jboss.as.server.logging.ServerLogger; import org.jboss.as.server.services.security.AbstractVaultReader; import org.jboss.msc.inject.Injector; 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.ServiceRegistry; import org.jboss.msc.service.ServiceTarget; import org.jboss.msc.service.StabilityMonitor; import org.jboss.msc.service.StartContext; import org.jboss.msc.service.StartException; import org.jboss.msc.service.StopContext; import org.jboss.msc.value.InjectedValue; /** * Abstract service responsible for managing the life-cycle of a {@link DeploymentUnit}. * * @author John Bailey * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a> */ public abstract class AbstractDeploymentUnitService implements Service<DeploymentUnit> { private static final String FIRST_PHASE_NAME = Phase.values()[0].name(); final ImmutableManagementResourceRegistration registration; final ManagementResourceRegistration mutableRegistration; final Resource resource; final CapabilityServiceSupport capabilityServiceSupport; final AbstractVaultReader vaultReader; private final InjectedValue<DeployerChains> deployerChainsInjector = new InjectedValue<DeployerChains>(); private DeploymentUnit deploymentUnit; private volatile StabilityMonitor monitor; AbstractDeploymentUnitService(final ImmutableManagementResourceRegistration registration, final ManagementResourceRegistration mutableRegistration, final Resource resource, final CapabilityServiceSupport capabilityServiceSupport, final AbstractVaultReader vaultReader) { this.mutableRegistration = mutableRegistration; this.capabilityServiceSupport = capabilityServiceSupport; this.registration = registration; this.vaultReader = vaultReader; this.resource = resource; } public synchronized void start(final StartContext context) throws StartException { ServiceTarget target = context.getChildTarget(); final String deploymentName = context.getController().getName().getSimpleName(); monitor = new StabilityMonitor(); monitor.addController(context.getController()); // Create the first phase deployer deploymentUnit = createAndInitializeDeploymentUnit(context.getController().getServiceContainer()); final String managementName = deploymentUnit.getAttachment(Attachments.MANAGEMENT_NAME); if (deploymentUnit.getParent()==null) { ServerLogger.DEPLOYMENT_LOGGER.startingDeployment(managementName, deploymentName); } else { ServerLogger.DEPLOYMENT_LOGGER.startingSubDeployment(deploymentName); } final ServiceName serviceName = deploymentUnit.getServiceName().append(FIRST_PHASE_NAME); final Phase firstPhase = Phase.values()[0]; final DeploymentUnitPhaseService<?> phaseService = DeploymentUnitPhaseService.create(deploymentUnit, firstPhase); final ServiceBuilder<?> phaseServiceBuilder = target.addService(serviceName, phaseService); phaseServiceBuilder.addDependency(Services.JBOSS_DEPLOYMENT_CHAINS, DeployerChains.class, phaseService.getDeployerChainsInjector()); phaseServiceBuilder.install(); } /** * Template method required for implementations to create and fully initialize a deployment unit instance. This method * should be used to attach any initial deployment unit attachments required for the deployment type. * * @param registry The service registry * @return An initialized DeploymentUnit instance */ protected abstract DeploymentUnit createAndInitializeDeploymentUnit(final ServiceRegistry registry); public synchronized void stop(final StopContext context) { final String deploymentName = context.getController().getName().getSimpleName(); final String managementName = deploymentUnit.getAttachment(Attachments.MANAGEMENT_NAME); if (deploymentUnit.getParent()==null) { ServerLogger.DEPLOYMENT_LOGGER.stoppedDeployment(managementName, deploymentName, (int) (context.getElapsedTime() / 1000000L)); } else { ServerLogger.DEPLOYMENT_LOGGER.stoppedSubDeployment(deploymentName, (int) (context.getElapsedTime() / 1000000L)); } //clear up all attachments SimpleAttachable attachable = (SimpleAttachable)deploymentUnit; attachable.attachmentKeys().forEach(key -> deploymentUnit.removeAttachment(key)); deploymentUnit = null; monitor.removeController(context.getController()); monitor = null; DeploymentResourceSupport.cleanup(resource); } public synchronized DeploymentUnit getValue() throws IllegalStateException, IllegalArgumentException { return deploymentUnit; } public DeploymentStatus getStatus() { StabilityMonitor monitor = this.monitor; if (monitor == null) { return DeploymentStatus.STOPPED; } final Set<ServiceController<?>> problems = new HashSet<ServiceController<?>>(); try { monitor.awaitStability(problems, problems); } catch (final InterruptedException e) { // ignore } return problems.isEmpty() ? DeploymentStatus.OK : DeploymentStatus.FAILED; } Injector<DeployerChains> getDeployerChainsInjector() { return deployerChainsInjector; } public enum DeploymentStatus { NEW, OK, FAILED, STOPPED } }