From c8598b5a0e7951f901727de39e6ee7bb58a59b34 Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 5 Aug 2020 11:08:18 +0800 Subject: [PATCH 01/10] 4.0.2 --- doc/docs/files/10100_提供restful接口.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/docs/files/10100_提供restful接口.md b/doc/docs/files/10100_提供restful接口.md index 2aef7b1f..1be388a3 100644 --- a/doc/docs/files/10100_提供restful接口.md +++ b/doc/docs/files/10100_提供restful接口.md @@ -1,4 +1,4 @@ -# 提供rest接口 +# 提供restful接口 有些接口没有被开放,但是也想要通过网关来访问,SOP提供一个固定的请求格式来访问。 From 8239a536b96defb9bf90d2ea2f97175b37177811 Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 5 Aug 2020 11:32:17 +0800 Subject: [PATCH 02/10] 4.0.2 --- .../com/gitee/sop/sdk/client/OpenClient.java | 17 +++++++++-------- .../sop/sdk/request/DemoFileUploadRequest.java | 2 +- .../gitee/sop/sdk/request/GetStoryRequest.java | 2 +- .../gitee/sop/sdk/response/BaseResponse.java | 2 ++ .../test/java/com/gitee/sop/sdk/SdkTest.java | 8 ++++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java index 342a5af1..c7232504 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java @@ -2,6 +2,7 @@ package com.gitee.sop.sdk.client; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; import com.gitee.sop.sdk.common.DataNameBuilder; import com.gitee.sop.sdk.common.OpenConfig; import com.gitee.sop.sdk.common.RequestForm; @@ -36,17 +37,17 @@ public class OpenClient { /** * 接口请求url */ - private String url; + private final String url; /** * 平台提供的appId */ - private String appId; + private final String appId; /** * 开放平台提供的私钥 */ - private String privateKey; + private final String privateKey; /** * 开放平台提供的公钥 @@ -56,17 +57,17 @@ public class OpenClient { /** * 配置项 */ - private OpenConfig openConfig; + private final OpenConfig openConfig; /** * 请求对象 */ - private OpenRequest openRequest; + private final OpenRequest openRequest; /** * 节点处理 */ - private DataNameBuilder dataNameBuilder; + private final DataNameBuilder dataNameBuilder; /** * 构建请求客户端 @@ -193,7 +194,7 @@ public class OpenClient { protected T parseResponse(String resp, BaseRequest request) { String method = request.getMethod(); String rootNodeName = dataNameBuilder.build(method); - JSONObject jsonObject = JSON.parseObject(resp); + JSONObject jsonObject = JSON.parseObject(resp, Feature.OrderedField); String errorResponseName = this.openConfig.getErrorResponseName(); boolean errorResponse = jsonObject.containsKey(errorResponseName); if (errorResponse) { @@ -210,7 +211,7 @@ public class OpenClient { } } T t = data.toJavaObject(request.getResponseClass()); - t.setBody(data.toJSONString()); + t.setBody(jsonObject.getString(rootNodeName)); return t; } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/DemoFileUploadRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/DemoFileUploadRequest.java index b5b6c340..c9943d0c 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/DemoFileUploadRequest.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/DemoFileUploadRequest.java @@ -8,6 +8,6 @@ import com.gitee.sop.sdk.response.DemoFileUploadResponse; public class DemoFileUploadRequest extends BaseRequest { @Override protected String method() { - return "demo.file.upload"; + return "file.upload"; } } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/GetStoryRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/GetStoryRequest.java index e8a1f062..077d1e9f 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/GetStoryRequest.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/GetStoryRequest.java @@ -5,7 +5,7 @@ import com.gitee.sop.sdk.response.GetStoryResponse; public class GetStoryRequest extends BaseRequest { @Override protected String method() { - return "alipay.story.find"; + return "story.get"; } } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java index 23bbf469..9536c043 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/BaseResponse.java @@ -22,6 +22,8 @@ import lombok.Setter; @Getter public abstract class BaseResponse { + @JSONField(name = "request_id") + private String requestId; private String code; private String msg; @JSONField(name = "sub_code") diff --git a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java index 4a843610..8ba796a2 100644 --- a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java +++ b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java @@ -48,19 +48,19 @@ public class SdkTest extends TestCase { if (response.isSuccess()) { // 返回结果 - System.out.println(String.format("成功!response:%s\n响应原始内容:%s", - JSON.toJSONString(response), response.getBody())); + System.out.println(String.format("response:%s", + JSON.toJSONString(response))); } else { System.out.println("错误,subCode:" + response.getSubCode() + ", subMsg:" + response.getSubMsg()); } } - // 懒人版,如果不想添加Request,Response,Model。可以用这种方式,返回全部是String,后续自己处理json + // 懒人版,如果不想添加Request,Response,可以用这种方式,返回全部是String,后续自己处理json @Test public void testLazy() { // 创建请求对象 - CommonRequest request = new CommonRequest("alipay.story.find"); + CommonRequest request = new CommonRequest("story.get"); // 请求参数 Map bizModel = new HashMap<>(); bizModel.put("name", "白雪公主"); From 49cd8f7fdafd48610da966cf6b28a6a96c9f1a43 Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 5 Aug 2020 11:34:50 +0800 Subject: [PATCH 03/10] 4.0.2 --- sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/BaseTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/BaseTest.java b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/BaseTest.java index 9798d2a1..310beea5 100644 --- a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/BaseTest.java +++ b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/BaseTest.java @@ -1,6 +1,5 @@ package com.gitee.sop.sdk; -import com.gitee.sop.sdk.client.OpenClient; import junit.framework.TestCase; public class BaseTest extends TestCase { From f1d8cc831882d5f430b2e732888de7704a10bf6a Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 10 Aug 2020 11:12:02 +0800 Subject: [PATCH 04/10] 4.0.2 --- .../java/com/gitee/app/config/OpenServletContextListener.java | 2 +- .../sop-story/src/main/resources/application-dev.properties | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java index fc99a94f..8b65ed64 100644 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java +++ b/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java @@ -27,7 +27,7 @@ public class OpenServletContextListener implements ServletContextListener { NamingService namingService = webApplicationContext.getBean(NamingService.class); try { - namingService.deregisterInstance(serviceId, ip, Integer.valueOf(port)); + namingService.deregisterInstance(serviceId, ip, Integer.parseInt(port)); } catch (NacosException e) { log.error("注销nacos服务失败,serviceId:{}, ip:{}, port:{}", serviceId, ip, port); } diff --git a/sop-example/sop-story/src/main/resources/application-dev.properties b/sop-example/sop-story/src/main/resources/application-dev.properties index 435c9b99..ea5b6216 100644 --- a/sop-example/sop-story/src/main/resources/application-dev.properties +++ b/sop-example/sop-story/src/main/resources/application-dev.properties @@ -2,5 +2,4 @@ server.port=2222 spring.application.name=story-service # 注册中心 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 -eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ From 315177677c8fd8b3f55255b6884ed4137be92146 Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 10 Aug 2020 11:16:48 +0800 Subject: [PATCH 05/10] 4.0.2 --- sop-website/src/main/resources/application-dev.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/sop-website/src/main/resources/application-dev.properties b/sop-website/src/main/resources/application-dev.properties index 49feb0aa..249ca94a 100644 --- a/sop-website/src/main/resources/application-dev.properties +++ b/sop-website/src/main/resources/application-dev.properties @@ -12,8 +12,6 @@ gateway.url=http://localhost:8081 ## nacos cloud配置 spring.cloud.nacos.discovery.server-addr=${register.url} -# eureka地址 -eureka.client.serviceUrl.defaultZone=${register.url} # 页面上显示的测试环境地址 api.url-test=http://open-test.yourdomain.com From 42979771ee4287005ad9a772ff93e706f941198d Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 10 Aug 2020 11:34:21 +0800 Subject: [PATCH 06/10] 4.0.2 --- .../sop/adminserver/api/config/ConfigListApi.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/config/ConfigListApi.java diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/config/ConfigListApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/config/ConfigListApi.java deleted file mode 100644 index 3ee17826..00000000 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/config/ConfigListApi.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.sop.adminserver.api.config; - -import com.gitee.easyopen.annotation.ApiService; -import com.gitee.easyopen.doc.annotation.ApiDoc; - -/** - * @author tanghc - */ -@ApiService -@ApiDoc("配置列表") -public class ConfigListApi { - -} From 160e57df0e655ef41969baaeac876d18cd0ab717 Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 10 Aug 2020 17:18:20 +0800 Subject: [PATCH 07/10] 4.0.2 --- sop-sdk/sdk-nodejs/.gitignore | 16 ++ sop-sdk/sdk-nodejs/aa.txt | 1 + sop-sdk/sdk-nodejs/bb.txt | 1 + sop-sdk/sdk-nodejs/common/Class.js | 125 +++++++++++++++ sop-sdk/sdk-nodejs/common/OpenClient.js | 151 ++++++++++++++++++ sop-sdk/sdk-nodejs/common/RequestType.js | 6 + sop-sdk/sdk-nodejs/common/SignUtil.js | 88 ++++++++++ sop-sdk/sdk-nodejs/main.js | 43 +++++ sop-sdk/sdk-nodejs/package.json | 17 ++ sop-sdk/sdk-nodejs/readme.md | 10 ++ sop-sdk/sdk-nodejs/request/BaseRequest.js | 48 ++++++ sop-sdk/sdk-nodejs/request/StoryGetRequest.js | 22 +++ sop-sdk/sdk-nodejs/testClass.js | 52 ++++++ 13 files changed, 580 insertions(+) create mode 100644 sop-sdk/sdk-nodejs/.gitignore create mode 100644 sop-sdk/sdk-nodejs/aa.txt create mode 100644 sop-sdk/sdk-nodejs/bb.txt create mode 100644 sop-sdk/sdk-nodejs/common/Class.js create mode 100644 sop-sdk/sdk-nodejs/common/OpenClient.js create mode 100644 sop-sdk/sdk-nodejs/common/RequestType.js create mode 100644 sop-sdk/sdk-nodejs/common/SignUtil.js create mode 100644 sop-sdk/sdk-nodejs/main.js create mode 100644 sop-sdk/sdk-nodejs/package.json create mode 100644 sop-sdk/sdk-nodejs/readme.md create mode 100644 sop-sdk/sdk-nodejs/request/BaseRequest.js create mode 100644 sop-sdk/sdk-nodejs/request/StoryGetRequest.js create mode 100644 sop-sdk/sdk-nodejs/testClass.js diff --git a/sop-sdk/sdk-nodejs/.gitignore b/sop-sdk/sdk-nodejs/.gitignore new file mode 100644 index 00000000..9ad28d23 --- /dev/null +++ b/sop-sdk/sdk-nodejs/.gitignore @@ -0,0 +1,16 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +package-lock.json +tests/**/coverage/ + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/sop-sdk/sdk-nodejs/aa.txt b/sop-sdk/sdk-nodejs/aa.txt new file mode 100644 index 00000000..524527cb --- /dev/null +++ b/sop-sdk/sdk-nodejs/aa.txt @@ -0,0 +1 @@ +hello你好123 \ No newline at end of file diff --git a/sop-sdk/sdk-nodejs/bb.txt b/sop-sdk/sdk-nodejs/bb.txt new file mode 100644 index 00000000..85f8e329 --- /dev/null +++ b/sop-sdk/sdk-nodejs/bb.txt @@ -0,0 +1 @@ +文件bb的内容 \ No newline at end of file diff --git a/sop-sdk/sdk-nodejs/common/Class.js b/sop-sdk/sdk-nodejs/common/Class.js new file mode 100644 index 00000000..e066def1 --- /dev/null +++ b/sop-sdk/sdk-nodejs/common/Class.js @@ -0,0 +1,125 @@ +/** + * 面相对象辅助类,可实现类的创建,继承,方法重写 + * +
+ //-------------------------
+ // JS类的创建,继承
+ //-------------------------
+
+ // 例子1:-------------------------
+ // 创建一个父类
+ var Person = Class.create({
+        // 构造函数
+        init:function(option){
+            this.name = option.name;
+        }
+        ,getName:function() {
+            return this.name;
+        }
+    });
+
+ // 声明类实例
+ var Jim = new Person({name:'Jim'});
+ console.log('Jim name:' + Jim.getName())
+
+ //例子2:-------------------------
+
+ // 创建一个类,继承Person类,并重写getName
+ var Man = Class.create({
+        init:function(option) {
+            this._super(option);// 调用父类构造函数
+            this.age = option.age;
+        }
+        // 重写父类方法
+        ,getName:function() {
+            // 调用父类的getName()
+            var name = this._super();
+            return '我重写了getName方法:{'+name+'}';
+        }
+    },Person);
+
+ var man = new Man({name:'Tom',age:22});
+ console.log('man name:' + man.getName())
+
+ console.log('Jim instanceof Person: ' + (Jim instanceof Person));
+ console.log('man instanceof Person: ' + (man instanceof Person));
+ 
+ * + */ +exports.Class = (function () { + // ------Class Creation------ + var initializing = false, + fnTest = /xyz/.test(function () { + xyz; + }) ? /\b_super\b/ : /.*/; + + // The base Class implementation (does nothing) + this.Class = function () { + }; + + // Create a new Class that inherits from this class + Class.extend = function (prop) { + var _super = this.prototype; + + // Instantiate a base class (but only create the instance, + // don't run the init constructor) + initializing = true; + var prototype = new this(); + initializing = false; + + // Copy the properties over onto the new prototype + for (var name in prop) { + // Check if we're overwriting an existing function + prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function (name, fn) { + return function () { + var tmp = this._super; + + // Add a new ._super() method that is the same method + // but on the super-class + this._super = _super[name]; + + // The method only need to be bound temporarily, so we + // remove it when we're done executing + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) : prop[name]; + } + + // The dummy class constructor + function Class() { + // All construction is actually done in the init method + if (!initializing && this.init) this.init.apply(this, arguments); + } + + // Populate our constructed prototype object + Class.prototype = prototype; + + // Enforce the constructor to be what we expect + Class.prototype.constructor = Class; + + // And make this class extendable + Class.extend = arguments.callee; + + return Class; + };// ------Class Creation end------ + + + + return { + /** + * 创建一个类 + * @param option 类方法,json数据 + * @param parentClass 父类 + */ + create: function (option, parentClass) { + if (!parentClass) { + parentClass = Class; + } + return parentClass.extend(option); + } + }; + +})(); diff --git a/sop-sdk/sdk-nodejs/common/OpenClient.js b/sop-sdk/sdk-nodejs/common/OpenClient.js new file mode 100644 index 00000000..1707ddf9 --- /dev/null +++ b/sop-sdk/sdk-nodejs/common/OpenClient.js @@ -0,0 +1,151 @@ +const needle = require('needle') +const moment = require('moment') + +const {Class} = require("./Class"); +const {RequestType} = require('./RequestType') +const {SignUtil} = require('./SignUtil') +const {BaseRequest} = require('../request/BaseRequest') + +const HEADERS = {'Accept-Encoding': 'identity'} + +const getHeaders = function (headers) { + if (!headers) { + return HEADERS + } + for (const key in HEADERS) { + headers[key] = HEADERS[key]; + } + return headers +} + +const OpenClient = Class.create({ + /** + * 初始化客户端 + * @param appId 应用ID + * @param privateKey 应用私钥,2048位,PKCS8 + * @param url 请求url + */ + init: function (appId, privateKey, url) { + this.appId = appId; + this.privateKey = privateKey; + this.url = url; + }, + /** + * 发送请求 + * @param request 请求类 + * @param callback 回调函数,参数json + */ + execute: function (request, callback) { + this.executeToken(request, null, callback) + }, + /** + * 发送请求 + * @param request 请求类 + * @param token token + * @param callback 回调函数,参数json + */ + executeToken: function (request, token, callback) { + if (!(request instanceof BaseRequest)) { + throw 'request类未继承BaseRequest' + } + const requestType = request.getRequestType(); + if (request.files) { + this._postFile(request, callback); + } else { + switch (requestType) { + case RequestType.GET: + this._get(request, callback); + break + case RequestType.POST_FORM: + this._postForm(request, callback); + break + case RequestType.POST_JSON: + this._postJson(request, callback); + break + case RequestType.POST_FILE: + this._postFile(request, callback); + break + default :{ + throw 'request.getRequestType()类型不正确' + } + } + } + }, + _get: function(request, callback) { + const allParams = this._buildParams(request) + const that = this + // needle.request(method, url, data[, options][, callback]) + needle.request('GET',this.url, allParams, { + headers: getHeaders() + }, function(error, response) { + callback(that._parseResponse(error, response, request)) + }); + }, + _postForm: function (request, callback) { + const allParams = this._buildParams(request) + const that = this + needle.request('POST',this.url, allParams, { + headers: getHeaders({ + 'Content-Type': 'application/x-www-form-urlencoded' + }) + }, function(error, response) { + callback(that._parseResponse(error, response, request)) + }); + }, + _postJson: function (request, callback) { + const allParams = this._buildParams(request) + const that = this + needle.request('POST',this.url, allParams, { + headers: getHeaders(), json: true + }, function(error, response) { + callback(that._parseResponse(error, response, request)) + }); + }, + _postFile: function (request, callback) { + const allParams = this._buildParams(request) + const files = request.files; + files.forEach(row => { + // 设置成{ file: row.path, content_type: 'application/octet-stream' }格式 + // needle会认为是上传文件 + allParams[row.name] = { file: row.path, content_type: 'application/octet-stream' } + }) + const that = this + needle.request('POST',this.url, allParams, { + headers: getHeaders(), multipart: true + }, function(error, response) { + callback(that._parseResponse(error, response, request)) + }); + }, + _parseResponse: function (error, response, request) { + if (!error && response.statusCode === 200) { + return request.parseResponse(response.body) + } else { + throw '请求异常:' + error + } + }, + _buildParams: function (request, token) { + const allParams = { + 'app_id': this.appId, + 'method': request.getMethod(), + 'charset': 'UTF-8', + 'sign_type': 'RSA2', + 'timestamp': moment().format('YYYY-MM-DD HH:mm:ss'), + 'version': request.getVersion() + } + const bizModel = request.bizModel + + for (const key in bizModel) { + allParams[key] = bizModel[key] + } + + if (token) { + allParams['app_auth_token'] = token + } + // 创建签名 + const sign = SignUtil.createSign(allParams, this.privateKey, 'RSA2') + allParams.sign = sign + return allParams; + } +}) + +module.exports = OpenClient diff --git a/sop-sdk/sdk-nodejs/common/RequestType.js b/sop-sdk/sdk-nodejs/common/RequestType.js new file mode 100644 index 00000000..e64db59d --- /dev/null +++ b/sop-sdk/sdk-nodejs/common/RequestType.js @@ -0,0 +1,6 @@ +exports.RequestType = { + GET: 'GET', + POST_FORM: 'POST_FORM', + POST_JSON: 'POST_JSON', + POST_FILE: 'POST_FILE' +} diff --git a/sop-sdk/sdk-nodejs/common/SignUtil.js b/sop-sdk/sdk-nodejs/common/SignUtil.js new file mode 100644 index 00000000..03d757a6 --- /dev/null +++ b/sop-sdk/sdk-nodejs/common/SignUtil.js @@ -0,0 +1,88 @@ +const {KJUR, hextob64} = require('jsrsasign') + +const HashMap = { + SHA256withRSA: 'SHA256withRSA', + SHA1withRSA: 'SHA1withRSA' +} + +const PEM_BEGIN = '-----BEGIN PRIVATE KEY-----\n' +const PEM_END = '\n-----END PRIVATE KEY-----' + +/** + * rsa签名参考:https://www.jianshu.com/p/145eab95322c + */ +exports.SignUtil = { + /** + * 创建签名 + * @param params 请求参数 + * @param privateKey 私钥,PKCS8 + * @param signType 签名类型,RSA,RSA2 + * @returns 返回签名内容 + */ + createSign(params, privateKey, signType) { + const content = this.getSignContent(params) + return this.sign(content, privateKey, signType) + }, + sign: function (content, privateKey, signType) { + if (signType.toUpperCase() === 'RSA') { + return this.rsaSign(content, privateKey, HashMap.SHA1withRSA) + } else if (signType.toUpperCase() === 'RSA2') { + return this.rsaSign(content, privateKey, HashMap.SHA256withRSA) + } else { + throw 'signType错误' + } + }, + /** + * rsa签名 + * @param content 签名内容 + * @param privateKey 私钥 + * @param hash hash算法,SHA256withRSA,SHA1withRSA + * @returns 返回签名字符串,base64 + */ + rsaSign: function (content, privateKey, hash) { + privateKey = this._formatKey(privateKey) + // 创建 Signature 对象 + const signature = new KJUR.crypto.Signature({ + alg: hash, + //!这里指定 私钥 pem! + prvkeypem: privateKey + }) + signature.updateString(content) + const signData = signature.sign() + // 将内容转成base64 + return hextob64(signData) + }, + _formatKey: function (key) { + if (!key.startsWith(PEM_BEGIN)) { + key = PEM_BEGIN + key + } + if (!key.endsWith(PEM_END)) { + key = key + PEM_END + } + return key + }, + /** + * 获取签名内容 + * @param params 请求参数 + * @returns {string} + */ + getSignContent: function (params) { + const paramNames = [] + for(const key in params) { + paramNames.push(key) + } + + paramNames.sort() + + const paramNameValue = [] + + for (let i = 0, len = paramNames.length; i < len; i++) { + const paramName = paramNames[i]; + const val = params[paramName]; + if (paramName && val) { + paramNameValue.push(`${paramName}=${val}`) + } + } + return paramNameValue.join('&') + } +} diff --git a/sop-sdk/sdk-nodejs/main.js b/sop-sdk/sdk-nodejs/main.js new file mode 100644 index 00000000..4745e990 --- /dev/null +++ b/sop-sdk/sdk-nodejs/main.js @@ -0,0 +1,43 @@ +const OpenClient = require('./common/OpenClient') + +const {StoryGetRequest} = require('./request/StoryGetRequest') + +// 应用ID +const appId = '2019032617262200001' +// 应用私钥,2048位,PKCS8 +const privateKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=' +// 接口url +const url = 'http://localhost:8081' + +// 创建客户端 +const openClient = new OpenClient(appId, privateKey, url) + +function test() { + // 创建请求 + const request = new StoryGetRequest() + + // 设置业务参数 + request.bizModel = { + name: 'jim' + } + + // 添加上传文件 + // request.files = [ + // // name: 表单名称,path:文件全路径 + // {name: 'file1', path: `${__dirname}/aa.txt`}, + // {name: 'file2', path: `${__dirname}/bb.txt`} + // ] + + openClient.execute(request, data => { + // 成功 + if (!data.sub_code) { + console.log('成功', data); + } else { + console.error('失败', data) + } + }) +} + + +test() + diff --git a/sop-sdk/sdk-nodejs/package.json b/sop-sdk/sdk-nodejs/package.json new file mode 100644 index 00000000..d1611bd4 --- /dev/null +++ b/sop-sdk/sdk-nodejs/package.json @@ -0,0 +1,17 @@ +{ + "name": "sdk-nodejs", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "jsrsasign": "^8.0.19", + "moment": "^2.27.0", + "needle": "^2.5.0" + } +} diff --git a/sop-sdk/sdk-nodejs/readme.md b/sop-sdk/sdk-nodejs/readme.md new file mode 100644 index 00000000..79b852e5 --- /dev/null +++ b/sop-sdk/sdk-nodejs/readme.md @@ -0,0 +1,10 @@ +- 执行`npm install --registry=https://registry.npm.taobao.org` + +- 执行`node main.js`进行测试 + +## 封装步骤 + +1. 新建request类,继承BaseRequest,参考`StoryGetRequest.js` + +2. 调用接口,参考`main.js` + diff --git a/sop-sdk/sdk-nodejs/request/BaseRequest.js b/sop-sdk/sdk-nodejs/request/BaseRequest.js new file mode 100644 index 00000000..7720828b --- /dev/null +++ b/sop-sdk/sdk-nodejs/request/BaseRequest.js @@ -0,0 +1,48 @@ +const {Class} = require("../common/Class"); + +/** + * 请求类父类 + */ +exports.BaseRequest = Class.create({ + init: function(){ + this.bizModel = {} + /* + [ + {name: 'file1', path: 'd:/dd/1.txt'}, + {name: 'file2', path: 'd:/dd/2.txt'} + ] + */ + this.files = [] + }, + /** + * 返回接口名称 + */ + getMethod: function() { + throw `未实现BaseRequest类getMethod()方法`; + }, + /** + * 返回版本号 + */ + getVersion: function() { + throw '未实现BaseRequest类getVersion()方法'; + }, + /** + * 返回请求类型,使用RequestType.js + */ + getRequestType: function() { + throw '未实现BaseRequest类getRequestType()方法'; + }, + /** + * 解析返回结果,子类可以覆盖实现 + * @param responseData 服务器返回内容 + * @returns 返回结果 + */ + parseResponse: function (responseData) { + let data = responseData['error_response']; + if (!data) { + const dataNodeName = this.getMethod().replace(/\./g, '_') + '_response' + data = responseData[dataNodeName] + } + return data; + } +}) diff --git a/sop-sdk/sdk-nodejs/request/StoryGetRequest.js b/sop-sdk/sdk-nodejs/request/StoryGetRequest.js new file mode 100644 index 00000000..fb66c2f6 --- /dev/null +++ b/sop-sdk/sdk-nodejs/request/StoryGetRequest.js @@ -0,0 +1,22 @@ +const {Class} = require("../common/Class"); +const {RequestType} = require("../common/RequestType"); +const {BaseRequest} = require('./BaseRequest') + +/** + * 创建一个请求类,继承BaseRequest,重写三个函数 + */ +const StoryGetRequest = Class.create({ + + getMethod: function () { + return "story.get" + }, + getVersion: function () { + return "1.0" + }, + getRequestType: function () { + return RequestType.GET + } + +}, BaseRequest) // 继承BaseRequest + +module.exports.StoryGetRequest = StoryGetRequest diff --git a/sop-sdk/sdk-nodejs/testClass.js b/sop-sdk/sdk-nodejs/testClass.js new file mode 100644 index 00000000..0e2fe2a8 --- /dev/null +++ b/sop-sdk/sdk-nodejs/testClass.js @@ -0,0 +1,52 @@ +/** + * 演示JS面相对象,包括类的创建,继承,方法重写 + * 运行:node testClass.js + */ + +const {Class} = require('./common/Class') + +function testClass() { + //------------------------- + // JS类的创建,继承 + //------------------------- + + // 例子1:------------------------- + // 创建一个父类 + var Person = Class.create({ + // 构造函数 + init:function(option){ + this.name = option.name; + } + ,getName:function() { + return this.name; + } + }); + + // 声明类实例 + var Jim = new Person({name:'Jim'}); + console.log('Jim name:' + Jim.getName()) + + //例子2:------------------------- + + // 创建一个类,继承Person类,并重写getName + var Man = Class.create({ + init:function(option) { + this._super(option);// 调用父类构造函数 + this.age = option.age; + } + // 重写父类方法 + ,getName:function() { + // 调用父类的getName() + var name = this._super(); + return '我重写了getName方法:{'+name+'}'; + } + },Person); + + var man = new Man({name:'Tom',age:22}); + console.log('man name:' + man.getName()) + + console.log('Jim instanceof Person: ' + (Jim instanceof Person)); + console.log('man instanceof Person: ' + (man instanceof Person)); +} + +testClass() From 7dab8da699ae9f1c62bdf93d404579a3211b69e5 Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 17 Aug 2020 16:51:33 +0800 Subject: [PATCH 08/10] 4.0.3 --- changelog.md | 5 ++ doc/docs/files/10041_编写文档.md | 6 +- sop-admin/sop-admin-server/pom.xml | 2 +- sop-auth/pom.xml | 2 +- sop-common/sop-bridge-eureka/pom.xml | 4 +- sop-common/sop-bridge-nacos/pom.xml | 4 +- sop-common/sop-gateway-common/pom.xml | 2 +- sop-common/sop-service-common/pom.xml | 2 +- .../sop/servercommon/annotation/BizCode.java | 37 ++++++++ .../sop/servercommon/annotation/Open.java | 5 ++ .../configuration/ServiceConfiguration.java | 15 ++++ .../CustomSwaggerParameterBuilder.java | 19 ++++ .../DocumentationPluginsManagerExt.java | 87 +++++++++++++++++++ sop-example/sop-springmvc/pom.xml | 2 +- sop-example/sop-story/pom.xml | 2 +- .../Example1001_BaseController.java | 13 ++- .../storyweb/controller/param/StoryParam.java | 2 + .../controller/result/StoryResult.java | 5 +- sop-gateway/pom.xml | 2 +- sop-website/pom.xml | 2 +- .../gitee/sop/websiteserver/bean/BizCode.java | 13 +++ .../gitee/sop/websiteserver/bean/DocItem.java | 1 + .../manager/SwaggerDocParser.java | 20 ++++- .../main/resources/public/pages/doc/doc.html | 23 +++++ .../resources/public/pages/doc/docEvent.js | 19 ++++ 25 files changed, 276 insertions(+), 18 deletions(-) create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/BizCode.java create mode 100644 sop-website/src/main/java/com/gitee/sop/websiteserver/bean/BizCode.java diff --git a/changelog.md b/changelog.md index 27ea95c3..2fb8a76c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,10 @@ # changelog +## 4.0.3 + +- 可定义业务错误码(见`@Open`注解中的`bizCode`属性) +- 文档参数可指定最大长度(使用`@Length(max = xx)`) + ## 4.0.2 - 支持swagger排序(position属性) diff --git a/doc/docs/files/10041_编写文档.md b/doc/docs/files/10041_编写文档.md index 25ad741e..c17cdb5f 100644 --- a/doc/docs/files/10041_编写文档.md +++ b/doc/docs/files/10041_编写文档.md @@ -84,7 +84,11 @@ public class StoryResult { * @return */ @ApiOperation(value = "获取故事信息", notes = "说明接口的详细信息,介绍,用途,注意事项等。") -@Open(value = "alipay.story.find") +@Open(value = "alipay.story.find", bizCode = { + // 定义业务错误码,用于文档显示 + @BizCode(code = "100001", msg = "姓名错误", solution = "填写正确的姓名"), + @BizCode(code = "100002", msg = "备注错误", solution = "填写正确备注"), + }) public StoryResult getStory2(StoryParam story) { log.info("获取故事信息参数, story: {}", story); // 获取其它参数 diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index f49439d7..54b00d40 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -24,7 +24,7 @@ com.gitee.sop sop-bridge-nacos - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-auth/pom.xml b/sop-auth/pom.xml index c6406bf2..dde8a818 100644 --- a/sop-auth/pom.xml +++ b/sop-auth/pom.xml @@ -25,7 +25,7 @@ com.gitee.sop sop-service-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-common/sop-bridge-eureka/pom.xml b/sop-common/sop-bridge-eureka/pom.xml index f367b7a9..a21ae837 100644 --- a/sop-common/sop-bridge-eureka/pom.xml +++ b/sop-common/sop-bridge-eureka/pom.xml @@ -10,7 +10,7 @@ 4.0.0 - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT sop-bridge-eureka @@ -18,7 +18,7 @@ com.gitee.sop sop-gateway-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-common/sop-bridge-nacos/pom.xml b/sop-common/sop-bridge-nacos/pom.xml index 822b8234..21504e9e 100644 --- a/sop-common/sop-bridge-nacos/pom.xml +++ b/sop-common/sop-bridge-nacos/pom.xml @@ -10,7 +10,7 @@ 4.0.0 - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT sop-bridge-nacos @@ -18,7 +18,7 @@ com.gitee.sop sop-gateway-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 0346be41..3b4d5df7 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -11,7 +11,7 @@ 4.0.0 sop-gateway-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT jar diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index 91d00021..582ab35d 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -12,7 +12,7 @@ 4.0.0 sop-service-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT jar diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/BizCode.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/BizCode.java new file mode 100644 index 00000000..892df082 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/BizCode.java @@ -0,0 +1,37 @@ +package com.gitee.sop.servercommon.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 错误码 + * + * @author tanghc + */ +@Target(ElementType.ANNOTATION_TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface BizCode { + + /** + * 错误码 + * + * @return + */ + String code(); + + /** + * 错误描述 + * @return + */ + String msg(); + + /** + * 解决方案 + * @return + */ + String solution() default ""; +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/Open.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/Open.java index 661471fe..f2eb882d 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/Open.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/Open.java @@ -44,4 +44,9 @@ public @interface Open { * 是否需要appAuthToken,设置为true,网关端会校验token是否存在 */ boolean needToken() default false; + + /** + * 定义业务错误码,用于文档显示 + */ + BizCode[] bizCode() default {}; } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java index 217a3614..adb68d04 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java @@ -59,6 +59,21 @@ public class ServiceConfiguration implements WebMvcConfigurer { registry.addInterceptor(new ServiceContextInterceptor()); } + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty("spring.cloud.nacos.discovery.server-addr") + public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties, ObjectProvider taskScheduler, Environment environment) { + Map metadata = nacosDiscoveryProperties.getMetadata(); + String contextPath = environment.getProperty("server.servlet.context-path"); + // 将context-path信息加入到metadata中 + if (contextPath != null) { + metadata.put("context-path", contextPath); + } + // 在元数据中新增启动时间,不能修改这个值,不然网关拉取接口会有问题 + metadata.put("time.startup", String.valueOf(System.currentTimeMillis())); + return new NacosWatch(nacosDiscoveryProperties, taskScheduler); + } + @Bean @ConditionalOnMissingBean GlobalExceptionHandler globalExceptionHandler() { diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/CustomSwaggerParameterBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/CustomSwaggerParameterBuilder.java index b3e4974b..e45ef2c3 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/CustomSwaggerParameterBuilder.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/CustomSwaggerParameterBuilder.java @@ -6,9 +6,12 @@ import com.google.common.base.Strings; import com.google.common.collect.Lists; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiParam; +import org.hibernate.validator.constraints.Length; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.service.AllowableListValues; import springfox.documentation.service.AllowableValues; +import springfox.documentation.service.StringVendorExtension; +import springfox.documentation.service.VendorExtension; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.schema.EnumTypeDeterminer; import springfox.documentation.spi.service.ExpandedParameterBuilderPlugin; @@ -18,6 +21,7 @@ import springfox.documentation.swagger.common.SwaggerPluginSupport; import springfox.documentation.swagger.readers.parameter.Examples; import springfox.documentation.swagger.schema.ApiModelProperties; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -76,6 +80,8 @@ public class CustomSwaggerParameterBuilder implements ExpandedParameterBuilderPl .scalarExample(apiParam.example()) .complexExamples(Examples.examples(apiParam.examples())) .order(SWAGGER_PLUGIN_ORDER) + // 添加额外属性 + .vendorExtensions(this.getVendorExtension(context)) .build(); } @@ -94,9 +100,22 @@ public class CustomSwaggerParameterBuilder implements ExpandedParameterBuilderPl .scalarExample(apiModelProperty.example()) //源码这里是: SWAGGER_PLUGIN_ORDER,需要修正 .order(apiModelProperty.position()) + // 添加额外属性 + .vendorExtensions(this.getVendorExtension(context)) .build(); } + private List getVendorExtension(ParameterExpansionContext context) { + List vendorExtensions = new ArrayList<>(4); + Optional annotation = context.findAnnotation(Length.class); + if (annotation.isPresent()) { + Length length = annotation.get(); + vendorExtensions.add(new StringVendorExtension("maxLength", String.valueOf(length.max()))); + vendorExtensions.add(new StringVendorExtension("minLength", String.valueOf(length.min()))); + } + return vendorExtensions; + } + private ParameterBuilder maybeSetParameterName(ParameterExpansionContext context, String parameterName) { if (!Strings.isNullOrEmpty(parameterName)) { context.getParameterBuilder().name(parameterName); diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/DocumentationPluginsManagerExt.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/DocumentationPluginsManagerExt.java index a7ed04f3..c44c9d8a 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/DocumentationPluginsManagerExt.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/DocumentationPluginsManagerExt.java @@ -1,10 +1,19 @@ package com.gitee.sop.servercommon.swagger; +import com.alibaba.fastjson.JSON; +import com.fasterxml.classmate.ResolvedType; +import com.fasterxml.classmate.members.RawField; +import com.gitee.sop.servercommon.annotation.BizCode; import com.gitee.sop.servercommon.annotation.Open; import com.gitee.sop.servercommon.bean.ServiceConfig; import com.google.common.base.Optional; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.hibernate.validator.constraints.Length; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import springfox.documentation.service.Operation; import springfox.documentation.service.StringVendorExtension; @@ -12,7 +21,15 @@ import springfox.documentation.service.VendorExtension; import springfox.documentation.spi.service.contexts.OperationContext; import springfox.documentation.spring.web.plugins.DocumentationPluginsManager; +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * @author tanghc @@ -23,6 +40,7 @@ public class DocumentationPluginsManagerExt extends DocumentationPluginsManager private static final String SOP_VERSION = "sop_version"; private static final String MODULE_ORDER = "module_order"; private static final String API_ORDER = "api_order"; + private static final String BIZ_CODE = "biz_code"; @Override public Operation operation(OperationContext operationContext) { @@ -40,6 +58,8 @@ public class DocumentationPluginsManagerExt extends DocumentationPluginsManager String version = buildVersion(open.version()); vendorExtensions.add(new StringVendorExtension(SOP_NAME, name)); vendorExtensions.add(new StringVendorExtension(SOP_VERSION, version)); + this.setBizCode(open, vendorExtensions); + this.setResultExtProperties(operationContext); } Optional apiOptional = operationContext.findControllerAnnotation(Api.class); int order = 0; @@ -60,6 +80,73 @@ public class DocumentationPluginsManagerExt extends DocumentationPluginsManager vendorExtensions.add(new StringVendorExtension(API_ORDER, String.valueOf(methodOrder))); } + /** + * 设置返回结果额外属性,如最大长度 + * @param operationContext + */ + private void setResultExtProperties(OperationContext operationContext) { + List vendorExtensions = operationContext.getDocumentationContext().getVendorExtentions(); + ResolvedType returnType = operationContext.getReturnType(); + Class erasedType = returnType.getErasedType(); + String className = erasedType.getSimpleName(); + boolean exist = vendorExtensions.stream().anyMatch(p -> Objects.equals(p.getName(), className)); + if (!exist) { + List memberFields = returnType.getMemberFields(); + Map> fieldProperties = new HashMap<>(16); + for (RawField memberField : memberFields) { + String key = memberField.getName(); + Length length = AnnotationUtils.findAnnotation(memberField.getRawMember(), Length.class); + if (length != null) { + Map properties = fieldProperties.computeIfAbsent(key, k -> new HashMap<>(16)); + properties.computeIfAbsent("maxLength", k -> length.max()); + properties.computeIfAbsent("minLength", k -> length.max()); + } + ApiModelProperty apiModelProperty = AnnotationUtils.findAnnotation(memberField.getRawMember(), ApiModelProperty.class); + if (apiModelProperty != null) { + Map properties = fieldProperties.computeIfAbsent(key, k -> new HashMap<>(16)); + boolean required = apiModelProperty.required(); + // 只有在必填的情况下设置 + if (required) { + properties.put("required", required); + } + } + } + vendorExtensions.add(new StringVendorExtension(className, JSON.toJSONString(fieldProperties))); + } + } + + private Class getGenericType(Field curField) { + // 当前集合的泛型类型 + Type genericType = curField.getGenericType(); + if (genericType instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType) genericType; + // 得到泛型里的class类型对象 + return (Class) pt.getActualTypeArguments()[0]; + } + return null; + } + + /** + * 设置业务错误码 + * @param open + * @param vendorExtensions + */ + private void setBizCode(Open open, List vendorExtensions) { + BizCode[] bizCodes = open.bizCode(); + List codeObjList = Stream.of(bizCodes) + .map(bizCode -> new BizCodeObj(bizCode.code(), bizCode.msg(), bizCode.solution())) + .collect(Collectors.toList()); + vendorExtensions.add(new StringVendorExtension(BIZ_CODE, JSON.toJSONString(codeObjList))); + } + + @Data + @AllArgsConstructor + private static class BizCodeObj { + private String code; + private String msg; + private String solution; + } + private String buildVersion(String version) { if ("".equals(version)) { return ServiceConfig.getInstance().getDefaultVersion(); diff --git a/sop-example/sop-springmvc/pom.xml b/sop-example/sop-springmvc/pom.xml index 959313eb..23060d5d 100644 --- a/sop-example/sop-springmvc/pom.xml +++ b/sop-example/sop-springmvc/pom.xml @@ -26,7 +26,7 @@ com.gitee.sop sop-service-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-example/sop-story/pom.xml b/sop-example/sop-story/pom.xml index e0fe48be..1a0afa2f 100644 --- a/sop-example/sop-story/pom.xml +++ b/sop-example/sop-story/pom.xml @@ -19,7 +19,7 @@ com.gitee.sop sop-service-common - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java index a291d960..b2eb6e2c 100644 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java @@ -1,5 +1,6 @@ package com.gitee.sop.storyweb.controller; +import com.gitee.sop.servercommon.annotation.BizCode; import com.gitee.sop.servercommon.annotation.Open; import com.gitee.sop.storyweb.controller.param.CategoryParam; import com.gitee.sop.storyweb.controller.param.LargeTextParam; @@ -42,7 +43,11 @@ public class Example1001_BaseController { // 基础用法 @ApiOperation(value = "获取故事信息(首位)", notes = "获取故事信息的详细信息", position = -100/* position默认0,值越小越靠前 */) - @Open("story.get") + @Open(value = "story.get", bizCode = { + // 定义业务错误码,用于文档显示 + @BizCode(code = "100001", msg = "姓名错误", solution = "填写正确的姓名"), + @BizCode(code = "100002", msg = "备注错误", solution = "填写正确备注"), + }) @RequestMapping("/get/v1") public StoryResult get_v1(StoryParam param) { StoryResult story = new StoryResult(); @@ -53,7 +58,11 @@ public class Example1001_BaseController { // 指定版本号 @ApiOperation(value = "获取故事信息", notes = "获取故事信息的详细信息") - @Open(value = "story.get", version = "2.0") + @Open(value = "story.get", version = "2.0", bizCode = { + // 定义业务错误码,用于文档显示 + @BizCode(code = "100001", msg = "姓名错误", solution = "填写正确的姓名"), + @BizCode(code = "100002", msg = "备注错误", solution = "填写正确备注"), + }) @RequestMapping("/get/v2") public StoryResult get_v2(StoryParam param) { StoryResult story = new StoryResult(); diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java index 6095f7c9..84ae44ea 100644 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java @@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.hibernate.validator.constraints.Length; +import javax.validation.constraints.Max; import javax.validation.constraints.NotBlank; @Data @@ -17,5 +18,6 @@ public class StoryParam { private String name; @ApiModelProperty(value = "备注 (第二)", example = "xx", position = 2) + @Length(max = 64, message = "长度不能超过64") private String remark; } \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java index b3bf99ef..80f6f69b 100644 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java @@ -12,10 +12,11 @@ import java.util.Date; */ @Data public class StoryResult { - @ApiModelProperty(value = "故事ID", example = "1") + @ApiModelProperty(value = "故事ID", required = true, example = "1") private Long id; - @ApiModelProperty(value = "故事名称", example = "海底小纵队") + @ApiModelProperty(value = "故事名称", required = true, example = "海底小纵队") + @Length(max = 20) private String name; @ApiModelProperty(value = "创建时间", example = "2019-04-14 19:02:12") diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index fb315931..2a3b5736 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -24,7 +24,7 @@ com.gitee.sop sop-bridge-nacos - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-website/pom.xml b/sop-website/pom.xml index f51225ce..26c466e6 100644 --- a/sop-website/pom.xml +++ b/sop-website/pom.xml @@ -25,7 +25,7 @@ com.gitee.sop sop-bridge-nacos - 4.0.2-SNAPSHOT + 4.0.3-SNAPSHOT diff --git a/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/BizCode.java b/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/BizCode.java new file mode 100644 index 00000000..f158e4b5 --- /dev/null +++ b/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/BizCode.java @@ -0,0 +1,13 @@ +package com.gitee.sop.websiteserver.bean; + +import lombok.Data; + +/** + * @author tanghc + */ +@Data +public class BizCode { + private String code; + private String msg; + private String solution; +} diff --git a/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java b/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java index 5a6236b6..929d20ad 100644 --- a/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java +++ b/sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java @@ -30,6 +30,7 @@ public class DocItem { List requestParameters; List responseParameters; + List bizCodeList; public String getNameVersion() { return name + version; diff --git a/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java b/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java index 95240efd..0f41da00 100644 --- a/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java +++ b/sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java @@ -1,7 +1,9 @@ package com.gitee.sop.websiteserver.manager; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.gitee.sop.websiteserver.bean.BizCode; import com.gitee.sop.websiteserver.bean.DocInfo; import com.gitee.sop.websiteserver.bean.DocItem; import com.gitee.sop.websiteserver.bean.DocModule; @@ -121,6 +123,10 @@ public class SwaggerDocParser implements DocParser { docItem.setDescription(docInfo.getString("description")); docItem.setMultiple(docInfo.getString("multiple") != null); docItem.setProduces(docInfo.getJSONArray("produces").toJavaList(String.class)); + String bizCodeStr = docInfo.getString("biz_code"); + if (bizCodeStr != null) { + docItem.setBizCodeList(JSON.parseArray(bizCodeStr, BizCode.class)); + } docItem.setModuleOrder(NumberUtils.toInt(docInfo.getString("module_order"), 0)); docItem.setApiOrder(NumberUtils.toInt(docInfo.getString("api_order"), 0)); String moduleName = this.buildModuleName(docInfo, docRoot); @@ -208,6 +214,8 @@ public class SwaggerDocParser implements DocParser { protected List buildDocParameters(String ref, JSONObject docRoot, boolean doSubRef) { JSONObject responseObject = docRoot.getJSONObject("definitions").getJSONObject(ref); + String className = responseObject.getString("title"); + JSONObject extProperties = docRoot.getJSONObject(className); JSONObject properties = responseObject.getJSONObject("properties"); List docParameterList = new ArrayList<>(); if (properties == null) { @@ -224,10 +232,20 @@ public class SwaggerDocParser implements DocParser { JSONObject fieldInfo = properties.getJSONObject(fieldName); DocParameter docParameter = fieldInfo.toJavaObject(DocParameter.class); docParameter.setName(fieldName); + if (extProperties != null) { + JSONObject prop = extProperties.getJSONObject(fieldName); + if (prop != null) { + String maxLength = prop.getString("maxLength"); + docParameter.setMaxLength(maxLength == null ? "-" : maxLength); + String required = prop.getString("required"); + if (required != null) { + docParameter.setRequired(Boolean.parseBoolean(required)); + } + } + } docParameterList.add(docParameter); RefInfo refInfo = this.getRefInfo(fieldInfo); if (refInfo != null && doSubRef) { - // 如果是树状菜单的话,这里可能触发死循环 String subRef = refInfo.ref; boolean nextDoRef = !Objects.equals(ref, subRef); List refs = buildDocParameters(subRef, docRoot, nextDoRef); diff --git a/sop-website/src/main/resources/public/pages/doc/doc.html b/sop-website/src/main/resources/public/pages/doc/doc.html index 65d0b6d5..b89b55a7 100644 --- a/sop-website/src/main/resources/public/pages/doc/doc.html +++ b/sop-website/src/main/resources/public/pages/doc/doc.html @@ -367,6 +367,29 @@ +
+
+ 业务错误码 +
+
+
+

+ 公共错误码 +

+
+ + + + + + + + + + +
错误码错误描述解决方案
+
+
diff --git a/sop-website/src/main/resources/public/pages/doc/docEvent.js b/sop-website/src/main/resources/public/pages/doc/docEvent.js index 5f58b327..9f6c60d9 100644 --- a/sop-website/src/main/resources/public/pages/doc/docEvent.js +++ b/sop-website/src/main/resources/public/pages/doc/docEvent.js @@ -16,6 +16,7 @@ function selectItem(docItem, layui) { createRequestParameter(docItem); createResponseParameter(docItem); createResponseCode(docItem); + buildBizCode(docItem); var $li = $('#docItemTree').find('li[nameversion="'+nameVersion+'"]'); $li.addClass('layui-this').siblings().removeClass('layui-this'); @@ -124,3 +125,21 @@ function buildExample(parameter) { return '\"' + parameter.example + '\"'; } } + +function buildBizCode(docItem) { + var html = [] + var bizCodeList = docItem.bizCodeList; + if (bizCodeList && bizCodeList.length > 0) { + for (var i = 0; i < bizCodeList.length; i++) { + var bizCode = bizCodeList[i]; + html.push('') + html.push(''+bizCode.code+'') + html.push(''+bizCode.msg+'') + html.push(''+bizCode.solution+'') + html.push('') + } + $('#bizCode').find('tbody').html(html.join('')); + } else { + $('#bizCode').find('tbody').html('暂无数据'); + } +} \ No newline at end of file From 1ac069fae88e335e696e86736b75ec2e97366eb8 Mon Sep 17 00:00:00 2001 From: tanghc Date: Mon, 17 Aug 2020 17:34:26 +0800 Subject: [PATCH 09/10] 4.0.3 --- doc/docs/files/10041_编写文档.md | 5 ++++- doc/docs/files/images/10041_4.png | Bin 0 -> 134298 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 doc/docs/files/images/10041_4.png diff --git a/doc/docs/files/10041_编写文档.md b/doc/docs/files/10041_编写文档.md index c17cdb5f..cc389727 100644 --- a/doc/docs/files/10041_编写文档.md +++ b/doc/docs/files/10041_编写文档.md @@ -120,4 +120,7 @@ swagger注解和文档界面显示关系如下图所示: ![预览](images/10041_2.png "10041_2.png") -![预览](images/10041_3.png "10041_3.png") \ No newline at end of file +![预览](images/10041_3.png "10041_3.png") + + +![预览](images/10041_4.png "10041_4.png") \ No newline at end of file diff --git a/doc/docs/files/images/10041_4.png b/doc/docs/files/images/10041_4.png new file mode 100644 index 0000000000000000000000000000000000000000..89f55a405787fd5f74e1707922079db05c7cf4d1 GIT binary patch literal 134298 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 B&T{|& literal 0 HcmV?d00001 From 43e5707c0141470a75e7a564a73566f5c680e6fc Mon Sep 17 00:00:00 2001 From: tanghc Date: Tue, 18 Aug 2020 14:04:29 +0800 Subject: [PATCH 10/10] 4.0.3 --- .../bridge/route/EurekaRegistryListener.java | 3 +- .../bridge/SopRegisterAutoConfiguration.java | 25 ---------- .../bridge/route/NacosRegistryListener.java | 48 ++++++++++--------- .../sop/gatewaycommon/bean/SopConstants.java | 2 + .../route/BaseRegistryListener.java | 5 +- .../gatewaycommon/route/ServiceHolder.java | 1 - .../configuration/ServiceConfiguration.java | 1 + 7 files changed, 33 insertions(+), 52 deletions(-) diff --git a/sop-common/sop-bridge-eureka/src/main/java/com/gitee/sop/bridge/route/EurekaRegistryListener.java b/sop-common/sop-bridge-eureka/src/main/java/com/gitee/sop/bridge/route/EurekaRegistryListener.java index f0ca2758..7b7e3797 100644 --- a/sop-common/sop-bridge-eureka/src/main/java/com/gitee/sop/bridge/route/EurekaRegistryListener.java +++ b/sop-common/sop-bridge-eureka/src/main/java/com/gitee/sop/bridge/route/EurekaRegistryListener.java @@ -48,6 +48,7 @@ public class EurekaRegistryListener extends BaseRegistryListener { return instanceInfos.get(0); }) .map(instanceInfo -> new ServiceHolder(instanceInfo.getAppName(), instanceInfo.getLastUpdatedTimestamp())) + .filter(this::canOperator) .collect(Collectors.toList()); final Set currentServices = new HashSet<>(serviceList); @@ -57,7 +58,7 @@ public class EurekaRegistryListener extends BaseRegistryListener { if (currentServices.size() > 0) { List newApplications = registeredApplications.stream() .filter(application -> - this.canOperator(application.getName()) && containsService(currentServices, application.getName())) + containsService(currentServices, application.getName())) .collect(Collectors.toList()); this.doRegister(newApplications); diff --git a/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/SopRegisterAutoConfiguration.java b/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/SopRegisterAutoConfiguration.java index 6929b702..63c49e23 100644 --- a/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/SopRegisterAutoConfiguration.java +++ b/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/SopRegisterAutoConfiguration.java @@ -1,20 +1,9 @@ package com.gitee.sop.bridge; -import com.alibaba.cloud.nacos.NacosDiscoveryProperties; -import com.alibaba.cloud.nacos.discovery.NacosWatch; import com.gitee.sop.bridge.route.NacosRegistryListener; import com.gitee.sop.gatewaycommon.route.RegistryListener; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.scheduling.TaskScheduler; - -import java.util.Map; /** * @author tanghc @@ -22,20 +11,6 @@ import java.util.Map; @Configuration public class SopRegisterAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties, ObjectProvider taskScheduler, Environment environment) { - Map metadata = nacosDiscoveryProperties.getMetadata(); - String contextPath = environment.getProperty("server.servlet.context-path"); - // 将context-path信息加入到metadata中 - if (contextPath != null) { - metadata.put("context-path", contextPath); - } - // 在元数据中新增启动时间,不能修改这个值,不然网关拉取接口会有问题 - metadata.put("time.startup", String.valueOf(System.currentTimeMillis())); - return new NacosWatch(nacosDiscoveryProperties, taskScheduler); - } - /** * 微服务路由加载 */ diff --git a/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/route/NacosRegistryListener.java b/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/route/NacosRegistryListener.java index cc871f80..48058ad4 100644 --- a/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/route/NacosRegistryListener.java +++ b/sop-common/sop-bridge-nacos/src/main/java/com/gitee/sop/bridge/route/NacosRegistryListener.java @@ -6,9 +6,12 @@ import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ListView; import com.gitee.sop.gatewaycommon.bean.InstanceDefinition; +import com.gitee.sop.gatewaycommon.bean.SopConstants; import com.gitee.sop.gatewaycommon.route.BaseRegistryListener; import com.gitee.sop.gatewaycommon.route.RegistryEvent; +import com.gitee.sop.gatewaycommon.route.ServiceHolder; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.math.NumberUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEvent; import org.springframework.util.CollectionUtils; @@ -29,8 +32,6 @@ import java.util.stream.Collectors; @Slf4j public class NacosRegistryListener extends BaseRegistryListener { - private static final String METADATA_KEY_TIME_STARTUP = "time.startup"; - private volatile Set cacheServices = new HashSet<>(); @Autowired @@ -73,6 +74,7 @@ public class NacosRegistryListener extends BaseRegistryListener { /** * 获取建康的服务实例 + * * @return 没有返回空的list */ private List getServiceList() { @@ -89,36 +91,36 @@ public class NacosRegistryListener extends BaseRegistryListener { return servicesOfServer .getData() .stream() - .filter(this::canOperator) .map(serviceName -> { + List allInstances; try { // 获取服务实例 - List allInstances = namingService.getAllInstances(serviceName); - if (CollectionUtils.isEmpty(allInstances)) { - return null; - } - Instance instance = allInstances.stream() - // 只获取建康实例 - .filter(Instance::isHealthy) - // 根据启动时间倒叙,找到最新的服务器 - .max(Comparator.comparing(ins -> { - String startupTime = ins.getMetadata().getOrDefault(METADATA_KEY_TIME_STARTUP, "0"); - return Long.valueOf(startupTime); - })) - .orElse(null); - if (instance == null) { - return null; - } else { - String startupTime = instance.getMetadata().getOrDefault("time.startup", "0"); - long time = Long.parseLong(startupTime); - return new NacosServiceHolder(serviceName, time, instance); - } + allInstances = namingService.getAllInstances(serviceName); } catch (NacosException e) { log.error("namingService.getAllInstances(serviceName)错误,serviceName:{}", serviceName, e); return null; } + if (CollectionUtils.isEmpty(allInstances)) { + return null; + } + return allInstances.stream() + // 只获取建康实例 + .filter(Instance::isHealthy) + .map(instance -> { + String startupTime = instance.getMetadata().get(SopConstants.METADATA_KEY_TIME_STARTUP); + if (startupTime == null) { + return null; + } + long time = NumberUtils.toLong(startupTime, 0); + return new NacosServiceHolder(serviceName, time, instance); + }) + .filter(Objects::nonNull) + .max(Comparator.comparing(ServiceHolder::getLastUpdatedTimestamp)) + .orElse(null); + }) .filter(Objects::nonNull) + .filter(this::canOperator) .collect(Collectors.toList()); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java index 47abfbd3..7c04cec7 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java @@ -54,4 +54,6 @@ public class SopConstants { public static final String TARGET_SERVICE = "sop-target-service"; public static final String RESTFUL_REQUEST = "sop-restful-request"; + public static final String METADATA_KEY_TIME_STARTUP = "time.startup"; + } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseRegistryListener.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseRegistryListener.java index 2e7128b5..06db6e24 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseRegistryListener.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseRegistryListener.java @@ -20,7 +20,7 @@ public abstract class BaseRegistryListener implements RegistryListener { private static final int FIVE_SECONDS = 1000 * 5; - private Map updateTimeMap = new ConcurrentHashMap<>(16); + private final Map updateTimeMap = new ConcurrentHashMap<>(16); public static List EXCLUDE_SERVICE_ID_LIST = new ArrayList<>(8); @@ -54,7 +54,8 @@ public abstract class BaseRegistryListener implements RegistryListener { serviceListener.onAddInstance(instance); } - protected boolean canOperator(String serviceId) { + protected boolean canOperator(ServiceHolder serviceHolder) { + String serviceId = serviceHolder.getServiceId(); // 被排除的服务,不能操作 if (isExcludeService(serviceId)) { return false; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceHolder.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceHolder.java index a5641f08..568ada29 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceHolder.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceHolder.java @@ -1,7 +1,6 @@ package com.gitee.sop.gatewaycommon.route; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.Getter; import lombok.Setter; diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java index adb68d04..e502b0f3 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java @@ -70,6 +70,7 @@ public class ServiceConfiguration implements WebMvcConfigurer { metadata.put("context-path", contextPath); } // 在元数据中新增启动时间,不能修改这个值,不然网关拉取接口会有问题 + // 如果没有这个值,网关会忽略这个服务 metadata.put("time.startup", String.valueOf(System.currentTimeMillis())); return new NacosWatch(nacosDiscoveryProperties, taskScheduler); }