diff --git a/README.md b/README.md index cbc6fb6..133aa93 100644 --- a/README.md +++ b/README.md @@ -5,38 +5,41 @@ ██║ ██║██║ ██║╚════╝██║ ██║██║██║╚██╗██║╚════╝██╔══██║██╔═══╝ ██║ ╚██████╔╝╚██████╔╝ ╚██████╔╝██║██║ ╚████║ ██║ ██║██║ ██║ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ + +* [register cors] +* [register rate] +* [register panic notify] +* [register pprof] +* [register swagger] +* [register prometheus] ``` ## go-gin-api -基于 [Gin](https://github.com/gin-gonic/gin) 进行模块化设计的 API 框架,封装了常用的功能,使用简单,致力于进行快速的业务研发。 +基于 [Gin](https://github.com/gin-gonic/gin) 进行模块化设计的 API 框架,封装了常用的功能,使用简单,致力于进行快速的业务研发,同时增加了更多限制,以约束项目组开发成员、规避混乱无序和自由随意。 + +供参考学习,线上使用请谨慎! + +**查看 Jaeger 链路追踪代码,请查看 [v1.0版](https://github.com/xinliangnote/go-gin-api/releases/tag/v1.0),文档 [jaeger.md](https://github.com/xinliangnote/go-gin-api/blob/master/docs/jaeger.md) 点这里**。 持续更新... ## Features -- [x] 使用 go modules 初始化项目 -- [x] 安装 Gin 框架 -- [x] 性能分析工具(pprof) -- [x] 支持优雅地重启或停止 -- [x] 规划项目目录 -- [x] 参数验证(validator.v9) - - [x] 模型绑定和验证 - - [x] 自定义验证器 -- [x] 路由中间件 - - [x] 签名验证 - - [x] MD5 组合加密 - - [x] AES 对称加密 - - [x] RSA 非对称加密 - - [x] 日志记录 - - [x] 异常捕获 - - [x] 链路追踪(Jaeger) - - [x] 限流 -- [x] 自定义告警 - - [x] 邮件(gomail) - - [ ] 微信 - - [ ] 短信 - - [ ] 钉钉 +- [x] 包管理工具 [Go Modules](https://github.com/golang/go/wiki/Modules) +- [x] [Gin](https://github.com/gin-gonic/gin) 支持优雅关闭 +- [x] 配置文件解析库 [Viper](https://github.com/spf13/viper) +- [x] 文档使用 [Swagger](https://swagger.io/) 生成 +- [x] 性能分析使用 [pprof](github.com/gin-contrib/pprof) +- [x] 集成 + - [x] [JWT](https://jwt.io/) 身份认证 + - [x] [zap](go.uber.org/zap) 日志记录 + - [x] [rate](golang.org/x/time/rate) 限流 + - [x] 异常捕获并邮件告警 + - [x] 每个请求具备链路ID + - [x] 统一定义错误码 + - [x] 支持 FAT、UAT、PRO 环境 + - [x] MD5、AES 对称加密、RSA 非对称加密 - [ ] 存储 - [ ] MySQL - [ ] Redis @@ -64,27 +67,15 @@ cd go-gin-api go run main.go ``` -#### HTTP Demo +#### swagger +```go +http://127.0.0.1:9999/swagger/index.html + +// 生成文档 +$ go get -u github.com/swaggo/swag/cmd/swag +$ swag init ``` -curl -X POST http://127.0.0.1:9999/demo/user -``` - -#### Jaeger Demo - -访问: - -``` -http://127.0.0.1:9999/jaeger_test -``` - -服务端测试代码: - -- [https://github.com/xinliangnote/go-jaeger-demo](https://github.com/xinliangnote/go-jaeger-demo) - -![](https://github.com/xinliangnote/Go/blob/master/03-go-gin-api%20%5B文档%5D/images/jaeger_demo_2.png) - -![](https://github.com/xinliangnote/Go/blob/master/03-go-gin-api%20%5B文档%5D/images/jaeger_demo_3.png) #### pprof diff --git a/configs/fat_configs.toml b/configs/fat_configs.toml index d2e62d2..8469772 100644 --- a/configs/fat_configs.toml +++ b/configs/fat_configs.toml @@ -1,6 +1,12 @@ -[db] -host = '127.0.0.1' -port = 3306 +[mail] +host = 'smtp.163.com' +port = 465 +user = "" +pass = "" +to = "" + +[jwt] +secret = 'i1ydX9RtHyuJTrw7frcu' [aes] key = 'IgkibX71IEf382PT' diff --git a/docs/docs.go b/docs/docs.go index 27d03f8..3c4bf6f 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -40,10 +40,17 @@ var doc = `{ "parameters": [ { "type": "string", - "description": "用户名", + "description": "用户名(Tom)", "name": "name", "in": "path", "required": true + }, + { + "type": "string", + "description": "签名", + "name": "Authorization", + "in": "header", + "required": true } ], "responses": { @@ -68,6 +75,64 @@ var doc = `{ } } } + }, + "/user/login": { + "post": { + "description": "登录获取 Authorization 码", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Demo" + ], + "summary": "登录获取 Authorization 码", + "parameters": [ + { + "description": "请求信息", + "name": "loginRequest", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/demo.loginRequest" + } + } + ], + "responses": { + "200": { + "description": "签名信息", + "schema": { + "$ref": "#/definitions/demo.loginResponse" + } + } + } + } + } + }, + "definitions": { + "demo.loginRequest": { + "type": "object", + "properties": { + "user_id": { + "description": "用户ID(\u003e0)", + "type": "integer" + }, + "user_name": { + "description": "用户名", + "type": "string" + } + } + }, + "demo.loginResponse": { + "type": "object", + "properties": { + "authorization": { + "description": "签名", + "type": "string" + } + } } } }` @@ -84,7 +149,7 @@ type swaggerInfo struct { // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = swaggerInfo{ Version: "", - Host: "localhost:9999", + Host: "127.0.0.1:9999", BasePath: "", Schemes: []string{}, Title: "go-gin-api docs api", diff --git a/docs/jaeger.md b/docs/jaeger.md new file mode 100644 index 0000000..ce568e0 --- /dev/null +++ b/docs/jaeger.md @@ -0,0 +1,20 @@ +## Jaeger Demo 代码 + +- 代码在 [v1.0](https://github.com/xinliangnote/go-gin-api/releases/tag/v1.0) 版本。 + +#### Jaeger Demo 文档 + +访问: + +``` +http://127.0.0.1:9999/jaeger_test +``` + +服务端测试代码: + +- [https://github.com/xinliangnote/go-jaeger-demo](https://github.com/xinliangnote/go-jaeger-demo) + +![](https://github.com/xinliangnote/Go/blob/master/03-go-gin-api%20%5B文档%5D/images/jaeger_demo_2.png) + +![](https://github.com/xinliangnote/Go/blob/master/03-go-gin-api%20%5B文档%5D/images/jaeger_demo_3.png) + diff --git a/docs/swagger.json b/docs/swagger.json index 7396517..f119341 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -4,7 +4,7 @@ "title": "go-gin-api docs api", "contact": {} }, - "host": "localhost:9999", + "host": "127.0.0.1:9999", "paths": { "/demo/user/{name}": { "get": { @@ -22,10 +22,17 @@ "parameters": [ { "type": "string", - "description": "用户名", + "description": "用户名(Tom)", "name": "name", "in": "path", "required": true + }, + { + "type": "string", + "description": "签名", + "name": "Authorization", + "in": "header", + "required": true } ], "responses": { @@ -50,6 +57,64 @@ } } } + }, + "/user/login": { + "post": { + "description": "登录获取 Authorization 码", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Demo" + ], + "summary": "登录获取 Authorization 码", + "parameters": [ + { + "description": "请求信息", + "name": "loginRequest", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/demo.loginRequest" + } + } + ], + "responses": { + "200": { + "description": "签名信息", + "schema": { + "$ref": "#/definitions/demo.loginResponse" + } + } + } + } + } + }, + "definitions": { + "demo.loginRequest": { + "type": "object", + "properties": { + "user_id": { + "description": "用户ID(\u003e0)", + "type": "integer" + }, + "user_name": { + "description": "用户名", + "type": "string" + } + } + }, + "demo.loginResponse": { + "type": "object", + "properties": { + "authorization": { + "description": "签名", + "type": "string" + } + } } } } \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b3c67bd..480225e 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,4 +1,20 @@ -host: localhost:9999 +definitions: + demo.loginRequest: + properties: + user_id: + description: 用户ID(>0) + type: integer + user_name: + description: 用户名 + type: string + type: object + demo.loginResponse: + properties: + authorization: + description: 签名 + type: string + type: object +host: 127.0.0.1:9999 info: contact: {} title: go-gin-api docs api @@ -9,11 +25,16 @@ paths: - application/json description: 获取用户信息 parameters: - - description: 用户名 + - description: 用户名(Tom) in: path name: name required: true type: string + - description: 签名 + in: header + name: Authorization + required: true + type: string produces: - application/json responses: @@ -33,4 +54,26 @@ paths: summary: 获取用户信息 tags: - Demo + /user/login: + post: + consumes: + - application/json + description: 登录获取 Authorization 码 + parameters: + - description: 请求信息 + in: body + name: loginRequest + required: true + schema: + $ref: '#/definitions/demo.loginRequest' + produces: + - application/json + responses: + "200": + description: 签名信息 + schema: + $ref: '#/definitions/demo.loginResponse' + summary: 登录获取 Authorization 码 + tags: + - Demo swagger: "2.0" diff --git a/go.mod b/go.mod index 955b4dd..54357f2 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,10 @@ go 1.12 require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 - github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-contrib/pprof v1.2.1 - github.com/gin-gonic/gin v1.4.0 + github.com/gin-gonic/gin v1.6.3 github.com/go-openapi/spec v0.20.0 // indirect - github.com/golang/protobuf v1.3.2 - github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 - github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v0.9.3 github.com/rs/cors v1.7.0 @@ -18,19 +15,15 @@ require ( github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/swag v1.7.0 github.com/tidwall/gjson v1.6.6 - github.com/uber-go/atomic v1.4.0 // indirect - github.com/uber/jaeger-client-go v2.18.1+incompatible - github.com/uber/jaeger-lib v2.1.1+incompatible // indirect - github.com/xinliangnote/go-util v0.0.0-20191115235314-e7d1576d41db + go.uber.org/multierr v1.5.0 go.uber.org/zap v1.16.0 golang.org/x/mod v0.4.0 // indirect golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect golang.org/x/sys v0.0.0-20201223074533-0d417f636930 // indirect golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 golang.org/x/tools v0.0.0-20201226215659-b1c90890d22a // indirect - google.golang.org/grpc v1.23.1 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect + gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) diff --git a/go.sum b/go.sum index 85239f3..f5ce9fe 100644 --- a/go.sum +++ b/go.sum @@ -17,7 +17,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -26,7 +25,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -38,8 +36,6 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -50,55 +46,58 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= github.com/gin-contrib/pprof v1.2.1 h1:p6mY/FsE3tDx2+Wp3ksrMe1QL5egQ7p+lsZ7WbQLT1U= github.com/gin-contrib/pprof v1.2.1/go.mod h1:u2l4P4YNkLXYz+xBbrl7Pxu1Btng6VCD7j3O3pUPP2w= github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= -github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk= github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA= github.com/go-openapi/spec v0.20.0 h1:HGLc8AJ7ynOxwv0Lq4TsnwLsWMawHAYiJIFzbcML86I= github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY= github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI= github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -106,12 +105,14 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -122,8 +123,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -151,8 +150,9 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -161,18 +161,17 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -181,10 +180,10 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -196,15 +195,15 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -237,8 +236,6 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -259,7 +256,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -268,7 +264,6 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI= github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0= -github.com/swaggo/swag v1.5.1 h1:2Agm8I4K5qb00620mHq0VJ05/KT4FtmALPIcQR9lEZM= github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E= github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo= @@ -279,26 +274,17 @@ github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/uber-go/atomic v1.4.0 h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o= -github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.18.1+incompatible h1:bI1w1jRSWBswo6LhGdqA2SbFQX/TSVleZhMty4IJ78A= -github.com/uber/jaeger-client-go v2.18.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.1.1+incompatible h1:VY/6p2WopO09BPnw787RbaCIlfKbCRC/kq3p5D0F168= -github.com/uber/jaeger-lib v2.1.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xinliangnote/go-util v0.0.0-20191115235314-e7d1576d41db h1:yReVDmqk6oBUOcSRUofahYHJlIwr7wrJ8yx1Ymkz84E= -github.com/xinliangnote/go-util v0.0.0-20191115235314-e7d1576d41db/go.mod h1:3ZornrplU9tYj9ar9jchik1XPQ10ZbSXkbgxXR5PVaU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -358,7 +344,6 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -385,13 +370,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201223074533-0d417f636930 h1:vRgIt+nup/B/BwIS0g2oC0haq0iqbV3ZA+u6+0TlNCo= @@ -399,7 +383,6 @@ golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= @@ -418,7 +401,6 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -429,7 +411,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -456,27 +437,20 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= @@ -489,8 +463,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -500,7 +474,6 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/api/config/config.go b/internal/api/config/config.go deleted file mode 100644 index 906dc60..0000000 --- a/internal/api/config/config.go +++ /dev/null @@ -1,45 +0,0 @@ -package config - -var ( - ApiAuthConfig = map[string]map[string]string{ - - // 调用方 - "DEMO": { - "md5": "IgkibX71IEf382PT", - "aes": "IgkibX71IEf382PT", - "rsa": "rsa/public.pem", - }, - } -) - -const ( - AppName = "go-gin-api" - - // 签名超时时间 - AppSignExpiry = "120" - - // RSA Private File - AppRsaPrivateFile = "rsa/private.pem" - - // 日志文件 - AppErrorLogName = "log/" + AppName + "-error.log" - AppGrpcLogName = "log/" + AppName + "-grpc.log" - - // 系统告警邮箱信息 - SystemEmailUser = "xinliangnote@163.com" - SystemEmailPass = "" //密码或授权码 - SystemEmailHost = "smtp.163.com" - SystemEmailPort = 465 - - // 告警接收人 - ErrorNotifyUser = "xinliangnote@163.com" - - // 告警开关 1=开通 -1=关闭 - ErrorNotifyOpen = -1 - - // Jaeger 配置信息 - JaegerHostPort = "172.20.2.212:6831" - - // Jaeger 配置开关 1=开通 -1=关闭 - JaegerOpen = 1 -) diff --git a/internal/api/controller/demo/demo.go b/internal/api/controller/demo/demo.go index f0281dc..643b9d2 100644 --- a/internal/api/controller/demo/demo.go +++ b/internal/api/controller/demo/demo.go @@ -101,7 +101,8 @@ type response []struct { // @Tags Demo // @Accept json // @Produce json -// @Param name path string true "用户名" +// @Param name path string true "用户名(Tom)" +// @Param Authorization header string true "签名" // @Success 200 {object} response "用户信息" // @Router /demo/user/{name} [get] func (d *Demo) User() core.HandlerFunc { @@ -121,6 +122,7 @@ func (d *Demo) User() core.HandlerFunc { httpclient.WithTTL(time.Second*2), httpclient.WithJournal(c.Journal()), httpclient.WithLogger(c.Logger()), + httpclient.WithHeader("Authorization", c.GetHeader("Authorization")), ) if err1 != nil { d.logger.Error("get [demo/get] err", zap.Error(err1)) @@ -132,22 +134,25 @@ func (d *Demo) User() core.HandlerFunc { httpclient.WithTTL(time.Second*2), httpclient.WithJournal(c.Journal()), httpclient.WithLogger(c.Logger()), + httpclient.WithHeader("Authorization", c.GetHeader("Authorization")), ) if err2 != nil { d.logger.Error("post [demo/post] err", zap.Error(err2)) } - data := &response{ - { - Name: jsonparse.Get(string(body1), "data.name").(string), - Job: jsonparse.Get(string(body1), "data.job").(string), - }, - { - Name: jsonparse.Get(string(body2), "data.name").(string), - Job: jsonparse.Get(string(body2), "data.job").(string), - }, + data := &response{} + if err1 == nil && err2 == nil { + data = &response{ + { + Name: jsonparse.Get(string(body1), "data.name").(string), + Job: jsonparse.Get(string(body1), "data.job").(string), + }, + { + Name: jsonparse.Get(string(body2), "data.name").(string), + Job: jsonparse.Get(string(body2), "data.job").(string), + }, + } } - c.SetPayload(errno.OK.WithData(data)) } } @@ -158,9 +163,9 @@ func (d *Demo) RsaTest() core.HandlerFunc { encryptStr := "param_1=xxx¶m_2=xxx&ak=xxx&ts=1111111111" count := 500 - cfg := configs.Get() - rsaPublic := rsa.NewPublic(cfg.Rsa.Public) - rsaPrivate := rsa.NewPrivate(cfg.Rsa.Private) + cfg := configs.Get().Rsa + rsaPublic := rsa.NewPublic(cfg.Public) + rsaPrivate := rsa.NewPrivate(cfg.Private) for i := 0; i < count; i++ { // 生成签名 @@ -187,8 +192,8 @@ func (d *Demo) AesTest() core.HandlerFunc { encryptStr := "param_1=xxx¶m_2=xxx&ak=xxx&ts=1111111111" count := 1000000 - cfg := configs.Get() - aes := aes.New(cfg.Aes.Key, cfg.Aes.Iv) + cfg := configs.Get().Aes + aes := aes.New(cfg.Key, cfg.Iv) for i := 0; i < count; i++ { // 生成签名 sn, err := aes.Encrypt(encryptStr) diff --git a/internal/api/controller/demo/login.go b/internal/api/controller/demo/login.go new file mode 100644 index 0000000..06d3b69 --- /dev/null +++ b/internal/api/controller/demo/login.go @@ -0,0 +1,47 @@ +package demo + +import ( + "github.com/xinliangnote/go-gin-api/internal/pkg/core" + "github.com/xinliangnote/go-gin-api/internal/pkg/errno" + "github.com/xinliangnote/go-gin-api/internal/pkg/token" + + "go.uber.org/zap" +) + +type loginRequest struct { + UserID int `json:"user_id" form:"user_id"` // 用户ID(>0) + UserName string `json:"user_name" form:"user_name"` // 用户名 +} + +type loginResponse struct { + Authorization string `json:"authorization"` // 签名 +} + +// 登录获取 Authorization 码 +// @Summary 登录获取 Authorization 码 +// @Description 登录获取 Authorization 码 +// @Tags Demo +// @Accept json +// @Produce json +// @Param loginRequest body loginRequest true "请求信息" +// @Success 200 {object} loginResponse "签名信息" +// @Router /user/login [post] +func (d *Demo) Login() core.HandlerFunc { + return func(c core.Context) { + req := new(loginRequest) + res := new(loginResponse) + if err := c.ShouldBindJSON(req); err != nil { + c.SetPayload(errno.ErrParam) + return + } + + tokenString, err := token.Sign(req.UserID, req.UserName) + if err != nil { + d.logger.Error("token sign err", zap.Error(err)) + res.Authorization = "" + } else { + res.Authorization = tokenString + } + c.SetPayload(errno.OK.WithData(res)) + } +} diff --git a/internal/api/controller/jaeger_conn/jaeger_conn.go b/internal/api/controller/jaeger_conn/jaeger_conn.go deleted file mode 100644 index 1f95325..0000000 --- a/internal/api/controller/jaeger_conn/jaeger_conn.go +++ /dev/null @@ -1,58 +0,0 @@ -package jaeger_conn - -import ( - "context" - - "github.com/xinliangnote/go-gin-api/internal/api/model/proto/listen" - "github.com/xinliangnote/go-gin-api/internal/api/model/proto/read" - "github.com/xinliangnote/go-gin-api/internal/api/model/proto/speak" - "github.com/xinliangnote/go-gin-api/internal/api/model/proto/write" - "github.com/xinliangnote/go-gin-api/internal/api/util/grpc_client" - "github.com/xinliangnote/go-gin-api/internal/api/util/request" - "github.com/xinliangnote/go-gin-api/internal/api/util/response" - - "github.com/gin-gonic/gin" -) - -func JaegerTest(c *gin.Context) { - - // 调用 gRPC 服务 - conn := grpc_client.CreateServiceListenConn(c) - grpcListenClient := listen.NewListenClient(conn) - resListen, _ := grpcListenClient.ListenData(context.Background(), &listen.Request{Name: "listen"}) - - // 调用 gRPC 服务 - conn = grpc_client.CreateServiceSpeakConn(c) - grpcSpeakClient := speak.NewSpeakClient(conn) - resSpeak, _ := grpcSpeakClient.SpeakData(context.Background(), &speak.Request{Name: "speak"}) - - // 调用 gRPC 服务 - conn = grpc_client.CreateServiceReadConn(c) - grpcReadClient := read.NewReadClient(conn) - resRead, _ := grpcReadClient.ReadData(context.Background(), &read.Request{Name: "read"}) - - // 调用 gRPC 服务 - conn = grpc_client.CreateServiceWriteConn(c) - grpcWriteClient := write.NewWriteClient(conn) - resWrite, _ := grpcWriteClient.WriteData(context.Background(), &write.Request{Name: "write"}) - - defer conn.Close() - - // 调用 HTTP 服务 - resHttpGet := "" - _, err := request.HttpGet("http://localhost:9905/sing", c) - if err == nil { - resHttpGet = "[HttpGetOk]" - } - - // 业务处理... - - msg := resListen.Message + "-" + - resSpeak.Message + "-" + - resRead.Message + "-" + - resWrite.Message + "-" + - resHttpGet - - utilGin := response.Gin{Ctx: c} - utilGin.Response(1, msg, nil) -} diff --git a/internal/api/model/proto/listen/listen.pb.go b/internal/api/model/proto/listen/listen.pb.go deleted file mode 100644 index 2f005ac..0000000 --- a/internal/api/model/proto/listen/listen.pb.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: listen.proto - -package listen - -import ( - context "context" - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Request 请求结构 -type Request struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_f05da38a4a3e5177, []int{0} -} - -func (m *Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Request.Unmarshal(m, b) -} -func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Request.Marshal(b, m, deterministic) -} -func (m *Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_Request.Merge(m, src) -} -func (m *Request) XXX_Size() int { - return xxx_messageInfo_Request.Size(m) -} -func (m *Request) XXX_DiscardUnknown() { - xxx_messageInfo_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_Request proto.InternalMessageInfo - -func (m *Request) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -// Response 响应结构 -type Response struct { - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_f05da38a4a3e5177, []int{1} -} - -func (m *Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Response.Unmarshal(m, b) -} -func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Response.Marshal(b, m, deterministic) -} -func (m *Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_Response.Merge(m, src) -} -func (m *Response) XXX_Size() int { - return xxx_messageInfo_Response.Size(m) -} -func (m *Response) XXX_DiscardUnknown() { - xxx_messageInfo_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_Response proto.InternalMessageInfo - -func (m *Response) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func init() { - proto.RegisterType((*Request)(nil), "listen.Request") - proto.RegisterType((*Response)(nil), "listen.Response") -} - -func init() { proto.RegisterFile("listen.proto", fileDescriptor_f05da38a4a3e5177) } - -var fileDescriptor_f05da38a4a3e5177 = []byte{ - // 133 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0xc9, 0x2c, 0x2e, - 0x49, 0xcd, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0x94, 0x64, 0xb9, 0xd8, - 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, - 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0xc0, 0x6c, 0x25, 0x15, 0x2e, 0x8e, 0xa0, 0xd4, 0xe2, 0x82, - 0xfc, 0xbc, 0xe2, 0x54, 0x21, 0x09, 0x2e, 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0x74, 0x98, 0x12, - 0x18, 0xd7, 0xc8, 0x9a, 0x8b, 0xcd, 0x07, 0x6c, 0x9c, 0x90, 0x21, 0x17, 0x17, 0x84, 0xe5, 0x92, - 0x58, 0x92, 0x28, 0xc4, 0xaf, 0x07, 0xb5, 0x13, 0x6a, 0x85, 0x94, 0x00, 0x42, 0x00, 0x62, 0xa8, - 0x12, 0x43, 0x12, 0x1b, 0xd8, 0x41, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xbf, 0x9d, - 0x0d, 0xa0, 0x00, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// ListenClient is the client API for Listen service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ListenClient interface { - // 定义 ListenData 方法 - ListenData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) -} - -type listenClient struct { - cc *grpc.ClientConn -} - -func NewListenClient(cc *grpc.ClientConn) ListenClient { - return &listenClient{cc} -} - -func (c *listenClient) ListenData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { - out := new(Response) - err := c.cc.Invoke(ctx, "/listen.Listen/ListenData", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ListenServer is the server API for Listen service. -type ListenServer interface { - // 定义 ListenData 方法 - ListenData(context.Context, *Request) (*Response, error) -} - -// UnimplementedListenServer can be embedded to have forward compatible implementations. -type UnimplementedListenServer struct { -} - -func (*UnimplementedListenServer) ListenData(ctx context.Context, req *Request) (*Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListenData not implemented") -} - -func RegisterListenServer(s *grpc.Server, srv ListenServer) { - s.RegisterService(&_Listen_serviceDesc, srv) -} - -func _Listen_ListenData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ListenServer).ListenData(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/listen.Listen/ListenData", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ListenServer).ListenData(ctx, req.(*Request)) - } - return interceptor(ctx, in, info, handler) -} - -var _Listen_serviceDesc = grpc.ServiceDesc{ - ServiceName: "listen.Listen", - HandlerType: (*ListenServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ListenData", - Handler: _Listen_ListenData_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "listen.proto", -} diff --git a/internal/api/model/proto/read/read.pb.go b/internal/api/model/proto/read/read.pb.go deleted file mode 100644 index a89b009..0000000 --- a/internal/api/model/proto/read/read.pb.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: read.proto - -package read - -import ( - context "context" - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Request 请求结构 -type Request struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_7b10ec61df6818dd, []int{0} -} - -func (m *Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Request.Unmarshal(m, b) -} -func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Request.Marshal(b, m, deterministic) -} -func (m *Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_Request.Merge(m, src) -} -func (m *Request) XXX_Size() int { - return xxx_messageInfo_Request.Size(m) -} -func (m *Request) XXX_DiscardUnknown() { - xxx_messageInfo_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_Request proto.InternalMessageInfo - -func (m *Request) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -// Response 响应结构 -type Response struct { - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_7b10ec61df6818dd, []int{1} -} - -func (m *Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Response.Unmarshal(m, b) -} -func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Response.Marshal(b, m, deterministic) -} -func (m *Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_Response.Merge(m, src) -} -func (m *Response) XXX_Size() int { - return xxx_messageInfo_Response.Size(m) -} -func (m *Response) XXX_DiscardUnknown() { - xxx_messageInfo_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_Response proto.InternalMessageInfo - -func (m *Response) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func init() { - proto.RegisterType((*Request)(nil), "read.Request") - proto.RegisterType((*Response)(nil), "read.Response") -} - -func init() { proto.RegisterFile("read.proto", fileDescriptor_7b10ec61df6818dd) } - -var fileDescriptor_7b10ec61df6818dd = []byte{ - // 132 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x4a, 0x4d, 0x4c, - 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x01, 0xb1, 0x95, 0x64, 0xb9, 0xd8, 0x83, 0x52, - 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18, 0x15, - 0x18, 0x35, 0x38, 0x83, 0xc0, 0x6c, 0x25, 0x15, 0x2e, 0x8e, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, 0xbc, - 0xe2, 0x54, 0x21, 0x09, 0x2e, 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0x74, 0x98, 0x12, 0x18, 0xd7, - 0xc8, 0x98, 0x8b, 0x25, 0x28, 0x35, 0x31, 0x45, 0x48, 0x1b, 0xa4, 0x3a, 0x31, 0xc5, 0x25, 0xb1, - 0x24, 0x51, 0x88, 0x57, 0x0f, 0x6c, 0x17, 0xd4, 0x70, 0x29, 0x3e, 0x18, 0x17, 0x62, 0x98, 0x12, - 0x43, 0x12, 0x1b, 0xd8, 0x19, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x4a, 0x9b, 0x2d, - 0x94, 0x00, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// ReadClient is the client API for Read service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ReadClient interface { - // 定义方法 - ReadData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) -} - -type readClient struct { - cc *grpc.ClientConn -} - -func NewReadClient(cc *grpc.ClientConn) ReadClient { - return &readClient{cc} -} - -func (c *readClient) ReadData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { - out := new(Response) - err := c.cc.Invoke(ctx, "/read.Read/ReadData", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ReadServer is the server API for Read service. -type ReadServer interface { - // 定义方法 - ReadData(context.Context, *Request) (*Response, error) -} - -// UnimplementedReadServer can be embedded to have forward compatible implementations. -type UnimplementedReadServer struct { -} - -func (*UnimplementedReadServer) ReadData(ctx context.Context, req *Request) (*Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method ReadData not implemented") -} - -func RegisterReadServer(s *grpc.Server, srv ReadServer) { - s.RegisterService(&_Read_serviceDesc, srv) -} - -func _Read_ReadData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ReadServer).ReadData(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/read.Read/ReadData", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ReadServer).ReadData(ctx, req.(*Request)) - } - return interceptor(ctx, in, info, handler) -} - -var _Read_serviceDesc = grpc.ServiceDesc{ - ServiceName: "read.Read", - HandlerType: (*ReadServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ReadData", - Handler: _Read_ReadData_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "read.proto", -} diff --git a/internal/api/model/proto/speak/speak.pb.go b/internal/api/model/proto/speak/speak.pb.go deleted file mode 100644 index e576336..0000000 --- a/internal/api/model/proto/speak/speak.pb.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: speak.proto - -package speak - -import ( - context "context" - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Request 请求结构 -type Request struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_3c7d3e2f29338937, []int{0} -} - -func (m *Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Request.Unmarshal(m, b) -} -func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Request.Marshal(b, m, deterministic) -} -func (m *Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_Request.Merge(m, src) -} -func (m *Request) XXX_Size() int { - return xxx_messageInfo_Request.Size(m) -} -func (m *Request) XXX_DiscardUnknown() { - xxx_messageInfo_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_Request proto.InternalMessageInfo - -func (m *Request) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -// Response 响应结构 -type Response struct { - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_3c7d3e2f29338937, []int{1} -} - -func (m *Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Response.Unmarshal(m, b) -} -func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Response.Marshal(b, m, deterministic) -} -func (m *Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_Response.Merge(m, src) -} -func (m *Response) XXX_Size() int { - return xxx_messageInfo_Response.Size(m) -} -func (m *Response) XXX_DiscardUnknown() { - xxx_messageInfo_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_Response proto.InternalMessageInfo - -func (m *Response) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func init() { - proto.RegisterType((*Request)(nil), "speak.Request") - proto.RegisterType((*Response)(nil), "speak.Response") -} - -func init() { proto.RegisterFile("speak.proto", fileDescriptor_3c7d3e2f29338937) } - -var fileDescriptor_3c7d3e2f29338937 = []byte{ - // 132 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0x2e, 0x48, 0x4d, - 0xcc, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x73, 0x94, 0x64, 0xb9, 0xd8, 0x83, - 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18, - 0x15, 0x18, 0x35, 0x38, 0x83, 0xc0, 0x6c, 0x25, 0x15, 0x2e, 0x8e, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, - 0xbc, 0xe2, 0x54, 0x21, 0x09, 0x2e, 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0x74, 0x98, 0x12, 0x18, - 0xd7, 0xc8, 0x9c, 0x8b, 0x35, 0x18, 0x64, 0x9a, 0x90, 0x1e, 0x17, 0x27, 0x98, 0xe1, 0x92, 0x58, - 0x92, 0x28, 0xc4, 0xa7, 0x07, 0xb1, 0x0f, 0x6a, 0xbe, 0x14, 0x3f, 0x9c, 0x0f, 0x31, 0x50, 0x89, - 0x21, 0x89, 0x0d, 0xec, 0x16, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4d, 0x04, 0x6f, 0x05, - 0x9a, 0x00, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// SpeakClient is the client API for Speak service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type SpeakClient interface { - // 定义方法 - SpeakData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) -} - -type speakClient struct { - cc *grpc.ClientConn -} - -func NewSpeakClient(cc *grpc.ClientConn) SpeakClient { - return &speakClient{cc} -} - -func (c *speakClient) SpeakData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { - out := new(Response) - err := c.cc.Invoke(ctx, "/speak.Speak/SpeakData", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// SpeakServer is the server API for Speak service. -type SpeakServer interface { - // 定义方法 - SpeakData(context.Context, *Request) (*Response, error) -} - -// UnimplementedSpeakServer can be embedded to have forward compatible implementations. -type UnimplementedSpeakServer struct { -} - -func (*UnimplementedSpeakServer) SpeakData(ctx context.Context, req *Request) (*Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method SpeakData not implemented") -} - -func RegisterSpeakServer(s *grpc.Server, srv SpeakServer) { - s.RegisterService(&_Speak_serviceDesc, srv) -} - -func _Speak_SpeakData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SpeakServer).SpeakData(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/speak.Speak/SpeakData", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SpeakServer).SpeakData(ctx, req.(*Request)) - } - return interceptor(ctx, in, info, handler) -} - -var _Speak_serviceDesc = grpc.ServiceDesc{ - ServiceName: "speak.Speak", - HandlerType: (*SpeakServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "SpeakData", - Handler: _Speak_SpeakData_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "speak.proto", -} diff --git a/internal/api/model/proto/write/write.pb.go b/internal/api/model/proto/write/write.pb.go deleted file mode 100644 index 7be3b3e..0000000 --- a/internal/api/model/proto/write/write.pb.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: write.proto - -package write - -import ( - context "context" - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Request 请求结构 -type Request struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_67966b2b12a73214, []int{0} -} - -func (m *Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Request.Unmarshal(m, b) -} -func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Request.Marshal(b, m, deterministic) -} -func (m *Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_Request.Merge(m, src) -} -func (m *Request) XXX_Size() int { - return xxx_messageInfo_Request.Size(m) -} -func (m *Request) XXX_DiscardUnknown() { - xxx_messageInfo_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_Request proto.InternalMessageInfo - -func (m *Request) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -// Response 响应结构 -type Response struct { - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_67966b2b12a73214, []int{1} -} - -func (m *Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Response.Unmarshal(m, b) -} -func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Response.Marshal(b, m, deterministic) -} -func (m *Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_Response.Merge(m, src) -} -func (m *Response) XXX_Size() int { - return xxx_messageInfo_Response.Size(m) -} -func (m *Response) XXX_DiscardUnknown() { - xxx_messageInfo_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_Response proto.InternalMessageInfo - -func (m *Response) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func init() { - proto.RegisterType((*Request)(nil), "write.Request") - proto.RegisterType((*Response)(nil), "write.Response") -} - -func init() { proto.RegisterFile("write.proto", fileDescriptor_67966b2b12a73214) } - -var fileDescriptor_67966b2b12a73214 = []byte{ - // 132 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0x2f, 0xca, 0x2c, - 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x73, 0x94, 0x64, 0xb9, 0xd8, 0x83, - 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18, - 0x15, 0x18, 0x35, 0x38, 0x83, 0xc0, 0x6c, 0x25, 0x15, 0x2e, 0x8e, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, - 0xbc, 0xe2, 0x54, 0x21, 0x09, 0x2e, 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0x74, 0x98, 0x12, 0x18, - 0xd7, 0xc8, 0x9c, 0x8b, 0x35, 0x1c, 0x64, 0x9a, 0x90, 0x1e, 0x17, 0x27, 0x98, 0xe1, 0x92, 0x58, - 0x92, 0x28, 0xc4, 0xa7, 0x07, 0xb1, 0x0f, 0x6a, 0xbe, 0x14, 0x3f, 0x9c, 0x0f, 0x31, 0x50, 0x89, - 0x21, 0x89, 0x0d, 0xec, 0x16, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x7d, 0xc4, 0x7d, - 0x9a, 0x00, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// WriteClient is the client API for Write service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type WriteClient interface { - // 定义方法 - WriteData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) -} - -type writeClient struct { - cc *grpc.ClientConn -} - -func NewWriteClient(cc *grpc.ClientConn) WriteClient { - return &writeClient{cc} -} - -func (c *writeClient) WriteData(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { - out := new(Response) - err := c.cc.Invoke(ctx, "/write.Write/WriteData", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// WriteServer is the server API for Write service. -type WriteServer interface { - // 定义方法 - WriteData(context.Context, *Request) (*Response, error) -} - -// UnimplementedWriteServer can be embedded to have forward compatible implementations. -type UnimplementedWriteServer struct { -} - -func (*UnimplementedWriteServer) WriteData(ctx context.Context, req *Request) (*Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method WriteData not implemented") -} - -func RegisterWriteServer(s *grpc.Server, srv WriteServer) { - s.RegisterService(&_Write_serviceDesc, srv) -} - -func _Write_WriteData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(WriteServer).WriteData(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/write.Write/WriteData", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WriteServer).WriteData(ctx, req.(*Request)) - } - return interceptor(ctx, in, info, handler) -} - -var _Write_serviceDesc = grpc.ServiceDesc{ - ServiceName: "write.Write", - HandlerType: (*WriteServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "WriteData", - Handler: _Write_WriteData_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "write.proto", -} diff --git a/internal/api/router/middleware/exception/exception.go b/internal/api/router/middleware/exception/exception.go deleted file mode 100644 index 305b2a7..0000000 --- a/internal/api/router/middleware/exception/exception.go +++ /dev/null @@ -1,53 +0,0 @@ -package exception - -import ( - "fmt" - "runtime/debug" - "strings" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - "github.com/xinliangnote/go-gin-api/internal/api/util/response" - - "github.com/gin-gonic/gin" - "github.com/xinliangnote/go-util/mail" - "github.com/xinliangnote/go-util/time" -) - -func SetUp() gin.HandlerFunc { - - return func(c *gin.Context) { - defer func() { - if err := recover(); err != nil { - - DebugStack := "" - for _, v := range strings.Split(string(debug.Stack()), "\n") { - DebugStack += v + "
" - } - - subject := fmt.Sprintf("【重要错误】%s 项目出错了!", config.AppName) - - body := strings.ReplaceAll(MailTemplate, "{ErrorMsg}", fmt.Sprintf("%s", err)) - body = strings.ReplaceAll(body, "{RequestTime}", time.GetCurrentDate()) - body = strings.ReplaceAll(body, "{RequestURL}", c.Request.Method+" "+c.Request.Host+c.Request.RequestURI) - body = strings.ReplaceAll(body, "{RequestUA}", c.Request.UserAgent()) - body = strings.ReplaceAll(body, "{RequestIP}", c.ClientIP()) - body = strings.ReplaceAll(body, "{DebugStack}", DebugStack) - - options := &mail.Options{ - MailHost: config.SystemEmailHost, - MailPort: config.SystemEmailPort, - MailUser: config.SystemEmailUser, - MailPass: config.SystemEmailPass, - MailTo: config.ErrorNotifyUser, - Subject: subject, - Body: body, - } - _ = mail.Send(options) - - utilGin := response.Gin{Ctx: c} - utilGin.Response(500, "系统异常,请联系管理员!", nil) - } - }() - c.Next() - } -} diff --git a/internal/api/router/middleware/exception/mail_temp.go b/internal/api/router/middleware/exception/mail_temp.go deleted file mode 100755 index 3ce7294..0000000 --- a/internal/api/router/middleware/exception/mail_temp.go +++ /dev/null @@ -1,946 +0,0 @@ -package exception - -var MailTemplate = ` - - - - -
- -
-
- - - - - - -
- - - - - - -
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

系统告警

-
-
-
-
-
-
-
-
-
- - - - - - -
-
- - - - - - -
-
-
-
-
-
- - - - - - -
- - - - - - - - -
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
- - - - - - -
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

告警

-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
- - - - - - -
-
-
-
-
-
-
-
- - - - - - -
-
- - - - - - -
-
-
-

{ErrorMsg}

-
-
-
-
-
-
-
- - - - - - -
-
- - - - - - -
-
-
-
-
-
- - - - - - -
- - - - - - - - -
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
- - - - - - -
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

详情

-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
- - - - - - -
-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

请求时间:

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

{RequestTime}

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

请求地址:

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

{RequestURL}

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

请求 UA:

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

{RequestUA}

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

请求 IP:

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

{RequestIP}

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

DebugStack:

-
-
-
-
-
-
-
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

{DebugStack}

-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - -
-
- - - - - - -
-
-
-
-
-
- - - - - - -
- - - - - - -
- - - - - - -
- - - - - - -
-
-
- - - - - - -
-
- - - - - - -
-
-
-

请注意,该邮件地址不接收回复邮件。

-
-
-
-
-
-
-
-
- -` diff --git a/internal/api/router/middleware/jaeger/jaeger.go b/internal/api/router/middleware/jaeger/jaeger.go deleted file mode 100644 index 43bb68d..0000000 --- a/internal/api/router/middleware/jaeger/jaeger.go +++ /dev/null @@ -1,40 +0,0 @@ -package jaeger - -import ( - "github.com/xinliangnote/go-gin-api/internal/api/config" - "github.com/xinliangnote/go-gin-api/internal/api/util/jaeger_trace" - - "github.com/gin-gonic/gin" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" -) - -func SetUp() gin.HandlerFunc { - - return func(c *gin.Context) { - if config.JaegerOpen == 1 { - - var parentSpan opentracing.Span - - tracer, closer := jaeger_trace.NewJaegerTracer("LXL-TEST", config.JaegerHostPort) - defer closer.Close() - - spCtx, err := opentracing.GlobalTracer().Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(c.Request.Header)) - if err != nil { - parentSpan = tracer.StartSpan(c.Request.URL.Path) - defer parentSpan.Finish() - } else { - parentSpan = opentracing.StartSpan( - c.Request.URL.Path, - opentracing.ChildOf(spCtx), - opentracing.Tag{Key: string(ext.Component), Value: "HTTP"}, - ext.SpanKindRPCServer, - ) - defer parentSpan.Finish() - } - c.Set("Tracer", tracer) - c.Set("ParentSpanContext", parentSpan.Context()) - } - c.Next() - } -} diff --git a/internal/api/router/middleware/sign/aes/aes.go b/internal/api/router/middleware/sign/aes/aes.go deleted file mode 100644 index 10e160a..0000000 --- a/internal/api/router/middleware/sign/aes/aes.go +++ /dev/null @@ -1,124 +0,0 @@ -package sign_aes - -import ( - "errors" - "fmt" - "net/url" - "sort" - "strconv" - "strings" - "time" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - "github.com/xinliangnote/go-gin-api/internal/api/util/response" - - "github.com/gin-gonic/gin" - "github.com/xinliangnote/go-util/aes" - timeUtil "github.com/xinliangnote/go-util/time" -) - -var AppSecret string - -// AES 对称加密 -func SetUp() gin.HandlerFunc { - - return func(c *gin.Context) { - utilGin := response.Gin{Ctx: c} - - sign, err := verifySign(c) - - if sign != nil { - utilGin.Response(-1, "Debug Sign", sign) - c.Abort() - return - } - - if err != nil { - utilGin.Response(-1, err.Error(), sign) - c.Abort() - return - } - - c.Next() - } -} - -// 验证签名 -func verifySign(c *gin.Context) (map[string]string, error) { - _ = c.Request.ParseForm() - req := c.Request.Form - debug := strings.Join(c.Request.Form["debug"], "") - ak := strings.Join(c.Request.Form["ak"], "") - sn := strings.Join(c.Request.Form["sn"], "") - ts := strings.Join(c.Request.Form["ts"], "") - - // 验证来源 - value, ok := config.ApiAuthConfig[ak] - if ok { - AppSecret = value["aes"] - } else { - return nil, errors.New("ak Error") - } - - if debug == "1" { - currentUnix := timeUtil.GetCurrentUnix() - req.Set("ts", strconv.FormatInt(currentUnix, 10)) - - sn, err := createSign(req) - if err != nil { - return nil, errors.New("sn Exception") - } - - res := map[string]string{ - "ts": strconv.FormatInt(currentUnix, 10), - "sn": sn, - } - return res, nil - } - - // 验证过期时间 - timestamp := time.Now().Unix() - exp, _ := strconv.ParseInt(config.AppSignExpiry, 10, 64) - tsInt, _ := strconv.ParseInt(ts, 10, 64) - if tsInt > timestamp || timestamp-tsInt >= exp { - return nil, errors.New("ts Error") - } - - // 验证签名 - if sn == "" { - return nil, errors.New("sn Error") - } - - decryptStr, decryptErr := aes.Decrypt(sn, []byte(AppSecret), AppSecret) - if decryptErr != nil { - return nil, errors.New(decryptErr.Error()) - } - if decryptStr != createEncryptStr(req) { - return nil, errors.New("sn Error") - } - return nil, nil -} - -// 创建签名 -func createSign(params url.Values) (string, error) { - return aes.Encrypt(createEncryptStr(params), []byte(AppSecret), AppSecret) -} - -func createEncryptStr(params url.Values) string { - var key []string - var str = "" - for k := range params { - if k != "sn" && k != "debug" { - key = append(key, k) - } - } - sort.Strings(key) - for i := 0; i < len(key); i++ { - if i == 0 { - str = fmt.Sprintf("%v=%v", key[i], params.Get(key[i])) - } else { - str = str + fmt.Sprintf("&%v=%v", key[i], params.Get(key[i])) - } - } - return str -} diff --git a/internal/api/router/middleware/sign/md5/md5.go b/internal/api/router/middleware/sign/md5/md5.go deleted file mode 100644 index fd422bc..0000000 --- a/internal/api/router/middleware/sign/md5/md5.go +++ /dev/null @@ -1,112 +0,0 @@ -package sign_md5 - -import ( - "errors" - "fmt" - "net/url" - "sort" - "strconv" - "strings" - "time" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - "github.com/xinliangnote/go-gin-api/internal/api/util/response" - - "github.com/gin-gonic/gin" - "github.com/xinliangnote/go-util/md5" - timeUtil "github.com/xinliangnote/go-util/time" -) - -var AppSecret string - -// MD5 组合加密 -func SetUp() gin.HandlerFunc { - - return func(c *gin.Context) { - utilGin := response.Gin{Ctx: c} - - sign, err := verifySign(c) - - if sign != nil { - utilGin.Response(-1, "Debug Sign", sign) - c.Abort() - return - } - - if err != nil { - utilGin.Response(-1, err.Error(), sign) - c.Abort() - return - } - - c.Next() - } -} - -// 验证签名 -func verifySign(c *gin.Context) (map[string]string, error) { - _ = c.Request.ParseForm() - req := c.Request.Form - debug := strings.Join(c.Request.Form["debug"], "") - ak := strings.Join(c.Request.Form["ak"], "") - sn := strings.Join(c.Request.Form["sn"], "") - ts := strings.Join(c.Request.Form["ts"], "") - - // 验证来源 - value, ok := config.ApiAuthConfig[ak] - if ok { - AppSecret = value["md5"] - } else { - return nil, errors.New("ak Error") - } - - if debug == "1" { - currentUnix := timeUtil.GetCurrentUnix() - req.Set("ts", strconv.FormatInt(currentUnix, 10)) - res := map[string]string{ - "ts": strconv.FormatInt(currentUnix, 10), - "sn": createSign(req), - } - return res, nil - } - - // 验证过期时间 - timestamp := time.Now().Unix() - exp, _ := strconv.ParseInt(config.AppSignExpiry, 10, 64) - tsInt, _ := strconv.ParseInt(ts, 10, 64) - if tsInt > timestamp || timestamp-tsInt >= exp { - return nil, errors.New("ts Error") - } - - // 验证签名 - if sn == "" || sn != createSign(req) { - return nil, errors.New("sn Error") - } - - return nil, nil -} - -// 创建签名 -func createSign(params url.Values) string { - // 自定义 MD5 组合 - return md5.MD5(AppSecret + createEncryptStr(params) + AppSecret) -} - -func createEncryptStr(params url.Values) string { - var key []string - var str = "" - for k := range params { - if k != "sn" && k != "debug" { - key = append(key, k) - } - } - sort.Strings(key) - for i := 0; i < len(key); i++ { - if i == 0 { - str = fmt.Sprintf("%v=%v", key[i], params.Get(key[i])) - } else { - str = str + fmt.Sprintf("&%v=%v", key[i], params.Get(key[i])) - } - } - return str -} diff --git a/internal/api/router/middleware/sign/rsa/rsa.go b/internal/api/router/middleware/sign/rsa/rsa.go deleted file mode 100644 index 9fbb228..0000000 --- a/internal/api/router/middleware/sign/rsa/rsa.go +++ /dev/null @@ -1,124 +0,0 @@ -package sign_rsa - -import ( - "errors" - "fmt" - "net/url" - "sort" - "strconv" - "strings" - "time" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - "github.com/xinliangnote/go-gin-api/internal/api/util/response" - - "github.com/gin-gonic/gin" - "github.com/xinliangnote/go-util/rsa" - timeUtil "github.com/xinliangnote/go-util/time" -) - -var AppSecret string - -// RSA 非对称加密 -func SetUp() gin.HandlerFunc { - - return func(c *gin.Context) { - utilGin := response.Gin{Ctx: c} - - sign, err := verifySign(c) - - if sign != nil { - utilGin.Response(-1, "Debug Sign", sign) - c.Abort() - return - } - - if err != nil { - utilGin.Response(-1, err.Error(), sign) - c.Abort() - return - } - - c.Next() - } -} - -// 验证签名 -func verifySign(c *gin.Context) (map[string]string, error) { - _ = c.Request.ParseForm() - req := c.Request.Form - debug := strings.Join(c.Request.Form["debug"], "") - ak := strings.Join(c.Request.Form["ak"], "") - sn := strings.Join(c.Request.Form["sn"], "") - ts := strings.Join(c.Request.Form["ts"], "") - - // 验证来源 - value, ok := config.ApiAuthConfig[ak] - if ok { - AppSecret = value["rsa"] - } else { - return nil, errors.New("ak Error") - } - - if debug == "1" { - currentUnix := timeUtil.GetCurrentUnix() - req.Set("ts", strconv.FormatInt(currentUnix, 10)) - - sn, err := createSign(req) - if err != nil { - return nil, errors.New("sn Exception") - } - - res := map[string]string{ - "ts": strconv.FormatInt(currentUnix, 10), - "sn": sn, - } - return res, nil - } - - // 验证过期时间 - timestamp := time.Now().Unix() - exp, _ := strconv.ParseInt(config.AppSignExpiry, 10, 64) - tsInt, _ := strconv.ParseInt(ts, 10, 64) - if tsInt > timestamp || timestamp-tsInt >= exp { - return nil, errors.New("ts Error") - } - - // 验证签名 - if sn == "" { - return nil, errors.New("sn Error") - } - - decryptStr, decryptErr := rsa.PrivateDecrypt(sn, config.AppRsaPrivateFile) - if decryptErr != nil { - return nil, errors.New(decryptErr.Error()) - } - if decryptStr != createEncryptStr(req) { - return nil, errors.New("sn Error") - } - return nil, nil -} - -// 创建签名 -func createSign(params url.Values) (string, error) { - return rsa.PublicEncrypt(createEncryptStr(params), AppSecret) -} - -func createEncryptStr(params url.Values) string { - var key []string - var str = "" - for k := range params { - if k != "sn" && k != "debug" { - key = append(key, k) - } - } - sort.Strings(key) - for i := 0; i < len(key); i++ { - if i == 0 { - str = fmt.Sprintf("%v=%v", key[i], params.Get(key[i])) - } else { - str = str + fmt.Sprintf("&%v=%v", key[i], params.Get(key[i])) - } - } - return str -} diff --git a/internal/api/util/grpc_client/grpc_client.go b/internal/api/util/grpc_client/grpc_client.go deleted file mode 100644 index 28118ae..0000000 --- a/internal/api/util/grpc_client/grpc_client.go +++ /dev/null @@ -1,77 +0,0 @@ -package grpc_client - -import ( - "context" - "fmt" - "time" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - "github.com/xinliangnote/go-gin-api/internal/api/util/grpc_log" - "github.com/xinliangnote/go-gin-api/internal/api/util/jaeger_trace" - - "github.com/gin-gonic/gin" - grpc_middeware "github.com/grpc-ecosystem/go-grpc-middleware" - "github.com/opentracing/opentracing-go" - "google.golang.org/grpc" -) - -func CreateServiceListenConn(c *gin.Context) *grpc.ClientConn { - return createGrpcConn("127.0.0.1:9901", c) -} - -func CreateServiceSpeakConn(c *gin.Context) *grpc.ClientConn { - return createGrpcConn("127.0.0.1:9902", c) -} - -func CreateServiceReadConn(c *gin.Context) *grpc.ClientConn { - return createGrpcConn("127.0.0.1:9903", c) -} - -func CreateServiceWriteConn(c *gin.Context) *grpc.ClientConn { - return createGrpcConn("127.0.0.1:9904", c) -} - -func createGrpcConn(serviceAddress string, c *gin.Context) *grpc.ClientConn { - - var conn *grpc.ClientConn - var err error - - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500) - defer cancel() - - if config.JaegerOpen == 1 { - - tracer, _ := c.Get("Tracer") - parentSpanContext, _ := c.Get("ParentSpanContext") - - conn, err = grpc.DialContext( - ctx, - serviceAddress, - grpc.WithInsecure(), - grpc.WithBlock(), - grpc.WithUnaryInterceptor( - grpc_middeware.ChainUnaryClient( - jaeger_trace.ClientInterceptor(tracer.(opentracing.Tracer), parentSpanContext.(opentracing.SpanContext)), - grpc_log.ClientInterceptor(), - ), - ), - ) - } else { - conn, err = grpc.DialContext( - ctx, - serviceAddress, - grpc.WithInsecure(), - grpc.WithBlock(), - grpc.WithUnaryInterceptor( - grpc_middeware.ChainUnaryClient( - grpc_log.ClientInterceptor(), - ), - ), - ) - } - - if err != nil { - fmt.Println(serviceAddress, "grpc conn err:", err) - } - return conn -} diff --git a/internal/api/util/grpc_log/grpc_log.go b/internal/api/util/grpc_log/grpc_log.go deleted file mode 100644 index 31eb0bb..0000000 --- a/internal/api/util/grpc_log/grpc_log.go +++ /dev/null @@ -1,63 +0,0 @@ -package grpc_log - -import ( - "context" - "fmt" - "log" - "os" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - - "github.com/xinliangnote/go-util/json" - "github.com/xinliangnote/go-util/time" - "google.golang.org/grpc" -) - -var grpcChannel = make(chan string, 100) - -func ClientInterceptor() grpc.UnaryClientInterceptor { - - go handleGrpcChannel() - - return func(ctx context.Context, method string, - req, reply interface{}, cc *grpc.ClientConn, - invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - - // 开始时间 - startTime := time.GetCurrentMilliUnix() - - err := invoker(ctx, method, req, reply, cc, opts...) - - // 结束时间 - endTime := time.GetCurrentMilliUnix() - - // 日志格式 - grpcLogMap := make(map[string]interface{}) - - grpcLogMap["request_time"] = startTime - grpcLogMap["request_data"] = req - grpcLogMap["request_method"] = method - - grpcLogMap["response_data"] = reply - grpcLogMap["response_error"] = err - - grpcLogMap["cost_time"] = fmt.Sprintf("%vms", endTime-startTime) - - grpcLogJson, _ := json.Encode(grpcLogMap) - - grpcChannel <- grpcLogJson - - return err - } -} - -func handleGrpcChannel() { - if f, err := os.OpenFile(config.AppGrpcLogName, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666); err != nil { - log.Println(err) - } else { - for accessLog := range grpcChannel { - _, _ = f.WriteString(accessLog + "\n") - } - } - return -} diff --git a/internal/api/util/jaeger_trace/jaeger_trace.go b/internal/api/util/jaeger_trace/jaeger_trace.go deleted file mode 100644 index 44e9d42..0000000 --- a/internal/api/util/jaeger_trace/jaeger_trace.go +++ /dev/null @@ -1,98 +0,0 @@ -package jaeger_trace - -import ( - "context" - "fmt" - "io" - "strings" - - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" - "github.com/opentracing/opentracing-go/log" - "github.com/uber/jaeger-client-go" - jaegerConfig "github.com/uber/jaeger-client-go/config" - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" -) - -func NewJaegerTracer(serviceName string, jaegerHostPort string) (opentracing.Tracer, io.Closer) { - - cfg := &jaegerConfig.Configuration{ - Sampler: &jaegerConfig.SamplerConfig{ - Type: "const", //固定采样 - Param: 1, //1=全采样、0=不采样 - }, - - Reporter: &jaegerConfig.ReporterConfig{ - LogSpans: true, - LocalAgentHostPort: jaegerHostPort, - }, - - ServiceName: serviceName, - } - - tracer, closer, err := cfg.NewTracer(jaegerConfig.Logger(jaeger.StdLogger)) - if err != nil { - panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err)) - } - opentracing.SetGlobalTracer(tracer) - return tracer, closer -} - -type MDReaderWriter struct { - metadata.MD -} - -// ForeachKey implements ForeachKey of opentracing.TextMapReader -func (c MDReaderWriter) ForeachKey(handler func(key, val string) error) error { - for k, vs := range c.MD { - for _, v := range vs { - if err := handler(k, v); err != nil { - return err - } - } - } - return nil -} - -// Set implements Set() of opentracing.TextMapWriter -func (c MDReaderWriter) Set(key, val string) { - key = strings.ToLower(key) - c.MD[key] = append(c.MD[key], val) -} - -// ClientInterceptor grpc client -func ClientInterceptor(tracer opentracing.Tracer, spanContext opentracing.SpanContext) grpc.UnaryClientInterceptor { - return func(ctx context.Context, method string, - req, reply interface{}, cc *grpc.ClientConn, - invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - - span := opentracing.StartSpan( - "call gRPC", - opentracing.ChildOf(spanContext), - opentracing.Tag{Key: string(ext.Component), Value: "gRPC"}, - ext.SpanKindRPCClient, - ) - - defer span.Finish() - - md, ok := metadata.FromOutgoingContext(ctx) - if !ok { - md = metadata.New(nil) - } else { - md = md.Copy() - } - - err := tracer.Inject(span.Context(), opentracing.TextMap, MDReaderWriter{md}) - if err != nil { - span.LogFields(log.String("inject-error", err.Error())) - } - - newCtx := metadata.NewOutgoingContext(ctx, md) - err = invoker(newCtx, method, req, reply, cc, opts...) - if err != nil { - span.LogFields(log.String("call-error", err.Error())) - } - return err - } -} diff --git a/internal/api/util/request/request.go b/internal/api/util/request/request.go deleted file mode 100644 index a71cf9b..0000000 --- a/internal/api/util/request/request.go +++ /dev/null @@ -1,64 +0,0 @@ -package request - -import ( - "crypto/tls" - "io/ioutil" - "log" - "net/http" - "time" - - "github.com/xinliangnote/go-gin-api/internal/api/config" - - "github.com/gin-gonic/gin" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" -) - -func HttpGet(url string, c *gin.Context) (string, error) { - - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - - client := &http.Client{ - Timeout: time.Second * 5, //默认5秒超时时间 - Transport: tr, - } - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return "", err - } - - if config.JaegerOpen == 1 { - - tracer, _ := c.Get("Tracer") - parentSpanContext, _ := c.Get("ParentSpanContext") - - span := opentracing.StartSpan( - "call Http Get", - opentracing.ChildOf(parentSpanContext.(opentracing.SpanContext)), - opentracing.Tag{Key: string(ext.Component), Value: "HTTP"}, - ext.SpanKindRPCClient, - ) - - span.Finish() - - injectErr := tracer.(opentracing.Tracer).Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header)) - if injectErr != nil { - log.Fatalf("%s: Couldn't inject headers", err) - } - } - - resp, err := client.Do(req) - if err != nil { - return "", err - } - content, err := ioutil.ReadAll(resp.Body) - defer resp.Body.Close() - - if err != nil { - return "", err - } - return string(content), err -} diff --git a/internal/api/util/response/response.go b/internal/api/util/response/response.go deleted file mode 100644 index 03ba98f..0000000 --- a/internal/api/util/response/response.go +++ /dev/null @@ -1,22 +0,0 @@ -package response - -import "github.com/gin-gonic/gin" - -type Gin struct { - Ctx *gin.Context -} - -type Response struct { - Code int `json:"code"` - Message string `json:"msg"` - Data interface{} `json:"data"` -} - -func (g *Gin) Response(code int, msg string, data interface{}) { - g.Ctx.JSON(200, Response{ - Code: code, - Message: msg, - Data: data, - }) - return -} diff --git a/internal/pkg/configs/configs.go b/internal/pkg/configs/configs.go index 1d2e1bf..9cf030d 100644 --- a/internal/pkg/configs/configs.go +++ b/internal/pkg/configs/configs.go @@ -9,10 +9,17 @@ import ( var config = new(Config) type Config struct { - DB struct { + Mail struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` - } `mapstructure:"db"` + User string `mapstructure:"user"` + Pass string `mapstructure:"pass"` + To string `mapstructure:"to"` + } `mapstructure:"mail"` + + JWT struct { + Secret string `mapstructure:"secret"` + } `mapstructure:"jwt"` Aes struct { Key string `mapstructure:"key"` diff --git a/internal/pkg/core/context.go b/internal/pkg/core/context.go index ae03671..11c722d 100644 --- a/internal/pkg/core/context.go +++ b/internal/pkg/core/context.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "net/http" "net/url" + "strings" "sync" "github.com/xinliangnote/go-gin-api/internal/pkg/errno" @@ -20,10 +21,14 @@ type HandlerFunc func(c Context) type Journal = journal.T const ( - _JournalName = "_journal_" - _LoggerName = "_logger_" - _BodyName = "_body_" - _PayloadName = "_payload_" + _Alias = "_alias_" + _JournalName = "_journal_" + _LoggerName = "_logger_" + _BodyName = "_body_" + _PayloadName = "_payload_" + _UserID = "_user_id_" + _UserName = "_user_name_" + _AbortErrorName = "_abort_error_" ) var contextPool = &sync.Pool{ @@ -87,14 +92,22 @@ type Context interface { GetHeader(key string) string SetHeader(key, value string) + UserID() int + setUserID(userID int) + + UserName() string + setUserName(userName string) + + AbortWithError(err errno.Error) + abortError() errno.Error + + Alias() string + setAlias(path string) + RawData() []byte - Method() string - Host() string - Path() string - URI() string } @@ -208,6 +221,59 @@ func (c *context) SetHeader(key, value string) { c.ctx.Header(key, value) } +func (c *context) UserID() int { + val, ok := c.ctx.Get(_UserID) + if !ok { + return 0 + } + + return val.(int) +} + +func (c *context) setUserID(userID int) { + c.ctx.Set(_UserID, userID) +} + +func (c *context) UserName() string { + val, ok := c.ctx.Get(_UserName) + if !ok { + return "" + } + + return val.(string) +} + +func (c *context) setUserName(userName string) { + c.ctx.Set(_UserName, userName) +} + +func (c *context) AbortWithError(err errno.Error) { + if err != nil { + c.ctx.AbortWithStatus(http.StatusInternalServerError) + c.ctx.Set(_AbortErrorName, err) + } +} + +func (c *context) abortError() errno.Error { + err, _ := c.ctx.Get(_AbortErrorName) + return err.(errno.Error) +} + +func (c *context) Alias() string { + path, ok := c.ctx.Get(_Alias) + if !ok { + return "" + } + + return path.(string) +} + +func (c *context) setAlias(path string) { + if path = strings.TrimSpace(path); path != "" { + c.ctx.Set(_Alias, path) + } +} + func (c *context) RawData() []byte { body, ok := c.ctx.Get(_BodyName) if !ok { diff --git a/internal/pkg/core/core.go b/internal/pkg/core/core.go index d859d15..3217acd 100644 --- a/internal/pkg/core/core.go +++ b/internal/pkg/core/core.go @@ -19,6 +19,7 @@ import ( cors "github.com/rs/cors/wrapper/gin" ginSwagger "github.com/swaggo/gin-swagger" "github.com/swaggo/gin-swagger/swaggerFiles" + "go.uber.org/multierr" "go.uber.org/zap" "golang.org/x/time/rate" ) @@ -41,6 +42,7 @@ type option struct { disableSwagger bool disablePrometheus bool panicNotify OnPanicNotify + recordMetrics RecordMetrics enableCors bool enableRate bool } @@ -48,6 +50,10 @@ type option struct { // OnPanicNotify 发生panic时通知用 type OnPanicNotify func(ctx Context, err interface{}, stackInfo string) +// RecordMetrics 记录prometheus指标用 +// 如果使用AliasForRecordMetrics配置了别名,uri将被替换为别名。 +type RecordMetrics func(method, uri string, success bool, httpCode, businessCode int, costSeconds float64) + // WithDisablePProf 禁用 pprof func WithDisablePProf() Option { return func(opt *option) { @@ -73,6 +79,14 @@ func WithDisableproPrometheus() Option { func WithPanicNotify(notify OnPanicNotify) Option { return func(opt *option) { opt.panicNotify = notify + fmt.Println(color.Green("* [register panic notify]")) + } +} + +// WithRecordMetrics 设置记录prometheus记录指标回调 +func WithRecordMetrics(record RecordMetrics) Option { + return func(opt *option) { + opt.recordMetrics = record } } @@ -80,12 +94,14 @@ func WithPanicNotify(notify OnPanicNotify) Option { func WithEnableCors() Option { return func(opt *option) { opt.enableCors = true + fmt.Println(color.Green("* [register cors]")) } } func WithEnableRate() Option { return func(opt *option) { opt.enableRate = true + fmt.Println(color.Green("* [register rate]")) } } @@ -94,6 +110,27 @@ func DisableJournal(ctx Context) { ctx.disableJournal() } +// AliasForRecordMetrics 对请求uri起个别名,用于prometheus记录指标。 +// 如:Get /user/:username 这样的uri,因为username会有非常多的情况,这样记录prometheus指标会非常的不有好。 +func AliasForRecordMetrics(path string) HandlerFunc { + return func(ctx Context) { + ctx.setAlias(path) + } +} + +// WrapAuthHandler 用来处理 Auth 的入口,在之后的handler中只需 ctx.UserID() ctx.UserName() 即可。 +func WrapAuthHandler(handler func(Context) (userID int, userName string, err errno.Error)) HandlerFunc { + return func(ctx Context) { + userID, userName, err := handler(ctx) + if err != nil { + ctx.AbortWithError(err) + return + } + ctx.setUserID(userID) + ctx.setUserName(userName) + } +} + // RouterGroup 包装gin的RouterGroup type RouterGroup interface { Group(string, ...HandlerFunc) RouterGroup @@ -199,8 +236,6 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) { gin.SetMode(gin.ReleaseMode) gin.DisableBindValidation() - engine := gin.New() - mux := &mux{ engine: gin.New(), } @@ -232,15 +267,18 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) { } if !opt.disablePProf { - pprof.Register(engine) // register pprof to gin + pprof.Register(mux.engine) // register pprof to gin + fmt.Println(color.Green("* [register pprof]")) } if !opt.disableSwagger { mux.engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // register swagger + fmt.Println(color.Green("* [register swagger]")) } if !opt.disablePrometheus { mux.engine.GET("/metrics", gin.WrapH(promhttp.Handler())) // register prometheus + fmt.Println(color.Green("* [register prometheus]")) } if opt.enableCors { @@ -303,18 +341,48 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) { return } - response := context.GetPayload() - if x := context.Journal(); x != nil { - context.SetHeader(journal.JournalHeader, x.ID()) - response.WithID(x.ID()) + var ( + response errno.Error + abortErr error + ) + + if ctx.IsAborted() { + for i := range ctx.Errors { // gin error + multierr.AppendInto(&abortErr, ctx.Errors[i]) + } + + if err := context.abortError(); err != nil { // customer err + multierr.AppendInto(&abortErr, errors.New(err.GetMsg())) + response = err + } } else { - response.WithID("") + response = context.GetPayload() } if response != nil { + if x := context.Journal(); x != nil { + context.SetHeader(journal.JournalHeader, x.ID()) + response.WithID(x.ID()) + } else { + response.WithID("") + } ctx.JSON(http.StatusOK, response) } + if opt.recordMetrics != nil { + uri := context.URI() + if alias := context.Alias(); alias != "" { + uri = alias + } + + businessCode := 0 + if response != nil { + businessCode = response.GetCode() + } + + opt.recordMetrics(context.Method(), uri, !ctx.IsAborted() && ctx.Writer.Status() == http.StatusOK, ctx.Writer.Status(), businessCode, time.Since(ts).Seconds()) + } + var j *journal.Journal if x := context.Journal(); x != nil { j = x.(*journal.Journal) diff --git a/internal/pkg/errno/errno.go b/internal/pkg/errno/errno.go index 2f9565b..641d058 100644 --- a/internal/pkg/errno/errno.go +++ b/internal/pkg/errno/errno.go @@ -13,6 +13,10 @@ type Error interface { WithData(data interface{}) Error // WithID 设置当前请求的唯一ID WithID(id string) Error + // GetCode 获取 Code + GetCode() int + // GetMsg 获取 Msg + GetMsg() string // ToString 返回 JSON 格式的错误详情 ToString() string } @@ -44,6 +48,14 @@ func (e *err) WithID(id string) Error { return e } +func (e *err) GetCode() int { + return e.Code +} + +func (e *err) GetMsg() string { + return e.Msg +} + // ToString 返回 JSON 格式的错误详情 func (e *err) ToString() string { err := &struct { diff --git a/internal/pkg/metrics/metrics.go b/internal/pkg/metrics/metrics.go new file mode 100644 index 0000000..3721716 --- /dev/null +++ b/internal/pkg/metrics/metrics.go @@ -0,0 +1,6 @@ +package metrics + +// RecordMetrics 记录指标 +func RecordMetrics(method, uri string, success bool, httpCode, businessCode int, costSeconds float64) { + //fmt.Printf(">>>>>>>Metrics\nmethod:%s\nuri:%s\nsuccess:%t\nhttp code:%d\nbusiness code:%d\ncost seconds:%.9f\n<<<<<<<\n", method, uri, success, httpCode, businessCode, costSeconds) +} diff --git a/internal/pkg/notify/email.go b/internal/pkg/notify/email.go deleted file mode 100644 index 70c5543..0000000 --- a/internal/pkg/notify/email.go +++ /dev/null @@ -1,29 +0,0 @@ -package notify - -import ( - "bytes" - "fmt" - "strings" - - "github.com/xinliangnote/go-gin-api/internal/pkg/core" - "github.com/xinliangnote/go-gin-api/pkg/color" -) - -// Email -func Email(ctx core.Context, err interface{}, stackInfo string) { - - buf := bytes.NewBuffer(nil) - buf.WriteString(fmt.Sprintf("URI: %s %s%s
", ctx.Method(), ctx.Host(), ctx.URI())) - buf.WriteString(fmt.Sprintf("JournalID: %s
", ctx.Journal().ID())) - buf.WriteString(fmt.Sprintf("ErrorInfo: %+v
", err)) - buf.WriteString(fmt.Sprintf("StackInfo:
")) - - for _, v := range strings.Split(stackInfo, "\n") { - buf.WriteString(v) - buf.WriteString("
") - } - - content := buf.String() - - fmt.Println(color.Red(content)) -} diff --git a/internal/pkg/notify/mail/mail.go b/internal/pkg/notify/mail/mail.go new file mode 100644 index 0000000..12c323c --- /dev/null +++ b/internal/pkg/notify/mail/mail.go @@ -0,0 +1,39 @@ +package mail + +import ( + "strings" + + "gopkg.in/gomail.v2" +) + +type Options struct { + MailHost string + MailPort int + MailUser string // 发件人 + MailPass string // 发件人密码 + MailTo string // 收件人 多个用,分割 + Subject string // 邮件主题 + Body string // 邮件内容 +} + +func Send(o *Options) error { + + m := gomail.NewMessage() + + //设置发件人 + m.SetHeader("From", o.MailUser) + + //设置发送给多个用户 + mailArrTo := strings.Split(o.MailTo, ",") + m.SetHeader("To", mailArrTo...) + + //设置邮件主题 + m.SetHeader("Subject", o.Subject) + + //设置邮件正文 + m.SetBody("text/html", o.Body) + + d := gomail.NewDialer(o.MailHost, o.MailPort, o.MailUser, o.MailPass) + + return d.DialAndSend(m) +} diff --git a/internal/pkg/notify/mail/mail_test.go b/internal/pkg/notify/mail/mail_test.go new file mode 100644 index 0000000..1320def --- /dev/null +++ b/internal/pkg/notify/mail/mail_test.go @@ -0,0 +1,23 @@ +package mail + +import ( + "testing" +) + +func TestSend(t *testing.T) { + options := &Options{ + MailHost: "smtp.163.com", + MailPort: 465, + MailUser: "xxx@163.com", + MailPass: "", //密码或授权码 + MailTo: "", + Subject: "subject", + Body: "body", + } + err := Send(options) + if err != nil { + t.Error("Mail Send error", err) + return + } + t.Log("success") +} diff --git a/internal/pkg/notify/mail/template.go b/internal/pkg/notify/mail/template.go new file mode 100644 index 0000000..fdcd861 --- /dev/null +++ b/internal/pkg/notify/mail/template.go @@ -0,0 +1,44 @@ +package mail + +import ( + "bytes" + "fmt" + "html/template" + "time" + + "github.com/xinliangnote/go-gin-api/internal/pkg/notify/mail/templates" +) + +// NewPanicHTMLEmail 发送系统异常邮件 html +func NewPanicHTMLEmail(method, host, uri, id string, msg interface{}, stack string) (subject string, body string, err error) { + mailData := &struct { + URL string + ID string + Msg string + Stack string + Year int + }{ + URL: fmt.Sprintf("%s %s%s", method, host, uri), + ID: id, + Msg: fmt.Sprintf("%+v", msg), + Stack: stack, + Year: time.Now().Year(), + } + + mailTplContent, err := getEmailHTMLContent(templates.PanicMail, mailData) + return fmt.Sprintf("[系统异常]-%s", uri), mailTplContent, err +} + +// getEmailHTMLContent 获取邮件模板 +func getEmailHTMLContent(mailTpl string, mailData interface{}) (string, error) { + tpl, err := template.New("email tpl").Parse(mailTpl) + if err != nil { + return "", err + } + buffer := new(bytes.Buffer) + err = tpl.Execute(buffer, mailData) + if err != nil { + return "", err + } + return buffer.String(), nil +} diff --git a/internal/pkg/notify/mail/templates/panic-mail.go b/internal/pkg/notify/mail/templates/panic-mail.go new file mode 100644 index 0000000..6552632 --- /dev/null +++ b/internal/pkg/notify/mail/templates/panic-mail.go @@ -0,0 +1,119 @@ +package templates + +const PanicMail = ` + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ 系统异常 +
+ + + + +
+ +

+ Hello! +

+ + +

+ 您收到此电子邮件,请紧急安排处理。 +

+ + + + + + + + + + + + + + + + + + + + + + +
+ ID: + + {{.ID}} +
+ URL: + + {{.URL}} +
+ Error: + + {{.Msg}} +
+ Stack: + + {{.Stack}}} +
+
+
+ + + + +
+

+ © {{.Year}} + All rights reserved. +

+
+
+
+ + +` diff --git a/internal/pkg/notify/notify.go b/internal/pkg/notify/notify.go new file mode 100644 index 0000000..a4be346 --- /dev/null +++ b/internal/pkg/notify/notify.go @@ -0,0 +1,38 @@ +package notify + +import ( + "github.com/xinliangnote/go-gin-api/internal/pkg/configs" + "github.com/xinliangnote/go-gin-api/internal/pkg/core" + "github.com/xinliangnote/go-gin-api/internal/pkg/notify/mail" + + "go.uber.org/zap" +) + +// OnPanicNotify +func OnPanicNotify(ctx core.Context, err interface{}, stackInfo string) { + cfg := configs.Get().Mail + if cfg.Host == "" || cfg.Port == 0 || cfg.User == "" || cfg.Pass == "" || cfg.To == "" { + ctx.Logger().Error("Mail config error") + return + } + + subject, body, htmlErr := mail.NewPanicHTMLEmail(ctx.Method(), ctx.Host(), ctx.URI(), ctx.Journal().ID(), err, stackInfo) + if htmlErr != nil { + ctx.Logger().Error("NewPanicHTMLEmail error", zap.Error(htmlErr)) + return + } + options := &mail.Options{ + MailHost: cfg.Host, + MailPort: cfg.Port, + MailUser: cfg.User, + MailPass: cfg.Pass, + MailTo: cfg.To, + Subject: subject, + Body: body, + } + sendErr := mail.Send(options) + if sendErr != nil { + ctx.Logger().Error("Mail Send error", zap.Error(sendErr)) + } + return +} diff --git a/internal/pkg/token/token.go b/internal/pkg/token/token.go new file mode 100644 index 0000000..080fcd4 --- /dev/null +++ b/internal/pkg/token/token.go @@ -0,0 +1,53 @@ +package token + +import ( + "time" + + "github.com/dgrijalva/jwt-go" +) + +//var secret = configs.Get().JWT.Secret +var secret = "i1ydX9RtHyuJTrw7frcu" + +type claims struct { + UserID int + UserName string + jwt.StandardClaims +} + +func Sign(userId int, userName string) (tokenString string, err error) { + // The token content. + // iss: (Issuer)签发者 + // iat: (Issued At)签发时间,用Unix时间戳表示 + // exp: (Expiration Time)过期时间,用Unix时间戳表示 + // aud: (Audience)接收该JWT的一方 + // sub: (Subject)该JWT的主题 + // nbf: (Not Before)不要早于这个时间 + // jti: (JWT ID)用于标识JWT的唯一ID + claims := claims{ + userId, + userName, + jwt.StandardClaims{ + NotBefore: time.Now().Unix(), + IssuedAt: time.Now().Unix(), + ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), + Issuer: "go-gin-api", + }, + } + tokenString, err = jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(secret)) + return +} + +func Parse(tokenString string) (*claims, error) { + tokenClaims, err := jwt.ParseWithClaims(tokenString, &claims{}, func(token *jwt.Token) (interface{}, error) { + return []byte(secret), nil + }) + + if tokenClaims != nil { + if claims, ok := tokenClaims.Claims.(*claims); ok && tokenClaims.Valid { + return claims, nil + } + } + + return nil, err +} diff --git a/internal/pkg/token/token_test.go b/internal/pkg/token/token_test.go new file mode 100644 index 0000000..63f9694 --- /dev/null +++ b/internal/pkg/token/token_test.go @@ -0,0 +1,26 @@ +package token + +import ( + "testing" +) + +// 执行 Test 时,先将 token.secret 设置值 + +func TestSign(t *testing.T) { + tokenString, err := Sign(123456789, "xinliangnote") + if err != nil { + t.Error("sign error", err) + return + } + t.Log(tokenString) +} + +func TestParse(t *testing.T) { + tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMzQ1Njc4OSwidXNlcm5hbWUiOiJ4aW5saWFuZyIsImV4cCI6MTYwOTQ2NzcwNCwiaWF0IjoxNjA5MzgxMzA0LCJpc3MiOiJnby1naW4tYXBpIiwibmJmIjoxNjA5MzgxMzA0fQ.hccv8F713WpKcwiSldBrFLZz_2SZzOTPedPi-8ps7M4" + user, err := Parse(tokenString) + if err != nil { + t.Error("parse error", err) + return + } + t.Log(user) +} diff --git a/internal/router/middleware/auth.go b/internal/router/middleware/auth.go new file mode 100644 index 0000000..62e0c28 --- /dev/null +++ b/internal/router/middleware/auth.go @@ -0,0 +1,29 @@ +package middleware + +import ( + "github.com/xinliangnote/go-gin-api/internal/pkg/core" + "github.com/xinliangnote/go-gin-api/internal/pkg/errno" + "github.com/xinliangnote/go-gin-api/internal/pkg/token" +) + +func AuthHandler(ctx core.Context) (userId int, userName string, err errno.Error) { + auth := ctx.GetHeader("Authorization") + if auth == "" { + err = errno.ErrSignParam + return + } + + claims, errParse := token.Parse(auth) + if errParse != nil { + err = errno.ErrSignParam + return + } + + userId = claims.UserID + if userId <= 0 { + err = errno.ErrSignParam + return + } + userName = claims.UserName + return +} diff --git a/internal/api/router/router.go b/internal/router/router.go similarity index 62% rename from internal/api/router/router.go rename to internal/router/router.go index 31d5e5f..851d0e3 100644 --- a/internal/api/router/router.go +++ b/internal/router/router.go @@ -3,7 +3,9 @@ package router import ( "github.com/xinliangnote/go-gin-api/internal/api/controller/demo" "github.com/xinliangnote/go-gin-api/internal/pkg/core" + "github.com/xinliangnote/go-gin-api/internal/pkg/metrics" "github.com/xinliangnote/go-gin-api/internal/pkg/notify" + "github.com/xinliangnote/go-gin-api/internal/router/middleware" "github.com/pkg/errors" "go.uber.org/zap" @@ -18,24 +20,27 @@ func NewHTTPMux(logger *zap.Logger) (core.Mux, error) { mux, err := core.New(logger, core.WithEnableCors(), core.WithEnableRate(), - core.WithPanicNotify(notify.Email), + core.WithPanicNotify(notify.OnPanicNotify), + core.WithRecordMetrics(metrics.RecordMetrics), ) if err != nil { panic(err) } - //设置路由中间件 - //engine.Use(exception.SetUp(), jaeger.SetUp()) - demoHandler := demo.NewDemo(logger) - d := mux.Group("/demo") + u := mux.Group("/user") { - d.GET("user/:name", demoHandler.User()) + u.POST("/login", demoHandler.Login()) + } + + d := mux.Group("/demo", core.WrapAuthHandler(middleware.AuthHandler)) //使用 auth 验证 + { + d.GET("user/:name", demoHandler.User(), core.DisableJournal) // 模拟数据 - d.GET("get/:name", demoHandler.Get(), core.DisableJournal) + d.GET("get/:name", demoHandler.Get()) d.POST("post", demoHandler.Post(), core.DisableJournal) // 测试加密性能 @@ -44,8 +49,5 @@ func NewHTTPMux(logger *zap.Logger) (core.Mux, error) { d.GET("/md5/test", demoHandler.MD5Test()) } - // 测试链路追踪 - //mux.GET("/jaeger_test", jaeger_conn.JaegerTest) - return mux, nil } diff --git a/logs/go-gin-api-error.log b/logs/go-gin-api-error.log deleted file mode 100644 index e69de29..0000000 diff --git a/logs/go-gin-api-grpc.log b/logs/go-gin-api-grpc.log deleted file mode 100644 index e69de29..0000000 diff --git a/main.go b/main.go index a0c1eff..014f7db 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,8 @@ import ( "net/http" "time" - "github.com/xinliangnote/go-gin-api/internal/api/router" "github.com/xinliangnote/go-gin-api/internal/pkg/configs" + "github.com/xinliangnote/go-gin-api/internal/router" "github.com/xinliangnote/go-gin-api/pkg/logger" "github.com/xinliangnote/go-gin-api/pkg/shutdown" @@ -22,7 +22,7 @@ import ( // @contact.url // @contact.email -// @host localhost:9999 +// @host 127.0.0.1:9999 // @BasePath func main() { loggers, err := logger.NewJSONLogger( @@ -33,6 +33,7 @@ func main() { if err != nil { panic(err) } + defer loggers.Sync() mux, err := router.NewHTTPMux(loggers) if err != nil { diff --git a/pkg/aes/aes_test.go b/pkg/aes/aes_test.go new file mode 100644 index 0000000..65d1aff --- /dev/null +++ b/pkg/aes/aes_test.go @@ -0,0 +1,16 @@ +package aes + +import "testing" + +const ( + Key = "IgkibX71IEf382PT" + Iv = "IgkibX71IEf382PT" +) + +func TestEncrypt(t *testing.T) { + t.Log(New(Key, Iv).Encrypt("123456")) +} + +func TestDecrypt(t *testing.T) { + t.Log(New(Key, Iv).Decrypt("GO-ri84zevE-z1biJwfQPw==")) +} diff --git a/pkg/env/env_test.go b/pkg/env/env_test.go new file mode 100644 index 0000000..b7b48bc --- /dev/null +++ b/pkg/env/env_test.go @@ -0,0 +1,7 @@ +package env + +import "testing" + +func TestActive(t *testing.T) { + t.Log(Active().Value()) +} diff --git a/pkg/md5/md5_test.go b/pkg/md5/md5_test.go new file mode 100644 index 0000000..da687d2 --- /dev/null +++ b/pkg/md5/md5_test.go @@ -0,0 +1,7 @@ +package md5 + +import "testing" + +func TestEncrypt(t *testing.T) { + t.Log(New().Encrypt("123456")) +} diff --git a/pkg/rsa/rsa_test.go b/pkg/rsa/rsa_test.go new file mode 100644 index 0000000..45acb40 --- /dev/null +++ b/pkg/rsa/rsa_test.go @@ -0,0 +1,64 @@ +package rsa + +import ( + "testing" +) + +func TestEncrypt(t *testing.T) { + publicKey := `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1O3p0JN0/RrP7eY3f81i +zPf16FS0WMNGCJkd+y5c6yBzUvN0IEeoxiIWIBhoMKH0pzlzBg0rfttojSodOgNo +m/UCAzAYEgdIsNee5LSN/7e0T2/QvsIAHINuA8gI8fGoGiSA2TEzpUo6aVXwhZT3 +4GGRdrSJ+m4iVk/Kt95tavBNk+NDVSeb5xAjxBchT5BjAMMlE0ffGZb0MMjjO5+e +9Tn8f99M2VMqpzXHXZzv1ABmqufzS20iWcSvnjhWcJ9hiKwO8Z30GgJyACmml+HM +xLYEFN9h2MWYgxLm9Z0rLMrWwMM+E2rCs8tsxAD5sO9RZMJPl1C0FIsMR53ngqbz +owIDAQAB +-----END PUBLIC KEY-----` + + rsaPublic := NewPublic(publicKey) + str, err := rsaPublic.Encrypt("123456") + if err != nil { + t.Error("rsa public encrypt error", err) + return + } + t.Log(str) +} + +func TestDecrypt(t *testing.T) { + privateKey := `-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA1O3p0JN0/RrP7eY3f81izPf16FS0WMNGCJkd+y5c6yBzUvN0 +IEeoxiIWIBhoMKH0pzlzBg0rfttojSodOgNom/UCAzAYEgdIsNee5LSN/7e0T2/Q +vsIAHINuA8gI8fGoGiSA2TEzpUo6aVXwhZT34GGRdrSJ+m4iVk/Kt95tavBNk+ND +VSeb5xAjxBchT5BjAMMlE0ffGZb0MMjjO5+e9Tn8f99M2VMqpzXHXZzv1ABmqufz +S20iWcSvnjhWcJ9hiKwO8Z30GgJyACmml+HMxLYEFN9h2MWYgxLm9Z0rLMrWwMM+ +E2rCs8tsxAD5sO9RZMJPl1C0FIsMR53ngqbzowIDAQABAoIBAQCO1RE1ItUlO6kj +Un0ENAgEqojAUqGvsT33Yo7kAZO+/cOeb0UEqk0iq5bf7L9ncBynWDg6ZPc6X3/g +wdFdKxAvHck9zjM3VL+EMP+bNyrR0K8ZYk5Kx+Q/PEK+Mp8dfRdgggAUsZaNWB+a +rVVspiMo1wo28KBl5x8NevTnJkOLqXAyB7UyLWqnOL1fb988lZvZPR7ZUYroVIZa +pyXtZcafIJeKyQ3bvWI5+eFqOe61Z4Bx1+TpfZ3fKfSDW0vhxzNqaimOa8jSXtMJ +jMeOctL4nZ0TPo/jS3I+XlaH4ZQlFLuUWGscpxwfEeBN23I8HRLkZXJsw66yvRN3 +s4bUKPXRAoGBAP/3oSZAECvfsYYzs76tnrAmR/0GxCqgguxDlWn5DowQzdWFOdHC +ZbTo/hUVoMSQnO1EKCFlnBS+wg/3TuIzUO0ewC1aeT7qHbOMDl0zKbNpS2Z9/j+U +zro+qz7XmkWolMCfmDrCrw9CtCxcMSII+ajbI8SAgFVMz9XnDt+xW9E9AoGBANT0 +4F6kCUJTEyqf2+v84tjQ2wGIF6XtZPU9JR806zeMyahQ9F6z3hY8BYb0tIy5b3uJ +VlJ9TG1qg/t59TWxIq43mYSUJHe0aJi3ilooObQtHlhPu8nwmmX47sX0PyG2hMoD +kBVxTpTDmBaDz7O9uBnlMXJN5qEygctaixpEbmZfAoGBAMBA9kEMjRjnAyeRXcgy +D6aumhNqKZz6wltCx864yjxZwsBFOJBcOpgPCAg+HmqFU9jCAIJVF05dmNT1I8Ky +WG5BUoa+FaMzpOtenstRylh/Far9pyGKW1t4BpdEyRLY9CFZvbUk1OfZagqHlD/E +DgDN16eX/MwUzWYUDg/l3tjhAoGBAKGip/ZNjVWRFpggs9z/mfK1O7WC5Wgksp9N +ZLK2CN6l9p3RrFmBLk00C4HulGfHi+15RVLhFbRqx3iFje/N3iPbwaMWikNtZIKd +tN5Pb9To9gJTqpZRD+/cLOeFRrHBBjMK1z7fPKS/fN2B+JFVq7nD827t3+J0In4F +4FT0odMDAoGBAJk3ELB/FHY8xzZ4jF1wG/a1CK681Xm6SuU5KIELDSAUNoou6OPG +mS8gU20MMPAeV2z7khyDcSxlHsUyL73eLeaakbQov9NMW7cc99XX4wnP4W7FRpmr +QbHmKuHIRFHCFv+XX8c0aK2mDZMUlzJdy4FgD/YCEZ7kZMZKyvZW/ZuV +-----END RSA PRIVATE KEY-----` + decryptStr := "KTKXckjkCLI6Vk_y_XROnY-a6nJpllruL-CX-v_2AFxfghA2tZ2nkQyS6d1-IIYMlgwm4ivwlzy-phLtaN9BB03htA5D9rwjA_JwYtqAG4iwuvgaDl2SiZ_H2ACv-aV1kNRgnyjh14hs0JiSt5VHEiJ3D2xYzOCKwtEzoo0WczJ-MYb3u_-bfcnm9YtvgtG5-y3Jy7WYr-IwXdBKqPO0E-jzrtY7m3Q1yC4znHdzjNpxCj0I6YRx4CZ362b706qNX7sl3E5KTJeSmYrsurB-SxQT1CaqGzVt7mshx1v2qGnv5NBNXpj7ZPKWGJbgaCUxcuxd1Mg0o81HnfbsGuSlFQ==" + + rsaPrivate := NewPrivate(privateKey) + str, err := rsaPrivate.Decrypt(decryptStr) + if err != nil { + t.Error("rsa private decrypt error", err) + return + } + t.Log(str) +} diff --git a/pkg/utils/sql/sql.go b/pkg/utils/sql/sql.go new file mode 100644 index 0000000..99b64a4 --- /dev/null +++ b/pkg/utils/sql/sql.go @@ -0,0 +1,14 @@ +package sql + +import "strings" + +// EscapeString 转义 SQL 语句中使用的字符串中的特殊字符 +func EscapeString(value string) string { + replace := map[string]string{"\\": "\\\\", "'": `\'`, "\\0": "\\\\0", "\n": "\\n", "\r": "\\r", `"`: `\"`, "\x1a": "\\Z"} + + for b, a := range replace { + value = strings.Replace(value, b, a, -1) + } + + return value +} diff --git a/pkg/utils/sql/sql_test.go b/pkg/utils/sql/sql_test.go new file mode 100644 index 0000000..f43f0e3 --- /dev/null +++ b/pkg/utils/sql/sql_test.go @@ -0,0 +1,8 @@ +package sql + +import "testing" + +func TestEscapeString(t *testing.T) { + str := "' OR ''=' union select 1,database(),2#" + t.Log(EscapeString(str)) +}