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

com.aliyun.manager.create.CreateServerlessManager Maven / Gradle / Ivy

Go to download

Aliyun Open API SDK for Java Copyright (C) Alibaba Cloud Computing All rights reserved. 版权所有 (C)阿里云计算有限公司 http://www.aliyun.com

There is a newer version: 1.1.9
Show newest version
package com.aliyun.manager.create;

import com.aliyun.Context;
import com.aliyun.bean.common.DockerProfile;
import com.aliyun.bean.common.OssProfile;
import com.aliyun.bean.common.ToolkitProfile;
import com.aliyun.bean.config.ToolkitPackageConfig;
import com.aliyun.bean.config.ToolkitCreateConfig;
import com.aliyun.bean.config.ToolkitDeployConfig;
import com.aliyun.enums.Constants;
import com.aliyun.manager.ImageManager;
import com.aliyun.manager.SaeChangeOrderManager;
import com.aliyun.manager.UploadPackageManager;
import com.aliyun.utils.CommonUtils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.sae.model.v20190506.CreateApplicationRequest;
import com.aliyuncs.sae.model.v20190506.CreateApplicationResponse;
import com.aliyuncs.sae.model.v20190506.DescribeApplicationConfigRequest;
import com.aliyuncs.sae.model.v20190506.DescribeApplicationConfigResponse;
import com.aliyuncs.sae.model.v20190506.ListApplicationsRequest;
import com.aliyuncs.sae.model.v20190506.ListApplicationsResponse;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

public class CreateServerlessManager {
    private Log logger;
    private ImageManager imageManager;
    private UploadPackageManager uploadPackageManager;

    public CreateServerlessManager() {
        this.logger = Context.getLogger();
        uploadPackageManager = new UploadPackageManager(Context.getProject());
        imageManager = new ImageManager();
    }

    private void checkParam(ToolkitCreateConfig createConfig, ToolkitPackageConfig packageConfig) throws Exception {
        ToolkitCreateConfig.Spec createConfigSpec = createConfig.getSpec();
        if (createConfigSpec == null) {
            createConfigSpec = new ToolkitCreateConfig.Spec();
            createConfig.setSpec(createConfigSpec);
        }

        if (createConfigSpec.getAppName() == null) {
            throw new Exception("appName is not defined in config file");
        }

        if (createConfigSpec.getNamespaceId() == null) {
            throw new Exception("packageType is not defined in config file");
        }

        if (createConfigSpec.getReplicas() == null) {
            throw new Exception("replicas is not defined in config file");
        }

        if (createConfigSpec.getCpu() == null) {
            throw new Exception("cpu is not defined in config file");
        }

        if (createConfigSpec.getMemory() == null) {
            throw new Exception("memory is not defined in config file");
        }

        if (Constants.IMAGE.equalsIgnoreCase(packageConfig.getSpec().getPackageType())) {
            String msg = "No imageUrl or image build information is found in toolkit package file.";
            if (packageConfig.getSpec().getBuild() == null || packageConfig.getSpec().getBuild().getDocker() == null) {
                throw new Exception(msg);
            }
        }
    }

    public void create(
            ToolkitProfile toolkitProfile,
            ToolkitCreateConfig createConfig,
            ToolkitDeployConfig deployConfig,
            ToolkitPackageConfig packageConfig) throws Exception {
        DefaultAcsClient client = Context.getAcsClient();
        MavenProject project = Context.getProject();
        checkParam(createConfig, packageConfig);

        ToolkitCreateConfig.Spec createConfigSpec = createConfig.getSpec();
        String namespaceId = createConfigSpec.getNamespaceId();
        String appName = createConfigSpec.getAppName();
        if (appExists(namespaceId, appName, client)) {
            throw new Exception(String.format(
                    "App(%s) already exists in namespace(%s), skip init process",
                    appName, namespaceId));
        }
        if (deployConfig.getSpec().getVersion() == null) {
            deployConfig.getSpec().setVersion(new SimpleDateFormat("ddHHmmss").format(new Date()));
        }

        String imageUrl = packageConfig.getSpec().getImageUrl();
        String packageUrl = packageConfig.getSpec().getPackageUrl();
        if (Constants.IMAGE.equalsIgnoreCase(packageConfig.getSpec().getPackageType())) {
            if (imageUrl == null) {
                imageUrl = buildAndUploadImage(packageConfig.getSpec().getBuild().getDocker(), project);
                packageConfig.getSpec().setImageUrl(imageUrl);
            } else {
                logger.info(String.format("imageUrl(%s) is set, use it to create serverless application...", imageUrl));
            }
        } else {
            if (packageUrl == null) {
                OssProfile ossProfile = null;
                if (packageConfig.getSpec().getBuild().getOss() != null) {
                    ossProfile = packageConfig.getSpec().getBuild().getOss();
                }
                String appId = UUID.randomUUID().toString(); //创建应用前没有appId
                String packageVersion = deployConfig.getSpec().getVersion();
                toolkitProfile.setProduct(CommonUtils.Product.Sae.name());
                packageUrl = uploadPackageManager.uploadPackage(toolkitProfile, ossProfile, appId, packageVersion);
                packageConfig.getSpec().setPackageUrl(packageUrl);
            } else {
                logger.info(String.format("packageUrl(%s) is set, use it to create serverless application...", packageUrl));
            }
        }

        CreateApplicationResponse response = createServerlessApplication(
                createConfig, packageConfig, deployConfig, client);
        String appId = response.getData().getAppId();
        String changeOrderId = response.getData().getChangeOrderId();
        boolean status = checkAppCreateStatus(client, appId, 60);
        if (!status) {
            throw new Exception(String.format("Send create application request successfully, but failed to get application config. "
                    + "Please login EDAS console to check if application(%s) exists.", createConfigSpec.getAppName()));
        }
        if (!CommonUtils.isEmpty(changeOrderId)) {
            SaeChangeOrderManager changeOrderManager = new SaeChangeOrderManager();
            changeOrderManager.trace(Context.getAcsClient(), changeOrderId, 600, 600);
        }
    }

    private boolean checkAppCreateStatus(DefaultAcsClient client, String appId, int timeout) {
        logger.info("Querying application status...");
        long end = System.currentTimeMillis() + timeout * 1000;
        while (System.currentTimeMillis() < end) {
            try {
                DescribeApplicationConfigRequest detailRequest = new DescribeApplicationConfigRequest();
                detailRequest.setAppId(appId);
                DescribeApplicationConfigResponse detailResponse = client.getAcsResponse(detailRequest);
                if (!"200".equals(detailResponse.getCode())) {
                    logger.info("Create application successfully.");
                    return true;
                }
            } catch (Exception ex) {
                logger.warn("Failed to query application status: " + ex.getMessage());
            }
        }

        return false;
    }

    private CreateApplicationResponse createServerlessApplication(
            ToolkitCreateConfig createConfig,
            ToolkitPackageConfig packageConfig,
            ToolkitDeployConfig deployConfig, DefaultAcsClient client) throws Exception {
        logger.info("Creating sae application...");
        ObjectMapper jsonMapper = new ObjectMapper();
        jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        CreateApplicationRequest request = new CreateApplicationRequest();
        request.setAppName(createConfig.getSpec().getAppName());
        request.setAppDescription(createConfig.getSpec().getAppDescription());
        request.setNamespaceId(createConfig.getSpec().getNamespaceId());
        request.setVpcId(createConfig.getSpec().getVpcId());
        request.setVSwitchId(createConfig.getSpec().getVswitchId());
        request.setPackageType(packageConfig.getSpec().getPackageType());
        request.setPackageVersion(deployConfig.getSpec().getVersion());
        request.setPackageUrl(packageConfig.getSpec().getPackageUrl());
        request.setImageUrl(packageConfig.getSpec().getImageUrl());
        request.setJdk(deployConfig.getSpec().getJdk());
        request.setWebContainer(deployConfig.getSpec().getWebContainer());
        request.setCpu(createConfig.getSpec().getCpu());
        request.setMemory(createConfig.getSpec().getMemory());
        request.setReplicas(createConfig.getSpec().getReplicas());
        request.setCommand(deployConfig.getSpec().getCommand());
        request.setCommandArgs(jsonMapper.writeValueAsString(deployConfig.getSpec().getCommandArgs()));
        if (deployConfig.getSpec().getEnvs() != null) {
            request.setEnvs(jsonMapper.writeValueAsString(deployConfig.getSpec().getEnvs()));
        }
        if (deployConfig.getSpec().getCustomHostAlias() != null) {
            request.setCustomHostAlias(jsonMapper.writeValueAsString(deployConfig.getSpec().getCustomHostAlias()));
        }

        request.setJarStartOptions(deployConfig.getSpec().getJarStartOptions());
        request.setJarStartArgs(deployConfig.getSpec().getJarStartArgs());
        if (deployConfig.getSpec().getLiveness() != null) {
            request.setLiveness(jsonMapper.writeValueAsString(deployConfig.getSpec().getLiveness()));
        }
        if (deployConfig.getSpec().getReadiness() != null) {
            request.setReadiness(jsonMapper.writeValueAsString(deployConfig.getSpec().getReadiness()));
        }

        request.setDeploy(createConfig.getSpec().getWithDeploy());
        CreateApplicationResponse response = client.getAcsResponse(request);
        if (!"200".equals(response.getCode())) {
            throw new Exception(String.format(
                    "Failed to create serverless application, code: %s, msg: %s",
                    response.getCode(), response.getMessage()));
        }
        String msg = String.format(
                "Send create application request successfully, app id is %s",
                response.getData().getAppId());
        if (createConfig.getSpec().getWithDeploy() != null && createConfig.getSpec().getWithDeploy()) {
            msg += String.format(
                    ", changeOrder id is %s", response.getData().getChangeOrderId());
        }
        logger.info(msg);

        return response;
    }

    private String buildAndUploadImage(
            DockerProfile dockerProfile,
            MavenProject project) throws Exception {
        logger.info("imageUrl is not found in init process, try to build image...");
        //ToolkitCreateConfig.Spec spec = createConfig.getSpec();

        String repoAddress = dockerProfile.getImageRepoAddress();
        if (repoAddress == null) {
            throw new Exception("imageRepoAddress is not configured in config file.");
        }
        String tag = dockerProfile.getImageTag();
        if (tag == null) {
            throw new Exception("imageTag is not configured in config file.");
        }
        String user = dockerProfile.getImageRepoUser();
        if (user == null) {
            throw new Exception("imageRepoUser is not configured in config file.");
        }
        String password = dockerProfile.getImageRepoPassword();
        if (password == null) {
            throw new Exception("imageRepoPassword is not configured in config file.");
        }

        String dockerfile = dockerProfile.getDockerfile();
        if (dockerfile == null) {
            dockerfile = Constants.DOCKERFILE;
        }
        logger.info(String.format(
                "Use %s to build image in current build repository(%s)",
                dockerfile, project.getBasedir().getPath()));
        String imageUrl = imageManager.buildAndUploadImage(
                dockerfile, repoAddress, tag,
                user, password, project);
        logger.info("Upload image successfully, imageUrl is: " + imageUrl);

        return imageUrl;
    }

    private boolean appExists(String namespaceId, String appName, DefaultAcsClient client) throws Exception {
        logger.info(String.format(
                "Checking app(%s) if exists in namespace(%s)...",
                appName, namespaceId));

        ListApplicationsRequest request = new ListApplicationsRequest();
        ListApplicationsResponse response = client.getAcsResponse(request);
        if (!"200".equals(response.getCode())) {
            throw new Exception(String.format(
                    "Failed to check app if exists by ListApplicationRequest, code: %s, msg: %s",
                    response.getCode(), response.getMessage()));
        }

        if (response.getData().getApplications() == null) {
            return false;
        }

        for (ListApplicationsResponse.Data.Application application: response.getData().getApplications()) {
            if (application.getBizRegionId().equals(namespaceId)
                    && application.getAppName().equals(appName)) {
                return true;
            }
        }

        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy