Package org.jboss.as.model

Source Code of org.jboss.as.model.ServerDeploymentStartStopHandler$AbstractDeploymentServiceTracker

/*
* 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.model;

import static org.jboss.as.deployment.attachment.VirtualFileAttachment.attachVirtualFile;

import java.io.Closeable;
import java.io.IOException;
import java.io.Serializable;
import java.util.jar.Manifest;

import org.jboss.as.deployment.DeploymentFailureListener;
import org.jboss.as.deployment.DeploymentService;
import org.jboss.as.deployment.ServerDeploymentRepository;
import org.jboss.as.deployment.attachment.ManifestAttachment;
import org.jboss.as.deployment.chain.DeploymentChain;
import org.jboss.as.deployment.chain.DeploymentChainProvider;
import org.jboss.as.deployment.module.MountHandle;
import org.jboss.as.deployment.unit.DeploymentUnitContext;
import org.jboss.as.deployment.unit.DeploymentUnitContextImpl;
import org.jboss.as.deployment.unit.DeploymentUnitProcessingException;
import org.jboss.logging.Logger;
import org.jboss.msc.service.AbstractServiceListener;
import org.jboss.msc.service.BatchBuilder;
import org.jboss.msc.service.BatchServiceBuilder;
import org.jboss.msc.service.ServiceActivatorContext;
import org.jboss.msc.service.ServiceActivatorContextImpl;
import org.jboss.msc.service.ServiceContainer;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceNotFoundException;
import org.jboss.msc.service.StartException;
import org.jboss.vfs.VFS;
import org.jboss.vfs.VFSUtils;
import org.jboss.vfs.VirtualFile;

/**
* Helper class that can handle the runtime aspects of deploying and undeploying
* on a server.
*
* @author Brian Stansberry
*/
public final class ServerDeploymentStartStopHandler implements Serializable {
    private static final long serialVersionUID = 4804538479425267270L;
    private static final Logger log = Logger.getLogger("org.jboss.as.deployment");


    public <P> void deploy(final String deploymentName, final String runtimeName, final byte[] deploymentHash, final ServiceContainer serviceContainer,
            final UpdateResultHandler<?, P> resultHandler, final P param) {
        try {
            BatchBuilder batchBuilder = serviceContainer.batchBuilder();
            deploy(deploymentName, runtimeName, deploymentHash, batchBuilder, serviceContainer, resultHandler, param);
            batchBuilder.install();
        }
        catch (Exception e) {
            resultHandler.handleFailure(e, param);
        }
    }

    public <P> void deploy(final String deploymentName, final String runtimeName, final byte[] deploymentHash,
            final BatchBuilder batchBuilder, final ServiceContainer serviceContainer,
            final UpdateResultHandler<?, P> resultHandler, final P param) {
        try {
            ServiceName deploymentServiceName = DeploymentService.getServiceName(deploymentName);
            // Add a listener so we can get ahold of the DeploymentService
            batchBuilder.addListener(new DeploymentServiceTracker<P>(deploymentServiceName, resultHandler, param));

            activate(deploymentName, runtimeName, deploymentHash, deploymentServiceName, new ServiceActivatorContextImpl(batchBuilder), serviceContainer);
        }
        catch (RuntimeException e) {
            resultHandler.handleFailure(e, param);
        }
    }

    public <P> void redeploy(final String deploymentName, final String runtimeName, final byte[] deploymentHash,
            final ServiceContainer serviceContainer, final UpdateResultHandler<?, P> resultHandler, final P param) {
        try {
            ServiceName deploymentServiceName = DeploymentService.getServiceName(deploymentName);
            @SuppressWarnings("unchecked")
            final ServiceController<DeploymentService> controller = (ServiceController<DeploymentService>) serviceContainer.getService(deploymentServiceName);
            if(controller != null && controller.getMode() != ServiceController.Mode.REMOVE) {
                RedeploymentServiceTracker tracker = new RedeploymentServiceTracker(deploymentName);
                controller.addListener(tracker);
                synchronized (tracker) {
                    controller.setMode(ServiceController.Mode.REMOVE);
                    try {
                        tracker.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        if (resultHandler != null) {
                            resultHandler.handleFailure(e, param);
                            return;
                        }
                    }
                }
            }

            deploy(deploymentName, runtimeName, deploymentHash, serviceContainer, resultHandler, param);
        }
        catch (RuntimeException e) {
            if (resultHandler != null) {
                resultHandler.handleFailure(e, param);
            }
        }
    }

    public <P> void undeploy(final String deploymentName, final ServiceContainer serviceContainer,
            final UpdateResultHandler<?, P> resultHandler, final P param) {
        try {
            ServiceName deploymentServiceName = DeploymentService.getServiceName(deploymentName);
            @SuppressWarnings("unchecked")
            final ServiceController<DeploymentService> controller = (ServiceController<DeploymentService>) serviceContainer.getService(deploymentServiceName);
            if(controller != null) {
                controller.addListener(new UndeploymentServiceTracker<P>(deploymentName, resultHandler, param));
                controller.setMode(ServiceController.Mode.REMOVE);
            }
            else if (resultHandler != null) {
                resultHandler.handleSuccess(null, param);
            }
        }
        catch (RuntimeException e) {
            if (resultHandler != null) {
                resultHandler.handleFailure(e, param);
            }
        }
    }

    private void activate(final String deploymentName, String runtimeName, final byte[] deploymentHash, final ServiceName deploymentServiceName, final ServiceActivatorContext context, final ServiceContainer serviceContainer) {
        log.infof("Activating deployment: %s", deploymentName);

        MountHandle handle = null;
        try {
            final ServerDeploymentRepository deploymentRepo = getDeploymentRepository(serviceContainer);

            // The mount point we will use for the repository file
            final VirtualFile deploymentRoot = VFS.getChild("content/" + runtimeName);

            // Mount virtual file
            try {
                Closeable mount = deploymentRepo.mountDeploymentContent(deploymentName, runtimeName, deploymentHash, deploymentRoot);
                handle = new MountHandle(mount);
            } catch (IOException e) {
                throw new RuntimeException("Failed to mount deployment archive", e);
            }

            final BatchBuilder batchBuilder = context.getBatchBuilder();
            // Create deployment service
            DeploymentService deploymentService = new DeploymentService(handle);
            BatchServiceBuilder<Void> serviceBuilder = batchBuilder.addService(deploymentServiceName, deploymentService);

            // Create a sub-batch for this deployment
            final BatchBuilder deploymentSubBatch = batchBuilder.subBatchBuilder();

            // Setup a batch level dependency on deployment service
            deploymentSubBatch.addDependency(deploymentServiceName);

            // Add a deployment failure listener to the batch
            deploymentSubBatch.addListener(new DeploymentFailureListener(deploymentServiceName));

            // Create the deployment unit context
            final DeploymentUnitContext deploymentUnitContext = new DeploymentUnitContextImpl(deploymentServiceName.getSimpleName(), deploymentSubBatch, serviceBuilder);
            attachVirtualFile(deploymentUnitContext, deploymentRoot);
            deploymentUnitContext.putAttachment(MountHandle.ATTACHMENT_KEY, handle);

            // Get the optional Manifest for this deployment
            try {
                Manifest manifest = VFSUtils.getManifest(deploymentRoot);
                if (manifest != null)
                    ManifestAttachment.attachManifest(deploymentUnitContext, manifest);
            } catch (IOException e) {
                throw new RuntimeException("Failed to get manifest for deployment " + deploymentRoot, e);
            }

            // Execute the deployment chain
            final DeploymentChainProvider deploymentChainProvider = DeploymentChainProvider.INSTANCE;
            final DeploymentChain deploymentChain = deploymentChainProvider.determineDeploymentChain(deploymentUnitContext);
            log.debugf("Executing deployment '%s' with chain: %s", deploymentName, deploymentChain);
            if(deploymentChain == null)
                throw new RuntimeException("Failed determine the deployment chain for deployment root: " + deploymentRoot);
            try {
                deploymentChain.processDeployment(deploymentUnitContext);
            } catch (DeploymentUnitProcessingException e) {
                throw new RuntimeException("Failed to process deployment chain.", e);
            }
        } catch(Throwable t) {
            VFSUtils.safeClose(handle);
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            }
            throw new RuntimeException("Failed to activate deployment unit " + deploymentName, t);
        }
    }

    private ServerDeploymentRepository getDeploymentRepository(ServiceContainer serviceContainer) throws ServiceNotFoundException {
        @SuppressWarnings("unchecked")
        ServiceController<ServerDeploymentRepository> serviceController = (ServiceController<ServerDeploymentRepository>) serviceContainer.getRequiredService(ServerDeploymentRepository.SERVICE_NAME);
        return serviceController.getValue();
    }

//    private static String getFullyQualifiedDeploymentPath(String name) {
//        final String fileName = name;
//        String path = System.getProperty("jboss.server.deploy.dir");
//        return (path.endsWith(File.separator)) ? path + fileName : path + File.separator + fileName;
//    }

    private abstract static class AbstractDeploymentServiceTracker<P> extends AbstractServiceListener<Object> {

        protected final UpdateResultHandler<?, P> resultHandler;
        protected final P param;

        protected AbstractDeploymentServiceTracker(final UpdateResultHandler<?, P> resultHandler,
                final P param) {
            this.resultHandler = resultHandler;
            this.param = param;
        }

        @Override
        public void serviceFailed(ServiceController<?> controller, StartException reason) {

            if (resultHandler != null && isCorrectService(controller)) {
                resultHandler.handleFailure(reason, param);
                // Ignore any further notifications
                controller.removeListener(this);
            }
        }

        protected void recordResult(ServiceController<? extends Object> controller) {
            resultHandler.handleSuccess(null, param);
            // Ignore any further notifications
            controller.removeListener(this);
        }

        protected abstract boolean isCorrectService(ServiceController<?> service);

    }

    private static class DeploymentServiceTracker<P> extends AbstractDeploymentServiceTracker<P> {

        private final ServiceName deploymentServiceName;

        private DeploymentServiceTracker(final ServiceName deploymentServiceName,
                final UpdateResultHandler<?, P> resultHandler, final P param) {
            super(resultHandler, param);
            assert deploymentServiceName != null : "deploymentServiceName is null";
            this.deploymentServiceName = deploymentServiceName;
        }

        @Override
        public void serviceStarted(ServiceController<?> controller) {
            if (resultHandler != null && isCorrectService(controller)) {
                recordResult(controller);
            }
        }

        @Override
        protected boolean isCorrectService(ServiceController<?> controller) {
            return deploymentServiceName.equals(controller.getName());
        }

    }

    private static class UndeploymentServiceTracker<P> extends AbstractDeploymentServiceTracker<P> {

        private final String deploymentName;

        private UndeploymentServiceTracker(final String deploymentName,
                final UpdateResultHandler<?, P> resultHandler, final P param) {
            super(resultHandler, param);
            this.deploymentName = deploymentName;
        }

        @Override
        public void serviceRemoved(ServiceController<?> controller) {
            if (resultHandler != null) {
                recordResult(controller);
            }
            log.infof("Undeployed %s", deploymentName);
        }

        @Override
        protected boolean isCorrectService(ServiceController<?> controller) {
            // We are only registered with a single service
            return true;
        }

    }

    private static class RedeploymentServiceTracker extends AbstractServiceListener<Object> {

        private final String deploymentName;

        RedeploymentServiceTracker(final String deploymentName) {
            this.deploymentName = deploymentName;
        }

        @Override
        public void serviceRemoved(ServiceController<?> controller) {
            synchronized (this) {
                notifyAll();
            }
            // Ignore any further notifications
            controller.removeListener(this);
            log.infof("Undeployed %s", deploymentName);
        }

    }
}
TOP

Related Classes of org.jboss.as.model.ServerDeploymentStartStopHandler$AbstractDeploymentServiceTracker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.