From 2faaa65325b5b6f76bdf8660a231fac86772b3ba Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 25 Jun 2022 21:36:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=20yudao-spring-boot-starter-?= =?UTF-8?q?env=20=E7=BB=84=E4=BB=B6=EF=BC=8C=E5=AE=8C=E6=88=90=20registry?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http-client.env.json | 3 + .../social/core/YudaoAuthRequestFactory.java | 1 + .../config/EnvEnvironmentPostProcessor.java | 52 +++++++++++++++ .../framework/env/config/EnvProperties.java | 6 +- .../config/YudaoEnvRpcAutoConfiguration.java | 2 + .../config/YudaoEnvWebAutoConfiguration.java | 2 + .../env/core/fegin/EnvLoadBalancerClient.java | 4 +- .../framework/env/core/util/EnvUtils.java | 19 +++++- .../main/resources/META-INF/spring.factories | 3 + .../controller/admin/auth/AuthController.http | 2 +- .../src/main/resources/application-local.yaml | 2 + .../config/DubboEnvironmentPostProcessor.java | 66 ------------------- .../main/resources/META-INF/spring.factories | 2 - 13 files changed, 91 insertions(+), 73 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvEnvironmentPostProcessor.java delete mode 100644 归档/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboEnvironmentPostProcessor.java delete mode 100644 归档/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/spring.factories diff --git a/http-client.env.json b/http-client.env.json index 77c59303..33c15fee 100644 --- a/http-client.env.json +++ b/http-client.env.json @@ -6,6 +6,7 @@ "token": "test1", "adminTenentId": "1", + "tag": "${HOSTNAME}", "appApi": "http://127.0.0.1:48080/app-api", "appToken": "test1", @@ -15,8 +16,10 @@ "baseUrl": "http://127.0.0.1:48080/admin-api", "systemBaseUrl": "http://127.0.0.1:48080/admin-api", "infaBaseUrl": "http://127.0.0.1:48080/admin-api", + "token": "test1", "adminTenentId": "1", + "tag": "${HOSTNAME}", "appApi": "http://127.0.0.1:8888/app-api", "appToken": "test1", diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java index 43d70052..b3b6ea1b 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java @@ -10,6 +10,7 @@ import me.zhyd.oauth.cache.AuthStateCache; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; import me.zhyd.oauth.request.AuthRequest; +import org.springframework.boot.context.properties.ConfigurationProperties; import java.lang.reflect.Method; diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvEnvironmentPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvEnvironmentPostProcessor.java new file mode 100644 index 00000000..4c1cb44f --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvEnvironmentPostProcessor.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.framework.env.config; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.framework.env.core.util.EnvUtils; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.env.ConfigurableEnvironment; + +import java.util.Set; + +import static cn.iocoder.yudao.framework.env.core.util.EnvUtils.HOST_NAME_VALUE; + +/** + * 多环境的 {@link EnvEnvironmentPostProcessor} 实现类 + * 将 yudao.env.tag 设置到 dubbo、nacos 等组件对应的 tag 配置项,当且仅当它们不存在时 + * + * @author 芋道源码 + */ +public class EnvEnvironmentPostProcessor implements EnvironmentPostProcessor { + + private static final Set TARGET_TAG_KEYS = SetUtils.asSet( + "spring.cloud.nacos.discovery.metadata.tag", // Nacos 注册中心 + "dubbo.provider.tag", // Dubbo 服务提供者的 tag + "dubbo.consumer.tag" // Dubbo 服务消费者的 tag + // MQ TODO + ); + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + // 0. 设置 ${HOST_NAME} 兜底的环境变量 + String hostNameKey = StrUtil.subBetween(HOST_NAME_VALUE, "{", "}"); + if (!environment.containsProperty(hostNameKey)) { + environment.getSystemProperties().put(hostNameKey, EnvUtils.getHostName()); + } + + // 1.1 如果没有 yudao.env.tag 配置项,则不进行配置项的修改 + String tag = EnvUtils.getTag(environment); + if (StrUtil.isEmpty(tag)) { + return; + } + // 1.2 需要修改的配置项 + for (String targetTagKey : TARGET_TAG_KEYS) { + String targetTagValue = environment.getProperty(targetTagKey); + if (StrUtil.isNotEmpty(targetTagValue)) { + continue; + } + environment.getSystemProperties().put(targetTagKey, tag); + } + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvProperties.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvProperties.java index 1be3a519..1c88ff27 100644 --- a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvProperties.java +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/EnvProperties.java @@ -1,15 +1,19 @@ package cn.iocoder.yudao.framework.env.config; import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; /** - * 环境 + * 环境配置 * * @author 芋道源码 */ +@ConfigurationProperties(prefix = "yudao.env") @Data public class EnvProperties { + public static final String TAG_KEY = "yudao.env.tag"; + /** * 环境标签 */ diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvRpcAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvRpcAutoConfiguration.java index 28e7148b..059e7165 100644 --- a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvRpcAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvRpcAutoConfiguration.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.env.config; import cn.iocoder.yudao.framework.env.core.fegin.EnvLoadBalancerClientFactory; import cn.iocoder.yudao.framework.env.core.fegin.EnvRequestInterceptor; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientSpecification; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; @@ -18,6 +19,7 @@ import java.util.List; * @author 芋道源码 */ @Configuration +@EnableConfigurationProperties(EnvProperties.class) public class YudaoEnvRpcAutoConfiguration { // ========== Feign 相关 ========== diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvWebAutoConfiguration.java index a730a685..ece03ef2 100644 --- a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvWebAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/config/YudaoEnvWebAutoConfiguration.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.env.config; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; import cn.iocoder.yudao.framework.env.core.web.EnvWebFilter; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,6 +15,7 @@ import org.springframework.context.annotation.Configuration; */ @Configuration @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@EnableConfigurationProperties(EnvProperties.class) public class YudaoEnvWebAutoConfiguration { /** diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/fegin/EnvLoadBalancerClient.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/fegin/EnvLoadBalancerClient.java index 950aa822..ac136e6b 100644 --- a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/fegin/EnvLoadBalancerClient.java +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/fegin/EnvLoadBalancerClient.java @@ -49,11 +49,13 @@ public class EnvLoadBalancerClient implements ReactorServiceInstanceLoadBalancer @Override public Mono> choose(Request request) { + // 情况一,没有 tag 时,使用默认的 reactiveLoadBalancer 实现负载均衡 String tag = EnvContextHolder.getTag(); if (StrUtil.isEmpty(tag)) { return Mono.from(reactiveLoadBalancer.choose(request)); } - // 选择实例 + + // 情况二,有 tag 时,使用 tag 匹配服务实例 ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new); return supplier.get(request).next().map(list -> getInstanceResponse(list, tag)); } diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/util/EnvUtils.java b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/util/EnvUtils.java index f867b9ab..0b393dea 100644 --- a/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/util/EnvUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/java/cn/iocoder/yudao/framework/env/core/util/EnvUtils.java @@ -1,8 +1,12 @@ package cn.iocoder.yudao.framework.env.core.util; import cn.hutool.core.net.NetUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.env.config.EnvProperties; import feign.RequestTemplate; import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.env.Environment; import javax.servlet.http.HttpServletRequest; import java.util.Objects; @@ -16,21 +20,32 @@ public class EnvUtils { private static final String HEADER_TAG = "tag"; - private static final String HOST_NAME_VALUE = "${HOSTNAME}"; + public static final String HOST_NAME_VALUE = "${HOSTNAME}"; public static String getTag(HttpServletRequest request) { String tag = request.getHeader(HEADER_TAG); // 如果请求的是 "${HOSTNAME}",则解析成对应的本地主机名 // 目的:特殊逻辑,解决 IDEA Rest Client 不支持环境变量的读取,所以就服务器来做 - return Objects.equals(tag, HOST_NAME_VALUE) ? NetUtil.getLocalHostName() : tag; + return Objects.equals(tag, HOST_NAME_VALUE) ? getHostName() : tag; } public static String getTag(ServiceInstance instance) { return instance.getMetadata().get(HEADER_TAG); } + public static String getTag(Environment environment) { + String tag = environment.getProperty(EnvProperties.TAG_KEY); + // 如果请求的是 "${HOSTNAME}",则解析成对应的本地主机名 + // 目的:特殊逻辑,解决 IDEA Rest Client 不支持环境变量的读取,所以就服务器来做 + return Objects.equals(tag, HOST_NAME_VALUE) ? getHostName() : tag; + } + public static void setTag(RequestTemplate requestTemplate, String tag) { requestTemplate.header(HEADER_TAG, tag); } + public static String getHostName() { + return StrUtil.blankToDefault(NetUtil.getLocalHostName(), IdUtil.fastSimpleUUID()); + } + } diff --git a/yudao-framework/yudao-spring-boot-starter-env/src/main/resources/META-INF/spring.factories b/yudao-framework/yudao-spring-boot-starter-env/src/main/resources/META-INF/spring.factories index ffb23203..1d959898 100644 --- a/yudao-framework/yudao-spring-boot-starter-env/src/main/resources/META-INF/spring.factories +++ b/yudao-framework/yudao-spring-boot-starter-env/src/main/resources/META-INF/spring.factories @@ -1,3 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ cn.iocoder.yudao.framework.env.config.YudaoEnvWebAutoConfiguration,\ cn.iocoder.yudao.framework.env.config.YudaoEnvRpcAutoConfiguration + +org.springframework.boot.env.EnvironmentPostProcessor=\ + cn.iocoder.yudao.framework.env.config.EnvEnvironmentPostProcessor diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.http index 2c38d003..a3792f1c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.http +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.http @@ -2,7 +2,7 @@ POST {{systemBaseUrl}}/system/auth/login Content-Type: application/json tenant-id: {{adminTenentId}} -tag: 123 +tag: {{tag}} { "username": "admin", diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml index 8895240b..ed91a918 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml @@ -137,6 +137,8 @@ wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-sta # 芋道配置项,设置当前项目所有自定义的配置 yudao: + env: # 多环境的配置项 + tag: ${HOSTNAME} captcha: enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试 security: diff --git a/归档/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboEnvironmentPostProcessor.java b/归档/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboEnvironmentPostProcessor.java deleted file mode 100644 index e17fc597..00000000 --- a/归档/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboEnvironmentPostProcessor.java +++ /dev/null @@ -1,66 +0,0 @@ -package cn.iocoder.mall.dubbo.config; - -import cn.iocoder.common.framework.util.OSUtils; -import cn.iocoder.common.framework.util.StringUtils; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.util.CollectionUtils; - -import java.util.HashMap; -import java.util.Map; - -/** - * Dubbo 配置项的后置处理器,主要目的如下: - * - * 1. 生成 {@link #DUBBO_TAG_PROPERTIES_KEY} 配置项,可用于本地开发环境下的 dubbo.provider.tag 配置项 - */ -public class DubboEnvironmentPostProcessor implements EnvironmentPostProcessor { - - /** - * 默认配置项的 PropertySource 名字 - */ - private static final String PROPERTY_SOURCE_NAME = "mallDubboProperties"; - - /** - * Dubbo 路由标签属性 KEY - */ - private static final String DUBBO_TAG_PROPERTIES_KEY = "DUBBO_TAG"; - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - // 需要修改的配置项 - Map modifyProperties = new HashMap<>(); - // 生成 DUBBO_TAG_PROPERTIES_KEY,使用 hostname - String dubboTag = OSUtils.getHostName(); - if (!StringUtils.hasText(dubboTag)) { - dubboTag = StringUtils.uuid(true); // 兜底,强行生成一个 - } - modifyProperties.put(DUBBO_TAG_PROPERTIES_KEY, dubboTag); - // 添加到 environment 中,排在最优,最低优先级 - addOrReplace(environment.getPropertySources(), modifyProperties); - } - - private void addOrReplace(MutablePropertySources propertySources, Map map) { - if (CollectionUtils.isEmpty(map)) { - return; - } - // 情况一,如果存在 defaultProperties 的 PropertySource,则进行 key 的修改 - if (propertySources.contains(PROPERTY_SOURCE_NAME)) { - PropertySource source = propertySources.get(PROPERTY_SOURCE_NAME); - if (source instanceof MapPropertySource) { - MapPropertySource target = (MapPropertySource) source; - for (String key : map.keySet()) { - target.getSource().put(key, map.get(key)); - } - } - return; - } - // 情况二,不存在 defaultProperties 的 PropertySource,则直接添加到其中 - propertySources.addLast(new MapPropertySource(PROPERTY_SOURCE_NAME, map)); - } - -} diff --git a/归档/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/spring.factories b/归档/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 25dddc37..00000000 --- a/归档/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.env.EnvironmentPostProcessor=\ - cn.iocoder.mall.dubbo.config.DubboEnvironmentPostProcessor