ms.dew.devops.kernel.config.ConfigBuilder.java Source code

Java tutorial

Introduction

Here is the source code for ms.dew.devops.kernel.config.ConfigBuilder.java

Source

/*
 * Copyright 2019. the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ms.dew.devops.kernel.config;

import com.ecfront.dew.common.$;
import ms.dew.devops.kernel.exception.ConfigException;
import ms.dew.devops.kernel.helper.GitHelper;
import ms.dew.devops.kernel.helper.YamlHelper;
import ms.dew.devops.kernel.plugin.appkind.AppKindPlugin;
import ms.dew.devops.kernel.plugin.deploy.DeployPlugin;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Config builder.
 *
 * @author gudaoxuri
 */
public class ConfigBuilder {

    /**
     * .
     */
    public static final String FLAG_DEW_DEVOPS_DEFAULT_PROFILE = "default";

    /**
     * default??.
     *
     * @param config the project config
     * @return merged content
     */
    public static String mergeProfiles(String config) {
        LinkedHashMap mergedConfig = new LinkedHashMap();
        ((Map) YamlHelper.toObject(config)).forEach((k, v) -> {
            if (!((String) k).equalsIgnoreCase("profiles")) {
                mergedConfig.put(k, v);
            }
        });
        if (((Map) YamlHelper.toObject(config)).containsKey("profiles")) {
            Map profiles = new LinkedHashMap();
            ((Map) ((Map) YamlHelper.toObject(config)).get("profiles")).forEach((k, v) -> {
                profiles.put(k, mergeItems(mergedConfig, (LinkedHashMap) v));
            });
            mergedConfig.put("profiles", profiles);
        }
        return YamlHelper.toString(mergedConfig);
    }

    /**
     * ???.
     *
     * @param source the source, ?
     * @param target the target ?
     * @return merged content
     */
    public static String mergeProject(String source, String target) {
        return YamlHelper.toString(mergeItems(YamlHelper.toObject(source), YamlHelper.toObject(target)));
    }

    private static LinkedHashMap mergeItems(LinkedHashMap source, LinkedHashMap target) {
        target.forEach((k, v) -> {
            if (source.containsKey(k) && v instanceof LinkedHashMap) {
                // ?mapmap??
                // ??
                target.put(k, mergeItems((LinkedHashMap) source.get(k), (LinkedHashMap) v));
            }
            // ????target
        });
        source.forEach((k, v) -> {
            if (!target.containsKey(k)) {
                //  ?mapmap?
                target.put(k, v);
            }
        });
        return target;
    }

    /**
     * Build project optional.
     *
     * @param dewConfig                       the dew config
     * @param appKindPlugin                   the app kind plugin
     * @param deployPlugin                    the deploy plugin
     * @param mavenProject                    the maven project
     * @param inputProfile                    the input profile
     * @param inputDockerHost                 the input docker host
     * @param inputDockerRegistryUrl          the input docker registry url
     * @param inputDockerRegistryUserName     the input docker registry user name
     * @param inputDockerRegistryPassword     the input docker registry password
     * @param inputKubeBase64Config           the input kube base 64 config
     * @param dockerHostAppendOpt             the docker host append opt
     * @param dockerRegistryUrlAppendOpt      the docker registry url append opt
     * @param dockerRegistryUserNameAppendOpt the docker registry user name append opt
     * @param dockerRegistryPasswordAppendOpt the docker registry password append opt
     * @param kubeBase64ConfigAppendOpt       the kube base 64 config append opt
     * @return the optional
     * @throws InvocationTargetException the invocation target exception
     * @throws IllegalAccessException    the illegal access exception
     */
    public static Optional<FinalProjectConfig> buildProject(DewConfig dewConfig, AppKindPlugin appKindPlugin,
            DeployPlugin deployPlugin, MavenProject mavenProject, String inputProfile, String inputDockerHost,
            String inputDockerRegistryUrl, String inputDockerRegistryUserName, String inputDockerRegistryPassword,
            String inputKubeBase64Config, Optional<String> dockerHostAppendOpt,
            Optional<String> dockerRegistryUrlAppendOpt, Optional<String> dockerRegistryUserNameAppendOpt,
            Optional<String> dockerRegistryPasswordAppendOpt, Optional<String> kubeBase64ConfigAppendOpt)
            throws InvocationTargetException, IllegalAccessException {
        // ?
        inputProfile = inputProfile.toLowerCase();
        dewConfig.setProfiles(dewConfig.getProfiles().entrySet().stream()
                .collect(Collectors.toMap(profile -> profile.getKey().toLowerCase(), Map.Entry::getValue)));

        // ??Kubernetes????????????Kubernetes
        Set<String> envChecker = dewConfig.getProfiles().values().stream()
                .map(prof -> prof.getNamespace() + prof.getKube().getBase64Config()).collect(Collectors.toSet());
        if (!dewConfig.getNamespace().isEmpty() && !dewConfig.getKube().getBase64Config().isEmpty()) {
            envChecker.add(dewConfig.getNamespace() + dewConfig.getKube().getBase64Config());
        } else {
            envChecker.add("");
        }
        if (envChecker.size() != dewConfig.getProfiles().size() + 1) {
            throw new ConfigException("[" + mavenProject.getArtifactId() + "] "
                    + "Namespace and kubernetes cluster between different environments cannot be the same");
        }
        // ?
        if (!inputProfile.equals(FLAG_DEW_DEVOPS_DEFAULT_PROFILE)
                && !dewConfig.getProfiles().containsKey(inputProfile)) {
            throw new ConfigException(
                    "[" + mavenProject.getArtifactId() + "] Can't be found [" + inputProfile + "] profile");
        }
        // ??skip
        if (inputProfile.equals(FLAG_DEW_DEVOPS_DEFAULT_PROFILE) && dewConfig.getSkip() != null
                && dewConfig.getSkip()
                || !inputProfile.equals(FLAG_DEW_DEVOPS_DEFAULT_PROFILE)
                        && dewConfig.getProfiles().get(inputProfile).getSkip() != null
                        && dewConfig.getProfiles().get(inputProfile).getSkip()) {
            return Optional.empty();
        }
        FinalProjectConfig finalProjectConfig = doBuildProject(dewConfig, appKindPlugin, deployPlugin, mavenProject,
                inputProfile, inputDockerHost, inputDockerRegistryUrl, inputDockerRegistryUserName,
                inputDockerRegistryPassword, inputKubeBase64Config, dockerHostAppendOpt, dockerRegistryUrlAppendOpt,
                dockerRegistryUserNameAppendOpt, dockerRegistryPasswordAppendOpt, kubeBase64ConfigAppendOpt);
        if (finalProjectConfig.getKube().getBase64Config().isEmpty()) {
            throw new ConfigException("[" + mavenProject.getArtifactId() + "] Kubernetes config can't be empty");
        }
        return Optional.of(finalProjectConfig);
    }

    private static FinalProjectConfig doBuildProject(DewConfig dewConfig, AppKindPlugin appKindPlugin,
            DeployPlugin deployPlugin, MavenProject mavenProject, String inputProfile, String inputDockerHost,
            String inputDockerRegistryUrl, String inputDockerRegistryUserName, String inputDockerRegistryPassword,
            String inputKubeBase64Config, Optional<String> dockerHostAppendOpt,
            Optional<String> dockerRegistryUrlAppendOpt, Optional<String> dockerRegistryUserNameAppendOpt,
            Optional<String> dockerRegistryPasswordAppendOpt, Optional<String> kubeBase64ConfigAppendOpt)
            throws InvocationTargetException, IllegalAccessException {
        FinalProjectConfig finalProjectConfig = new FinalProjectConfig();
        if (inputProfile.equalsIgnoreCase(FLAG_DEW_DEVOPS_DEFAULT_PROFILE)) {
            $.bean.copyProperties(finalProjectConfig, dewConfig);
        } else {
            $.bean.copyProperties(finalProjectConfig, dewConfig.getProfiles().get(inputProfile));
        }
        // setting basic
        finalProjectConfig.setId(mavenProject.getId());
        finalProjectConfig.setAppKindPlugin(appKindPlugin);
        finalProjectConfig.setDeployPlugin(deployPlugin);
        finalProjectConfig.setProfile(inputProfile);
        finalProjectConfig.setAppGroup(mavenProject.getGroupId());
        finalProjectConfig.setAppName(mavenProject.getArtifactId());
        finalProjectConfig.setSkip(false);
        if (mavenProject.getName() != null && !mavenProject.getName().trim().isEmpty()) {
            finalProjectConfig.setAppShowName(mavenProject.getName());
        } else {
            finalProjectConfig.setAppShowName(mavenProject.getArtifactId());
        }
        // ?
        if (inputDockerHost != null && !inputDockerHost.trim().isEmpty()) {
            finalProjectConfig.getDocker().setHost(inputDockerHost.trim());
        }
        if (inputDockerRegistryUrl != null && !inputDockerRegistryUrl.trim().isEmpty()) {
            finalProjectConfig.getDocker().setRegistryUrl(inputDockerRegistryUrl.trim());
        }
        if (inputDockerRegistryUserName != null && !inputDockerRegistryUserName.trim().isEmpty()) {
            finalProjectConfig.getDocker().setRegistryUserName(inputDockerRegistryUserName.trim());
        }
        if (inputDockerRegistryPassword != null && !inputDockerRegistryPassword.trim().isEmpty()) {
            finalProjectConfig.getDocker().setRegistryPassword(inputDockerRegistryPassword.trim());
        }
        if (inputKubeBase64Config != null && !inputKubeBase64Config.trim().isEmpty()) {
            finalProjectConfig.getKube().setBase64Config(inputKubeBase64Config.trim());
        }

        // setting path
        finalProjectConfig.setDirectory(mavenProject.getBasedir().getPath() + File.separator);
        finalProjectConfig.setTargetDirectory(finalProjectConfig.getDirectory() + "target" + File.separator);

        // setting git info
        finalProjectConfig.setScmUrl(GitHelper.inst().getScmUrl());
        finalProjectConfig.setGitCommit(GitHelper.inst().getCurrentCommit());
        finalProjectConfig.setImageVersion(finalProjectConfig.getGitCommit());
        finalProjectConfig.setAppVersion(finalProjectConfig.getGitCommit());

        // setting custom config by app kind
        finalProjectConfig.getAppKindPlugin().customConfig(finalProjectConfig);
        // setting reuse version
        fillReuseVersionInfo(finalProjectConfig, dewConfig, dockerHostAppendOpt, dockerRegistryUrlAppendOpt,
                dockerRegistryUserNameAppendOpt, dockerRegistryPasswordAppendOpt, kubeBase64ConfigAppendOpt);
        return finalProjectConfig;
    }

    private static void fillReuseVersionInfo(FinalProjectConfig finalProjectConfig, DewConfig dewConfig,
            Optional<String> dockerHostAppendOpt, Optional<String> dockerRegistryUrlAppendOpt,
            Optional<String> dockerRegistryUserNameAppendOpt, Optional<String> dockerRegistryPasswordAppendOpt,
            Optional<String> kubeBase64ConfigAppendOpt) {
        if (finalProjectConfig.getDisableReuseVersion() != null && finalProjectConfig.getDisableReuseVersion()) {
            // ????
            return;
        }
        // ?
        // ?
        finalProjectConfig.setDisableReuseVersion(false);
        if ((finalProjectConfig.getReuseLastVersionFromProfile() == null
                || finalProjectConfig.getReuseLastVersionFromProfile().isEmpty())
                && (finalProjectConfig.getProfile().equals("production")
                        || finalProjectConfig.getProfile().equals("prod"))) {
            // ?
            // ??
            String guessFromProfile = null;
            if (dewConfig.getProfiles().containsKey("pre-prod")) {
                guessFromProfile = "pre-prod";
            } else if (dewConfig.getProfiles().containsKey("pre-production")) {
                guessFromProfile = "pre-production";
            } else if (dewConfig.getProfiles().containsKey("uat")) {
                guessFromProfile = "uat";
            }
            if (guessFromProfile != null) {
                finalProjectConfig.setReuseLastVersionFromProfile(guessFromProfile);
            }
        }
        if (finalProjectConfig.getReuseLastVersionFromProfile() == null
                || finalProjectConfig.getReuseLastVersionFromProfile().isEmpty()) {
            // ?
            finalProjectConfig.setDisableReuseVersion(true);
            return;
        }
        // ????profile
        // KubernetesDocker?
        // ?
        // 1)  '-append' ?
        // 2) '.dew' ??
        // 3) ???????
        DewProfile appendProfile = dewConfig.getProfiles().get(finalProjectConfig.getReuseLastVersionFromProfile());
        dockerHostAppendOpt.ifPresent(obj -> appendProfile.getDocker().setHost(obj.trim()));
        if (appendProfile.getDocker().getHost() == null || appendProfile.getDocker().getHost().isEmpty()) {
            appendProfile.getDocker().setHost(dewConfig.getDocker().getHost());
        }
        if (appendProfile.getDocker().getHost() == null || appendProfile.getDocker().getHost().isEmpty()) {
            appendProfile.getDocker().setHost(finalProjectConfig.getDocker().getHost());
        }

        dockerRegistryUrlAppendOpt.ifPresent(obj -> appendProfile.getDocker().setRegistryUrl(obj.trim()));
        if (appendProfile.getDocker().getRegistryUrl() == null
                || appendProfile.getDocker().getRegistryUrl().isEmpty()) {
            appendProfile.getDocker().setRegistryUrl(dewConfig.getDocker().getRegistryUrl());
        }
        if (appendProfile.getDocker().getRegistryUrl() == null
                || appendProfile.getDocker().getRegistryUrl().isEmpty()) {
            appendProfile.getDocker().setRegistryUrl(finalProjectConfig.getDocker().getRegistryUrl());
        }

        dockerRegistryUserNameAppendOpt.ifPresent(obj -> appendProfile.getDocker().setRegistryUserName(obj.trim()));
        if (appendProfile.getDocker().getRegistryUserName() == null
                || appendProfile.getDocker().getRegistryUserName().isEmpty()) {
            appendProfile.getDocker().setRegistryUserName(dewConfig.getDocker().getRegistryUserName());
        }
        if (appendProfile.getDocker().getRegistryUserName() == null
                || appendProfile.getDocker().getRegistryUserName().isEmpty()) {
            appendProfile.getDocker().setRegistryUserName(finalProjectConfig.getDocker().getRegistryUserName());
        }

        dockerRegistryPasswordAppendOpt.ifPresent(obj -> appendProfile.getDocker().setRegistryPassword(obj.trim()));
        if (appendProfile.getDocker().getRegistryPassword() == null
                || appendProfile.getDocker().getRegistryPassword().isEmpty()) {
            appendProfile.getDocker().setRegistryPassword(dewConfig.getDocker().getRegistryPassword());
        }
        if (appendProfile.getDocker().getRegistryPassword() == null
                || appendProfile.getDocker().getRegistryPassword().isEmpty()) {
            appendProfile.getDocker().setRegistryPassword(finalProjectConfig.getDocker().getRegistryPassword());
        }

        kubeBase64ConfigAppendOpt.ifPresent(obj -> appendProfile.getKube().setBase64Config(obj.trim()));
        if (appendProfile.getKube().getBase64Config() == null
                || appendProfile.getKube().getBase64Config().isEmpty()) {
            appendProfile.getKube().setBase64Config(dewConfig.getKube().getBase64Config());
        }
        if (appendProfile.getKube().getBase64Config() == null
                || appendProfile.getKube().getBase64Config().isEmpty()) {
            appendProfile.getKube().setBase64Config(finalProjectConfig.getKube().getBase64Config());
        }

        if (appendProfile.getKube().getBase64Config().isEmpty() || appendProfile.getDocker().getHost().isEmpty()) {
            throw new ConfigException(
                    "In reuse version mode, " + "'kubernetes base64 config' and 'docker host' must be specified by "
                            + "command-line arguments '" + "dew_devops_kube_config-append'/ "
                            + "dew_devops_docker_host-append'" + "OR '.dew' profile configuration file");
        }
        finalProjectConfig.setAppendProfile(appendProfile);
    }

}