Skip to content

Commit

Permalink
feature: 支持自定义开发环境, 实际业务场景中: 不是用 dev 代表开发环境
Browse files Browse the repository at this point in the history
  • Loading branch information
myoss committed Oct 2, 2019
1 parent 442a8c9 commit 466d049
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class ApmWebEndpointEnvironmentPostProcessor
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MutablePropertySources propertySources = environment.getPropertySources();
Map<String, Object> map = new HashMap<>();
if (!DeployEnvEnum.isDev()) {
if (!DeployEnvEnum.isCustomizeDev()) {
map.put("management.server.port", "8088");
}
map.put("management.endpoints.enabled-by-default", "true");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
*/
@AllArgsConstructor
public enum DeployEnvEnum {
/**
* 自定义本地开发环境: 运行在办公室开发者的电脑中
*/
CUSTOMIZE_DEV("DEPLOY_ENV_CUSTOMIZE_DEV", "自定义本地开发环境"),
/**
* 本地开发环境: 运行在办公室开发者的电脑中
*/
LOCAL("local", "本地开发环境"),
/**
* 开发环境
*/
Expand Down Expand Up @@ -77,7 +85,45 @@ public static DeployEnvEnum getEnumByValue(String value) {
}

/**
* 是否为开发环境或者测试环境
* 是否为自定义开发环境, 实际业务场景中: 不是用 dev 代表开发环境
*
* @return true: 是; false: 不是
* @see app.myoss.cloud.core.spring.boot.config.DeployEnvEnvironmentPostProcessor
* 请参考文档进行设置
*/
public static boolean isCustomizeDev() {
String value = getDeployEnv();
String customizeDev = StringUtils.defaultIfBlank(System.getProperty(CUSTOMIZE_DEV.getValue()),
System.getenv(CUSTOMIZE_DEV.getValue()));
if (StringUtils.isNotBlank(customizeDev)) {
return StringUtils.equals(value, customizeDev);
} else {
return isDev(value);
}
}

/**
* 是否为本地开发环境: DEPLOY_ENV=local
*
* @param value 部署的环境变量
* @return true: 是; false: 不是
*/
public static boolean isLocal(String value) {
return LOCAL.getValue().equals(value);
}

/**
* 是否为开发环境: DEPLOY_ENV=local
*
* @return true: 是; false: 不是
*/
public static boolean isLocal() {
String value = getDeployEnv();
return LOCAL.getValue().equals(value);
}

/**
* 是否为开发环境或者测试环境: dev or test
*
* @param value 部署的环境变量
* @return true: 是; false: 不是
Expand All @@ -87,7 +133,7 @@ public static boolean isDevOrTest(String value) {
}

/**
* 是否为开发环境或者测试环境
* 是否为开发环境或者测试环境: dev or test
*
* @return true: 是; false: 不是
*/
Expand All @@ -97,7 +143,7 @@ public static boolean isDevOrTest() {
}

/**
* 是否为开发环境
* 是否为开发环境: DEPLOY_ENV=dev
*
* @param value 部署的环境变量
* @return true: 是; false: 不是
Expand All @@ -107,7 +153,7 @@ public static boolean isDev(String value) {
}

/**
* 是否为开发环境
* 是否为开发环境: DEPLOY_ENV=dev
*
* @return true: 是; false: 不是
*/
Expand All @@ -117,7 +163,7 @@ public static boolean isDev() {
}

/**
* 是否为测试环境
* 是否为测试环境: DEPLOY_ENV=test
*
* @param value 部署的环境变量
* @return true: 是; false: 不是
Expand All @@ -127,7 +173,7 @@ public static boolean isTest(String value) {
}

/**
* 是否为测试环境
* 是否为测试环境: DEPLOY_ENV=test
*
* @return true: 是; false: 不是
*/
Expand All @@ -137,7 +183,7 @@ public static boolean isTest() {
}

/**
* 是否为预发环境
* 是否为预发环境: DEPLOY_ENV=pre
*
* @param value 部署的环境变量
* @return true: 是; false: 不是
Expand All @@ -147,7 +193,7 @@ public static boolean isPre(String value) {
}

/**
* 是否为预发环境
* 是否为预发环境: DEPLOY_ENV==pre
*
* @return true: 是; false: 不是
*/
Expand All @@ -157,7 +203,7 @@ public static boolean isPre() {
}

/**
* 是否为生产环境
* 是否为生产环境: DEPLOY_ENV=prd
*
* @param value 部署的环境变量
* @return true: 是; false: 不是
Expand All @@ -167,7 +213,7 @@ public static boolean isPrd(String value) {
}

/**
* 是否为生产环境
* 是否为生产环境: DEPLOY_ENV=prd
*
* @return true: 是; false: 不是
*/
Expand Down Expand Up @@ -198,4 +244,13 @@ public static DeployEnvEnum getDeployEnvEnum() {
String deployEnv = getDeployEnv();
return getEnumByValue(deployEnv);
}

/**
* 设置应用部署的环境变量
*
* @param deployEnv 部署的环境变量
*/
public static void setDeployEnv(String deployEnv) {
System.setProperty(DEPLOY_ENV, deployEnv);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,14 @@

package app.myoss.cloud.core.spring.boot.config;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.boot.logging.DeferredLog;
import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;
Expand All @@ -42,6 +37,7 @@

import app.myoss.cloud.core.constants.DeployEnvEnum;
import app.myoss.cloud.core.constants.MyossConstants;
import app.myoss.cloud.core.utils.YamlUtils;

/**
* 加载核心自定义基础配置信息,保存到 spring {@link org.springframework.core.env.Environment} 中
Expand All @@ -63,22 +59,21 @@ public class CoreCommonEnvironmentPostProcessor implements EnvironmentPostProces
/**
* {@link EnvironmentPostProcessor} 中比较特殊,不能直接用 @Slf4j 进行输出日志
*/
private static final DeferredLog LOGGER = new DeferredLog();
private static final DeferredLog LOGGER = new DeferredLog();
/**
* The default order for the processor.
*/
public static final int DEFAULT_ORDER = ConfigFileApplicationListener.DEFAULT_ORDER + 9;
public static final int DEFAULT_ORDER = ConfigFileApplicationListener.DEFAULT_ORDER + 9;
/**
* 属性配置名字
*/
public static final String PROPERTY_SOURCE_NAME = "defaultProperties";
private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
public static final String PROPERTY_SOURCE_NAME = "defaultProperties";

@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 加载默认的配置文件
Resource path = new ClassPathResource("core-config/application.yml");
LinkedHashMap<String, Object> linkedHashMap = loadYaml2Map(path);
LinkedHashMap<String, Object> linkedHashMap = YamlUtils.loadYaml2Map(path);
addOrReplace(environment.getPropertySources(), linkedHashMap);

// 加载当前环境的配置文件,进行覆盖
Expand All @@ -88,31 +83,10 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp
deployEnv = environment.getProperty(MyossConstants.DEPLOY_ENV);
}
path = new ClassPathResource("core-config/application-" + deployEnv + ".yml");
linkedHashMap = loadYaml2Map(path);
linkedHashMap = YamlUtils.loadYaml2Map(path);
addOrReplace(environment.getPropertySources(), linkedHashMap);
}

@SuppressWarnings("unchecked")
private LinkedHashMap<String, Object> loadYaml2Map(Resource path) {
if (!path.exists()) {
LOGGER.info("Resource " + path + " does not exist, ignore add to environment");
return null;
}

PropertySource<Map<String, OriginTrackedValue>> propertySource;
try {
propertySource = (PropertySource<Map<String, OriginTrackedValue>>) this.loader.load("config", path).get(0);
} catch (IOException ex) {
throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
}

return propertySource.getSource()
.entrySet()
.stream()
.collect(Collectors.toMap(Entry::getKey, e -> e.getValue().getValue(), (oldValue, newValue) -> newValue,
LinkedHashMap::new));
}

/**
* 增加或者替换配置属性:{@link #PROPERTY_SOURCE_NAME}
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2018-2019 https://github.com/myoss
*
* 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 app.myoss.cloud.core.spring.boot.config;

import java.util.LinkedHashMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLog;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import app.myoss.cloud.core.constants.DeployEnvEnum;
import app.myoss.cloud.core.constants.MyossConstants;
import app.myoss.cloud.core.utils.YamlUtils;

/**
* 加载"服务部署的环境变量",保存到 spring {@link org.springframework.core.env.Environment} 中
* <p>
* 如果需要启用这个功能,请按下面的步骤操作:
* <ul>
* <li>可以在某个核心 maven依赖中,增加配置文件信息:resources:core-config/service-deploy-env.yml
* <li>service-deploy-env.yml 中增加配置项:DEPLOY_ENV_CUSTOMIZE_DEV: local
* </ul>
*
* @author Jerry.Chen
* @since 2019年10月2日 下午3:26:17
*/
public class DeployEnvEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered, SmartApplicationListener {
/**
* {@link EnvironmentPostProcessor} 中比较特殊,不能直接用 @Slf4j 进行输出日志
*/
private static final DeferredLog LOGGER = new DeferredLog();
/**
* The default order for the processor.
*/
public static final int DEFAULT_ORDER = CoreCommonEnvironmentPostProcessor.DEFAULT_ORDER - 1;

@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 加载 "服务部署的环境变量" 的配置文件
Resource path = new ClassPathResource("core-config/service-deploy-env.yml");
LinkedHashMap<String, Object> linkedHashMap = YamlUtils.loadYaml2Map(path);
if (linkedHashMap != null) {
String customizeDev = (String) linkedHashMap.get(DeployEnvEnum.CUSTOMIZE_DEV.getValue());
if (StringUtils.isNotBlank(customizeDev)) {
// 自定义开发环境, 实际业务场景中: 不是用 dev 代表开发环境
LOGGER.info("DEPLOY_ENV_CUSTOMIZE_DEV set to " + customizeDev);
System.setProperty(DeployEnvEnum.CUSTOMIZE_DEV.getValue(), customizeDev);

// 加载当前环境的配置文件,进行覆盖
String deployEnv = DeployEnvEnum.getDeployEnv();
if (deployEnv == null) {
// 跑 test case 的时候,可以考虑加下这个: @SpringBootTest(properties = {"DEPLOY_ENV:test"})
deployEnv = environment.getProperty(MyossConstants.DEPLOY_ENV);
}
if (deployEnv == null) {
LOGGER.info("DEPLOY_ENV set to " + customizeDev);
DeployEnvEnum.setDeployEnv(customizeDev);
}
}
CoreCommonEnvironmentPostProcessor.addOrReplace(environment.getPropertySources(), linkedHashMap);
}
}

@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationPreparedEvent.class.isAssignableFrom(eventType);
}

@Override
public boolean supportsSourceType(Class<?> sourceType) {
return true;
}

@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationPreparedEvent) {
LOGGER.replayTo(DeployEnvEnvironmentPostProcessor.class);
}
}

@Override
public int getOrder() {
return DEFAULT_ORDER;
}
}
Loading

0 comments on commit 466d049

Please sign in to comment.