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

com.microsoft.azure.maven.springcloud.DeployMojo Maven / Gradle / Ivy

There is a newer version: 1.11.0
Show newest version
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 */

package com.microsoft.azure.maven.springcloud;

import com.microsoft.azure.maven.prompt.DefaultPrompter;
import com.microsoft.azure.maven.prompt.IPrompter;
import com.microsoft.azure.maven.utils.MavenConfigUtils;
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
import com.microsoft.azure.toolkit.lib.common.task.AzureTask;
import com.microsoft.azure.toolkit.lib.common.utils.TextUtils;
import com.microsoft.azure.toolkit.lib.springcloud.SpringCloudApp;
import com.microsoft.azure.toolkit.lib.springcloud.SpringCloudDeployment;
import com.microsoft.azure.toolkit.lib.springcloud.Utils;
import com.microsoft.azure.toolkit.lib.springcloud.config.SpringCloudAppConfig;
import com.microsoft.azure.toolkit.lib.springcloud.task.DeploySpringCloudAppTask;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import java.io.IOException;
import java.util.List;

@Mojo(name = "deploy")
@Slf4j
public class DeployMojo extends AbstractMojoBase {

    private static final int GET_URL_TIMEOUT = 60;
    private static final int GET_STATUS_TIMEOUT = 180;
    private static final String PROJECT_SKIP = "Packaging type is pom, taking no actions.";
    private static final String PROJECT_NO_CONFIGURATION = "Configuration does not exist, taking no actions.";
    private static final String PROJECT_NOT_SUPPORT = "`azure-spring-cloud:deploy` does not support maven project with " +
            "packaging %s, only jar is supported";
    private static final String GET_DEPLOYMENT_STATUS_TIMEOUT = "Deployment succeeded but the app is still starting, " +
            "you can check the app status from Azure Portal.";
    private static final String CONFIRM_PROMPT_START = "`azure-spring-cloud:deploy` will perform the following tasks";
    private static final String CONFIRM_PROMPT_CONFIRM = "Perform the above tasks? (Y/n):";

    @Parameter(property = "noWait")
    private boolean noWait;

    @Parameter(property = "prompt")
    private boolean prompt;

    @SneakyThrows
    @Override
    @AzureOperation(name = "springcloud|app.create_update_mojo", type = AzureOperation.Type.ACTION)
    protected void doExecute() {
        // set up account and select subscription here in `deploy`, since in some cases, `config` will not need to sign in
        getAzureAccount();
        selectSubscription();

        // Init spring clients, and prompt users to confirm
        final SpringCloudAppConfig appConfig = this.getConfiguration();
        final DeploySpringCloudAppTask task = new DeploySpringCloudAppTask(appConfig);

        final List> tasks = task.getSubTasks();
        final boolean shouldSkipConfirm = !prompt || (this.settings != null && !this.settings.isInteractiveMode());
        if (!shouldSkipConfirm && !this.confirm(tasks)) {
            log.warn("Deployment is cancelled!");
            return;
        }
        final SpringCloudDeployment deployment = task.execute();
        if (!noWait) {
            if (!deployment.waitUntilReady(GET_STATUS_TIMEOUT)) {
                log.warn(GET_DEPLOYMENT_STATUS_TIMEOUT);
            }
        }
        printStatus(deployment);
        printPublicUrl(deployment.app());
    }

    protected boolean confirm(List> tasks) throws MojoFailureException {
        try {
            final IPrompter prompter = new DefaultPrompter();
            System.out.println(CONFIRM_PROMPT_START);
            tasks.stream().filter(t -> StringUtils.isNotBlank(t.getTitle().toString())).forEach((t) -> System.out.printf("\t- %s%n", t.getTitle()));
            return prompter.promoteYesNo(CONFIRM_PROMPT_CONFIRM, true, true);
        } catch (IOException e) {
            throw new MojoFailureException(e.getMessage(), e);
        }
    }

    protected void printPublicUrl(SpringCloudApp app) {
        if (!app.entity().isPublic()) {
            return;
        }
        log.info("Getting public url of app({})...", TextUtils.cyan(app.name()));
        String publicUrl = app.entity().getApplicationUrl();
        if (!noWait && StringUtils.isEmpty(publicUrl)) {
            publicUrl = Utils.pollUntil(() -> app.refresh().entity().getApplicationUrl(), StringUtils::isNotBlank, GET_URL_TIMEOUT);
        }
        if (StringUtils.isEmpty(publicUrl)) {
            log.warn("Failed to get application url");
        } else {
            log.info("Application url: {}", TextUtils.cyan(publicUrl));
        }
    }

    protected void printStatus(SpringCloudDeployment deployment) {
        log.info("Deployment Status: {}", color(deployment.entity().getStatus().getLabel()));
        deployment.entity().getInstances().forEach(instance ->
                log.info(String.format("  InstanceName:%-10s  Status:%-10s Reason:%-10s DiscoverStatus:%-10s",
                        instance.getName(), color(instance.status()), instance.reason(), instance.discoveryStatus())));
    }

    private static String color(String status) {
        switch (status.toUpperCase()) {
            case "RUNNING":
                return TextUtils.green(status);
            case "FAILED":
            case "STOPPED":
                return TextUtils.red(status);
            case "UNKNOWN":
                return status;
            default:
                return TextUtils.blue(status);
        }
    }

    protected boolean checkProjectPackaging(MavenProject project) throws MojoExecutionException {
        if (MavenConfigUtils.isJarPackaging(project)) {
            return true;
        } else if (MavenConfigUtils.isPomPackaging(project)) {
            log.info(PROJECT_SKIP);
            return false;
        } else {
            throw new MojoExecutionException(String.format(PROJECT_NOT_SUPPORT, project.getPackaging()));
        }
    }

    protected boolean checkConfiguration() {
        final String pluginKey = plugin.getPluginLookupKey();
        final Xpp3Dom pluginDom = MavenConfigUtils.getPluginConfiguration(project, pluginKey);
        if (pluginDom == null || pluginDom.getChildren().length == 0) {
            log.warn(PROJECT_NO_CONFIGURATION);
            return false;
        } else {
            return true;
        }
    }

    @SneakyThrows
    @Override
    protected boolean isSkipMojo() {
        return !checkProjectPackaging(project) || !checkConfiguration();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy