From baa6289aa377a1c1731b8068fdea80be2f349dda Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 1 Jul 2019 17:53:12 +0800 Subject: [PATCH 01/82] update --- .../com/gitee/sop/registryapi/bean/EurekaUri.java | 3 +++ sop-gateway/src/main/resources/application-dev.yml | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) 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 1d7b39e8..8a229ca7 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 @@ -50,6 +50,9 @@ public enum EurekaUri { } public Request getRequest(String url, String... args) { + if (url.endsWith("/")) { + url = url.substring(0, url.length() - 1); + } String requestUrl = url + getUri(args); Request request = this.getBuilder() .url(requestUrl) diff --git a/sop-gateway/src/main/resources/application-dev.yml b/sop-gateway/src/main/resources/application-dev.yml index c025fd63..825d97d2 100644 --- a/sop-gateway/src/main/resources/application-dev.yml +++ b/sop-gateway/src/main/resources/application-dev.yml @@ -19,6 +19,12 @@ ribbon: # 请谨慎设置,因为post请求大多都是写入请求,如果要支持重试,确保服务的幂等性 OkToRetryOnAllOperations: false +# eureka注册中心,如果使用nacos注册中心,这里要注释掉 +#eureka: +# client: +# serviceUrl: +# defaultZone: http://localhost:1111/eureka/ + spring: application: name: api-gateway @@ -39,12 +45,6 @@ spring: discovery: server-addr: 127.0.0.1:8848 -# eureka注册中心,如果使用nacos注册中心,这里要注释掉 -#eureka: -# client: -# serviceUrl: -# defaultZone: http://localhost:1111/eureka/ - # 数据源,根据实际情况修改 datasource: driver-class-name: com.mysql.jdbc.Driver From 0f468963064f7fb052185bd68001bc7eec93508f Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 1 Jul 2019 20:55:25 +0800 Subject: [PATCH 02/82] update --- .../com/gitee/sop/websiteserver/manager/DocManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java index fa3adabb..4837f7a3 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java @@ -86,7 +86,7 @@ public class DocManagerImpl implements DocManager { protected void loadDocInfo(ServiceInstance serviceInstance) { String query = this.buildQuery(); - String url = "http://" + serviceInstance.getIpPort() + "/v2/api-docs" + query; + String url = "http://" + serviceInstance.getIp() + ":" + serviceInstance.getPort() + "/v2/api-docs" + query; try { log.info("读取swagger文档,url:{}", url); ResponseEntity entity = restTemplate.getForEntity(url, String.class); From dad2fa7de331cedd7d6533caaccfedd8572eaf3c Mon Sep 17 00:00:00 2001 From: tanghc Date: Tue, 2 Jul 2019 14:06:38 +0800 Subject: [PATCH 03/82] nacos --- .../src/main/resources/application-dev.yml | 2 +- sop-example/sop-book/sop-book-web/pom.xml | 8 ++++---- .../src/main/resources/application-dev.yml | 14 +++++++------- sop-example/sop-story/sop-story-web/pom.xml | 8 ++++---- .../src/main/resources/application-dev.yml | 14 +++++++------- sop-gateway/pom.xml | 7 ++++--- .../src/main/resources/application-dev.yml | 2 +- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/sop-admin/sop-admin-server/src/main/resources/application-dev.yml b/sop-admin/sop-admin-server/src/main/resources/application-dev.yml index 64b56db8..e9436142 100644 --- a/sop-admin/sop-admin-server/src/main/resources/application-dev.yml +++ b/sop-admin/sop-admin-server/src/main/resources/application-dev.yml @@ -38,7 +38,7 @@ registry: # nacos服务器地址 nacos-server-addr: 127.0.0.1:8848 # 使用eureka,填:eureka,使用nacos填:nacos - name: eureka + name: nacos # 根据实际情况改 diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml index e0443e6b..e2fa4087 100644 --- a/sop-example/sop-book/sop-book-web/pom.xml +++ b/sop-example/sop-book/sop-book-web/pom.xml @@ -39,23 +39,23 @@ - + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery 0.2.2.RELEASE - --> + diff --git a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml index 649fcf39..4f39516a 100644 --- a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml +++ b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml @@ -11,15 +11,15 @@ spring: connect-string: localhost:2181 # nacos注册中心,和eureka只能用一个 -# nacos: -# discovery: -# server-addr: 127.0.0.1:8848 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # eureka注册中心,如果使用nacos注册中心,这里要注释掉 -eureka: - client: - serviceUrl: - defaultZone: http://localhost:1111/eureka/ +#eureka: +# client: +# serviceUrl: +# defaultZone: http://localhost:1111/eureka/ # dubbo consumer demo: diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index 670cea0d..c9118361 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -33,23 +33,23 @@ - + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery 0.2.2.RELEASE - --> + diff --git a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml index 59f250ab..62354b7a 100644 --- a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml +++ b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml @@ -11,15 +11,15 @@ spring: connect-string: localhost:2181 # nacos注册中心,和eureka只能用一个 -# nacos: -# discovery: -# server-addr: 127.0.0.1:8848 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # eureka注册中心,如果使用nacos注册中心,这里要注释掉 -eureka: - client: - serviceUrl: - defaultZone: http://localhost:1111/eureka/ +#eureka: +# client: +# serviceUrl: +# defaultZone: http://localhost:1111/eureka/ # dubbo provider dubbo: diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index cef66f3a..534f30d5 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -66,23 +66,24 @@ - + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery 0.2.2.RELEASE - --> + diff --git a/sop-website/website-server/src/main/resources/application-dev.yml b/sop-website/website-server/src/main/resources/application-dev.yml index 79f736b6..34fb17a3 100644 --- a/sop-website/website-server/src/main/resources/application-dev.yml +++ b/sop-website/website-server/src/main/resources/application-dev.yml @@ -7,7 +7,7 @@ registry: # nacos服务器地址 nacos-server-addr: 127.0.0.1:8848 # 使用eureka,填:eureka,使用nacos填:nacos - name: eureka + name: nacos spring: application: From 167d0a77f774cf516f7800bd0d5fc30d5322f58e Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 18 Jul 2019 15:28:48 +0800 Subject: [PATCH 04/82] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-admin/sop-admin-server/pom.xml | 9 +-- .../main/resources/application-dev.properties | 2 +- .../src/main/resources/application-dev.yml | 61 ------------------ .../src/main/resources/application.yml | 3 - .../main/resources/application-dev.properties | 4 +- .../src/main/resources/application-dev.yml | 37 ----------- .../src/main/resources/application.yml | 3 - .../main/resources/application-dev.properties | 4 +- .../src/main/resources/application-dev.yml | 32 ---------- .../src/main/resources/application.yml | 3 - .../main/resources/application-dev.properties | 10 ++- .../src/main/resources/application-dev.yml | 64 ------------------- .../src/main/resources/application.yml | 3 - .../src/main/resources/application-dev.yml | 17 ----- .../src/main/resources/application.yml | 3 - .../main/resources/application-dev.properties | 2 +- .../src/main/resources/application-dev.yml | 27 -------- .../src/main/resources/application.yml | 3 - 18 files changed, 12 insertions(+), 275 deletions(-) delete mode 100644 sop-admin/sop-admin-server/src/main/resources/application-dev.yml delete mode 100644 sop-admin/sop-admin-server/src/main/resources/application.yml delete mode 100644 sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml delete mode 100644 sop-example/sop-book/sop-book-web/src/main/resources/application.yml delete mode 100644 sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml delete mode 100644 sop-example/sop-story/sop-story-web/src/main/resources/application.yml delete mode 100644 sop-gateway/src/main/resources/application-dev.yml delete mode 100644 sop-gateway/src/main/resources/application.yml delete mode 100644 sop-registry/src/main/resources/application-dev.yml delete mode 100644 sop-registry/src/main/resources/application.yml delete mode 100644 sop-website/website-server/src/main/resources/application-dev.yml delete mode 100644 sop-website/website-server/src/main/resources/application.yml diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index b7ca28fe..37da3bb6 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -103,14 +103,7 @@ 1.18.4 provided - - org.springframework.cloud - spring-cloud-commons - 2.1.0.RELEASE - compile - - - + 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 68597209..9edc0864 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 @@ -41,7 +41,7 @@ easyopen.ignore-validate=true registry.eureka-server-addr=${eureka.url} registry.nacos-server-addr=${nacos.url} # 使用eureka,填:eureka,使用nacos填:nacos -registry.name=eureka +registry.name=nacos logging.level.com.gitee=debug diff --git a/sop-admin/sop-admin-server/src/main/resources/application-dev.yml b/sop-admin/sop-admin-server/src/main/resources/application-dev.yml deleted file mode 100644 index 2aa372aa..00000000 --- a/sop-admin/sop-admin-server/src/main/resources/application-dev.yml +++ /dev/null @@ -1,61 +0,0 @@ -server: - port: 8082 - -# token过期时间,分钟 -admin: - access-token: - timeout-minutes: 30 - -sop: - # 签名方式,rsa:支付宝开放平台签名方式,md5:淘宝开放平台签名方式 - sign-type: rsa - -# 不用改 -spring: - application: - name: sop-admin - - cloud: - - # zookeeper地址,根据实际情况修改 - zookeeper: - connect-string: localhost:2181 - baseSleepTimeMs: 3000 - maxRetries: 3 - - # 数据源 - datasource: - driver-class-name: com.mysql.jdbc.Driver - url: jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull - username: root - password: root - - -# 固定不用改 -easyopen: - show-doc: true - ignore-validate: true - -# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册 -registry: - eureka-server-addr: http://localhost:1111/eureka/ - # nacos服务器地址 - nacos-server-addr: 127.0.0.1:8848 - # 使用eureka,填:eureka,使用nacos填:nacos - name: nacos - - -# 根据实际情况改 -logging: - level: - com: - gitee: debug - -# 不用改 -mybatis: - fill: {com.gitee.fastmybatis.core.support.DateFillInsert: gmt_create, - com.gitee.fastmybatis.core.support.DateFillUpdate: gmt_modified} - -# 不用改,如果要改,请全局替换修改 -zuul: - secret: MZZOUSTua6LzApIWXCwEgbBmxSzpzC \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/application.yml b/sop-admin/sop-admin-server/src/main/resources/application.yml deleted file mode 100644 index caf4dfcd..00000000 --- a/sop-admin/sop-admin-server/src/main/resources/application.yml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties index 6d7402c9..bd175f34 100644 --- a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties +++ b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties @@ -2,10 +2,8 @@ server.port=3333 spring.application.name=book-service spring.application.description=book服务 -# eureka注册中心,如果使用nacos注册中心,这里要注释掉 -eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ # nacos注册中心 -# spring.nacos.discovery.server-addr=127.0.0.1:8848 +spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 # zookeeper配置 spring.cloud.zookeeper.connect-string=localhost:2181 diff --git a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml deleted file mode 100644 index 4f39516a..00000000 --- a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.yml +++ /dev/null @@ -1,37 +0,0 @@ -server: - port: 3333 - -spring: - application: - name: book-service - - cloud: - zookeeper: - # zookeeper配置 - connect-string: localhost:2181 - - # nacos注册中心,和eureka只能用一个 - nacos: - discovery: - server-addr: 127.0.0.1:8848 - -# eureka注册中心,如果使用nacos注册中心,这里要注释掉 -#eureka: -# client: -# serviceUrl: -# defaultZone: http://localhost:1111/eureka/ - -# dubbo consumer -demo: - service: - version: 1.0.0 -dubbo: - application: - id: dubbo-consumer-demo - name: dubbo-consumer-demo - protocol: - id: dubbo - name: dubbo - port: 12345 -management: - port: 8081 \ No newline at end of file diff --git a/sop-example/sop-book/sop-book-web/src/main/resources/application.yml b/sop-example/sop-book/sop-book-web/src/main/resources/application.yml deleted file mode 100644 index caf4dfcd..00000000 --- a/sop-example/sop-book/sop-book-web/src/main/resources/application.yml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties index 67aa5e68..c2709748 100644 --- a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties +++ b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties @@ -2,10 +2,8 @@ server.port=2222 spring.application.name=story-service spring.application.description=story服务 -# eureka注册中心,如果使用nacos注册中心,这里要注释掉 -eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ # nacos注册中心 -# spring.nacos.discovery.server-addr=127.0.0.1:8848 +spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 # zookeeper配置 spring.cloud.zookeeper.connect-string=localhost:2181 diff --git a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml deleted file mode 100644 index 62354b7a..00000000 --- a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.yml +++ /dev/null @@ -1,32 +0,0 @@ -server: - port: 2222 - -spring: - application: - name: story-service - description: story服务 - - cloud: - zookeeper: - connect-string: localhost:2181 - - # nacos注册中心,和eureka只能用一个 - nacos: - discovery: - server-addr: 127.0.0.1:8848 - -# eureka注册中心,如果使用nacos注册中心,这里要注释掉 -#eureka: -# client: -# serviceUrl: -# defaultZone: http://localhost:1111/eureka/ - -# dubbo provider -dubbo: - protocol: - name: dubbo - port: 12345 - registry: - address: N/A - scan: - base-packages: com.gitee.sop.storyweb.service diff --git a/sop-example/sop-story/sop-story-web/src/main/resources/application.yml b/sop-example/sop-story/sop-story-web/src/main/resources/application.yml deleted file mode 100644 index caf4dfcd..00000000 --- a/sop-example/sop-story/sop-story-web/src/main/resources/application.yml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/sop-gateway/src/main/resources/application-dev.properties b/sop-gateway/src/main/resources/application-dev.properties index fbaf6c9d..0e1a2649 100644 --- a/sop-gateway/src/main/resources/application-dev.properties +++ b/sop-gateway/src/main/resources/application-dev.properties @@ -9,6 +9,8 @@ mysql.password=root eureka.url=http://localhost:1111/eureka/ # zookeeper地址 zookeeper.url=localhost:2181 +# nacos地址 +nacos.url=127.0.0.1:8848 # zipkin服务监控地址,没有开启不用改 zipkin.url=http://127.0.0.1:9411/ # ------- 需要改的配置end ------- @@ -32,10 +34,12 @@ ribbon.ReadTimeout=2000 # 请谨慎设置,因为post请求大多都是写入请求,如果要支持重试,确保服务的幂等性 ribbon.OkToRetryOnAllOperations=false -eureka.client.serviceUrl.defaultZone=${eureka.url} +# nacos注册中心配置 +spring.cloud.nacos.discovery.server-addr=${nacos.url} + +# zookeeper配置 spring.cloud.zookeeper.connect-string=${zookeeper.url} -#spring.cloud.gateway.discovery.locator.lower-case-service-id=true -#spring.cloud.gateway.discovery.locator.enabled=true + spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull spring.datasource.username=${mysql.username} diff --git a/sop-gateway/src/main/resources/application-dev.yml b/sop-gateway/src/main/resources/application-dev.yml deleted file mode 100644 index 2df36ab4..00000000 --- a/sop-gateway/src/main/resources/application-dev.yml +++ /dev/null @@ -1,64 +0,0 @@ -server: - port: 8081 - -zuul: - # 入口地址,不用改,默认是/zuul - servlet-path: /api - # 禁用默认的过滤器,不能删,不用改 - FormBodyWrapperFilter: - pre: - disable: true - Servlet30WrapperFilter: - pre: - disable: true - # 不用改,如果要改,请全局替换修改 - secret: MZZOUSTua6LzApIWXCwEgbBmxSzpzC - -ribbon: - # https://blog.csdn.net/qq_36872046/article/details/81058045 - # 路由转发超时时间,毫秒,默认值1000,详见:RibbonClientConfiguration.DEFAULT_READ_TIMEOUT。 - # 如果微服务端 处理时间过长,会导致ribbon read超时,解决办法将这个值调大一点 - ReadTimeout: 2000 - # 设置为true(默认false),则所有请求都重试,默认只支持get请求重试 - # 请谨慎设置,因为post请求大多都是写入请求,如果要支持重试,确保服务的幂等性 - OkToRetryOnAllOperations: false - -# eureka注册中心,如果使用nacos注册中心,这里要注释掉 -#eureka: -# client: -# serviceUrl: -# defaultZone: http://localhost:1111/eureka/ - -spring: - application: - name: api-gateway - # zookeeper,根据实际情况修改 - cloud: - zookeeper: - connect-string: localhost:2181 - - # Spring Cloud Gateway配置,如果用了zuul,这段配置没有效果,不用改 - gateway: - discovery: - locator: - lower-case-service-id: true - enabled: true - - # nacos注册中心,和eureka只能用一个 - nacos: - discovery: - server-addr: 127.0.0.1:8848 - - # 数据源,根据实际情况修改 - datasource: - driver-class-name: com.mysql.jdbc.Driver - url: jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull - username: root - password: root - - # 上传文件配置,根据实际情况修改 - servlet: - multipart: - enabled: true - max-file-size: 20MB # 上传文件最大20MB,默认1MB - max-request-size: 20MB diff --git a/sop-gateway/src/main/resources/application.yml b/sop-gateway/src/main/resources/application.yml deleted file mode 100644 index caf4dfcd..00000000 --- a/sop-gateway/src/main/resources/application.yml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/sop-registry/src/main/resources/application-dev.yml b/sop-registry/src/main/resources/application-dev.yml deleted file mode 100644 index 41d0ffad..00000000 --- a/sop-registry/src/main/resources/application-dev.yml +++ /dev/null @@ -1,17 +0,0 @@ -eureka: - client: - fetch-registry: false - # 不注册自己 - register-with-eureka: false - serviceUrl: - defaultZone: http://${eureka.host}:${eureka.port}/eureka/ - # 注册中心地址 - host: localhost - port: 1111 - -server: - port: 1111 - -spring: - application: - name: sop-registry \ No newline at end of file diff --git a/sop-registry/src/main/resources/application.yml b/sop-registry/src/main/resources/application.yml deleted file mode 100644 index caf4dfcd..00000000 --- a/sop-registry/src/main/resources/application.yml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/sop-website/website-server/src/main/resources/application-dev.properties b/sop-website/website-server/src/main/resources/application-dev.properties index 4fa2eedf..80bc493b 100644 --- a/sop-website/website-server/src/main/resources/application-dev.properties +++ b/sop-website/website-server/src/main/resources/application-dev.properties @@ -17,7 +17,7 @@ registry.eureka-server-addr=${eureka.url} # nacos服务器地址 registry.nacos-server-addr=${nacos.url} # 使用eureka,填:eureka,使用nacos填:nacos -registry.name=eureka +registry.name=nacos spring.cloud.zookeeper.connect-string=${zookeeper.url} diff --git a/sop-website/website-server/src/main/resources/application-dev.yml b/sop-website/website-server/src/main/resources/application-dev.yml deleted file mode 100644 index 34fb17a3..00000000 --- a/sop-website/website-server/src/main/resources/application-dev.yml +++ /dev/null @@ -1,27 +0,0 @@ -server: - port: 8083 - -# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册 -registry: - eureka-server-addr: http://localhost:1111/eureka/ - # nacos服务器地址 - nacos-server-addr: 127.0.0.1:8848 - # 使用eureka,填:eureka,使用nacos填:nacos - name: nacos - -spring: - application: - name: website-server - - cloud: - zookeeper: - connect-string: localhost:2181 - -api: - # 测试地址 - url-test: http://api-test.yourdomain.com/api - # 沙箱环境 - url-sandbox: http://localhost:8081/api - # 正式地址 - url-prod: http://open.yourdomain.com/api - pwd: doc#123 \ No newline at end of file diff --git a/sop-website/website-server/src/main/resources/application.yml b/sop-website/website-server/src/main/resources/application.yml deleted file mode 100644 index caf4dfcd..00000000 --- a/sop-website/website-server/src/main/resources/application.yml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file From 3a2d591005d21a789375e8a6c88e4ac142a6d81f Mon Sep 17 00:00:00 2001 From: tanghc Date: Fri, 9 Aug 2019 17:08:47 +0800 Subject: [PATCH 05/82] =?UTF-8?q?admin=E6=9C=8D=E5=8A=A1=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E9=9D=A0=E5=89=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/service/serviceList.vue | 6 ++++-- .../service/impl/RegistryServiceNacos.java | 14 ++++++++++---- .../loadbalancer/EnvironmentServerChooser.java | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) 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 d4847174..225078a6 100644 --- a/sop-admin/sop-admin-vue/src/views/service/serviceList.vue +++ b/sop-admin/sop-admin-vue/src/views/service/serviceList.vue @@ -82,8 +82,10 @@ 开启预发布 开启灰度 - 禁用 - 启用 + + 禁用 + 启用 + 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 00b31d85..03c0614d 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 @@ -11,6 +11,7 @@ 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 lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.CollectionUtils; @@ -19,7 +20,6 @@ import javax.annotation.PostConstruct; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,6 +28,7 @@ import java.util.Map; * nacos接口实现, https://nacos.io/zh-cn/docs/open-api.html * @author tanghc */ +@Slf4j public class RegistryServiceNacos implements RegistryService { static HttpTool httpTool = new HttpTool(); @@ -72,7 +73,7 @@ public class RegistryServiceNacos implements RegistryService { } serviceInfoList.add(serviceInfo); } - serviceInfoList.sort(Comparator.comparingInt(o -> o.getInstances().size())); + serviceInfoList.sort((o1, o2) -> o2.getInstances().size() - o1.getInstances().size()); return serviceInfoList; } @@ -107,7 +108,10 @@ public class RegistryServiceNacos implements RegistryService { 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); + String response = httpTool.request("http://" + nacosAddr + "/nacos/v1/ns/instance", jsonObject, null, HttpTool.HTTPMethod.PUT); + if (!"ok".equalsIgnoreCase(response)) { + throw new RuntimeException(response); + } } /** @@ -122,6 +126,8 @@ public class RegistryServiceNacos implements RegistryService { 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); + Instance instance = JSON.parseObject(instanceJson, Instance.class); + instance.setServiceName(serviceInstance.getServiceId()); + return instance; } } 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 addf958c..fbd1f74a 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 @@ -5,7 +5,7 @@ import com.gitee.sop.gatewaycommon.bean.SpringContext; import com.gitee.sop.gatewaycommon.param.Param; import com.gitee.sop.gatewaycommon.zuul.loadbalancer.BaseServerChooser; import com.netflix.loadbalancer.Server; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; +import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer; import org.springframework.core.env.Environment; import javax.servlet.http.HttpServletRequest; @@ -41,7 +41,7 @@ public class EnvironmentServerChooser extends BaseServerChooser { private String getEnvValue(Server server) { // eureka存储的metadata - Map metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata(); + Map metadata = ((NacosServer) server).getMetadata(); return metadata.get(MEDATA_KEY_ENV); } From 219f9441627be25e303d0a37233beb1245b415f4 Mon Sep 17 00:00:00 2001 From: tanghc Date: Tue, 20 Aug 2019 19:17:23 +0800 Subject: [PATCH 06/82] =?UTF-8?q?=E5=85=A8=E9=9D=A2=E4=BD=BF=E7=94=A8nacos?= =?UTF-8?q?=EF=BC=8C=E8=88=8D=E5=BC=83zookeeper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-admin/sop-admin-server/pom.xml | 46 +-- .../gitee/sop/adminserver/api/isv/IsvApi.java | 18 +- .../api/service/IPBlacklistApi.java | 22 +- .../sop/adminserver/api/service/RouteApi.java | 55 ++- .../adminserver/api/service/ServiceApi.java | 71 ++-- .../sop/adminserver/bean/NacosConfigs.java | 29 ++ .../adminserver/bean/ZookeeperContext.java | 344 ---------------- .../common/ZookeeperOperationException.java | 26 -- .../common/ZookeeperPathExistException.java | 10 - .../ZookeeperPathNotExistException.java | 10 - .../sop/adminserver/config/WebConfig.java | 2 - .../service/ConfigPushService.java | 32 ++ .../service/RouteConfigService.java | 17 +- .../service/RoutePermissionService.java | 24 +- .../sop/adminserver/service/RouteService.java | 31 +- .../main/resources/application-dev.properties | 17 +- .../gitee/sop/adminserver/CuratorTest.java | 45 --- sop-common/pom.xml | 42 +- sop-common/sop-gateway-common/pom.xml | 9 +- .../bean/AbstractTargetRoute.java | 12 +- .../GatewayFilterDefinition.java | 2 +- .../bean/GatewayPredicateDefinition.java | 42 ++ .../bean/GatewayRouteDefinition.java | 72 ++++ .../sop/gatewaycommon/bean/NacosConfigs.java | 29 ++ .../gatewaycommon/bean/ServiceRouteInfo.java | 38 ++ .../sop/gatewaycommon/bean/TargetRoute.java | 6 +- .../BaseGatewayConfiguration.java | 8 +- .../route/GatewayPredicateDefinition.java | 17 - ...uteManager.java => GatewayRouteCache.java} | 32 +- .../gateway/route/GatewayRouteDefinition.java | 21 - .../gateway/route/GatewayRouteRepository.java | 1 + .../route/GatewayServiceRouteInfo.java | 9 - .../gateway/route/GatewayTargetRoute.java | 9 +- .../manager/AbstractConfiguration.java | 31 +- .../gatewaycommon/manager/BaseRouteCache.java | 62 +++ .../manager/BaseRouteManager.java | 220 ---------- .../gatewaycommon/manager/ManagerContext.java | 24 -- .../gatewaycommon/manager/RouteLoader.java | 12 + .../gatewaycommon/manager/RouteManager.java | 1 + .../manager/RoutePermissionManager.java | 20 - .../manager/ServiceRoutesLoader.java | 118 ++++++ .../manager/ZookeeperContext.java | 252 ------------ .../gatewaycommon/param/BaseParamBuilder.java | 4 +- .../result/BaseExecutorAdapter.java | 14 +- .../gatewaycommon/validate/ApiValidator.java | 4 +- .../configuration/BaseZuulConfiguration.java | 15 +- .../zuul/filter/PreRoutePermissionFilter.java | 54 --- .../zuul/route/ZuulRouteCache.java | 34 ++ .../zuul/route/ZuulRouteDefinition.java | 13 - .../zuul/route/ZuulServiceRouteInfo.java | 9 - .../zuul/route/ZuulTargetRoute.java | 8 +- .../zuul/route/ZuulZookeeperRouteManager.java | 40 -- sop-common/sop-registry-api/pom.xml | 2 +- .../service/impl/RegistryServiceNacos.java | 2 +- sop-common/sop-service-common/pom.xml | 5 + .../sop/servercommon/bean/ZookeeperTool.java | 138 ------- .../BaseServiceConfiguration.java | 26 +- .../EasyopenServiceConfiguration.java | 6 - .../SpringMvcServiceConfiguration.java | 21 - .../ZookeeperOperationException.java | 26 -- .../ZookeeperPathNotExistException.java | 10 - .../servercommon/manager/ApiMetaBuilder.java | 100 +++++ .../manager/DefaultRequestMappingEvent.java | 89 +--- .../manager/ServiceRouteController.java | 46 +++ .../manager/ServiceRouteInfoBuilder.java | 150 +++++++ .../ServiceZookeeperApiMetaManager.java | 271 ------------- .../swagger/SwaggerValidator.java | 12 +- .../gitee/sop/servercommon/util/OpenUtil.java | 11 + sop-example/sop-story/sop-story-web/pom.xml | 16 + sop-gateway/pom.xml | 20 +- .../sop/gateway/manager/DbEnvGrayManager.java | 35 +- .../gateway/manager/DbIPBlacklistManager.java | 31 +- .../sop/gateway/manager/DbIsvManager.java | 30 +- .../manager/DbIsvRoutePermissionManager.java | 40 +- .../gateway/manager/DbLimitConfigManager.java | 30 +- .../gateway/manager/DbRouteConfigManager.java | 36 +- .../gateway/manager/ManagerInitializer.java | 19 - .../main/resources/application-dev.properties | 2 +- .../src/main/resources/bootstrap.properties | 3 + .../com/gitee/sop/gateway/CuratorTest.java | 52 --- sop-website/website-server/pom.xml | 63 +-- .../sop/websiteserver/bean/HttpTool.java | 381 ++++++++++++++++++ .../websiteserver/bean/ZookeeperContext.java | 179 -------- .../websiteserver/config/RegistryConfig.java | 12 - .../websiteserver/config/WebsiteConfig.java | 2 +- .../controller/DocController.java | 11 - .../controller/SandboxController.java | 9 +- .../websiteserver/manager/DocDiscovery.java | 99 +++++ .../sop/websiteserver/manager/DocManager.java | 4 +- .../websiteserver/manager/DocManagerImpl.java | 244 ++--------- .../main/resources/application-dev.properties | 14 +- 91 files changed, 1775 insertions(+), 2555 deletions(-) create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/NacosConfigs.java delete mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java delete mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperOperationException.java delete mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathExistException.java delete mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathNotExistException.java create mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/ConfigPushService.java delete mode 100644 sop-admin/sop-admin-server/src/test/java/com/gitee/sop/adminserver/CuratorTest.java rename sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/{gateway/route => bean}/GatewayFilterDefinition.java (84%) create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayPredicateDefinition.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayRouteDefinition.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/NacosConfigs.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceRouteInfo.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayPredicateDefinition.java rename sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/{GatewayZookeeperRouteManager.java => GatewayRouteCache.java} (73%) delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteDefinition.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayServiceRouteInfo.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteCache.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteLoader.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RoutePermissionManager.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ZookeeperContext.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteCache.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteDefinition.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulServiceRouteInfo.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java delete mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ZookeeperTool.java delete mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperOperationException.java delete mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperPathNotExistException.java create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java delete mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java delete mode 100644 sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java create mode 100644 sop-gateway/src/main/resources/bootstrap.properties delete mode 100644 sop-gateway/src/test/java/com/gitee/sop/gateway/CuratorTest.java create mode 100644 sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java delete mode 100644 sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/ZookeeperContext.java delete mode 100644 sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/RegistryConfig.java create mode 100644 sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocDiscovery.java diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index 5b5fb943..0b4436af 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -27,6 +27,17 @@ + + com.alibaba.boot + nacos-config-spring-boot-starter + 0.2.2 + + + com.alibaba.boot + nacos-discovery-spring-boot-starter + 0.2.2 + + com.gitee.sop sop-registry-api @@ -45,39 +56,13 @@ fastmybatis-spring-boot-starter 1.8.1 + mysql mysql-connector-java runtime - - - org.apache.curator - curator-recipes - ${curator-recipes.version} - - - org.apache.zookeeper - zookeeper - - - - - org.apache.zookeeper - zookeeper - ${zookeeper.version} - - - org.slf4j - slf4j-log4j12 - - - - org.springframework.boot spring-boot-starter-web @@ -122,5 +107,12 @@ + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + 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 bd4b6d25..b96a48db 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 @@ -1,6 +1,5 @@ package com.gitee.sop.adminserver.api.isv; -import com.alibaba.fastjson.JSON; import com.gitee.easyopen.annotation.Api; import com.gitee.easyopen.annotation.ApiService; import com.gitee.easyopen.doc.DataType; @@ -24,12 +23,11 @@ import com.gitee.sop.adminserver.api.isv.result.IsvKeysGenVO; import com.gitee.sop.adminserver.api.isv.result.IsvKeysVO; 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.bean.NacosConfigs; 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; import com.gitee.sop.adminserver.entity.IsvInfo; import com.gitee.sop.adminserver.entity.IsvKeys; import com.gitee.sop.adminserver.entity.PermIsvRole; @@ -38,6 +36,7 @@ import com.gitee.sop.adminserver.mapper.IsvInfoMapper; import com.gitee.sop.adminserver.mapper.IsvKeysMapper; import com.gitee.sop.adminserver.mapper.PermIsvRoleMapper; import com.gitee.sop.adminserver.mapper.PermRoleMapper; +import com.gitee.sop.adminserver.service.ConfigPushService; import com.gitee.sop.adminserver.service.RoutePermissionService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -86,6 +85,9 @@ public class IsvApi { @Autowired RoutePermissionService routePermissionService; + @Autowired + private ConfigPushService configPushService; + @Value("${sop.sign-type}") private String sopSignType; @@ -231,15 +233,7 @@ public class IsvApi { return; } ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.ISV_INFO_UPDATE, isvDetail); - String path = ZookeeperContext.getIsvInfoChannelPath(); - String data = JSON.toJSONString(channelMsg); - try { - log.info("消息推送--ISV信息(update), path:{}, data:{}", path, data); - ZookeeperContext.updatePathData(path, data); - } catch (ZookeeperPathNotExistException e) { - log.error("发送isvChannelMsg失败, path:{}, msg:{}", path, data, e); - throw new BizException("路径不存在"); - } + configPushService.publishConfig(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, channelMsg); } private IsvKeysGenVO createIsvKeys() throws Exception { 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 4bb78936..44b3de1d 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 @@ -1,6 +1,5 @@ package com.gitee.sop.adminserver.api.service; -import com.alibaba.fastjson.JSON; import com.gitee.easyopen.annotation.Api; import com.gitee.easyopen.annotation.ApiService; import com.gitee.easyopen.doc.annotation.ApiDoc; @@ -14,11 +13,12 @@ import com.gitee.sop.adminserver.api.service.param.ConfigIpBlackForm; import com.gitee.sop.adminserver.api.service.param.ConfigIpBlacklistPageParam; 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.bean.NacosConfigs; 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 com.gitee.sop.adminserver.service.ConfigPushService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -33,6 +33,9 @@ public class IPBlacklistApi { @Autowired ConfigIpBlacklistMapper configIpBlacklistMapper; + @Autowired + private ConfigPushService configPushService; + @ApiDocMethod(description = "获取IP黑名单,分页") @Api(name = "ip.blacklist.page") PageEasyui page(ConfigIpBlacklistPageParam form) { @@ -85,20 +88,7 @@ public class IPBlacklistApi { 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:{}",channelOperation.getOperation(), path, jsonData); - ZookeeperContext.createOrUpdateData(path, jsonData); + configPushService.publishConfig(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, channelMsg); } - enum BlacklistMsgType { - /** - * 黑名单消息类型:添加 - */ - ADD, - /** - * 黑名单消息类型:删除 - */ - DELETE - } } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java index 8b582df2..a79d8704 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java @@ -1,6 +1,5 @@ package com.gitee.sop.adminserver.api.service; -import com.alibaba.fastjson.JSON; import com.gitee.easyopen.annotation.Api; import com.gitee.easyopen.annotation.ApiService; import com.gitee.easyopen.doc.annotation.ApiDoc; @@ -15,10 +14,7 @@ import com.gitee.sop.adminserver.api.service.param.RouteUpdateParam; import com.gitee.sop.adminserver.api.service.result.RouteVO; import com.gitee.sop.adminserver.bean.GatewayRouteDefinition; import com.gitee.sop.adminserver.bean.RouteConfigDto; -import com.gitee.sop.adminserver.bean.ZookeeperContext; import com.gitee.sop.adminserver.common.BizException; -import com.gitee.sop.adminserver.common.ZookeeperPathExistException; -import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException; import com.gitee.sop.adminserver.entity.ConfigRouteBase; import com.gitee.sop.adminserver.entity.PermRole; import com.gitee.sop.adminserver.mapper.ConfigRouteBaseMapper; @@ -28,7 +24,6 @@ import com.gitee.sop.adminserver.service.RouteConfigService; import com.gitee.sop.adminserver.service.RoutePermissionService; import com.gitee.sop.adminserver.service.RouteService; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -71,6 +66,10 @@ public class RouteApi { RouteVO vo = new RouteVO(); BeanUtils.copyProperties(gatewayRouteDefinition, vo); vo.setRoles(this.getRouteRole(gatewayRouteDefinition.getId())); + ConfigRouteBase configRouteBase = configRouteBaseMapper.getByColumn("route_id", gatewayRouteDefinition.getId()); + if (configRouteBase != null) { + vo.setStatus(configRouteBase.getStatus()); + } return vo; }) .collect(Collectors.toList()); @@ -96,54 +95,48 @@ public class RouteApi { @Api(name = "route.add") @ApiDocMethod(description = "新增路由") void addRoute(RouteAddParam param) { + // TODO:新增路由 String id = param.getName() + param.getVersion(); - String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), id); +// String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), id); GatewayRouteDefinition routeDefinition = new GatewayRouteDefinition(); CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition); routeDefinition.setId(id); routeDefinition.setCustom(1); - try { - ZookeeperContext.addPath(routePath, JSON.toJSONString(routeDefinition)); - } catch (ZookeeperPathExistException e) { - throw new BizException("路由已存在"); - } +// try { +// ZookeeperContext.addPath(routePath, JSON.toJSONString(routeDefinition)); +// } catch (ZookeeperPathExistException e) { +// throw new BizException("路由已存在"); +// } this.updateRouteConfig(routeDefinition); } @Api(name = "route.update") @ApiDocMethod(description = "修改路由") void updateRoute(RouteUpdateParam param) { - String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId()); - GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath); - CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition); - try { - ZookeeperContext.updatePathData(routePath, JSON.toJSONString(routeDefinition)); - } catch (ZookeeperPathNotExistException e) { - throw new BizException("路由不存在"); - } - this.updateRouteConfig(routeDefinition); + // TODO:修改路由 +// String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId()); +// GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath); +// CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition); +// try { +// ZookeeperContext.updatePathData(routePath, JSON.toJSONString(routeDefinition)); +// } catch (ZookeeperPathNotExistException e) { +// throw new BizException("路由不存在"); +// } +// this.updateRouteConfig(routeDefinition); } @Api(name = "route.del") @ApiDocMethod(description = "删除路由") void delRoute(RouteDeleteParam param) { - String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId()); + // TODO:删除路由 + /*String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId()); GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath); if (!BooleanUtils.toBoolean(routeDefinition.getCustom())) { throw new BizException("非自定义路由,无法删除"); } - ZookeeperContext.deletePathDeep(routePath); + ZookeeperContext.deletePathDeep(routePath);*/ } - private GatewayRouteDefinition getGatewayRouteDefinition(String zookeeperRoutePath) { - String data = null; - try { - data = ZookeeperContext.getData(zookeeperRoutePath); - } catch (ZookeeperPathNotExistException e) { - throw new BizException("路由不存在"); - } - return JSON.parseObject(data, GatewayRouteDefinition.class); - } private void updateRouteConfig(GatewayRouteDefinition routeDefinition) { try { 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 82e9999b..b30348aa 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 @@ -1,6 +1,8 @@ package com.gitee.sop.adminserver.api.service; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.annotation.NacosInjected; +import com.alibaba.nacos.api.naming.NamingService; import com.gitee.easyopen.annotation.Api; import com.gitee.easyopen.annotation.ApiService; import com.gitee.easyopen.doc.annotation.ApiDoc; @@ -15,27 +17,26 @@ 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.NacosConfigs; import com.gitee.sop.adminserver.bean.ServiceGrayDefinition; import com.gitee.sop.adminserver.bean.ServiceRouteInfo; -import com.gitee.sop.adminserver.bean.ZookeeperContext; import com.gitee.sop.adminserver.common.BizException; import com.gitee.sop.adminserver.common.ChannelOperation; import com.gitee.sop.adminserver.common.StatusEnum; -import com.gitee.sop.adminserver.common.ZookeeperPathExistException; -import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException; import com.gitee.sop.adminserver.entity.ConfigGray; import com.gitee.sop.adminserver.entity.ConfigGrayInstance; import com.gitee.sop.adminserver.mapper.ConfigGrayInstanceMapper; import com.gitee.sop.adminserver.mapper.ConfigGrayMapper; +import com.gitee.sop.adminserver.service.ConfigPushService; import com.gitee.sop.registryapi.bean.ServiceInfo; import com.gitee.sop.registryapi.bean.ServiceInstance; import com.gitee.sop.registryapi.service.RegistryService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; -import org.apache.curator.framework.recipes.cache.ChildData; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; import java.io.IOException; import java.util.ArrayList; @@ -63,35 +64,54 @@ public class ServiceApi { @Autowired private ConfigGrayInstanceMapper configGrayInstanceMapper; + @Autowired + private ConfigPushService configPushService; + + @NacosInjected + private NamingService namingService; + @Api(name = "zookeeper.service.list") @ApiDocMethod(description = "zk中的服务列表", elementClass = RouteServiceInfo.class) List listServiceInfo(ServiceSearchParam param) { - String routeRootPath = ZookeeperContext.getSopRouteRootPath(); - List childDataList = ZookeeperContext.getChildrenData(routeRootPath); - List serviceInfoList = childDataList.stream() - .filter(childData -> childData.getData() != null && childData.getData().length > 0) - .map(childData -> { - String serviceNodeData = new String(childData.getData()); - RouteServiceInfo serviceInfo = JSON.parseObject(serviceNodeData, RouteServiceInfo.class); - return serviceInfo; - }) + List servicesOfServer = null; + try { + servicesOfServer = registryService.listAllService(1, Integer.MAX_VALUE); + } catch (Exception e) { + log.error("nacos获取服务列表失败", e); + throw new BizException("获取服务列表失败"); + } + + return servicesOfServer + .stream() .filter(serviceInfo -> { + String serviceId = serviceInfo.getServiceId(); + if ("api-gateway".equalsIgnoreCase(serviceId)) { + return false; + } + // 隐藏空服务 + if (CollectionUtils.isEmpty(serviceInfo.getInstances())) { + return false; + } if (StringUtils.isBlank(param.getServiceId())) { return true; } else { - return serviceInfo.getServiceId().contains(param.getServiceId()); + return serviceId.contains(param.getServiceId()); } }) + .map(serviceInfo -> { + RouteServiceInfo routeServiceInfo = new RouteServiceInfo(); + routeServiceInfo.setServiceId(serviceInfo.getServiceId()); + return routeServiceInfo; + }) .collect(Collectors.toList()); - - return serviceInfoList; } @Api(name = "service.custom.add") @ApiDocMethod(description = "添加服务") void addService(ServiceAddParam param) { + // TODO:添加服务 String serviceId = param.getServiceId(); - String servicePath = ZookeeperContext.buildServiceIdPath(serviceId); +// String servicePath = ZookeeperContext.buildServiceIdPath(serviceId); ServiceRouteInfo serviceRouteInfo = new ServiceRouteInfo(); Date now = new Date(); serviceRouteInfo.setServiceId(serviceId); @@ -100,17 +120,19 @@ public class ServiceApi { serviceRouteInfo.setUpdateTime(now); serviceRouteInfo.setCustom(BooleanUtils.toInteger(true)); String serviceData = JSON.toJSONString(serviceRouteInfo); - try { + + /* try { ZookeeperContext.addPath(servicePath, serviceData); } catch (ZookeeperPathExistException e) { throw new BizException("服务已存在"); - } + }*/ } @Api(name = "service.custom.del") @ApiDocMethod(description = "删除自定义服务") void delService(ServiceSearchParam param) { - String serviceId = param.getServiceId(); + // TODO:删除自定义服务 + /*String serviceId = param.getServiceId(); String servicePath = ZookeeperContext.buildServiceIdPath(serviceId); String data = null; try { @@ -126,7 +148,7 @@ public class ServiceApi { if (!BooleanUtils.toBoolean(custom)) { throw new BizException("非自定义服务,无法删除"); } - ZookeeperContext.deletePathDeep(servicePath); + ZookeeperContext.deletePathDeep(servicePath);*/ } @Api(name = "service.instance.list") @@ -134,7 +156,7 @@ public class ServiceApi { List listService(ServiceSearchParam param) { List serviceInfos; try { - serviceInfos = registryService.listAllService(1, 99999); + serviceInfos = registryService.listAllService(1, Integer.MAX_VALUE); } catch (Exception e) { log.error("获取服务实例失败", e); return Collections.emptyList(); @@ -293,10 +315,7 @@ public class ServiceApi { serviceGrayDefinition.setInstanceId(instanceId); serviceGrayDefinition.setServiceId(serviceId); ChannelMsg channelMsg = new ChannelMsg(channelOperation, serviceGrayDefinition); - String jsonData = JSON.toJSONString(channelMsg); - String path = ZookeeperContext.getServiceGrayChannelPath(); - log.info("消息推送--灰度发布({}), path:{}, data:{}", channelOperation.getOperation(), path, jsonData); - ZookeeperContext.createOrUpdateData(path, jsonData); + configPushService.publishConfig(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, channelMsg); } private ConfigGray getConfigGray(String serviceId) { diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/NacosConfigs.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/NacosConfigs.java new file mode 100644 index 00000000..4110e8e8 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/NacosConfigs.java @@ -0,0 +1,29 @@ +package com.gitee.sop.adminserver.bean; + +/** + * @author tanghc + */ +public class NacosConfigs { + + public static final String GROUP_CHANNEL = "sop:channel"; + + public static final String GROUP_ROUTE = "sop:route"; + + public static final String DATA_ID_GRAY = "com.gitee.sop.channel.gray"; + + public static final String DATA_ID_IP_BLACKLIST = "com.gitee.sop.channel.ipblacklist"; + + public static final String DATA_ID_ISV = "com.gitee.sop.channel.isv"; + + public static final String DATA_ID_ROUTE_PERMISSION = "com.gitee.sop.channel.routepermission"; + + public static final String DATA_ID_LIMIT_CONFIG = "com.gitee.sop.channel.limitconfig"; + + public static final String DATA_ID_ROUTE_CONFIG = "com.gitee.sop.channel.routeconfig"; + + private static final String DATA_ID_TPL = "com.gitee.sop.route.%s"; + + public static String getRouteDataId(String serviceId) { + return String.format(DATA_ID_TPL, serviceId); + } +} 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 deleted file mode 100644 index 76f814b3..00000000 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ZookeeperContext.java +++ /dev/null @@ -1,344 +0,0 @@ -package com.gitee.sop.adminserver.bean; - -import com.gitee.sop.adminserver.common.ZookeeperOperationException; -import com.gitee.sop.adminserver.common.ZookeeperPathExistException; -import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.NodeCache; -import org.apache.curator.framework.recipes.cache.NodeCacheListener; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.data.Stat; -import org.springframework.core.env.Environment; -import org.springframework.util.Assert; - -import java.io.Closeable; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Executors; - -import static com.gitee.sop.adminserver.bean.SopAdminConstants.SOP_MSG_CHANNEL_PATH; - -/** - * @author tanghc - */ -@Slf4j -public class ZookeeperContext { - - private static CuratorFramework client; - - private static Environment environment; - - public static void setEnvironment(Environment environment) { - Assert.notNull(environment, "environment不能为null"); - ZookeeperContext.environment = environment; - initZookeeperClient(); - } - - public synchronized static void initZookeeperClient() { - if (client != null) { - return; - } - setClient(createClient()); - } - - public static CuratorFramework createClient() { - String zookeeperServerAddr = environment.getProperty("spring.cloud.zookeeper.connect-string"); - if (StringUtils.isBlank(zookeeperServerAddr)) { - throw new RuntimeException("未指定spring.cloud.zookeeper.connect-string参数"); - } - String baseSleepTimeMs = environment.getProperty("spring.cloud.zookeeper.baseSleepTimeMs"); - String maxRetries = environment.getProperty("spring.cloud.zookeeper.maxRetries"); - log.info("初始化zookeeper客户端,zookeeperServerAddr:{}, baseSleepTimeMs:{}, maxRetries:{}", - zookeeperServerAddr, baseSleepTimeMs, maxRetries); - CuratorFramework client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(NumberUtils.toInt(baseSleepTimeMs, 3000), NumberUtils.toInt(maxRetries, 3))) - .build(); - - client.start(); - return client; - } - - public static String getSopRouteRootPath() { - return SopAdminConstants.SOP_SERVICE_ROUTE_PATH; - } - - public static String buildServiceIdPath(String serviceId) { - if (StringUtils.isBlank(serviceId)) { - throw new NullPointerException("serviceId不能为空"); - } - return getSopRouteRootPath() + "/" + serviceId; - } - - public static String buildRoutePath(String serviceId, String routeId) { - if (StringUtils.isBlank(serviceId)) { - throw new NullPointerException("serviceId不能为空"); - } - if (StringUtils.isBlank(routeId)) { - throw new NullPointerException("routeId不能为空"); - } - String serviceIdPath = getSopRouteRootPath() + "/" + serviceId; - return serviceIdPath + "/" + routeId; - } - - public static String getServiceGrayChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/gray"; - } - - public static String getIsvInfoChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/isvinfo"; - } - - public static String getIsvRoutePermissionChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/isv-route-permission"; - } - - public static String getRouteConfigChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/route-conf"; - } - - public static String getLimitConfigChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/limit-conf"; - } - - public static String getIpBlacklistChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/ipblacklist-conf"; - } - - public static CuratorFramework getClient() { - return client; - } - - public static void setClient(CuratorFramework client) { - ZookeeperContext.client = client; - } - - public static boolean isPathExist(String path) { - try { - return client.checkExists().forPath(path) != null; - } catch (Exception e) { - return false; - } - } - - /** - * 对已存在的path赋值。如果path不存在抛异常 - * - * @param path 已存在的 - * @param data 数据 - * @return - * @throws ZookeeperPathNotExistException - */ - public static Stat updatePathData(String path, String data) throws ZookeeperPathNotExistException { - if (!isPathExist(path)) { - throw new ZookeeperPathNotExistException("path " + path + " 不存在"); - } - try { - return getClient().setData().forPath(path, data.getBytes()); - } catch (Exception e) { - throw new ZookeeperOperationException("updatePathData error, path=" + path, e); - } - } - - /** - * 创建新的path,并赋值。如果path已存在抛异常 - * - * @param path 待创建的path - * @param data 值 - * @throws ZookeeperPathExistException - */ - public static String addPath(String path, String data) throws ZookeeperPathExistException { - if (isPathExist(path)) { - throw new ZookeeperPathExistException("path " + path + " 已存在"); - } - try { - return addPath(path, CreateMode.PERSISTENT, data); - } catch (Exception e) { - throw new ZookeeperOperationException("addPath error path=" + path, e); - } - } - - /** - * 添加节点 - * - * @param path 待创建的path - * @param createMode 节点类型 - * @param data 节点数据 - * @return - */ - public static String addPath(String path, CreateMode createMode, String data) { - try { - return getClient().create() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .withMode(createMode) - .forPath(path, data.getBytes()); - } catch (Exception e) { - throw new ZookeeperOperationException("addPath error path=" + path, e); - } - } - - /** - * 删除节点及子节点 - * - * @param path - */ - public static void deletePathDeep(String path) { - try { - getClient().delete() - .deletingChildrenIfNeeded() - .forPath(path); - } catch (Exception e) { - } - } - - - /** - * 创建新的path,并赋值。如果path已存在则不创建 - * - * @param path 待创建的path - * @param data 值 - */ - public static String addPathQuietly(String path, String data) { - if (isPathExist(path)) { - return path; - } - try { - return addPath(path, data); - } catch (Exception e) { - throw new ZookeeperOperationException("addPathQuietly error path=" + path, e); - } - } - - /** - * 新建或保存节点 - * - * @param path - * @param data - * @return - */ - public static String createOrUpdateData(String path, String data) { - try { - return getClient().create() - // 如果节点存在则Curator将会使用给出的数据设置这个节点的值 - .orSetData() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .forPath(path, data.getBytes()); - } catch (Exception e) { - throw new ZookeeperOperationException("createOrUpdateData error path=" + path, e); - } - } - - /** - * 获取节点内容 - * - * @param path - * @return - * @throws ZookeeperPathNotExistException - */ - public static String getData(String path) throws ZookeeperPathNotExistException { - if (!isPathExist(path)) { - throw new ZookeeperPathNotExistException("path 不存在, path=" + path); - } - try { - byte[] data = getClient().getData().forPath(path); - return new String(data); - } catch (Exception e) { - throw new ZookeeperOperationException("getData error path=" + path, e); - } - } - - /** - * 获取子节点数据 - * - * @param parentPath 父节点 - * @return - */ - public static List getChildrenData(String parentPath) { - PathChildrenCache pathChildrenCache = buildPathChildrenCache(parentPath); - if (pathChildrenCache == null) { - return Collections.emptyList(); - } - return pathChildrenCache.getCurrentData(); - } - - public static PathChildrenCache buildPathChildrenCache(String path) { - if (!isPathExist(path)) { - return null; - } - // PathChildrenCache: 监听数据节点的增删改,可以设置触发的事件 - // 且第三个参数要设置为true,不然ChildData对象中的getData返回null - PathChildrenCache childrenCache = new PathChildrenCache(client, path, true); - // 列出子节点数据列表,需要使用BUILD_INITIAL_CACHE同步初始化模式才能获得,异步是获取不到的 - try { - childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); - } catch (Exception e) { - throw new ZookeeperOperationException("buildPathChildrenCache error path=" + path, e); - } - return childrenCache; - } - - /** - * 监听一个临时节点 - * - * @param path - * @param listenCallback 回调 - * @return 返回path - * @throws Exception - */ - public static void listenTempPath(String path, ListenCallback listenCallback) throws Exception { - String initData = "{}"; - CuratorFramework client = createClient(); - client.create() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .withMode(CreateMode.EPHEMERAL) - .forPath(path, initData.getBytes()); - - final NodeCache cache = new NodeCache(client, path, false); - cache.getListenable().addListener(new NodeCacheListener() { - @Override - public void nodeChanged() throws Exception { - byte[] nodeData = cache.getCurrentData().getData(); - String data = new String(nodeData); - if (StringUtils.isNotBlank(data) && !initData.equals(data)) { - listenCallback.onError(data); - Executors.newSingleThreadExecutor().execute(() -> new ZKClose(cache, client)); - } - } - }); - cache.start(); - } - - public interface ListenCallback { - void onError(String errorMsg); - } - - static class ZKClose implements Runnable { - Closeable[] closes; - - public ZKClose(Closeable ...closes) { - this.closes = closes; - } - - @Override - public void run() { - try { - Thread.sleep(2000); - IOUtils.closeQuietly(closes); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - -} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperOperationException.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperOperationException.java deleted file mode 100644 index d75f35df..00000000 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperOperationException.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.gitee.sop.adminserver.common; - -/** - * @author tanghc - */ -public class ZookeeperOperationException extends RuntimeException { - - public ZookeeperOperationException() { - } - - public ZookeeperOperationException(String message) { - super(message); - } - - public ZookeeperOperationException(String message, Throwable cause) { - super(message, cause); - } - - public ZookeeperOperationException(Throwable cause) { - super(cause); - } - - public ZookeeperOperationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathExistException.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathExistException.java deleted file mode 100644 index 4ec2e104..00000000 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathExistException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.sop.adminserver.common; - -/** - * @author tanghc - */ -public class ZookeeperPathExistException extends Exception { - public ZookeeperPathExistException(String message) { - super(message); - } -} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathNotExistException.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathNotExistException.java deleted file mode 100644 index bf690146..00000000 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/ZookeeperPathNotExistException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.sop.adminserver.common; - -/** - * @author tanghc - */ -public class ZookeeperPathNotExistException extends Exception { - public ZookeeperPathNotExistException(String message) { - super(message); - } -} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java index 7a157171..549a6223 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java @@ -8,7 +8,6 @@ import com.gitee.easyopen.ApiParamParser; import com.gitee.easyopen.ParamNames; import com.gitee.easyopen.interceptor.ApiInterceptor; import com.gitee.easyopen.session.ApiSessionManager; -import com.gitee.sop.adminserver.bean.ZookeeperContext; import com.gitee.sop.adminserver.interceptor.LoginInterceptor; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; @@ -68,7 +67,6 @@ public class WebConfig { @PostConstruct public void after() { - ZookeeperContext.setEnvironment(environment); } } \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/ConfigPushService.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/ConfigPushService.java new file mode 100644 index 00000000..10e3eefc --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/ConfigPushService.java @@ -0,0 +1,32 @@ +package com.gitee.sop.adminserver.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.annotation.NacosInjected; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; +import com.gitee.sop.adminserver.bean.ChannelMsg; +import com.gitee.sop.adminserver.common.BizException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * @author tanghc + */ +@Slf4j +@Service +public class ConfigPushService { + + @NacosInjected + private ConfigService configService; + + public void publishConfig(String dataId, String groupId, ChannelMsg channelMsg) { + try { + log.info("nacos配置, dataId:{}, groupId:{}, operation:{}", dataId, groupId, channelMsg.getOperation()); + configService.publishConfig(dataId, groupId, JSON.toJSONString(channelMsg)); + } catch (NacosException e) { + log.error("nacos配置失败, dataId:{}, groupId:{}, operation:{}", dataId, groupId, channelMsg.getOperation(), e); + throw new BizException("nacos配置失败"); + } + } + +} 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 d1dd2ceb..2ad3ba35 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 @@ -1,12 +1,12 @@ package com.gitee.sop.adminserver.service; -import com.alibaba.fastjson.JSON; import com.gitee.sop.adminserver.bean.ChannelMsg; import com.gitee.sop.adminserver.bean.ConfigLimitDto; +import com.gitee.sop.adminserver.bean.NacosConfigs; 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.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -16,6 +16,9 @@ import org.springframework.stereotype.Service; @Slf4j public class RouteConfigService { + @Autowired + private ConfigPushService configPushService; + /** * 发送路由配置消息 * @param routeConfigDto @@ -23,10 +26,7 @@ public class RouteConfigService { */ public void sendRouteConfigMsg(RouteConfigDto routeConfigDto) { 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); - ZookeeperContext.createOrUpdateData(path, jsonData); + configPushService.publishConfig(NacosConfigs.DATA_ID_ROUTE_CONFIG, NacosConfigs.GROUP_CHANNEL, channelMsg); } /** @@ -36,9 +36,6 @@ public class RouteConfigService { */ public void sendLimitConfigMsg(ConfigLimitDto routeConfigDto) throws Exception { 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); - ZookeeperContext.createOrUpdateData(path, jsonData); + configPushService.publishConfig(NacosConfigs.DATA_ID_LIMIT_CONFIG, NacosConfigs.GROUP_CHANNEL, channelMsg); } } 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 3595d88f..181f37e3 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 @@ -5,8 +5,7 @@ import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.adminserver.api.service.param.RoutePermissionParam; 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.bean.NacosConfigs; import com.gitee.sop.adminserver.common.ChannelOperation; import com.gitee.sop.adminserver.entity.PermIsvRole; import com.gitee.sop.adminserver.entity.PermRolePermission; @@ -42,6 +41,9 @@ public class RoutePermissionService { @Autowired PermRolePermissionMapper permRolePermissionMapper; + @Autowired + private ConfigPushService configPushService; + /** * 获取客户端角色码列表 * @@ -70,10 +72,8 @@ public class RoutePermissionService { isvRoutePermission.setRouteIdList(routeIdList); isvRoutePermission.setRouteIdListMd5(roleCodeListMd5); 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); - ZookeeperContext.createOrUpdateData(path, jsonData); + configPushService.publishConfig(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, channelMsg); + } /** @@ -98,19 +98,9 @@ public class RoutePermissionService { * 推送所有路由权限到zookeeper */ public void sendRoutePermissionReloadMsg(RoutePermissionParam oldRoutePermission) throws Exception { - String listenPath = SopAdminConstants.RELOAD_ROUTE_PERMISSION_PATH + "/" + System.currentTimeMillis(); - ZookeeperContext.listenTempPath(listenPath, errorMsg -> { - log.error("推送所有路由权限到zookeeper失败,进行回滚,errorMsg: {},oldRoutePermission:{}", errorMsg, JSON.toJSONString(oldRoutePermission)); - // 回滚 - updateRoutePermission(oldRoutePermission); - }); IsvRoutePermission isvRoutePermission = new IsvRoutePermission(); - isvRoutePermission.setListenPath(listenPath); 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); - ZookeeperContext.createOrUpdateData(path, jsonData); + configPushService.publishConfig(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, channelMsg); } /** diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteService.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteService.java index b3fe1670..9de5e76e 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteService.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RouteService.java @@ -1,11 +1,13 @@ package com.gitee.sop.adminserver.service; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.annotation.NacosInjected; +import com.alibaba.nacos.api.config.ConfigService; import com.gitee.sop.adminserver.api.service.param.RouteSearchParam; import com.gitee.sop.adminserver.bean.GatewayRouteDefinition; -import com.gitee.sop.adminserver.bean.ZookeeperContext; +import com.gitee.sop.adminserver.bean.NacosConfigs; +import com.gitee.sop.adminserver.bean.ServiceRouteInfo; import org.apache.commons.lang.StringUtils; -import org.apache.curator.framework.recipes.cache.ChildData; import org.springframework.stereotype.Service; import java.util.Collections; @@ -19,21 +21,22 @@ import static java.util.stream.Collectors.toList; @Service public class RouteService { + @NacosInjected + private ConfigService configService; + public List getRouteDefinitionList(RouteSearchParam param) throws Exception { - if (StringUtils.isBlank(param.getServiceId())) { + String serviceId = param.getServiceId(); + if (StringUtils.isBlank(serviceId)) { return Collections.emptyList(); } + String configData = configService.getConfig(NacosConfigs.getRouteDataId(serviceId), NacosConfigs.GROUP_ROUTE, 3000); + if (StringUtils.isBlank(configData)) { + return Collections.emptyList(); + } + ServiceRouteInfo serviceRouteInfo = JSON.parseObject(configData, ServiceRouteInfo.class); - String searchPath = ZookeeperContext.getSopRouteRootPath() + "/" + param.getServiceId(); - - List childDataList = ZookeeperContext.getChildrenData(searchPath); - - List routeDefinitionStream = childDataList.stream() - .map(childData -> { - String serviceNodeData = new String(childData.getData()); - GatewayRouteDefinition routeDefinition = JSON.parseObject(serviceNodeData, GatewayRouteDefinition.class); - return routeDefinition; - }) + return serviceRouteInfo.getRouteDefinitionList() + .stream() .filter(gatewayRouteDefinition -> { boolean isRoute = gatewayRouteDefinition.getOrder() != Integer.MIN_VALUE; String id = param.getId(); @@ -44,8 +47,6 @@ public class RouteService { } }) .collect(toList()); - - return routeDefinitionStream; } } 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 b0da0007..0393d04e 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 @@ -6,12 +6,9 @@ spring.application.name=sop-admin mysql.username=root mysql.password=root -# eureka注册中心地址 -eureka.url=http://localhost:1111/eureka/ # nacos注册中心地址 nacos.url=127.0.0.1:8848 -# zookeeper地址 -zookeeper.url=localhost:2181 + # zipkin服务监控地址,没有开启不用改 zipkin.url=http://127.0.0.1:9411/ # ------- 需要改的配置end ------- @@ -21,10 +18,9 @@ admin.access-token.timeout-minutes=30 # 签名方式,rsa:支付宝开放平台签名方式,md5:淘宝开放平台签名方式 sop.sign-type=rsa -# zookeeper配置 -spring.cloud.zookeeper.connect-string=${zookeeper.url} -spring.cloud.zookeeper.baseSleepTimeMs=3000 -spring.cloud.zookeeper.maxRetries=3 +# nacos配置 +nacos.config.server-addr=${nacos.url} +nacos.discovery.server-addr=${nacos.url} # 数据库配置 spring.datasource.driver-class-name=com.mysql.jdbc.Driver @@ -36,10 +32,7 @@ spring.datasource.password=${mysql.password} easyopen.show-doc=false easyopen.ignore-validate=true -# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册 -registry.eureka-server-addr=${eureka.url} -registry.nacos-server-addr=${nacos.url} -# 使用eureka,填:eureka,使用nacos填:nacos +# 固定不用改 registry.name=nacos logging.level.com.gitee=debug diff --git a/sop-admin/sop-admin-server/src/test/java/com/gitee/sop/adminserver/CuratorTest.java b/sop-admin/sop-admin-server/src/test/java/com/gitee/sop/adminserver/CuratorTest.java deleted file mode 100644 index 7cf5c1ed..00000000 --- a/sop-admin/sop-admin-server/src/test/java/com/gitee/sop/adminserver/CuratorTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.gitee.sop.adminserver; - -import com.gitee.sop.adminserver.bean.SopAdminConstants; -import junit.framework.TestCase; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.apache.zookeeper.data.Stat; - -public class CuratorTest extends TestCase { - - private static String zookeeperServerAddr = "localhost:2181"; - - static CuratorFramework client; - - public CuratorTest() { - client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(1000, 3)) - .build(); - - client.start(); - } - - /** - * 递归删除节点,只能在测试环境用。 - * - * @throws Exception - */ - public void testDel() { - try { - client.delete() - .deletingChildrenIfNeeded() - .forPath(SopAdminConstants.RELOAD_ROUTE_PERMISSION_PATH); - } catch (Exception e) { - } - } - - public void testCheck() throws Exception { - String path = SopAdminConstants.RELOAD_ROUTE_PERMISSION_PATH + "/1562231019332"; - Stat stat = client.checkExists().forPath(path); - System.out.println(path + (stat == null ? "不存在" : "存在")); - } - -} \ No newline at end of file diff --git a/sop-common/pom.xml b/sop-common/pom.xml index a040c4dc..86889370 100644 --- a/sop-common/pom.xml +++ b/sop-common/pom.xml @@ -28,8 +28,6 @@ 3.2.2 3.8.1 1.11 - 3.4.12 - 4.0.1 2.0.1.Final 6.0.13.Final @@ -57,36 +55,24 @@ pom import + + org.springframework.cloud + spring-cloud-alibaba-nacos-discovery + 0.9.0.RELEASE + pom + import + + + org.springframework.cloud + spring-cloud-starter-alibaba-nacos-config + 0.9.0.RELEASE + pom + import + - - - org.apache.curator - curator-recipes - ${curator-recipes.version} - - - org.apache.zookeeper - zookeeper - - - - - org.apache.zookeeper - zookeeper - ${zookeeper.version} - - - org.slf4j - slf4j-log4j12 - - - com.alibaba diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 7632cd29..1c0f6d3c 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -20,6 +20,14 @@ + + org.springframework.cloud + spring-cloud-alibaba-nacos-discovery + + + org.springframework.cloud + spring-cloud-starter-alibaba-nacos-config + com.google.guava guava @@ -60,7 +68,6 @@ spring-boot-starter-webflux true - diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java index 08f1b172..2ac5d14d 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java @@ -3,25 +3,25 @@ package com.gitee.sop.gatewaycommon.bean; /** * @author tanghc */ -public abstract class AbstractTargetRoute implements TargetRoute { +public abstract class AbstractTargetRoute implements TargetRoute { - private R serviceRouteInfo; - private E routeDefinition; + private ServiceRouteInfo serviceRouteInfo; + private GatewayRouteDefinition routeDefinition; private T targetRoute; - public AbstractTargetRoute(R serviceRouteInfo, E routeDefinition, T targetRoute) { + public AbstractTargetRoute(ServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition routeDefinition, T targetRoute) { this.serviceRouteInfo = serviceRouteInfo; this.routeDefinition = routeDefinition; this.targetRoute = targetRoute; } @Override - public R getServiceRouteInfo() { + public ServiceRouteInfo getServiceRouteInfo() { return serviceRouteInfo; } @Override - public E getRouteDefinition() { + public GatewayRouteDefinition getRouteDefinition() { return routeDefinition; } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayFilterDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayFilterDefinition.java similarity index 84% rename from sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayFilterDefinition.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayFilterDefinition.java index 9a3ca38e..1ee1c2a6 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayFilterDefinition.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayFilterDefinition.java @@ -1,4 +1,4 @@ -package com.gitee.sop.gatewaycommon.gateway.route; +package com.gitee.sop.gatewaycommon.bean; import lombok.Data; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayPredicateDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayPredicateDefinition.java new file mode 100644 index 00000000..06a6c0e5 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayPredicateDefinition.java @@ -0,0 +1,42 @@ +package com.gitee.sop.gatewaycommon.bean; + +import lombok.Data; +import org.springframework.util.StringUtils; + +import javax.validation.ValidationException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author tanghc + */ +@Data +public class GatewayPredicateDefinition { + public static final String GEN_KEY = "_genkey_"; + /** 断言对应的Name */ + private String name; + /** 配置的断言规则 */ + private Map args = new LinkedHashMap<>(); + + public GatewayPredicateDefinition() { + } + + public GatewayPredicateDefinition(String text) { + int eqIdx = text.indexOf(61); + if (eqIdx <= 0) { + throw new ValidationException("Unable to parse GatewayPredicateDefinition text '" + text + "', must be of the form name=value"); + } else { + this.setName(text.substring(0, eqIdx)); + String[] params = StringUtils.tokenizeToStringArray(text.substring(eqIdx + 1), ","); + + for(int i = 0; i < params.length; ++i) { + this.args.put(generateName(i), params[i]); + } + + } + } + + public static String generateName(int i) { + return GEN_KEY + i; + } +} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayRouteDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayRouteDefinition.java new file mode 100644 index 00000000..fdf1830a --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayRouteDefinition.java @@ -0,0 +1,72 @@ +package com.gitee.sop.gatewaycommon.bean; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author tanghc + */ +@Data +public class GatewayRouteDefinition { + /** + * 路由的Id(接口名+版本号),确保此id全局唯一 + */ + private String id; + + /** + * 接口名 + */ + private String name; + + /** + * 版本号 + */ + private String version; + + /** + * 路由断言集合配置 + */ + private List predicates = new ArrayList<>(); + + /** + * 路由过滤器集合配置 + */ + private List filters = new ArrayList<>(); + + /** + * 路由规则转发的目标uri + */ + private String uri; + + /** + * uri后面跟的path + */ + private String path; + + /** + * 路由执行的顺序 + */ + private int order = 0; + + /** + * 是否忽略验证,业务参数验证除外 + */ + private int ignoreValidate; + + /** + * 状态,0:待审核,1:启用,2:禁用 + */ + private int status = 1; + + /** + * 是否合并结果 + */ + private int mergeResult; + + /** + * 是否需要授权才能访问 + */ + private int permission; +} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/NacosConfigs.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/NacosConfigs.java new file mode 100644 index 00000000..15fd1423 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/NacosConfigs.java @@ -0,0 +1,29 @@ +package com.gitee.sop.gatewaycommon.bean; + +/** + * @author tanghc + */ +public class NacosConfigs { + + public static final String GROUP_CHANNEL = "sop:channel"; + + public static final String GROUP_ROUTE = "sop:route"; + + public static final String DATA_ID_GRAY = "com.gitee.sop.channel.gray"; + + public static final String DATA_ID_IP_BLACKLIST = "com.gitee.sop.channel.ipblacklist"; + + public static final String DATA_ID_ISV = "com.gitee.sop.channel.isv"; + + public static final String DATA_ID_ROUTE_PERMISSION = "com.gitee.sop.channel.routepermission"; + + public static final String DATA_ID_LIMIT_CONFIG = "com.gitee.sop.channel.limitconfig"; + + public static final String DATA_ID_ROUTE_CONFIG = "com.gitee.sop.channel.routeconfig"; + + private static final String DATA_ID_TPL = "com.gitee.sop.route.%s"; + + public static String getRouteDataId(String serviceId) { + return String.format(DATA_ID_TPL, serviceId); + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceRouteInfo.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceRouteInfo.java new file mode 100644 index 00000000..64951b19 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceRouteInfo.java @@ -0,0 +1,38 @@ +package com.gitee.sop.gatewaycommon.bean; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @author tanghc + */ +@Data +public class ServiceRouteInfo { + + /** + * 服务名称,对应spring.application.name + */ + private String serviceId; + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private Date createTime = new Date(); + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private Date updateTime = new Date(); + + private String description; + + /** + * 路由信息md5,md5(sort(routeIdList)) + */ + private String md5; + + private List routeDefinitionList; + + public String fetchServiceIdLowerCase() { + return serviceId.toLowerCase(); + } +} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java index 8f6def1c..fad4af9d 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java @@ -3,21 +3,21 @@ package com.gitee.sop.gatewaycommon.bean; /** * @author tanghc */ -public interface TargetRoute { +public interface TargetRoute { /** * 返回服务信息 * * @return 返回服务信息 */ - R getServiceRouteInfo(); + ServiceRouteInfo getServiceRouteInfo(); /** * 返回微服务路由对象 * * @return 返回微服务路由对象 */ - E getRouteDefinition(); + GatewayRouteDefinition getRouteDefinition(); /** * 返回网关路由对象 diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java index badbd26f..bb7b50e0 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java @@ -6,12 +6,11 @@ import com.gitee.sop.gatewaycommon.gateway.filter.LoadBalancerClientExtFilter; import com.gitee.sop.gatewaycommon.gateway.filter.ParameterFormatterFilter; import com.gitee.sop.gatewaycommon.gateway.filter.ValidateFilter; import com.gitee.sop.gatewaycommon.gateway.handler.GatewayExceptionHandler; +import com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteCache; import com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteRepository; -import com.gitee.sop.gatewaycommon.gateway.route.GatewayZookeeperRouteManager; import com.gitee.sop.gatewaycommon.gateway.route.NameVersionRoutePredicateFactory; import com.gitee.sop.gatewaycommon.gateway.route.ReadBodyRoutePredicateFactory; import com.gitee.sop.gatewaycommon.manager.AbstractConfiguration; -import com.gitee.sop.gatewaycommon.manager.RouteManager; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; import com.gitee.sop.gatewaycommon.param.ParamBuilder; import org.springframework.beans.factory.ObjectProvider; @@ -21,7 +20,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; -import org.springframework.core.env.Environment; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.server.ServerWebExchange; @@ -96,8 +94,8 @@ public class BaseGatewayConfiguration extends AbstractConfiguration { } @Bean - RouteManager gatewayZookeeperRouteManager(Environment environment, GatewayRouteRepository gatewayRouteManager) { - return new GatewayZookeeperRouteManager(environment, gatewayRouteManager); + GatewayRouteCache gatewayRouteLoader(GatewayRouteRepository gatewayRouteManager) { + return new GatewayRouteCache(gatewayRouteManager); } @Bean diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayPredicateDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayPredicateDefinition.java deleted file mode 100644 index 4b6c2a6d..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayPredicateDefinition.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.sop.gatewaycommon.gateway.route; - -import lombok.Data; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * @author tanghc - */ -@Data -public class GatewayPredicateDefinition { - /** 断言对应的Name */ - private String name; - /** 配置的断言规则 */ - private Map args = new LinkedHashMap<>(); -} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayZookeeperRouteManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java similarity index 73% rename from sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayZookeeperRouteManager.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java index b77844e0..2bcd3ba2 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayZookeeperRouteManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java @@ -1,14 +1,15 @@ package com.gitee.sop.gatewaycommon.gateway.route; -import com.gitee.sop.gatewaycommon.manager.BaseRouteManager; +import com.gitee.sop.gatewaycommon.bean.GatewayFilterDefinition; +import com.gitee.sop.gatewaycommon.bean.GatewayPredicateDefinition; +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; +import com.gitee.sop.gatewaycommon.manager.BaseRouteCache; import com.gitee.sop.gatewaycommon.manager.RouteRepository; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.cloud.gateway.filter.FilterDefinition; import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; import org.springframework.cloud.gateway.route.RouteDefinition; -import org.springframework.core.env.Environment; import java.net.URI; import java.util.ArrayList; @@ -16,30 +17,16 @@ import java.util.LinkedList; import java.util.List; /** - * 从zookeeper监听route信息 - * * @author tanghc */ -@Getter -@Slf4j -public class GatewayZookeeperRouteManager extends BaseRouteManager { +public class GatewayRouteCache extends BaseRouteCache { - public GatewayZookeeperRouteManager(Environment environment, RouteRepository routeRepository) { - super(environment, routeRepository); + public GatewayRouteCache(RouteRepository routeRepository) { + super(routeRepository); } @Override - protected Class getServiceRouteInfoClass() { - return GatewayServiceRouteInfo.class; - } - - @Override - protected Class getRouteDefinitionClass() { - return GatewayRouteDefinition.class; - } - - @Override - protected GatewayTargetRoute buildRouteDefinition(GatewayServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition gatewayRouteDefinition) { + protected GatewayTargetRoute buildRouteDefinition(ServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition gatewayRouteDefinition) { RouteDefinition routeDefinition = new RouteDefinition(); routeDefinition.setId(gatewayRouteDefinition.getId()); routeDefinition.setUri(URI.create(gatewayRouteDefinition.getUri() + "#" + gatewayRouteDefinition.getPath())); @@ -80,5 +67,4 @@ public class GatewayZookeeperRouteManager extends BaseRouteManager implements RouteLoader { + + /** + * KEY:serviceId, value: md5 + */ + private Map serviceIdMd5Map = new HashMap<>(); + + private RouteRepository routeRepository; + + /** + * 构建目标路由对象,zuul和gateway定义的路由对象 + * + * @param serviceRouteInfo 路由服务对象 + * @param gatewayRouteDefinition 路由对象 + * @return 返回目标路由对象 + */ + protected abstract T buildRouteDefinition(ServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition gatewayRouteDefinition); + + public BaseRouteCache(RouteRepository routeRepository) { + this.routeRepository = routeRepository; + } + + @Override + public void load(ServiceRouteInfo serviceRouteInfo) { + try { + String newMd5 = serviceRouteInfo.getMd5(); + String md5 = serviceIdMd5Map.putIfAbsent(serviceRouteInfo.getServiceId(), newMd5); + if (Objects.equals(newMd5, md5)) { + return; + } + List routeDefinitionList = serviceRouteInfo.getRouteDefinitionList(); + for (GatewayRouteDefinition gatewayRouteDefinition : routeDefinitionList) { + T routeDefinition = this.buildRouteDefinition(serviceRouteInfo, gatewayRouteDefinition); + routeRepository.add(routeDefinition); + } + } catch (Exception e) { + log.error("加载路由信息失败,serviceRouteInfo:{}", serviceRouteInfo, e); + } + } + + @Override + public void remove(String serviceId) { + serviceIdMd5Map.remove(serviceId); + routeRepository.deleteAll(serviceId); + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java deleted file mode 100644 index 4b4ea6ec..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.gitee.sop.gatewaycommon.manager; - -import com.alibaba.fastjson.JSON; -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; -import com.gitee.sop.gatewaycommon.bean.BaseServiceRouteInfo; -import com.gitee.sop.gatewaycommon.bean.TargetRoute; -import lombok.extern.slf4j.Slf4j; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; -import org.springframework.core.env.Environment; - - -/** - * 路由管理,采用zookeeper实现,监听路由的增删改,并适时更新到本地。路由的存储格式为: - *
- * /com.gitee.sop.route  根节点
- *      /serviceId       服务节点,名字为服务名
- *          /route1      路由节点,名字为:name+version,存放路由信息
- *          /route2
- *          /...
- * 
- * - * @param 路由根对象,可以理解为最外面的大json:{....,routeDefinitionList:[]} - * @param 路由Item对象,对应大json里面的具体路由信息,routeDefinitionList:[] - * @param 目标路由对象 - * @author tanghc - */ -@Slf4j -public abstract class BaseRouteManager, E extends BaseRouteDefinition, T extends TargetRoute> implements RouteManager { - - protected Environment environment; - - protected RouteRepository routeRepository; - - protected String routeRootPath; - - /** - * 返回路由根对象class - * - * @return 返回R.class - */ - protected abstract Class getServiceRouteInfoClass(); - - /** - * 返回路由Item对象class - * - * @return 返回E.class - */ - protected abstract Class getRouteDefinitionClass(); - - /** - * 构建目标路由对象,zuul和gateway定义的路由对象 - * - * @param serviceRouteInfo - * @param routeDefinition - * @return 返回目标路由对象 - */ - protected abstract T buildRouteDefinition(R serviceRouteInfo, E routeDefinition); - - public BaseRouteManager(Environment environment, RouteRepository routeRepository) { - this.environment = environment; - ZookeeperContext.setEnvironment(environment); - this.routeRepository = routeRepository; - this.routeRootPath = ZookeeperContext.getRouteRootPath(); - this.createRouteRootPath(this.routeRootPath); - } - - @Override - public void refresh() { - this.refreshRouteInfo(); - } - - protected void refreshRouteInfo() { - try { - this.watchServiceChange(routeRootPath); - } catch (Exception e) { - log.error("刷新路由配置失败", e); - throw new IllegalStateException("刷新路由配置失败"); - } - } - - protected void createRouteRootPath(String routeRootPath) { - try { - ZookeeperContext.createPath(routeRootPath, ""); - } catch (Exception e) { - log.error("创建路由根节点失败", e); - throw new IllegalStateException("创建路由根节点失败"); - } - } - - /** - * 监听微服务更改 - * - * @param rootPath - * @throws Exception - */ - protected void watchServiceChange(String rootPath) throws Exception { - ZookeeperContext.getChildrenAndListen(rootPath, childDataList -> { - log.info("========== 加载路由信息 =========="); - log.info("{} # 路由根节点", rootPath); - for (ChildData childData : childDataList) { - String serviceNodeData = new String(childData.getData()); - R serviceRouteInfo = JSON.parseObject(serviceNodeData, getServiceRouteInfoClass()); - String servicePath = childData.getPath(); - log.info("\t{} # service节点,节点数据:{}", servicePath, serviceNodeData); - try { - this.loadServiceRouteItem(serviceRouteInfo, servicePath); - } catch (Exception e) { - log.error("加载路由信息失败,servicePath:{}", servicePath, e); - } - } - }, (client, event) -> { - PathChildrenCacheEvent.Type type = event.getType(); - synchronized (type) { - // 通过判断event type的方式来实现不同事件的触发 - if (PathChildrenCacheEvent.Type.CHILD_ADDED.equals(type)) { - String serviceNodeData = new String(event.getData().getData()); - R serviceRouteInfo = JSON.parseObject(serviceNodeData, getServiceRouteInfoClass()); - // 添加子节点时触发 - String servicePath = event.getData().getPath(); - log.info("新增serviceId节点:{},节点数据:{}", servicePath, serviceNodeData); - this.watchRouteItems(serviceRouteInfo, servicePath); - } else if (PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(type)) { - // 修改子节点数据时触发,暂时没有什么操作 - String nodeData = new String(event.getData().getData()); - log.info("修改serviceId节点:{},节点数据:{}", event.getData().getPath(), nodeData); - } else if (PathChildrenCacheEvent.Type.CHILD_REMOVED.equals(type)) { - // 删除service节点 - String nodeData = new String(event.getData().getData()); - log.info("删除serviceId节点:{},节点数据:{}", event.getData().getPath(), nodeData); - R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass()); - routeRepository.deleteAll(serviceRouteInfo.getServiceId()); - } - } - }); - } - - /** - * 加载service下的路由信息 - * - * @param servicePath - */ - protected void loadServiceRouteItem(R serviceRouteInfo, String servicePath) throws Exception { - ZookeeperContext.getChildrenData(servicePath, childDataList -> { - for (ChildData childData : childDataList) { - String routeItemPath = childData.getPath(); - byte[] routeItemData = childData.getData(); - String routeDataJson = buildZookeeperData(routeItemData); - log.info("\t\t{} # 路由节点,节点数据:{}", routeItemPath, routeDataJson); - this.saveRouteItem(serviceRouteInfo, routeDataJson); - } - }); - this.watchRouteItems(serviceRouteInfo, servicePath); - } - - - /** - * 监听serviceId目录下面的子节点 - * - * @param serviceRouteInfo - * @param servicePath serviceId节点 - */ - protected void watchRouteItems(R serviceRouteInfo, String servicePath) throws Exception { - log.info("监听{}下子节点增删改", servicePath); - // 添加事件监听器 - ZookeeperContext.listenChildren(servicePath, (client, event) -> { - PathChildrenCacheEvent.Type type = event.getType(); - synchronized (type) { - // 通过判断event type的方式来实现不同事件的触发 - if (PathChildrenCacheEvent.Type.CHILD_ADDED.equals(type)) { - // 新增单个路由 - String routeDataJson = buildZookeeperData(event.getData().getData()); - log.info("新增单个路由,serviceId:{}, 路由数据:{}", serviceRouteInfo.getServiceId(), routeDataJson); - saveRouteItem(serviceRouteInfo, routeDataJson); - } else if (PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(type)) { - // 修改单个路由 - String routeDataJson = buildZookeeperData(event.getData().getData()); - log.info("修改单个路由,serviceId:{}, 路由数据:{}", serviceRouteInfo.getServiceId(), routeDataJson); - updateRouteItem(serviceRouteInfo, routeDataJson); - } else if (PathChildrenCacheEvent.Type.CHILD_REMOVED.equals(type)) { - // 删除单个路由 - String routeDataJson = buildZookeeperData(event.getData().getData()); - log.info("删除单个路由,serviceId:{}, 路由数据:{}", serviceRouteInfo.getServiceId(), routeDataJson); - deleteRouteItem(serviceRouteInfo, routeDataJson); - } - } - }); - - } - - protected void saveRouteItem(R serviceRouteInfo, String nodeDataJson) { - T routeDefinition = getRouteDefinition(serviceRouteInfo, nodeDataJson); - routeRepository.add(routeDefinition); - } - - protected void updateRouteItem(R serviceRouteInfo, String nodeDataJson) { - T routeDefinition = getRouteDefinition(serviceRouteInfo, nodeDataJson); - routeRepository.update(routeDefinition); - } - - protected void deleteRouteItem(R serviceRouteInfo, String nodeDataJson) { - E routeDefinitionItem = getRouteDefinitionItem(nodeDataJson); - routeRepository.delete(routeDefinitionItem.getId()); - } - - protected T getRouteDefinition(R serviceRouteInfo, String nodeDataJson) { - E routeDefinitionItem = getRouteDefinitionItem(nodeDataJson); - T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem); - return routeDefinition; - } - - protected E getRouteDefinitionItem(String nodeDataJson) { - return JSON.parseObject(nodeDataJson, getRouteDefinitionClass()); - } - - protected String buildZookeeperData(byte[] data) { - return new String(data); - } - -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java deleted file mode 100644 index aa99921f..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ManagerContext.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.sop.gatewaycommon.manager; - -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; - -/** - * @author tanghc - */ -public class ManagerContext { - - private static ApplicationContext ctx; - - public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - ctx = applicationContext; - } - - public static T getManager(Class clazz) { - return ctx.getBean(clazz); - } - - public static ApplicationContext getApplicationContext() { - return ctx; - } -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteLoader.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteLoader.java new file mode 100644 index 00000000..ba4566fe --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteLoader.java @@ -0,0 +1,12 @@ +package com.gitee.sop.gatewaycommon.manager; + +import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; + +/** + * @author tanghc + */ +public interface RouteLoader { + void load(ServiceRouteInfo serviceRouteInfo); + + void remove(String serviceId); +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteManager.java index b443974e..fd4eba19 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteManager.java @@ -4,6 +4,7 @@ package com.gitee.sop.gatewaycommon.manager; * 管理各服务路由信息 * @author tanghc */ +@Deprecated public interface RouteManager { /** diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RoutePermissionManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RoutePermissionManager.java deleted file mode 100644 index df9a63f9..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RoutePermissionManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.sop.gatewaycommon.manager; - -import com.gitee.sop.gatewaycommon.bean.IsvRoutePermission; - -/** - * @author tanghc - */ -public interface RoutePermissionManager { - /** - * 加载路由授权 - */ - void load(); - - /** - * 更新路由授权信息 - * - * @param isvRoutePermission 授权信息 - */ - void update(IsvRoutePermission isvRoutePermission); -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java new file mode 100644 index 00000000..ad28c439 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java @@ -0,0 +1,118 @@ +package com.gitee.sop.gatewaycommon.manager; + +import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import com.gitee.sop.gatewaycommon.bean.NacosConfigs; +import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; +import com.gitee.sop.gatewaycommon.bean.TargetRoute; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; +import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; +import org.springframework.context.ApplicationEvent; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.web.client.RestTemplate; + +import java.util.List; +import java.util.Objects; + +/** + * 发现新服务,更新路由信息 + * + * @author tanghc + */ +@Slf4j +public class ServiceRoutesLoader { + + private static final String SECRET = "a3d9sf!1@odl90zd>fkASwq"; + + private static final int FIVE_SECONDS = 1000 * 5; + + @Autowired + private NacosDiscoveryProperties nacosDiscoveryProperties; + + @Autowired + private NacosConfigProperties nacosConfigProperties; + + @Autowired + private BaseRouteCache baseRouteCache; + + private RestTemplate restTemplate = new RestTemplate(); + + private volatile long lastUpdateTime; + + public synchronized void load(ApplicationEvent event) { + long now = System.currentTimeMillis(); + // 5秒内只能执行一次,解决重启应用连续加载4次问题 + if (now - lastUpdateTime < FIVE_SECONDS) { + return; + } + lastUpdateTime = now; + NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); + List subscribes = null; + try { + subscribes = namingService.getSubscribeServices(); + } catch (NacosException e) { + log.error("namingService.getSubscribeServices()错误", e); + } + if (CollectionUtils.isEmpty(subscribes)) { + return; + } + // subscribe + String thisServiceId = nacosDiscoveryProperties.getService(); + ConfigService configService = nacosConfigProperties.configServiceInstance(); + for (ServiceInfo serviceInfo : subscribes) { + String serviceName = serviceInfo.getName(); + // 如果是本机服务,跳过 + if (Objects.equals(thisServiceId, serviceName)) { + continue; + } + try { + String dataId = NacosConfigs.getRouteDataId(serviceName); + String groupId = NacosConfigs.GROUP_ROUTE; + List allInstances = namingService.getAllInstances(serviceName); + if (CollectionUtils.isEmpty(allInstances)) { + log.info("{}服务下线,删除路由信息", serviceName); + // 如果没有服务列表,则删除所有路由信息 + baseRouteCache.remove(serviceName); + configService.removeConfig(dataId, groupId); + } else { + for (Instance instance : allInstances) { + log.info("加载服务路由,instance:{}", instance); + String url = getRouteRequestUrl(instance); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + if (responseEntity.getStatusCode() == HttpStatus.OK) { + String body = responseEntity.getBody(); + log.debug("加载{}路由,路由信息:{}", serviceName, body); + ServiceRouteInfo serviceRouteInfo = JSON.parseObject(body, ServiceRouteInfo.class); + baseRouteCache.load(serviceRouteInfo); + configService.publishConfig(dataId, groupId, body); + } + } + } + } catch (NacosException e) { + log.error("选择服务实例失败,serviceName:{}", serviceName, e); + } + } + } + + private static String getRouteRequestUrl(Instance instance) { + String query = buildQuery(SECRET); + return "http://" + instance.getIp() + ":" + instance.getPort() + "/sop/routes" + query; + } + + private static String buildQuery(String secret) { + String time = String.valueOf(System.currentTimeMillis()); + String source = secret + time + secret; + String sign = DigestUtils.md5DigestAsHex(source.getBytes()); + return "?time=" + time + "&sign=" + sign; + } + +} 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 deleted file mode 100644 index b7672836..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ZookeeperContext.java +++ /dev/null @@ -1,252 +0,0 @@ -package com.gitee.sop.gatewaycommon.manager; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.NodeCache; -import org.apache.curator.framework.recipes.cache.NodeCacheListener; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.springframework.core.env.Environment; -import org.springframework.util.Assert; - -import java.util.List; -import java.util.function.Consumer; - -import static com.gitee.sop.gatewaycommon.bean.SopConstants.SOP_MSG_CHANNEL_PATH; -import static com.gitee.sop.gatewaycommon.bean.SopConstants.SOP_SERVICE_ROUTE_PATH; - -/** - * @author tanghc - */ -@Slf4j -public class ZookeeperContext { - - private static CuratorFramework client; - - private static Environment environment; - - public static void setEnvironment(Environment environment) { - Assert.notNull(environment, "environment不能为null"); - ZookeeperContext.environment = environment; - initZookeeperClient(); - } - - public synchronized static void initZookeeperClient() { - if (client != null) { - return; - } - setClient(createClient()); - } - - public static CuratorFramework createClient() { - String zookeeperServerAddr = environment.getProperty("spring.cloud.zookeeper.connect-string"); - if (StringUtils.isBlank(zookeeperServerAddr)) { - throw new RuntimeException("未指定spring.cloud.zookeeper.connect-string参数"); - } - String baseSleepTimeMs = environment.getProperty("spring.cloud.zookeeper.baseSleepTimeMs"); - String maxRetries = environment.getProperty("spring.cloud.zookeeper.maxRetries"); - log.info("初始化zookeeper客户端,zookeeperServerAddr:{}, baseSleepTimeMs:{}, maxRetries:{}", - zookeeperServerAddr, baseSleepTimeMs, maxRetries); - CuratorFramework client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(NumberUtils.toInt(baseSleepTimeMs, 3000), NumberUtils.toInt(maxRetries, 3))) - .build(); - - client.start(); - return client; - } - - public static String getRouteRootPath() { - return SOP_SERVICE_ROUTE_PATH; - } - - public static String getIsvInfoChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/isvinfo"; - } - - public static String getServiceGrayChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/gray"; - } - - public static String getIsvRoutePermissionChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/isv-route-permission"; - } - - public static String getRouteConfigChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/route-conf"; - } - - public static String getLimitConfigChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/limit-conf"; - } - - public static String getIpBlacklistChannelPath() { - return SOP_MSG_CHANNEL_PATH + "/ipblacklist-conf"; - } - - public static CuratorFramework getClient() { - return client; - } - - public static void setClient(CuratorFramework client) { - ZookeeperContext.client = client; - } - - /** - * 新建或保存节点 - * - * @param path - * @param data - * @return 返回path - * @throws Exception - */ - public static String createOrUpdateData(String path, String data) throws Exception { - return getClient().create() - // 如果节点存在则Curator将会使用给出的数据设置这个节点的值 - .orSetData() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .forPath(path, data.getBytes()); - } - - /** - * 更新节点 - * @param path - * @param data - * @throws Exception - */ - public static void updatePath(String path, String data) throws Exception { - getClient().setData().forPath(path, data.getBytes()); - } - - /** - * 创建path,如果path存在不报错,静默返回path名称 - * - * @param path - * @param data - * @return - * @throws Exception - */ - public static String createPath(String path, String data) throws Exception { - if (isPathExist(path)) { - return path; - } - return getClient().create() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .forPath(path, data.getBytes()); - } - - public static boolean isPathExist(String path) { - try { - return client.checkExists().forPath(path) != null; - } catch (Exception e) { - return false; - } - } - - /** - * 监听一个节点 - * - * @param path - * @param onChange 节点修改后触发 - * @return 返回path - * @throws Exception - */ - public static String listenPath(String path, Consumer onChange) throws Exception { - String ret = createOrUpdateData(path, "{}"); - final NodeCache cache = new NodeCache(client, path, false); - cache.getListenable().addListener(new NodeCacheListener() { - @Override - public void nodeChanged() throws Exception { - onChange.accept(cache); - } - }); - cache.start(); - return ret; - } - - /** - * 获取子节点信息并监听子节点 - * - * @param parentPath 父节点路径 - * @param listConsumer 子节点数据 - * @param listener 监听事件 - * @throws Exception - */ - public static void getChildrenAndListen(String parentPath, Consumer> listConsumer, PathChildrenCacheListener listener) throws Exception { - // 为子节点添加watcher - // PathChildrenCache: 监听数据节点的增删改,可以设置触发的事件 - PathChildrenCache childrenCache = new PathChildrenCache(client, parentPath, true); - - /** - * StartMode: 初始化方式 - * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件 - * NORMAL:异步初始化 - * BUILD_INITIAL_CACHE:同步初始化 - */ - childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); - - // 列出子节点数据列表,需要使用BUILD_INITIAL_CACHE同步初始化模式才能获得,异步是获取不到的 - List childDataList = childrenCache.getCurrentData(); - listConsumer.accept(childDataList); - log.info("监听子节点增删改,监听路径:{}", parentPath); - // 监听根节点下面的子节点 - childrenCache.getListenable().addListener(listener); - } - - /** - * 获取子节点信息 - * - * @param parentPath 父节点路径 - * @param listConsumer 子节点数据 - * @throws Exception - */ - public static void getChildrenData(String parentPath, Consumer> listConsumer) throws Exception { - // 为子节点添加watcher - // PathChildrenCache: 监听数据节点的增删改,可以设置触发的事件 - PathChildrenCache childrenCache = new PathChildrenCache(client, parentPath, true); - - /** - * StartMode: 初始化方式 - * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件 - * NORMAL:异步初始化 - * BUILD_INITIAL_CACHE:同步初始化 - */ - childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); - - // 列出子节点数据列表,需要使用BUILD_INITIAL_CACHE同步初始化模式才能获得,异步是获取不到的 - List childDataList = childrenCache.getCurrentData(); - listConsumer.accept(childDataList); - childrenCache.close(); - } - - /** - * 监听子节点的增删改 - * - * @param parentPath 父节点路径 - * @param listener - * @throws Exception - */ - public static void listenChildren(String parentPath, PathChildrenCacheListener listener) throws Exception { - // 为子节点添加watcher - // PathChildrenCache: 监听数据节点的增删改,可以设置触发的事件 - PathChildrenCache childrenCache = new PathChildrenCache(client, parentPath, true); - - /** - * StartMode: 初始化方式 - * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件 - * NORMAL:异步初始化 - * BUILD_INITIAL_CACHE:同步初始化 - */ - childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); - // 监听根节点下面的子节点 - childrenCache.getListenable().addListener(listener); - } - -} 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 4518ff89..6da65c17 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 @@ -1,6 +1,6 @@ package com.gitee.sop.gatewaycommon.param; -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; import com.gitee.sop.gatewaycommon.bean.TargetRoute; import com.gitee.sop.gatewaycommon.manager.RouteRepository; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; @@ -65,7 +65,7 @@ public abstract class BaseParamBuilder implements ParamBuilder { TargetRoute targetRoute = routeRepository.get(nameVersion); Integer ignoreValidate = Optional.ofNullable(targetRoute) .map(t -> t.getRouteDefinition()) - .map(BaseRouteDefinition::getIgnoreValidate) + .map(GatewayRouteDefinition::getIgnoreValidate) // 默认不忽略 .orElse(BooleanUtils.toInteger(false)); apiParam.setIgnoreValidate(BooleanUtils.toBoolean(ignoreValidate)); 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 fff6b09a..0b011636 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 @@ -4,10 +4,10 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ApiContext; -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; -import com.gitee.sop.gatewaycommon.bean.BaseServiceRouteInfo; import com.gitee.sop.gatewaycommon.bean.ErrorDefinition; +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; import com.gitee.sop.gatewaycommon.bean.Isv; +import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; import com.gitee.sop.gatewaycommon.bean.SopConstants; import com.gitee.sop.gatewaycommon.bean.TargetRoute; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; @@ -139,7 +139,7 @@ public abstract class BaseExecutorAdapter implements ResultExecutor return defaultSetting; } ApiInfo apiInfo = this.getApiInfo(request); - BaseRouteDefinition baseRouteDefinition = apiInfo.baseRouteDefinition; + GatewayRouteDefinition baseRouteDefinition = apiInfo.gatewayRouteDefinition; return Optional.ofNullable(baseRouteDefinition) .map(routeDefinition -> { int mergeResult = baseRouteDefinition.getMergeResult(); @@ -157,10 +157,10 @@ public abstract class BaseExecutorAdapter implements ResultExecutor String serviceId = Optional.ofNullable(targetRoute) .flatMap(route -> Optional.ofNullable(route.getServiceRouteInfo())) - .map(BaseServiceRouteInfo::getServiceId) + .map(ServiceRouteInfo::getServiceId) .orElse(SopConstants.UNKNOWN_SERVICE); - BaseRouteDefinition baseRouteDefinition = Optional.ofNullable(targetRoute) + GatewayRouteDefinition baseRouteDefinition = Optional.ofNullable(targetRoute) .map(route -> route.getRouteDefinition()) .orElse(null); @@ -168,7 +168,7 @@ public abstract class BaseExecutorAdapter implements ResultExecutor apiInfo.name = name; apiInfo.version = version; apiInfo.serviceId = serviceId; - apiInfo.baseRouteDefinition = baseRouteDefinition; + apiInfo.gatewayRouteDefinition = baseRouteDefinition; return apiInfo; } @@ -276,7 +276,7 @@ public abstract class BaseExecutorAdapter implements ResultExecutor private String name; private String version; private String serviceId; - private BaseRouteDefinition baseRouteDefinition; + private GatewayRouteDefinition gatewayRouteDefinition; } enum ErrorType { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java index fccd5c23..a8ed1357 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java @@ -2,7 +2,7 @@ package com.gitee.sop.gatewaycommon.validate; import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ApiContext; -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; import com.gitee.sop.gatewaycommon.bean.Isv; import com.gitee.sop.gatewaycommon.bean.RouteConfig; import com.gitee.sop.gatewaycommon.bean.TargetRoute; @@ -216,7 +216,7 @@ public class ApiValidator implements Validator { protected void checkPermission(ApiParam apiParam) { String routeId = apiParam.fetchNameVersion(); TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); - BaseRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); + GatewayRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission()); if (needCheckPermission) { String appKey = apiParam.fetchAppKey(); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java index f0470ec0..07811339 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java @@ -15,8 +15,8 @@ import com.gitee.sop.gatewaycommon.zuul.filter.PreValidateFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreVersionDecisionFilter; import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt; import com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator; +import com.gitee.sop.gatewaycommon.zuul.route.ZuulRouteCache; import com.gitee.sop.gatewaycommon.zuul.route.ZuulRouteRepository; -import com.gitee.sop.gatewaycommon.zuul.route.ZuulZookeeperRouteManager; import com.netflix.zuul.context.RequestContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -26,7 +26,6 @@ import org.springframework.cloud.netflix.zuul.filters.RouteLocator; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter; import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; /** * @author tanghc @@ -46,8 +45,7 @@ public class BaseZuulConfiguration extends AbstractConfiguration { } /** - * 路由存储 - * @return + * 路由仓库 */ @Bean ZuulRouteRepository zuulRouteRepository() { @@ -89,12 +87,11 @@ public class BaseZuulConfiguration extends AbstractConfiguration { /** * 路由管理 - * @param environment - * @param zuulRouteRepository + * @param zuulRouteRepository 路由仓库 */ @Bean - ZuulZookeeperRouteManager zuulZookeeperRouteManager(Environment environment, ZuulRouteRepository zuulRouteRepository) { - return new ZuulZookeeperRouteManager(environment, zuulRouteRepository); + ZuulRouteCache zuulRouteLoader(ZuulRouteRepository zuulRouteRepository) { + return new ZuulRouteCache(zuulRouteRepository); } /** @@ -126,8 +123,6 @@ public class BaseZuulConfiguration extends AbstractConfiguration { return new PreVersionDecisionFilter(); } - - /** * 错误处理扩展 */ diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java deleted file mode 100644 index c693f9b5..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreRoutePermissionFilter.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.gitee.sop.gatewaycommon.zuul.filter; - -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; -import com.gitee.sop.gatewaycommon.bean.TargetRoute; -import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager; -import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; -import com.gitee.sop.gatewaycommon.message.ErrorEnum; -import com.gitee.sop.gatewaycommon.param.ApiParam; -import com.gitee.sop.gatewaycommon.zuul.ZuulContext; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * 路由权限校验,有些接口需要配置权限才能访问。 - * @author tanghc - * @deprecated 已经整合到ApiValidator中,见ApiValidator.checkPermission() - */ -@Deprecated -public class PreRoutePermissionFilter extends BaseZuulFilter { - - @Autowired - private IsvRoutePermissionManager isvRoutePermissionManager; - - @Override - protected FilterType getFilterType() { - return FilterType.PRE; - } - - @Override - protected int getFilterOrder() { - // 放在签名验证后面 - return PRE_ROUTE_PERMISSION_FILTER_ORDER; - } - - @Override - protected Object doRun(RequestContext requestContext) throws ZuulException { - ApiParam apiParam = ZuulContext.getApiParam(); - String routeId = apiParam.fetchNameVersion(); - TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); - BaseRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); - boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission()); - if (needCheckPermission) { - String appKey = apiParam.fetchAppKey(); - boolean hasPermission = isvRoutePermissionManager.hasPermission(appKey, routeId); - if (!hasPermission) { - throw ErrorEnum.ISV_ROUTE_NO_PERMISSIONS.getErrorMeta().getException(); - } - } - - return null; - } -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteCache.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteCache.java new file mode 100644 index 00000000..e8285ad2 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteCache.java @@ -0,0 +1,34 @@ +package com.gitee.sop.gatewaycommon.zuul.route; + +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; +import com.gitee.sop.gatewaycommon.manager.BaseRouteCache; +import com.gitee.sop.gatewaycommon.manager.RouteRepository; +import com.gitee.sop.gatewaycommon.util.RouteUtil; +import org.springframework.cloud.netflix.zuul.filters.Route; + +/** + * @author tanghc + */ +public class ZuulRouteCache extends BaseRouteCache { + + /** 路由重试 */ + public static final boolean RETRYABLE = true; + + public ZuulRouteCache(RouteRepository routeRepository) { + super(routeRepository); + } + + @Override + protected ZuulTargetRoute buildRouteDefinition(ServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition gatewayRouteDefinition) { + Route route = new Route( + gatewayRouteDefinition.getId() + , gatewayRouteDefinition.getPath() + , RouteUtil.getZuulLocation(gatewayRouteDefinition.getUri()) + , "" + , RETRYABLE + , null + ); + return new ZuulTargetRoute(serviceRouteInfo, gatewayRouteDefinition, route); + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteDefinition.java deleted file mode 100644 index fba3d5ff..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulRouteDefinition.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.sop.gatewaycommon.zuul.route; - -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; -import lombok.Getter; -import lombok.Setter; - -/** - * @author tanghc - */ -@Getter -@Setter -public class ZuulRouteDefinition extends BaseRouteDefinition { -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulServiceRouteInfo.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulServiceRouteInfo.java deleted file mode 100644 index 7e22c1f9..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulServiceRouteInfo.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.sop.gatewaycommon.zuul.route; - -import com.gitee.sop.gatewaycommon.bean.BaseServiceRouteInfo; - -/** - * @author tanghc - */ -public class ZuulServiceRouteInfo extends BaseServiceRouteInfo { -} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulTargetRoute.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulTargetRoute.java index 4d6223a4..00b928f9 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulTargetRoute.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulTargetRoute.java @@ -1,6 +1,8 @@ package com.gitee.sop.gatewaycommon.zuul.route; import com.gitee.sop.gatewaycommon.bean.AbstractTargetRoute; +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; import lombok.Getter; import org.springframework.cloud.netflix.zuul.filters.Route; @@ -8,9 +10,9 @@ import org.springframework.cloud.netflix.zuul.filters.Route; * @author tanghc */ @Getter -public class ZuulTargetRoute extends AbstractTargetRoute { +public class ZuulTargetRoute extends AbstractTargetRoute { - public ZuulTargetRoute(ZuulServiceRouteInfo baseServiceRouteInfo, ZuulRouteDefinition baseRouteDefinition, Route targetRoute) { - super(baseServiceRouteInfo, baseRouteDefinition, targetRoute); + public ZuulTargetRoute(ServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition routeDefinition, Route targetRoute) { + super(serviceRouteInfo, routeDefinition, targetRoute); } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java deleted file mode 100644 index 3e0cb7b8..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/route/ZuulZookeeperRouteManager.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.gitee.sop.gatewaycommon.zuul.route; - -import com.gitee.sop.gatewaycommon.manager.BaseRouteManager; -import com.gitee.sop.gatewaycommon.manager.RouteRepository; -import com.gitee.sop.gatewaycommon.util.RouteUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.core.env.Environment; - -/** - * 路由内容管理,新增活修改路由 - * - * @author tanghc - */ -@Slf4j -public class ZuulZookeeperRouteManager extends BaseRouteManager { - - /** 路由重试 */ - public static final boolean RETRYABLE = true; - - public ZuulZookeeperRouteManager(Environment environment, RouteRepository routeRepository) { - super(environment, routeRepository); - } - - @Override - protected Class getServiceRouteInfoClass() { - return ZuulServiceRouteInfo.class; - } - - @Override - protected Class getRouteDefinitionClass() { - return ZuulRouteDefinition.class; - } - - @Override - protected ZuulTargetRoute buildRouteDefinition(ZuulServiceRouteInfo serviceRouteInfo, ZuulRouteDefinition routeDefinition) { - Route route = new Route(routeDefinition.getId(), routeDefinition.getPath(), RouteUtil.getZuulLocation(routeDefinition.getUri()), "", RETRYABLE, null); - return new ZuulTargetRoute(serviceRouteInfo, routeDefinition, route); - } -} diff --git a/sop-common/sop-registry-api/pom.xml b/sop-common/sop-registry-api/pom.xml index a7a89cde..086f59ce 100644 --- a/sop-common/sop-registry-api/pom.xml +++ b/sop-common/sop-registry-api/pom.xml @@ -25,7 +25,7 @@ com.alibaba.nacos nacos-client - 1.0.1 + 1.1.3 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 03c0614d..9192b947 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 @@ -33,7 +33,7 @@ public class RegistryServiceNacos implements RegistryService { static HttpTool httpTool = new HttpTool(); - @Value("${registry.nacos-server-addr:}") + @Value("${nacos.discovery.server-addr:}") private String nacosAddr; private NamingService namingService; diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index f22638cb..5fab3da9 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -21,6 +21,11 @@ + + org.springframework.cloud + spring-cloud-alibaba-nacos-discovery + + org.springframework spring-webmvc diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ZookeeperTool.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ZookeeperTool.java deleted file mode 100644 index 8130d7f8..00000000 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ZookeeperTool.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.gitee.sop.servercommon.bean; - -import com.gitee.sop.servercommon.exception.ZookeeperOperationException; -import com.gitee.sop.servercommon.exception.ZookeeperPathNotExistException; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.apache.zookeeper.CreateMode; -import org.springframework.core.env.Environment; - -import java.io.Closeable; -import java.io.IOException; - - -/** - * @author tanghc - */ -@Slf4j -@Getter -public class ZookeeperTool implements Closeable { - - private CuratorFramework client; - private Environment environment; - - public ZookeeperTool(Environment environment) { - this.environment = environment; - initZookeeperClient(environment); - } - - public void initZookeeperClient(Environment environment) { - String zookeeperServerAddr = environment.getProperty("spring.cloud.zookeeper.connect-string"); - if (StringUtils.isBlank(zookeeperServerAddr)) { - throw new RuntimeException("未指定spring.cloud.zookeeper.connect-string参数"); - } - String baseSleepTimeMs = environment.getProperty("spring.cloud.zookeeper.baseSleepTimeMs"); - String maxRetries = environment.getProperty("spring.cloud.zookeeper.maxRetries"); - log.info("初始化zookeeper客户端,zookeeperServerAddr:{}, baseSleepTimeMs:{}, maxRetries:{}", - zookeeperServerAddr, baseSleepTimeMs, maxRetries); - CuratorFramework client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(NumberUtils.toInt(baseSleepTimeMs, 3000), NumberUtils.toInt(maxRetries, 3))) - .build(); - - client.start(); - - this.client = client; - } - - /** - * 获取节点内容 - * - * @param path - * @return 返回节点内容 - * @throws ZookeeperPathNotExistException 节点不存在,抛出异常 - */ - public String getData(String path) throws ZookeeperPathNotExistException { - if (!isPathExist(path)) { - throw new ZookeeperPathNotExistException("path 不存在, path=" + path); - } - try { - byte[] data = getClient().getData().forPath(path); - return new String(data); - } catch (Exception e) { - throw new ZookeeperOperationException("getData error path=" + path, e); - } - } - - public boolean isPathExist(String path) { - try { - return client.checkExists().forPath(path) != null; - } catch (Exception e) { - return false; - } - } - - /** - * 创建path,如果path存在不报错,静默返回path名称 - * - * @param path - * @param data - * @return - * @throws Exception - */ - public String createPath(String path, String data) throws Exception { - if (isPathExist(path)) { - return path; - } - return getClient().create() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .forPath(path, data.getBytes()); - } - - /** - * 创建临时序列节点 - * @param path 节点路径 - * @param data 数据 - * @return 返回节点路径 - * @throws Exception - */ - public String createOrUpdateEphemeralSequentialPath(String path, String data) throws Exception { - return getClient().create() - // 如果节点存在则Curator将会使用给出的数据设置这个节点的值 - .orSetData() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .withMode(CreateMode.EPHEMERAL_SEQUENTIAL) - .forPath(path, data.getBytes()); - } - - /** - * 新建或保存节点 - * - * @param path - * @param data - * @return 返回path - * @throws Exception - */ - public String createOrUpdateData(String path, String data) throws Exception { - return getClient().create() - // 如果节点存在则Curator将会使用给出的数据设置这个节点的值 - .orSetData() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .forPath(path, data.getBytes()); - } - - @Override - public void close() throws IOException { - if (this.client != null) { - this.client.close(); - } - } -} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java index 6dcdd549..8f87f45a 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java @@ -2,18 +2,13 @@ package com.gitee.sop.servercommon.configuration; import com.gitee.sop.servercommon.bean.ServiceConfig; import com.gitee.sop.servercommon.interceptor.ServiceContextInterceptor; -import com.gitee.sop.servercommon.manager.ApiMetaManager; -import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent; -import com.gitee.sop.servercommon.manager.RequestMappingEvent; -import com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager; +import com.gitee.sop.servercommon.manager.ServiceRouteController; import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping; import com.gitee.sop.servercommon.message.ServiceErrorFactory; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -36,9 +31,6 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport ServiceConfig.getInstance().getI18nModules().add("i18n/isp/bizerror"); } - @Autowired - private Environment environment; - private ApiMappingHandlerMapping apiMappingHandlerMapping = new ApiMappingHandlerMapping(); @Override @@ -77,19 +69,16 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport return apiMappingHandlerMapping; } - protected RequestMappingEvent getRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) { - return new DefaultRequestMappingEvent(apiMetaManager, environment); - } - - protected ApiMetaManager getApiMetaManager(Environment environment) { - return new ServiceZookeeperApiMetaManager(environment); - } - @Bean GlobalExceptionHandler globalExceptionHandler() { return ServiceConfig.getInstance().getGlobalExceptionHandler(); } + @Bean + ServiceRouteController serviceRouteController() { + return new ServiceRouteController(); + } + @PostConstruct public final void after() { log.info("-----spring容器加载完毕-----"); @@ -105,9 +94,6 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport @Override public void run(ApplicationArguments args) throws Exception { log.info("-----服务器启动完毕-----"); - ApiMetaManager apiMetaManager = getApiMetaManager(environment); - RequestMappingEvent requestMappingEvent = getRequestMappingEvent(apiMetaManager, environment); - requestMappingEvent.onRegisterSuccess(apiMappingHandlerMapping); this.onStartup(args); } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java index f0d4b7e1..075db50f 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java @@ -6,7 +6,6 @@ import com.gitee.easyopen.util.ReflectionUtil; import com.gitee.sop.servercommon.bean.ServiceApiInfo; import com.gitee.sop.servercommon.manager.ApiMetaManager; import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent; -import com.gitee.sop.servercommon.manager.RequestMappingEvent; import org.apache.commons.lang3.BooleanUtils; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AnnotationUtils; @@ -30,11 +29,6 @@ public class EasyopenServiceConfiguration extends BaseServiceConfiguration { ApiContext.getApiConfig().setIgnoreValidate(true); } - @Override - protected RequestMappingEvent getRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) { - return new EasyopenRequestMappingEvent(apiMetaManager, environment); - } - class EasyopenRequestMappingEvent extends DefaultRequestMappingEvent { String prefixPath; diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/SpringMvcServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/SpringMvcServiceConfiguration.java index 6b76778e..36492179 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/SpringMvcServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/SpringMvcServiceConfiguration.java @@ -1,21 +1,14 @@ package com.gitee.sop.servercommon.configuration; import com.gitee.sop.servercommon.bean.ServiceConfig; -import com.gitee.sop.servercommon.manager.ApiMetaManager; -import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent; -import com.gitee.sop.servercommon.manager.RequestMappingEvent; -import com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager; import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping; import com.gitee.sop.servercommon.message.ServiceErrorFactory; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; -import org.springframework.core.env.Environment; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.annotation.PostConstruct; -import java.util.concurrent.Executors; /** * 提供给springmvc工程 @@ -30,10 +23,6 @@ public class SpringMvcServiceConfiguration { private ApiMappingHandlerMapping apiMappingHandlerMapping = new ApiMappingHandlerMapping(); - @Autowired - private Environment environment; - - /** * 自定义Mapping,详见@ApiMapping * @@ -54,20 +43,10 @@ public class SpringMvcServiceConfiguration { @PostConstruct public final void after() { log.info("-----spring容器加载完毕-----"); - Executors.newSingleThreadExecutor().execute(()->{ - uploadRouteToZookeeper(); - }); initMessage(); doAfter(); } - private void uploadRouteToZookeeper() { - ApiMetaManager apiMetaManager = new ServiceZookeeperApiMetaManager(environment); - RequestMappingEvent requestMappingEvent = new DefaultRequestMappingEvent(apiMetaManager, environment); - requestMappingEvent.onRegisterSuccess(apiMappingHandlerMapping); - } - - /** * spring容器加载完毕后执行 */ diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperOperationException.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperOperationException.java deleted file mode 100644 index 64823412..00000000 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperOperationException.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.gitee.sop.servercommon.exception; - -/** - * @author tanghc - */ -public class ZookeeperOperationException extends RuntimeException { - - public ZookeeperOperationException() { - } - - public ZookeeperOperationException(String message) { - super(message); - } - - public ZookeeperOperationException(String message, Throwable cause) { - super(message, cause); - } - - public ZookeeperOperationException(Throwable cause) { - super(cause); - } - - public ZookeeperOperationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperPathNotExistException.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperPathNotExistException.java deleted file mode 100644 index 2b82263e..00000000 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/exception/ZookeeperPathNotExistException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.sop.servercommon.exception; - -/** - * @author tanghc - */ -public class ZookeeperPathNotExistException extends Exception { - public ZookeeperPathNotExistException(String message) { - super(message); - } -} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java new file mode 100644 index 00000000..4ca6f95e --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java @@ -0,0 +1,100 @@ +package com.gitee.sop.servercommon.manager; + +import com.gitee.sop.servercommon.bean.ServiceApiInfo; +import com.gitee.sop.servercommon.bean.ServiceConfig; +import com.gitee.sop.servercommon.mapping.ApiMappingInfo; +import com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition; +import com.gitee.sop.servercommon.mapping.RouteUtil; +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.condition.RequestCondition; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author tanghc + */ +public class ApiMetaBuilder { + + /** 接口名规则:允许字母、数字、点、下划线 */ + private static final String REGEX_API_NAME = "^[a-zA-Z0-9\\.\\_\\-]+$"; + + public ServiceApiInfo getServiceApiInfo(String serviceId, RequestMappingHandlerMapping requestMappingHandlerMapping) { + if (serviceId == null) { + throw new IllegalArgumentException("请在application.properties中指定spring.application.name属性"); + } + List apis = this.buildApiMetaList(requestMappingHandlerMapping); + // 排序 + apis.sort(Comparator.comparing(ServiceApiInfo.ApiMeta::fetchNameVersion)); + + ServiceApiInfo serviceApiInfo = new ServiceApiInfo(); + serviceApiInfo.setServiceId(serviceId); + serviceApiInfo.setApis(apis); + + return serviceApiInfo; + } + + protected List buildApiMetaList(RequestMappingHandlerMapping requestMappingHandlerMapping) { + Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); + Set requestMappingInfos = handlerMethods.keySet(); + List store = new ArrayList<>(); + List apis = new ArrayList<>(requestMappingInfos.size()); + + for (Map.Entry handlerMethodEntry : handlerMethods.entrySet()) { + ServiceApiInfo.ApiMeta apiMeta = this.buildApiMeta(handlerMethodEntry); + if (apiMeta == null) { + continue; + } + String key = apiMeta.fetchNameVersion(); + if (store.contains(key)) { + throw new IllegalArgumentException("重复申明接口,请检查path和version,path:" + apiMeta.getPath() + ", version:" + apiMeta.getVersion()); + } else { + store.add(key); + } + apis.add(apiMeta); + } + return apis; + } + + protected ServiceApiInfo.ApiMeta buildApiMeta(Map.Entry handlerMethodEntry) { + RequestMappingInfo requestMappingInfo = handlerMethodEntry.getKey(); + Set patterns = requestMappingInfo.getPatternsCondition().getPatterns(); + RequestCondition customCondition = requestMappingInfo.getCustomCondition(); + if (customCondition instanceof ApiMappingRequestCondition) { + ApiMappingRequestCondition condition = (ApiMappingRequestCondition) customCondition; + ApiMappingInfo apiMappingInfo = condition.getApiMappingInfo(); + String name = apiMappingInfo.getName(); + String version = apiMappingInfo.getVersion(); + // 方法完整的path,如: /goods/listGoods,/users/user/get + String path = patterns.iterator().next(); + // 不是ApiMapping注解的接口,name属性是null + if (name == null || ServiceConfig.getInstance().isWebappMode()) { + name = buildName(path); + } + this.checkApiName(name); + ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(name, path, version); + apiMeta.setIgnoreValidate(BooleanUtils.toInteger(apiMappingInfo.isIgnoreValidate())); + apiMeta.setMergeResult(BooleanUtils.toInteger(apiMappingInfo.isMergeResult())); + apiMeta.setPermission(BooleanUtils.toInteger(apiMappingInfo.isPermission())); + return apiMeta; + } + return null; + } + + protected void checkApiName(String name) { + if (!name.matches(REGEX_API_NAME)) { + throw new IllegalArgumentException("接口名称只允许【字母、数字、点(.)、下划线(_)、减号(-)】,错误接口:" + name); + } + } + + + protected String buildName(String path) { + return RouteUtil.buildApiName(path); + } +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java index 4b3474db..3e3a59bb 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java @@ -1,32 +1,15 @@ package com.gitee.sop.servercommon.manager; import com.gitee.sop.servercommon.bean.ServiceApiInfo; -import com.gitee.sop.servercommon.bean.ServiceConfig; -import com.gitee.sop.servercommon.mapping.ApiMappingInfo; -import com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition; -import com.gitee.sop.servercommon.mapping.RouteUtil; import lombok.Getter; -import org.apache.commons.lang3.BooleanUtils; import org.springframework.core.env.Environment; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.mvc.condition.RequestCondition; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * @author tanghc */ @Getter -public class DefaultRequestMappingEvent implements RequestMappingEvent { - - /** 接口名规则:允许字母、数字、点、下划线 */ - private static final String REGEX_API_NAME = "^[a-zA-Z0-9\\.\\_\\-]+$"; +public class DefaultRequestMappingEvent extends ApiMetaBuilder implements RequestMappingEvent { private ApiMetaManager apiMetaManager; private Environment environment; @@ -39,76 +22,8 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent { @Override public void onRegisterSuccess(RequestMappingHandlerMapping requestMappingHandlerMapping) { String serviceId = environment.getProperty("spring.application.name"); - if (serviceId == null) { - throw new IllegalArgumentException("请在application.properties中指定spring.application.name属性"); - } - List apis = this.buildApiMetaList(requestMappingHandlerMapping); - // 排序 - apis.sort(Comparator.comparing(ServiceApiInfo.ApiMeta::fetchNameVersion)); - - ServiceApiInfo serviceApiInfo = new ServiceApiInfo(); - serviceApiInfo.setServiceId(serviceId); - serviceApiInfo.setApis(apis); - + ServiceApiInfo serviceApiInfo = getServiceApiInfo(serviceId, requestMappingHandlerMapping); apiMetaManager.uploadApi(serviceApiInfo); } - protected List buildApiMetaList(RequestMappingHandlerMapping requestMappingHandlerMapping) { - Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); - Set requestMappingInfos = handlerMethods.keySet(); - List store = new ArrayList<>(); - List apis = new ArrayList<>(requestMappingInfos.size()); - - for (Map.Entry handlerMethodEntry : handlerMethods.entrySet()) { - ServiceApiInfo.ApiMeta apiMeta = this.buildApiMeta(handlerMethodEntry); - if (apiMeta == null) { - continue; - } - String key = apiMeta.fetchNameVersion(); - if (store.contains(key)) { - throw new IllegalArgumentException("重复申明接口,请检查path和version,path:" + apiMeta.getPath() + ", version:" + apiMeta.getVersion()); - } else { - store.add(key); - } - apis.add(apiMeta); - } - return apis; - } - - protected ServiceApiInfo.ApiMeta buildApiMeta(Map.Entry handlerMethodEntry) { - RequestMappingInfo requestMappingInfo = handlerMethodEntry.getKey(); - Set patterns = requestMappingInfo.getPatternsCondition().getPatterns(); - RequestCondition customCondition = requestMappingInfo.getCustomCondition(); - if (customCondition instanceof ApiMappingRequestCondition) { - ApiMappingRequestCondition condition = (ApiMappingRequestCondition) customCondition; - ApiMappingInfo apiMappingInfo = condition.getApiMappingInfo(); - String name = apiMappingInfo.getName(); - String version = apiMappingInfo.getVersion(); - // 方法完整的path,如: /goods/listGoods,/users/user/get - String path = patterns.iterator().next(); - // 不是ApiMapping注解的接口,name属性是null - if (name == null || ServiceConfig.getInstance().isWebappMode()) { - name = buildName(path); - } - this.checkApiName(name); - ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(name, path, version); - apiMeta.setIgnoreValidate(BooleanUtils.toInteger(apiMappingInfo.isIgnoreValidate())); - apiMeta.setMergeResult(BooleanUtils.toInteger(apiMappingInfo.isMergeResult())); - apiMeta.setPermission(BooleanUtils.toInteger(apiMappingInfo.isPermission())); - return apiMeta; - } - return null; - } - - protected void checkApiName(String name) { - if (!name.matches(REGEX_API_NAME)) { - throw new IllegalArgumentException("接口名称只允许【字母、数字、点(.)、下划线(_)、减号(-)】,错误接口:" + name); - } - } - - - protected String buildName(String path) { - return RouteUtil.buildApiName(path); - } - } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java new file mode 100644 index 00000000..8c92d708 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java @@ -0,0 +1,46 @@ +package com.gitee.sop.servercommon.manager; + +import com.gitee.sop.servercommon.bean.ServiceApiInfo; +import com.gitee.sop.servercommon.route.ServiceRouteInfo; +import com.gitee.sop.servercommon.util.OpenUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author tanghc + */ +@Slf4j +@RestController +public class ServiceRouteController { + + private static final String SECRET = "a3d9sf!1@odl90zd>fkASwq"; + + @Autowired + private RequestMappingHandlerMapping requestMappingHandlerMapping; + + @Autowired + private Environment environment; + + + @RequestMapping("/sop/routes") + public ServiceRouteInfo listRoutes(HttpServletRequest request, HttpServletResponse response) { + if (!OpenUtil.validateSimpleSign(request, SECRET)) { + log.error("签名验证失败, params:{}", request.getQueryString()); + return null; + } + String serviceId = environment.getProperty("spring.application.name"); + ApiMetaBuilder apiMetaBuilder = new ApiMetaBuilder(); + ServiceApiInfo serviceApiInfo = apiMetaBuilder.getServiceApiInfo(serviceId, requestMappingHandlerMapping); + ServiceRouteInfoBuilder serviceRouteInfoBuilder = new ServiceRouteInfoBuilder(environment); + return serviceRouteInfoBuilder.build(serviceApiInfo); + } + + +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java new file mode 100644 index 00000000..868a8756 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java @@ -0,0 +1,150 @@ +package com.gitee.sop.servercommon.manager; + +import com.alibaba.fastjson.JSON; +import com.gitee.sop.servercommon.bean.ServiceApiInfo; +import com.gitee.sop.servercommon.route.GatewayPredicateDefinition; +import com.gitee.sop.servercommon.route.GatewayRouteDefinition; +import com.gitee.sop.servercommon.route.ServiceRouteInfo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.core.env.Environment; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author tanghc + */ +@Slf4j +public class ServiceRouteInfoBuilder { + + /** + * 网关对应的LoadBalance协议 + */ + private static final String PROTOCOL_LOAD_BALANCE = "lb://"; + + private static final String PATH_SPLIT = "/"; + + private static final String DEFAULT_CONTEXT_PATH = "/"; + + /** + * NameVersion=alipay.story.get1.0 + * see com.gitee.sop.gatewaycommon.routeDefinition.NameVersionRoutePredicateFactory + */ + private static String QUERY_PREDICATE_DEFINITION_TPL = "NameVersion=%s"; + + private static ServiceApiInfo.ApiMeta FIRST_API_META = new ServiceApiInfo.ApiMeta("_first.route_", "/", "v_000"); + + private Environment environment; + + public ServiceRouteInfoBuilder(Environment environment) { + this.environment = environment; + } + + public ServiceRouteInfo build(ServiceApiInfo serviceApiInfo) { + return this.buildServiceGatewayInfo(serviceApiInfo); + } + + /** + * 构建接口信息,符合spring cloud gateway的格式 + * + * @param serviceApiInfo 服务接口信息 + * @return 返回服务路由信息 + */ + protected ServiceRouteInfo buildServiceGatewayInfo(ServiceApiInfo serviceApiInfo) { + List apis = serviceApiInfo.getApis(); + List routeDefinitionList = new ArrayList<>(apis.size()); + routeDefinitionList.add(this.buildReadBodyRouteDefinition(serviceApiInfo)); + for (ServiceApiInfo.ApiMeta apiMeta : apis) { + GatewayRouteDefinition gatewayRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, apiMeta); + routeDefinitionList.add(gatewayRouteDefinition); + } + ServiceRouteInfo serviceRouteInfo = new ServiceRouteInfo(); + serviceRouteInfo.setServiceId(serviceApiInfo.getServiceId()); + serviceRouteInfo.setRouteDefinitionList(routeDefinitionList); + String md5 = buildMd5(routeDefinitionList); + serviceRouteInfo.setMd5(md5); + return serviceRouteInfo; + } + + /** + * 构建路由id MD5 + * + * @param routeDefinitionList 路由列表 + * @return 返回MD5 + */ + protected String buildMd5(List routeDefinitionList) { + List routeIdList = routeDefinitionList.stream() + .map(JSON::toJSONString) + .sorted() + .collect(Collectors.toList()); + String md5Source = org.apache.commons.lang3.StringUtils.join(routeIdList, ""); + return DigestUtils.md5DigestAsHex(md5Source.getBytes(StandardCharsets.UTF_8)); + } + + protected GatewayRouteDefinition buildGatewayRouteDefinition(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { + GatewayRouteDefinition gatewayRouteDefinition = new GatewayRouteDefinition(); + // 唯一id规则:接口名 + 版本号 + String routeId = apiMeta.fetchNameVersion(); + this.checkPath(routeId, "接口定义(" + routeId + ")不能有斜杠字符'/'"); + BeanUtils.copyProperties(apiMeta, gatewayRouteDefinition); + gatewayRouteDefinition.setId(routeId); + gatewayRouteDefinition.setFilters(Collections.emptyList()); + gatewayRouteDefinition.setPredicates(this.buildPredicates(apiMeta)); + String uri = this.buildUri(serviceApiInfo, apiMeta); + String path = this.buildServletPath(serviceApiInfo, apiMeta); + gatewayRouteDefinition.setUri(uri); + gatewayRouteDefinition.setPath(path); + return gatewayRouteDefinition; + } + + protected List buildPredicates(ServiceApiInfo.ApiMeta apiMeta) { + GatewayPredicateDefinition gatewayPredicateDefinition = new GatewayPredicateDefinition(); + gatewayPredicateDefinition.setName("ReadBody"); + return Arrays.asList(gatewayPredicateDefinition, this.buildNameVersionPredicateDefinition(apiMeta)); + } + + protected GatewayPredicateDefinition buildNameVersionPredicateDefinition(ServiceApiInfo.ApiMeta apiMeta) { + return new GatewayPredicateDefinition(String.format(QUERY_PREDICATE_DEFINITION_TPL, apiMeta.fetchNameVersion())); + } + + /** + * 添加com.gitee.sop.gatewaycommon.routeDefinition.ReadBodyRoutePredicateFactory,解决form表单获取不到问题 + * + * @return 返回路由定义 + */ + protected GatewayRouteDefinition buildReadBodyRouteDefinition(ServiceApiInfo serviceApiInfo) { + GatewayRouteDefinition readBodyRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, FIRST_API_META); + readBodyRouteDefinition.setOrder(Integer.MIN_VALUE); + + readBodyRouteDefinition.setPredicates(this.buildPredicates(FIRST_API_META)); + + return readBodyRouteDefinition; + } + + protected String buildUri(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { + return PROTOCOL_LOAD_BALANCE + serviceApiInfo.getServiceId(); + } + + protected String buildServletPath(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { + String contextPath = environment.getProperty("server.servlet.context-path", DEFAULT_CONTEXT_PATH); + String servletPath = apiMeta.getPath(); + if (servletPath == null) { + servletPath = ""; + } + servletPath = StringUtils.trimLeadingCharacter(servletPath, '/'); + return contextPath + servletPath; + } + + private void checkPath(String path, String errorMsg) { + if (path.contains(PATH_SPLIT)) { + throw new IllegalArgumentException(errorMsg); + } + } +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java deleted file mode 100644 index 10ff3503..00000000 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java +++ /dev/null @@ -1,271 +0,0 @@ -package com.gitee.sop.servercommon.manager; - -import com.alibaba.fastjson.JSON; -import com.gitee.sop.servercommon.bean.ServiceApiInfo; -import com.gitee.sop.servercommon.bean.ZookeeperTool; -import com.gitee.sop.servercommon.exception.ZookeeperPathNotExistException; -import com.gitee.sop.servercommon.route.GatewayPredicateDefinition; -import com.gitee.sop.servercommon.route.GatewayRouteDefinition; -import com.gitee.sop.servercommon.route.ServiceRouteInfo; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeanUtils; -import org.springframework.core.env.Environment; -import org.springframework.util.DigestUtils; -import org.springframework.util.StringUtils; - -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * 上传路由到zookeeper - * - * @author tanghc - */ -@Slf4j -@Getter -@Setter -public class ServiceZookeeperApiMetaManager implements ApiMetaManager { - - /** 网关对应的LoadBalance协议 */ - private static final String PROTOCOL_LOAD_BALANCE = "lb://"; - - private static final String PATH_SPLIT = "/"; - - private static final String DEFAULT_CONTEXT_PATH = "/"; - - /** - * NameVersion=alipay.story.get1.0 - * see com.gitee.sop.gatewaycommon.routeDefinition.NameVersionRoutePredicateFactory - */ - private static String QUERY_PREDICATE_DEFINITION_TPL = "NameVersion=%s"; - - private static ServiceApiInfo.ApiMeta FIRST_API_META = new ServiceApiInfo.ApiMeta("_first.route_", "/", "v_000"); - - - private Environment environment; - - private ZookeeperTool zookeeperTool; - - private String serviceId; - - public ServiceZookeeperApiMetaManager(Environment environment) { - this.environment = environment; - serviceId = environment.getProperty("spring.application.name"); - if (StringUtils.isEmpty(serviceId)) { - throw new IllegalArgumentException("请在application.properties中指定spring.application.name属性"); - } - this.zookeeperTool = new ZookeeperTool(environment); - - this.uploadServiceId(environment); - } - - /** - * 上传serviceId目录 - * - * @param environment environment - */ - protected void uploadServiceId(Environment environment) { - try { - this.checkZookeeperNode(serviceId, "serviceId(" + serviceId + ")不能有斜杠字符'/'"); - ServiceRouteInfo serviceRouteInfo = this.buildServiceRouteInfo(); - // 保存路径 - String savePath = serviceRouteInfo.getZookeeperPath(); - String nodeData = JSON.toJSONString(serviceRouteInfo); - log.info("serviceId:{}, zookeeper保存路径:{}", serviceId, savePath); - this.zookeeperTool.createPath(savePath, nodeData); - this.zookeeperTool.createPath(serviceRouteInfo.getZookeeperTempServiceIdPath(), ""); - } catch (Exception e) { - throw new IllegalStateException("zookeeper操作失败"); - } - } - - @Override - public void uploadApi(ServiceApiInfo serviceApiInfo) { - try { - ServiceRouteInfo serviceRouteInfo = this.buildServiceGatewayInfo(serviceApiInfo); - this.uploadServiceRouteInfoToZookeeper(serviceRouteInfo); - // 同时上传一个临时节点 - String tempPath = serviceRouteInfo.getZookeeperTempServiceIdChildPath(); - this.zookeeperTool.createOrUpdateEphemeralSequentialPath(tempPath, JSON.toJSONString(serviceRouteInfo)); - } catch (Exception e) { - log.error("上传一个临时节点失败, serviceApiInfo:{}", serviceApiInfo, e); - } - } - - /** - * 构建接口信息,符合spring cloud gateway的格式 - * - * @param serviceApiInfo 服务接口信息 - * @return 返回服务路由信息 - */ - protected ServiceRouteInfo buildServiceGatewayInfo(ServiceApiInfo serviceApiInfo) { - List apis = serviceApiInfo.getApis(); - List routeDefinitionList = new ArrayList<>(apis.size()); - routeDefinitionList.add(this.buildReadBodyRouteDefinition(serviceApiInfo)); - for (ServiceApiInfo.ApiMeta apiMeta : apis) { - GatewayRouteDefinition gatewayRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, apiMeta); - routeDefinitionList.add(gatewayRouteDefinition); - } - ServiceRouteInfo serviceRouteInfo = this.buildServiceRouteInfo(); - serviceRouteInfo.setRouteDefinitionList(routeDefinitionList); - String md5 = buildMd5(routeDefinitionList); - serviceRouteInfo.setMd5(md5); - return serviceRouteInfo; - } - - /** - * 构建路由id MD5 - * - * @param routeDefinitionList 路由列表 - * @return 返回MD5 - */ - protected String buildMd5(List routeDefinitionList) { - List routeIdList = routeDefinitionList.stream() - .map(JSON::toJSONString) - .sorted() - .collect(Collectors.toList()); - String md5Source = org.apache.commons.lang3.StringUtils.join(routeIdList, ""); - return DigestUtils.md5DigestAsHex(md5Source.getBytes(StandardCharsets.UTF_8)); - } - - protected ServiceRouteInfo buildServiceRouteInfo() { - ServiceRouteInfo serviceRouteInfo = new ServiceRouteInfo(); - serviceRouteInfo.setServiceId(serviceId); - String description = environment.getProperty("spring.application.description"); - serviceRouteInfo.setDescription(description); - return serviceRouteInfo; - } - - protected GatewayRouteDefinition buildGatewayRouteDefinition(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { - GatewayRouteDefinition gatewayRouteDefinition = new GatewayRouteDefinition(); - // 唯一id规则:接口名 + 版本号 - String routeId = apiMeta.fetchNameVersion(); - this.checkZookeeperNode(routeId, "接口定义(" + routeId + ")不能有斜杠字符'/'"); - BeanUtils.copyProperties(apiMeta, gatewayRouteDefinition); - gatewayRouteDefinition.setId(routeId); - gatewayRouteDefinition.setFilters(Collections.emptyList()); - gatewayRouteDefinition.setPredicates(this.buildPredicates(apiMeta)); - String uri = this.buildUri(serviceApiInfo, apiMeta); - String path = this.buildServletPath(serviceApiInfo, apiMeta); - gatewayRouteDefinition.setUri(uri); - gatewayRouteDefinition.setPath(path); - return gatewayRouteDefinition; - } - - protected List buildPredicates(ServiceApiInfo.ApiMeta apiMeta) { - GatewayPredicateDefinition gatewayPredicateDefinition = new GatewayPredicateDefinition(); - gatewayPredicateDefinition.setName("ReadBody"); - return Arrays.asList(gatewayPredicateDefinition, this.buildNameVersionPredicateDefinition(apiMeta)); - } - - protected GatewayPredicateDefinition buildNameVersionPredicateDefinition(ServiceApiInfo.ApiMeta apiMeta) { - return new GatewayPredicateDefinition(String.format(QUERY_PREDICATE_DEFINITION_TPL, apiMeta.fetchNameVersion())); - } - - /** - * 添加com.gitee.sop.gatewaycommon.routeDefinition.ReadBodyRoutePredicateFactory,解决form表单获取不到问题 - * - * @return 返回路由定义 - */ - protected GatewayRouteDefinition buildReadBodyRouteDefinition(ServiceApiInfo serviceApiInfo) { - GatewayRouteDefinition readBodyRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, FIRST_API_META); - readBodyRouteDefinition.setOrder(Integer.MIN_VALUE); - - readBodyRouteDefinition.setPredicates(this.buildPredicates(FIRST_API_META)); - - return readBodyRouteDefinition; - } - - protected String buildUri(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { - return PROTOCOL_LOAD_BALANCE + serviceApiInfo.getServiceId(); - } - - protected String buildServletPath(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) { - String contextPath = environment.getProperty("server.servlet.context-path", DEFAULT_CONTEXT_PATH); - String servletPath = apiMeta.getPath(); - if (servletPath == null) { - servletPath = ""; - } - servletPath = StringUtils.trimLeadingCharacter(servletPath, '/'); - return contextPath + servletPath; - } - - /** - * 上传接口信息到zookeeper - * - * @param serviceRouteInfo 路由服务信息 - */ - protected void uploadServiceRouteInfoToZookeeper(ServiceRouteInfo serviceRouteInfo) { - String savePath = serviceRouteInfo.getZookeeperPath(); - try { - String existServiceRouteInfoData = zookeeperTool.getData(savePath); - ServiceRouteInfo serviceRouteInfoExist = JSON.parseObject(existServiceRouteInfoData, ServiceRouteInfo.class); - String oldMD5 = serviceRouteInfoExist.getMd5(); - String newMD5 = serviceRouteInfo.getMd5(); - if (Objects.equals(oldMD5, newMD5)) { - log.info("接口没有改变,无需上传路由信息"); - return; - } - } catch (ZookeeperPathNotExistException e) { - log.warn("服务路径不存在,path:{}", savePath); - } - try { - log.info("上传接口信息到zookeeper,path:{}, serviceId:{}, 接口数量:{}", - savePath, - serviceRouteInfo.getServiceId(), - serviceRouteInfo.getRouteDefinitionList().size()); - - String parentPath = this.uploadFolder(serviceRouteInfo); - this.uploadRouteItems(serviceRouteInfo, parentPath); - } catch (Exception e) { - log.error("更新接口信息到zookeeper失败, serviceId:{}", serviceRouteInfo.getServiceId(), e); - } - } - - /** - * 上传文件夹内容 - * - * @param serviceRouteInfo 路由服务信息 - * @return 返回文件夹路径 - */ - protected String uploadFolder(ServiceRouteInfo serviceRouteInfo) throws Exception { - // 保存路径 - String savePath = serviceRouteInfo.getZookeeperPath(); - String serviceRouteInfoJson = JSON.toJSONString(serviceRouteInfo); - log.info("上传service目录到zookeeper,路径:{},内容:{}", savePath, serviceRouteInfoJson); - this.zookeeperTool.createOrUpdateData(savePath, serviceRouteInfoJson); - return savePath; - } - - /** - * 上传路由信息 - * - * @param serviceRouteInfo 路由服务 - * @param parentPath 父节点 - * @throws Exception - */ - protected void uploadRouteItems(ServiceRouteInfo serviceRouteInfo, String parentPath) throws Exception { - List routeDefinitionList = serviceRouteInfo.getRouteDefinitionList(); - for (GatewayRouteDefinition routeDefinition : routeDefinitionList) { - // 父目录/子目录 - String savePath = parentPath + PATH_SPLIT + routeDefinition.getId(); - String routeDefinitionJson = JSON.toJSONString(routeDefinition); - log.info("上传路由配置到zookeeper,路径:{},路由数据:{}", savePath, routeDefinitionJson); - this.zookeeperTool.createOrUpdateData(savePath, routeDefinitionJson); - } - } - - private void checkZookeeperNode(String path, String errorMsg) { - if (path.contains(PATH_SPLIT)) { - throw new IllegalArgumentException(errorMsg); - } - } - -} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerValidator.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerValidator.java index 80667950..ac2a9e8f 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerValidator.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerValidator.java @@ -1,7 +1,6 @@ package com.gitee.sop.servercommon.swagger; -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.DigestUtils; +import com.gitee.sop.servercommon.util.OpenUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -33,14 +32,7 @@ public class SwaggerValidator { } public boolean validate(HttpServletRequest request) { - String time = request.getParameter("time"); - String sign = request.getParameter("sign"); - if (StringUtils.isAnyBlank(time, sign)) { - return false; - } - String source = secret + time + secret; - String serverSign = DigestUtils.md5DigestAsHex(source.getBytes()); - return serverSign.equals(sign); + return OpenUtil.validateSimpleSign(request, secret); } public void writeForbidden(HttpServletResponse response) throws IOException { diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java index a99813cd..d4f7eb26 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java @@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.http.MediaType; +import org.springframework.util.DigestUtils; import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; @@ -75,4 +76,14 @@ public class OpenUtil { return retMap; } + public static boolean validateSimpleSign(HttpServletRequest request, String secret) { + String time = request.getParameter("time"); + String sign = request.getParameter("sign"); + if (StringUtils.isAnyBlank(time, sign)) { + return false; + } + String source = secret + time + secret; + String serverSign = DigestUtils.md5DigestAsHex(source.getBytes()); + return serverSign.equals(sign); + } } diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index f800e269..b9bf7682 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -48,6 +48,17 @@ org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery 0.2.2.RELEASE + + + com.alibaba.nacos + nacos-client + + + + + com.alibaba.nacos + nacos-client + 1.1.0 @@ -73,6 +84,11 @@ netty-all + + com.google.guava + guava + 25.1-jre + diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 4146a1c0..273161b7 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -65,15 +65,6 @@ runtime - - - - 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 305ace89..fb2f5603 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 @@ -1,20 +1,23 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.AbstractListener; import com.gitee.fastmybatis.core.query.Query; 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.NacosConfigs; 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; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -50,6 +53,9 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager { @Autowired private ConfigGrayInstanceMapper configGrayInstanceMapper; + @Autowired + private NacosConfigProperties nacosConfigProperties; + @Override public void load() { @@ -98,7 +104,7 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager { @PostConstruct protected void after() throws Exception { - ZookeeperContext.setEnvironment(environment); + /*ZookeeperContext.setEnvironment(environment); String isvChannelPath = ZookeeperContext.getServiceGrayChannelPath(); ZookeeperContext.listenPath(isvChannelPath, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); @@ -120,6 +126,31 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager { default: } + });*/ + + // nacos + ConfigService configService = nacosConfigProperties.configServiceInstance(); + configService.addListener(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class); + String data = channelMsg.getData(); + ServiceGrayDefinition userKeyDefinition = JSON.parseObject(data, ServiceGrayDefinition.class); + String serviceId = userKeyDefinition.getServiceId(); + switch (channelMsg.getOperation()) { + case "set": + ConfigGray configGray = configGrayMapper.getByColumn("service_id", serviceId); + setServiceGrayConfig(configGray); + break; + case "open": + openGray(userKeyDefinition.getInstanceId(), serviceId); + break; + case "close": + closeGray(userKeyDefinition.getInstanceId()); + break; + default: + } + } }); } 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 7db0eada..7ab89cda 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 @@ -1,13 +1,16 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.AbstractListener; import com.gitee.sop.gateway.mapper.IPBlacklistMapper; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; +import com.gitee.sop.gatewaycommon.bean.NacosConfigs; import com.gitee.sop.gatewaycommon.manager.DefaultIPBlacklistManager; -import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -29,6 +32,9 @@ public class DbIPBlacklistManager extends DefaultIPBlacklistManager { @Autowired Environment environment; + @Autowired + private NacosConfigProperties nacosConfigProperties; + @Override public void load() { List ipList = ipBlacklistMapper.listAllIP(); @@ -39,7 +45,7 @@ public class DbIPBlacklistManager extends DefaultIPBlacklistManager { @PostConstruct protected void after() throws Exception { - ZookeeperContext.setEnvironment(environment); + /*ZookeeperContext.setEnvironment(environment); String path = ZookeeperContext.getIpBlacklistChannelPath(); ZookeeperContext.listenPath(path, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); @@ -57,6 +63,27 @@ public class DbIPBlacklistManager extends DefaultIPBlacklistManager { break; default: } + });*/ + // nacos + ConfigService configService = nacosConfigProperties.configServiceInstance(); + configService.addListener(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class); + final IPDto ipDto = JSON.parseObject(channelMsg.getData(), IPDto.class); + String ip = ipDto.getIp(); + switch (channelMsg.getOperation()) { + case "add": + log.info("添加IP黑名单,ip:{}", ip); + add(ip); + break; + case "delete": + log.info("移除IP黑名单,ip:{}", ip); + remove(ip); + break; + default: + } + } }); } 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 6ece0b03..9e361eeb 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 @@ -1,16 +1,19 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.AbstractListener; import com.gitee.sop.gateway.entity.IsvDetailDTO; import com.gitee.sop.gateway.mapper.IsvInfoMapper; import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; import com.gitee.sop.gatewaycommon.bean.IsvDefinition; -import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; +import com.gitee.sop.gatewaycommon.bean.NacosConfigs; import com.gitee.sop.gatewaycommon.secret.CacheIsvManager; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -30,6 +33,8 @@ public class DbIsvManager extends CacheIsvManager { @Autowired Environment environment; + @Autowired + private NacosConfigProperties nacosConfigProperties; @Override public void load() { @@ -45,7 +50,7 @@ public class DbIsvManager extends CacheIsvManager { @PostConstruct protected void after() throws Exception { ApiConfig.getInstance().setIsvManager(this); - ZookeeperContext.setEnvironment(environment); + /*ZookeeperContext.setEnvironment(environment); String isvChannelPath = ZookeeperContext.getIsvInfoChannelPath(); ZookeeperContext.listenPath(isvChannelPath, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); @@ -63,6 +68,27 @@ public class DbIsvManager extends CacheIsvManager { default: } + });*/ + + ConfigService configService = nacosConfigProperties.configServiceInstance(); + configService.addListener(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class); + final IsvDefinition isvDefinition = JSON.parseObject(channelMsg.getData(), IsvDefinition.class); + switch (channelMsg.getOperation()) { + case "update": + log.info("更新ISV信息,isvDefinition:{}", isvDefinition); + update(isvDefinition); + break; + case "remove": + log.info("删除ISV,isvDefinition:{}", isvDefinition); + remove(isvDefinition.getAppKey()); + break; + default: + + } + } }); } 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 0715703a..8ea658f8 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 @@ -1,6 +1,8 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.AbstractListener; import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.gateway.entity.IsvInfo; import com.gitee.sop.gateway.entity.PermIsvRole; @@ -10,12 +12,13 @@ import com.gitee.sop.gateway.mapper.PermIsvRoleMapper; import com.gitee.sop.gateway.mapper.PermRolePermissionMapper; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; import com.gitee.sop.gatewaycommon.bean.IsvRoutePermission; +import com.gitee.sop.gatewaycommon.bean.NacosConfigs; import com.gitee.sop.gatewaycommon.manager.DefaultIsvRoutePermissionManager; -import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -51,6 +54,9 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage @Autowired IsvInfoMapper isvInfoMapper; + @Autowired + private NacosConfigProperties nacosConfigProperties; + @Override public void load() { // key: appKey, value: roleCodeList @@ -121,7 +127,7 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage @PostConstruct protected void after() throws Exception { - ZookeeperContext.setEnvironment(environment); + /*ZookeeperContext.setEnvironment(environment); String isvChannelPath = ZookeeperContext.getIsvRoutePermissionChannelPath(); ZookeeperContext.listenPath(isvChannelPath, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); @@ -155,6 +161,36 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage default: } + });*/ + + ConfigService configService = nacosConfigProperties.configServiceInstance(); + configService.addListener(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class); + final IsvRoutePermission isvRoutePermission = JSON.parseObject(channelMsg.getData(), IsvRoutePermission.class); + switch (channelMsg.getOperation()) { + case "reload": + log.info("重新加载路由权限信息,isvRoutePermission:{}", isvRoutePermission); + String listenPath = isvRoutePermission.getListenPath(); + try { + load(); + } catch (Exception e) { + log.error("重新加载路由权限失败, channelMsg:{}", channelMsg, e); + } + break; + case "update": + log.info("更新ISV路由权限信息,isvRoutePermission:{}", isvRoutePermission); + update(isvRoutePermission); + break; + case "remove": + 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 0f150334..9aab7fda 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 @@ -1,15 +1,18 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.AbstractListener; import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.gateway.mapper.ConfigLimitMapper; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; import com.gitee.sop.gatewaycommon.bean.ConfigLimitDto; +import com.gitee.sop.gatewaycommon.bean.NacosConfigs; import com.gitee.sop.gatewaycommon.manager.DefaultLimitConfigManager; -import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; import com.gitee.sop.gatewaycommon.util.MyBeanUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -29,6 +32,9 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager { @Autowired Environment environment; + @Autowired + private NacosConfigProperties nacosConfigProperties; + @Override public void load() { Query query = new Query(); @@ -47,7 +53,7 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager { @PostConstruct protected void after() throws Exception { - ZookeeperContext.setEnvironment(environment); + /*ZookeeperContext.setEnvironment(environment); String path = ZookeeperContext.getLimitConfigChannelPath(); ZookeeperContext.listenPath(path, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); @@ -64,6 +70,26 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager { break; default: } + });*/ + + ConfigService configService = nacosConfigProperties.configServiceInstance(); + configService.addListener(NacosConfigs.DATA_ID_LIMIT_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class); + final ConfigLimitDto configLimitDto = JSON.parseObject(channelMsg.getData(), ConfigLimitDto.class); + switch (channelMsg.getOperation()) { + case "reload": + log.info("重新加载限流配置信息,configLimitDto:{}", configLimitDto); + load(); + break; + case "update": + log.info("更新限流配置信息,configLimitDto:{}", configLimitDto); + update(configLimitDto); + break; + default: + } + } }); } 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 ef7125f5..4b92cdcd 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 @@ -1,18 +1,21 @@ package com.gitee.sop.gateway.manager; import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.AbstractListener; import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.gateway.mapper.ConfigRouteBaseMapper; import com.gitee.sop.gateway.mapper.ConfigRouteLimitMapper; -import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; import com.gitee.sop.gatewaycommon.bean.ChannelMsg; +import com.gitee.sop.gatewaycommon.bean.GatewayRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.NacosConfigs; import com.gitee.sop.gatewaycommon.bean.RouteConfig; import com.gitee.sop.gatewaycommon.bean.TargetRoute; import com.gitee.sop.gatewaycommon.manager.DefaultRouteConfigManager; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; -import com.gitee.sop.gatewaycommon.manager.ZookeeperContext; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -35,6 +38,9 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager { @Autowired Environment environment; + @Autowired + private NacosConfigProperties nacosConfigProperties; + @Override public void load() { loadAllRoute(); @@ -52,12 +58,12 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager { Collection targetRoutes = RouteRepositoryContext.getRouteRepository().getAll(); targetRoutes.stream() .forEach(targetRoute -> { - BaseRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); + GatewayRouteDefinition routeDefinition = targetRoute.getRouteDefinition(); initRouteConfig(routeDefinition); }); } - protected void initRouteConfig(BaseRouteDefinition routeDefinition) { + protected void initRouteConfig(GatewayRouteDefinition routeDefinition) { String routeId = routeDefinition.getId(); RouteConfig routeConfig = newRouteConfig(); routeConfig.setRouteId(routeId); @@ -71,7 +77,7 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager { @PostConstruct protected void after() throws Exception { - ZookeeperContext.setEnvironment(environment); + /*ZookeeperContext.setEnvironment(environment); String path = ZookeeperContext.getRouteConfigChannelPath(); ZookeeperContext.listenPath(path, nodeCache -> { String nodeData = new String(nodeCache.getCurrentData().getData()); @@ -88,6 +94,26 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager { break; default: } + });*/ + + ConfigService configService = nacosConfigProperties.configServiceInstance(); + configService.addListener(NacosConfigs.DATA_ID_ROUTE_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class); + final RouteConfig routeConfig = JSON.parseObject(channelMsg.getData(), RouteConfig.class); + switch (channelMsg.getOperation()) { + case "reload": + log.info("重新加载路由配置信息,routeConfigDto:{}", routeConfig); + load(); + break; + case "update": + log.info("更新路由配置信息,routeConfigDto:{}", routeConfig); + update(routeConfig); + break; + default: + } + } }); } } diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java deleted file mode 100644 index 9f260f1b..00000000 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ManagerInitializer.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gitee.sop.gateway.manager; - -import com.gitee.sop.gatewaycommon.bean.ApiConfig; - -/** - * @author tanghc - */ -public class ManagerInitializer { - - public ManagerInitializer() { - ApiConfig apiConfig = ApiConfig.getInstance(); - apiConfig.setIsvManager(new DbIsvManager()); - apiConfig.setIsvRoutePermissionManager(new DbIsvRoutePermissionManager()); - apiConfig.setRouteConfigManager(new DbRouteConfigManager()); - apiConfig.setLimitConfigManager(new DbLimitConfigManager()); - apiConfig.setIpBlacklistManager(new DbIPBlacklistManager()); - apiConfig.setUserKeyManager(new DbEnvGrayManager()); - } -} diff --git a/sop-gateway/src/main/resources/application-dev.properties b/sop-gateway/src/main/resources/application-dev.properties index 297addd1..0e80a3dd 100644 --- a/sop-gateway/src/main/resources/application-dev.properties +++ b/sop-gateway/src/main/resources/application-dev.properties @@ -37,7 +37,7 @@ ribbon.ReadTimeout=2000 # 请谨慎设置,因为post请求大多都是写入请求,如果要支持重试,确保服务的幂等性 ribbon.OkToRetryOnAllOperations=false -# nacos注册中心配置 +# nacos cloud配置 spring.cloud.nacos.discovery.server-addr=${nacos.url} # zookeeper配置 diff --git a/sop-gateway/src/main/resources/bootstrap.properties b/sop-gateway/src/main/resources/bootstrap.properties new file mode 100644 index 00000000..9af67138 --- /dev/null +++ b/sop-gateway/src/main/resources/bootstrap.properties @@ -0,0 +1,3 @@ +spring.application.name=api-gateway +# nacos的config需要放在bootstrap.properties中 +spring.cloud.nacos.config.server-addr=127.0.0.1:8848 \ No newline at end of file diff --git a/sop-gateway/src/test/java/com/gitee/sop/gateway/CuratorTest.java b/sop-gateway/src/test/java/com/gitee/sop/gateway/CuratorTest.java deleted file mode 100644 index 91ae48b7..00000000 --- a/sop-gateway/src/test/java/com/gitee/sop/gateway/CuratorTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.gitee.sop.gateway; - -import com.gitee.sop.gatewaycommon.bean.SopConstants; -import junit.framework.TestCase; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.retry.ExponentialBackoffRetry; - -/** - * @author tanghc - */ -public class CuratorTest extends TestCase { - - private String zookeeperServerAddr = "localhost:2181"; - - /** - * 递归删除节点,只能在测试环境用。 - * - * @throws Exception - */ - public void testDel() throws Exception { - CuratorFramework client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(1000, 3)) - .build(); - - client.start(); - - try { - client.delete().deletingChildrenIfNeeded().forPath(SopConstants.SOP_SERVICE_ROUTE_PATH); - } catch (Exception e) { - } - } - - /** - * 删除临时节点 - */ - public void testDelTemp() { - String tempRoot = "/com.gitee.sop.service.tmp"; - CuratorFramework client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(1000, 3)) - .build(); - - client.start(); - - try { - client.delete().deletingChildrenIfNeeded().forPath(tempRoot); - } catch (Exception e) { - } - } -} diff --git a/sop-website/website-server/pom.xml b/sop-website/website-server/pom.xml index 015d1e65..ddeb9407 100644 --- a/sop-website/website-server/pom.xml +++ b/sop-website/website-server/pom.xml @@ -12,20 +12,17 @@ website-server 1.0.0-SNAPSHOT website-server - Demo project for Spring Boot + website-server 1.8 - 3.4.12 - 4.0.1 - - com.gitee.sop - sop-registry-api - 1.15.2-SNAPSHOT + org.springframework.cloud + spring-cloud-alibaba-nacos-discovery + 0.9.0.RELEASE @@ -33,38 +30,6 @@ spring-boot-starter-web - - - org.apache.curator - curator-recipes - ${curator-recipes.version} - - - org.apache.zookeeper - zookeeper - - - - - org.apache.zookeeper - zookeeper - ${zookeeper.version} - - - org.slf4j - slf4j-log4j12 - - - - - - org.springframework.boot - spring-boot-starter-test - test - commons-lang commons-lang @@ -77,12 +42,7 @@ 3.14.0 compile - - org.projectlombok - lombok - 1.18.4 - provided - + com.alibaba fastjson @@ -94,6 +54,19 @@ httpclient 4.5.6 + + + org.projectlombok + lombok + 1.18.4 + provided + + + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java new file mode 100644 index 00000000..07362f53 --- /dev/null +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/HttpTool.java @@ -0,0 +1,381 @@ +package com.gitee.sop.websiteserver.bean; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.FormBody; +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.apache.commons.codec.digest.DigestUtils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * http请求工具,基于OKHTTP3 + * @author tanghc + */ +public class HttpTool { + private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); + + private Map> cookieStore = new HashMap>(); + + private OkHttpClient httpClient; + + public HttpTool() { + this(new HttpToolConfig()); + } + + public HttpTool(HttpToolConfig httpToolConfig) { + this.initHttpClient(httpToolConfig); + } + + protected void initHttpClient(HttpToolConfig httpToolConfig) { + httpClient = new OkHttpClient.Builder() + .connectTimeout(httpToolConfig.connectTimeoutSeconds, TimeUnit.SECONDS) // 设置链接超时时间,默认10秒 + .readTimeout(httpToolConfig.readTimeoutSeconds, TimeUnit.SECONDS) + .writeTimeout(httpToolConfig.writeTimeoutSeconds, TimeUnit.SECONDS) + .cookieJar(new CookieJar() { + public void saveFromResponse(HttpUrl httpUrl, List list) { + cookieStore.put(httpUrl.host(), list); + } + + public List loadForRequest(HttpUrl httpUrl) { + List cookies = cookieStore.get(httpUrl.host()); + return cookies != null ? cookies : new ArrayList(); + } + }).build(); + } + + @Data + public static class HttpToolConfig { + /** + * 请求超时时间 + */ + private int connectTimeoutSeconds = 10; + /** + * http读取超时时间 + */ + private int readTimeoutSeconds = 10; + /** + * http写超时时间 + */ + private int writeTimeoutSeconds = 10; + } + + /** + * get请求 + * + * @param url + * @param header + * @return + * @throws IOException + */ + public String get(String url, Map header) throws IOException { + Request.Builder builder = new Request.Builder().url(url).get(); + // 添加header + addHeader(builder, header); + + Request request = builder.build(); + Response response = httpClient.newCall(request).execute(); + return response.body().string(); + } + + /** + * 提交表单 + * + * @param url url + * @param form 参数 + * @param header header + * @param method 请求方式,post,get等 + * @return + * @throws IOException + */ + public String request(String url, Map form, Map header, HTTPMethod method) throws IOException { + Request.Builder requestBuilder = buildRequestBuilder(url, form, method); + // 添加header + addHeader(requestBuilder, header); + + Request request = requestBuilder.build(); + Response response = httpClient + .newCall(request) + .execute(); + try { + return response.body().string(); + } finally { + response.close(); + } + } + + /** + * 请求json数据,contentType=application/json + * @param url 请求路径 + * @param json json数据 + * @param header header + * @return 返回响应结果 + * @throws IOException + */ + public String requestJson(String url, String json, Map header) throws IOException { + RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json); + Request.Builder requestBuilder = new Request.Builder() + .url(url) + .post(body); + // 添加header + addHeader(requestBuilder, header); + + Request request = requestBuilder.build(); + Response response = httpClient + .newCall(request) + .execute(); + try { + return response.body().string(); + } finally { + response.close(); + } + } + + public static Request.Builder buildRequestBuilder(String url, Map form, HTTPMethod method) { + switch (method) { + case GET: + return new Request.Builder() + .url(buildHttpUrl(url, form)) + .get(); + case HEAD: + return new Request.Builder() + .url(buildHttpUrl(url, form)) + .head(); + case PUT: + return new Request.Builder() + .url(url) + .put(buildFormBody(form)); + case DELETE: + return new Request.Builder() + .url(url) + .delete(buildFormBody(form)); + default: + return new Request.Builder() + .url(url) + .post(buildFormBody(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(), String.valueOf(entry.getValue())); + } + return urlBuilder.build(); + } + + 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(), String.valueOf(entry.getValue())); + } + return paramBuilder.build(); + } + + /** + * 提交表单,并且上传文件 + * + * @param url + * @param form + * @param header + * @param files + * @return + * @throws IOException + */ + public String requestFile(String url, Map form, Map header, List files) + throws IOException { + // 创建MultipartBody.Builder,用于添加请求的数据 + MultipartBody.Builder bodyBuilder = new MultipartBody.Builder(); + bodyBuilder.setType(MultipartBody.FORM); + + for (UploadFile uploadFile : files) { + bodyBuilder.addFormDataPart(uploadFile.getName(), // 请求的名字 + uploadFile.getFileName(), // 文件的文字,服务器端用来解析的 + RequestBody.create(null, uploadFile.getFileData()) // 创建RequestBody,把上传的文件放入 + ); + } + + Set> entrySet = form.entrySet(); + for (Map.Entry entry : entrySet) { + bodyBuilder.addFormDataPart(entry.getKey(), entry.getValue()); + } + + RequestBody requestBody = bodyBuilder.build(); + + Request.Builder builder = new Request.Builder().url(url).post(requestBody); + + // 添加header + addHeader(builder, header); + + Request request = builder.build(); + Response response = httpClient.newCall(request).execute(); + try { + return response.body().string(); + } finally { + response.close(); + } + } + + private void addHeader(Request.Builder builder, Map header) { + if (header != null) { + Set> entrySet = header.entrySet(); + for (Map.Entry entry : entrySet) { + builder.addHeader(entry.getKey(), String.valueOf(entry.getValue())); + } + } + } + + public void setCookieStore(Map> cookieStore) { + this.cookieStore = cookieStore; + } + + public void setHttpClient(OkHttpClient httpClient) { + this.httpClient = httpClient; + } + + public enum HTTPMethod { + GET, + POST, + PUT, + HEAD, + DELETE; + + private HTTPMethod() { + } + + public String value() { + return this.name(); + } + + public static HTTPMethod fromValue(String v) { + return valueOf(v.toUpperCase()); + } + } + + /** + * 文件上传类 + * @author tanghc + */ + @Getter + @Setter + public static class UploadFile implements Serializable { + private static final long serialVersionUID = -1100614660944996398L; + + /** + * @param name 表单名称,不能重复 + * @param file 文件 + * @throws IOException + */ + public UploadFile(String name, File file) throws IOException { + this(name, file.getName(), FileUtil.toBytes(file)); + } + + /** + * @param name 表单名称,不能重复 + * @param fileName 文件名 + * @param input 文件流 + * @throws IOException + */ + public UploadFile(String name, String fileName, InputStream input) throws IOException { + this(name, fileName, FileUtil.toBytes(input)); + } + + /** + * @param name 表单名称,不能重复 + * @param fileName 文件名 + * @param fileData 文件数据 + */ + public UploadFile(String name, String fileName, byte[] fileData) { + super(); + this.name = name; + this.fileName = fileName; + this.fileData = fileData; + this.md5 = DigestUtils.md5Hex(fileData); + } + + private String name; + private String fileName; + private byte[] fileData; + private String md5; + + } + + public static class FileUtil { + + /** + * The default buffer size to use. + */ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + private static final int EOF = -1; + + /** + * 将文件流转换成byte[] + * @param input + * @return + * @throws IOException + */ + public static byte[] toBytes(InputStream input) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + int n = 0; + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + + while (EOF != (n = input.read(buffer))) { + output.write(buffer, 0, n); + } + return output.toByteArray(); + } + + /** + * 将文件转换成数据流 + * @param file 文件 + * @return 返回数据流 + * @throws IOException + */ + public static byte[] toBytes(File file) throws IOException { + if (file.exists()) { + if (file.isDirectory()) { + throw new IOException("File '" + file + "' exists but is a directory"); + } + if (file.canRead() == false) { + throw new IOException("File '" + file + "' cannot be read"); + } + } else { + throw new FileNotFoundException("File '" + file + "' does not exist"); + } + InputStream input = null; + try { + input = new FileInputStream(file); + return toBytes(input); + } finally { + try { + if (input != null) { + input.close(); + } + } catch (IOException ioe) { + } + } + } + } +} diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/ZookeeperContext.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/ZookeeperContext.java deleted file mode 100644 index e2cd6a85..00000000 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/ZookeeperContext.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.gitee.sop.websiteserver.bean; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; -import org.apache.curator.framework.recipes.cache.TreeCache; -import org.apache.curator.framework.recipes.cache.TreeCacheListener; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.springframework.core.env.Environment; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -import java.util.List; -import java.util.function.Consumer; - -/** - * @author tanghc - */ -@Slf4j -public class ZookeeperContext { - - private static CuratorFramework client; - - public static void setEnvironment(Environment environment) { - Assert.notNull(environment, "environment不能为null"); - initZookeeperClient(environment); - } - - public synchronized static void initZookeeperClient(Environment environment) { - if (client != null) { - return; - } - String zookeeperServerAddr = environment.getProperty("spring.cloud.zookeeper.connect-string"); - if (StringUtils.isBlank(zookeeperServerAddr)) { - throw new RuntimeException("未指定spring.cloud.zookeeper.connect-string参数"); - } - String baseSleepTimeMs = environment.getProperty("spring.cloud.zookeeper.baseSleepTimeMs"); - String maxRetries = environment.getProperty("spring.cloud.zookeeper.maxRetries"); - log.info("初始化zookeeper客户端,zookeeperServerAddr:{}, baseSleepTimeMs:{}, maxRetries:{}", - zookeeperServerAddr, baseSleepTimeMs, maxRetries); - CuratorFramework client = CuratorFrameworkFactory.builder() - .connectString(zookeeperServerAddr) - .retryPolicy(new ExponentialBackoffRetry(NumberUtils.toInt(baseSleepTimeMs, 3000), NumberUtils.toInt(maxRetries, 3))) - .build(); - - client.start(); - - setClient(client); - } - - public static String getRouteRootPath() { - return WebsiteConstants.SOP_SERVICE_ROUTE_PATH; - } - - public static String getServiceTempRootPath() { - return WebsiteConstants.SOP_SERVICE_TEMP_PATH; - } - - public static CuratorFramework getClient() { - return client; - } - - public static void setClient(CuratorFramework client) { - ZookeeperContext.client = client; - } - - public static boolean isPathExist(String path) { - try { - return client.checkExists().forPath(path) != null; - } catch (Exception e) { - return false; - } - } - - /** - * 是否有子节点 - * @param parentPath - * @return - * @throws Exception - */ - public static boolean hasChildren(String parentPath) throws Exception { - List children = client.getChildren().forPath(parentPath); - return !CollectionUtils.isEmpty(children); - } - - /** - * 创建path,如果path存在不报错,静默返回path名称 - * - * @param path - * @param data - * @return - * @throws Exception - */ - public static String createPath(String path, String data) throws Exception { - if (isPathExist(path)) { - return path; - } - return getClient().create() - // 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点 - .creatingParentContainersIfNeeded() - .forPath(path, data.getBytes()); - } - - /** - * 获取子节点信息并监听子节点 - * - * @param parentPath 父节点路径 - * @param listConsumer 子节点数据 - * @param listener 监听事件 - * @throws Exception - */ - public static void getChildrenAndListen(String parentPath, Consumer> listConsumer, PathChildrenCacheListener listener) throws Exception { - // 为子节点添加watcher - // PathChildrenCache: 监听数据节点的增删改,可以设置触发的事件 - PathChildrenCache childrenCache = new PathChildrenCache(client, parentPath, true); - - /** - * StartMode: 初始化方式 - * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件 - * NORMAL:异步初始化 - * BUILD_INITIAL_CACHE:同步初始化 - */ - childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); - - // 列出子节点数据列表,需要使用BUILD_INITIAL_CACHE同步初始化模式才能获得,异步是获取不到的 - List childDataList = childrenCache.getCurrentData(); - listConsumer.accept(childDataList); - log.info("监听子节点增删改,监听路径:{}", parentPath); - // 监听根节点下面的子节点 - childrenCache.getListenable().addListener(listener); - } - - /** - * 监听子节点的增删改 - * - * @param parentPath 父节点路径 - * @param listener - * @throws Exception - */ - public static void listenChildren(String parentPath, PathChildrenCacheListener listener) throws Exception { - // 为子节点添加watcher - // PathChildrenCache: 监听数据节点的增删改,可以设置触发的事件 - PathChildrenCache childrenCache = new PathChildrenCache(client, parentPath, true); - - /** - * StartMode: 初始化方式 - * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件 - * NORMAL:异步初始化 - * BUILD_INITIAL_CACHE:同步初始化 - */ - childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); - // 监听根节点下面的子节点 - childrenCache.getListenable().addListener(listener); - } - - /** - * 监听子节点,可以自定义层级 - * @param parentPath 父节点路径 - * @param maxDepth 层级,从1开始。比如当前监听节点/t1,目录最深为/t1/t2/t3/t4,则maxDepth=3,说明下面3级子目录全部监听 - * @param listener - * @throws Exception - */ - public static void listenChildren(String parentPath, int maxDepth, TreeCacheListener listener) throws Exception { - final TreeCache treeCache = TreeCache - .newBuilder(client, parentPath) - .setCacheData(true) - .setMaxDepth(maxDepth) - .build(); - - treeCache.getListenable().addListener(listener); - treeCache.start(); - } - -} diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/RegistryConfig.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/RegistryConfig.java deleted file mode 100644 index 1721a2d1..00000000 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/RegistryConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.gitee.sop.websiteserver.config; - -import com.gitee.sop.registryapi.config.BaseRegistryConfig; -import org.springframework.context.annotation.Configuration; - -/** - * @author tanghc - */ -@Configuration -public class RegistryConfig extends BaseRegistryConfig { - -} \ No newline at end of file diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java index 710b9fac..cdf8d8ae 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java @@ -40,6 +40,6 @@ public class WebsiteConfig implements ApplicationRunner { */ @Override public void run(ApplicationArguments args) throws Exception { - docManager.load(null); +// docManager.load(null); } } diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java index 957a9275..ed2e972e 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java @@ -4,7 +4,6 @@ import com.gitee.sop.websiteserver.bean.DocInfo; import com.gitee.sop.websiteserver.manager.DocManager; import com.gitee.sop.websiteserver.vo.DocBaseInfoVO; import com.gitee.sop.websiteserver.vo.DocInfoVO; -import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -58,14 +57,4 @@ public class DocController { return docManager.getByTitle(title); } - - // 后门地址,可手动更新文档内容,一般情况下用不到 - @GetMapping("/reload") - public String reload(String pwd) { - boolean correct = StringUtils.equals(this.pwd, pwd); - if (correct) { - docManager.load(null); - } - return String.valueOf(correct); - } } 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 794770d4..9c122e86 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,6 @@ package com.gitee.sop.websiteserver.controller; -import com.gitee.sop.registryapi.bean.HttpTool; -import com.gitee.sop.registryapi.bean.HttpTool.*; +import com.gitee.sop.websiteserver.bean.HttpTool; import com.gitee.sop.websiteserver.sign.AlipayApiException; import com.gitee.sop.websiteserver.sign.AlipaySignature; import com.gitee.sop.websiteserver.util.UploadUtil; @@ -97,10 +96,10 @@ public class SandboxController { params.put("sign", sign); Collection uploadFiles = UploadUtil.getUploadFiles(request); - List files = uploadFiles.stream() + List files = uploadFiles.stream() .map(multipartFile -> { try { - return new UploadFile(multipartFile.getName(), multipartFile.getOriginalFilename(), multipartFile.getBytes()); + return new HttpTool.UploadFile(multipartFile.getName(), multipartFile.getOriginalFilename(), multipartFile.getBytes()); } catch (IOException e) { log.error("封装文件失败", e); return null; @@ -114,7 +113,7 @@ public class SandboxController { if (!CollectionUtils.isEmpty(files)) { responseData = httpTool.requestFile(url, params, Collections.emptyMap(), files); } else { - responseData = httpTool.request(url, params, Collections.emptyMap(), HTTPMethod.fromValue(httpMethod)); + responseData = httpTool.request(url, params, Collections.emptyMap(), HttpTool.HTTPMethod.fromValue(httpMethod)); } result.apiResult = responseData; return result; diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocDiscovery.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocDiscovery.java new file mode 100644 index 00000000..96f9f55a --- /dev/null +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocDiscovery.java @@ -0,0 +1,99 @@ +package com.gitee.sop.websiteserver.manager; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.web.client.RestTemplate; + +import java.util.List; +import java.util.Objects; + +/** + * @author tanghc + */ +@Slf4j +@Service +public class DocDiscovery { + + private static final String SECRET = "b749a2ec000f4f29"; + + private static final int FIVE_SECONDS = 1000 * 5; + + @Autowired + private NacosDiscoveryProperties nacosDiscoveryProperties; + + private RestTemplate restTemplate = new RestTemplate(); + + private volatile long lastUpdateTime; + + public synchronized void refresh(DocManager docManager) { + long now = System.currentTimeMillis(); + // 5秒内只能执行一次,解决重启应用连续加载4次问题 + if (now - lastUpdateTime < FIVE_SECONDS) { + return; + } + lastUpdateTime = now; + NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); + List subscribes = null; + try { + subscribes = namingService.getSubscribeServices(); + } catch (NacosException e) { + log.error("namingService.getSubscribeServices()错误", e); + } + if (CollectionUtils.isEmpty(subscribes)) { + return; + } + // subscribe + String thisServiceId = nacosDiscoveryProperties.getService(); + for (ServiceInfo serviceInfo : subscribes) { + String serviceName = serviceInfo.getName(); + // 如果是本机服务,跳过 + if (Objects.equals(thisServiceId, serviceName) || "api-gateway".equalsIgnoreCase(serviceName)) { + continue; + } + try { + List allInstances = namingService.getAllInstances(serviceName); + if (CollectionUtils.isEmpty(allInstances)) { + log.info("{}服务下线,删除文档信息", serviceName); + // 如果没有服务列表,则删除所有路由信息 + docManager.remove(serviceName); + } else { + for (Instance instance : allInstances) { + log.info("加载服务文档,instance:{}", instance); + String url = getRouteRequestUrl(instance); + ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); + if (responseEntity.getStatusCode() == HttpStatus.OK) { + String body = responseEntity.getBody(); + log.debug("加载{}文档,文档信息:{}", serviceName, body); + docManager.addDocInfo(serviceName, body); + } + } + } + } catch (NacosException e) { + log.error("选择服务实例失败,serviceName:{}", serviceName, e); + } + } + } + + private static String getRouteRequestUrl(Instance instance) { + String query = buildQuery(SECRET); + return "http://" + instance.getIp() + ":" + instance.getPort() + "/v2/api-docs" + query; + } + + private static String buildQuery(String secret) { + String time = String.valueOf(System.currentTimeMillis()); + String source = secret + time + secret; + String sign = DigestUtils.md5DigestAsHex(source.getBytes()); + return "?time=" + time + "&sign=" + sign; + } + +} diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManager.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManager.java index 8716e269..f5490aa8 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManager.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManager.java @@ -9,9 +9,11 @@ import java.util.Collection; */ public interface DocManager { - void load(String serviceId); + void addDocInfo(String serviceId, String docJson); DocInfo getByTitle(String title); Collection listAll(); + + void remove(String serviceId); } diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java index 925ddd0d..2fb9849b 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java @@ -3,119 +3,54 @@ package com.gitee.sop.websiteserver.manager; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.Feature; -import com.gitee.sop.registryapi.bean.ServiceInfo; -import com.gitee.sop.registryapi.bean.ServiceInstance; -import com.gitee.sop.registryapi.service.RegistryService; import com.gitee.sop.websiteserver.bean.DocInfo; -import com.gitee.sop.websiteserver.bean.ZookeeperContext; -import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.math.NumberUtils; -import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import org.springframework.cloud.client.discovery.event.HeartbeatEvent; +import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.client.RestTemplate; -import javax.annotation.PostConstruct; +import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.concurrent.DelayQueue; -import java.util.concurrent.Delayed; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; +import java.util.Objects; /** * @author tanghc */ @Service @Slf4j -public class DocManagerImpl implements DocManager { +public class DocManagerImpl implements DocManager, ApplicationListener { // key:title private Map docDefinitionMap = new HashMap<>(); - private RestTemplate restTemplate = new RestTemplate(); + /** + * KEY:serviceId, value: md5 + */ + private Map serviceIdMd5Map = new HashMap<>(); private DocParser swaggerDocParser = new SwaggerDocParser(); private DocParser easyopenDocParser = new EasyopenDocParser(); - private ExecutorService executorService = Executors.newSingleThreadExecutor(); - - private DelayQueue queue = new DelayQueue<>(); - - private String secret = "b749a2ec000f4f29"; - @Autowired - private Environment environment; - - @Autowired - private RegistryService registryService; - - @Value("${doc.refresh-seconds:60}") - private String refreshSeconds; + private DocDiscovery docDiscovery; @Override - public void load(String serviceId) { - try { - List serviceInfoList = registryService.listAllService(1, 9999); - serviceInfoList - .stream() - // 网关没有文档提供,需要排除 - .filter(serviceInfo -> !"API-GATEWAY".equalsIgnoreCase(serviceInfo.getServiceId())) - .filter(serviceInfo -> !serviceInfo.getInstances().isEmpty()) - .filter(serviceInfo -> { - if (StringUtils.isEmpty(serviceId)) { - return true; - } - return serviceId.equalsIgnoreCase(serviceInfo.getServiceId()); - }) - .map(serviceInfo -> serviceInfo.getInstances().get(0)) - .collect(Collectors.toList()) - .forEach(this::loadDocInfo); - } catch (Exception e) { - log.error("加载失败", e); - } - } - - protected void loadDocInfo(ServiceInstance serviceInstance) { - String query = this.buildQuery(); - String url = "http://" + serviceInstance.getIp() + ":" + serviceInstance.getPort() + "/v2/api-docs" + query; - try { - log.info("读取swagger文档,serviceId:{}, url:{}", serviceInstance.getServiceId(), url); - ResponseEntity entity = restTemplate.getForEntity(url, String.class); - if (entity.getStatusCode() != HttpStatus.OK) { - throw new IllegalAccessException("无权访问"); - } - String docInfoJson = entity.getBody(); - JSONObject docRoot = JSON.parseObject(docInfoJson, Feature.OrderedField, Feature.DisableCircularReferenceDetect); - DocParser docParser = this.buildDocParser(docRoot); - DocInfo docInfo = docParser.parseJson(docRoot); - docInfo.setServiceId(serviceInstance.getServiceId()); - docDefinitionMap.put(docInfo.getTitle(), docInfo); - } catch (Exception e) { - // 这里报错可能是因为有些微服务没有配置swagger文档,导致404访问不到 - // 这里catch跳过即可 - log.warn("读取文档失败, url:{}, msg:{}", url, e.getMessage()); + public void addDocInfo(String serviceId, String docInfoJson) { + String newMd5 = DigestUtils.md5DigestAsHex(docInfoJson.getBytes(StandardCharsets.UTF_8)); + String md5 = serviceIdMd5Map.putIfAbsent(serviceId, newMd5); + if (Objects.equals(newMd5, md5)) { + return; } - } - - protected String buildQuery() { - String time = String.valueOf(System.currentTimeMillis()); - String source = secret + time + secret; - String sign = DigestUtils.md5DigestAsHex(source.getBytes()); - return "?time=" + time + "&sign=" + sign; + JSONObject docRoot = JSON.parseObject(docInfoJson, Feature.OrderedField, Feature.DisableCircularReferenceDetect); + DocParser docParser = this.buildDocParser(docRoot); + DocInfo docInfo = docParser.parseJson(docRoot); + docInfo.setServiceId(serviceId); + docDefinitionMap.put(docInfo.getTitle(), docInfo); } protected DocParser buildDocParser(JSONObject rootDoc) { @@ -137,143 +72,14 @@ public class DocManagerImpl implements DocManager { return docDefinitionMap.values(); } - @PostConstruct - protected void after() throws Exception { - this.listenServiceId(); - } - - /** - * 监听serviceId更改 - * - * @throws Exception - */ - protected void listenServiceId() throws Exception { - - executorService.execute(new Consumer(queue, this)); - - ZookeeperContext.setEnvironment(environment); - String serviceTempRootPath = ZookeeperContext.getServiceTempRootPath(); - ZookeeperContext.createPath(serviceTempRootPath, "{}"); - // 如果节点内容有变化则自动更新文档 - - ZookeeperContext.getChildrenAndListen(serviceTempRootPath, childDataList -> { - for (ChildData childData : childDataList) { - String serviceIdPath = childData.getPath(); - try { - boolean hasChildren = ZookeeperContext.hasChildren(serviceIdPath); - if (hasChildren) { - log.info("加载文档服务器,path:{}", serviceIdPath); - listenServiceIdPath(serviceIdPath); - } - } catch (Exception e) { - log.error("监听路径失败,serviceIdPath:{}", serviceIdPath); - } - } - }, (client, event) -> { - PathChildrenCacheEvent.Type type = event.getType(); - if (type == PathChildrenCacheEvent.Type.CHILD_ADDED) { - String serviceIdPath = event.getData().getPath(); - log.info("新增文档服务器,path:{}", serviceIdPath); - listenServiceIdPath(serviceIdPath); - } - }); - } - - private void listenServiceIdPath(String serviceIdPath) throws Exception { - ZookeeperContext.listenChildren(serviceIdPath, (client, event) -> { - String path = event.getData().getPath(); - PathChildrenCacheEvent.Type type = event.getType(); - log.info("服务节点变更,path:{}, eventType:{}", path, event.getType().name()); - if (type == PathChildrenCacheEvent.Type.CHILD_ADDED - || type == PathChildrenCacheEvent.Type.CHILD_UPDATED) { - byte[] data = event.getData().getData(); - String serviceInfoJson = new String(data); - if (StringUtils.isEmpty(serviceInfoJson)) { - return; - } - ZKServiceInfo serviceInfo = JSON.parseObject(serviceInfoJson, ZKServiceInfo.class); - String serviceId = serviceInfo.getServiceId(); - int delaySeconds = NumberUtils.toInt(refreshSeconds, 60); - log.info("微服务[{}]推送更新,{}秒后加载文档内容", serviceId, delaySeconds); - long id = System.currentTimeMillis(); - Msg msg = new Msg(id, delaySeconds * 1000); - msg.serviceId = serviceId; - // 延迟20秒执行 - queue.offer(msg); - } else if (event.getType() == PathChildrenCacheEvent.Type.CHILD_REMOVED) { - byte[] data = event.getData().getData(); - String serviceInfoJson = new String(data); - ZKServiceInfo serviceInfo = JSON.parseObject(serviceInfoJson, ZKServiceInfo.class); - String serviceId = serviceInfo.getServiceId(); - boolean hasChildren = ZookeeperContext.hasChildren(serviceIdPath); - // 如果没有子节点就删除 - if (!hasChildren) { - log.info("服务节点已删除,删除对应文档信息,path:{}", event.getData().getPath()); - removeDoc(serviceId); - } - } - }); - } - - public void removeDoc(String serviceId) { + @Override + public void remove(String serviceId) { docDefinitionMap.entrySet().removeIf(entry -> serviceId.equalsIgnoreCase(entry.getValue().getServiceId())); } - static class Msg implements Delayed { - private long id; - private long delay; - private String serviceId; - - // 自定义实现比较方法返回 1 0 -1三个参数 - - - public Msg(long id, long delay) { - this.id = id; - this.delay = delay + System.currentTimeMillis(); - } - - @Override - public int compareTo(Delayed delayed) { - Msg msg = (Msg) delayed; - return Long.compare(this.id, msg.id); - } - - // 延迟任务是否到时就是按照这个方法判断如果返回的是负数则说明到期否则还没到期 - @Override - public long getDelay(TimeUnit unit) { - return unit.convert(this.delay - System.currentTimeMillis(), TimeUnit.MILLISECONDS); - } - } - - @Data - static class ZKServiceInfo { - /** 服务名称,对应spring.application.name */ - private String serviceId; - - private String description; + @Override + public void onApplicationEvent(HeartbeatEvent heartbeatEvent) { + docDiscovery.refresh(this); } - @Slf4j - static class Consumer implements Runnable { - private DelayQueue queue; - private DocManager docManager; - - public Consumer(DelayQueue queue, DocManager docManager) { - this.queue = queue; - this.docManager = docManager; - } - - @Override - public void run() { - while (true) { - try { - Msg msg = queue.take(); - log.info("延迟队列触发--重新加载文档信息"); - docManager.load(msg.serviceId); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } } diff --git a/sop-website/website-server/src/main/resources/application-dev.properties b/sop-website/website-server/src/main/resources/application-dev.properties index 59fabaed..c8a6582f 100644 --- a/sop-website/website-server/src/main/resources/application-dev.properties +++ b/sop-website/website-server/src/main/resources/application-dev.properties @@ -2,9 +2,6 @@ server.port=8083 spring.application.name=website-server # ------- 需要改的配置 ------- - -# eureka注册中心地址 -eureka.url=http://localhost:1111/eureka/ # zookeeper地址 zookeeper.url=localhost:2181 # nacos地址 @@ -12,15 +9,8 @@ nacos.url=127.0.0.1:8848 # ------- 需要改的配置end ------- -# eureka注册中心地址,这里只是参数,并不会去注册 -registry.eureka-server-addr=${eureka.url} -# nacos服务器地址 -registry.nacos-server-addr=${nacos.url} -# 使用eureka,填:eureka,使用nacos填:nacos -registry.name=nacos - -# zookeeper配置 -spring.cloud.zookeeper.connect-string=${zookeeper.url} +# nacos cloud配置 +spring.cloud.nacos.discovery.server-addr=${nacos.url} # 测试环境 api.url-test=http://api-test.yourdomain.com/api From bf4b920e17563af0c9daefda611964c46da3de8a Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 21 Aug 2019 11:58:23 +0800 Subject: [PATCH 07/82] =?UTF-8?q?=E5=85=A8=E9=9D=A2=E4=BD=BF=E7=94=A8nacos?= =?UTF-8?q?=EF=BC=8C=E8=88=8D=E5=BC=83zookeeper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sop/gatewaycommon/manager/DefaultEnvGrayManager.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 bdfc8760..9e6df3be 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 @@ -22,15 +22,14 @@ public class DefaultEnvGrayManager implements EnvGrayManager { @Override public void saveServiceGrayConfig(ServiceGrayConfig serviceGrayConfig) { - serviceGrayConfigMap.putIfAbsent(serviceGrayConfig.getServiceId(), serviceGrayConfig); + serviceGrayConfigMap.put(serviceGrayConfig.getServiceId(), serviceGrayConfig); } @Override - public boolean containsKey(String instanceId, Object userKey) { - if (instanceId == null || userKey == null) { + public boolean containsKey(String serviceId, Object userKey) { + if (serviceId == null || userKey == null) { return false; } - String serviceId = instanceIdServiceIdMap.get(instanceId); ServiceGrayConfig grayConfig = this.getGrayConfig(serviceId); return grayConfig != null && grayConfig.containsKey(userKey); } From c7451c84f91c2ab36f4836865cc7ed4648223dd1 Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 21 Aug 2019 12:35:07 +0800 Subject: [PATCH 08/82] =?UTF-8?q?=E5=85=A8=E9=9D=A2=E4=BD=BF=E7=94=A8nacos?= =?UTF-8?q?=EF=BC=8C=E8=88=8D=E5=BC=83zookeeper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/dashboard/dashboard.html | 2 +- .../adminserver/api/service/ServiceApi.java | 59 ++++--------------- .../sop/adminserver/bean/ChannelMsg.java | 12 ++++ .../service/ConfigPushService.java | 4 +- .../src/main/resources/public/index.html | 2 +- ...31fb07.css => chunk-510c5a69.5e48e29a.css} | 2 +- .../js/{app.8145abe4.js => app.4f45e42d.js} | 2 +- ...98e1e7e5.js => chunk-510c5a69.93406082.js} | 2 +- .../static/js/chunk-9b31c83a.2758df30.js | 1 - .../static/js/chunk-9b31c83a.355cc725.js | 1 + ...53fe8d4e.js => chunk-9f479afe.c1cbb02b.js} | 2 +- .../sop-admin-vue/src/views/service/limit.vue | 2 +- .../sop-admin-vue/src/views/service/route.vue | 3 +- .../src/views/service/serviceList.vue | 38 ++++++++---- .../gatewaycommon/manager/BaseRouteCache.java | 6 +- .../gatewaycommon/manager/EnvGrayManager.java | 4 +- .../zuul/filter/PreVersionDecisionFilter.java | 2 +- .../zuul/loadbalancer/BaseServerChooser.java | 3 +- .../service/impl/RegistryServiceNacos.java | 8 ++- .../EnvironmentServerChooser.java | 17 ------ .../sop/gateway/manager/DbEnvGrayManager.java | 4 -- .../gateway/manager/DbIPBlacklistManager.java | 6 +- .../sop/gateway/manager/DbIsvManager.java | 6 +- .../websiteserver/manager/DocManagerImpl.java | 5 +- 24 files changed, 82 insertions(+), 111 deletions(-) rename sop-admin/sop-admin-server/src/main/resources/public/static/css/{chunk-34c76be7.f531fb07.css => chunk-510c5a69.5e48e29a.css} (85%) rename sop-admin/sop-admin-server/src/main/resources/public/static/js/{app.8145abe4.js => app.4f45e42d.js} (99%) rename sop-admin/sop-admin-server/src/main/resources/public/static/js/{chunk-34c76be7.98e1e7e5.js => chunk-510c5a69.93406082.js} (76%) delete mode 100644 sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.2758df30.js create mode 100644 sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.355cc725.js rename sop-admin/sop-admin-server/src/main/resources/public/static/js/{chunk-9f479afe.53fe8d4e.js => chunk-9f479afe.c1cbb02b.js} (62%) diff --git a/sop-admin/sop-admin-front/pages/dashboard/dashboard.html b/sop-admin/sop-admin-front/pages/dashboard/dashboard.html index ab949e74..75a990d8 100644 --- a/sop-admin/sop-admin-front/pages/dashboard/dashboard.html +++ b/sop-admin/sop-admin-front/pages/dashboard/dashboard.html @@ -56,7 +56,7 @@