From 043b760e03056d81d700e67051774dabccfc1c0e Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 31 Jul 2019 15:40:25 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/docs/_sidebar.md | 60 ++++----- doc/docs/files/10087_自定义返回结果.md | 125 ++++++++++++++++++ ..._自定义过滤器.md => 10088_自定义过滤器.md} | 0 doc/docs/files/10099_更改数据节点名称.md | 69 ---------- 4 files changed, 155 insertions(+), 99 deletions(-) create mode 100644 doc/docs/files/10087_自定义返回结果.md rename doc/docs/files/{10102_自定义过滤器.md => 10088_自定义过滤器.md} (100%) delete mode 100644 doc/docs/files/10099_更改数据节点名称.md diff --git a/doc/docs/_sidebar.md b/doc/docs/_sidebar.md index 8d4723a5..7f3785ec 100644 --- a/doc/docs/_sidebar.md +++ b/doc/docs/_sidebar.md @@ -1,32 +1,32 @@ -* [首页](/?t=1564370846275) +* [首页](/?t=1564558762831) * 开发文档 - * [快速体验](files/10010_快速体验.md?t=1564370846281) - * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1564370846298) - * [新增接口](files/10020_新增接口.md?t=1564370846298) - * [业务参数校验](files/10030_业务参数校验.md?t=1564370846299) - * [错误处理](files/10040_错误处理.md?t=1564370846299) - * [编写文档](files/10041_编写文档.md?t=1564370846299) - * [接口交互详解](files/10050_接口交互详解.md?t=1564370846299) - * [easyopen支持](files/10070_easyopen支持.md?t=1564370846299) - * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1564370846299) - * [ISV管理](files/10085_ISV管理.md?t=1564370846299) - * [自定义路由](files/10086_自定义路由.md?t=1564370846299) - * [路由授权](files/10090_路由授权.md?t=1564370846300) - * [接口限流](files/10092_接口限流.md?t=1564370846300) - * [监控日志](files/10093_监控日志.md?t=1564370846300) - * [SDK开发](files/10095_SDK开发.md?t=1564370846300) - * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1564370846300) - * [应用授权](files/10097_应用授权.md?t=1564370846300) - * [更改数据节点名称](files/10099_更改数据节点名称.md?t=1564370846300) - * [传统web开发](files/10100_传统web开发.md?t=1564370846300) - * [自定义过滤器](files/10102_自定义过滤器.md?t=1564370846300) - * [文件上传](files/10104_文件上传.md?t=1564370846301) - * [nacos注册中心](files/10106_nacos注册中心.md?t=1564370846301) - * [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1564370846301) - * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1564370846301) + * [快速体验](files/10010_快速体验.md?t=1564558762834) + * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1564558762850) + * [新增接口](files/10020_新增接口.md?t=1564558762850) + * [业务参数校验](files/10030_业务参数校验.md?t=1564558762850) + * [错误处理](files/10040_错误处理.md?t=1564558762850) + * [编写文档](files/10041_编写文档.md?t=1564558762850) + * [接口交互详解](files/10050_接口交互详解.md?t=1564558762850) + * [easyopen支持](files/10070_easyopen支持.md?t=1564558762850) + * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1564558762850) + * [ISV管理](files/10085_ISV管理.md?t=1564558762850) + * [自定义路由](files/10086_自定义路由.md?t=1564558762851) + * [自定义返回结果](files/10087_自定义返回结果.md?t=1564558762851) + * [自定义过滤器](files/10088_自定义过滤器.md?t=1564558762851) + * [路由授权](files/10090_路由授权.md?t=1564558762851) + * [接口限流](files/10092_接口限流.md?t=1564558762851) + * [监控日志](files/10093_监控日志.md?t=1564558762851) + * [SDK开发](files/10095_SDK开发.md?t=1564558762851) + * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1564558762851) + * [应用授权](files/10097_应用授权.md?t=1564558762851) + * [传统web开发](files/10100_传统web开发.md?t=1564558762851) + * [文件上传](files/10104_文件上传.md?t=1564558762852) + * [nacos注册中心](files/10106_nacos注册中心.md?t=1564558762852) + * [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1564558762852) + * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1564558762852) * 原理分析 - * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1564370846301) - * [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1564370846301) - * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1564370846301) - * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1564370846301) - * [常见问题](files/90100_常见问题.md?t=1564370846301) + * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1564558762852) + * [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1564558762852) + * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1564558762852) + * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1564558762852) + * [常见问题](files/90100_常见问题.md?t=1564558762852) diff --git a/doc/docs/files/10087_自定义返回结果.md b/doc/docs/files/10087_自定义返回结果.md new file mode 100644 index 00000000..352f7ccf --- /dev/null +++ b/doc/docs/files/10087_自定义返回结果.md @@ -0,0 +1,125 @@ +# 自定义返回结果 + +网关默认对业务结果进行合并,然后返回统一的格式。 + +针对`alipay.story.find`接口,微服务端返回结果如下: + +```json +{ + "name": "白雪公主", + "id": 1, + "gmtCreate": 1554193987378 +} +``` + +网关合并后,最终结果如下 + +```json +{ + "alipay_story_find_response": { + "msg": "Success", + "code": "10000", + "name": "白雪公主", + "id": 1, + "gmtCreate": 1554193987378 + }, + "sign": "xxxxx" +} +``` + +其中`alipay_story_find_response`是它的数据节点。规则是: + +> 将接口名中的点`.`转换成下划线`_`,后面加上`_response` + +代码实现如下: + +```java +String method = "alipay.story.find"; +return method.replace('.', '_') + "_response"; +``` + +详见`DefaultDataNameBuilder.java` + +如果要更改数据节点,比如`result`,可使用`CustomDataNameBuilder.java`。 + +```java +@Configuration +public class ZuulConfig extends AlipayZuulConfiguration { + + static { + ... + ApiConfig.getInstance().setDataNameBuilder(new CustomDataNameBuilder()); + ... + } + +} +``` + +设置后,网关统一的返回结果如下: + +```json +{ + "result": { + ... + }, + "sign": "xxxxx" +} +``` + +此外,构造方法可指定自定义字段名称:`new CustomDataNameBuilder("data");`。 +设置后,数据节点将变成`data` + +```json +{ + "data": { + ... + }, + "sign": "xxxxx" +} +``` + +**注**:网关设置了CustomDataNameBuilder后,SDK也要做相应的更改:`SdkConfig.dataNameBuilder = new CustomDataNameBuilder();` + +## 自定义结果处理 + +如果想要对微服务结果做更深一步处理,步骤如下: + +1. 新增一个类,继承`ZuulResultExecutor.java`,并重写`public String merge(T exchange, JSONObject responseData)`方法 + +方法merge参数说明如下: + + exchange:RequestContext对象 + responseData:微服务端返回的结果 + +方法返回最终结果 + +2. 配置自定义类 + +```java +public class SopGatewayApplication { + + public static void main(String[] args) { + ApiConfig.getInstance().setZuulResultExecutor(new MyzuulResultExecutor()); + SpringApplication.run(SopGatewayApplication.class, args); + } + +} +``` + + +## 不合并结果 + +如果不希望对结果进行合并,可设置`ApiConfig.getInstance().setMergeResult(false);` + +```java +public class SopGatewayApplication { + + public static void main(String[] args) { + ApiConfig.getInstance().setMergeResult(false); + SpringApplication.run(SopGatewayApplication.class, args); + } + +} +``` + +这样,网关最终返回结果即为微服务端的返回结果。 \ No newline at end of file diff --git a/doc/docs/files/10102_自定义过滤器.md b/doc/docs/files/10088_自定义过滤器.md similarity index 100% rename from doc/docs/files/10102_自定义过滤器.md rename to doc/docs/files/10088_自定义过滤器.md diff --git a/doc/docs/files/10099_更改数据节点名称.md b/doc/docs/files/10099_更改数据节点名称.md deleted file mode 100644 index 75e278c2..00000000 --- a/doc/docs/files/10099_更改数据节点名称.md +++ /dev/null @@ -1,69 +0,0 @@ -# 更改数据节点名称 - -针对`alipay.story.find`接口,它的返回结果如下: - -```json -{ - "alipay_story_find_response": { - "msg": "Success", - "code": "10000", - "name": "白雪公主", - "id": 1, - "gmtCreate": 1554193987378 - }, - "sign": "xxxxx" -} -``` - -其中`alipay_story_find_response`是它的数据节点。规则是: - -> 将接口名中的点`.`转换成下划线`_`,后面加上`_response` - -代码实现如下: - -```java -String method = "alipay.story.find"; -return method.replace('.', '_') + "_response"; -``` - -详见`DefaultDataNameBuilder.java` - -如果要更改数据节点,比如`result`,可使用`CustomDataNameBuilder.java`。 - -```java -@Configuration -public class ZuulConfig extends AlipayZuulConfiguration { - - static { - ... - ApiConfig.getInstance().setDataNameBuilder(new CustomDataNameBuilder()); - ... - } - -} -``` - -设置后,网关统一的返回结果如下: - -```json -{ - "result": { - ... - }, - "sign": "xxxxx" -} -``` - -此外,构造方法可指定自定义字段名称:`new CustomDataNameBuilder("data");`。 -设置后,数据节点将变成`data` - -```json -{ - "data": { - ... - }, - "sign": "xxxxx" -} -``` - -**注**:网关设置了CustomDataNameBuilder后,SDK也要做相应的更改:`SdkConfig.dataNameBuilder = new CustomDataNameBuilder();` From 6125625b876572121199b3e0db9c15be53cdb875 Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 31 Jul 2019 20:00:25 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=A2=84=E5=8F=91?= =?UTF-8?q?=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adminserver/api/service/ServiceApi.java | 48 +++++++++++- .../api/service/result/ServiceInstanceVO.java | 5 ++ .../sop/adminserver/bean/MetadataEnum.java | 37 ++++++++++ .../src/views/service/serviceList.vue | 73 ++++++++++++++++--- .../sop/gatewaycommon/bean/SopConstants.java | 1 + .../gateway/result/GatewayResultExecutor.java | 2 +- .../route/ReadBodyRoutePredicateFactory.java | 2 +- .../sop/gatewaycommon/message/ErrorEnum.java | 4 +- .../gatewaycommon/message/ErrorFactory.java | 4 +- .../gatewaycommon/param/BaseParamBuilder.java | 2 +- .../result/BaseExecutorAdapter.java | 2 +- .../result/CustomDataNameBuilder.java | 2 +- .../result/DefaultDataNameBuilder.java | 2 +- .../gatewaycommon/result/ResultExecutor.java | 2 +- .../session/ApiSessionManager.java | 2 +- .../zuul/loadbalancer/BaseServerChooser.java | 72 ++++++++++++++++++ .../zuul/result/ZuulResultExecutor.java | 2 +- .../sop/registryapi/bean/EurekaInstance.java | 41 +++++++++++ .../gitee/sop/registryapi/bean/EurekaUri.java | 10 +++ .../gitee/sop/registryapi}/bean/HttpTool.java | 21 +++--- .../sop/registryapi/bean/ServiceInstance.java | 8 ++ .../registryapi/service/RegistryService.java | 9 +++ .../service/impl/RegistryServiceEureka.java | 6 ++ .../service/impl/RegistryServiceNacos.java | 67 +++++++++++------ .../message/ServiceErrorEnum.java | 2 +- .../resources/i18n/isp/error_en.properties | 2 +- .../resources/i18n/isp/error_zh_CN.properties | 2 +- .../gitee/sop/gateway/config/ZuulConfig.java | 8 ++ .../PreEnvironmentServerChooser.java | 55 ++++++++++++++ .../loadbalancer/SopPropertiesFactory.java | 39 ++++++++++ .../sop/sdk/common/CustomDataNameBuilder.java | 2 +- .../sdk/common/DefaultDataNameBuilder.java | 2 +- .../gitee/sop/sdk/response/BaseResponse.java | 2 +- .../java/com/gitee/sop/test/HttpTool.java | 16 ++-- sop-website/website-front/pages/doc/code.html | 2 +- .../website-front/pages/doc/docEvent.js | 2 +- .../controller/SandboxController.java | 4 +- 37 files changed, 484 insertions(+), 78 deletions(-) create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/MetadataEnum.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java rename {sop-website/website-server/src/main/java/com/gitee/sop/websiteserver => sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi}/bean/HttpTool.java (94%) create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/PreEnvironmentServerChooser.java create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java 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 a80393e5..fa3d4b0a 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 @@ -10,6 +10,7 @@ import com.gitee.sop.adminserver.api.service.param.ServiceSearchParam; import com.gitee.sop.adminserver.api.service.result.RouteServiceInfo; import com.gitee.sop.adminserver.api.service.result.ServiceInfoVo; import com.gitee.sop.adminserver.api.service.result.ServiceInstanceVO; +import com.gitee.sop.adminserver.bean.MetadataEnum; import com.gitee.sop.adminserver.bean.ServiceRouteInfo; import com.gitee.sop.adminserver.bean.ZookeeperContext; import com.gitee.sop.adminserver.common.BizException; @@ -144,6 +145,9 @@ public class ServiceApi { int id = idGen.getAndIncrement(); instanceVO.setId(id); instanceVO.setParentId(pid); + if (instanceVO.getMetadata() == null) { + instanceVO.setMetadata(Collections.emptyMap()); + } serviceInfoVoList.add(instanceVO); } }); @@ -152,21 +156,57 @@ public class ServiceApi { } @Api(name = "service.instance.offline") - @ApiDocMethod(description = "服务下线") + @ApiDocMethod(description = "服务禁用") void serviceOffline(ServiceInstance param) { try { registryService.offlineInstance(param); } catch (Exception e) { - log.error("下线失败,param:{}", param, e); - throw new BizException("下线失败,请查看日志"); + log.error("服务禁用失败,param:{}", param, e); + throw new BizException("服务禁用失败,请查看日志"); } } @Api(name = "service.instance.online") - @ApiDocMethod(description = "服务上线") + @ApiDocMethod(description = "服务启用") void serviceOnline(ServiceInstance param) throws IOException { try { registryService.onlineInstance(param); + } catch (Exception e) { + log.error("服务启用失败,param:{}", param, e); + throw new BizException("服务启用失败,请查看日志"); + } + } + + @Api(name = "service.instance.env.pre") + @ApiDocMethod(description = "预发布") + void serviceEnvPre(ServiceInstance param) throws IOException { + try { + MetadataEnum envPre = MetadataEnum.ENV_PRE; + registryService.setMetadata(param, envPre.getKey(), envPre.getValue()); + } catch (Exception e) { + log.error("预发布失败,param:{}", param, e); + throw new BizException("预发布失败,请查看日志"); + } + } + + @Api(name = "service.instance.env.gray") + @ApiDocMethod(description = "灰度发布") + void serviceEnvGray(ServiceInstance param) throws IOException { + try { + MetadataEnum envPre = MetadataEnum.ENV_GRAY; + registryService.setMetadata(param, envPre.getKey(), envPre.getValue()); + } catch (Exception e) { + log.error("灰度发布失败,param:{}", param, e); + throw new BizException("灰度发布失败,请查看日志"); + } + } + + @Api(name = "service.instance.env.online") + @ApiDocMethod(description = "上线") + void serviceEnvOnline(ServiceInstance param) throws IOException { + try { + MetadataEnum envPre = MetadataEnum.ENV_ONLINE; + registryService.setMetadata(param, envPre.getKey(), envPre.getValue()); } catch (Exception e) { log.error("上线失败,param:{}", param, e); throw new BizException("上线失败,请查看日志"); diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/ServiceInstanceVO.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/ServiceInstanceVO.java index 7cffb7de..9c48e516 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/ServiceInstanceVO.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/ServiceInstanceVO.java @@ -3,6 +3,8 @@ package com.gitee.sop.adminserver.api.service.result; import com.gitee.easyopen.doc.annotation.ApiDocField; import lombok.Data; +import java.util.Map; + /** * @author tanghc */ @@ -35,6 +37,9 @@ public class ServiceInstanceVO { @ApiDocField(description = "parentId") private Integer parentId; + @ApiDocField(description = "metadata") + private Map metadata; + public String getIpPort() { return ip != null && port > 0 ? ip + ":" + port : ""; } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/MetadataEnum.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/MetadataEnum.java new file mode 100644 index 00000000..2eb5f25b --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/MetadataEnum.java @@ -0,0 +1,37 @@ +package com.gitee.sop.adminserver.bean; + +/** + * @author tanghc + */ +public enum MetadataEnum { + /** + * 预发布环境 + */ + ENV_PRE("env", "pre"), + + /** + * 上线环境 + */ + ENV_ONLINE("env", ""), + + /** + * 灰度环境 + */ + ENV_GRAY("env", "gray"), + ; + private String key,value; + + MetadataEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + +} 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 9572923c..4de2689c 100644 --- a/sop-admin/sop-admin-vue/src/views/service/serviceList.vue +++ b/sop-admin/sop-admin-vue/src/views/service/serviceList.vue @@ -28,16 +28,36 @@ label="IP端口" width="250" /> + + + + + + @@ -103,22 +126,46 @@ export default { onSearchTable: function() { this.loadTable() }, - onOffline: function(row) { - this.confirm('确定要下线【' + row.serviceId + '】吗?', function(done) { + onDisable: function(row) { + this.confirm('确定要禁用【' + row.serviceId + '】吗?', function(done) { this.post('service.instance.offline', row, function() { this.tip('下线成功') done() }) }) }, - onOnline: function(row) { - this.confirm('确定要上线【' + row.serviceId + '】吗?', function(done) { + onEnable: function(row) { + this.confirm('确定要启用【' + row.serviceId + '】吗?', function(done) { this.post('service.instance.online', row, function() { this.tip('上线成功') done() }) }) }, + onEnvOnline: function(row) { + this.confirm('确定要上线【' + row.serviceId + '】吗?', function(done) { + this.post('service.instance.env.online', row, function() { + this.tip('上线成功') + done() + }) + }) + }, + onEnvPre: function(row) { + this.confirm('确定要预发布【' + row.serviceId + '】吗?', function(done) { + this.post('service.instance.env.pre', row, function() { + this.tip('预发布成功') + done() + }) + }) + }, + onEnvGray: function(row) { + this.confirm('确定要灰度发布【' + row.serviceId + '】吗?', function(done) { + this.post('service.instance.env.gray', row, function() { + this.tip('灰度发布发成功') + done() + }) + }) + }, renderServiceName: function(row) { let instanceCount = '' if (row.children && row.children.length > 0) { @@ -128,6 +175,14 @@ export default { instanceCount = ` (${onlineCount}/${row.children.length})` } return row.serviceId + instanceCount + }, + renderMetadata: function(row) { + const metadata = row.metadata + const html = [] + for (const key in metadata) { + html.push(key + '=' + metadata[key]) + } + return html.join('
') } } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java index 7ed69b01..4a3f5c99 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java @@ -54,4 +54,5 @@ public class SopConstants { public static final String UNKNOWN_SERVICE= "_sop_unknown_service_"; public static final String UNKNOWN_METHOD = "_sop_unknown_method_"; public static final String UNKNOWN_VERSION = "_sop_unknown_version_"; + } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java index 884e013a..f7724b29 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java @@ -69,7 +69,7 @@ public class GatewayResultExecutor extends BaseExecutorAdapterString solution = getErrorMessage(modulePrefix + code + UNDERLINE + subCode + "_solution", locale, params); error = new ErrorImpl(code, msg, subCode, subMsg, null); errorCache.put(key, error); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/BaseParamBuilder.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/BaseParamBuilder.java index 36aa6458..fcb1849f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/BaseParamBuilder.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/BaseParamBuilder.java @@ -51,7 +51,7 @@ public abstract class BaseParamBuilder implements ParamBuilder { RouteRepository routeRepository = RouteRepositoryContext.getRouteRepository(); if (routeRepository == null) { log.error("RouteRepositoryContext.setRouteRepository()方法未使用"); - throw ErrorEnum.AOP_UNKNOW_ERROR.getErrorMeta().getException(); + throw ErrorEnum.ISP_UNKNOWN_ERROR.getErrorMeta().getException(); } String nameVersion = Optional.ofNullable(apiParam.fetchNameVersion()).orElse(String.valueOf(System.currentTimeMillis())); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java index 4307e7c6..14751f84 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java @@ -35,7 +35,7 @@ import java.util.Optional; @Slf4j public abstract class BaseExecutorAdapter implements ResultExecutor { private static final ErrorMeta SUCCESS_META = ErrorEnum.SUCCESS.getErrorMeta(); - private static final ErrorMeta ISP_UNKNOW_ERROR_META = ErrorEnum.ISP_UNKNOW_ERROR.getErrorMeta(); + private static final ErrorMeta ISP_UNKNOW_ERROR_META = ErrorEnum.ISP_UNKNOWN_ERROR.getErrorMeta(); private static final ErrorMeta ISP_BIZ_ERROR = ErrorEnum.BIZ_ERROR.getErrorMeta(); public static final String GATEWAY_CODE_NAME = "code"; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/CustomDataNameBuilder.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/CustomDataNameBuilder.java index 5e710d1f..726db193 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/CustomDataNameBuilder.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/CustomDataNameBuilder.java @@ -6,7 +6,7 @@ package com.gitee.sop.gatewaycommon.result; * "result": { * "code": "20000", * "msg": "Service Currently Unavailable", - * "sub_code": "isp.unknow-error", + * "sub_code": "isp.unknown-error", * "sub_msg": "系统繁忙" * }, * "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/DefaultDataNameBuilder.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/DefaultDataNameBuilder.java index 987041ec..1cb5d0be 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/DefaultDataNameBuilder.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/DefaultDataNameBuilder.java @@ -8,7 +8,7 @@ package com.gitee.sop.gatewaycommon.result; * "alipay_trade_order_settle_response": { * "code": "20000", * "msg": "Service Currently Unavailable", - * "sub_code": "isp.unknow-error", + * "sub_code": "isp.unknown-error", * "sub_msg": "系统繁忙" * }, * "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java index d20ff5ea..051b988b 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java @@ -22,7 +22,7 @@ package com.gitee.sop.gatewaycommon.result; * "alipay_trade_fastpay_refund_query_response": { * "code": "20000", * "msg": "Service Currently Unavailable", - * "sub_code": "isp.unknow-error", + * "sub_code": "isp.unknown-error", * "sub_msg": "系统繁忙" * }, * "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/session/ApiSessionManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/session/ApiSessionManager.java index 5791ef38..19d2d742 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/session/ApiSessionManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/session/ApiSessionManager.java @@ -36,7 +36,7 @@ public class ApiSessionManager implements SessionManager { return cache.get(sessionId); } catch (Exception e) { logger.error(e.getMessage(), e); - throw ErrorEnum.AOP_UNKNOW_ERROR.getErrorMeta().getException(); + throw ErrorEnum.ISP_UNKNOWN_ERROR.getErrorMeta().getException(); } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java new file mode 100644 index 00000000..bbda7bef --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java @@ -0,0 +1,72 @@ +package com.gitee.sop.gatewaycommon.zuul.loadbalancer; + +import com.google.common.base.Optional; +import com.netflix.loadbalancer.ILoadBalancer; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ZoneAvoidanceRule; +import com.netflix.zuul.context.RequestContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; + +/** + * 服务实例选择器 + * + * @author tanghc + */ +@Slf4j +public abstract class BaseServerChooser extends ZoneAvoidanceRule { + + /** + * 是否匹配对应的服务器,可在此判断是否是预发布,灰度环境 + * + * @param server 指定服务器 + * @return 返回true:是 + */ + protected abstract boolean match(Server server); + + /** + * 客户端能否够访问服务器 + * + * @param server 服务器实例 + * @param request request + * @return 返回true:能访问 + */ + protected abstract boolean canVisit(Server server, HttpServletRequest request); + + @Override + public Server choose(Object key) { + ILoadBalancer lb = getLoadBalancer(); + // 获取服务实例列表 + List allServers = new ArrayList<>(lb.getAllServers()); + int index = -1; + for (int i = 0; i < allServers.size(); i++) { + Server server = allServers.get(i); + if (match(server)) { + index = i; + if (canVisit(server, RequestContext.getCurrentContext().getRequest())) { + return server; + } + } + } + // 调用默认的算法 + // 如果选出了特殊环境服务器,需要移除命中的服务器 + if (index > -1) { + allServers.remove(index); + } + if (CollectionUtils.isEmpty(allServers)) { + log.error("无可用服务实例,key:", key); + return null; + } + Optional server = getPredicate().chooseRoundRobinAfterFiltering(allServers, key); + if (server.isPresent()) { + return server.get(); + } else { + return null; + } + } + +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java index aee316f7..526a90b0 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java @@ -76,7 +76,7 @@ public class ZuulResultExecutor extends BaseExecutorAdapter metadata; + public String fetchPort() { if (CollectionUtils.isEmpty(port)) { return ""; diff --git a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/EurekaUri.java b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/EurekaUri.java index 8a229ca7..2a76893e 100644 --- a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/EurekaUri.java +++ b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/EurekaUri.java @@ -16,6 +16,10 @@ public enum EurekaUri { * 查询所有实例 Query for all instances */ QUERY_APPS("GET", "/apps"), + /** + * 查询一个实例 + */ + QUERY_INSTANCES("GET", "/instances/%s"), /** * 下线 Take instance out of service */ @@ -24,6 +28,12 @@ public enum EurekaUri { * 上线 Move instance back into service (remove override) */ ONLINE_SERVICE("DELETE", "/apps/%s/%s/status?value=UP"), + /** + * 设置metadata信息 + * + * /apps/{appID}/{instanceID}/metadata?key=value + */ + SET_METADATA("PUT", "/apps/%s/%s/metadata?%s=%s") ; public static final String URL_PREFIX = "/"; diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/HttpTool.java similarity index 94% rename from sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java rename to sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/HttpTool.java index 8e0cce0e..f323e0d7 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java +++ b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/HttpTool.java @@ -1,4 +1,4 @@ -package com.gitee.sop.websiteserver.bean; +package com.gitee.sop.registryapi.bean; import lombok.Data; import lombok.Getter; @@ -110,7 +110,7 @@ public class HttpTool { * @return * @throws IOException */ - public String request(String url, Map form, Map header, HTTPMethod method) throws IOException { + public String request(String url, Map form, Map header, HTTPMethod method) throws IOException { Request.Builder requestBuilder = buildRequestBuilder(url, form, method.value()); // 添加header addHeader(requestBuilder, header); @@ -153,7 +153,7 @@ public class HttpTool { } } - public static Request.Builder buildRequestBuilder(String url, Map form, String method) { + public static Request.Builder buildRequestBuilder(String url, Map form, String method) { switch (method) { case "get": return new Request.Builder() @@ -178,18 +178,18 @@ public class HttpTool { } } - public static HttpUrl buildHttpUrl(String url, Map form) { + public static HttpUrl buildHttpUrl(String url, Map form) { HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder(); - for (Map.Entry entry : form.entrySet()) { - urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + for (Map.Entry entry : form.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue())); } return urlBuilder.build(); } - public static FormBody buildFormBody(Map form) { + public static FormBody buildFormBody(Map form) { FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8); - for (Map.Entry entry : form.entrySet()) { - paramBuilder.add(entry.getKey(), entry.getValue()); + for (Map.Entry entry : form.entrySet()) { + paramBuilder.add(entry.getKey(), String.valueOf(entry.getValue())); } return paramBuilder.build(); } @@ -262,6 +262,9 @@ public class HttpTool { HEAD, DELETE; + private HTTPMethod() { + } + public String value() { return this.name(); } diff --git a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/ServiceInstance.java b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/ServiceInstance.java index 9025aa62..8e62edb7 100644 --- a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/ServiceInstance.java +++ b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/bean/ServiceInstance.java @@ -2,6 +2,9 @@ package com.gitee.sop.registryapi.bean; import lombok.Data; +import java.util.HashMap; +import java.util.Map; + /** * @author tanghc */ @@ -37,4 +40,9 @@ public class ServiceInstance { */ private String updateTime; + /** + * user extended attributes + */ + private Map metadata = new HashMap(); + } \ No newline at end of file diff --git a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/RegistryService.java b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/RegistryService.java index 829b9a5a..33988ca3 100644 --- a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/RegistryService.java +++ b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/RegistryService.java @@ -38,4 +38,13 @@ public interface RegistryService { void offlineInstance(ServiceInstance serviceInstance) throws Exception; + /** + * 设置实例元数据 + * + * @param serviceInstance 实例 + * @param key key + * @param value 值 + * @throws Exception 设置实例元数据失败抛出异常 + */ + void setMetadata(ServiceInstance serviceInstance, String key, String value) throws Exception; } diff --git a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceEureka.java b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceEureka.java index f6a1c774..57793f3b 100644 --- a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceEureka.java +++ b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceEureka.java @@ -60,6 +60,7 @@ public class RegistryServiceEureka implements RegistryService { serviceInstance.setStatus(eurekaInstance.getStatus()); Date updateTime = new Date(Long.valueOf(eurekaInstance.getLastUpdatedTimestamp())); serviceInstance.setUpdateTime(DateFormatUtils.format(updateTime, TIMESTAMP_PATTERN)); + serviceInstance.setMetadata(eurekaInstance.getMetadata()); serviceInfo.getInstances().add(serviceInstance); } } @@ -80,6 +81,11 @@ public class RegistryServiceEureka implements RegistryService { this.requestEurekaServer(EurekaUri.OFFLINE_SERVICE, serviceInstance.getServiceId(), serviceInstance.getInstanceId()); } + @Override + public void setMetadata(ServiceInstance serviceInstance, String key, String value) throws Exception { + this.requestEurekaServer(EurekaUri.SET_METADATA, serviceInstance.getServiceId(), serviceInstance.getInstanceId(), key, value); + } + private String requestEurekaServer(EurekaUri eurekaUri, String... args) throws IOException { Request request = eurekaUri.getRequest(this.eurekaUrl, args); Response response = client.newCall(request).execute(); diff --git a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceNacos.java b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceNacos.java index 0a6cbcd8..8d24ad8a 100644 --- a/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceNacos.java +++ b/sop-common/sop-registry-api/src/main/java/com/gitee/sop/registryapi/service/impl/RegistryServiceNacos.java @@ -1,17 +1,17 @@ package com.gitee.sop.registryapi.service.impl; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingFactory; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ListView; +import com.gitee.sop.registryapi.bean.HttpTool; import com.gitee.sop.registryapi.bean.ServiceInfo; import com.gitee.sop.registryapi.bean.ServiceInstance; import com.gitee.sop.registryapi.service.RegistryService; -import okhttp3.FormBody; import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.CollectionUtils; @@ -24,13 +24,15 @@ import java.util.List; import java.util.Map; /** - * nacos接口实现 + * nacos接口实现, https://nacos.io/zh-cn/docs/open-api.html * @author tanghc */ public class RegistryServiceNacos implements RegistryService { OkHttpClient client = new OkHttpClient(); + static HttpTool httpTool = new HttpTool(); + @Value("${registry.nacos-server-addr:}") private String nacosAddr; @@ -63,6 +65,7 @@ public class RegistryServiceNacos implements RegistryService { boolean isOnline = instance.getWeight() > 0; String status = isOnline ? "UP" : "OUT_OF_SERVICE"; serviceInstance.setStatus(status); + serviceInstance.setMetadata(instance.getMetadata()); serviceInfo.getInstances().add(serviceInstance); } } @@ -73,34 +76,50 @@ public class RegistryServiceNacos implements RegistryService { @Override public void onlineInstance(ServiceInstance serviceInstance) throws Exception { - Map params = new HashMap<>(8); + // 查询实例 + Instance instance = this.getInstance(serviceInstance); // 上线,把权重设置成1 - params.put("weight", "1"); - this.updateInstance(serviceInstance, params); + instance.setWeight(1); + this.updateInstance(instance); } @Override public void offlineInstance(ServiceInstance serviceInstance) throws Exception { - Map params = new HashMap<>(8); + // 查询实例 + Instance instance = this.getInstance(serviceInstance); // 下线,把权重设置成0 - params.put("weight", "0"); - this.updateInstance(serviceInstance, params); + instance.setWeight(0); + this.updateInstance(instance); } - private Response updateInstance(ServiceInstance serviceInstance, Map params) throws IOException { - FormBody.Builder builder = new FormBody.Builder(); - for (Map.Entry entry : params.entrySet()) { - builder.add(entry.getKey(), String.valueOf(entry.getValue())); - } - builder.add("serviceName", serviceInstance.getServiceId()) - .add("ip", serviceInstance.getIp()) - .add("port", String.valueOf(serviceInstance.getPort())); - FormBody formBody = builder.build(); - final Request request = new Request.Builder() - .url("http://" + nacosAddr + "/nacos/v1/ns/instance") - .put(formBody) - .build(); + @Override + public void setMetadata(ServiceInstance serviceInstance, String key, String value) throws Exception { + // 查询实例 + Instance instance = this.getInstance(serviceInstance); + // 设置metadata + Map metadata = instance.getMetadata(); + metadata.put(key, value); + this.updateInstance(instance); + } + + protected void updateInstance(Instance instance) throws IOException { + String json = JSON.toJSONString(instance); + JSONObject jsonObject = JSON.parseObject(json); + httpTool.request("http://" + nacosAddr + "/nacos/v1/ns/instance", jsonObject, null, HttpTool.HTTPMethod.PUT); + } - return client.newCall(request).execute(); + /** + * 查询实例 + * @param serviceInstance 实例信息 + * @return 返回nacos实例 + * @throws IOException 查询异常 + */ + protected Instance getInstance(ServiceInstance serviceInstance) throws IOException { + Map params = new HashMap<>(8); + params.put("serviceName", serviceInstance.getServiceId()); + params.put("ip", serviceInstance.getIp()); + params.put("port", String.valueOf(serviceInstance.getPort())); + String instanceJson = httpTool.request("http://" + nacosAddr + "/nacos/v1/ns/instance", params, null, HttpTool.HTTPMethod.GET); + return JSON.parseObject(instanceJson, Instance.class); } } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/message/ServiceErrorEnum.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/message/ServiceErrorEnum.java index 56244f9c..7bd28618 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/message/ServiceErrorEnum.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/message/ServiceErrorEnum.java @@ -5,7 +5,7 @@ package com.gitee.sop.servercommon.message; */ public enum ServiceErrorEnum { /** 系统繁忙 */ - ISP_UNKNOW_ERROR("isp.unknow-error"), + ISP_UNKNOW_ERROR("isp.unknown-error"), /** 参数错误 */ ISV_PARAM_ERROR("isv.invalid-parameter"), /** 通用错误 */ diff --git a/sop-common/sop-service-common/src/main/resources/i18n/isp/error_en.properties b/sop-common/sop-service-common/src/main/resources/i18n/isp/error_en.properties index 8560312c..9b36e636 100644 --- a/sop-common/sop-service-common/src/main/resources/i18n/isp/error_en.properties +++ b/sop-common/sop-service-common/src/main/resources/i18n/isp/error_en.properties @@ -1,4 +1,4 @@ # 错误配置 -isp.error_isp.unknow-error=Service is temporarily unavailable +isp.error_isp.unknown-error=Service is temporarily unavailable isp.error_isv.invalid-parameter=Invalid parameter \ No newline at end of file diff --git a/sop-common/sop-service-common/src/main/resources/i18n/isp/error_zh_CN.properties b/sop-common/sop-service-common/src/main/resources/i18n/isp/error_zh_CN.properties index 42616e36..48fc185c 100644 --- a/sop-common/sop-service-common/src/main/resources/i18n/isp/error_zh_CN.properties +++ b/sop-common/sop-service-common/src/main/resources/i18n/isp/error_zh_CN.properties @@ -1,5 +1,5 @@ # 错误配置 -isp.error_isp.unknow-error=\u670d\u52a1\u6682\u4e0d\u53ef\u7528 +isp.error_isp.unknown-error=\u670d\u52a1\u6682\u4e0d\u53ef\u7528 # 参数无效 isp.error_isv.invalid-parameter=\u53c2\u6570\u65e0\u6548 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 e87b22bf..3dfe7ba7 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 @@ -6,8 +6,11 @@ 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; import org.springframework.context.annotation.Configuration; /** @@ -21,6 +24,11 @@ public class ZuulConfig extends AlipayZuulConfiguration { new ManagerInitializer(); } + @Bean + PropertiesFactory propertiesFactory() { + return new SopPropertiesFactory(); + } + } /** diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/PreEnvironmentServerChooser.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/PreEnvironmentServerChooser.java new file mode 100644 index 00000000..eb63135f --- /dev/null +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/PreEnvironmentServerChooser.java @@ -0,0 +1,55 @@ +package com.gitee.sop.gateway.loadbalancer; + +import com.gitee.sop.gatewaycommon.zuul.loadbalancer.BaseServerChooser; +import com.netflix.loadbalancer.Server; +import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; +import java.util.Objects; + +/** + * 预发布环境选择,参考自:https://segmentfault.com/a/1190000017412946 + * + * @author tanghc + */ +public class PreEnvironmentServerChooser extends BaseServerChooser { + + private static final String MEDATA_KEY_ENV = "env"; + private static final String ENV_PRE_VALUE = "pre"; + + private static final String HOST_NAME = "localhost"; + + @Override + protected boolean match(Server server) { + // eureka存储的metadata + Map metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata(); + String env = metadata.get(MEDATA_KEY_ENV); + return StringUtils.isNotBlank(env); + } + + /** + * 这里判断客户端能否访问,可以根据ip地址,域名,header内容来决定是否可以访问预发布环境 + * @param server 服务器实例 + * @param request request + * @return + */ + @Override + protected boolean canVisit(Server server, HttpServletRequest request) { + // eureka存储的metadata + Map metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata(); + String env = metadata.get(MEDATA_KEY_ENV); + return Objects.equals(ENV_PRE_VALUE, env) && canClientVisit(request); + } + + /** + * 通过判断hostname来确定是否是预发布请求,如果需要通过其它条件判断,修改此方法 + * @param request request + * @return 返回true:可以进入到预发环境 + */ + protected boolean canClientVisit(HttpServletRequest request) { + String serverName = request.getServerName(); + return HOST_NAME.equals(serverName); + } +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java new file mode 100644 index 00000000..2cda625a --- /dev/null +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java @@ -0,0 +1,39 @@ +package com.gitee.sop.gateway.loadbalancer; + +import com.netflix.loadbalancer.IRule; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.netflix.ribbon.PropertiesFactory; +import org.springframework.core.env.Environment; + +/** + * 自定义PropertiesFactory,用来动态添加LoadBalance规则 + * @author tanghc + */ +public class SopPropertiesFactory extends PropertiesFactory { + + /** + * 可在配置文件中设置zuul.custom-rule-classname=com.xx.ClassName指定负载均衡规则类 + * 默认使用com.gitee.sop.gateway.loadbalancer.PreEnvironmentServerChooser + */ + private static final String PROPERTIES_KEY = "zuul.custom-rule-classname"; + + private static final String CUSTOM_RULE_CLASSNAME = PreEnvironmentServerChooser.class.getName(); + + @Autowired + private Environment environment; + + /** + * 配置文件配置:.ribbon.NFLoadBalancerRuleClassName=com.gitee.sop.gateway.loadbalancer.PreEnvironmentServerChooser + * @param clazz + * @param name serviceId + * @return 返回class全限定名 + */ + @Override + public String getClassName(Class clazz, String name) { + if (clazz == IRule.class) { + return this.environment.getProperty(PROPERTIES_KEY, CUSTOM_RULE_CLASSNAME); + } else { + return super.getClassName(clazz, name); + } + } +} diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/CustomDataNameBuilder.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/CustomDataNameBuilder.java index f015a85c..ab54e4f5 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/CustomDataNameBuilder.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/CustomDataNameBuilder.java @@ -6,7 +6,7 @@ package com.gitee.sop.sdk.common; * "result": { * "code": "20000", * "msg": "Service Currently Unavailable", - * "sub_code": "isp.unknow-error", + * "sub_code": "isp.unknown-error", * "sub_msg": "系统繁忙" * }, * "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java index 31f97fa8..77d3a78b 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java @@ -8,7 +8,7 @@ package com.gitee.sop.sdk.common; * "alipay_trade_order_settle_response": { * "code": "20000", * "msg": "Service Currently Unavailable", - * "sub_code": "isp.unknow-error", + * "sub_code": "isp.unknown-error", * "sub_msg": "系统繁忙" * }, * "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java index efc376fc..23bbf469 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java @@ -11,7 +11,7 @@ import lombok.Setter; * "alipay_trade_close_response": { * "code": "20000", * "msg": "Service Currently Unavailable", - * "sub_code": "isp.unknow-error", + * "sub_code": "isp.unknown-error", * "sub_msg": "系统繁忙" * }, * "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" diff --git a/sop-test/src/main/java/com/gitee/sop/test/HttpTool.java b/sop-test/src/main/java/com/gitee/sop/test/HttpTool.java index 989382df..b7fa77ef 100644 --- a/sop-test/src/main/java/com/gitee/sop/test/HttpTool.java +++ b/sop-test/src/main/java/com/gitee/sop/test/HttpTool.java @@ -110,7 +110,7 @@ public class HttpTool { * @return * @throws IOException */ - public String request(String url, Map form, Map header, HTTPMethod method) throws IOException { + public String request(String url, Map form, Map header, HTTPMethod method) throws IOException { Request.Builder requestBuilder = buildRequestBuilder(url, form, method.value()); // 添加header addHeader(requestBuilder, header); @@ -153,7 +153,7 @@ public class HttpTool { } } - public static Request.Builder buildRequestBuilder(String url, Map form, String method) { + public static Request.Builder buildRequestBuilder(String url, Map form, String method) { switch (method) { case "get": return new Request.Builder() @@ -178,18 +178,18 @@ public class HttpTool { } } - public static HttpUrl buildHttpUrl(String url, Map form) { + public static HttpUrl buildHttpUrl(String url, Map form) { HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder(); - for (Map.Entry entry : form.entrySet()) { - urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + for (Map.Entry entry : form.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue())); } return urlBuilder.build(); } - public static FormBody buildFormBody(Map form) { + public static FormBody buildFormBody(Map form) { FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8); - for (Map.Entry entry : form.entrySet()) { - paramBuilder.add(entry.getKey(), entry.getValue()); + for (Map.Entry entry : form.entrySet()) { + paramBuilder.add(entry.getKey(), String.valueOf(entry.getValue())); } return paramBuilder.build(); } diff --git a/sop-website/website-front/pages/doc/code.html b/sop-website/website-front/pages/doc/code.html index 5d7d8bf6..9fecb963 100644 --- a/sop-website/website-front/pages/doc/code.html +++ b/sop-website/website-front/pages/doc/code.html @@ -141,7 +141,7 @@
服务不可用
-
isp.unknow-error
+
isp.unknown-error
服务暂不可用(业务系统不可用)
diff --git a/sop-website/website-front/pages/doc/docEvent.js b/sop-website/website-front/pages/doc/docEvent.js index e3aee12f..5f58b327 100644 --- a/sop-website/website-front/pages/doc/docEvent.js +++ b/sop-website/website-front/pages/doc/docEvent.js @@ -93,7 +93,7 @@ function createResponseCode(docItem) { ' "'+method+'_response": {\n' + ' "code": "20000",\n' + ' "msg": "Service is temporarily unavailable",\n' + - ' "sub_code": "isp.unknow-error",\n' + + ' "sub_code": "isp.unknown-error",\n' + ' "sub_msg": "服务暂不可用"\n' + ' }' + '}'; diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/SandboxController.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/SandboxController.java index 5bfd6aa0..794770d4 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/SandboxController.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/SandboxController.java @@ -1,7 +1,7 @@ package com.gitee.sop.websiteserver.controller; -import com.gitee.sop.websiteserver.bean.HttpTool; -import com.gitee.sop.websiteserver.bean.HttpTool.*; +import com.gitee.sop.registryapi.bean.HttpTool; +import com.gitee.sop.registryapi.bean.HttpTool.*; import com.gitee.sop.websiteserver.sign.AlipayApiException; import com.gitee.sop.websiteserver.sign.AlipaySignature; import com.gitee.sop.websiteserver.util.UploadUtil; From 202267b686a874f513f1730f9bfb687b2e4e9c99 Mon Sep 17 00:00:00 2001 From: tanghc Date: Fri, 2 Aug 2019 20:16:14 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=A2=84=E5=8F=91?= =?UTF-8?q?=E5=B8=83=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 --- doc/docs/files/10110_预发布灰度发布.md | 31 +++ sop-1.14.0.sql | 12 + sop-admin/sop-admin-server/pom.xml | 6 +- .../SopAdminServerApplication.java | 4 + .../gitee/sop/adminserver/api/isv/IsvApi.java | 3 +- .../api/service/IPBlacklistApi.java | 12 +- .../adminserver/api/service/ServiceApi.java | 65 ++++- .../param/ServiceInstanceGrayParam.java | 26 ++ .../service/param/ServiceInstanceParam.java | 27 +++ .../api/service/param/ServiceSearchParam.java | 5 +- .../sop/adminserver/bean/ChannelMsg.java | 5 +- .../adminserver/bean/UserKeyDefinition.java | 12 + .../adminserver/bean/ZookeeperContext.java | 4 + .../adminserver/common/ChannelOperation.java | 60 +++++ .../adminserver/entity/ConfigGrayUserkey.java | 42 ++++ .../mapper/ConfigGrayUserkeyMapper.java | 12 + .../service/RouteConfigService.java | 7 +- .../service/RoutePermissionService.java | 5 +- .../main/resources/application-dev.properties | 4 - .../src/views/service/ipBlacklist.vue | 2 +- .../src/views/service/serviceList.vue | 227 +++++++++++++++++- .../sop/gatewaycommon/bean/SpringContext.java | 30 +++ .../gatewaycommon/bean/UserKeyDefinition.java | 12 + .../manager/ZookeeperContext.java | 4 + .../gatewaycommon/param/BaseParamBuilder.java | 8 +- .../sop/gatewaycommon/param/ParamNames.java | 2 + .../sop/gatewaycommon/util/RequestUtil.java | 10 +- .../configuration/BaseZuulConfiguration.java | 8 + .../zuul/param/ZuulParamBuilder.java | 9 +- .../sop/servercommon/bean/ParamNames.java | 2 + .../mapping/ApiMappingRequestCondition.java | 4 + .../gitee/sop/servercommon/util/OpenUtil.java | 5 +- .../sop/gateway/entity/ConfigGrayUserkey.java | 42 ++++ .../EnvironmentServerChooser.java | 116 +++++++++ .../PreEnvironmentServerChooser.java | 55 ----- .../loadbalancer/ServiceGrayConfig.java | 33 +++ .../loadbalancer/SopPropertiesFactory.java | 4 +- .../sop/gateway/manager/UserKeyManager.java | 132 ++++++++++ .../mapper/ConfigGrayUserkeyMapper.java | 11 + sop.sql | 12 + 40 files changed, 947 insertions(+), 123 deletions(-) create mode 100644 doc/docs/files/10110_预发布灰度发布.md create mode 100644 sop-1.14.0.sql create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceGrayParam.java create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/UserKeyDefinition.java create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ChannelOperation.java create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigGrayUserkeyMapper.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SpringContext.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/UserKeyDefinition.java create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayUserkey.java create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java delete mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/PreEnvironmentServerChooser.java create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/ServiceGrayConfig.java create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/manager/UserKeyManager.java create mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayUserkeyMapper.java diff --git a/doc/docs/files/10110_预发布灰度发布.md b/doc/docs/files/10110_预发布灰度发布.md new file mode 100644 index 00000000..6a19915d --- /dev/null +++ b/doc/docs/files/10110_预发布灰度发布.md @@ -0,0 +1,31 @@ +# 预发布灰度发布 + +从1.14.0开始支持预发布、灰度发布,可登陆`SOP-Admin`,然后选择`服务列表`进行操作。 + +## 使用预发布 + +假设网关工程在阿里云负载均衡有两台服务器,域名分别为: + +|域名|说明| +|:---- |:---- | +|open1.domain.com |网关服务器1 | +|openpre.domain.com | 网关服务器2,作为预发布请求入口| + +线上域名为`open.domain.com`,请求网关`http://open.domain.com/api`会负载均衡到这两台服务器 + +在网关工程打开`com.gitee.sop.gateway.loadbalancer.EnvironmentServerChooser`类,修改`PRE_DOMAIN`变量 + +```java +/** + * 预发布机器域名 + */ +private static final String PRE_DOMAIN = "openpre.domain.com"; +``` + +网关工程打包发布到阿里云 + +登录SOP-Admin,在服务列表中点击预发布,然后接口的请求地址变成:`http://openpre.domain.com/api` + +## 使用灰度发布 + +灰度发布可允许指定的用户进行访问,其它用户则走正常流程。 diff --git a/sop-1.14.0.sql b/sop-1.14.0.sql new file mode 100644 index 00000000..d84dadbb --- /dev/null +++ b/sop-1.14.0.sql @@ -0,0 +1,12 @@ +use sop; + +CREATE TABLE `config_gray_userkey` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `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', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_instanceid` (`instance_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='灰度发布用户key'; \ No newline at end of file diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index ff05f7e3..8e5bb49c 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -24,6 +24,8 @@ 3.4.12 4.0.1 3.11.0 + 1.16.2 + 1.8.0 @@ -37,13 +39,13 @@ net.oschina.durcframework easyopen-spring-boot-starter - 1.16.2 + ${easyopen.version} net.oschina.durcframework fastmybatis-spring-boot-starter - 1.7.2 + ${fastmybatis.version} mysql 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 e388660d..dc6f561e 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,12 +1,16 @@ 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/isv/IsvApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/isv/IsvApi.java index 273c3553..bd4b6d25 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/isv/IsvApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/isv/IsvApi.java @@ -26,6 +26,7 @@ import com.gitee.sop.adminserver.api.isv.result.RoleVO; import com.gitee.sop.adminserver.bean.ChannelMsg; 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.IdGen; import com.gitee.sop.adminserver.common.RSATool; import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException; @@ -229,7 +230,7 @@ public class IsvApi { if (isvDetail == null) { return; } - ChannelMsg channelMsg = new ChannelMsg("update", isvDetail); + ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.ISV_INFO_UPDATE, isvDetail); String path = ZookeeperContext.getIsvInfoChannelPath(); String data = JSON.toJSONString(channelMsg); try { diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/IPBlacklistApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/IPBlacklistApi.java index 284140cc..4bb78936 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/IPBlacklistApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/IPBlacklistApi.java @@ -16,6 +16,7 @@ import com.gitee.sop.adminserver.api.service.result.ConfigIpBlacklistVO; import com.gitee.sop.adminserver.bean.ChannelMsg; 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.entity.ConfigIpBlacklist; import com.gitee.sop.adminserver.mapper.ConfigIpBlacklistMapper; import lombok.extern.slf4j.Slf4j; @@ -51,7 +52,7 @@ public class IPBlacklistApi { CopyUtil.copyPropertiesIgnoreNull(form, rec); configIpBlacklistMapper.saveIgnoreNull(rec); try { - this.sendIpBlacklistMsg(rec, BlacklistMsgType.ADD); + this.sendIpBlacklistMsg(rec, ChannelOperation.BLACKLIST_ADD); } catch (Exception e) { log.error("推送IP黑名单失败, rec:{}",rec, e); throw new BizException("推送IP黑名单失败"); @@ -75,19 +76,18 @@ public class IPBlacklistApi { } configIpBlacklistMapper.deleteById(id); try { - this.sendIpBlacklistMsg(rec, BlacklistMsgType.DELETE); + this.sendIpBlacklistMsg(rec, ChannelOperation.BLACKLIST_DELETE); } catch (Exception e) { log.error("推送IP黑名单失败, rec:{}",rec, e); throw new BizException("推送IP黑名单失败"); } } - public void sendIpBlacklistMsg(ConfigIpBlacklist configIpBlacklist, BlacklistMsgType blacklistMsgType) throws Exception { - String configData = JSON.toJSONString(configIpBlacklist); - ChannelMsg channelMsg = new ChannelMsg(blacklistMsgType.name().toLowerCase(), configData); + public void sendIpBlacklistMsg(ConfigIpBlacklist configIpBlacklist, ChannelOperation channelOperation) throws Exception { + ChannelMsg channelMsg = new ChannelMsg(channelOperation, configIpBlacklist); String jsonData = JSON.toJSONString(channelMsg); String path = ZookeeperContext.getIpBlacklistChannelPath(); - log.info("消息推送--IP黑名单设置({}), path:{}, data:{}",blacklistMsgType.name(), path, jsonData); + log.info("消息推送--IP黑名单设置({}), path:{}, data:{}",channelOperation.getOperation(), path, jsonData); ZookeeperContext.createOrUpdateData(path, jsonData); } 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 fa3d4b0a..aa4e6b9c 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 @@ -6,16 +6,23 @@ import com.gitee.easyopen.annotation.ApiService; import com.gitee.easyopen.doc.annotation.ApiDoc; import com.gitee.easyopen.doc.annotation.ApiDocMethod; import com.gitee.sop.adminserver.api.service.param.ServiceAddParam; +import com.gitee.sop.adminserver.api.service.param.ServiceInstanceGrayParam; +import com.gitee.sop.adminserver.api.service.param.ServiceInstanceParam; import com.gitee.sop.adminserver.api.service.param.ServiceSearchParam; import com.gitee.sop.adminserver.api.service.result.RouteServiceInfo; import com.gitee.sop.adminserver.api.service.result.ServiceInfoVo; import com.gitee.sop.adminserver.api.service.result.ServiceInstanceVO; +import com.gitee.sop.adminserver.bean.ChannelMsg; import com.gitee.sop.adminserver.bean.MetadataEnum; import com.gitee.sop.adminserver.bean.ServiceRouteInfo; +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.ZookeeperPathExistException; import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException; +import com.gitee.sop.adminserver.entity.ConfigGrayUserkey; +import com.gitee.sop.adminserver.mapper.ConfigGrayUserkeyMapper; import com.gitee.sop.registryapi.bean.ServiceInfo; import com.gitee.sop.registryapi.bean.ServiceInstance; import com.gitee.sop.registryapi.service.RegistryService; @@ -45,6 +52,9 @@ public class ServiceApi { @Autowired private RegistryService registryService; + @Autowired + private ConfigGrayUserkeyMapper configGrayUserkeyMapper; + @Api(name = "zookeeper.service.list") @ApiDocMethod(description = "zk中的服务列表", elementClass = RouteServiceInfo.class) List listServiceInfo(ServiceSearchParam param) { @@ -157,9 +167,9 @@ public class ServiceApi { @Api(name = "service.instance.offline") @ApiDocMethod(description = "服务禁用") - void serviceOffline(ServiceInstance param) { + void serviceOffline(ServiceInstanceParam param) { try { - registryService.offlineInstance(param); + registryService.offlineInstance(param.buildServiceInstance()); } catch (Exception e) { log.error("服务禁用失败,param:{}", param, e); throw new BizException("服务禁用失败,请查看日志"); @@ -168,9 +178,9 @@ public class ServiceApi { @Api(name = "service.instance.online") @ApiDocMethod(description = "服务启用") - void serviceOnline(ServiceInstance param) throws IOException { + void serviceOnline(ServiceInstanceParam param) throws IOException { try { - registryService.onlineInstance(param); + registryService.onlineInstance(param.buildServiceInstance()); } catch (Exception e) { log.error("服务启用失败,param:{}", param, e); throw new BizException("服务启用失败,请查看日志"); @@ -179,10 +189,10 @@ public class ServiceApi { @Api(name = "service.instance.env.pre") @ApiDocMethod(description = "预发布") - void serviceEnvPre(ServiceInstance param) throws IOException { + void serviceEnvPre(ServiceInstanceParam param) throws IOException { try { MetadataEnum envPre = MetadataEnum.ENV_PRE; - registryService.setMetadata(param, envPre.getKey(), envPre.getValue()); + registryService.setMetadata(param.buildServiceInstance(), envPre.getKey(), envPre.getValue()); } catch (Exception e) { log.error("预发布失败,param:{}", param, e); throw new BizException("预发布失败,请查看日志"); @@ -191,10 +201,31 @@ public class ServiceApi { @Api(name = "service.instance.env.gray") @ApiDocMethod(description = "灰度发布") - void serviceEnvGray(ServiceInstance param) throws IOException { + void serviceEnvGray(ServiceInstanceGrayParam param) throws IOException { try { - MetadataEnum envPre = MetadataEnum.ENV_GRAY; - registryService.setMetadata(param, envPre.getKey(), envPre.getValue()); + Boolean onlyUpdateGrayUserkey = param.getOnlyUpdateGrayUserkey(); + if (onlyUpdateGrayUserkey == null || !onlyUpdateGrayUserkey) { + MetadataEnum envPre = MetadataEnum.ENV_GRAY; + registryService.setMetadata(param.buildServiceInstance(), envPre.getKey(), envPre.getValue()); + } + + String instanceId = param.getInstanceId(); + String userKeyContent = param.getUserKeyContent(); + String nameVersionContent = param.getNameVersionContent(); + + ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("instance_id", instanceId); + if (configGrayUserkey == null) { + configGrayUserkey = new ConfigGrayUserkey(); + configGrayUserkey.setInstanceId(instanceId); + configGrayUserkey.setUserKeyContent(userKeyContent); + configGrayUserkey.setNameVersionContent(nameVersionContent); + configGrayUserkeyMapper.save(configGrayUserkey); + } else { + configGrayUserkey.setUserKeyContent(userKeyContent); + configGrayUserkey.setNameVersionContent(nameVersionContent); + configGrayUserkeyMapper.update(configGrayUserkey); + } + this.sendUserKeyMsg(instanceId, ChannelOperation.GRAY_USER_KEY_SET); } catch (Exception e) { log.error("灰度发布失败,param:{}", param, e); throw new BizException("灰度发布失败,请查看日志"); @@ -207,10 +238,26 @@ 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); } catch (Exception e) { log.error("上线失败,param:{}", param, e); throw new BizException("上线失败,请查看日志"); } } + @Api(name = "service.instance.gray.userkey.get") + ConfigGrayUserkey getGrayUserkey(ServiceSearchParam param) { + return configGrayUserkeyMapper.getByColumn("instance_id", param.getInstanceId()); + } + + private void sendUserKeyMsg(String serviceId, ChannelOperation channelOperation) { + UserKeyDefinition userKeyDefinition = new UserKeyDefinition(); + userKeyDefinition.setServiceId(serviceId); + ChannelMsg channelMsg = new ChannelMsg(channelOperation, userKeyDefinition); + String jsonData = JSON.toJSONString(channelMsg); + String path = ZookeeperContext.getUserKeyChannelPath(); + log.info("消息推送--灰度发布({}), path:{}, data:{}",channelOperation.getOperation(), path, jsonData); + ZookeeperContext.createOrUpdateData(path, jsonData); + } + } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceGrayParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceGrayParam.java new file mode 100644 index 00000000..7fbc377d --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceGrayParam.java @@ -0,0 +1,26 @@ +package com.gitee.sop.adminserver.api.service.param; + +import com.gitee.easyopen.doc.annotation.ApiDocField; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; + +/** + * @author tanghc + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ServiceInstanceGrayParam extends ServiceInstanceParam { + + @ApiDocField(description = "灰度发布用户,多个用英文逗号隔开") + @NotBlank(message = "灰度发布用户不能为空") + private String userKeyContent; + + @ApiDocField(description = "灰度发布接口名版本号如:order.get1.0=1.2,多个用英文逗号隔开") + @NotBlank(message = "灰度发布接口名版本号不能为空") + private String nameVersionContent; + + @ApiDocField(description = "是否仅更新灰度用户") + private Boolean onlyUpdateGrayUserkey; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceParam.java index 7dfe26fc..ad550de5 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceParam.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceInstanceParam.java @@ -1,6 +1,8 @@ package com.gitee.sop.adminserver.api.service.param; import com.gitee.easyopen.doc.annotation.ApiDocField; +import com.gitee.easyopen.util.CopyUtil; +import com.gitee.sop.registryapi.bean.ServiceInstance; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -17,4 +19,29 @@ public class ServiceInstanceParam { @ApiDocField(description = "instanceId") @NotBlank(message = "instanceId不能为空") private String instanceId; + + /** + * ip + */ + @ApiDocField(description = "ip") + private String ip; + + /** + * port + */ + @ApiDocField(description = "port") + private int port; + + /** + * 服务状态,UP:已上线,OUT_OF_SERVICE:已下线 + */ + @ApiDocField(description = "status") + private String status; + + + public ServiceInstance buildServiceInstance() { + ServiceInstance serviceInstance = new ServiceInstance(); + CopyUtil.copyPropertiesIgnoreNull(this, serviceInstance); + return serviceInstance; + } } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceSearchParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceSearchParam.java index 34535ad6..217482a8 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceSearchParam.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/ServiceSearchParam.java @@ -4,8 +4,6 @@ import com.gitee.easyopen.doc.annotation.ApiDocField; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotBlank; - /** * @author tanghc */ @@ -15,4 +13,7 @@ public class ServiceSearchParam { @ApiDocField(description = "服务名serviceId") private String serviceId; + + @ApiDocField(description = "instanceId") + private String instanceId; } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ChannelMsg.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ChannelMsg.java index dabbe29b..558107c4 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ChannelMsg.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ChannelMsg.java @@ -1,5 +1,6 @@ package com.gitee.sop.adminserver.bean; +import com.gitee.sop.adminserver.common.ChannelOperation; import lombok.Data; /** @@ -8,8 +9,8 @@ import lombok.Data; @Data public class ChannelMsg { - public ChannelMsg(String operation, Object data) { - this.operation = operation; + public ChannelMsg(ChannelOperation channelOperation, Object data) { + this.operation = channelOperation.getOperation(); this.data = data; } 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 new file mode 100644 index 00000000..9fe32449 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/UserKeyDefinition.java @@ -0,0 +1,12 @@ +package com.gitee.sop.adminserver.bean; + +import lombok.Data; + +/** + * @author tanghc + */ +@Data +public class UserKeyDefinition { + private String serviceId; + private String data; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java index 50547a75..285433f0 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java @@ -89,6 +89,10 @@ public class ZookeeperContext { return serviceIdPath + "/" + routeId; } + public static String getUserKeyChannelPath() { + return SOP_MSG_CHANNEL_PATH + "/userkey"; + } + public static String getIsvInfoChannelPath() { return SOP_MSG_CHANNEL_PATH + "/isvinfo"; } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ChannelOperation.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ChannelOperation.java new file mode 100644 index 00000000..741ae0b8 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ChannelOperation.java @@ -0,0 +1,60 @@ +package com.gitee.sop.adminserver.common; + +/** + * @author tanghc + */ +public enum ChannelOperation { + /** + * 限流推送路由配置-修改 + */ + LIMIT_CONFIG_UPDATE("update"), + + /** + * 路由信息更新 + */ + ROUTE_CONFIG_UPDATE("update"), + + /** + * isv信息修改 + */ + ISV_INFO_UPDATE("update"), + + /** + * 黑名单消息类型:添加 + */ + BLACKLIST_ADD("add"), + /** + * 黑名单消息类型:删除 + */ + BLACKLIST_DELETE("delete"), + + /** + * 路由权限配置更新 + */ + ROUTE_PERMISSION_UPDATE("update"), + /** + * 路由权限加载 + */ + ROUTE_PERMISSION_RELOAD("reload"), + + /** + * 灰度发布用户key设置 + */ + GRAY_USER_KEY_SET("set"), + /** + * 灰度发布用户key清除 + */ + GRAY_USER_KEY_CLEAR("clear"), + + ; + + private String operation; + + ChannelOperation(String operation) { + this.operation = operation; + } + + public String getOperation() { + return operation; + } +} 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 new file mode 100644 index 00000000..1bd13466 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java @@ -0,0 +1,42 @@ +package com.gitee.sop.adminserver.entity; + +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + + +/** + * 表名:config_gray_userkey + * 备注:灰度发布用户key + * + * @author tanghc + */ +@Table(name = "config_gray_userkey") +@Data +public class ConfigGrayUserkey { + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + /** 数据库字段:id */ + private Long id; + + /** instanceId, 数据库字段:instance_id */ + private String instanceId; + + /** 用户key,多个用引文逗号隔开, 数据库字段:user_key_content */ + private String userKeyContent; + + /** 需要灰度的接口,goods.get=1.2,order.list=1.2, 数据库字段:name_version_content */ + private String nameVersionContent; + + /** 数据库字段:gmt_create */ + private Date gmtCreate; + + /** 数据库字段:gmt_modified */ + private Date gmtModified; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigGrayUserkeyMapper.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigGrayUserkeyMapper.java new file mode 100644 index 00000000..7af34e0d --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigGrayUserkeyMapper.java @@ -0,0 +1,12 @@ +package com.gitee.sop.adminserver.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; + +import com.gitee.sop.adminserver.entity.ConfigGrayUserkey; + + +/** + * @author tanghc + */ +public interface ConfigGrayUserkeyMapper extends CrudMapper { +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java index 0b09a09b..d1dd2ceb 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteConfigService.java @@ -5,6 +5,7 @@ import com.gitee.sop.adminserver.bean.ChannelMsg; import com.gitee.sop.adminserver.bean.ConfigLimitDto; import com.gitee.sop.adminserver.bean.RouteConfigDto; import com.gitee.sop.adminserver.bean.ZookeeperContext; +import com.gitee.sop.adminserver.common.ChannelOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -21,8 +22,7 @@ public class RouteConfigService { * @throws Exception */ public void sendRouteConfigMsg(RouteConfigDto routeConfigDto) { - String configData = JSON.toJSONString(routeConfigDto); - ChannelMsg channelMsg = new ChannelMsg("update", configData); + ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.ROUTE_CONFIG_UPDATE, routeConfigDto); String jsonData = JSON.toJSONString(channelMsg); String path = ZookeeperContext.getRouteConfigChannelPath(); log.info("消息推送--路由配置(update), path:{}, data:{}", path, jsonData); @@ -35,8 +35,7 @@ public class RouteConfigService { * @throws Exception */ public void sendLimitConfigMsg(ConfigLimitDto routeConfigDto) throws Exception { - String configData = JSON.toJSONString(routeConfigDto); - ChannelMsg channelMsg = new ChannelMsg("update", configData); + ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.LIMIT_CONFIG_UPDATE, routeConfigDto); String jsonData = JSON.toJSONString(channelMsg); String path = ZookeeperContext.getLimitConfigChannelPath(); log.info("消息推送--限流配置(update), path:{}, data:{}", path, jsonData); diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RoutePermissionService.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RoutePermissionService.java index 3a352bbd..3595d88f 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RoutePermissionService.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RoutePermissionService.java @@ -7,6 +7,7 @@ import com.gitee.sop.adminserver.bean.ChannelMsg; import com.gitee.sop.adminserver.bean.IsvRoutePermission; import com.gitee.sop.adminserver.bean.SopAdminConstants; import com.gitee.sop.adminserver.bean.ZookeeperContext; +import com.gitee.sop.adminserver.common.ChannelOperation; import com.gitee.sop.adminserver.entity.PermIsvRole; import com.gitee.sop.adminserver.entity.PermRolePermission; import com.gitee.sop.adminserver.mapper.IsvInfoMapper; @@ -68,7 +69,7 @@ public class RoutePermissionService { isvRoutePermission.setAppKey(appKey); isvRoutePermission.setRouteIdList(routeIdList); isvRoutePermission.setRouteIdListMd5(roleCodeListMd5); - ChannelMsg channelMsg = new ChannelMsg("update", isvRoutePermission); + ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.ROUTE_PERMISSION_UPDATE, isvRoutePermission); String jsonData = JSON.toJSONString(channelMsg); String path = ZookeeperContext.getIsvRoutePermissionChannelPath(); log.info("消息推送--路由权限(update), path:{}, data:{}", path, jsonData); @@ -105,7 +106,7 @@ public class RoutePermissionService { }); IsvRoutePermission isvRoutePermission = new IsvRoutePermission(); isvRoutePermission.setListenPath(listenPath); - ChannelMsg channelMsg = new ChannelMsg("reload", isvRoutePermission); + ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.ROUTE_PERMISSION_RELOAD, isvRoutePermission); String jsonData = JSON.toJSONString(channelMsg); String path = ZookeeperContext.getIsvRoutePermissionChannelPath(); log.info("消息推送--路由权限(reload), path:{}, data:{}", path, jsonData); 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 72f173cd..de57a517 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,9 +44,5 @@ registry.name=eureka logging.level.com.gitee=debug -# 不用改 -mybatis.fill.com.gitee.fastmybatis.core.support.DateFillInsert=gmt_create -mybatis.fill.com.gitee.fastmybatis.core.support.DateFillUpdate=gmt_modified - # 不用改,如果要改,请全局替换修改 zuul.secret=MZZOUSTua6LzApIWXCwEgbBmxSzpzC diff --git a/sop-admin/sop-admin-vue/src/views/service/ipBlacklist.vue b/sop-admin/sop-admin-vue/src/views/service/ipBlacklist.vue index e7e79a25..c6ce5592 100644 --- a/sop-admin/sop-admin-vue/src/views/service/ipBlacklist.vue +++ b/sop-admin/sop-admin-vue/src/views/service/ipBlacklist.vue @@ -88,11 +88,11 @@ \ No newline at end of file +SOP Admin
\ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-29e7142c.d10599db.css b/sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-ea2e58a4.d10599db.css similarity index 100% rename from sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-29e7142c.d10599db.css rename to sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-ea2e58a4.d10599db.css diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.4a507d5e.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.8145abe4.js similarity index 99% rename from sop-admin/sop-admin-server/src/main/resources/public/static/js/app.4a507d5e.js rename to sop-admin/sop-admin-server/src/main/resources/public/static/js/app.8145abe4.js index d70a41b1..03fbcc41 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.4a507d5e.js +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.8145abe4.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(e,t,n){e.exports=n("56d7")},"0cb8":function(e,t,n){},"186a":function(e,t,n){"use strict";var a=n("dc52"),i=n.n(a);i.a},"18f0":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-link",use:"icon-link-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"1f59":function(e,t,n){},2536:function(e,t,n){},2635:function(e,t,n){},"2a3d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-password",use:"icon-password-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"30c3":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-example",use:"icon-example-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"34c8":function(e,t,n){"use strict";var a=n("5332"),i=n.n(a);i.a},"405a":function(e,t,n){"use strict";var a=n("1f59"),i=n.n(a);i.a},"47f1":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-table",use:"icon-table-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"4df5":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-eye",use:"icon-eye-usage",viewBox:"0 0 128 64",content:''});r.a.add(c);t["default"]=c},"50be":function(e,t,n){"use strict";var a=n("2536"),i=n.n(a);i.a},"51ff":function(e,t,n){var a={"./dashboard.svg":"f782","./example.svg":"30c3","./eye-open.svg":"d7ec","./eye.svg":"4df5","./form.svg":"eb1b","./link.svg":"18f0","./nested.svg":"dcf8","./password.svg":"2a3d","./table.svg":"47f1","./tree.svg":"93cd","./user.svg":"b3b5"};function i(e){var t=o(e);return n(t)}function o(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}i.keys=function(){return Object.keys(a)},i.resolve=o,e.exports=i,i.id="51ff"},5332:function(e,t,n){},"56d7":function(e,t,n){"use strict";n.r(t);n("cadf"),n("551c"),n("f751"),n("097d");var a=n("2b0e"),i=(n("f5df"),n("5c96")),o=n.n(i),r=(n("0fae"),n("f0d9")),c=n.n(r),s=(n("b20f"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],l={name:"App"},d=l,m=n("2877"),h=Object(m["a"])(d,s,u,!1,null,null,null),f=h.exports,p=n("2f62"),v=(n("7f7f"),{sidebar:function(e){return e.app.sidebar},device:function(e){return e.app.device},token:function(e){return e.user.token},avatar:function(e){return e.user.avatar},name:function(e){return e.user.name}}),b=v,g=n("a78e"),w=n.n(g),x={sidebar:{opened:!w.a.get("sidebarStatus")||!!+w.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop"},y={TOGGLE_SIDEBAR:function(e){e.sidebar.opened=!e.sidebar.opened,e.sidebar.withoutAnimation=!1,e.sidebar.opened?w.a.set("sidebarStatus",1):w.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(e,t){w.a.set("sidebarStatus",0),e.sidebar.opened=!1,e.sidebar.withoutAnimation=t},TOGGLE_DEVICE:function(e,t){e.device=t}},k={toggleSideBar:function(e){var t=e.commit;t("TOGGLE_SIDEBAR")},closeSideBar:function(e,t){var n=e.commit,a=t.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(e,t){var n=e.commit;n("TOGGLE_DEVICE",t)}},_={namespaced:!0,state:x,mutations:y,actions:k},C=n("83d6"),O=n.n(C),S=O.a.showSettings,z=O.a.fixedHeader,B=O.a.sidebarLogo,H={showSettings:S,fixedHeader:z,sidebarLogo:B},M={CHANGE_SETTING:function(e,t){var n=t.key,a=t.value;e.hasOwnProperty(n)&&(e[n]=a)}},T={changeSetting:function(e,t){var n=e.commit;n("CHANGE_SETTING",t)}},E={namespaced:!0,state:H,mutations:M,actions:T},L=n("bc3a"),$=n.n(L),V=n("5f87"),A=$.a.create({baseURL:"/api",withCredentials:!0,timeout:5e3});A.interceptors.request.use(function(e){return bt.getters.token&&(e.headers["X-Token"]=Object(V["a"])()),e},function(e){return console.log(e),Promise.reject(e)}),A.interceptors.response.use(function(e){var t=e.data;return 2e4!==t.code?(Object(i["Message"])({message:t.message||"error",type:"error",duration:5e3}),50008!==t.code&&50012!==t.code&&50014!==t.code||i["MessageBox"].confirm("You have been logged out, you can cancel to stay on this page, or log in again","Confirm logout",{confirmButtonText:"Re-Login",cancelButtonText:"Cancel",type:"warning"}).then(function(){bt.dispatch("user/resetToken").then(function(){location.reload()})}),Promise.reject(t.message||"error")):t},function(e){return console.log("err"+e),Object(i["Message"])({message:e.message,type:"error",duration:5e3}),Promise.reject(e)});var j=A;function I(e){return j({url:"/user/login",method:"post",data:e})}function P(e){return j({url:"/user/info",method:"get",params:{token:e}})}function N(){return j({url:"/user/logout",method:"post"})}var D=n("8c4f"),R=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-wrapper",class:e.classObj},["mobile"===e.device&&e.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:e.handleClickOutside}}):e._e(),e._v(" "),n("sidebar",{staticClass:"sidebar-container"}),e._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":e.fixedHeader}},[n("navbar")],1),e._v(" "),n("app-main")],1)],1)},q=[],G=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"navbar"},[n("hamburger",{staticClass:"hamburger-container",attrs:{"is-active":e.sidebar.opened},on:{toggleClick:e.toggleSideBar}}),e._v(" "),n("breadcrumb",{staticClass:"breadcrumb-container"}),e._v(" "),n("div",{staticClass:"right-menu"},[n("el-button",{staticStyle:{"margin-right":"10px"},attrs:{type:"text"},on:{click:e.doLogout}},[e._v("退出")])],1)],1)},F=[],U=n("cebc"),K=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},e._l(e.levelList,function(t,a){return n("el-breadcrumb-item",{key:t.path},["noRedirect"===t.redirect||a==e.levelList.length-1?n("span",{staticClass:"no-redirect"},[e._v(e._s(t.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),e.handleLink(t)}}},[e._v(e._s(t.meta.title))])])}),1)],1)},W=[],J=n("bd11"),X=n.n(J),Y={data:function(){return{levelList:null}},watch:{$route:function(){this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var e=this.$route.matched.filter(function(e){return e.meta&&e.meta.title}),t=e[0];this.isDashboard(t)||(e=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(e)),this.levelList=e.filter(function(e){return e.meta&&e.meta.title&&!1!==e.meta.breadcrumb})},isDashboard:function(e){var t=e&&e.name;return!!t&&t.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(e){var t=this.$route.params,n=X.a.compile(e);return n(t)},handleLink:function(e){var t=e.redirect,n=e.path;t?this.$router.push(t):this.$router.push(this.pathCompile(n))}}},Q=Y,Z=(n("34c8"),Object(m["a"])(Q,K,W,!1,null,"62cc9144",null)),ee=Z.exports,te=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticStyle:{padding:"0 15px"},on:{click:e.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":e.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},ne=[],ae={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},ie=ae,oe=(n("186a"),Object(m["a"])(ie,te,ne,!1,null,"49e15297",null)),re=oe.exports,ce={components:{Breadcrumb:ee,Hamburger:re},computed:Object(U["a"])({},Object(p["b"])(["sidebar","avatar"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},doLogout:function(){this.logout()}}},se=ce,ue=(n("405a"),Object(m["a"])(se,G,F,!1,null,"1eff5c58",null)),le=ue.exports,de=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:{"has-logo":e.showLogo}},[e.showLogo?n("logo",{attrs:{collapse:e.isCollapse}}):e._e(),e._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":e.activeMenu,collapse:e.isCollapse,"background-color":e.variables.menuBg,"text-color":e.variables.menuText,"unique-opened":!1,"active-text-color":e.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},e._l(e.routes,function(e){return n("sidebar-item",{key:e.path,attrs:{item:e,"base-path":e.path}})}),1)],1)],1)},me=[],he=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:e.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[e.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):e._e(),e._v(" "),n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])])],1)],1)},fe=[],pe={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"SOP Admin",logo:"https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png"}}},ve=pe,be=(n("7c27"),Object(m["a"])(ve,he,fe,!1,null,"b905289c",null)),ge=be.exports,we=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.item.hidden?e._e():n("div",{staticClass:"menu-wrapper"},[!e.hasOneShowingChild(e.item.children,e.item)||e.onlyOneChild.children&&!e.onlyOneChild.noShowingChildren||e.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:e.resolvePath(e.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[e.item.meta?n("item",{attrs:{icon:e.item.meta&&e.item.meta.icon,title:e.item.meta.title}}):e._e()],1),e._v(" "),e._l(e.item.children,function(t){return n("sidebar-item",{key:t.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:t,"base-path":e.resolvePath(t.path)}})})],2):[e.onlyOneChild.meta?n("app-link",{attrs:{to:e.resolvePath(e.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!e.isNest},attrs:{index:e.resolvePath(e.onlyOneChild.path)}},[n("item",{attrs:{icon:e.onlyOneChild.meta.icon||e.item.meta&&e.item.meta.icon,title:e.onlyOneChild.meta.title}})],1)],1):e._e()]],2)},xe=[],ye=n("df7c"),ke=n.n(ye);function _e(e){return/^(https?:|mailto:|tel:)/.test(e)}var Ce,Oe,Se={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(e,t){var n=t.props,a=n.icon,i=n.title,o=[];return a&&o.push(e("svg-icon",{attrs:{"icon-class":a}})),i&&o.push(e("span",{slot:"title"},[i])),o}},ze=Se,Be=Object(m["a"])(ze,Ce,Oe,!1,null,null,null),He=Be.exports,Me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("component",e._b({},"component",e.linkProps(e.to),!1),[e._t("default")],2)},Te=[],Ee={props:{to:{type:String,required:!0}},methods:{linkProps:function(e){return _e(e)?{is:"a",href:e,target:"_blank",rel:"noopener"}:{is:"router-link",to:e}}}},Le=Ee,$e=Object(m["a"])(Le,Me,Te,!1,null,null,null),Ve=$e.exports,Ae={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var e=this,t=this.$refs.subMenu;if(t){var n=t.handleMouseleave;t.handleMouseleave=function(t){"mobile"!==e.device&&n(t)}}}}},je={name:"SidebarItem",components:{Item:He,AppLink:Ve},mixins:[Ae],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=t.filter(function(t){return!t.hidden&&(e.onlyOneChild=t,!0)});return 1===a.length||0===a.length&&(this.onlyOneChild=Object(U["a"])({},n,{path:"",noShowingChildren:!0}),!0)},resolvePath:function(e){return _e(e)?e:_e(this.basePath)?this.basePath:ke.a.resolve(this.basePath,e)}}},Ie=je,Pe=Object(m["a"])(Ie,we,xe,!1,null,null,null),Ne=Pe.exports,De=n("cf1e"),Re=n.n(De),qe={components:{SidebarItem:Ne,Logo:ge},computed:Object(U["a"])({},Object(p["b"])(["sidebar"]),{routes:function(){return this.$router.options.routes},activeMenu:function(){var e=this.$route,t=e.meta,n=e.path;return t.activeMenu?t.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return Re.a},isCollapse:function(){return!this.sidebar.opened}})},Ge=qe,Fe=Object(m["a"])(Ge,de,me,!1,null,null,null),Ue=Fe.exports,Ke=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:e.key})],1)],1)},We=[],Je={name:"AppMain",computed:{key:function(){return this.$route.fullPath}}},Xe=Je,Ye=(n("50be"),Object(m["a"])(Xe,Ke,We,!1,null,"43c24f68",null)),Qe=Ye.exports,Ze=document,et=Ze.body,tt=992,nt={watch:{$route:function(e){"mobile"===this.device&&this.sidebar.opened&&bt.dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var e=this.$_isMobile();e&&(bt.dispatch("app/toggleDevice","mobile"),bt.dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var e=et.getBoundingClientRect();return e.width-1'});r.a.add(c);t["default"]=c},"9f2b":function(e,t,n){"use strict";var a=n("5bb9"),i=n.n(a);i.a},b20f:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},b3b5:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-user",use:"icon-user-usage",viewBox:"0 0 130 130",content:''});r.a.add(c);t["default"]=c},cf1e:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d7ec:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-eye-open",use:"icon-eye-open-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(c);t["default"]=c},dc52:function(e,t,n){},dcf8:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-nested",use:"icon-nested-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},eb1b:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-form",use:"icon-form-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},f782:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-dashboard",use:"icon-dashboard-usage",viewBox:"0 0 128 100",content:''});r.a.add(c);t["default"]=c}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(e,t,n){e.exports=n("56d7")},"0cb8":function(e,t,n){},"186a":function(e,t,n){"use strict";var a=n("dc52"),i=n.n(a);i.a},"18f0":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-link",use:"icon-link-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"1f59":function(e,t,n){},2536:function(e,t,n){},2635:function(e,t,n){},"2a3d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-password",use:"icon-password-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"30c3":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-example",use:"icon-example-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"34c8":function(e,t,n){"use strict";var a=n("5332"),i=n.n(a);i.a},"405a":function(e,t,n){"use strict";var a=n("1f59"),i=n.n(a);i.a},"47f1":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-table",use:"icon-table-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},"4df5":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-eye",use:"icon-eye-usage",viewBox:"0 0 128 64",content:''});r.a.add(c);t["default"]=c},"50be":function(e,t,n){"use strict";var a=n("2536"),i=n.n(a);i.a},"51ff":function(e,t,n){var a={"./dashboard.svg":"f782","./example.svg":"30c3","./eye-open.svg":"d7ec","./eye.svg":"4df5","./form.svg":"eb1b","./link.svg":"18f0","./nested.svg":"dcf8","./password.svg":"2a3d","./table.svg":"47f1","./tree.svg":"93cd","./user.svg":"b3b5"};function i(e){var t=o(e);return n(t)}function o(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}i.keys=function(){return Object.keys(a)},i.resolve=o,e.exports=i,i.id="51ff"},5332:function(e,t,n){},"56d7":function(e,t,n){"use strict";n.r(t);n("cadf"),n("551c"),n("f751"),n("097d");var a=n("2b0e"),i=(n("f5df"),n("5c96")),o=n.n(i),r=(n("0fae"),n("f0d9")),c=n.n(r),s=(n("b20f"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],l={name:"App"},d=l,m=n("2877"),h=Object(m["a"])(d,s,u,!1,null,null,null),f=h.exports,p=n("2f62"),v=(n("7f7f"),{sidebar:function(e){return e.app.sidebar},device:function(e){return e.app.device},token:function(e){return e.user.token},avatar:function(e){return e.user.avatar},name:function(e){return e.user.name}}),b=v,g=n("a78e"),w=n.n(g),x={sidebar:{opened:!w.a.get("sidebarStatus")||!!+w.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop"},y={TOGGLE_SIDEBAR:function(e){e.sidebar.opened=!e.sidebar.opened,e.sidebar.withoutAnimation=!1,e.sidebar.opened?w.a.set("sidebarStatus",1):w.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(e,t){w.a.set("sidebarStatus",0),e.sidebar.opened=!1,e.sidebar.withoutAnimation=t},TOGGLE_DEVICE:function(e,t){e.device=t}},k={toggleSideBar:function(e){var t=e.commit;t("TOGGLE_SIDEBAR")},closeSideBar:function(e,t){var n=e.commit,a=t.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(e,t){var n=e.commit;n("TOGGLE_DEVICE",t)}},_={namespaced:!0,state:x,mutations:y,actions:k},C=n("83d6"),O=n.n(C),S=O.a.showSettings,z=O.a.fixedHeader,B=O.a.sidebarLogo,H={showSettings:S,fixedHeader:z,sidebarLogo:B},M={CHANGE_SETTING:function(e,t){var n=t.key,a=t.value;e.hasOwnProperty(n)&&(e[n]=a)}},T={changeSetting:function(e,t){var n=e.commit;n("CHANGE_SETTING",t)}},E={namespaced:!0,state:H,mutations:M,actions:T},L=n("bc3a"),$=n.n(L),V=n("5f87"),A=$.a.create({baseURL:"/api",withCredentials:!0,timeout:5e3});A.interceptors.request.use(function(e){return bt.getters.token&&(e.headers["X-Token"]=Object(V["a"])()),e},function(e){return console.log(e),Promise.reject(e)}),A.interceptors.response.use(function(e){var t=e.data;return 2e4!==t.code?(Object(i["Message"])({message:t.message||"error",type:"error",duration:5e3}),50008!==t.code&&50012!==t.code&&50014!==t.code||i["MessageBox"].confirm("You have been logged out, you can cancel to stay on this page, or log in again","Confirm logout",{confirmButtonText:"Re-Login",cancelButtonText:"Cancel",type:"warning"}).then(function(){bt.dispatch("user/resetToken").then(function(){location.reload()})}),Promise.reject(t.message||"error")):t},function(e){return console.log("err"+e),Object(i["Message"])({message:e.message,type:"error",duration:5e3}),Promise.reject(e)});var j=A;function I(e){return j({url:"/user/login",method:"post",data:e})}function P(e){return j({url:"/user/info",method:"get",params:{token:e}})}function N(){return j({url:"/user/logout",method:"post"})}var D=n("8c4f"),R=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-wrapper",class:e.classObj},["mobile"===e.device&&e.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:e.handleClickOutside}}):e._e(),e._v(" "),n("sidebar",{staticClass:"sidebar-container"}),e._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":e.fixedHeader}},[n("navbar")],1),e._v(" "),n("app-main")],1)],1)},q=[],G=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"navbar"},[n("hamburger",{staticClass:"hamburger-container",attrs:{"is-active":e.sidebar.opened},on:{toggleClick:e.toggleSideBar}}),e._v(" "),n("breadcrumb",{staticClass:"breadcrumb-container"}),e._v(" "),n("div",{staticClass:"right-menu"},[n("el-button",{staticStyle:{"margin-right":"10px"},attrs:{type:"text"},on:{click:e.doLogout}},[e._v("退出")])],1)],1)},F=[],U=n("cebc"),K=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},e._l(e.levelList,function(t,a){return n("el-breadcrumb-item",{key:t.path},["noRedirect"===t.redirect||a==e.levelList.length-1?n("span",{staticClass:"no-redirect"},[e._v(e._s(t.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),e.handleLink(t)}}},[e._v(e._s(t.meta.title))])])}),1)],1)},W=[],J=n("bd11"),X=n.n(J),Y={data:function(){return{levelList:null}},watch:{$route:function(){this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var e=this.$route.matched.filter(function(e){return e.meta&&e.meta.title}),t=e[0];this.isDashboard(t)||(e=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(e)),this.levelList=e.filter(function(e){return e.meta&&e.meta.title&&!1!==e.meta.breadcrumb})},isDashboard:function(e){var t=e&&e.name;return!!t&&t.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(e){var t=this.$route.params,n=X.a.compile(e);return n(t)},handleLink:function(e){var t=e.redirect,n=e.path;t?this.$router.push(t):this.$router.push(this.pathCompile(n))}}},Q=Y,Z=(n("34c8"),Object(m["a"])(Q,K,W,!1,null,"62cc9144",null)),ee=Z.exports,te=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticStyle:{padding:"0 15px"},on:{click:e.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":e.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},ne=[],ae={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},ie=ae,oe=(n("186a"),Object(m["a"])(ie,te,ne,!1,null,"49e15297",null)),re=oe.exports,ce={components:{Breadcrumb:ee,Hamburger:re},computed:Object(U["a"])({},Object(p["b"])(["sidebar","avatar"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},doLogout:function(){this.logout()}}},se=ce,ue=(n("405a"),Object(m["a"])(se,G,F,!1,null,"1eff5c58",null)),le=ue.exports,de=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:{"has-logo":e.showLogo}},[e.showLogo?n("logo",{attrs:{collapse:e.isCollapse}}):e._e(),e._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":e.activeMenu,collapse:e.isCollapse,"background-color":e.variables.menuBg,"text-color":e.variables.menuText,"unique-opened":!1,"active-text-color":e.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},e._l(e.routes,function(e){return n("sidebar-item",{key:e.path,attrs:{item:e,"base-path":e.path}})}),1)],1)],1)},me=[],he=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:e.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[e.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):e._e(),e._v(" "),n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])])],1)],1)},fe=[],pe={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"SOP Admin",logo:"https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png"}}},ve=pe,be=(n("7c27"),Object(m["a"])(ve,he,fe,!1,null,"b905289c",null)),ge=be.exports,we=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.item.hidden?e._e():n("div",{staticClass:"menu-wrapper"},[!e.hasOneShowingChild(e.item.children,e.item)||e.onlyOneChild.children&&!e.onlyOneChild.noShowingChildren||e.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:e.resolvePath(e.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[e.item.meta?n("item",{attrs:{icon:e.item.meta&&e.item.meta.icon,title:e.item.meta.title}}):e._e()],1),e._v(" "),e._l(e.item.children,function(t){return n("sidebar-item",{key:t.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:t,"base-path":e.resolvePath(t.path)}})})],2):[e.onlyOneChild.meta?n("app-link",{attrs:{to:e.resolvePath(e.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!e.isNest},attrs:{index:e.resolvePath(e.onlyOneChild.path)}},[n("item",{attrs:{icon:e.onlyOneChild.meta.icon||e.item.meta&&e.item.meta.icon,title:e.onlyOneChild.meta.title}})],1)],1):e._e()]],2)},xe=[],ye=n("df7c"),ke=n.n(ye);function _e(e){return/^(https?:|mailto:|tel:)/.test(e)}var Ce,Oe,Se={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(e,t){var n=t.props,a=n.icon,i=n.title,o=[];return a&&o.push(e("svg-icon",{attrs:{"icon-class":a}})),i&&o.push(e("span",{slot:"title"},[i])),o}},ze=Se,Be=Object(m["a"])(ze,Ce,Oe,!1,null,null,null),He=Be.exports,Me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("component",e._b({},"component",e.linkProps(e.to),!1),[e._t("default")],2)},Te=[],Ee={props:{to:{type:String,required:!0}},methods:{linkProps:function(e){return _e(e)?{is:"a",href:e,target:"_blank",rel:"noopener"}:{is:"router-link",to:e}}}},Le=Ee,$e=Object(m["a"])(Le,Me,Te,!1,null,null,null),Ve=$e.exports,Ae={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var e=this,t=this.$refs.subMenu;if(t){var n=t.handleMouseleave;t.handleMouseleave=function(t){"mobile"!==e.device&&n(t)}}}}},je={name:"SidebarItem",components:{Item:He,AppLink:Ve},mixins:[Ae],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=t.filter(function(t){return!t.hidden&&(e.onlyOneChild=t,!0)});return 1===a.length||0===a.length&&(this.onlyOneChild=Object(U["a"])({},n,{path:"",noShowingChildren:!0}),!0)},resolvePath:function(e){return _e(e)?e:_e(this.basePath)?this.basePath:ke.a.resolve(this.basePath,e)}}},Ie=je,Pe=Object(m["a"])(Ie,we,xe,!1,null,null,null),Ne=Pe.exports,De=n("cf1e"),Re=n.n(De),qe={components:{SidebarItem:Ne,Logo:ge},computed:Object(U["a"])({},Object(p["b"])(["sidebar"]),{routes:function(){return this.$router.options.routes},activeMenu:function(){var e=this.$route,t=e.meta,n=e.path;return t.activeMenu?t.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return Re.a},isCollapse:function(){return!this.sidebar.opened}})},Ge=qe,Fe=Object(m["a"])(Ge,de,me,!1,null,null,null),Ue=Fe.exports,Ke=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:e.key})],1)],1)},We=[],Je={name:"AppMain",computed:{key:function(){return this.$route.fullPath}}},Xe=Je,Ye=(n("50be"),Object(m["a"])(Xe,Ke,We,!1,null,"43c24f68",null)),Qe=Ye.exports,Ze=document,et=Ze.body,tt=992,nt={watch:{$route:function(e){"mobile"===this.device&&this.sidebar.opened&&bt.dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var e=this.$_isMobile();e&&(bt.dispatch("app/toggleDevice","mobile"),bt.dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var e=et.getBoundingClientRect();return e.width-1'});r.a.add(c);t["default"]=c},"9f2b":function(e,t,n){"use strict";var a=n("5bb9"),i=n.n(a);i.a},b20f:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},b3b5:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-user",use:"icon-user-usage",viewBox:"0 0 130 130",content:''});r.a.add(c);t["default"]=c},cf1e:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d7ec:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-eye-open",use:"icon-eye-open-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(c);t["default"]=c},dc52:function(e,t,n){},dcf8:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-nested",use:"icon-nested-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},eb1b:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-form",use:"icon-form-usage",viewBox:"0 0 128 128",content:''});r.a.add(c);t["default"]=c},f782:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),c=new i.a({id:"icon-dashboard",use:"icon-dashboard-usage",viewBox:"0 0 128 100",content:''});r.a.add(c);t["default"]=c}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d208c3a.93f165b2.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d208c3a.93f165b2.js deleted file mode 100644 index b4948d4d..00000000 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d208c3a.93f165b2.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d208c3a"],{a5d4:function(t,e,n){"use strict";n.r(e);var a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"app-container"},[n("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[n("el-form-item",{attrs:{label:"serviceId"}},[n("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"serviceId"},model:{value:t.searchFormData.serviceId,callback:function(e){t.$set(t.searchFormData,"serviceId",e)},expression:"searchFormData.serviceId"}})],1),t._v(" "),n("el-form-item",[n("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),n("el-table",{staticStyle:{width:"100%","margin-bottom":"20px"},attrs:{data:t.tableData,border:"","row-key":"id"}},[n("el-table-column",{attrs:{prop:"serviceId",label:"服务名称",width:"200"},scopedSlots:t._u([{key:"default",fn:function(e){return[n("span",{domProps:{innerHTML:t._s(t.renderServiceName(e.row))}})]}}])}),t._v(" "),n("el-table-column",{attrs:{prop:"ipPort",label:"IP端口",width:"250"}}),t._v(" "),n("el-table-column",{attrs:{prop:"status",label:"服务状态",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?n("el-tag",{attrs:{type:"success"}},[t._v("已上线")]):t._e(),t._v(" "),e.row.parentId>0&&"STARTING"===e.row.status?n("el-tag",{attrs:{type:"info"}},[t._v("正在启动")]):t._e(),t._v(" "),e.row.parentId>0&&"UNKNOWN"===e.row.status?n("el-tag",[t._v("未知")]):t._e(),t._v(" "),e.row.parentId>0&&("OUT_OF_SERVICE"===e.row.status||"DOWN"===e.row.status)?n("el-tag",{attrs:{type:"danger"}},[t._v("已下线")]):t._e()]}}])}),t._v(" "),n("el-table-column",{attrs:{prop:"updateTime",label:"最后更新时间",width:"160"}}),t._v(" "),n("el-table-column",{attrs:{label:"操作",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return t.onOffline(e.row)}}},[t._v("下线")]):t._e(),t._v(" "),e.row.parentId>0&&"OUT_OF_SERVICE"===e.row.status?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return t.onOnline(e.row)}}},[t._v("上线")]):t._e()]}}])})],1)],1)},r=[],i=(n("ac6a"),{data:function(){return{searchFormData:{serviceId:""},tableData:[]}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("service.instance.list",this.searchFormData,function(t){this.tableData=this.buildTreeData(t.data)})},buildTreeData:function(t){return t.forEach(function(e){var n=e.parentId;0===n||t.forEach(function(t){if(t.id===n){var a=t.children;a||(a=[]),a.push(e),t.children=a}})}),t=t.filter(function(t){return 0===t.parentId}),t},onSearchTable:function(){this.loadTable()},onOffline:function(t){this.confirm("确定要下线【"+t.serviceId+"】吗?",function(e){this.post("service.instance.offline",t,function(){this.tip("下线成功"),e()})})},onOnline:function(t){this.confirm("确定要上线【"+t.serviceId+"】吗?",function(e){this.post("service.instance.online",t,function(){this.tip("上线成功"),e()})})},renderServiceName:function(t){var e="";if(t.children&&t.children.length>0){var n=t.children.filter(function(t){return"UP"===t.status}).length;e=" (".concat(n,"/").concat(t.children.length,")")}return t.serviceId+e}}}),o=i,s=n("2877"),l=Object(s["a"])(o,a,r,!1,null,null,null);e["default"]=l.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.8f017357.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.c8ef105a.js similarity index 65% rename from sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.8f017357.js rename to sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.c8ef105a.js index 282b5296..379d4bc1 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.8f017357.js +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.c8ef105a.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d221c34"],{cc75:function(a,t,e){"use strict";e.r(t);var i=function(){var a=this,t=a.$createElement,e=a._self._c||t;return e("div",{staticClass:"app-container"},[e("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:a.searchFormData,size:"mini"}},[e("el-form-item",{attrs:{label:"IP"}},[e("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"输入IP"},model:{value:a.searchFormData.ip,callback:function(t){a.$set(a.searchFormData,"ip",t)},expression:"searchFormData.ip"}})],1),a._v(" "),e("el-form-item",[e("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:a.loadTable}},[a._v("查询")])],1)],1),a._v(" "),e("el-button",{staticStyle:{"margin-bottom":"10px"},attrs:{type:"primary",size:"mini",icon:"el-icon-plus"},on:{click:a.onAdd}},[a._v("新增IP")]),a._v(" "),e("el-table",{attrs:{data:a.pageInfo.rows,border:"","highlight-current-row":""}},[e("el-table-column",{attrs:{prop:"ip",label:"IP",width:"200"}}),a._v(" "),e("el-table-column",{attrs:{prop:"remark",label:"备注",width:"300"}}),a._v(" "),e("el-table-column",{attrs:{prop:"gmtCreate",label:"添加时间",width:"160"}}),a._v(" "),e("el-table-column",{attrs:{prop:"gmtModified",label:"修改时间",width:"160"}}),a._v(" "),e("el-table-column",{attrs:{label:"操作",width:"150"},scopedSlots:a._u([{key:"default",fn:function(t){return[e("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(e){return a.onTableUpdate(t.row)}}},[a._v("修改")]),a._v(" "),e("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(e){return a.onTableDelete(t.row)}}},[a._v("删除")])]}}])})],1),a._v(" "),e("el-pagination",{staticStyle:{"margin-top":"5px"},attrs:{background:"","current-page":a.searchFormData.pageIndex,"page-size":a.searchFormData.pageSize,"page-sizes":[5,10,20,40],total:a.pageInfo.total,layout:"total, sizes, prev, pager, next"},on:{"size-change":a.onSizeChange,"current-change":a.onPageIndexChange}}),a._v(" "),e("el-dialog",{attrs:{title:a.dialogTitle,visible:a.dialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(t){a.dialogVisible=t},close:function(t){return a.resetForm("dialogForm")}}},[e("el-form",{ref:"dialogForm",attrs:{rules:a.dialogFormRules,model:a.dialogFormData,"label-width":"120px",size:"mini"}},[e("el-form-item",{attrs:{prop:"ip",label:"IP"}},[e("el-input",{directives:[{name:"show",rawName:"v-show",value:0===a.dialogFormData.id,expression:"dialogFormData.id === 0"}],model:{value:a.dialogFormData.ip,callback:function(t){a.$set(a.dialogFormData,"ip",t)},expression:"dialogFormData.ip"}}),a._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:a.dialogFormData.id>0,expression:"dialogFormData.id > 0"}]},[a._v(a._s(a.dialogFormData.ip))])],1),a._v(" "),e("el-form-item",{attrs:{prop:"remark",label:"备注"}},[e("el-input",{model:{value:a.dialogFormData.remark,callback:function(t){a.$set(a.dialogFormData,"remark",t)},expression:"dialogFormData.remark"}})],1)],1),a._v(" "),e("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[e("el-button",{on:{click:function(t){a.dialogVisible=!1}}},[a._v("取 消")]),a._v(" "),e("el-button",{attrs:{type:"primary"},on:{click:a.onDialogSave}},[a._v("保 存")])],1)],1)],1)},o=[],l={data:function(){var a=function(a,t,e){if(""===t)e(new Error("请输入IP"));else{var i=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;i.test(t)||e(new Error("IP格式不正确")),e()}};return{searchFormData:{ip:"",pageIndex:1,pageSize:10},pageInfo:{rows:[],total:0},dialogVisible:!1,dialogTitle:"",dialogFormData:{id:0,ip:"",remark:""},dialogFormRules:{ip:[{validator:a,trigger:"blur"},{min:1,max:64,message:"长度在 1 到 64 个字符",trigger:"blur"}],remark:[{max:100,message:"不能超过 100 个字符",trigger:"blur"}]}}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("ip.blacklist.page",this.searchFormData,function(a){this.pageInfo=a.data})},onTableUpdate:function(a){var t=this;this.dialogTitle="修改IP",this.dialogVisible=!0,this.$nextTick(function(){Object.assign(t.dialogFormData,a)})},onTableDelete:function(a){this.confirm("确认要移除IP【".concat(a.ip,"】吗?"),function(t){var e={id:a.id};this.post("ip.blacklist.del",e,function(){t(),this.tip("删除成功"),this.loadTable()})})},onDialogSave:function(){var a=this;this.$refs.dialogForm.validate(function(t){if(t){var e=a.dialogFormData.id?"ip.blacklist.update":"ip.blacklist.add";a.post(e,a.dialogFormData,function(){this.dialogVisible=!1,this.loadTable()})}})},onSizeChange:function(a){this.searchFormData.pageSize=a,this.loadTable()},onAdd:function(){this.dialogTitle="新增IP",this.dialogVisible=!0,this.dialogFormData.id=0},onPageIndexChange:function(a){this.searchFormData.pageIndex=a,this.loadTable()}}},r=l,n=e("2877"),s=Object(n["a"])(r,i,o,!1,null,null,null);t["default"]=s.exports}}]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d221c34"],{cc75:function(a,t,e){"use strict";e.r(t);var i=function(){var a=this,t=a.$createElement,e=a._self._c||t;return e("div",{staticClass:"app-container"},[e("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:a.searchFormData,size:"mini"}},[e("el-form-item",{attrs:{label:"IP"}},[e("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"输入IP"},model:{value:a.searchFormData.ip,callback:function(t){a.$set(a.searchFormData,"ip",t)},expression:"searchFormData.ip"}})],1),a._v(" "),e("el-form-item",[e("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:a.loadTable}},[a._v("查询")])],1)],1),a._v(" "),e("el-button",{staticStyle:{"margin-bottom":"10px"},attrs:{type:"primary",size:"mini",icon:"el-icon-plus"},on:{click:a.onAdd}},[a._v("新增IP")]),a._v(" "),e("el-table",{attrs:{data:a.pageInfo.rows,border:"","highlight-current-row":""}},[e("el-table-column",{attrs:{prop:"ip",label:"IP",width:"200"}}),a._v(" "),e("el-table-column",{attrs:{prop:"remark",label:"备注",width:"300"}}),a._v(" "),e("el-table-column",{attrs:{prop:"gmtCreate",label:"添加时间",width:"160"}}),a._v(" "),e("el-table-column",{attrs:{prop:"gmtModified",label:"修改时间",width:"160"}}),a._v(" "),e("el-table-column",{attrs:{label:"操作",width:"150"},scopedSlots:a._u([{key:"default",fn:function(t){return[e("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(e){return a.onTableUpdate(t.row)}}},[a._v("修改")]),a._v(" "),e("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(e){return a.onTableDelete(t.row)}}},[a._v("删除")])]}}])})],1),a._v(" "),e("el-pagination",{staticStyle:{"margin-top":"5px"},attrs:{background:"","current-page":a.searchFormData.pageIndex,"page-size":a.searchFormData.pageSize,"page-sizes":[5,10,20,40],total:a.pageInfo.total,layout:"total, sizes, prev, pager, next"},on:{"size-change":a.onSizeChange,"current-change":a.onPageIndexChange}}),a._v(" "),e("el-dialog",{attrs:{title:a.dialogTitle,visible:a.dialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(t){a.dialogVisible=t},close:function(t){return a.resetForm("dialogForm")}}},[e("el-form",{ref:"dialogForm",attrs:{rules:a.dialogFormRules,model:a.dialogFormData,"label-width":"120px",size:"mini"}},[e("el-form-item",{attrs:{prop:"ip",label:"IP"}},[e("el-input",{directives:[{name:"show",rawName:"v-show",value:0===a.dialogFormData.id,expression:"dialogFormData.id === 0"}],model:{value:a.dialogFormData.ip,callback:function(t){a.$set(a.dialogFormData,"ip",t)},expression:"dialogFormData.ip"}}),a._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:a.dialogFormData.id>0,expression:"dialogFormData.id > 0"}]},[a._v(a._s(a.dialogFormData.ip))])],1),a._v(" "),e("el-form-item",{attrs:{prop:"remark",label:"备注"}},[e("el-input",{model:{value:a.dialogFormData.remark,callback:function(t){a.$set(a.dialogFormData,"remark",t)},expression:"dialogFormData.remark"}})],1)],1),a._v(" "),e("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[e("el-button",{on:{click:function(t){a.dialogVisible=!1}}},[a._v("取 消")]),a._v(" "),e("el-button",{attrs:{type:"primary"},on:{click:a.onDialogSave}},[a._v("保 存")])],1)],1)],1)},o=[],l={data:function(){var a=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/,t=function(t,e,i){""===e?i(new Error("请输入IP")):(a.test(e)||i(new Error("IP格式不正确")),i())};return{searchFormData:{ip:"",pageIndex:1,pageSize:10},pageInfo:{rows:[],total:0},dialogVisible:!1,dialogTitle:"",dialogFormData:{id:0,ip:"",remark:""},dialogFormRules:{ip:[{validator:t,trigger:"blur"},{min:1,max:64,message:"长度在 1 到 64 个字符",trigger:"blur"}],remark:[{max:100,message:"不能超过 100 个字符",trigger:"blur"}]}}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("ip.blacklist.page",this.searchFormData,function(a){this.pageInfo=a.data})},onTableUpdate:function(a){var t=this;this.dialogTitle="修改IP",this.dialogVisible=!0,this.$nextTick(function(){Object.assign(t.dialogFormData,a)})},onTableDelete:function(a){this.confirm("确认要移除IP【".concat(a.ip,"】吗?"),function(t){var e={id:a.id};this.post("ip.blacklist.del",e,function(){t(),this.tip("删除成功"),this.loadTable()})})},onDialogSave:function(){var a=this;this.$refs.dialogForm.validate(function(t){if(t){var e=a.dialogFormData.id?"ip.blacklist.update":"ip.blacklist.add";a.post(e,a.dialogFormData,function(){this.dialogVisible=!1,this.loadTable()})}})},onSizeChange:function(a){this.searchFormData.pageSize=a,this.loadTable()},onAdd:function(){this.dialogTitle="新增IP",this.dialogVisible=!0,this.dialogFormData.id=0},onPageIndexChange:function(a){this.searchFormData.pageIndex=a,this.loadTable()}}},r=l,n=e("2877"),s=Object(n["a"])(r,i,o,!1,null,null,null);t["default"]=s.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9f479afe.1204bc29.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9f479afe.1204bc29.js new file mode 100644 index 00000000..6bd0e42d --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9f479afe.1204bc29.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-9f479afe"],{"02f4":function(e,t,n){var r=n("4588"),o=n("be13");e.exports=function(e){return function(t,n){var i,a,s=String(o(t)),l=r(n),c=s.length;return l<0||l>=c?e?"":void 0:(i=s.charCodeAt(l),i<55296||i>56319||l+1===c||(a=s.charCodeAt(l+1))<56320||a>57343?e?s.charAt(l):i:e?s.slice(l,l+2):a-56320+(i-55296<<10)+65536)}}},"0390":function(e,t,n){"use strict";var r=n("02f4")(!0);e.exports=function(e,t,n){return t+(n?r(e,t).length:1)}},"0bfb":function(e,t,n){"use strict";var r=n("cb7c");e.exports=function(){var e=r(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t}},"214f":function(e,t,n){"use strict";n("b0c5");var r=n("2aba"),o=n("32e9"),i=n("79e5"),a=n("be13"),s=n("2b4c"),l=n("520a"),c=s("species"),u=!i(function(){var e=/./;return e.exec=function(){var e=[];return e.groups={a:"7"},e},"7"!=="".replace(e,"$")}),f=function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var n="ab".split(e);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();e.exports=function(e,t,n){var d=s(e),p=!i(function(){var t={};return t[d]=function(){return 7},7!=""[e](t)}),v=p?!i(function(){var t=!1,n=/a/;return n.exec=function(){return t=!0,null},"split"===e&&(n.constructor={},n.constructor[c]=function(){return n}),n[d](""),!t}):void 0;if(!p||!v||"replace"===e&&!u||"split"===e&&!f){var g=/./[d],h=n(a,d,""[e],function(e,t,n,r,o){return t.exec===l?p&&!o?{done:!0,value:g.call(t,n,r)}:{done:!0,value:e.call(n,t,r)}:{done:!1}}),m=h[0],y=h[1];r(String.prototype,e,m),o(RegExp.prototype,d,2==t?function(e,t){return y.call(e,this,t)}:function(e){return y.call(e,this)})}}},"28a5":function(e,t,n){"use strict";var r=n("aae3"),o=n("cb7c"),i=n("ebd6"),a=n("0390"),s=n("9def"),l=n("5f1b"),c=n("520a"),u=n("79e5"),f=Math.min,d=[].push,p="split",v="length",g="lastIndex",h=4294967295,m=!u(function(){RegExp(h,"y")});n("214f")("split",2,function(e,t,n,u){var y;return y="c"=="abbc"[p](/(b)*/)[1]||4!="test"[p](/(?:)/,-1)[v]||2!="ab"[p](/(?:ab)*/)[v]||4!="."[p](/(.?)(.?)/)[v]||"."[p](/()()/)[v]>1||""[p](/.?/)[v]?function(e,t){var o=String(this);if(void 0===e&&0===t)return[];if(!r(e))return n.call(o,e,t);var i,a,s,l=[],u=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),f=0,p=void 0===t?h:t>>>0,m=new RegExp(e.source,u+"g");while(i=c.call(m,o)){if(a=m[g],a>f&&(l.push(o.slice(f,i.index)),i[v]>1&&i.index=p))break;m[g]===i.index&&m[g]++}return f===o[v]?!s&&m.test("")||l.push(""):l.push(o.slice(f)),l[v]>p?l.slice(0,p):l}:"0"[p](void 0,0)[v]?function(e,t){return void 0===e&&0===t?[]:n.call(this,e,t)}:n,[function(n,r){var o=e(this),i=void 0==n?void 0:n[t];return void 0!==i?i.call(n,o,r):y.call(String(o),n,r)},function(e,t){var r=u(y,e,this,t,y!==n);if(r.done)return r.value;var c=o(e),d=String(this),p=i(c,RegExp),v=c.unicode,g=(c.ignoreCase?"i":"")+(c.multiline?"m":"")+(c.unicode?"u":"")+(m?"y":"g"),b=new p(m?c:"^(?:"+c.source+")",g),w=void 0===t?h:t>>>0;if(0===w)return[];if(0===d.length)return null===l(b,d)?[d]:[];var _=0,x=0,I=[];while(x1&&i.call(a[0],n,function(){for(u=1;u0&&"pre"===t.row.metadata.env?n("el-tag",{attrs:{type:"warning"}},[e._v("预发布")]):e._e(),e._v(" "),t.row.parentId>0&&"gray"===t.row.metadata.env?n("el-tag",{attrs:{type:"info"}},[e._v("灰度")]):e._e(),e._v(" "),t.row.parentId>0&&!t.row.metadata.env?n("el-tag",{attrs:{type:"success"}},[e._v("线上")]):e._e()]}}])}),e._v(" "),n("el-table-column",{attrs:{prop:"metadata",label:"metadata",width:"250"},scopedSlots:e._u([{key:"default",fn:function(t){return[t.row.parentId>0?n("span",[e._v(e._s(JSON.stringify(t.row.metadata)))]):e._e()]}}])}),e._v(" "),n("el-table-column",{attrs:{prop:"status",label:"服务状态",width:"100"},scopedSlots:e._u([{key:"default",fn:function(t){return[t.row.parentId>0&&"UP"===t.row.status?n("el-tag",{attrs:{type:"success"}},[e._v("正常")]):e._e(),e._v(" "),t.row.parentId>0&&"STARTING"===t.row.status?n("el-tag",{attrs:{type:"info"}},[e._v("正在启动")]):e._e(),e._v(" "),t.row.parentId>0&&"UNKNOWN"===t.row.status?n("el-tag",[e._v("未知")]):e._e(),e._v(" "),t.row.parentId>0&&("OUT_OF_SERVICE"===t.row.status||"DOWN"===t.row.status)?n("el-tag",{attrs:{type:"danger"}},[e._v("已禁用")]):e._e()]}}])}),e._v(" "),n("el-table-column",{attrs:{prop:"updateTime",label:"最后更新时间",width:"160"}}),e._v(" "),n("el-table-column",{attrs:{label:"操作",width:"250"},scopedSlots:e._u([{key:"default",fn:function(t){return[t.row.parentId>0&&"pre"===t.row.metadata.env?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onEnvPreClose(t.row)}}},[e._v("结束预发布")]):e._e(),e._v(" "),t.row.parentId>0&&"gray"===t.row.metadata.env?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onEnvGrayClose(t.row)}}},[e._v("结束灰度")]):e._e(),e._v(" "),t.row.parentId>0&&!t.row.metadata.env?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onEnvPreOpen(t.row)}}},[e._v("开启预发布")]):e._e(),e._v(" "),t.row.parentId>0&&!t.row.metadata.env?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onEnvGrayOpen(t.row)}}},[e._v("开启灰度")]):e._e(),e._v(" "),0===t.row.parentId?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onGrayConfigUpdate(t.row)}}},[e._v("设置灰度参数")]):e._e(),e._v(" "),t.row.parentId>0&&"UP"===t.row.status?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onDisable(t.row)}}},[e._v("禁用")]):e._e(),e._v(" "),t.row.parentId>0&&"OUT_OF_SERVICE"===t.row.status?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return e.onEnable(t.row)}}},[e._v("启用")]):e._e()]}}])})],1),e._v(" "),n("el-dialog",{attrs:{title:"灰度设置",visible:e.grayDialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(t){e.grayDialogVisible=t},close:function(t){return e.resetForm("grayForm")}}},[n("el-form",{ref:"grayForm",attrs:{model:e.grayForm,rules:e.grayFormRules,size:"mini"}},[n("el-form-item",{attrs:{label:"serviceId"}},[e._v("\n "+e._s(e.grayForm.serviceId)+"\n ")]),e._v(" "),n("el-tabs",{attrs:{type:"card"},model:{value:e.tabsActiveName,callback:function(t){e.tabsActiveName=t},expression:"tabsActiveName"}},[n("el-tab-pane",{attrs:{label:"灰度用户",name:"first"}},[n("el-alert",{staticStyle:{"margin-bottom":"20px"},attrs:{title:"可以是appId,或userId,多个用英文逗号隔开",type:"info",closable:!1}}),e._v(" "),n("el-form-item",{attrs:{prop:"userKeyContent"}},[n("el-input",{attrs:{placeholder:"可以是appId,或userId,多个用英文逗号隔开",type:"textarea",rows:6},model:{value:e.grayForm.userKeyContent,callback:function(t){e.$set(e.grayForm,"userKeyContent",t)},expression:"grayForm.userKeyContent"}})],1)],1),e._v(" "),n("el-tab-pane",{attrs:{label:"接口配置",name:"second"}},[n("el-form-item",[n("el-button",{attrs:{type:"text"},on:{click:e.addNameVersion}},[e._v("新增灰度接口")])],1),e._v(" "),n("table",{attrs:{cellpadding:"0",cellspacing:"0"}},e._l(e.grayForm.grayRouteConfigList,function(t,r){return n("tr",{key:t.key},[n("td",[n("el-form-item",{key:t.key,attrs:{prop:"grayRouteConfigList."+r+".oldRouteId",rules:{required:!0,message:"不能为空",trigger:["blur","change"]}}},[e._v("\n 老接口:\n "),n("el-select",{staticStyle:{"margin-right":"10px"},on:{change:function(n){return e.onChangeOldRoute(t)}},model:{value:t.oldRouteId,callback:function(n){e.$set(t,"oldRouteId",n)},expression:"grayRouteConfig.oldRouteId"}},e._l(e.routeList,function(e){return n("el-option",{key:e.id,attrs:{label:e.name+"("+e.version+")",value:e.id}})}),1)],1)],1),e._v(" "),n("td",[n("el-form-item",{key:t.key+1,attrs:{prop:"grayRouteConfigList."+r+".newVersion",rules:{required:!0,message:"不能为空",trigger:["blur","change"]}}},[e._v("\n 灰度接口:\n "),n("el-select",{attrs:{"no-data-text":"无数据"},model:{value:t.newVersion,callback:function(n){e.$set(t,"newVersion",n)},expression:"grayRouteConfig.newVersion"}},e._l(e.getGraySelectData(t.oldRouteId),function(e){return n("el-option",{key:e.id,attrs:{label:e.name+"("+e.version+")",value:e.version}})}),1)],1)],1),e._v(" "),n("td",{staticStyle:{"vertical-align":"baseline"}},[n("el-button",{directives:[{name:"show",rawName:"v-show",value:e.grayForm.grayRouteConfigList.length>1,expression:"grayForm.grayRouteConfigList.length > 1"}],attrs:{type:"text"},on:{click:function(n){return n.preventDefault(),e.removeNameVersion(t)}}},[e._v("删除")])],1)])}),0)],1)],1)],1),e._v(" "),n("span",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[n("el-button",{on:{click:function(t){e.grayDialogVisible=!1}}},[e._v("取 消")]),e._v(" "),n("el-button",{attrs:{type:"primary"},on:{click:e.onGrayConfigSave}},[e._v("确 定")])],1)],1)],1)},o=[],i=(n("28a5"),n("ac6a"),n("7f7f"),{data:function(){var e=/^\w+(,\w+)*$/,t=function(t,n,r){""===n?r(new Error("不能为空")):(e.test(n)||r(new Error("格式不正确")),r())};return{searchFormData:{serviceId:""},grayDialogVisible:!1,grayForm:{serviceId:"",userKeyContent:"",onlyUpdateGrayUserkey:!1,grayRouteConfigList:[]},tabsActiveName:"first",routeList:[],selectNameVersion:[],grayFormRules:{userKeyContent:[{required:!0,message:"不能为空",trigger:"blur"},{validator:t,trigger:"blur"}]},tableData:[]}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("service.instance.list",this.searchFormData,function(e){this.tableData=this.buildTreeData(e.data)})},loadRouteList:function(e){0===this.routeList.length&&this.post("route.list/1.2",{serviceId:e.toLowerCase()},function(e){this.routeList=e.data})},getGraySelectData:function(e){return this.routeList.filter(function(t){return e!==t.id&&e.indexOf(t.name)>-1})},buildTreeData:function(e){return e.forEach(function(t){var n=t.parentId;0===n||e.forEach(function(e){if(e.id===n){var r=e.children;r||(r=[]),r.push(t),e.children=r}})}),e=e.filter(function(e){return 0===e.parentId}),e},onSearchTable:function(){this.loadTable()},onDisable:function(e){this.confirm("确定要禁用【"+e.serviceId+"】吗?",function(t){this.post("service.instance.offline",e,function(){this.tip("下线成功"),t()})})},onEnable:function(e){this.confirm("确定要启用【"+e.serviceId+"】吗?",function(t){this.post("service.instance.online",e,function(){this.tip("上线成功"),t()})})},doEnvOnline:function(e,t){this.post("service.instance.env.online",e,function(){t&&t.call(this)})},onEnvPreOpen:function(e){this.confirm("确定要开启 ".concat(e.instanceId," 预发布吗?"),function(t){this.post("service.instance.env.pre.open",e,function(){this.tip("预发布成功"),t()})})},onEnvPreClose:function(e){this.confirm("确定要结束 ".concat(e.instanceId," 预发布吗?"),function(t){this.doEnvOnline(e,function(){this.tip("操作成功"),t()})})},onEnvGrayOpen:function(e){this.confirm("确定要开启 ".concat(e.instanceId," 灰度吗?"),function(t){this.post("service.instance.env.gray.open",e,function(){this.tip("开启成功"),t()})})},onEnvGrayClose:function(e){this.confirm("确定要结束 ".concat(e.instanceId," 灰度吗?"),function(t){this.doEnvOnline(e,function(){this.tip("操作成功"),t()})})},onGrayConfigUpdate:function(e){var t=e.serviceId;this.loadRouteList(t),this.post("service.gray.config.get",{serviceId:t},function(e){this.grayDialogVisible=!0;var n=e.data;Object.assign(this.grayForm,{serviceId:t,userKeyContent:n.userKeyContent||"",grayRouteConfigList:this.createGrayRouteConfigList(n.nameVersionContent)})})},onGrayConfigSave:function(){var e=this;this.$refs.grayForm.validate(function(t){if(t){for(var n=[],r=e.grayForm.grayRouteConfigList,o=0;o0){var n=e.children.filter(function(e){return"UP"===e.status}).length;t=" (".concat(n,"/").concat(e.children.length,")")}return e.serviceId+t}}}),a=i,s=n("2877"),l=Object(s["a"])(a,r,o,!1,null,null,null);t["default"]=l.exports},b0c5:function(e,t,n){"use strict";var r=n("520a");n("5ca1")({target:"RegExp",proto:!0,forced:r!==/./.exec},{exec:r})}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-29e7142c.994a3ac0.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-ea2e58a4.f3f85b0e.js similarity index 98% rename from sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-29e7142c.994a3ac0.js rename to sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-ea2e58a4.f3f85b0e.js index b402f56e..71a5f277 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-29e7142c.994a3ac0.js +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-ea2e58a4.f3f85b0e.js @@ -1,4 +1,4 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-29e7142c"],{2017:function(t,e,r){"use strict";var s=r("3b76"),o=r.n(s);o.a},"3b76":function(t,e,r){},"3c35":function(t,e){(function(e){t.exports=e}).call(this,{})},8237:function(module,exports,__webpack_require__){(function(process,global){var __WEBPACK_AMD_DEFINE_RESULT__; +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-ea2e58a4"],{2017:function(t,e,r){"use strict";var s=r("3b76"),o=r.n(s);o.a},"3b76":function(t,e,r){},"3c35":function(t,e){(function(e){t.exports=e}).call(this,{})},8237:function(module,exports,__webpack_require__){(function(process,global){var __WEBPACK_AMD_DEFINE_RESULT__; /** * [js-md5]{@link https://github.com/emn178/js-md5} * @@ -17,4 +17,4 @@ * @copyright Chen, Yi-Cyuan 2014-2017 * @license MIT */ -(function(){"use strict";var ERROR="input is invalid type",WINDOW="object"===typeof window,root=WINDOW?window:{};root.JS_MD5_NO_WINDOW&&(WINDOW=!1);var WEB_WORKER=!WINDOW&&"object"===typeof self,NODE_JS=!root.JS_MD5_NO_NODE_JS&&"object"===typeof process&&process.versions&&process.versions.node;NODE_JS?root=global:WEB_WORKER&&(root=self);var COMMON_JS=!root.JS_MD5_NO_COMMON_JS&&"object"===typeof module&&module.exports,AMD=__webpack_require__("3c35"),ARRAY_BUFFER=!root.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!==typeof ArrayBuffer,HEX_CHARS="0123456789abcdef".split(""),EXTRA=[128,32768,8388608,-2147483648],SHIFT=[0,8,16,24],OUTPUT_TYPES=["hex","array","digest","buffer","arrayBuffer","base64"],BASE64_ENCODE_CHAR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),blocks=[],buffer8;if(ARRAY_BUFFER){var buffer=new ArrayBuffer(68);buffer8=new Uint8Array(buffer),blocks=new Uint32Array(buffer)}!root.JS_MD5_NO_NODE_JS&&Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),!ARRAY_BUFFER||!root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&ArrayBuffer.isView||(ArrayBuffer.isView=function(t){return"object"===typeof t&&t.buffer&&t.buffer.constructor===ArrayBuffer});var createOutputMethod=function(t){return function(e){return new Md5(!0).update(e)[t]()}},createMethod=function(){var t=createOutputMethod("hex");NODE_JS&&(t=nodeWrap(t)),t.create=function(){return new Md5},t.update=function(e){return t.create().update(e)};for(var e=0;e>2]|=t[i]<>6,h[o++]=128|63&s):s<55296||s>=57344?(h[o++]=224|s>>12,h[o++]=128|s>>6&63,h[o++]=128|63&s):(s=65536+((1023&s)<<10|1023&t.charCodeAt(++i)),h[o++]=240|s>>18,h[o++]=128|s>>12&63,h[o++]=128|s>>6&63,h[o++]=128|63&s);else for(o=this.start;i>2]|=s<>2]|=(192|s>>6)<>2]|=(128|63&s)<=57344?(a[o>>2]|=(224|s>>12)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<>2]|=(240|s>>18)<>2]|=(128|s>>12&63)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<=64?(this.start=o-64,this.hash(),this.hashed=!0):this.start=o}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296<<0,this.bytes=this.bytes%4294967296),this}},Md5.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var t=this.blocks,e=this.lastByteIndex;t[e>>2]|=EXTRA[3&e],e>=56&&(this.hashed||this.hash(),t[0]=t[16],t[16]=t[1]=t[2]=t[3]=t[4]=t[5]=t[6]=t[7]=t[8]=t[9]=t[10]=t[11]=t[12]=t[13]=t[14]=t[15]=0),t[14]=this.bytes<<3,t[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},Md5.prototype.hash=function(){var t,e,r,s,o,i,n=this.blocks;this.first?(t=n[0]-680876937,t=(t<<7|t>>>25)-271733879<<0,s=(-1732584194^2004318071&t)+n[1]-117830708,s=(s<<12|s>>>20)+t<<0,r=(-271733879^s&(-271733879^t))+n[2]-1126478375,r=(r<<17|r>>>15)+s<<0,e=(t^r&(s^t))+n[3]-1316259209,e=(e<<22|e>>>10)+r<<0):(t=this.h0,e=this.h1,r=this.h2,s=this.h3,t+=(s^e&(r^s))+n[0]-680876936,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[1]-389564586,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[2]+606105819,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[3]-1044525330,e=(e<<22|e>>>10)+r<<0),t+=(s^e&(r^s))+n[4]-176418897,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[5]+1200080426,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[6]-1473231341,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[7]-45705983,e=(e<<22|e>>>10)+r<<0,t+=(s^e&(r^s))+n[8]+1770035416,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[9]-1958414417,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[10]-42063,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[11]-1990404162,e=(e<<22|e>>>10)+r<<0,t+=(s^e&(r^s))+n[12]+1804603682,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[13]-40341101,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[14]-1502002290,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[15]+1236535329,e=(e<<22|e>>>10)+r<<0,t+=(r^s&(e^r))+n[1]-165796510,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[6]-1069501632,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[11]+643717713,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[0]-373897302,e=(e<<20|e>>>12)+r<<0,t+=(r^s&(e^r))+n[5]-701558691,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[10]+38016083,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[15]-660478335,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[4]-405537848,e=(e<<20|e>>>12)+r<<0,t+=(r^s&(e^r))+n[9]+568446438,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[14]-1019803690,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[3]-187363961,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[8]+1163531501,e=(e<<20|e>>>12)+r<<0,t+=(r^s&(e^r))+n[13]-1444681467,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[2]-51403784,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[7]+1735328473,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[12]-1926607734,e=(e<<20|e>>>12)+r<<0,o=e^r,t+=(o^s)+n[5]-378558,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[8]-2022574463,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[11]+1839030562,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[14]-35309556,e=(e<<23|e>>>9)+r<<0,o=e^r,t+=(o^s)+n[1]-1530992060,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[4]+1272893353,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[7]-155497632,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[10]-1094730640,e=(e<<23|e>>>9)+r<<0,o=e^r,t+=(o^s)+n[13]+681279174,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[0]-358537222,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[3]-722521979,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[6]+76029189,e=(e<<23|e>>>9)+r<<0,o=e^r,t+=(o^s)+n[9]-640364487,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[12]-421815835,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[15]+530742520,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[2]-995338651,e=(e<<23|e>>>9)+r<<0,t+=(r^(e|~s))+n[0]-198630844,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[7]+1126891415,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[14]-1416354905,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[5]-57434055,e=(e<<21|e>>>11)+r<<0,t+=(r^(e|~s))+n[12]+1700485571,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[3]-1894986606,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[10]-1051523,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[1]-2054922799,e=(e<<21|e>>>11)+r<<0,t+=(r^(e|~s))+n[8]+1873313359,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[15]-30611744,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[6]-1560198380,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[13]+1309151649,e=(e<<21|e>>>11)+r<<0,t+=(r^(e|~s))+n[4]-145523070,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[11]-1120210379,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[2]+718787259,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[9]-343485551,e=(e<<21|e>>>11)+r<<0,this.first?(this.h0=t+1732584193<<0,this.h1=e-271733879<<0,this.h2=r-1732584194<<0,this.h3=s+271733878<<0,this.first=!1):(this.h0=this.h0+t<<0,this.h1=this.h1+e<<0,this.h2=this.h2+r<<0,this.h3=this.h3+s<<0)},Md5.prototype.hex=function(){this.finalize();var t=this.h0,e=this.h1,r=this.h2,s=this.h3;return HEX_CHARS[t>>4&15]+HEX_CHARS[15&t]+HEX_CHARS[t>>12&15]+HEX_CHARS[t>>8&15]+HEX_CHARS[t>>20&15]+HEX_CHARS[t>>16&15]+HEX_CHARS[t>>28&15]+HEX_CHARS[t>>24&15]+HEX_CHARS[e>>4&15]+HEX_CHARS[15&e]+HEX_CHARS[e>>12&15]+HEX_CHARS[e>>8&15]+HEX_CHARS[e>>20&15]+HEX_CHARS[e>>16&15]+HEX_CHARS[e>>28&15]+HEX_CHARS[e>>24&15]+HEX_CHARS[r>>4&15]+HEX_CHARS[15&r]+HEX_CHARS[r>>12&15]+HEX_CHARS[r>>8&15]+HEX_CHARS[r>>20&15]+HEX_CHARS[r>>16&15]+HEX_CHARS[r>>28&15]+HEX_CHARS[r>>24&15]+HEX_CHARS[s>>4&15]+HEX_CHARS[15&s]+HEX_CHARS[s>>12&15]+HEX_CHARS[s>>8&15]+HEX_CHARS[s>>20&15]+HEX_CHARS[s>>16&15]+HEX_CHARS[s>>28&15]+HEX_CHARS[s>>24&15]},Md5.prototype.toString=Md5.prototype.hex,Md5.prototype.digest=function(){this.finalize();var t=this.h0,e=this.h1,r=this.h2,s=this.h3;return[255&t,t>>8&255,t>>16&255,t>>24&255,255&e,e>>8&255,e>>16&255,e>>24&255,255&r,r>>8&255,r>>16&255,r>>24&255,255&s,s>>8&255,s>>16&255,s>>24&255]},Md5.prototype.array=Md5.prototype.digest,Md5.prototype.arrayBuffer=function(){this.finalize();var t=new ArrayBuffer(16),e=new Uint32Array(t);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,t},Md5.prototype.buffer=Md5.prototype.arrayBuffer,Md5.prototype.base64=function(){for(var t,e,r,s="",o=this.array(),i=0;i<15;)t=o[i++],e=o[i++],r=o[i++],s+=BASE64_ENCODE_CHAR[t>>>2]+BASE64_ENCODE_CHAR[63&(t<<4|e>>>4)]+BASE64_ENCODE_CHAR[63&(e<<2|r>>>6)]+BASE64_ENCODE_CHAR[63&r];return t=o[i],s+=BASE64_ENCODE_CHAR[t>>>2]+BASE64_ENCODE_CHAR[t<<4&63]+"==",s};var exports=createMethod();COMMON_JS?module.exports=exports:(root.md5=exports,AMD&&(__WEBPACK_AMD_DEFINE_RESULT__=function(){return exports}.call(exports,__webpack_require__,exports,module),void 0===__WEBPACK_AMD_DEFINE_RESULT__||(module.exports=__WEBPACK_AMD_DEFINE_RESULT__)))})()}).call(this,__webpack_require__("4362"),__webpack_require__("c8ba"))},"9ed6":function(t,e,r){"use strict";r.r(e);var s=function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("div",{staticClass:"login-container"},[r("el-form",{ref:"loginForm",staticClass:"login-form",attrs:{model:t.loginForm,rules:t.loginRules,"auto-complete":"on","label-position":"left"}},[r("div",{staticClass:"title-container"},[r("h3",{staticClass:"title"},[t._v("SOP Admin")])]),t._v(" "),r("el-form-item",{attrs:{prop:"username"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"user"}})],1),t._v(" "),r("el-input",{ref:"username",attrs:{placeholder:"用户名",name:"username",type:"text",tabindex:"1","auto-complete":"on"},model:{value:t.loginForm.username,callback:function(e){t.$set(t.loginForm,"username",e)},expression:"loginForm.username"}})],1),t._v(" "),r("el-form-item",{attrs:{prop:"password"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"password"}})],1),t._v(" "),r("el-input",{key:t.passwordType,ref:"password",attrs:{type:t.passwordType,placeholder:"密码",name:"password",tabindex:"2","auto-complete":"on"},nativeOn:{keyup:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:t.handleLogin(e)}},model:{value:t.loginForm.password,callback:function(e){t.$set(t.loginForm,"password",e)},expression:"loginForm.password"}}),t._v(" "),r("span",{staticClass:"show-pwd",on:{click:t.showPwd}},[r("svg-icon",{attrs:{"icon-class":"password"===t.passwordType?"eye":"eye-open"}})],1)],1),t._v(" "),r("el-button",{staticStyle:{width:"100%","margin-bottom":"30px"},attrs:{loading:t.loading,type:"primary"},nativeOn:{click:function(e){return e.preventDefault(),t.handleLogin(e)}}},[t._v("登 录")])],1)],1)},o=[],i=r("8237"),n=r.n(i),a=r("5f87"),h={name:"Login",data:function(){var t=function(t,e,r){0===e.length?r(new Error("请输入用户名")):r()},e=function(t,e,r){0===e.length?r(new Error("请输入密码")):e.length<6?r(new Error("请密码长度不得小于6位")):r()};return{loginForm:{username:"",password:""},loginRules:{username:[{required:!0,trigger:"blur",validator:t}],password:[{required:!0,trigger:"blur",validator:e}]},loading:!1,passwordType:"password",redirect:void 0}},watch:{$route:{handler:function(t){this.redirect=t.query&&t.query.redirect},immediate:!0}},methods:{showPwd:function(){var t=this;"password"===this.passwordType?this.passwordType="":this.passwordType="password",this.$nextTick(function(){t.$refs.password.focus()})},handleLogin:function(){var t=this;this.$refs.loginForm.validate(function(e){if(e){var r=t.loginForm,s=r.password;s=n()(s);var o={username:r.username,password:s};t.post("nologin.admin.login",o,function(t){Object(a["c"])(t.data),this.$router.push({path:this.redirect||"/"})})}})}}},c=h,u=(r("2017"),r("d982"),r("2877")),f=Object(u["a"])(c,s,o,!1,null,"0204d890",null);e["default"]=f.exports},d982:function(t,e,r){"use strict";var s=r("dabb"),o=r.n(s);o.a},dabb:function(t,e,r){}}]); \ No newline at end of file +(function(){"use strict";var ERROR="input is invalid type",WINDOW="object"===typeof window,root=WINDOW?window:{};root.JS_MD5_NO_WINDOW&&(WINDOW=!1);var WEB_WORKER=!WINDOW&&"object"===typeof self,NODE_JS=!root.JS_MD5_NO_NODE_JS&&"object"===typeof process&&process.versions&&process.versions.node;NODE_JS?root=global:WEB_WORKER&&(root=self);var COMMON_JS=!root.JS_MD5_NO_COMMON_JS&&"object"===typeof module&&module.exports,AMD=__webpack_require__("3c35"),ARRAY_BUFFER=!root.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!==typeof ArrayBuffer,HEX_CHARS="0123456789abcdef".split(""),EXTRA=[128,32768,8388608,-2147483648],SHIFT=[0,8,16,24],OUTPUT_TYPES=["hex","array","digest","buffer","arrayBuffer","base64"],BASE64_ENCODE_CHAR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),blocks=[],buffer8;if(ARRAY_BUFFER){var buffer=new ArrayBuffer(68);buffer8=new Uint8Array(buffer),blocks=new Uint32Array(buffer)}!root.JS_MD5_NO_NODE_JS&&Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),!ARRAY_BUFFER||!root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&ArrayBuffer.isView||(ArrayBuffer.isView=function(t){return"object"===typeof t&&t.buffer&&t.buffer.constructor===ArrayBuffer});var createOutputMethod=function(t){return function(e){return new Md5(!0).update(e)[t]()}},createMethod=function(){var t=createOutputMethod("hex");NODE_JS&&(t=nodeWrap(t)),t.create=function(){return new Md5},t.update=function(e){return t.create().update(e)};for(var e=0;e>2]|=t[i]<>6,h[o++]=128|63&s):s<55296||s>=57344?(h[o++]=224|s>>12,h[o++]=128|s>>6&63,h[o++]=128|63&s):(s=65536+((1023&s)<<10|1023&t.charCodeAt(++i)),h[o++]=240|s>>18,h[o++]=128|s>>12&63,h[o++]=128|s>>6&63,h[o++]=128|63&s);else for(o=this.start;i>2]|=s<>2]|=(192|s>>6)<>2]|=(128|63&s)<=57344?(a[o>>2]|=(224|s>>12)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<>2]|=(240|s>>18)<>2]|=(128|s>>12&63)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<=64?(this.start=o-64,this.hash(),this.hashed=!0):this.start=o}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296<<0,this.bytes=this.bytes%4294967296),this}},Md5.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var t=this.blocks,e=this.lastByteIndex;t[e>>2]|=EXTRA[3&e],e>=56&&(this.hashed||this.hash(),t[0]=t[16],t[16]=t[1]=t[2]=t[3]=t[4]=t[5]=t[6]=t[7]=t[8]=t[9]=t[10]=t[11]=t[12]=t[13]=t[14]=t[15]=0),t[14]=this.bytes<<3,t[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},Md5.prototype.hash=function(){var t,e,r,s,o,i,n=this.blocks;this.first?(t=n[0]-680876937,t=(t<<7|t>>>25)-271733879<<0,s=(-1732584194^2004318071&t)+n[1]-117830708,s=(s<<12|s>>>20)+t<<0,r=(-271733879^s&(-271733879^t))+n[2]-1126478375,r=(r<<17|r>>>15)+s<<0,e=(t^r&(s^t))+n[3]-1316259209,e=(e<<22|e>>>10)+r<<0):(t=this.h0,e=this.h1,r=this.h2,s=this.h3,t+=(s^e&(r^s))+n[0]-680876936,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[1]-389564586,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[2]+606105819,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[3]-1044525330,e=(e<<22|e>>>10)+r<<0),t+=(s^e&(r^s))+n[4]-176418897,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[5]+1200080426,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[6]-1473231341,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[7]-45705983,e=(e<<22|e>>>10)+r<<0,t+=(s^e&(r^s))+n[8]+1770035416,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[9]-1958414417,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[10]-42063,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[11]-1990404162,e=(e<<22|e>>>10)+r<<0,t+=(s^e&(r^s))+n[12]+1804603682,t=(t<<7|t>>>25)+e<<0,s+=(r^t&(e^r))+n[13]-40341101,s=(s<<12|s>>>20)+t<<0,r+=(e^s&(t^e))+n[14]-1502002290,r=(r<<17|r>>>15)+s<<0,e+=(t^r&(s^t))+n[15]+1236535329,e=(e<<22|e>>>10)+r<<0,t+=(r^s&(e^r))+n[1]-165796510,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[6]-1069501632,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[11]+643717713,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[0]-373897302,e=(e<<20|e>>>12)+r<<0,t+=(r^s&(e^r))+n[5]-701558691,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[10]+38016083,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[15]-660478335,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[4]-405537848,e=(e<<20|e>>>12)+r<<0,t+=(r^s&(e^r))+n[9]+568446438,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[14]-1019803690,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[3]-187363961,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[8]+1163531501,e=(e<<20|e>>>12)+r<<0,t+=(r^s&(e^r))+n[13]-1444681467,t=(t<<5|t>>>27)+e<<0,s+=(e^r&(t^e))+n[2]-51403784,s=(s<<9|s>>>23)+t<<0,r+=(t^e&(s^t))+n[7]+1735328473,r=(r<<14|r>>>18)+s<<0,e+=(s^t&(r^s))+n[12]-1926607734,e=(e<<20|e>>>12)+r<<0,o=e^r,t+=(o^s)+n[5]-378558,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[8]-2022574463,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[11]+1839030562,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[14]-35309556,e=(e<<23|e>>>9)+r<<0,o=e^r,t+=(o^s)+n[1]-1530992060,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[4]+1272893353,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[7]-155497632,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[10]-1094730640,e=(e<<23|e>>>9)+r<<0,o=e^r,t+=(o^s)+n[13]+681279174,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[0]-358537222,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[3]-722521979,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[6]+76029189,e=(e<<23|e>>>9)+r<<0,o=e^r,t+=(o^s)+n[9]-640364487,t=(t<<4|t>>>28)+e<<0,s+=(o^t)+n[12]-421815835,s=(s<<11|s>>>21)+t<<0,i=s^t,r+=(i^e)+n[15]+530742520,r=(r<<16|r>>>16)+s<<0,e+=(i^r)+n[2]-995338651,e=(e<<23|e>>>9)+r<<0,t+=(r^(e|~s))+n[0]-198630844,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[7]+1126891415,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[14]-1416354905,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[5]-57434055,e=(e<<21|e>>>11)+r<<0,t+=(r^(e|~s))+n[12]+1700485571,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[3]-1894986606,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[10]-1051523,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[1]-2054922799,e=(e<<21|e>>>11)+r<<0,t+=(r^(e|~s))+n[8]+1873313359,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[15]-30611744,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[6]-1560198380,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[13]+1309151649,e=(e<<21|e>>>11)+r<<0,t+=(r^(e|~s))+n[4]-145523070,t=(t<<6|t>>>26)+e<<0,s+=(e^(t|~r))+n[11]-1120210379,s=(s<<10|s>>>22)+t<<0,r+=(t^(s|~e))+n[2]+718787259,r=(r<<15|r>>>17)+s<<0,e+=(s^(r|~t))+n[9]-343485551,e=(e<<21|e>>>11)+r<<0,this.first?(this.h0=t+1732584193<<0,this.h1=e-271733879<<0,this.h2=r-1732584194<<0,this.h3=s+271733878<<0,this.first=!1):(this.h0=this.h0+t<<0,this.h1=this.h1+e<<0,this.h2=this.h2+r<<0,this.h3=this.h3+s<<0)},Md5.prototype.hex=function(){this.finalize();var t=this.h0,e=this.h1,r=this.h2,s=this.h3;return HEX_CHARS[t>>4&15]+HEX_CHARS[15&t]+HEX_CHARS[t>>12&15]+HEX_CHARS[t>>8&15]+HEX_CHARS[t>>20&15]+HEX_CHARS[t>>16&15]+HEX_CHARS[t>>28&15]+HEX_CHARS[t>>24&15]+HEX_CHARS[e>>4&15]+HEX_CHARS[15&e]+HEX_CHARS[e>>12&15]+HEX_CHARS[e>>8&15]+HEX_CHARS[e>>20&15]+HEX_CHARS[e>>16&15]+HEX_CHARS[e>>28&15]+HEX_CHARS[e>>24&15]+HEX_CHARS[r>>4&15]+HEX_CHARS[15&r]+HEX_CHARS[r>>12&15]+HEX_CHARS[r>>8&15]+HEX_CHARS[r>>20&15]+HEX_CHARS[r>>16&15]+HEX_CHARS[r>>28&15]+HEX_CHARS[r>>24&15]+HEX_CHARS[s>>4&15]+HEX_CHARS[15&s]+HEX_CHARS[s>>12&15]+HEX_CHARS[s>>8&15]+HEX_CHARS[s>>20&15]+HEX_CHARS[s>>16&15]+HEX_CHARS[s>>28&15]+HEX_CHARS[s>>24&15]},Md5.prototype.toString=Md5.prototype.hex,Md5.prototype.digest=function(){this.finalize();var t=this.h0,e=this.h1,r=this.h2,s=this.h3;return[255&t,t>>8&255,t>>16&255,t>>24&255,255&e,e>>8&255,e>>16&255,e>>24&255,255&r,r>>8&255,r>>16&255,r>>24&255,255&s,s>>8&255,s>>16&255,s>>24&255]},Md5.prototype.array=Md5.prototype.digest,Md5.prototype.arrayBuffer=function(){this.finalize();var t=new ArrayBuffer(16),e=new Uint32Array(t);return e[0]=this.h0,e[1]=this.h1,e[2]=this.h2,e[3]=this.h3,t},Md5.prototype.buffer=Md5.prototype.arrayBuffer,Md5.prototype.base64=function(){for(var t,e,r,s="",o=this.array(),i=0;i<15;)t=o[i++],e=o[i++],r=o[i++],s+=BASE64_ENCODE_CHAR[t>>>2]+BASE64_ENCODE_CHAR[63&(t<<4|e>>>4)]+BASE64_ENCODE_CHAR[63&(e<<2|r>>>6)]+BASE64_ENCODE_CHAR[63&r];return t=o[i],s+=BASE64_ENCODE_CHAR[t>>>2]+BASE64_ENCODE_CHAR[t<<4&63]+"==",s};var exports=createMethod();COMMON_JS?module.exports=exports:(root.md5=exports,AMD&&(__WEBPACK_AMD_DEFINE_RESULT__=function(){return exports}.call(exports,__webpack_require__,exports,module),void 0===__WEBPACK_AMD_DEFINE_RESULT__||(module.exports=__WEBPACK_AMD_DEFINE_RESULT__)))})()}).call(this,__webpack_require__("4362"),__webpack_require__("c8ba"))},"9ed6":function(t,e,r){"use strict";r.r(e);var s=function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("div",{staticClass:"login-container"},[r("el-form",{ref:"loginForm",staticClass:"login-form",attrs:{model:t.loginForm,rules:t.loginRules,"auto-complete":"on","label-position":"left"}},[r("div",{staticClass:"title-container"},[r("h3",{staticClass:"title"},[t._v("SOP Admin")])]),t._v(" "),r("el-form-item",{attrs:{prop:"username"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"user"}})],1),t._v(" "),r("el-input",{ref:"username",attrs:{placeholder:"用户名",name:"username",type:"text",tabindex:"1","auto-complete":"on"},model:{value:t.loginForm.username,callback:function(e){t.$set(t.loginForm,"username",e)},expression:"loginForm.username"}})],1),t._v(" "),r("el-form-item",{attrs:{prop:"password"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"password"}})],1),t._v(" "),r("el-input",{key:t.passwordType,ref:"password",attrs:{type:t.passwordType,placeholder:"密码",name:"password",tabindex:"2","auto-complete":"on"},nativeOn:{keyup:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:t.handleLogin(e)}},model:{value:t.loginForm.password,callback:function(e){t.$set(t.loginForm,"password",e)},expression:"loginForm.password"}}),t._v(" "),r("span",{staticClass:"show-pwd",on:{click:t.showPwd}},[r("svg-icon",{attrs:{"icon-class":"password"===t.passwordType?"eye":"eye-open"}})],1)],1),t._v(" "),r("el-button",{staticStyle:{width:"100%","margin-bottom":"30px"},attrs:{loading:t.loading,type:"primary"},nativeOn:{click:function(e){return e.preventDefault(),t.handleLogin(e)}}},[t._v("登 录")])],1)],1)},o=[],i=r("8237"),n=r.n(i),a=r("5f87"),h={name:"Login",data:function(){var t=function(t,e,r){0===e.length?r(new Error("请输入用户名")):r()},e=function(t,e,r){0===e.length?r(new Error("请输入密码")):e.length<6?r(new Error("请密码长度不得小于6位")):r()};return{loginForm:{username:"",password:""},loginRules:{username:[{required:!0,trigger:"blur",validator:t}],password:[{required:!0,trigger:"blur",validator:e}]},loading:!1,passwordType:"password",redirect:void 0}},watch:{$route:{handler:function(t){this.redirect=t.query&&t.query.redirect},immediate:!0}},methods:{showPwd:function(){var t=this;"password"===this.passwordType?this.passwordType="":this.passwordType="password",this.$nextTick(function(){t.$refs.password.focus()})},handleLogin:function(){var t=this;this.$refs.loginForm.validate(function(e){if(e){var r=t.loginForm,s=r.password;s=n()(s);var o={username:r.username,password:s};t.post("nologin.admin.login",o,function(t){Object(a["c"])(t.data),this.$router.push({path:this.redirect||"/"})})}})}}},u=h,c=(r("2017"),r("d982"),r("2877")),f=Object(c["a"])(u,s,o,!1,null,"0204d890",null);e["default"]=f.exports},d982:function(t,e,r){"use strict";var s=r("dabb"),o=r.n(s);o.a},dabb:function(t,e,r){}}]); \ No newline at end of file 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 753f97f5..4200471c 100644 --- a/sop-admin/sop-admin-vue/src/views/service/serviceList.vue +++ b/sop-admin/sop-admin-vue/src/views/service/serviceList.vue @@ -54,7 +54,7 @@ width="100" > @@ -281,15 +281,12 @@ export default { }, doEnvOnline: function(row, callback) { this.post('service.instance.env.online', row, function() { - callback && callback() + callback && callback.call(this) }) }, onEnvPreOpen: function(row) { this.confirm(`确定要开启 ${row.instanceId} 预发布吗?`, function(done) { - this.post('service.instance.env.pre.open', { - serviceId: row.serviceId, - instanceId: row.instanceId - }, function() { + this.post('service.instance.env.pre.open', row, function() { this.tip('预发布成功') done() }) @@ -305,10 +302,7 @@ export default { }, onEnvGrayOpen: function(row) { this.confirm(`确定要开启 ${row.instanceId} 灰度吗?`, function(done) { - this.post('service.instance.env.gray.open', { - serviceId: row.serviceId, - instanceId: row.instanceId - }, function() { + this.post('service.instance.env.gray.open', row, function() { this.tip('开启成功') done() }) diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java index b5d46aa1..a66d0f17 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java @@ -12,4 +12,8 @@ import java.util.List; public class BaseServiceRouteInfo { private String serviceId; private List routeDefinitionList = Collections.emptyList(); + + public String fetchServiceIdLowerCase() { + return this.serviceId.toLowerCase(); + } } \ No newline at end of file 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/ServiceGrayDefinition.java similarity index 69% rename from sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/UserKeyDefinition.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceGrayDefinition.java index 0889d4cb..8126ca88 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/ServiceGrayDefinition.java @@ -6,7 +6,8 @@ import lombok.Data; * @author tanghc */ @Data -public class UserKeyDefinition { +public class ServiceGrayDefinition { + private String serviceId; private String instanceId; private String data; } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultEnvGrayManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultEnvGrayManager.java index 6aae3577..3fa8561f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultEnvGrayManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultEnvGrayManager.java @@ -2,11 +2,8 @@ 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.List; import java.util.Map; -import java.util.stream.Collectors; /** * @author tanghc @@ -14,17 +11,18 @@ import java.util.stream.Collectors; public class DefaultEnvGrayManager implements EnvGrayManager { /** - * KEY:instanceId + * key:serviceId,服务对应的灰度配置 */ - private Map serviceUserKeyMap = Maps.newConcurrentMap(); + private Map serviceGrayConfigMap = Maps.newConcurrentMap(); + + /** + * key:instanceId value:serviceId + */ + private Map instanceIdServiceIdMap = Maps.newConcurrentMap(); @Override - public List listGrayInstanceId(String serviceId) { - return serviceUserKeyMap - .values() - .stream() - .map(ServiceGrayConfig::getInstanceId) - .collect(Collectors.toList()); + public void saveServiceGrayConfig(ServiceGrayConfig serviceGrayConfig) { + serviceGrayConfigMap.putIfAbsent(serviceGrayConfig.getServiceId(), serviceGrayConfig); } @Override @@ -32,26 +30,40 @@ public class DefaultEnvGrayManager implements EnvGrayManager { if (instanceId == null || userKey == null) { return false; } - return this.getServiceGrayConfig(instanceId).containsKey(userKey); + String serviceId = instanceIdServiceIdMap.get(instanceId); + ServiceGrayConfig grayConfig = this.getGrayConfig(serviceId); + return grayConfig != null && grayConfig.containsKey(userKey); } @Override - public String getVersion(String instanceId, String nameVersion) { - if (instanceId == null || nameVersion == null) { + public String getVersion(String serviceId, String nameVersion) { + if (serviceId == null || nameVersion == null) { + return null; + } + boolean opened = instanceIdServiceIdMap.values().contains(serviceId); + // 没有开启灰度 + if (!opened) { + return null; + } + ServiceGrayConfig grayConfig = this.getGrayConfig(serviceId); + return grayConfig != null ? grayConfig.getVersion(nameVersion) : null; + } + + private ServiceGrayConfig getGrayConfig(String serviceId) { + if (serviceId == null) { return null; } - return this.getServiceGrayConfig(instanceId).getVersion(nameVersion); + return serviceGrayConfigMap.get(serviceId); + } + + @Override + public void openGray(String instanceId, String serviceId) { + instanceIdServiceIdMap.putIfAbsent(instanceId, serviceId); } @Override - public ServiceGrayConfig getServiceGrayConfig(String instanceId) { - return serviceUserKeyMap.computeIfAbsent(instanceId, key -> { - ServiceGrayConfig serviceGrayConfig = new ServiceGrayConfig(); - serviceGrayConfig.setInstanceId(instanceId); - serviceGrayConfig.setUserKeys(Sets.newConcurrentHashSet()); - serviceGrayConfig.setGrayNameVersion(Maps.newConcurrentMap()); - return serviceGrayConfig; - }); + public void closeGray(String instanceId) { + instanceIdServiceIdMap.remove(instanceId); } @Override diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java index d89fea0b..9591a36e 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java @@ -3,18 +3,43 @@ package com.gitee.sop.gatewaycommon.manager; import com.gitee.sop.gatewaycommon.bean.BeanInitializer; import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig; -import java.util.List; - /** * @author tanghc */ public interface EnvGrayManager extends BeanInitializer { - List listGrayInstanceId(String serviceId); + /** + * 保存灰度配置 + * @param serviceGrayConfig 灰度配置 + */ + void saveServiceGrayConfig(ServiceGrayConfig serviceGrayConfig); + /** + * 实例是否允许 + * @param instanceId 实例id + * @param userKey 用户key,如appKey + * @return true:允许访问 + */ boolean containsKey(String instanceId, Object userKey); - String getVersion(String instanceId, String nameVersion); + /** + * 获取灰度发布新版本号 + * @param serviceId serviceId + * @param nameVersion 路由id + * @return 返回新版本号 + */ + String getVersion(String serviceId, String nameVersion); + + /** + * 开启灰度 + * @param instanceId instanceId + * @param serviceId serviceId + */ + void openGray(String instanceId, String serviceId); - ServiceGrayConfig getServiceGrayConfig(String instanceId); + /** + * 关闭灰度 + * @param instanceId instanceId + */ + void closeGray(String instanceId); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ZookeeperContext.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ZookeeperContext.java index 508afda7..b7672836 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ZookeeperContext.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ZookeeperContext.java @@ -69,8 +69,8 @@ public class ZookeeperContext { return SOP_MSG_CHANNEL_PATH + "/isvinfo"; } - public static String getUserKeyChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/userkey"; + public static String getServiceGrayChannelPath() { + return SOP_MSG_CHANNEL_PATH + "/gray"; } public static String getIsvRoutePermissionChannelPath() { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreVersionDecisionFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreVersionDecisionFilter.java index dfea50c4..d0198414 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreVersionDecisionFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreVersionDecisionFilter.java @@ -10,8 +10,6 @@ import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.beans.factory.annotation.Autowired; -import java.util.List; - /** * @author tanghc */ @@ -38,17 +36,11 @@ public class PreVersionDecisionFilter extends BaseZuulFilter { if (targetRoute == null) { return null; } - String serviceId = targetRoute.getServiceRouteInfo().getServiceId(); - List instanceIdList = envGrayManager.listGrayInstanceId(serviceId); - String appKey = apiParam.fetchAppKey(); - for (String instanceId : instanceIdList) { - if (envGrayManager.containsKey(instanceId, appKey)) { - String version = envGrayManager.getVersion(instanceId, nameVersion); - if (version != null) { - requestContext.addZuulRequestHeader(ParamNames.HEADER_VERSION_NAME, version); - break; - } - } + String serviceId = targetRoute.getServiceRouteInfo().fetchServiceIdLowerCase(); + // 如果服务在灰度阶段,返回一个灰度版本号 + String version = envGrayManager.getVersion(serviceId, nameVersion); + if (version != null) { + requestContext.addZuulRequestHeader(ParamNames.HEADER_VERSION_NAME, version); } return null; } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java index 2b3b5953..fed0ae94 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java @@ -42,14 +42,6 @@ public abstract class BaseServerChooser extends ZoneAvoidanceRule { */ protected abstract boolean canVisitPre(Server server, HttpServletRequest request); - /** - * 能否访问灰度服务器 - * @param server 灰度服务器 - * @param request request - * @return true:能 - */ - protected abstract boolean canVisitGray(Server server, HttpServletRequest request); - @Override public Server choose(Object key) { ILoadBalancer lb = getLoadBalancer(); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java index 2e11b8e8..7aed5c38 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/ServiceGrayConfig.java @@ -13,8 +13,6 @@ public class ServiceGrayConfig { private String serviceId; - private String instanceId; - /** * 用户id */ @@ -31,8 +29,4 @@ public class ServiceGrayConfig { return grayNameVersion.get(name); } - public void clear() { - this.userKeys.clear(); - this.grayNameVersion.clear(); - } } 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/ConfigGray.java similarity index 62% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayUserkey.java rename to sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGray.java index 9f91de18..15da8353 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/ConfigGray.java @@ -11,35 +11,29 @@ import java.util.Date; /** - * 表名:config_gray_userkey - * 备注:灰度发布用户key + * 表名:config_gray + * 备注:服务灰度配置 * * @author tanghc */ -@Table(name = "config_gray_userkey") +@Table(name = "config_gray") @Data -public class ConfigGrayUserkey { +public class ConfigGray { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) /** 数据库字段:id */ private Long id; - /** serviceId, 数据库字段:service_id */ + /** 数据库字段:service_id */ private String serviceId; - /** instanceId, 数据库字段:instance_id */ - private String instanceId; - /** 用户key,多个用引文逗号隔开, 数据库字段:user_key_content */ private String userKeyContent; - /** 需要灰度的接口,goods.get=1.2,order.list=1.2, 数据库字段:name_version_content */ + /** 需要灰度的接口,goods.get1.0=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/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayInstance.java similarity index 55% rename from sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java rename to sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayInstance.java index d822e182..81bc95ce 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigGrayUserkey.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigGrayInstance.java @@ -1,4 +1,4 @@ -package com.gitee.sop.adminserver.entity; +package com.gitee.sop.gateway.entity; import lombok.Data; @@ -11,31 +11,24 @@ import java.util.Date; /** - * 表名:config_gray_userkey - * 备注:灰度发布用户key + * 表名:config_gray_instance * * @author tanghc */ -@Table(name = "config_gray_userkey") +@Table(name = "config_gray_instance") @Data -public class ConfigGrayUserkey { +public class ConfigGrayInstance { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) /** 数据库字段:id */ private Long id; - /** serviceId, 数据库字段:service_id */ - private String serviceId; - - /** instanceId, 数据库字段:instance_id */ + /** instance_id, 数据库字段:instance_id */ private String instanceId; - /** 用户key,多个用引文逗号隔开, 数据库字段:user_key_content */ - private String userKeyContent; - - /** 需要灰度的接口,goods.get=1.2,order.list=1.2, 数据库字段:name_version_content */ - private String nameVersionContent; + /** service_id, 数据库字段:service_id */ + private String serviceId; /** 0:禁用,1:启用, 数据库字段:status */ private Byte status; 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 905bb846..addf958c 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 @@ -2,12 +2,11 @@ package com.gitee.sop.gateway.loadbalancer; import com.gitee.sop.gateway.manager.DbEnvGrayManager; import com.gitee.sop.gatewaycommon.bean.SpringContext; -import com.gitee.sop.gatewaycommon.param.ApiParam; import com.gitee.sop.gatewaycommon.param.Param; -import com.gitee.sop.gatewaycommon.zuul.ZuulContext; import com.gitee.sop.gatewaycommon.zuul.loadbalancer.BaseServerChooser; import com.netflix.loadbalancer.Server; import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; +import org.springframework.core.env.Environment; import javax.servlet.http.HttpServletRequest; import java.util.Map; @@ -56,22 +55,10 @@ public class EnvironmentServerChooser extends BaseServerChooser { @Override protected boolean canVisitPre(Server server, HttpServletRequest request) { String serverName = request.getServerName(); - return PRE_DOMAIN.equals(serverName); + String domain = SpringContext.getBean(Environment.class).getProperty("pre.domain", PRE_DOMAIN); + return domain.equals(serverName); } - /** - * 能否进入灰度环境 - * - * @param request request - * @return 返回true:可以进入到预发环境 - */ - protected boolean canVisitGray(Server server, HttpServletRequest request) { - ApiParam apiParam = ZuulContext.getApiParam(); - DbEnvGrayManager userKeyManager = SpringContext.getBean(DbEnvGrayManager.class); - return this.isGrayUser(apiParam, userKeyManager, server, request); - } - - /** * 是否是灰度用户,可修改此方法实现自己想要的 * diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java index f5491605..305ace89 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java @@ -2,13 +2,16 @@ 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.mapper.ConfigGrayUserkeyMapper; +import com.gitee.sop.gateway.entity.ConfigGray; +import com.gitee.sop.gateway.entity.ConfigGrayInstance; +import com.gitee.sop.gateway.mapper.ConfigGrayInstanceMapper; +import com.gitee.sop.gateway.mapper.ConfigGrayMapper; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; -import com.gitee.sop.gatewaycommon.bean.UserKeyDefinition; +import com.gitee.sop.gatewaycommon.bean.ServiceGrayDefinition; import com.gitee.sop.gatewaycommon.manager.DefaultEnvGrayManager; import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig; +import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +22,8 @@ import javax.annotation.PostConstruct; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -33,82 +38,86 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager { private static final int STATUS_ENABLE = 1; + private static final Function FUNCTION_KEY = arr -> arr[0]; + private static final Function FUNCTION_VALUE = arr -> arr[1]; + @Autowired private Environment environment; @Autowired - private ConfigGrayUserkeyMapper configGrayUserkeyMapper; + private ConfigGrayMapper configGrayMapper; + + @Autowired + private ConfigGrayInstanceMapper configGrayInstanceMapper; @Override public void load() { + + List list = configGrayMapper.list(new Query()); + for (ConfigGray configGray : list) { + this.setServiceGrayConfig(configGray); + } + Query query = new Query(); query.eq("status", STATUS_ENABLE); - List list = configGrayUserkeyMapper.list(query); - for (ConfigGrayUserkey configGrayUserkey : list) { - this.setServiceGrayConfig(configGrayUserkey); + List grayInstanceList = configGrayInstanceMapper.list(query); + for (ConfigGrayInstance configGrayInstance : grayInstanceList) { + this.openGray(configGrayInstance.getInstanceId(), configGrayInstance.getServiceId()); } } /** * 设置用户key * - * @param configGrayUserkey 灰度配置 + * @param configGray 灰度配置 */ - public void setServiceGrayConfig(ConfigGrayUserkey configGrayUserkey) { - if (configGrayUserkey == null) { + public void setServiceGrayConfig(ConfigGray configGray) { + if (configGray == null) { return; } - String instanceId = configGrayUserkey.getInstanceId(); - this.clear(instanceId); - String userKeyData = configGrayUserkey.getUserKeyContent(); - String nameVersionContent = configGrayUserkey.getNameVersionContent(); + String userKeyData = configGray.getUserKeyContent(); + String nameVersionContent = configGray.getNameVersionContent(); String[] userKeys = StringUtils.split(userKeyData, ','); String[] nameVersionList = StringUtils.split(nameVersionContent, ','); - log.info("添加userKey,userKeys.length:{}, nameVersionList:{}", userKeys.length, Arrays.toString(nameVersionList)); - - List list = Stream.of(userKeys).collect(Collectors.toList()); - ServiceGrayConfig serviceGrayConfig = getServiceGrayConfig(instanceId); - serviceGrayConfig.setServiceId(configGrayUserkey.getServiceId()); - serviceGrayConfig.getUserKeys().addAll(list); - - Map grayNameVersion = serviceGrayConfig.getGrayNameVersion(); - for (String nameVersion : nameVersionList) { - String[] nameVersionInfo = StringUtils.split(nameVersion, '='); - String name = nameVersionInfo[0]; - String version = nameVersionInfo[1]; - grayNameVersion.put(name, version); - } + log.info("灰度配置,userKeys.length:{}, nameVersionList:{}", userKeys.length, Arrays.toString(nameVersionList)); - } + Set userKeySet = Stream.of(userKeys) + .collect(Collectors.toCollection(Sets::newConcurrentHashSet)); - /** - * 清空用户key - */ - public void clear(String instanceId) { - getServiceGrayConfig(instanceId).clear(); + Map grayNameVersionMap = Stream.of(nameVersionList) + .map(nameVersion -> StringUtils.split(nameVersion, '=')) + .collect(Collectors.toConcurrentMap(FUNCTION_KEY, FUNCTION_VALUE)); + + ServiceGrayConfig serviceGrayConfig = new ServiceGrayConfig(); + serviceGrayConfig.setServiceId(configGray.getServiceId()); + serviceGrayConfig.setUserKeys(userKeySet); + serviceGrayConfig.setGrayNameVersion(grayNameVersionMap); + this.saveServiceGrayConfig(serviceGrayConfig); } @PostConstruct protected void after() throws Exception { ZookeeperContext.setEnvironment(environment); - String isvChannelPath = ZookeeperContext.getUserKeyChannelPath(); + String isvChannelPath = ZookeeperContext.getServiceGrayChannelPath(); ZookeeperContext.listenPath(isvChannelPath, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class); String data = channelMsg.getData(); - UserKeyDefinition userKeyDefinition = JSON.parseObject(data, UserKeyDefinition.class); - String instanceId = userKeyDefinition.getInstanceId(); + ServiceGrayDefinition userKeyDefinition = JSON.parseObject(data, ServiceGrayDefinition.class); + String serviceId = userKeyDefinition.getServiceId(); switch (channelMsg.getOperation()) { case "set": - ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("instance_id", instanceId); - this.setServiceGrayConfig(configGrayUserkey); + ConfigGray configGray = configGrayMapper.getByColumn("service_id", serviceId); + this.setServiceGrayConfig(configGray); + break; + case "open": + openGray(userKeyDefinition.getInstanceId(), serviceId); break; - case "clear": - clear(instanceId); + case "close": + closeGray(userKeyDefinition.getInstanceId()); break; default: - log.error("userKey消息,错误的消息指令,nodeData:{}", nodeData); } }); 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 8f97e349..7db0eada 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 @@ -56,7 +56,6 @@ public class DbIPBlacklistManager extends DefaultIPBlacklistManager { remove(ip); break; default: - log.error("IP黑名单,错误的消息指令,nodeData:{}", nodeData); } }); } 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 51cc9b2c..6ece0b03 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 @@ -61,7 +61,6 @@ public class DbIsvManager extends CacheIsvManager { remove(isvDefinition.getAppKey()); break; default: - log.error("ISV信息,错误的消息指令,nodeData:{}", nodeData); } }); 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 2162d0e7..0715703a 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 @@ -152,6 +152,8 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage log.info("删除ISV路由权限信息,isvRoutePermission:{}", isvRoutePermission); remove(isvRoutePermission.getAppKey()); break; + default: + } }); } 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 9804f492..0f150334 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 @@ -63,7 +63,6 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager { update(configLimitDto); break; default: - log.error("限流配置信息,错误的消息指令,nodeData:{}", nodeData); } }); } 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 6c5a9674..ef7125f5 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 @@ -87,7 +87,6 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager { update(routeConfig); break; default: - log.error("路由配置信息,错误的消息指令,nodeData:{}", nodeData); } }); } diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayInstanceMapper.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayInstanceMapper.java new file mode 100644 index 00000000..cd8bd242 --- /dev/null +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayInstanceMapper.java @@ -0,0 +1,11 @@ +package com.gitee.sop.gateway.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; +import com.gitee.sop.gateway.entity.ConfigGrayInstance; + + +/** + * @author tanghc + */ +public interface ConfigGrayInstanceMapper extends CrudMapper { +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayMapper.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayMapper.java new file mode 100644 index 00000000..3405badb --- /dev/null +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayMapper.java @@ -0,0 +1,11 @@ +package com.gitee.sop.gateway.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; +import com.gitee.sop.gateway.entity.ConfigGray; + + +/** + * @author tanghc + */ +public interface ConfigGrayMapper extends CrudMapper { +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayUserkeyMapper.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayUserkeyMapper.java deleted file mode 100644 index 38e4d70a..00000000 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigGrayUserkeyMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.sop.gateway.mapper; - -import com.gitee.fastmybatis.core.mapper.CrudMapper; -import com.gitee.sop.gateway.entity.ConfigGrayUserkey; - - -/** - * @author tanghc - */ -public interface ConfigGrayUserkeyMapper extends CrudMapper { -} diff --git a/sop-gateway/src/main/resources/application-dev.properties b/sop-gateway/src/main/resources/application-dev.properties index 8517f0ee..b8aa8f58 100644 --- a/sop-gateway/src/main/resources/application-dev.properties +++ b/sop-gateway/src/main/resources/application-dev.properties @@ -12,6 +12,9 @@ eureka.url=http://localhost:1111/eureka/ zookeeper.url=localhost:2181 # zipkin服务监控地址,没有开启不用改 zipkin.url=http://127.0.0.1:9411/ + +# 预发布网关域名 +pre.domain=localhost # ------- 需要改的配置end ------- # 入口地址,不用改,默认是/zuul diff --git a/sop.sql b/sop.sql index 18d4af9d..d9d8cfb0 100644 --- a/sop.sql +++ b/sop.sql @@ -15,7 +15,8 @@ DROP TABLE IF EXISTS `admin_user_info`; DROP TABLE IF EXISTS `config_common`; DROP TABLE IF EXISTS `isv_keys`; DROP TABLE IF EXISTS `config_ip_blacklist`; -DROP TABLE IF EXISTS `config_gray_userkey`; +DROP TABLE IF EXISTS `config_gray`; +DROP TABLE IF EXISTS `config_gray_instance`; CREATE TABLE `admin_user_info` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, @@ -176,17 +177,29 @@ CREATE TABLE `config_ip_blacklist` ( UNIQUE KEY `uk_ip` (`ip`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='IP黑名单'; -CREATE TABLE `config_gray_userkey` ( +CREATE TABLE `config_gray` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `instance_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'serviceId', + `service_id` varchar(64) NOT NULL DEFAULT '', `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:启用', + `name_version_content` text COMMENT '需要灰度的接口,goods.get1.0=1.2,多个用英文逗号隔开', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_serviceid` (`service_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='服务灰度配置'; + + +CREATE TABLE `config_gray_instance` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `instance_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'instance_id', + `service_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'service_id', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0:禁用,1:启用', `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), - UNIQUE KEY `uk_instanceid` (`instance_id`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='灰度发布用户key'; + UNIQUE KEY `uk_instanceid` (`instance_id`) USING BTREE, + KEY `idx_serviceid` (`service_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='开启灰度服务器实例'; SET FOREIGN_KEY_CHECKS = @PREVIOUS_FOREIGN_KEY_CHECKS; From 06e06081304d11a8a9ea7ad291f368ad359ad20f Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 7 Aug 2019 15:12:56 +0800 Subject: [PATCH 09/10] 1.14.0 --- sop-admin/sop-admin-server/pom.xml | 2 +- sop-common/pom.xml | 2 +- sop-common/sop-gateway-common/pom.xml | 4 ++-- sop-common/sop-registry-api/pom.xml | 2 +- sop-common/sop-service-common/pom.xml | 4 ++-- sop-example/sop-auth/pom.xml | 2 +- sop-example/sop-book/sop-book-web/pom.xml | 2 +- sop-example/sop-easyopen/pom.xml | 2 +- sop-example/sop-springmvc/pom.xml | 2 +- sop-example/sop-story/sop-story-web/pom.xml | 2 +- sop-gateway/pom.xml | 2 +- sop-website/website-server/pom.xml | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index c890a936..c4c88dc5 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -32,7 +32,7 @@ com.gitee.sop sop-registry-api - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT diff --git a/sop-common/pom.xml b/sop-common/pom.xml index b9474842..9a6dbde8 100644 --- a/sop-common/pom.xml +++ b/sop-common/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.gitee.sop sop-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT pom diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 4944f39f..41eff995 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -5,11 +5,11 @@ com.gitee.sop sop-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT ../pom.xml sop-gateway-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT jar sop-gateway-common diff --git a/sop-common/sop-registry-api/pom.xml b/sop-common/sop-registry-api/pom.xml index f2aa4b67..4e98940b 100644 --- a/sop-common/sop-registry-api/pom.xml +++ b/sop-common/sop-registry-api/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.gitee.sop sop-registry-api - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT UTF-8 diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index a0b12082..8b7c7da6 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -6,11 +6,11 @@ com.gitee.sop sop-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT ../pom.xml sop-service-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT jar sop-service-common diff --git a/sop-example/sop-auth/pom.xml b/sop-example/sop-auth/pom.xml index 581fb460..af511639 100644 --- a/sop-example/sop-auth/pom.xml +++ b/sop-example/sop-auth/pom.xml @@ -26,7 +26,7 @@ com.gitee.sop sop-service-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT org.springframework.cloud diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml index c1610423..d7391a35 100644 --- a/sop-example/sop-book/sop-book-web/pom.xml +++ b/sop-example/sop-book/sop-book-web/pom.xml @@ -24,7 +24,7 @@ com.gitee.sop sop-service-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT com.gitee.sop diff --git a/sop-example/sop-easyopen/pom.xml b/sop-example/sop-easyopen/pom.xml index ce2fe39c..77630c70 100644 --- a/sop-example/sop-easyopen/pom.xml +++ b/sop-example/sop-easyopen/pom.xml @@ -29,7 +29,7 @@ com.gitee.sop sop-service-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT org.springframework.cloud diff --git a/sop-example/sop-springmvc/pom.xml b/sop-example/sop-springmvc/pom.xml index 84f68b37..88f06728 100644 --- a/sop-example/sop-springmvc/pom.xml +++ b/sop-example/sop-springmvc/pom.xml @@ -20,7 +20,7 @@ com.gitee.sop sop-service-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index c80b2131..e326ea9f 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -24,7 +24,7 @@ com.gitee.sop sop-service-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT com.gitee.sop diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 617820af..3dcbf06d 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -23,7 +23,7 @@ com.gitee.sop sop-gateway-common - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT diff --git a/sop-website/website-server/pom.xml b/sop-website/website-server/pom.xml index 72a66b50..5a13af45 100644 --- a/sop-website/website-server/pom.xml +++ b/sop-website/website-server/pom.xml @@ -25,7 +25,7 @@ com.gitee.sop sop-registry-api - 1.13.5-SNAPSHOT + 1.14.0-SNAPSHOT From 6b6ed9346a2b712490f942d9ca58d282a8a914d1 Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 7 Aug 2019 15:13:40 +0800 Subject: [PATCH 10/10] 1.14.0 --- .../zuul/loadbalancer/BaseServerChooser.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java index fed0ae94..6d663ffc 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java @@ -53,19 +53,6 @@ public abstract class BaseServerChooser extends ZoneAvoidanceRule { .filter(this::isPreServer) .filter(server -> canVisitPre(server, request)) .collect(Collectors.toList()); -// int index = -1; -// for (int i = 0; i < allServers.size(); i++) { -// Server server = allServers.get(i); -// if (isPreServer(server)) { -// preServers.add(server); -// } -// if (match(server)) { -// index = i; -// if (canVisit(server, RequestContext.getCurrentContext().getRequest())) { -// return server; -// } -// } -// } if (!preServers.isEmpty()) { return this.doChoose(preServers, key); @@ -81,16 +68,6 @@ public abstract class BaseServerChooser extends ZoneAvoidanceRule { } return super.choose(key); - // 调用默认的算法 - // 如果选出了特殊环境服务器,需要移除命中的服务器 -// if (index > -1) { -// allServers.remove(index); -// } -// if (CollectionUtils.isEmpty(allServers)) { -// log.error("无可用服务实例,key:", key); -// return null; -// } - } protected Server doChoose(List servers, Object key) {