Java tutorial
/* * 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); } }