From 2e9e3c7ca7b187f94ad4b1b47be7d171343273f1 Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 5 Aug 2019 14:48:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=A2=84=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E3=80=81=E7=81=B0=E5=BA=A6=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 4 ++ sop-1.14.0.sql | 1 + sop-admin/sop-admin-server/pom.xml | 2 +- .../SopAdminServerApplication.java | 4 -- .../adminserver/api/service/ServiceApi.java | 16 ++++- .../adminserver/bean/UserKeyDefinition.java | 2 +- .../sop/adminserver/common/StatusEnum.java | 26 ++++++++ .../adminserver/entity/ConfigGrayUserkey.java | 3 + .../main/resources/application-dev.properties | 4 ++ .../src/views/service/serviceList.vue | 8 +-- .../sop/gatewaycommon/bean/ApiConfig.java | 17 +++-- .../sop/gatewaycommon/bean/SpringContext.java | 13 ++-- .../gatewaycommon/bean/UserKeyDefinition.java | 2 +- .../gateway/filter/ValidateFilter.java | 14 +++-- .../manager/AbstractConfiguration.java | 35 +++++++++++ .../manager/DefaultUserKeyManager.java | 51 +++++++++++++++ .../gatewaycommon/manager/ManagerContext.java | 24 +++++++ .../gatewaycommon/manager/UserKeyManager.java | 15 +++++ .../sop/gatewaycommon/param/ParamNames.java | 2 +- .../gatewaycommon/validate/ApiValidator.java | 35 ++++++----- .../sop/gatewaycommon/zuul/ZuulContext.java | 14 ----- .../configuration/BaseZuulConfiguration.java | 9 ++- .../zuul/filter/PreLimitFilter.java | 10 ++- .../zuul/filter/PreRoutePermissionFilter.java | 7 ++- .../zuul/filter/PreValidateFilter.java | 15 +++-- .../EnvHttpRequestInterceptor.java | 23 +++++++ .../HystrixRequestVariableContext.java | 18 ++++++ .../zuul}/loadbalancer/ServiceGrayConfig.java | 2 +- .../zuul/route/ZuulZookeeperRouteManager.java | 2 +- .../sop/servercommon/bean/ParamNames.java | 2 +- .../mapping/ApiMappingRequestCondition.java | 1 - .../storyweb/controller/AlipayController.java | 7 ++- .../sop/gateway/config/GatewayConfig.java | 4 -- .../gitee/sop/gateway/config/ZuulConfig.java | 5 -- .../sop/gateway/entity/ConfigGrayUserkey.java | 3 + .../EnvironmentServerChooser.java | 13 ++-- .../gateway/manager/DbIPBlacklistManager.java | 2 + .../sop/gateway/manager/DbIsvManager.java | 4 ++ .../manager/DbIsvRoutePermissionManager.java | 2 + .../gateway/manager/DbLimitConfigManager.java | 2 + .../gateway/manager/DbRouteConfigManager.java | 2 + ...rKeyManager.java => DbUserKeyManager.java} | 62 +++++++------------ .../gateway/manager/ManagerInitializer.java | 1 + .../gitee/sop/test/AlipayClientPostTest.java | 31 ++++++++++ sop.sql | 1 + 45 files changed, 383 insertions(+), 137 deletions(-) create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/StatusEnum.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultUserKeyManager.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/UserKeyManager.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/EnvHttpRequestInterceptor.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/HystrixRequestVariableContext.java rename {sop-gateway/src/main/java/com/gitee/sop/gateway => sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul}/loadbalancer/ServiceGrayConfig.java (92%) rename sop-gateway/src/main/java/com/gitee/sop/gateway/manager/{UserKeyManager.java => DbUserKeyManager.java} (65%) diff --git a/changelog.md b/changelog.md index 251584a7..85cb353d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # changelog +## 1.14.0 + +- 支持预发布、灰度发布环境 + ## 1.13.4 - 修复admin服务列表最后更新时间不显示问题 diff --git a/sop-1.14.0.sql b/sop-1.14.0.sql index d84dadbb..b2669e93 100644 --- a/sop-1.14.0.sql +++ b/sop-1.14.0.sql @@ -5,6 +5,7 @@ CREATE TABLE `config_gray_userkey` ( `instance_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'serviceId', `user_key_content` text COMMENT '用户key,多个用引文逗号隔开', `name_version_content` text COMMENT '需要灰度的接口,goods.get=1.2,order.list=1.2', + `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '0:禁用,1:启用', `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index 8e5bb49c..5a04b2bb 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -25,7 +25,7 @@ 4.0.1 3.11.0 1.16.2 - 1.8.0 + 1.8.1 diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/SopAdminServerApplication.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/SopAdminServerApplication.java index dc6f561e..e388660d 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/SopAdminServerApplication.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/SopAdminServerApplication.java @@ -1,16 +1,12 @@ package com.gitee.sop.adminserver; -import com.gitee.fastmybatis.core.FastmybatisConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import java.util.Arrays; - @SpringBootApplication public class SopAdminServerApplication { public static void main(String[] args) { - FastmybatisConfig.defaultIgnoreUpdateColumns = Arrays.asList("gmt_create", "gmt_modified"); SpringApplication.run(SopAdminServerApplication.class, args); } } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java index aa4e6b9c..8dbf3364 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java @@ -19,6 +19,7 @@ import com.gitee.sop.adminserver.bean.UserKeyDefinition; import com.gitee.sop.adminserver.bean.ZookeeperContext; import com.gitee.sop.adminserver.common.BizException; import com.gitee.sop.adminserver.common.ChannelOperation; +import com.gitee.sop.adminserver.common.StatusEnum; import com.gitee.sop.adminserver.common.ZookeeperPathExistException; import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException; import com.gitee.sop.adminserver.entity.ConfigGrayUserkey; @@ -49,6 +50,7 @@ import java.util.stream.Collectors; @Slf4j public class ServiceApi { + @Autowired private RegistryService registryService; @@ -219,10 +221,12 @@ public class ServiceApi { configGrayUserkey.setInstanceId(instanceId); configGrayUserkey.setUserKeyContent(userKeyContent); configGrayUserkey.setNameVersionContent(nameVersionContent); + configGrayUserkey.setStatus(StatusEnum.STATUS_ENABLE.getStatus()); configGrayUserkeyMapper.save(configGrayUserkey); } else { configGrayUserkey.setUserKeyContent(userKeyContent); configGrayUserkey.setNameVersionContent(nameVersionContent); + configGrayUserkey.setStatus(StatusEnum.STATUS_ENABLE.getStatus()); configGrayUserkeyMapper.update(configGrayUserkey); } this.sendUserKeyMsg(instanceId, ChannelOperation.GRAY_USER_KEY_SET); @@ -238,7 +242,13 @@ public class ServiceApi { try { MetadataEnum envPre = MetadataEnum.ENV_ONLINE; registryService.setMetadata(param, envPre.getKey(), envPre.getValue()); - this.sendUserKeyMsg(param.getServiceId(), ChannelOperation.GRAY_USER_KEY_CLEAR); + + ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("instance_id", param.getInstanceId()); + if (configGrayUserkey != null && configGrayUserkey.getStatus() == StatusEnum.STATUS_ENABLE.getStatus()) { + configGrayUserkey.setStatus(StatusEnum.STATUS_DISABLE.getStatus()); + configGrayUserkeyMapper.update(configGrayUserkey); + } + this.sendUserKeyMsg(param.getInstanceId(), ChannelOperation.GRAY_USER_KEY_CLEAR); } catch (Exception e) { log.error("上线失败,param:{}", param, e); throw new BizException("上线失败,请查看日志"); @@ -250,9 +260,9 @@ public class ServiceApi { return configGrayUserkeyMapper.getByColumn("instance_id", param.getInstanceId()); } - private void sendUserKeyMsg(String serviceId, ChannelOperation channelOperation) { + private void sendUserKeyMsg(String instanceId, ChannelOperation channelOperation) { UserKeyDefinition userKeyDefinition = new UserKeyDefinition(); - userKeyDefinition.setServiceId(serviceId); + userKeyDefinition.setInstanceId(instanceId); ChannelMsg channelMsg = new ChannelMsg(channelOperation, userKeyDefinition); String jsonData = JSON.toJSONString(channelMsg); String path = ZookeeperContext.getUserKeyChannelPath(); diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/UserKeyDefinition.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/UserKeyDefinition.java index 9fe32449..ffb6cb9b 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/UserKeyDefinition.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/UserKeyDefinition.java @@ -7,6 +7,6 @@ import lombok.Data; */ @Data public class UserKeyDefinition { - private String serviceId; + private String instanceId; private String data; } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/StatusEnum.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/StatusEnum.java new file mode 100644 index 00000000..14ec863e --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/StatusEnum.java @@ -0,0 +1,26 @@ +package com.gitee.sop.adminserver.common; + +import lombok.Getter; + +/** + * 通用状态枚举 + * + * @author tanghc + */ +@Getter +public enum StatusEnum { + /** + * 启用 + */ + STATUS_ENABLE((byte)1), + /** + * 禁用 + */ + STATUS_DISABLE((byte)0), + ; + private byte status; + + StatusEnum(byte status) { + this.status = status; + } +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java index 1bd13466..531a76c6 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java @@ -34,6 +34,9 @@ public class ConfigGrayUserkey { /** 需要灰度的接口,goods.get=1.2,order.list=1.2, 数据库字段:name_version_content */ private String nameVersionContent; + /** 0:禁用,1:启用, 数据库字段:status */ + private Byte status; + /** 数据库字段:gmt_create */ private Date gmtCreate; diff --git a/sop-admin/sop-admin-server/src/main/resources/application-dev.properties b/sop-admin/sop-admin-server/src/main/resources/application-dev.properties index de57a517..ff14b565 100644 --- a/sop-admin/sop-admin-server/src/main/resources/application-dev.properties +++ b/sop-admin/sop-admin-server/src/main/resources/application-dev.properties @@ -44,5 +44,9 @@ registry.name=eureka logging.level.com.gitee=debug +# 不用改 +mybatis.ignore-update-columns[0]=gmt_create +mybatis.ignore-update-columns[1]=gmt_modified + # 不用改,如果要改,请全局替换修改 zuul.secret=MZZOUSTua6LzApIWXCwEgbBmxSzpzC diff --git a/sop-admin/sop-admin-vue/src/views/service/serviceList.vue b/sop-admin/sop-admin-vue/src/views/service/serviceList.vue index 53cd1cf1..a9ea6b71 100644 --- a/sop-admin/sop-admin-vue/src/views/service/serviceList.vue +++ b/sop-admin/sop-admin-vue/src/views/service/serviceList.vue @@ -163,7 +163,7 @@ - 删除 + 删除 @@ -203,11 +203,7 @@ export default { ipPort: '', userKeyContent: '', onlyUpdateGrayUserkey: false, - grayRouteConfigList: [{ - oldRouteId: '', - newVersion: '', - key: Date.now() - }] + grayRouteConfigList: [] }, tabsActiveName: 'first', routeList: [], diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java index 89afbc9b..47853f38 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java @@ -10,11 +10,13 @@ import com.gitee.sop.gatewaycommon.manager.DefaultIsvRoutePermissionManager; import com.gitee.sop.gatewaycommon.manager.DefaultLimitConfigManager; import com.gitee.sop.gatewaycommon.manager.DefaultRouteConfigManager; import com.gitee.sop.gatewaycommon.manager.DefaultServiceErrorManager; +import com.gitee.sop.gatewaycommon.manager.DefaultUserKeyManager; import com.gitee.sop.gatewaycommon.manager.IPBlacklistManager; import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager; import com.gitee.sop.gatewaycommon.manager.LimitConfigManager; import com.gitee.sop.gatewaycommon.manager.RouteConfigManager; import com.gitee.sop.gatewaycommon.manager.ServiceErrorManager; +import com.gitee.sop.gatewaycommon.manager.UserKeyManager; import com.gitee.sop.gatewaycommon.param.ParamBuilder; import com.gitee.sop.gatewaycommon.result.DataNameBuilder; import com.gitee.sop.gatewaycommon.result.DefaultDataNameBuilder; @@ -97,11 +99,6 @@ public class ApiConfig { */ private SessionManager sessionManager = new ApiSessionManager(); - /** - * zuul网关全局异常处理 - */ - private ZuulErrorController zuulErrorController = new ZuulErrorController(); - /** * isv路由权限 */ @@ -127,6 +124,11 @@ public class ApiConfig { */ private LimitManager limitManager = new DefaultLimitManager(); + /** + * 用户key管理 + */ + private UserKeyManager userKeyManager = new DefaultUserKeyManager(); + /** * 构建数据节点名称 */ @@ -142,6 +144,11 @@ public class ApiConfig { */ private ServiceErrorManager serviceErrorManager = new DefaultServiceErrorManager(); + /** + * zuul网关全局异常处理 + */ + private ZuulErrorController zuulErrorController = new ZuulErrorController(); + // -------- fields --------- /** diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SpringContext.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SpringContext.java index d72b2df0..1073fe44 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SpringContext.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SpringContext.java @@ -1,21 +1,14 @@ package com.gitee.sop.gatewaycommon.bean; -import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; /** * @author tanghc */ -public class SpringContext implements ApplicationContextAware { +public class SpringContext { private static ApplicationContext ctx; - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - ctx = applicationContext; - } - public static T getBean(Class clazz) { return ctx.getBean(clazz); } @@ -24,6 +17,10 @@ public class SpringContext implements ApplicationContextAware { return ctx.getBean(beanName); } + public static void setApplicationContext(ApplicationContext ctx) { + SpringContext.ctx = ctx; + } + public static ApplicationContext getApplicationContext() { return ctx; } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/UserKeyDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/UserKeyDefinition.java index 1c092ca8..0889d4cb 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/UserKeyDefinition.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/UserKeyDefinition.java @@ -7,6 +7,6 @@ import lombok.Data; */ @Data public class UserKeyDefinition { - private String serviceId; + private String instanceId; private String data; } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/ValidateFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/ValidateFilter.java index 36911028..66e3e928 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/ValidateFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/ValidateFilter.java @@ -1,12 +1,12 @@ package com.gitee.sop.gatewaycommon.gateway.filter; -import com.gitee.sop.gatewaycommon.bean.ApiConfig; -import com.gitee.sop.gatewaycommon.bean.ApiContext; import com.gitee.sop.gatewaycommon.exception.ApiException; import com.gitee.sop.gatewaycommon.gateway.GatewayContext; import com.gitee.sop.gatewaycommon.param.ApiParam; +import com.gitee.sop.gatewaycommon.param.ParamBuilder; import com.gitee.sop.gatewaycommon.validate.Validator; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; @@ -19,14 +19,18 @@ import reactor.core.publisher.Mono; @Slf4j public class ValidateFilter implements GlobalFilter, Ordered { + @Autowired + private ParamBuilder paramBuilder; + + @Autowired + private Validator validator; + @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - ApiConfig apiConfig = ApiContext.getApiConfig(); // 解析参数 - ApiParam param = apiConfig.getGatewayParamBuilder().build(exchange); + ApiParam param = paramBuilder.build(exchange); GatewayContext.setApiParam(exchange, param); // 验证操作,这里有负责验证签名参数 - Validator validator = apiConfig.getValidator(); try { validator.validate(param); } catch (ApiException e) { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java index fa8abada..8e14007a 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java @@ -3,10 +3,15 @@ package com.gitee.sop.gatewaycommon.manager; import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ApiContext; import com.gitee.sop.gatewaycommon.bean.BeanInitializer; +import com.gitee.sop.gatewaycommon.bean.SpringContext; +import com.gitee.sop.gatewaycommon.limit.LimitManager; import com.gitee.sop.gatewaycommon.message.ErrorFactory; import com.gitee.sop.gatewaycommon.secret.IsvManager; +import com.gitee.sop.gatewaycommon.session.SessionManager; +import com.gitee.sop.gatewaycommon.validate.Validator; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; @@ -35,30 +40,59 @@ public class AbstractConfiguration implements ApplicationContextAware { } @Bean + @ConditionalOnMissingBean + Validator validator() { + return ApiConfig.getInstance().getValidator(); + } + + @Bean + @ConditionalOnMissingBean IsvManager isvManager() { return ApiConfig.getInstance().getIsvManager(); } @Bean + @ConditionalOnMissingBean IsvRoutePermissionManager isvRoutePermissionManager() { return ApiConfig.getInstance().getIsvRoutePermissionManager(); } @Bean + @ConditionalOnMissingBean RouteConfigManager routeConfigManager() { return ApiConfig.getInstance().getRouteConfigManager(); } @Bean + @ConditionalOnMissingBean LimitConfigManager limitConfigManager() { return ApiConfig.getInstance().getLimitConfigManager(); } @Bean + @ConditionalOnMissingBean + LimitManager limitManager() { + return ApiConfig.getInstance().getLimitManager(); + } + + @Bean + @ConditionalOnMissingBean IPBlacklistManager ipBlacklistManager() { return ApiConfig.getInstance().getIpBlacklistManager(); } + @Bean + @ConditionalOnMissingBean + UserKeyManager userKeyManager() { + return ApiConfig.getInstance().getUserKeyManager(); + } + + @Bean + @ConditionalOnMissingBean + SessionManager sessionManager() { + return ApiConfig.getInstance().getSessionManager(); + } + /** * 跨域过滤器 * @@ -89,6 +123,7 @@ public class AbstractConfiguration implements ApplicationContextAware { @PostConstruct public final void after() { + SpringContext.setApplicationContext(applicationContext); if (RouteRepositoryContext.getRouteRepository() == null) { throw new IllegalArgumentException("RouteRepositoryContext.setRouteRepository()方法未使用"); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultUserKeyManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultUserKeyManager.java new file mode 100644 index 00000000..fabab80b --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultUserKeyManager.java @@ -0,0 +1,51 @@ +package com.gitee.sop.gatewaycommon.manager; + +import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import java.util.Map; + +/** + * @author tanghc + */ +public class DefaultUserKeyManager implements UserKeyManager { + + /** + * KEY:instanceId + */ + private Map serviceUserKeyMap = Maps.newConcurrentMap(); + + @Override + public boolean containsKey(String instanceId, Object userKey) { + if (instanceId == null || userKey == null) { + return false; + } + return this.getServiceGrayConfig(instanceId).containsKey(userKey); + } + + @Override + public String getVersion(String instanceId, String nameVersion) { + if (instanceId == null || nameVersion == null) { + return null; + } + return this.getServiceGrayConfig(instanceId).getVersion(nameVersion); + } + + @Override + public ServiceGrayConfig getServiceGrayConfig(String instanceId) { + ServiceGrayConfig serviceGrayConfig = serviceUserKeyMap.get(instanceId); + if (serviceGrayConfig == null) { + serviceGrayConfig = new ServiceGrayConfig(); + serviceGrayConfig.setUserKeys(Sets.newConcurrentHashSet()); + serviceGrayConfig.setGrayNameVersion(Maps.newConcurrentMap()); + serviceUserKeyMap.put(instanceId, serviceGrayConfig); + } + return serviceGrayConfig; + } + + @Override + public void load() { + + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java new file mode 100644 index 00000000..aa99921f --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java @@ -0,0 +1,24 @@ +package com.gitee.sop.gatewaycommon.manager; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; + +/** + * @author tanghc + */ +public class ManagerContext { + + private static ApplicationContext ctx; + + public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + ctx = applicationContext; + } + + public static T getManager(Class clazz) { + return ctx.getBean(clazz); + } + + public static ApplicationContext getApplicationContext() { + return ctx; + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/UserKeyManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/UserKeyManager.java new file mode 100644 index 00000000..568cd597 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/UserKeyManager.java @@ -0,0 +1,15 @@ +package com.gitee.sop.gatewaycommon.manager; + +import com.gitee.sop.gatewaycommon.bean.BeanInitializer; +import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig; + +/** + * @author tanghc + */ +public interface UserKeyManager extends BeanInitializer { + boolean containsKey(String instanceId, Object userKey); + + String getVersion(String instanceId, String nameVersion); + + ServiceGrayConfig getServiceGrayConfig(String instanceId); +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ParamNames.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ParamNames.java index 8e39ae85..f58309c8 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ParamNames.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ParamNames.java @@ -45,7 +45,7 @@ public class ParamNames { /** 返回sign名称 */ public static String RESPONSE_SIGN_NAME = "sign"; - public static String HEADER_VERSION_NAME = "x-sop-version"; + public static String GRAY_HEADER_VERSION_NAME = "sop_gray_version"; } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java index 8b81e809..31463a1d 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java @@ -15,11 +15,11 @@ import com.gitee.sop.gatewaycommon.param.ApiParam; import com.gitee.sop.gatewaycommon.param.ParamNames; import com.gitee.sop.gatewaycommon.param.UploadContext; import com.gitee.sop.gatewaycommon.secret.IsvManager; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.BooleanUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.Assert; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; @@ -35,15 +35,26 @@ import java.util.List; * * @author tanghc */ +@Slf4j +@Getter public class ApiValidator implements Validator { - private static final Logger logger = LoggerFactory.getLogger(ApiValidator.class); private static final int MILLISECOND_OF_ONE_SECOND = 1000; - public static final int STATUS_FORBIDDEN = 2; - + private static final int STATUS_FORBIDDEN = 2; private static List FORMAT_LIST = Arrays.asList("json", "xml"); + @Autowired + private IsvManager isvManager; + + @Autowired + private IsvRoutePermissionManager isvRoutePermissionManager; + + @Autowired + private IPBlacklistManager ipBlacklistManager; + + @Autowired + private RouteConfigManager routeConfigManager; @Override public void validate(ApiParam param) { @@ -52,8 +63,8 @@ public class ApiValidator implements Validator { ApiConfig apiConfig = ApiContext.getApiConfig(); if (apiConfig.isIgnoreValidate() || param.fetchIgnoreValidate()) { - if (logger.isDebugEnabled()) { - logger.debug("忽略所有验证(ignoreValidate=true), name:{}, version:{}", param.fetchName(), param.fetchVersion()); + if (log.isDebugEnabled()) { + log.debug("忽略所有验证(ignoreValidate=true), name:{}, version:{}", param.fetchName(), param.fetchVersion()); } return; } @@ -71,7 +82,6 @@ public class ApiValidator implements Validator { * @param param 接口参数 */ protected void checkIP(ApiParam param) { - IPBlacklistManager ipBlacklistManager = ApiConfig.getInstance().getIpBlacklistManager(); String ip = param.fetchIp(); if (ipBlacklistManager.contains(ip)) { throw ErrorEnum.ISV_IP_FORBIDDEN.getErrorMeta().getException(); @@ -87,7 +97,6 @@ public class ApiValidator implements Validator { // 检查路由是否存在 RouteRepositoryContext.checkExist(routeId, ErrorEnum.ISV_INVALID_METHOD); // 检查路由是否启用 - RouteConfigManager routeConfigManager = ApiConfig.getInstance().getRouteConfigManager(); RouteConfig routeConfig = routeConfigManager.get(routeId); if (!routeConfig.enable()) { throw ErrorEnum.ISP_API_DISABLED.getErrorMeta().getException(); @@ -115,7 +124,7 @@ public class ApiValidator implements Validator { } } } catch (IOException e) { - logger.error("验证上传文件MD5错误", e); + log.error("验证上传文件MD5错误", e); throw ErrorEnum.ISV_UPLOAD_FAIL.getErrorMeta().getException(); } } @@ -147,8 +156,6 @@ public class ApiValidator implements Validator { if (StringUtils.isEmpty(param.fetchAppKey())) { throw ErrorEnum.ISV_MISSING_APP_ID.getErrorMeta().getException(); } - IsvManager isvManager = ApiContext.getApiConfig().getIsvManager(); - Assert.notNull(isvManager, "isvManager未初始化"); Isv isv = isvManager.getIsv(param.fetchAppKey()); // 没有用户 if (isv == null) { @@ -167,7 +174,6 @@ public class ApiValidator implements Validator { throw ErrorEnum.ISV_MISSING_SIGNATURE.getErrorMeta().getException(param.fetchNameVersion(), ParamNames.SIGN_NAME); } ApiConfig apiConfig = ApiContext.getApiConfig(); - IsvManager isvManager = apiConfig.getIsvManager(); // 根据appId获取秘钥 Isv isvInfo = isvManager.getIsv(param.fetchAppKey()); String secret = isvInfo.getSecretInfo(); @@ -205,7 +211,6 @@ public class ApiValidator implements Validator { BaseRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission()); if (needCheckPermission) { - IsvRoutePermissionManager isvRoutePermissionManager = ApiConfig.getInstance().getIsvRoutePermissionManager(); String appKey = apiParam.fetchAppKey(); boolean hasPermission = isvRoutePermissionManager.hasPermission(appKey, routeId); if (!hasPermission) { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ZuulContext.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ZuulContext.java index 3c40c836..6ad62646 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ZuulContext.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/ZuulContext.java @@ -69,20 +69,6 @@ public class ZuulContext extends ApiContext { } - /** - * 返回自定义的session,被SessionManager管理 - * - * @return 如果sessionId为null,则返回null - */ - public static HttpSession getManagedSession() { - String sessionId = getSessionId(); - if (sessionId != null) { - return getSessionManager().getSession(sessionId); - } else { - return null; - } - } - /** * 获取登陆的token * diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java index 849f0047..bd7b8a29 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java @@ -1,9 +1,10 @@ package com.gitee.sop.gatewaycommon.zuul.configuration; +import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ApiContext; -import com.gitee.sop.gatewaycommon.bean.SpringContext; import com.gitee.sop.gatewaycommon.manager.AbstractConfiguration; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; +import com.gitee.sop.gatewaycommon.param.ParamBuilder; import com.gitee.sop.gatewaycommon.zuul.filter.ErrorFilter; import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt; import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter; @@ -14,6 +15,7 @@ import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt; import com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator; import com.gitee.sop.gatewaycommon.zuul.route.ZuulRouteRepository; import com.gitee.sop.gatewaycommon.zuul.route.ZuulZookeeperRouteManager; +import com.netflix.zuul.context.RequestContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.web.ServerProperties; @@ -37,8 +39,8 @@ public class BaseZuulConfiguration extends AbstractConfiguration { @Bean @ConditionalOnMissingBean - SpringContext springContext() { - return new SpringContext(); + ParamBuilder paramBuilder() { + return ApiConfig.getInstance().getZuulParamBuilder(); } /** @@ -129,6 +131,7 @@ public class BaseZuulConfiguration extends AbstractConfiguration { * 统一错误处理 */ @Bean + @ConditionalOnMissingBean ZuulErrorController baseZuulController() { return ApiContext.getApiConfig().getZuulErrorController(); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreLimitFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreLimitFilter.java index 8649ad2a..f6b2caf6 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreLimitFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreLimitFilter.java @@ -12,6 +12,7 @@ import com.gitee.sop.gatewaycommon.util.RequestUtil; import com.gitee.sop.gatewaycommon.zuul.ZuulContext; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; +import org.springframework.beans.factory.annotation.Autowired; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; @@ -26,6 +27,12 @@ import java.util.List; */ public class PreLimitFilter extends BaseZuulFilter { + @Autowired + private LimitManager limitManager; + + @Autowired + private LimitConfigManager limitConfigManager; + @Override protected FilterType getFilterType() { return FilterType.PRE; @@ -53,7 +60,6 @@ public class PreLimitFilter extends BaseZuulFilter { return null; } byte limitType = configLimitDto.getLimitType().byteValue(); - LimitManager limitManager = ApiConfig.getInstance().getLimitManager(); // 如果是漏桶策略 if (limitType == LimitType.LEAKY_BUCKET.getType()) { boolean acquire = limitManager.acquire(configLimitDto); @@ -67,8 +73,6 @@ public class PreLimitFilter extends BaseZuulFilter { } protected ConfigLimitDto findConfigLimitDto(ApiConfig apiConfig, ApiParam apiParam, HttpServletRequest request) { - LimitConfigManager limitConfigManager = apiConfig.getLimitConfigManager(); - String routeId = apiParam.fetchNameVersion(); String appKey = apiParam.fetchAppKey(); String ip = RequestUtil.getIP(request); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java index b100dc8e..c693f9b5 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java @@ -1,6 +1,5 @@ package com.gitee.sop.gatewaycommon.zuul.filter; -import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; import com.gitee.sop.gatewaycommon.bean.TargetRoute; import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager; @@ -11,6 +10,7 @@ import com.gitee.sop.gatewaycommon.zuul.ZuulContext; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; /** * 路由权限校验,有些接口需要配置权限才能访问。 @@ -19,6 +19,10 @@ import org.apache.commons.lang3.BooleanUtils; */ @Deprecated public class PreRoutePermissionFilter extends BaseZuulFilter { + + @Autowired + private IsvRoutePermissionManager isvRoutePermissionManager; + @Override protected FilterType getFilterType() { return FilterType.PRE; @@ -38,7 +42,6 @@ public class PreRoutePermissionFilter extends BaseZuulFilter { BaseRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission()); if (needCheckPermission) { - IsvRoutePermissionManager isvRoutePermissionManager = ApiConfig.getInstance().getIsvRoutePermissionManager(); String appKey = apiParam.fetchAppKey(); boolean hasPermission = isvRoutePermissionManager.hasPermission(appKey, routeId); if (!hasPermission) { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java index 9164635b..41999b66 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java @@ -1,13 +1,13 @@ package com.gitee.sop.gatewaycommon.zuul.filter; -import com.gitee.sop.gatewaycommon.bean.ApiConfig; -import com.gitee.sop.gatewaycommon.bean.ApiContext; import com.gitee.sop.gatewaycommon.exception.ApiException; import com.gitee.sop.gatewaycommon.param.ApiParam; +import com.gitee.sop.gatewaycommon.param.ParamBuilder; import com.gitee.sop.gatewaycommon.validate.Validator; import com.gitee.sop.gatewaycommon.zuul.ZuulContext; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; +import org.springframework.beans.factory.annotation.Autowired; /** * 前置校验 @@ -15,6 +15,13 @@ import com.netflix.zuul.exception.ZuulException; * @author tanghc */ public class PreValidateFilter extends BaseZuulFilter { + + @Autowired + private ParamBuilder paramBuilder; + + @Autowired + private Validator validator; + @Override protected FilterType getFilterType() { return FilterType.PRE; @@ -27,12 +34,10 @@ public class PreValidateFilter extends BaseZuulFilter { @Override protected Object doRun(RequestContext requestContext) throws ZuulException { - ApiConfig apiConfig = ApiContext.getApiConfig(); // 解析参数 - ApiParam param = apiConfig.getZuulParamBuilder().build(requestContext); + ApiParam param = paramBuilder.build(requestContext); ZuulContext.setApiParam(param); // 验证操作,这里有负责验证签名参数 - Validator validator = apiConfig.getValidator(); try { validator.validate(param); } catch (ApiException e) { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/EnvHttpRequestInterceptor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/EnvHttpRequestInterceptor.java new file mode 100644 index 00000000..9f924f55 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/EnvHttpRequestInterceptor.java @@ -0,0 +1,23 @@ +package com.gitee.sop.gatewaycommon.zuul.loadbalancer; + +import com.gitee.sop.gatewaycommon.param.ParamNames; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.support.HttpRequestWrapper; + +import java.io.IOException; + +/** + * @author tanghc + */ +public class EnvHttpRequestInterceptor implements ClientHttpRequestInterceptor { + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request); + String newVersion = HystrixRequestVariableContext.getVersion(); + requestWrapper.getHeaders().add(ParamNames.GRAY_HEADER_VERSION_NAME, newVersion); + return execution.execute(requestWrapper, body); + } +} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/HystrixRequestVariableContext.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/HystrixRequestVariableContext.java new file mode 100644 index 00000000..a4d4901c --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/HystrixRequestVariableContext.java @@ -0,0 +1,18 @@ +package com.gitee.sop.gatewaycommon.zuul.loadbalancer; + +/** + * @author tanghc + */ +public class HystrixRequestVariableContext { +// private static final HystrixRequestVariableDefault VERSION_HOLDER = new HystrixRequestVariableDefault<>(); + private static final ThreadLocal VERSION_HOLDER = new ThreadLocal<>(); + + public static void setVersion(String version) { + VERSION_HOLDER.set(version); + } + + public static String getVersion() { + return VERSION_HOLDER.get(); + } + +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/ServiceGrayConfig.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java similarity index 92% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/ServiceGrayConfig.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java index de737157..049f1f45 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/ServiceGrayConfig.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java @@ -1,4 +1,4 @@ -package com.gitee.sop.gateway.loadbalancer; +package com.gitee.sop.gatewaycommon.zuul.loadbalancer; import lombok.Data; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java index 7ccab8f0..3e0cb7b8 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java @@ -34,7 +34,7 @@ public class ZuulZookeeperRouteManager extends BaseRouteManager { - public static final String UTF_8 = "UTF-8"; private String defaultVersion = ServiceConfig.getInstance().getDefaultVersion(); private ApiMappingInfo apiMappingInfo; diff --git a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java index c22509cb..c47819b4 100644 --- a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java +++ b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java @@ -130,7 +130,7 @@ public class AlipayController { public Story getStory() { Story story = new Story(); story.setId(1); - story.setName("海底小纵队(alipay.story.get),2222"); + story.setName("海底小纵队(alipay.story.get1.0)"); return story; } @@ -160,7 +160,10 @@ public class AlipayController { */ @ApiMapping(value = "alipay.story.get", version = "1.2") public Story getStory11(Story story) { - return story; + Story story2 = new Story(); + story2.setId(1); + story2.setName("海底小纵队(alipay.story.get1.2)"); + return story2; } /** diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/GatewayConfig.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/GatewayConfig.java index 6b103018..3345063d 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/GatewayConfig.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/GatewayConfig.java @@ -1,6 +1,5 @@ package com.gitee.sop.gateway.config; -import com.gitee.sop.gateway.manager.ManagerInitializer; import com.gitee.sop.gatewaycommon.gateway.configuration.AlipayGatewayConfiguration; @@ -20,9 +19,6 @@ import com.gitee.sop.gatewaycommon.gateway.configuration.AlipayGatewayConfigurat //@Configuration public class GatewayConfig extends AlipayGatewayConfiguration { - static { - new ManagerInitializer(); - } } /** diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java index 3dfe7ba7..d5f66cd6 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java @@ -7,7 +7,6 @@ package com.gitee.sop.gateway.config; */ import com.gitee.sop.gateway.loadbalancer.SopPropertiesFactory; -import com.gitee.sop.gateway.manager.ManagerInitializer; import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration; import org.springframework.cloud.netflix.ribbon.PropertiesFactory; import org.springframework.context.annotation.Bean; @@ -20,10 +19,6 @@ import org.springframework.context.annotation.Configuration; @Configuration public class ZuulConfig extends AlipayZuulConfiguration { - static { - new ManagerInitializer(); - } - @Bean PropertiesFactory propertiesFactory() { return new SopPropertiesFactory(); diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayUserkey.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayUserkey.java index d496a0d0..a69a2f72 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayUserkey.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayUserkey.java @@ -34,6 +34,9 @@ public class ConfigGrayUserkey { /** 需要灰度的接口,goods.get=1.2,order.list=1.2, 数据库字段:name_version_content */ private String nameVersionContent; + /** 0:禁用,1:启用, 数据库字段:status */ + private Byte status; + /** 数据库字段:gmt_create */ private Date gmtCreate; diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java index 0003f89a..2ff9be85 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java @@ -1,6 +1,6 @@ package com.gitee.sop.gateway.loadbalancer; -import com.gitee.sop.gateway.manager.UserKeyManager; +import com.gitee.sop.gateway.manager.DbUserKeyManager; import com.gitee.sop.gatewaycommon.bean.SpringContext; import com.gitee.sop.gatewaycommon.param.ApiParam; import com.gitee.sop.gatewaycommon.param.Param; @@ -83,14 +83,15 @@ public class EnvironmentServerChooser extends BaseServerChooser { */ protected boolean canVisitGray(Server server, HttpServletRequest request) { ApiParam apiParam = ZuulContext.getApiParam(); - UserKeyManager userKeyManager = SpringContext.getBean(UserKeyManager.class); + DbUserKeyManager userKeyManager = SpringContext.getBean(DbUserKeyManager.class); boolean canVisit = false; if (this.isGrayUser(apiParam, userKeyManager, server, request)) { // 指定灰度版本号 - String instanceId = server.getId(); + String instanceId = server.getMetaInfo().getInstanceId(); String newVersion = userKeyManager.getVersion(instanceId, apiParam.fetchNameVersion()); if (newVersion != null) { - RequestContext.getCurrentContext().getZuulRequestHeaders().put(ParamNames.HEADER_VERSION_NAME, newVersion); + // 在header中设置新的版本号,然后微服务端先获取这个新版本号 + RequestContext.getCurrentContext().addZuulRequestHeader(ParamNames.GRAY_HEADER_VERSION_NAME, newVersion); canVisit = true; } } @@ -107,8 +108,8 @@ public class EnvironmentServerChooser extends BaseServerChooser { * @param request request * @return true:是 */ - protected boolean isGrayUser(Param param, UserKeyManager userKeyManager, Server server, HttpServletRequest request) { - String instanceId = server.getId(); + protected boolean isGrayUser(Param param, DbUserKeyManager userKeyManager, Server server, HttpServletRequest request) { + String instanceId = server.getMetaInfo().getInstanceId(); // 这里的灰度用户为appKey,包含此appKey则为灰度用户,允许访问 String appKey = param.fetchAppKey(); return userKeyManager.containsKey(instanceId, appKey); diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java index 30788c85..8f97e349 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java @@ -9,6 +9,7 @@ import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.List; @@ -19,6 +20,7 @@ import java.util.List; * @author tanghc */ @Slf4j +@Service public class DbIPBlacklistManager extends DefaultIPBlacklistManager { @Autowired diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java index 3a58efae..51cc9b2c 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java @@ -3,6 +3,7 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; import com.gitee.sop.gateway.entity.IsvDetailDTO; import com.gitee.sop.gateway.mapper.IsvInfoMapper; +import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; import com.gitee.sop.gatewaycommon.bean.IsvDefinition; import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; @@ -11,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.List; @@ -19,6 +21,7 @@ import java.util.List; * @author tanghc */ @Slf4j +@Service public class DbIsvManager extends CacheIsvManager { @Autowired @@ -41,6 +44,7 @@ public class DbIsvManager extends CacheIsvManager { @PostConstruct protected void after() throws Exception { + ApiConfig.getInstance().setIsvManager(this); ZookeeperContext.setEnvironment(environment); String isvChannelPath = ZookeeperContext.getIsvInfoChannelPath(); ZookeeperContext.listenPath(isvChannelPath, nodeCache -> { diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java index 0f8132fb..2162d0e7 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java @@ -17,6 +17,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.PostConstruct; @@ -35,6 +36,7 @@ import static java.util.stream.Collectors.toList; * @author tanghc */ @Slf4j +@Service public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManager { @Autowired diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java index 3df9f051..9804f492 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java @@ -11,6 +11,7 @@ import com.gitee.sop.gatewaycommon.util.MyBeanUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @@ -19,6 +20,7 @@ import javax.annotation.PostConstruct; * @author tanghc */ @Slf4j +@Service public class DbLimitConfigManager extends DefaultLimitConfigManager { @Autowired diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java index 004eed57..6c5a9674 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java @@ -14,6 +14,7 @@ import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.Collection; @@ -22,6 +23,7 @@ import java.util.Collection; * @author tanghc */ @Slf4j +@Service public class DbRouteConfigManager extends DefaultRouteConfigManager { @Autowired diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/UserKeyManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbUserKeyManager.java similarity index 65% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/manager/UserKeyManager.java rename to sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbUserKeyManager.java index 6dddaeb4..a4b12ec6 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/UserKeyManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbUserKeyManager.java @@ -1,14 +1,14 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.gateway.entity.ConfigGrayUserkey; -import com.gitee.sop.gateway.loadbalancer.ServiceGrayConfig; import com.gitee.sop.gateway.mapper.ConfigGrayUserkeyMapper; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; import com.gitee.sop.gatewaycommon.bean.UserKeyDefinition; +import com.gitee.sop.gatewaycommon.manager.DefaultUserKeyManager; import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -27,14 +27,11 @@ import java.util.stream.Stream; * * @author tanghc */ -@Service @Slf4j -public class UserKeyManager { +@Service +public class DbUserKeyManager extends DefaultUserKeyManager { - /** - * KEY:instanceId - */ - private Map serviceUserKeyMap = Maps.newConcurrentMap(); + private static final int STATUS_ENABLE = 1; @Autowired private Environment environment; @@ -42,18 +39,14 @@ public class UserKeyManager { @Autowired private ConfigGrayUserkeyMapper configGrayUserkeyMapper; - public boolean containsKey(String serviceId, Object userKey) { - if (serviceId == null || userKey == null) { - return false; + @Override + public void load() { + Query query = new Query(); + query.eq("status", STATUS_ENABLE); + List list = configGrayUserkeyMapper.list(query); + for (ConfigGrayUserkey configGrayUserkey : list) { + this.setServiceGrayConfig(configGrayUserkey); } - return this.getServiceGrayConfig(serviceId).containsKey(userKey); - } - - public String getVersion(String serviceId, String nameVersion) { - if (serviceId == null || nameVersion == null) { - return null; - } - return this.getServiceGrayConfig(serviceId).getVersion(nameVersion); } /** @@ -61,11 +54,12 @@ public class UserKeyManager { * * @param configGrayUserkey 灰度配置 */ - public void setServiceGrayConfig(String serviceId, ConfigGrayUserkey configGrayUserkey) { + public void setServiceGrayConfig(ConfigGrayUserkey configGrayUserkey) { if (configGrayUserkey == null) { return; } - this.clear(serviceId); + String instanceId = configGrayUserkey.getInstanceId(); + this.clear(instanceId); String userKeyData = configGrayUserkey.getUserKeyContent(); String nameVersionContent = configGrayUserkey.getNameVersionContent(); String[] userKeys = StringUtils.split(userKeyData, ','); @@ -73,7 +67,7 @@ public class UserKeyManager { log.info("添加userKey,userKeys.length:{}, nameVersionList:{}", userKeys.length, Arrays.toString(nameVersionList)); List list = Stream.of(userKeys).collect(Collectors.toList()); - ServiceGrayConfig serviceGrayConfig = getServiceGrayConfig(serviceId); + ServiceGrayConfig serviceGrayConfig = getServiceGrayConfig(instanceId); serviceGrayConfig.getUserKeys().addAll(list); Map grayNameVersion = serviceGrayConfig.getGrayNameVersion(); @@ -89,20 +83,10 @@ public class UserKeyManager { /** * 清空用户key */ - public void clear(String serviceId) { - getServiceGrayConfig(serviceId).clear(); + public void clear(String instanceId) { + getServiceGrayConfig(instanceId).clear(); } - public ServiceGrayConfig getServiceGrayConfig(String serviceId) { - ServiceGrayConfig serviceGrayConfig = serviceUserKeyMap.get(serviceId); - if (serviceGrayConfig == null) { - serviceGrayConfig = new ServiceGrayConfig(); - serviceGrayConfig.setUserKeys(Sets.newConcurrentHashSet()); - serviceGrayConfig.setGrayNameVersion(Maps.newConcurrentMap()); - serviceUserKeyMap.put(serviceId, serviceGrayConfig); - } - return serviceGrayConfig; - } @PostConstruct protected void after() throws Exception { @@ -113,14 +97,14 @@ public class UserKeyManager { ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class); String data = channelMsg.getData(); UserKeyDefinition userKeyDefinition = JSON.parseObject(data, UserKeyDefinition.class); - String serviceId = userKeyDefinition.getServiceId(); + String instanceId = userKeyDefinition.getInstanceId(); switch (channelMsg.getOperation()) { case "set": - ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("service_id", serviceId); - this.setServiceGrayConfig(serviceId, configGrayUserkey); + ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("instance_id", instanceId); + this.setServiceGrayConfig(configGrayUserkey); break; case "clear": - clear(serviceId); + clear(instanceId); break; default: log.error("userKey消息,错误的消息指令,nodeData:{}", nodeData); diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java index 0a59778b..d36cd8fc 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java @@ -14,5 +14,6 @@ public class ManagerInitializer { apiConfig.setRouteConfigManager(new DbRouteConfigManager()); apiConfig.setLimitConfigManager(new DbLimitConfigManager()); apiConfig.setIpBlacklistManager(new DbIPBlacklistManager()); + apiConfig.setUserKeyManager(new DbUserKeyManager()); } } diff --git a/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java b/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java index 640fb5e7..b93faa81 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java @@ -231,4 +231,35 @@ public class AlipayClientPostTest extends TestBase { System.out.println(responseData); } + @Test + public void testApiAbility() throws AlipayApiException { + // 公共请求参数 + Map params = new HashMap(); + params.put("app_id", appId); + params.put("method", "getStory2"); + params.put("version", "1.0"); + params.put("format", "json"); + params.put("charset", "utf-8"); + params.put("sign_type", "RSA2"); + params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + // 业务参数 + Map bizContent = new HashMap<>(); + + params.put("biz_content", JSON.toJSONString(bizContent)); + + System.out.println("----------- 请求信息 -----------"); + System.out.println("请求参数:" + buildParamQuery(params)); + System.out.println("商户秘钥:" + privateKey); + String content = AlipaySignature.getSignContent(params); + System.out.println("待签名内容:" + content); + String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8"); + System.out.println("签名(sign):" + sign); + + params.put("sign", sign); + + System.out.println("----------- 返回结果 -----------"); + String responseData = get(url, params);// 发送请求 + System.out.println(responseData); + } + } diff --git a/sop.sql b/sop.sql index 0c59ae83..18d4af9d 100644 --- a/sop.sql +++ b/sop.sql @@ -181,6 +181,7 @@ CREATE TABLE `config_gray_userkey` ( `instance_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'serviceId', `user_key_content` text COMMENT '用户key,多个用引文逗号隔开', `name_version_content` text COMMENT '需要灰度的接口,goods.get=1.2,order.list=1.2', + `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '0:禁用,1:启用', `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`),