All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.deployment.admin.DeployCommand Maven / Gradle / Ivy

/*
 * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.deployment.admin;

import java.net.URI;
import java.net.URISyntaxException;
import com.sun.enterprise.config.serverbeans.*;
import com.sun.enterprise.deploy.shared.ArchiveFactory;
import com.sun.enterprise.deploy.shared.FileArchive;
import com.sun.enterprise.util.LocalStringManagerImpl;

import org.glassfish.admin.payload.PayloadImpl;
import org.glassfish.api.ActionReport;
import org.glassfish.api.I18n;
import org.glassfish.api.admin.AdminCommand;
import org.glassfish.api.admin.AdminCommandContext;
import org.glassfish.api.admin.CommandRunner;
import org.glassfish.api.admin.ExecuteOn;
import org.glassfish.api.admin.RuntimeType;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.api.deployment.DeployCommandParameters;
import org.glassfish.api.deployment.DeploymentContext;
import org.glassfish.api.deployment.archive.ArchiveHandler;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.deployment.common.*;
import org.glassfish.internal.data.ApplicationInfo;
import org.glassfish.internal.deployment.*;
import org.glassfish.config.support.TargetType;
import org.glassfish.config.support.CommandTarget;
import org.jvnet.hk2.annotations.Contract;
import jakarta.inject.Inject;

import org.jvnet.hk2.annotations.Service;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.api.ServiceLocator;
import org.jvnet.hk2.config.Transaction;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.api.ActionReport.ExitCode;
import org.glassfish.api.admin.AccessRequired;
import org.glassfish.api.admin.AccessRequired.AccessCheck;
import org.glassfish.api.admin.AdminCommandSecurity;
import org.glassfish.api.admin.ParameterMap;
import org.glassfish.api.admin.Payload;
import org.glassfish.api.admin.RestEndpoint;
import org.glassfish.api.admin.RestEndpoints;
import org.glassfish.api.admin.RestParam;
import org.glassfish.api.event.EventListener;
import org.glassfish.api.event.Events;
import org.glassfish.deployment.versioning.VersioningSyntaxException;
import org.glassfish.deployment.versioning.VersioningUtils;

import org.glassfish.deployment.versioning.VersioningService;


/**
 * Deploy command
 *
 * @author Jerome Dochez
 */
@Service(name="deploy")
@I18n("deploy.command")
@PerLookup
@ExecuteOn(value={RuntimeType.DAS})
@TargetType(value={CommandTarget.DOMAIN, CommandTarget.DAS, CommandTarget.STANDALONE_INSTANCE, CommandTarget.CLUSTER})
@RestEndpoints({
    @RestEndpoint(configBean=Applications.class,opType=RestEndpoint.OpType.POST, path="deploy"),
    @RestEndpoint(configBean=Cluster.class,opType=RestEndpoint.OpType.POST, path="deploy", params={
        @RestParam(name="target", value="$parent")
    }),
    @RestEndpoint(configBean=Server.class,opType=RestEndpoint.OpType.POST, path="deploy", params={
        @RestParam(name="target", value="$parent")
    })
})
public class DeployCommand extends DeployCommandParameters implements AdminCommand, EventListener,
        AdminCommandSecurity.Preauthorization, AdminCommandSecurity.AccessCheckProvider {

    final private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(DeployCommand.class);

    @Inject
    Applications apps;

    @Inject
    ServerEnvironment env;

    @Inject
    ServiceLocator habitat;

    @Inject
    CommandRunner commandRunner;

    @Inject
    Deployment deployment;

    @Inject
    SnifferManager snifferManager;

    @Inject
    ArchiveFactory archiveFactory;

    @Inject
    Domain domain;

    @Inject
    Events events;

    @Inject
    VersioningService versioningService;

    private File safeCopyOfApp = null;
    private File safeCopyOfDeploymentPlan = null;
    private File safeCopyOfAltDD = null;
    private File safeCopyOfRuntimeAltDD = null;
    private File originalPathValue;
    private List previousTargets = new ArrayList();
    private Properties previousVirtualServers = new Properties();
    private Properties previousEnabledAttributes = new Properties();
    private Logger logger;
    private ExtendedDeploymentContext initialContext;
    private ExtendedDeploymentContext deploymentContext;
    private ArchiveHandler archiveHandler;
    private DeploymentTracing tracing;
    private File expansionDir;
    private ReadableArchive archive;
    private ActionReport report;
    private DeploymentTracing timing;
    private transient DeployCommandSupplementalInfo suppInfo;

    public DeployCommand() {
        origin = Origin.deploy;
    }

    @Override
    public boolean preAuthorization(AdminCommandContext context) {
        events.register(this);

      suppInfo =
              new DeployCommandSupplementalInfo();
      context.getActionReport().
              setResultType(DeployCommandSupplementalInfo.class, suppInfo);

          timing = new DeploymentTracing();
          tracing=null;
          if (System.getProperty("org.glassfish.deployment.trace")!=null) {
            tracing = new DeploymentTracing();
          }

        report = context.getActionReport();
        logger = context.getLogger();

        originalPathValue = path;
        if (!path.exists()) {
            report.setMessage(localStrings.getLocalString("fnf","File not found", path.getAbsolutePath()));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            return false;
        }
        if (!path.canRead()) {
            report.setMessage(localStrings.getLocalString("fnr","File {0} does not have read permission", path.getAbsolutePath()));
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            return false;
        }

        if (snifferManager.hasNoSniffers()) {
            String msg = localStrings.getLocalString("nocontainer", "No container services registered, done...");
            report.failure(logger,msg);
            return false;
        }


        try {
            archive = archiveFactory.openArchive(path, this);
            if (tracing!=null) {
                tracing.addMark(DeploymentTracing.Mark.ARCHIVE_OPENED);
            }
        } catch (IOException e) {
            final String msg = localStrings.getLocalString("deploy.errOpeningArtifact",
                    "deploy.errOpeningArtifact", path.getAbsolutePath());
            if (logReportedErrors) {
                report.failure(logger, msg, e);
            } else {
                report.setMessage(msg + path.getAbsolutePath() + e.toString());
                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            }
            return false;
        }

        if (altdd != null) {
            archive.addArchiveMetaData(DeploymentProperties.ALT_DD, altdd);
        }

        if (runtimealtdd != null) {
            archive.addArchiveMetaData(DeploymentProperties.RUNTIME_ALT_DD,
                runtimealtdd);
        }

        expansionDir=null;
        deploymentContext = null;
        try {

            deployment.validateSpecifiedTarget(target);

            archiveHandler = deployment.getArchiveHandler(archive, type);
            if (tracing!=null) {
                tracing.addMark(DeploymentTracing.Mark.ARCHIVE_HANDLER_OBTAINED);
            }
            if (archiveHandler==null) {
                report.failure(logger,localStrings.getLocalString("deploy.unknownarchivetype","Archive type of {0} was not recognized",path));
                return false;
            }

            // create an initial  context
            initialContext = new DeploymentContextImpl(report, archive, this, env);
            initialContext.setArchiveHandler(archiveHandler);

            if (tracing!=null) {
                initialContext.addModuleMetaData(tracing);
                tracing.addMark(DeploymentTracing.Mark.INITIAL_CONTEXT_CREATED);
            }
            events.send(new Event(Deployment.INITIAL_CONTEXT_CREATED, initialContext), false);
            if (name==null) {
                name = archiveHandler.getDefaultApplicationName(initialContext.getSource(), initialContext);
            } else {
                DeploymentUtils.validateApplicationName(name);
            }
            if (tracing!=null) {
                tracing.addMark(DeploymentTracing.Mark.APPNAME_DETERMINED);
            }

            boolean isUntagged = VersioningUtils.isUntagged(name);
            // no GlassFish versioning support for OSGi budles
            if ( name != null && !isUntagged && type != null && type.equals("osgi") ) {
                ActionReport.MessagePart msgPart = context.getActionReport().getTopMessagePart();
                msgPart.setChildrenType("WARNING");
                ActionReport.MessagePart childPart = msgPart.addChild();
                childPart.setMessage(VersioningUtils.LOCALSTRINGS.getLocalString(
                        "versioning.deployment.osgi.warning",
                        "OSGi bundles will not use the GlassFish versioning, any version information embedded as part of the name option will be ignored"));
                name = VersioningUtils.getUntaggedName(name);
            }

            // if no version information embedded as part of application name
            // we try to retrieve the version-identifier element's value from DD
            if ( isUntagged ){
                String versionIdentifier = archiveHandler.getVersionIdentifier(initialContext.getSource());

                if ( versionIdentifier != null && !versionIdentifier.isEmpty() ) {
                  StringBuilder sb = new StringBuilder(name).
                          append(VersioningUtils.EXPRESSION_SEPARATOR).
                          append(versionIdentifier);
                  name = sb.toString();
                }
            }

            if (target == null) {
                target = deployment.getDefaultTarget(name, origin, _classicstyle);
            }

            boolean isRegistered = deployment.isRegistered(name);
            isredeploy = isRegistered && force;
            return true;
        } catch (Exception ex) {
            events.unregister(this);
            if (initialContext != null && initialContext.getSource() != null) {
                try {
                  initialContext.getSource().close();
                } catch (IOException ioex) {
                    throw new RuntimeException(ioex);
                }
            }
            throw new RuntimeException(ex);
        }
    }


    @Override
    public Collection getAccessChecks() {
        final List accessChecks = new ArrayList();
        accessChecks.add(new AccessCheck(DeploymentCommandUtils.getResourceNameForApps(domain), "create"));
        accessChecks.add(new AccessCheck(DeploymentCommandUtils.getTargetResourceNameForNewAppRef(domain, target), "create"));

        /*
         * If this app is already deployed then this operation also represents
         * an undeployment - a delete - of that app.
         */
        if (isredeploy) {
            final String appResource = DeploymentCommandUtils.getResourceNameForNewApp(domain, name);
            accessChecks.add(new AccessCheck(appResource, "delete"));
            final String appRefResource = DeploymentCommandUtils.getTargetResourceNameForNewAppRef(domain, target, name);
            accessChecks.add(new AccessCheck(appRefResource, "delete"));
        }

        return accessChecks;
    }

    /**
     * Entry point from the framework into the command execution
     * @param context context for the command.
     */
    @Override
    public void execute(AdminCommandContext context) {
        try {
          // needs to be fixed in hk2, we don't generate the right innerclass index. it should use $
            Collection interceptors = habitat.getAllServices(Interceptor.class);
            if (interceptors!=null) {
                for (Interceptor interceptor : interceptors) {
                    interceptor.intercept(this, initialContext);
                }
            }


            deployment.validateDeploymentTarget(target, name, isredeploy);
            if (tracing!=null) {
                tracing.addMark(DeploymentTracing.Mark.TARGET_VALIDATED);
            }

            ActionReport.MessagePart part = report.getTopMessagePart();
            part.addProperty(DeploymentProperties.NAME, name);

            ApplicationConfigInfo savedAppConfig =
                    new ApplicationConfigInfo(apps.getModule(Application.class, name));
            Properties undeployProps = handleRedeploy(name, report, context);
            if (enabled == null) {
                enabled = Boolean.TRUE;
            }

            // clean up any left over repository files
            if ( ! keepreposdir.booleanValue()) {
                final File reposDir = new File(env.getApplicationRepositoryPath(), VersioningUtils.getRepositoryName(name));
                if (reposDir.exists()) {
                    for (int i=0 ; i
     * We rename any uploaded files from the temp directory to the permanent
     * place, and we copy any archive files that were not uploaded.  This
     * prevents any confusion that could result if the developer modified the
     * archive file - changing its lastModified value - before redeploying it.
     *
     * @param deploymentContext
     * @param logger logger
     * @throws IOException
     */
    private void moveAppFilesToPermanentLocation(
            final ExtendedDeploymentContext deploymentContext,
            final Logger logger) throws IOException {
        final File finalUploadDir = deploymentContext.getAppInternalDir();
        final File finalAltDDDir = deploymentContext.getAppAltDDDir();
        if ( ! finalUploadDir.mkdirs()) {
            logger.log(Level.FINE," Attempting to create upload directory {0} was reported as failed; attempting to continue",
                    new Object[] {finalUploadDir.getAbsolutePath()});
        }
        safeCopyOfApp = DeploymentCommandUtils.renameUploadedFileOrCopyInPlaceFile( finalUploadDir, originalPathValue, logger, env);
        safeCopyOfDeploymentPlan = DeploymentCommandUtils.renameUploadedFileOrCopyInPlaceFile( finalUploadDir, deploymentplan, logger, env);
        safeCopyOfAltDD = DeploymentCommandUtils.renameUploadedFileOrCopyInPlaceFile( finalAltDDDir, altdd, logger, env);
        safeCopyOfRuntimeAltDD = DeploymentCommandUtils.renameUploadedFileOrCopyInPlaceFile( finalAltDDDir, runtimealtdd, logger, env);
    }

    private void recordFileLocations(
            final Properties appProps) throws URISyntaxException {
        /*
         * Setting the properties in the appProps now will cause them to be
         * stored in the domain.xml elements along with other properties when
         * the entire config is saved.
         */
        if (safeCopyOfApp != null) {
            appProps.setProperty(Application.APP_LOCATION_PROP_NAME,
                    DeploymentUtils.relativizeWithinDomainIfPossible(
                    safeCopyOfApp.toURI()));
        }
        if (safeCopyOfDeploymentPlan != null) {
                appProps.setProperty(Application.DEPLOYMENT_PLAN_LOCATION_PROP_NAME,
                        DeploymentUtils.relativizeWithinDomainIfPossible(
                        safeCopyOfDeploymentPlan.toURI()));
        }
        if (safeCopyOfAltDD != null) {
                appProps.setProperty(Application.ALT_DD_LOCATION_PROP_NAME,
                        DeploymentUtils.relativizeWithinDomainIfPossible(
                        safeCopyOfAltDD.toURI()));
        }
        if (safeCopyOfRuntimeAltDD != null) {
                appProps.setProperty(
                        Application.RUNTIME_ALT_DD_LOCATION_PROP_NAME,
                        DeploymentUtils.relativizeWithinDomainIfPossible(
                        safeCopyOfRuntimeAltDD.toURI()));
        }
    }

    /**
     *  Check if the application is deployed or not.
     *  If force option is true and appInfo is not null, then undeploy
     *  the application and return false.  This will force deployment
     *  if there's already a running application deployed.
     *
     *  @param name application name
     *  @param report ActionReport, report object to send back to client.
     * @return context properties that might have been set by the deployers
     * while undeploying the application
     *
     */
    private Properties handleRedeploy(final String name, final ActionReport report, final AdminCommandContext context)
        throws Exception {
        if (isredeploy)
        {
            //preserve settings first before undeploy
            Application app = apps.getModule(Application.class, name);
            if (app.isLifecycleModule()){
                throw new IllegalArgumentException(localStrings.getLocalString("lifecyclemodule_withsamename_exists", "Lifecycle module with same name {0} already exists, please pick a different name for the application. ", name));
            }

            // we save some of the old registration information in our deployment parameters
            settingsFromDomainXML(app);

            //if application is already deployed and force=true,
            //then undeploy the application first.

            // Use ParameterMap till we have a better way
            // to invoke a command on both DAS and instance with the
            // replication framework
            final ParameterMap parameters = new ParameterMap();
            parameters.add("DEFAULT", name);
            parameters.add(DeploymentProperties.TARGET, target);
            parameters.add(DeploymentProperties.KEEP_REPOSITORY_DIRECTORY, keepreposdir.toString());
            parameters.add(DeploymentProperties.IS_REDEPLOY, isredeploy.toString());
            if (dropandcreatetables != null) {
                parameters.add(DeploymentProperties.DROP_TABLES, dropandcreatetables.toString());
            }
            parameters.add(DeploymentProperties.IGNORE_CASCADE, force.toString());
            if (keepstate != null) {
                parameters.add(DeploymentProperties.KEEP_STATE, keepstate.toString());
            }

            ActionReport subReport = report.addSubActionsReport();
            subReport.setExtraProperties(new Properties());

            List propertyNames = new ArrayList();
            propertyNames.add(DeploymentProperties.KEEP_SESSIONS);
            propertyNames.add(DeploymentProperties.PRESERVE_APP_SCOPED_RESOURCES);
            populatePropertiesToParameterMap(parameters, propertyNames);

            CommandRunner.CommandInvocation inv = commandRunner.getCommandInvocation("undeploy", subReport,
                    context.getSubject());

            inv.parameters(parameters).execute();
            return subReport.getExtraProperties();
        }
        return null;
    }

    private void populatePropertiesToParameterMap(ParameterMap parameters, List propertyNamesList) {

        Properties props = new Properties();
        if (properties != null) {
            for (String propertyName : propertyNamesList) {
                if (properties.containsKey(propertyName)) {
                    props.put(propertyName, properties.getProperty(propertyName));
                }
            }
        }
        parameters.add("properties", DeploymentUtils.propertiesValue(props, ':'));
    }

    /**
     * Places into the outgoing payload the downloadable artifacts for an application.
     * @param context the admin command context for the command requesting the artifacts download
     * @param app the application of interest
     * @param targetLocalDir the client-specified local directory to receive the downloaded files
     */
    public static void retrieveArtifacts(final AdminCommandContext context,
            final Application app,
            final String targetLocalDir) {
        retrieveArtifacts(context, app, targetLocalDir, true);
    }

    /**
     * Places into the outgoing payload the downloadable artifacts for an application.
     * @param context the admin command context for the command currently running
     * @param app the application of interest
     * @param targetLocalDir the client-specified local directory to receive the downloaded files
     * @param reportErrorsInTopReport whether to include error indications in the report's top-level
     */
    public static void retrieveArtifacts(final AdminCommandContext context,
            final Application app,
            final String targetLocalDir,
            final boolean reportErrorsInTopReport) {
        retrieveArtifacts(context,
                DeploymentUtils.downloadableArtifacts(app).getArtifacts(),
                targetLocalDir,
                reportErrorsInTopReport,
                app.getName());
    }

    private static void retrieveArtifacts(final AdminCommandContext context,
            final Collection artifactInfo,
            final String targetLocalDir,
            final boolean reportErrorsInTopReport,
            final String appname) {

        if (artifactInfo.isEmpty()) {
            final ActionReport report = context.getActionReport();
            final ActionReport subReport = report.addSubActionsReport();
            subReport.setMessage(localStrings.getLocalString(
                DeployCommand.class,
                "get-client-stubs.noStubApp",
                "There are no files to retrieve for application {0}",
            new Object[] {appname}));
            subReport.setActionExitCode(ExitCode.SUCCESS);
            return;
        }

        Logger logger = context.getLogger();
        FileOutputStream targetStream = null;
        try {
            Payload.Outbound outboundPayload = context.getOutboundPayload();
            // GLASSFISH-17554: pass to DownloadServlet
            boolean retrieveArtifacts = false;
            if (outboundPayload == null) {
                outboundPayload = PayloadImpl.Outbound.newInstance();
                retrieveArtifacts = true;
            }

            Properties props = new Properties();
            /*
             * file-xfer-root is used as a URI, so convert backslashes.
             */
            props.setProperty("file-xfer-root", targetLocalDir.replace('\\', '/'));
            for (Artifacts.FullAndPartURIs uriPair : artifactInfo) {
                if(logger.isLoggable(Level.FINE)) {
                    logger.log(Level.FINE, "About to download artifact {0}", uriPair.getFull());
                }
                outboundPayload.attachFile("application/octet-stream",
                        uriPair.getPart(),"files",props,
                        new File(uriPair.getFull().getSchemeSpecificPart()));
            }
            if (retrieveArtifacts) {
                File targetLocalFile = new File(targetLocalDir); // CAUTION: file instead of dir
                if (targetLocalFile.exists()) {
                    final String msg = localStrings.getLocalString("download.errFileExists",
                            "Unable to generate files. File [{0}] already exists.", targetLocalFile.getAbsolutePath());
                    throw new Exception(msg);
                }

                if (!targetLocalFile.getParentFile().exists()) {
                    final String msg = localStrings.getLocalString("download.errParentFileMissing",
                            "Unable to generate files. Directory [{0}] does not exist.", targetLocalFile.getParent());
                    throw new Exception(msg);
                }
                targetStream = new FileOutputStream(targetLocalFile);
                outboundPayload.writeTo(targetStream);
                targetStream.flush();
            }
        } catch (Exception e) {
            handleRetrieveException(e, context, reportErrorsInTopReport);
        } finally {
            if (targetStream != null) {
                try {
                    targetStream.close();
                } catch (IOException ex) {
                    handleRetrieveException(ex, context, reportErrorsInTopReport);
                }
            }
        }
    }

    private static void handleRetrieveException(final Exception e,
            final AdminCommandContext context, final boolean reportErrorsInTopReport) {
        final String errorMsg = localStrings.getLocalString(
                    "download.errDownloading", "Error while downloading generated files");
        final Logger logger = context.getLogger();
        logger.log(Level.SEVERE, errorMsg, e);
        ActionReport report = context.getActionReport();
        if ( ! reportErrorsInTopReport) {
            report = report.addSubActionsReport();
            report.setActionExitCode(ExitCode.WARNING);
        } else {
            report.setActionExitCode(ExitCode.FAILURE);
        }
        report.setMessage(errorMsg);
        report.setFailureCause(e);
    }


    /**
     *  Get settings from domain.xml and preserve the values.
     *  This is a private api and its invoked when --force=true and if the app is registered.
     *
     *  @param app is the registration information about the previously deployed application
     *
     */
    private void settingsFromDomainXML(Application app) {
            //if name is null then cannot get the application's setting from domain.xml
        if (name != null) {
            if (contextroot == null) {
                if (app.getContextRoot() != null) {
                    this.previousContextRoot = app.getContextRoot();
                }
            }
            if (libraries == null) {
                libraries = app.getLibraries();
            }

            previousTargets = domain.getAllReferencedTargetsForApplication(name);
            if (virtualservers == null) {
                if (DeploymentUtils.isDomainTarget(target)) {
                    for (String tgt : previousTargets) {
                        String vs = domain.getVirtualServersForApplication(tgt, name);
                        if (vs != null) {
                            previousVirtualServers.put(tgt, vs);
                        }
                    }
                } else {
                    virtualservers = domain.getVirtualServersForApplication(
                        target, name);
                }
            }

            if (enabled == null) {
                if (DeploymentUtils.isDomainTarget(target)) {
                    // save the enable attributes of the application-ref
                    for (String tgt : previousTargets) {
                        previousEnabledAttributes.put(tgt, domain.getEnabledForApplication(tgt, name));
                    }
                    // save the enable attribute of the application
                    previousEnabledAttributes.put(DeploymentUtils.DOMAIN_TARGET_NAME, app.getEnabled());
                    // set the enable command param for DAS
                    enabled = deployment.isAppEnabled(app);
                } else {
                    enabled = Boolean.valueOf(domain.getEnabledForApplication(
                        target, name));
                }
            }

            String compatProp = app.getDeployProperties().getProperty(
                DeploymentProperties.COMPATIBILITY);
            if (compatProp != null) {
                if (properties == null) {
                    properties = new Properties();
                }
                // if user does not specify the compatibility flag
                // explictly in this deployment, set it to the old value
                if (properties.getProperty(DeploymentProperties.COMPATIBILITY) == null) {
                    properties.setProperty(DeploymentProperties.COMPATIBILITY, compatProp);
                }
            }

        }
    }

    @Override
    public void event(Event event) {
        if (event.is(Deployment.DEPLOYMENT_BEFORE_CLASSLOADER_CREATION)) {
            // this is where we have processed metadata and
            // haven't created the application classloader yet
            DeploymentContext context = (DeploymentContext)event.hook();
            if (verify) {
                Verifier verifier = habitat.getService(Verifier.class);
                if (verifier != null) {
                    verifier.verify(context);
                } else  {
                    context.getLogger().warning("Verifier is not installed yet. Install verifier module.");
                }
            }
        }
    }

    private void validateDeploymentProperties(Properties properties,
        DeploymentContext context) {
        String compatProp = properties.getProperty(
            DeploymentProperties.COMPATIBILITY);
        if (compatProp != null && !compatProp.equals("v2")) {
            // this only allowed value for property compatibility is v2
            String warningMsg = localStrings.getLocalString("compat.value.not.supported", "{0} is not a supported value for compatibility property.", compatProp);
            ActionReport subReport = context.getActionReport().addSubActionsReport();
            subReport.setActionExitCode(ActionReport.ExitCode.WARNING);
            subReport.setMessage(warningMsg);
            context.getLogger().log(Level.WARNING, warningMsg);
        }
    }

    /**
     * Crude interception mechanisms for deploy comamnd execution
     */
    @Contract
    public interface Interceptor {
        /**
         * Called by the deployment command to intercept a deployment activity.
         *
         * @param self the deployment command in flight.
         * @param context of the deployment
         */
        void intercept(DeployCommand self, DeploymentContext context);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy