Compare commits

..

No commits in common. 'main' and 'consul/multiple-data-centers' have entirely different histories.

  1. 8
      .github/pull_request_template.md
  2. 12
      .github/stable.yml
  3. 21
      .github/workflows/go.yml
  4. 16
      .github/workflows/issue-translator.yml
  5. 2
      .golangci.yml
  6. 24
      Makefile
  7. 2
      README.md
  8. 2
      SECURITY.md
  9. 4
      api/metadata/server.go
  10. 4
      app_test.go
  11. 10
      cmd/kratos/go.mod
  12. 38
      cmd/kratos/go.sum
  13. 6
      cmd/kratos/internal/base/mod_test.go
  14. 23
      cmd/kratos/internal/base/path.go
  15. 7
      cmd/kratos/internal/base/repo.go
  16. 2
      cmd/kratos/internal/change/change.go
  17. 10
      cmd/kratos/internal/project/add.go
  18. 16
      cmd/kratos/internal/project/new.go
  19. 70
      cmd/kratos/internal/project/project.go
  20. 29
      cmd/kratos/internal/project/project_linux_test.go
  21. 144
      cmd/kratos/internal/project/project_test.go
  22. 30
      cmd/kratos/internal/project/project_windows_test.go
  23. 7
      cmd/kratos/internal/proto/add/add.go
  24. 6
      cmd/kratos/internal/proto/add/proto.go
  25. 6
      cmd/kratos/internal/proto/client/client.go
  26. 4
      cmd/kratos/internal/proto/proto.go
  27. 18
      cmd/kratos/internal/proto/server/server.go
  28. 40
      cmd/kratos/internal/proto/server/server_test.go
  29. 18
      cmd/kratos/internal/run/run.go
  30. 6
      cmd/kratos/internal/upgrade/upgrade.go
  31. 4
      cmd/kratos/main.go
  32. 2
      cmd/kratos/version.go
  33. 2
      cmd/protoc-gen-go-errors/errors.go
  34. 17
      cmd/protoc-gen-go-errors/errorsTemplate.tpl
  35. 2
      cmd/protoc-gen-go-errors/go.mod
  36. 24
      cmd/protoc-gen-go-errors/go.sum
  37. 22
      cmd/protoc-gen-go-errors/template.go
  38. 2
      cmd/protoc-gen-go-errors/version.go
  39. 29
      cmd/protoc-gen-go-http/http.go
  40. 93
      cmd/protoc-gen-go-http/httpTemplate.tpl
  41. 3
      cmd/protoc-gen-go-http/main.go
  42. 96
      cmd/protoc-gen-go-http/template.go
  43. 2
      cmd/protoc-gen-go-http/version.go
  44. 2
      config/options.go
  45. 43
      contrib/config/apollo/apollo.go
  46. 90
      contrib/config/apollo/apollo_test.go
  47. 9
      contrib/config/apollo/go.mod
  48. 992
      contrib/config/apollo/go.sum
  49. 4
      contrib/config/apollo/watcher.go
  50. 9
      contrib/config/consul/go.mod
  51. 1473
      contrib/config/consul/go.sum
  52. 2
      contrib/config/consul/watcher.go
  53. 6
      contrib/config/etcd/go.mod
  54. 1459
      contrib/config/etcd/go.sum
  55. 8
      contrib/config/kubernetes/go.mod
  56. 1229
      contrib/config/kubernetes/go.sum
  57. 6
      contrib/config/nacos/go.mod
  58. 1462
      contrib/config/nacos/go.sum
  59. 170
      contrib/config/polaris/config_test.go
  60. 6
      contrib/config/polaris/go.mod
  61. 1191
      contrib/config/polaris/go.sum
  62. 2
      contrib/encoding/msgpack/go.mod
  63. 1460
      contrib/encoding/msgpack/go.sum
  64. 2
      contrib/log/aliyun/aliyun_test.go
  65. 6
      contrib/log/aliyun/go.mod
  66. 1432
      contrib/log/aliyun/go.sum
  67. 3
      contrib/log/fluent/go.mod
  68. 1442
      contrib/log/fluent/go.sum
  69. 2
      contrib/log/logrus/go.mod
  70. 1459
      contrib/log/logrus/go.sum
  71. 4
      contrib/log/tencent/go.mod
  72. 1462
      contrib/log/tencent/go.sum
  73. 1
      contrib/log/tencent/tencent.go
  74. 2
      contrib/log/zap/go.mod
  75. 1440
      contrib/log/zap/go.sum
  76. 7
      contrib/log/zap/zap.go
  77. 4
      contrib/metrics/datadog/gauge.go
  78. 6
      contrib/metrics/datadog/go.mod
  79. 1461
      contrib/metrics/datadog/go.sum
  80. 6
      contrib/metrics/prometheus/go.mod
  81. 1198
      contrib/metrics/prometheus/go.sum
  82. 23
      contrib/opensergo/go.mod
  83. 1477
      contrib/opensergo/go.sum
  84. 4
      contrib/opensergo/opensergo.go
  85. 2
      contrib/opensergo/opensergo_test.go
  86. 119
      contrib/polaris/config.go
  87. 45
      contrib/polaris/go.mod
  88. 593
      contrib/polaris/go.sum
  89. 105
      contrib/polaris/limiter.go
  90. 101
      contrib/polaris/polaris.go
  91. 53
      contrib/polaris/ratelimit.go
  92. 380
      contrib/polaris/registry.go
  93. 58
      contrib/polaris/registry_test.go
  94. 144
      contrib/polaris/router.go
  95. 206
      contrib/polaris/router_test.go
  96. 102
      contrib/registry/consul/client.go
  97. 9
      contrib/registry/consul/go.mod
  98. 1461
      contrib/registry/consul/go.sum
  99. 55
      contrib/registry/consul/registry.go
  100. 66
      contrib/registry/consul/registry_test.go
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,20 +3,22 @@
1. If this is your first time contributing to Kratos, please read our contribution guide: https://go-kratos.dev/en/docs/community/contribution/ 1. If this is your first time contributing to Kratos, please read our contribution guide: https://go-kratos.dev/en/docs/community/contribution/
2. Ensure you have added or ran the appropriate tests and lint for your PR, please use `make lint` and `make test` before filing your PR, use `make clean` to tidy your go mod. 2. Ensure you have added or ran the appropriate tests and lint for your PR, please use `make lint` and `make test` before filing your PR, use `make clean` to tidy your go mod.
3. If the PR is unfinished, you may need to mark it as a WIP(Work In Progress) PR or Draft PR 3. If the PR is unfinished, you may need to mark it as a WIP(Work In Progress) PR or draft PR
4. Please use a semantic commits format title, such as `<type>[optional scope]: <description>`, see: https://go-kratos.dev/docs/community/contribution#type 4. Please use a semantic commits format title, such as `<type>[optional scope]: <description>`, see: https://go-kratos.dev/docs/community/contribution#type
5. at the same time, please note that similar work should be submitted in one PR as far as possible to reduce the workload of reviewers. Do not split a work into multiple PR unless it should. 5. at the same time, please note that similar work should be submitted in one PR as far as possible to reduce the workload of reviewers. Do not split a work into multiple PR unless it should.
--> -->
<!-- <!--
🎉 感谢您向 Kratos 发送 PR!以下是一些提示: 🎉 感谢您向 Kratos 发送 PR 请求!以下是一些提示:
如果这是你第一次为 Kratos 贡献,请阅读我们的贡献指南:https://go-kratos.dev/en/docs/community/contribution/ 如果这是你第一次为 Kratos 贡献,请阅读我们的贡献指南:https://go-kratos.dev/en/docs/community/contribution/
2、确保您已经为您的 PR 添加或运行了适当的测试和lint,请在提交PR之前使用“make lint”和“make test”,使用“make clean”整理您的 go.mod。 2、确保您已经为您的 PR 添加或运行了适当的测试和lint,请在提交PR之前使用“make lint”和“make test”,使用“make clean”整理您的 go.mod。
3、如果 PR 未完成,您可能需要将其标记为 WIP(Work In Progress)PR 或 Draft PR 3、如果请购单未完成,您可能需要将其标记为 WIP(在制品)PR 或 draft PR
4、请使用语义提交格式标题,如“<类型>[可选范围]:<说明>`,请参阅:https://go-kratos.dev/docs/community/contribution#type 4、请使用语义提交格式标题,如“<类型>[可选范围]:<说明>`,请参阅:https://go-kratos.dev/docs/community/contribution#type
5. 同时请注意,同类的工作请尽量在一个PR中提交,以减轻 review 者的工作负担,不要把一项工作拆分成很多个PR,除非它应该这样做。 5. 同时请注意,同类的工作请尽量在一个PR中提交,以减轻 review 者的工作负担,不要把一项工作拆分成很多个PR,除非它应该这样做。
--> -->
<!--
-->
#### Description (what this PR does / why we need it): #### Description (what this PR does / why we need it):
<!-- <!--

@ -1,12 +0,0 @@
daysUntilStale: 30
daysUntilClose: 3
exemptLabels:
- pinned
- security
- bug
staleLabel: wontfix
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
closeComment: true

@ -13,7 +13,7 @@ jobs:
build: build:
strategy: strategy:
matrix: matrix:
go: [1.19,1.20.x] go: [1.16, 1.17, 1.18, 1.19]
name: build & test name: build & test
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
@ -36,7 +36,7 @@ jobs:
- "8848:8848" - "8848:8848"
- "9848:9848" - "9848:9848"
polaris: polaris:
image: polarismesh/polaris-standalone:latest image: polarismesh/polaris-server-standalone:v1.9.0
ports: ports:
- 8090:8090 - 8090:8090
- 8091:8091 - 8091:8091
@ -44,25 +44,10 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v4.0.1 uses: actions/setup-go@v3.3.1
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
- name: Setup Environment
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
- name: Module cache
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go
- name: Build - name: Build
run: go build ./... run: go build ./...

@ -1,16 +0,0 @@
name: 'issue-translator'
on:
issue_comment:
types: [created]
issues:
types: [opened]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: usthe/issues-translate-action@v2.7
with:
IS_MODIFY_TITLE: true
CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}

@ -68,4 +68,4 @@ linters-settings:
# recommend 10-20 # recommend 10-20
min-complexity: 50 min-complexity: 50
goimports: goimports:
local-prefixes: github.com/go-kratos # Put imports beginning with prefix after 3rd-party packages local-prefixes: github.com/go-kratos/kratos # Put imports beginning with prefix after 3rd-party packages

@ -1,27 +1,9 @@
user := $(shell whoami) user := $(shell whoami)
rev := $(shell git rev-parse --short HEAD) rev := $(shell git rev-parse --short HEAD)
os := $(shell expr substr $(shell uname -s) 1 5)
# GOBIN > GOPATH > INSTALLDIR # GOBIN > GOPATH > INSTALLDIR
# Mac OS X
ifeq ($(shell uname),Darwin)
GOBIN := $(shell echo ${GOBIN} | cut -d':' -f1) GOBIN := $(shell echo ${GOBIN} | cut -d':' -f1)
GOPATH := $(shell echo $(GOPATH) | cut -d':' -f1) GOPATH := $(shell echo $(GOPATH) | cut -d':' -f1)
endif
# Linux
ifeq ($(os),Linux)
GOBIN := $(shell echo ${GOBIN} | cut -d':' -f1)
GOPATH := $(shell echo $(GOPATH) | cut -d':' -f1)
endif
# Windows
ifeq ($(os),MINGW)
GOBIN := $(subst \,/,$(GOBIN))
GOPATH := $(subst \,/,$(GOPATH))
GOBIN :=/$(shell echo "$(GOBIN)" | cut -d';' -f1 | sed 's/://g')
GOPATH :=/$(shell echo "$(GOPATH)" | cut -d';' -f1 | sed 's/://g')
endif
BIN := "" BIN := ""
TOOLS_SHELL="./hack/tools.sh" TOOLS_SHELL="./hack/tools.sh"
@ -55,9 +37,9 @@ ifeq ($(user),root)
@cp ./cmd/protoc-gen-go-http/protoc-gen-go-http /usr/bin @cp ./cmd/protoc-gen-go-http/protoc-gen-go-http /usr/bin
else else
#!root, install for current user #!root, install for current user
$(shell if [ -z '$(BIN)' ]; then read -p "Please select installdir: " REPLY; mkdir -p $${REPLY};\ $(shell if [ -z $(BIN) ]; then read -p "Please select installdir: " REPLY; mkdir -p $${REPLY};\
cp ./cmd/kratos/kratos $${REPLY}/;cp ./cmd/protoc-gen-go-errors/protoc-gen-go-errors $${REPLY}/;cp ./cmd/protoc-gen-go-http/protoc-gen-go-http $${REPLY}/;else mkdir -p '$(BIN)';\ cp ./cmd/kratos/kratos $${REPLY}/;cp ./cmd/protoc-gen-go-errors/protoc-gen-go-errors $${REPLY}/;cp ./cmd/protoc-gen-go-http/protoc-gen-go-http $${REPLY}/;else mkdir -p $(BIN);\
cp ./cmd/kratos/kratos '$(BIN)';cp ./cmd/protoc-gen-go-errors/protoc-gen-go-errors '$(BIN)';cp ./cmd/protoc-gen-go-http/protoc-gen-go-http '$(BIN)'; fi) cp ./cmd/kratos/kratos $(BIN);cp ./cmd/protoc-gen-go-errors/protoc-gen-go-errors $(BIN);cp ./cmd/protoc-gen-go-http/protoc-gen-go-http $(BIN); fi)
endif endif
@which protoc-gen-go &> /dev/null || go get google.golang.org/protobuf/cmd/protoc-gen-go @which protoc-gen-go &> /dev/null || go get google.golang.org/protobuf/cmd/protoc-gen-go
@which protoc-gen-go-grpc &> /dev/null || go get google.golang.org/grpc/cmd/protoc-gen-go-grpc @which protoc-gen-go-grpc &> /dev/null || go get google.golang.org/grpc/cmd/protoc-gen-go-grpc

@ -110,5 +110,5 @@ The following project had particular influence on kratos's design.
- [go-kit/kit](https://github.com/go-kit/kit) is a programming toolkit for building microservices in go. - [go-kit/kit](https://github.com/go-kit/kit) is a programming toolkit for building microservices in go.
- [asim/go-micro](https://github.com/asim/go-micro) a distributed systems development framework. - [asim/go-micro](https://github.com/asim/go-micro) a distributed systems development framework.
- [google/go-cloud](https://github.com/google/go-cloud) is go cloud development kit. - [google/go-cloud](https://github.com/google/go-cloud) is go cloud development kit.
- [zeromicro/go-zero](https://github.com/zeromicro/go-zero) is a web and rpc framework with lots of builtin engineering practices. - [tal-tech/go-zero](https://github.com/tal-tech/go-zero) is a web and rpc framework with lots of builtin engineering practices.
- [beego/beego](https://github.com/beego/beego) is a web framework including RESTful APIs, web apps and backend services. - [beego/beego](https://github.com/beego/beego) is a web framework including RESTful APIs, web apps and backend services.

@ -6,7 +6,7 @@ Use this section to tell people about which versions of your project are
currently being supported with security updates. currently being supported with security updates.
| Version | Supported | | Version | Supported |
|-------------|--------------------| | ------- | ------------------ |
| 2.0.rc1 | :white_check_mark: | | 2.0.rc1 | :white_check_mark: |
| < 2.0.beta3 | :x: | | < 2.0.beta3 | :x: |

@ -98,7 +98,7 @@ func (s *Server) load() error {
} }
// ListServices return all services // ListServices return all services
func (s *Server) ListServices(_ context.Context, _ *ListServicesRequest) (*ListServicesReply, error) { func (s *Server) ListServices(ctx context.Context, in *ListServicesRequest) (*ListServicesReply, error) {
s.lock.Lock() s.lock.Lock()
defer s.lock.Unlock() defer s.lock.Unlock()
if err := s.load(); err != nil { if err := s.load(); err != nil {
@ -122,7 +122,7 @@ func (s *Server) ListServices(_ context.Context, _ *ListServicesRequest) (*ListS
} }
// GetServiceDesc return service meta by name // GetServiceDesc return service meta by name
func (s *Server) GetServiceDesc(_ context.Context, in *GetServiceDescRequest) (*GetServiceDescReply, error) { func (s *Server) GetServiceDesc(ctx context.Context, in *GetServiceDescRequest) (*GetServiceDescReply, error) {
s.lock.Lock() s.lock.Lock()
defer s.lock.Unlock() defer s.lock.Unlock()
if err := s.load(); err != nil { if err := s.load(); err != nil {

@ -19,7 +19,7 @@ type mockRegistry struct {
service map[string]*registry.ServiceInstance service map[string]*registry.ServiceInstance
} }
func (r *mockRegistry) Register(_ context.Context, service *registry.ServiceInstance) error { func (r *mockRegistry) Register(ctx context.Context, service *registry.ServiceInstance) error {
if service == nil || service.ID == "" { if service == nil || service.ID == "" {
return errors.New("no service id") return errors.New("no service id")
} }
@ -30,7 +30,7 @@ func (r *mockRegistry) Register(_ context.Context, service *registry.ServiceInst
} }
// Deregister the registration. // Deregister the registration.
func (r *mockRegistry) Deregister(_ context.Context, service *registry.ServiceInstance) error { func (r *mockRegistry) Deregister(ctx context.Context, service *registry.ServiceInstance) error {
r.lk.Lock() r.lk.Lock()
defer r.lk.Unlock() defer r.lk.Unlock()
if r.service[service.ID] == nil { if r.service[service.ID] == nil {

@ -3,13 +3,15 @@ module github.com/go-kratos/kratos/cmd/kratos/v2
go 1.16 go 1.16
require ( require (
github.com/AlecAivazis/survey/v2 v2.3.7 github.com/AlecAivazis/survey/v2 v2.3.4
github.com/emicklei/proto v1.10.0 github.com/emicklei/proto v1.10.0
github.com/fatih/color v1.13.0 github.com/fatih/color v1.13.0
github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-colorable v0.1.12 // indirect
github.com/spf13/cobra v1.4.0 github.com/spf13/cobra v1.4.0
github.com/stretchr/testify v1.7.0 // indirect github.com/stretchr/testify v1.7.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 golang.org/x/mod v0.5.1
golang.org/x/text v0.4.0 golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect golang.org/x/text v0.3.7
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
) )

@ -1,5 +1,5 @@
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.4 h1:pchTU9rsLUSvWEl2Aq9Pv3k0IE2fkqtGxazskAMd9Ng=
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/AlecAivazis/survey/v2 v2.3.4/go.mod h1:hrV6Y/kQCLhIZXGcriDCUBtB3wnN7156gMXJ3+b23xM=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -39,41 +39,37 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -18,6 +18,8 @@ func TestModulePath(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
defer os.RemoveAll("/tmp/test_mod")
f, err := os.Create("/tmp/test_mod/go.mod") f, err := os.Create("/tmp/test_mod/go.mod")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -36,8 +38,6 @@ go 1.16`
t.Fatal(err) t.Fatal(err)
} }
if p != "github.com/go-kratos/kratos/v2" { if p != "github.com/go-kratos/kratos/v2" {
t.Fatalf("want: %s, got: %s", "github.com/go-kratos/kratos/v2", p) t.Fatalf("want: %s, got: %s", "module github.com/go-kratos/kratos/v2", p)
} }
t.Cleanup(func() { os.RemoveAll("/tmp/test_mod") })
} }

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"log" "log"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
@ -16,7 +17,7 @@ func kratosHome() string {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
home := filepath.Join(dir, ".kratos") home := path.Join(dir, ".kratos")
if _, err := os.Stat(home); os.IsNotExist(err) { if _, err := os.Stat(home); os.IsNotExist(err) {
if err := os.MkdirAll(home, 0o700); err != nil { if err := os.MkdirAll(home, 0o700); err != nil {
log.Fatal(err) log.Fatal(err)
@ -26,7 +27,7 @@ func kratosHome() string {
} }
func kratosHomeWithDir(dir string) string { func kratosHomeWithDir(dir string) string {
home := filepath.Join(kratosHome(), dir) home := path.Join(kratosHome(), dir)
if _, err := os.Stat(home); os.IsNotExist(err) { if _, err := os.Stat(home); os.IsNotExist(err) {
if err := os.MkdirAll(home, 0o700); err != nil { if err := os.MkdirAll(home, 0o700); err != nil {
log.Fatal(err) log.Fatal(err)
@ -36,6 +37,7 @@ func kratosHomeWithDir(dir string) string {
} }
func copyFile(src, dst string, replaces []string) error { func copyFile(src, dst string, replaces []string) error {
var err error
srcinfo, err := os.Stat(src) srcinfo, err := os.Stat(src)
if err != nil { if err != nil {
return err return err
@ -56,26 +58,27 @@ func copyFile(src, dst string, replaces []string) error {
} }
func copyDir(src, dst string, replaces, ignores []string) error { func copyDir(src, dst string, replaces, ignores []string) error {
srcinfo, err := os.Stat(src) var err error
if err != nil { var fds []os.DirEntry
var srcinfo os.FileInfo
if srcinfo, err = os.Stat(src); err != nil {
return err return err
} }
err = os.MkdirAll(dst, srcinfo.Mode()) if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
if err != nil {
return err return err
} }
fds, err := os.ReadDir(src) if fds, err = os.ReadDir(src); err != nil {
if err != nil {
return err return err
} }
for _, fd := range fds { for _, fd := range fds {
if hasSets(fd.Name(), ignores) { if hasSets(fd.Name(), ignores) {
continue continue
} }
srcfp := filepath.Join(src, fd.Name()) srcfp := path.Join(src, fd.Name())
dstfp := filepath.Join(dst, fd.Name()) dstfp := path.Join(dst, fd.Name())
var e error var e error
if fd.IsDir() { if fd.IsDir() {
e = copyDir(srcfp, dstfp, replaces, ignores) e = copyDir(srcfp, dstfp, replaces, ignores)

@ -7,7 +7,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"path/filepath"
"strings" "strings"
) )
@ -69,7 +68,7 @@ func (r *Repo) Pull(ctx context.Context) error {
cmd.Dir = r.Path() cmd.Dir = r.Path()
_, err := cmd.CombinedOutput() _, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return err return nil
} }
cmd = exec.CommandContext(ctx, "git", "pull") cmd = exec.CommandContext(ctx, "git", "pull")
cmd.Dir = r.Path() cmd.Dir = r.Path()
@ -105,7 +104,7 @@ func (r *Repo) CopyTo(ctx context.Context, to string, modPath string, ignores []
if err := r.Clone(ctx); err != nil { if err := r.Clone(ctx); err != nil {
return err return err
} }
mod, err := ModulePath(filepath.Join(r.Path(), "go.mod")) mod, err := ModulePath(path.Join(r.Path(), "go.mod"))
if err != nil { if err != nil {
return err return err
} }
@ -117,7 +116,7 @@ func (r *Repo) CopyToV2(ctx context.Context, to string, modPath string, ignores,
if err := r.Clone(ctx); err != nil { if err := r.Clone(ctx); err != nil {
return err return err
} }
mod, err := ModulePath(filepath.Join(r.Path(), "go.mod")) mod, err := ModulePath(path.Join(r.Path(), "go.mod"))
if err != nil { if err != nil {
return err return err
} }

@ -28,7 +28,7 @@ func init() {
token = os.Getenv("GITHUB_TOKEN") token = os.Getenv("GITHUB_TOKEN")
} }
func run(_ *cobra.Command, args []string) { func run(cmd *cobra.Command, args []string) {
owner, repo := ParseGithubURL(repoURL) owner, repo := ParseGithubURL(repoURL)
api := GithubAPI{Owner: owner, Repo: repo, Token: token} api := GithubAPI{Owner: owner, Repo: repo, Token: token}
version := "latest" version := "latest"

@ -4,7 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path/filepath" "path"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/fatih/color" "github.com/fatih/color"
@ -17,7 +17,7 @@ var repoAddIgnores = []string{
} }
func (p *Project) Add(ctx context.Context, dir string, layout string, branch string, mod string) error { func (p *Project) Add(ctx context.Context, dir string, layout string, branch string, mod string) error {
to := filepath.Join(dir, p.Name) to := path.Join(dir, p.Path)
if _, err := os.Stat(to); !os.IsNotExist(err) { if _, err := os.Stat(to); !os.IsNotExist(err) {
fmt.Printf("🚫 %s already exists\n", p.Name) fmt.Printf("🚫 %s already exists\n", p.Name)
@ -40,13 +40,13 @@ func (p *Project) Add(ctx context.Context, dir string, layout string, branch str
repo := base.NewRepo(layout, branch) repo := base.NewRepo(layout, branch)
if err := repo.CopyToV2(ctx, to, filepath.Join(mod, p.Path), repoAddIgnores, []string{filepath.Join(p.Path, "api"), "api"}); err != nil { if err := repo.CopyToV2(ctx, to, path.Join(mod, p.Path), repoAddIgnores, []string{path.Join(p.Path, "api"), "api"}); err != nil {
return err return err
} }
e := os.Rename( e := os.Rename(
filepath.Join(to, "cmd", "server"), path.Join(to, "cmd", "server"),
filepath.Join(to, "cmd", p.Name), path.Join(to, "cmd", p.Name),
) )
if e != nil { if e != nil {
return e return e

@ -4,12 +4,12 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path/filepath" "path"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
) )
// Project is a project template. // Project is a project template.
@ -20,14 +20,14 @@ type Project struct {
// New new a project from remote repo. // New new a project from remote repo.
func (p *Project) New(ctx context.Context, dir string, layout string, branch string) error { func (p *Project) New(ctx context.Context, dir string, layout string, branch string) error {
to := filepath.Join(dir, p.Name) to := path.Join(dir, p.Name)
if _, err := os.Stat(to); !os.IsNotExist(err) { if _, err := os.Stat(to); !os.IsNotExist(err) {
fmt.Printf("🚫 %s already exists\n", p.Name) fmt.Printf("🚫 %s already exists\n", p.Name)
override := false
prompt := &survey.Confirm{ prompt := &survey.Confirm{
Message: "📂 Do you want to override the folder ?", Message: "📂 Do you want to override the folder ?",
Help: "Delete the existing folder and create the project.", Help: "Delete the existing folder and create the project.",
} }
var override bool
e := survey.AskOne(prompt, &override) e := survey.AskOne(prompt, &override)
if e != nil { if e != nil {
return e return e
@ -39,12 +39,12 @@ func (p *Project) New(ctx context.Context, dir string, layout string, branch str
} }
fmt.Printf("🚀 Creating service %s, layout repo is %s, please wait a moment.\n\n", p.Name, layout) fmt.Printf("🚀 Creating service %s, layout repo is %s, please wait a moment.\n\n", p.Name, layout)
repo := base.NewRepo(layout, branch) repo := base.NewRepo(layout, branch)
if err := repo.CopyTo(ctx, to, p.Name, []string{".git", ".github"}); err != nil { if err := repo.CopyTo(ctx, to, p.Path, []string{".git", ".github"}); err != nil {
return err return err
} }
e := os.Rename( e := os.Rename(
filepath.Join(to, "cmd", "server"), path.Join(to, "cmd", "server"),
filepath.Join(to, "cmd", p.Name), path.Join(to, "cmd", p.Name),
) )
if e != nil { if e != nil {
return e return e

@ -5,8 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path/filepath" "path"
"strings"
"time" "time"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
@ -41,7 +40,7 @@ func init() {
CmdNew.Flags().BoolVarP(&nomod, "nomod", "", nomod, "retain go mod") CmdNew.Flags().BoolVarP(&nomod, "nomod", "", nomod, "retain go mod")
} }
func run(_ *cobra.Command, args []string) { func run(cmd *cobra.Command, args []string) {
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {
panic(err) panic(err)
@ -65,34 +64,23 @@ func run(_ *cobra.Command, args []string) {
} else { } else {
name = args[0] name = args[0]
} }
projectName, workingDir := processProjectParams(name, wd) p := &Project{Name: path.Base(name), Path: name}
p := &Project{Name: projectName}
done := make(chan error, 1) done := make(chan error, 1)
go func() { go func() {
if !nomod { if !nomod {
done <- p.New(ctx, workingDir, repoURL, branch) done <- p.New(ctx, wd, repoURL, branch)
return return
} }
projectRoot := getgomodProjectRoot(workingDir) if _, e := os.Stat(path.Join(wd, "go.mod")); os.IsNotExist(e) {
if gomodIsNotExistIn(projectRoot) { done <- fmt.Errorf("🚫 go.mod don't exists in %s", wd)
done <- fmt.Errorf("🚫 go.mod don't exists in %s", projectRoot)
return return
} }
p.Path, err = filepath.Rel(projectRoot, filepath.Join(workingDir, projectName)) mod, e := base.ModulePath(path.Join(wd, "go.mod"))
if err != nil {
done <- fmt.Errorf("🚫 failed to get relative path: %v", err)
return
}
mod, e := base.ModulePath(filepath.Join(projectRoot, "go.mod"))
if e != nil { if e != nil {
done <- fmt.Errorf("🚫 failed to parse `go.mod`: %v", e) panic(e)
return
} }
// Get the relative path for adding a project based on Go modules done <- p.Add(ctx, wd, repoURL, branch, mod)
p.Path = filepath.Join(strings.TrimPrefix(workingDir, projectRoot+"/"), p.Name)
done <- p.Add(ctx, workingDir, repoURL, branch, mod)
}() }()
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -107,43 +95,3 @@ func run(_ *cobra.Command, args []string) {
} }
} }
} }
func processProjectParams(projectName string, workingDir string) (projectNameResult, workingDirResult string) {
_projectDir := projectName
_workingDir := workingDir
// Process ProjectName with system variable
if strings.HasPrefix(projectName, "~") {
homeDir, err := os.UserHomeDir()
if err != nil {
// cannot get user home return fallback place dir
return _projectDir, _workingDir
}
_projectDir = filepath.Join(homeDir, projectName[2:])
}
// check path is relative
if !filepath.IsAbs(projectName) {
absPath, err := filepath.Abs(projectName)
if err != nil {
return _projectDir, _workingDir
}
_projectDir = absPath
}
return filepath.Base(_projectDir), filepath.Dir(_projectDir)
}
func getgomodProjectRoot(dir string) string {
if dir == filepath.Dir(dir) {
return dir
}
if gomodIsNotExistIn(dir) {
return getgomodProjectRoot(filepath.Dir(dir))
}
return dir
}
func gomodIsNotExistIn(dir string) bool {
_, e := os.Stat(filepath.Join(dir, "go.mod"))
return os.IsNotExist(e)
}

@ -1,29 +0,0 @@
//go:build linux
// +build linux
package project
import (
"testing"
)
func Test_processProjectParams(t *testing.T) {
type args struct {
projectName string
fallbackPlaceDir string
}
tests := []struct {
name string
args args
want string
}{
{"absLinux", args{projectName: "/home/kratos/awesome/go/demo", fallbackPlaceDir: ""}, "/home/kratos/awesome/go"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if _, got := processProjectParams(tt.args.projectName, tt.args.fallbackPlaceDir); got != tt.want {
t.Errorf("processProjectParams() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,144 +0,0 @@
package project
import (
"fmt"
"go/parser"
"go/token"
"os"
"path/filepath"
"testing"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
)
// TestCmdNew tests the `kratos new` command.
func TestCmdNew(t *testing.T) {
cwd := changeCurrentDir(t)
projectName := "helloworld"
// create a new project
CmdNew.SetArgs([]string{projectName})
if err := CmdNew.Execute(); err != nil {
t.Fatalf("executing command: %v", err)
}
// check that the expected files were created
for _, file := range []string{
"go.mod",
"go.sum",
"README.md",
"cmd/helloworld/main.go",
} {
if _, err := os.Stat(filepath.Join(cwd, projectName, file)); err != nil {
t.Errorf("expected file %s to exist", file)
}
}
// check that the go.mod file contains the expected module name
assertGoMod(t, filepath.Join(cwd, projectName, "go.mod"), projectName)
assertImportsInclude(t, filepath.Join(cwd, projectName, "cmd", projectName, "wire.go"), fmt.Sprintf(`"%s/internal/biz"`, projectName))
}
// TestCmdNewNoMod tests the `kratos new` command with the --nomod flag.
func TestCmdNewNoMod(t *testing.T) {
cwd := changeCurrentDir(t)
// create a new project
CmdNew.SetArgs([]string{"project"})
if err := CmdNew.Execute(); err != nil {
t.Fatalf("executing command: %v", err)
}
// add new app with --nomod flag
CmdNew.SetArgs([]string{"--nomod", "project/app/user"})
if err := CmdNew.Execute(); err != nil {
t.Fatalf("executing command: %v", err)
}
// check that the expected files were created
for _, file := range []string{
"go.mod",
"go.sum",
"README.md",
"cmd/project/main.go",
"app/user/cmd/user/main.go",
} {
if _, err := os.Stat(filepath.Join(cwd, "project", file)); err != nil {
t.Errorf("expected file %s to exist", file)
}
}
assertImportsInclude(t, filepath.Join(cwd, "project/app/user/cmd/user/wire.go"), `"project/app/user/internal/biz"`)
}
// assertImportsInclude checks that the file at path contains the expected import.
func assertImportsInclude(t *testing.T, path, expected string) {
t.Helper()
got, err := imports(path)
if err != nil {
t.Fatalf("getting imports: %v", err)
}
for _, imp := range got {
if imp == expected {
return
}
}
t.Errorf("expected imports to include %s, got %v", expected, got)
}
// imports returns the imports in the file at path.
func imports(path string) ([]string, error) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly)
if err != nil {
return nil, err
}
imports := make([]string, 0, len(f.Imports))
for _, s := range f.Imports {
imports = append(imports, s.Path.Value)
}
return imports, nil
}
// assertGoMod checks that the go.mod file contains the expected module name.
func assertGoMod(t *testing.T, path, expected string) {
t.Helper()
got, err := base.ModulePath(path)
if err != nil {
t.Fatalf("getting module path: %v", err)
}
if got != expected {
t.Errorf("expected module name %s, got %s", expected, got)
}
}
// change the working directory to the tempdir
func changeCurrentDir(t *testing.T) string {
t.Helper()
tmp := t.TempDir()
oldCWD, err := os.Getwd()
if err != nil {
t.Fatalf("getting working directory: %v", err)
}
if err := os.Chdir(tmp); err != nil {
t.Fatalf("changing working directory: %v", err)
}
t.Cleanup(func() {
if err := os.Chdir(oldCWD); err != nil {
t.Fatalf("restoring working directory: %v", err)
}
})
return tmp
}

@ -1,30 +0,0 @@
//go:build windows
// +build windows
package project
import (
"testing"
)
func Test_processProjectParams(t *testing.T) {
type args struct {
projectName string
fallbackPlaceDir string
}
tests := []struct {
name string
args args
want string
}{
{"absWindows", args{projectName: "c:\\kratos\\awesome\\go\\demo", fallbackPlaceDir: ""}, "c:\\kratos\\awesome\\go"},
//{"relativeWindows", args{projectName: "/home/kratos/awesome/go/demo", fallbackPlaceDir: ""}, "/home/kratos/awesome/go"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if _, got := processProjectParams(tt.args.projectName, tt.args.fallbackPlaceDir); got != tt.want {
t.Errorf("getProjectPlaceDir() = %v, want %v", got, tt.want)
}
})
}
}

@ -19,11 +19,8 @@ var CmdAdd = &cobra.Command{
Run: run, Run: run,
} }
func run(_ *cobra.Command, args []string) { func run(cmd *cobra.Command, args []string) {
if len(args) == 0 { // kratos proto add helloworld/v1/helloworld.proto
fmt.Println("Please enter the proto file or directory")
return
}
input := args[0] input := args[0]
n := strings.LastIndex(input, "/") n := strings.LastIndex(input, "/")
if n == -1 { if n == -1 {

@ -3,7 +3,7 @@ package add
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path"
) )
// Proto is a proto generator. // Proto is a proto generator.
@ -26,13 +26,13 @@ func (p *Proto) Generate() error {
if err != nil { if err != nil {
panic(err) panic(err)
} }
to := filepath.Join(wd, p.Path) to := path.Join(wd, p.Path)
if _, err := os.Stat(to); os.IsNotExist(err) { if _, err := os.Stat(to); os.IsNotExist(err) {
if err := os.MkdirAll(to, 0o700); err != nil { if err := os.MkdirAll(to, 0o700); err != nil {
return err return err
} }
} }
name := filepath.Join(to, p.Name) name := path.Join(to, p.Name)
if _, err := os.Stat(name); !os.IsNotExist(err) { if _, err := os.Stat(name); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", p.Name) return fmt.Errorf("%s already exists", p.Name)
} }

@ -8,9 +8,9 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/spf13/cobra"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
"github.com/spf13/cobra"
) )
// CmdClient represents the source command. // CmdClient represents the source command.
@ -30,7 +30,7 @@ func init() {
CmdClient.Flags().StringVarP(&protoPath, "proto_path", "p", protoPath, "proto path") CmdClient.Flags().StringVarP(&protoPath, "proto_path", "p", protoPath, "proto path")
} }
func run(_ *cobra.Command, args []string) { func run(cmd *cobra.Command, args []string) {
if len(args) == 0 { if len(args) == 0 {
fmt.Println("Please enter the proto file or directory") fmt.Println("Please enter the proto file or directory")
return return

@ -1,11 +1,11 @@
package proto package proto
import ( import (
"github.com/spf13/cobra"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto/add" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto/add"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto/client" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto/client"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto/server" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto/server"
"github.com/spf13/cobra"
) )
// CmdProto represents the proto command. // CmdProto represents the proto command.

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"os" "os"
"path/filepath" "path"
"strings" "strings"
"github.com/emicklei/proto" "github.com/emicklei/proto"
@ -16,8 +16,8 @@ import (
// CmdServer the service command. // CmdServer the service command.
var CmdServer = &cobra.Command{ var CmdServer = &cobra.Command{
Use: "server", Use: "server",
Short: "Generate the proto server implementations", Short: "Generate the proto Server implementations",
Long: "Generate the proto server implementations. Example: kratos proto server api/xxx.proto --target-dir=internal/service", Long: "Generate the proto Server implementations. Example: kratos proto server api/xxx.proto -target-dir=internal/service",
Run: run, Run: run,
} }
var targetDir string var targetDir string
@ -26,7 +26,7 @@ func init() {
CmdServer.Flags().StringVarP(&targetDir, "target-dir", "t", "internal/service", "generate target directory") CmdServer.Flags().StringVarP(&targetDir, "target-dir", "t", "internal/service", "generate target directory")
} }
func run(_ *cobra.Command, args []string) { func run(cmd *cobra.Command, args []string) {
if len(args) == 0 { if len(args) == 0 {
fmt.Fprintln(os.Stderr, "Please specify the proto file. Example: kratos proto server api/xxx.proto") fmt.Fprintln(os.Stderr, "Please specify the proto file. Example: kratos proto server api/xxx.proto")
return return
@ -64,8 +64,8 @@ func run(_ *cobra.Command, args []string) {
continue continue
} }
cs.Methods = append(cs.Methods, &Method{ cs.Methods = append(cs.Methods, &Method{
Service: serviceName(s.Name), Name: serviceName(r.Name), Request: parametersName(r.RequestType), Service: serviceName(s.Name), Name: serviceName(r.Name), Request: r.RequestType,
Reply: parametersName(r.ReturnsType), Type: getMethodType(r.StreamsRequest, r.StreamsReturns), Reply: r.ReturnsType, Type: getMethodType(r.StreamsRequest, r.StreamsReturns),
}) })
} }
res = append(res, cs) res = append(res, cs)
@ -76,7 +76,7 @@ func run(_ *cobra.Command, args []string) {
return return
} }
for _, s := range res { for _, s := range res {
to := filepath.Join(targetDir, strings.ToLower(s.Service)+".go") to := path.Join(targetDir, strings.ToLower(s.Service)+".go")
if _, err := os.Stat(to); !os.IsNotExist(err) { if _, err := os.Stat(to); !os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "%s already exists: %s\n", s.Service, to) fmt.Fprintf(os.Stderr, "%s already exists: %s\n", s.Service, to)
continue continue
@ -105,10 +105,6 @@ func getMethodType(streamsRequest, streamsReturns bool) MethodType {
return unaryType return unaryType
} }
func parametersName(name string) string {
return strings.ReplaceAll(name, ".", "_")
}
func serviceName(name string) string { func serviceName(name string) string {
return toUpperCamelCase(strings.Split(name, ".")[0]) return toUpperCamelCase(strings.Split(name, ".")[0])
} }

@ -60,43 +60,3 @@ func Test_serviceName(t *testing.T) {
}) })
} }
} }
func Test_parametersName(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
want string
}{
{
name: "parametersName on not nested",
args: args{
name: "MessageResponse",
},
want: "MessageResponse",
},
{
name: "parametersName on One layer of nesting",
args: args{
name: "Message.Response",
},
want: "Message_Response",
},
{
name: "parametersName on Two layer of nesting",
args: args{
name: "Message.Message2.Response",
},
want: "Message_Message2_Response",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := parametersName(tt.args.name); got != tt.want {
t.Errorf("parametersName() = %v, want %v", got, tt.want)
}
})
}
}

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
@ -18,11 +19,6 @@ var CmdRun = &cobra.Command{
Long: "Run project. Example: kratos run", Long: "Run project. Example: kratos run",
Run: Run, Run: Run,
} }
var targetDir string
func init() {
CmdRun.Flags().StringVarP(&targetDir, "work", "w", "", "target working directory")
}
// Run run project. // Run run project.
func Run(cmd *cobra.Command, args []string) { func Run(cmd *cobra.Command, args []string) {
@ -68,11 +64,10 @@ func Run(cmd *cobra.Command, args []string) {
dir = cmdPath[dir] dir = cmdPath[dir]
} }
} }
fd := exec.Command("go", append([]string{"run", dir}, programArgs...)...) fd := exec.Command("go", append([]string{"run", "."}, programArgs...)...)
fd.Stdout = os.Stdout fd.Stdout = os.Stdout
fd.Stderr = os.Stderr fd.Stderr = os.Stderr
fd.Dir = dir fd.Dir = dir
changeWorkingDirectory(fd, targetDir)
if err := fd.Run(); err != nil { if err := fd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "\033[31mERROR: %s\033[m\n", err.Error()) fmt.Fprintf(os.Stderr, "\033[31mERROR: %s\033[m\n", err.Error())
return return
@ -107,7 +102,7 @@ func findCMD(base string) (map[string]string, error) {
} }
for _, fileInfo := range paths { for _, fileInfo := range paths {
if fileInfo.IsDir() { if fileInfo.IsDir() {
abs := filepath.Join(walkPath, fileInfo.Name()) abs := path.Join(walkPath, fileInfo.Name())
cmdPath[strings.TrimPrefix(abs, wd)] = abs cmdPath[strings.TrimPrefix(abs, wd)] = abs
} }
} }
@ -136,10 +131,3 @@ func findCMD(base string) (map[string]string, error) {
} }
return map[string]string{"": base}, nil return map[string]string{"": base}, nil
} }
func changeWorkingDirectory(cmd *exec.Cmd, targetDir string) {
targetDir = strings.TrimSpace(targetDir)
if targetDir != "" {
cmd.Dir = targetDir
}
}

@ -3,9 +3,9 @@ package upgrade
import ( import (
"fmt" "fmt"
"github.com/spf13/cobra"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
"github.com/spf13/cobra"
) )
// CmdUpgrade represents the upgrade command. // CmdUpgrade represents the upgrade command.
@ -17,7 +17,7 @@ var CmdUpgrade = &cobra.Command{
} }
// Run upgrade the kratos tools. // Run upgrade the kratos tools.
func Run(_ *cobra.Command, _ []string) { func Run(cmd *cobra.Command, args []string) {
err := base.GoInstall( err := base.GoInstall(
"github.com/go-kratos/kratos/cmd/kratos/v2@latest", "github.com/go-kratos/kratos/cmd/kratos/v2@latest",
"github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest", "github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest",

@ -3,13 +3,13 @@ package main
import ( import (
"log" "log"
"github.com/spf13/cobra"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/change" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/change"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/project" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/project"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/proto"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/run" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/run"
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/upgrade" "github.com/go-kratos/kratos/cmd/kratos/v2/internal/upgrade"
"github.com/spf13/cobra"
) )
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{

@ -1,4 +1,4 @@
package main package main
// release is the current kratos tool version. // release is the current kratos tool version.
const release = "v2.6.3" const release = "v2.5.3"

@ -59,7 +59,7 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.
} }
} }
func genErrorsReason(_ *protogen.Plugin, _ *protogen.File, g *protogen.GeneratedFile, enum *protogen.Enum) bool { func genErrorsReason(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, enum *protogen.Enum) bool {
defaultCode := proto.GetExtension(enum.Desc.Options(), errors.E_DefaultCode) defaultCode := proto.GetExtension(enum.Desc.Options(), errors.E_DefaultCode)
code := 0 code := 0
if ok := defaultCode.(int32); ok != 0 { if ok := defaultCode.(int32); ok != 0 {

@ -1,17 +0,0 @@
{{ range .Errors }}
{{ if .HasComment }}{{ .Comment }}{{ end -}}
func Is{{.CamelValue}}(err error) bool {
if err == nil {
return false
}
e := errors.FromError(err)
return e.Reason == {{ .Name }}_{{ .Value }}.String() && e.Code == {{ .HTTPCode }}
}
{{ if .HasComment }}{{ .Comment }}{{ end -}}
func Error{{ .CamelValue }}(format string, args ...interface{}) *errors.Error {
return errors.New({{ .HTTPCode }}, {{ .Name }}_{{ .Value }}.String(), fmt.Sprintf(format, args...))
}
{{- end }}

@ -3,6 +3,6 @@ module github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2
go 1.16 go 1.16
require ( require (
golang.org/x/text v0.3.8 golang.org/x/text v0.3.7
google.golang.org/protobuf v1.28.0 google.golang.org/protobuf v1.28.0
) )

@ -1,31 +1,9 @@
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=

@ -2,12 +2,28 @@ package main
import ( import (
"bytes" "bytes"
_ "embed"
"text/template" "text/template"
) )
//go:embed errorsTemplate.tpl var errorsTemplate = `
var errorsTemplate string {{ range .Errors }}
{{ if .HasComment }}{{ .Comment }}{{ end -}}
func Is{{.CamelValue}}(err error) bool {
if err == nil {
return false
}
e := errors.FromError(err)
return e.Reason == {{ .Name }}_{{ .Value }}.String() && e.Code == {{ .HTTPCode }}
}
{{ if .HasComment }}{{ .Comment }}{{ end -}}
func Error{{ .CamelValue }}(format string, args ...interface{}) *errors.Error {
return errors.New({{ .HTTPCode }}, {{ .Name }}_{{ .Value }}.String(), fmt.Sprintf(format, args...))
}
{{- end }}
`
type errorInfo struct { type errorInfo struct {
Name string Name string

@ -1,4 +1,4 @@
package main package main
// release is the current protoc-gen-go-errors version. // release is the current protoc-gen-go-errors version.
const release = "v2.6.3" const release = "v2.5.3"

@ -24,7 +24,7 @@ const (
var methodSets = make(map[string]int) var methodSets = make(map[string]int)
// generateFile generates a _http.pb.go file containing kratos errors definitions. // generateFile generates a _http.pb.go file containing kratos errors definitions.
func generateFile(gen *protogen.Plugin, file *protogen.File, omitempty bool, omitemptyPrefix string) *protogen.GeneratedFile { func generateFile(gen *protogen.Plugin, file *protogen.File, omitempty bool) *protogen.GeneratedFile {
if len(file.Services) == 0 || (omitempty && !hasHTTPRule(file.Services)) { if len(file.Services) == 0 || (omitempty && !hasHTTPRule(file.Services)) {
return nil return nil
} }
@ -42,12 +42,12 @@ func generateFile(gen *protogen.Plugin, file *protogen.File, omitempty bool, omi
g.P() g.P()
g.P("package ", file.GoPackageName) g.P("package ", file.GoPackageName)
g.P() g.P()
generateFileContent(gen, file, g, omitempty, omitemptyPrefix) generateFileContent(gen, file, g, omitempty)
return g return g
} }
// generateFileContent generates the kratos errors definitions, excluding the package statement. // generateFileContent generates the kratos errors definitions, excluding the package statement.
func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, omitempty bool, omitemptyPrefix string) { func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, omitempty bool) {
if len(file.Services) == 0 { if len(file.Services) == 0 {
return return
} }
@ -59,11 +59,11 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.
g.P() g.P()
for _, service := range file.Services { for _, service := range file.Services {
genService(gen, file, g, service, omitempty, omitemptyPrefix) genService(gen, file, g, service, omitempty)
} }
} }
func genService(_ *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service, omitempty bool, omitemptyPrefix string) { func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service, omitempty bool) {
if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
g.P("//") g.P("//")
g.P(deprecationComment) g.P(deprecationComment)
@ -81,11 +81,11 @@ func genService(_ *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFi
rule, ok := proto.GetExtension(method.Desc.Options(), annotations.E_Http).(*annotations.HttpRule) rule, ok := proto.GetExtension(method.Desc.Options(), annotations.E_Http).(*annotations.HttpRule)
if rule != nil && ok { if rule != nil && ok {
for _, bind := range rule.AdditionalBindings { for _, bind := range rule.AdditionalBindings {
sd.Methods = append(sd.Methods, buildHTTPRule(g, service, method, bind, omitemptyPrefix)) sd.Methods = append(sd.Methods, buildHTTPRule(g, method, bind))
} }
sd.Methods = append(sd.Methods, buildHTTPRule(g, service, method, rule, omitemptyPrefix)) sd.Methods = append(sd.Methods, buildHTTPRule(g, method, rule))
} else if !omitempty { } else if !omitempty {
path := fmt.Sprintf("%s/%s/%s", omitemptyPrefix, service.Desc.FullName(), method.Desc.Name()) path := fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.Desc.Name())
sd.Methods = append(sd.Methods, buildMethodDesc(g, method, http.MethodPost, path)) sd.Methods = append(sd.Methods, buildMethodDesc(g, method, http.MethodPost, path))
} }
} }
@ -109,7 +109,7 @@ func hasHTTPRule(services []*protogen.Service) bool {
return false return false
} }
func buildHTTPRule(g *protogen.GeneratedFile, service *protogen.Service, m *protogen.Method, rule *annotations.HttpRule, omitemptyPrefix string) *methodDesc { func buildHTTPRule(g *protogen.GeneratedFile, m *protogen.Method, rule *annotations.HttpRule) *methodDesc {
var ( var (
path string path string
method string method string
@ -137,12 +137,6 @@ func buildHTTPRule(g *protogen.GeneratedFile, service *protogen.Service, m *prot
path = pattern.Custom.Path path = pattern.Custom.Path
method = pattern.Custom.Kind method = pattern.Custom.Kind
} }
if method == "" {
method = http.MethodPost
}
if path == "" {
path = fmt.Sprintf("%s/%s/%s", omitemptyPrefix, service.Desc.FullName(), m.Desc.Name())
}
body = rule.Body body = rule.Body
responseBody = rule.ResponseBody responseBody = rule.ResponseBody
md := buildMethodDesc(g, m, method, path) md := buildMethodDesc(g, m, method, path)
@ -204,17 +198,12 @@ func buildMethodDesc(g *protogen.GeneratedFile, m *protogen.Method, method, path
} }
} }
} }
comment := m.Comments.Leading.String() + m.Comments.Trailing.String()
if comment != "" {
comment = "// " + m.GoName + strings.TrimPrefix(strings.TrimSuffix(comment, "\n"), "//")
}
return &methodDesc{ return &methodDesc{
Name: m.GoName, Name: m.GoName,
OriginalName: string(m.Desc.Name()), OriginalName: string(m.Desc.Name()),
Num: methodSets[m.GoName], Num: methodSets[m.GoName],
Request: g.QualifiedGoIdent(m.Input.GoIdent), Request: g.QualifiedGoIdent(m.Input.GoIdent),
Reply: g.QualifiedGoIdent(m.Output.GoIdent), Reply: g.QualifiedGoIdent(m.Output.GoIdent),
Comment: comment,
Path: path, Path: path,
Method: method, Method: method,
HasVars: len(vars) > 0, HasVars: len(vars) > 0,

@ -1,93 +0,0 @@
{{$svrType := .ServiceType}}
{{$svrName := .ServiceName}}
{{- range .MethodSets}}
const Operation{{$svrType}}{{.OriginalName}} = "/{{$svrName}}/{{.OriginalName}}"
{{- end}}
type {{.ServiceType}}HTTPServer interface {
{{- range .MethodSets}}
{{- if ne .Comment ""}}
{{.Comment}}
{{- end}}
{{.Name}}(context.Context, *{{.Request}}) (*{{.Reply}}, error)
{{- end}}
}
func Register{{.ServiceType}}HTTPServer(s *http.Server, srv {{.ServiceType}}HTTPServer) {
r := s.Route("/")
{{- range .Methods}}
r.{{.Method}}("{{.Path}}", _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv))
{{- end}}
}
{{range .Methods}}
func _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv {{$svrType}}HTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in {{.Request}}
{{- if .HasBody}}
if err := ctx.Bind(&in{{.Body}}); err != nil {
return err
}
{{- if not (eq .Body "")}}
if err := ctx.BindQuery(&in); err != nil {
return err
}
{{- end}}
{{- else}}
if err := ctx.BindQuery(&in{{.Body}}); err != nil {
return err
}
{{- end}}
{{- if .HasVars}}
if err := ctx.BindVars(&in); err != nil {
return err
}
{{- end}}
http.SetOperation(ctx,Operation{{$svrType}}{{.OriginalName}})
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.{{.Name}}(ctx, req.(*{{.Request}}))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*{{.Reply}})
return ctx.Result(200, reply{{.ResponseBody}})
}
}
{{end}}
type {{.ServiceType}}HTTPClient interface {
{{- range .MethodSets}}
{{.Name}}(ctx context.Context, req *{{.Request}}, opts ...http.CallOption) (rsp *{{.Reply}}, err error)
{{- end}}
}
type {{.ServiceType}}HTTPClientImpl struct{
cc *http.Client
}
func New{{.ServiceType}}HTTPClient (client *http.Client) {{.ServiceType}}HTTPClient {
return &{{.ServiceType}}HTTPClientImpl{client}
}
{{range .MethodSets}}
func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http.CallOption) (*{{.Reply}}, error) {
var out {{.Reply}}
pattern := "{{.Path}}"
path := binding.EncodeURL(pattern, in, {{not .HasBody}})
opts = append(opts, http.Operation(Operation{{$svrType}}{{.OriginalName}}))
opts = append(opts, http.PathTemplate(pattern))
{{if .HasBody -}}
err := c.cc.Invoke(ctx, "{{.Method}}", path, in{{.Body}}, &out{{.ResponseBody}}, opts...)
{{else -}}
err := c.cc.Invoke(ctx, "{{.Method}}", path, nil, &out{{.ResponseBody}}, opts...)
{{end -}}
if err != nil {
return nil, err
}
return &out, err
}
{{end}}

@ -11,7 +11,6 @@ import (
var ( var (
showVersion = flag.Bool("version", false, "print the version and exit") showVersion = flag.Bool("version", false, "print the version and exit")
omitempty = flag.Bool("omitempty", true, "omit if google.api is empty") omitempty = flag.Bool("omitempty", true, "omit if google.api is empty")
omitemptyPrefix = flag.String("omitempty_prefix", "", "omit if google.api is empty")
) )
func main() { func main() {
@ -28,7 +27,7 @@ func main() {
if !f.Generate { if !f.Generate {
continue continue
} }
generateFile(gen, f, *omitempty, *omitemptyPrefix) generateFile(gen, f, *omitempty)
} }
return nil return nil
}) })

@ -2,13 +2,102 @@ package main
import ( import (
"bytes" "bytes"
_ "embed"
"strings" "strings"
"text/template" "text/template"
) )
//go:embed httpTemplate.tpl var httpTemplate = `
var httpTemplate string {{$svrType := .ServiceType}}
{{$svrName := .ServiceName}}
{{- range .MethodSets}}
const Operation{{$svrType}}{{.OriginalName}} = "/{{$svrName}}/{{.OriginalName}}"
{{- end}}
type {{.ServiceType}}HTTPServer interface {
{{- range .MethodSets}}
{{.Name}}(context.Context, *{{.Request}}) (*{{.Reply}}, error)
{{- end}}
}
func Register{{.ServiceType}}HTTPServer(s *http.Server, srv {{.ServiceType}}HTTPServer) {
r := s.Route("/")
{{- range .Methods}}
r.{{.Method}}("{{.Path}}", _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv))
{{- end}}
}
{{range .Methods}}
func _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv {{$svrType}}HTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in {{.Request}}
{{- if .HasBody}}
if err := ctx.Bind(&in{{.Body}}); err != nil {
return err
}
{{- if not (eq .Body "")}}
if err := ctx.BindQuery(&in); err != nil {
return err
}
{{- end}}
{{- else}}
if err := ctx.BindQuery(&in{{.Body}}); err != nil {
return err
}
{{- end}}
{{- if .HasVars}}
if err := ctx.BindVars(&in); err != nil {
return err
}
{{- end}}
http.SetOperation(ctx,Operation{{$svrType}}{{.OriginalName}})
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.{{.Name}}(ctx, req.(*{{.Request}}))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*{{.Reply}})
return ctx.Result(200, reply{{.ResponseBody}})
}
}
{{end}}
type {{.ServiceType}}HTTPClient interface {
{{- range .MethodSets}}
{{.Name}}(ctx context.Context, req *{{.Request}}, opts ...http.CallOption) (rsp *{{.Reply}}, err error)
{{- end}}
}
type {{.ServiceType}}HTTPClientImpl struct{
cc *http.Client
}
func New{{.ServiceType}}HTTPClient (client *http.Client) {{.ServiceType}}HTTPClient {
return &{{.ServiceType}}HTTPClientImpl{client}
}
{{range .MethodSets}}
func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http.CallOption) (*{{.Reply}}, error) {
var out {{.Reply}}
pattern := "{{.Path}}"
path := binding.EncodeURL(pattern, in, {{not .HasBody}})
opts = append(opts, http.Operation(Operation{{$svrType}}{{.OriginalName}}))
opts = append(opts, http.PathTemplate(pattern))
{{if .HasBody -}}
err := c.cc.Invoke(ctx, "{{.Method}}", path, in{{.Body}}, &out{{.ResponseBody}}, opts...)
{{else -}}
err := c.cc.Invoke(ctx, "{{.Method}}", path, nil, &out{{.ResponseBody}}, opts...)
{{end -}}
if err != nil {
return nil, err
}
return &out, err
}
{{end}}
`
type serviceDesc struct { type serviceDesc struct {
ServiceType string // Greeter ServiceType string // Greeter
@ -25,7 +114,6 @@ type methodDesc struct {
Num int Num int
Request string Request string
Reply string Reply string
Comment string
// http_rule // http_rule
Path string Path string
Method string Method string

@ -1,4 +1,4 @@
package main package main
// release is the current protoc-gen-go-http version. // release is the current protoc-gen-go-http version.
const release = "v2.6.3" const release = "v2.5.3"

@ -51,7 +51,7 @@ func WithResolver(r Resolver) Option {
// WithLogger with config logger. // WithLogger with config logger.
// Deprecated: use global logger instead. // Deprecated: use global logger instead.
func WithLogger(_ log.Logger) Option { func WithLogger(l log.Logger) Option {
return func(o *options) {} return func(o *options) {}
} }

@ -5,7 +5,7 @@ import (
"github.com/apolloconfig/agollo/v4" "github.com/apolloconfig/agollo/v4"
"github.com/apolloconfig/agollo/v4/constant" "github.com/apolloconfig/agollo/v4/constant"
apolloconfig "github.com/apolloconfig/agollo/v4/env/config" apolloConfig "github.com/apolloconfig/agollo/v4/env/config"
"github.com/apolloconfig/agollo/v4/extension" "github.com/apolloconfig/agollo/v4/extension"
"github.com/go-kratos/kratos/v2/config" "github.com/go-kratos/kratos/v2/config"
@ -25,8 +25,6 @@ const (
properties = "properties" properties = "properties"
) )
var formats map[string]struct{}
// Option is apollo option // Option is apollo option
type Option func(*options) type Option func(*options)
@ -112,8 +110,8 @@ func NewSource(opts ...Option) config.Source {
for _, o := range opts { for _, o := range opts {
o(&op) o(&op)
} }
client, err := agollo.StartWithConfig(func() (*apolloconfig.AppConfig, error) { client, err := agollo.StartWithConfig(func() (*apolloConfig.AppConfig, error) {
return &apolloconfig.AppConfig{ return &apolloConfig.AppConfig{
AppID: op.appid, AppID: op.appid,
Cluster: op.cluster, Cluster: op.cluster,
NamespaceName: op.namespace, NamespaceName: op.namespace,
@ -131,16 +129,10 @@ func NewSource(opts ...Option) config.Source {
func format(ns string) string { func format(ns string) string {
arr := strings.Split(ns, ".") arr := strings.Split(ns, ".")
suffix := arr[len(arr)-1] if len(arr) <= 1 || arr[len(arr)-1] == properties {
if len(arr) <= 1 || suffix == properties {
return json
}
if _, ok := formats[suffix]; !ok {
// fallback
return json return json
} }
return arr[len(arr)-1]
return suffix
} }
func (e *apollo) load() []*config.KeyValue { func (e *apollo) load() []*config.KeyValue {
@ -157,7 +149,7 @@ func (e *apollo) load() []*config.KeyValue {
kvs = append(kvs, kv) kvs = append(kvs, kv)
continue continue
} }
if strings.Contains(ns, ".") && !strings.HasSuffix(ns, "."+properties) && if strings.Contains(ns, ".") && !strings.Contains(ns, properties) &&
(format(ns) == yaml || format(ns) == yml || format(ns) == json) { (format(ns) == yaml || format(ns) == yml || format(ns) == json) {
kv, err := e.getOriginConfig(ns) kv, err := e.getOriginConfig(ns)
if err != nil { if err != nil {
@ -166,7 +158,7 @@ func (e *apollo) load() []*config.KeyValue {
} }
kvs = append(kvs, kv) kvs = append(kvs, kv)
continue continue
} } else {
kv, err := e.getConfig(ns) kv, err := e.getConfig(ns)
if err != nil { if err != nil {
log.Errorf("apollo get config failed,err:%v", err) log.Errorf("apollo get config failed,err:%v", err)
@ -174,6 +166,7 @@ func (e *apollo) load() []*config.KeyValue {
} }
kvs = append(kvs, kv) kvs = append(kvs, kv)
} }
}
return kvs return kvs
} }
@ -259,28 +252,16 @@ func resolve(key string, value interface{}, target map[string]interface{}) {
// eg: namespace.ext with subKey got namespace.subKey // eg: namespace.ext with subKey got namespace.subKey
func genKey(ns, sub string) string { func genKey(ns, sub string) string {
arr := strings.Split(ns, ".") arr := strings.Split(ns, ".")
if len(arr) < 1 {
return sub
}
if len(arr) == 1 { if len(arr) == 1 {
if ns == "" { if ns == "" {
return sub return sub
} }
return ns + "." + sub return ns + "." + sub
} }
suffix := arr[len(arr)-1]
_, ok := formats[suffix]
if ok {
return strings.Join(arr[:len(arr)-1], ".") + "." + sub return strings.Join(arr[:len(arr)-1], ".") + "." + sub
} }
return ns + "." + sub
}
func init() {
formats = make(map[string]struct{})
formats[yaml] = struct{}{}
formats[yml] = struct{}{}
formats[json] = struct{}{}
formats[properties] = struct{}{}
}

@ -1,90 +0,0 @@
package apollo
import (
"testing"
)
func Test_genKey(t *testing.T) {
type args struct {
ns string
sub string
}
tests := []struct {
name string
args args
want string
}{
{
name: "blank namespace",
args: args{
ns: "",
sub: "x.y",
},
want: "x.y",
},
{
name: "properties namespace",
args: args{
ns: "application",
sub: "x.y",
},
want: "application.x.y",
},
{
name: "namespace with format",
args: args{
ns: "app.yaml",
sub: "x.y",
},
want: "app.x.y",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := genKey(tt.args.ns, tt.args.sub); got != tt.want {
t.Errorf("genKey() = %v, want %v", got, tt.want)
}
})
}
}
func Test_format(t *testing.T) {
tests := []struct {
name string
namespace string
want string
}{
{
name: "properties namespace",
namespace: "application",
want: "json",
},
{
name: "properties namespace #1",
namespace: "app.setting",
want: "json",
},
{
name: "namespace with format[yaml]",
namespace: "app.yaml",
want: "yaml",
},
{
name: "namespace with format[yml]",
namespace: "app.yml",
want: "yml",
},
{
name: "namespace with format[json]",
namespace: "app.json",
want: "json",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := format(tt.namespace); got != tt.want {
t.Errorf("format() = %v, want %v", got, tt.want)
}
})
}
}

@ -3,10 +3,13 @@ module github.com/go-kratos/kratos/contrib/config/apollo/v2
go 1.16 go 1.16
require ( require (
github.com/apolloconfig/agollo/v4 v4.3.0 github.com/apolloconfig/agollo/v4 v4.2.1
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.4.0
) )
require github.com/spf13/viper v1.11.0 // indirect require (
github.com/spf13/viper v1.11.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -25,7 +25,7 @@ type customChangeListener struct {
func (c *customChangeListener) onChange(namespace string, changes map[string]*storage.ConfigChange) []*config.KeyValue { func (c *customChangeListener) onChange(namespace string, changes map[string]*storage.ConfigChange) []*config.KeyValue {
kv := make([]*config.KeyValue, 0, 2) kv := make([]*config.KeyValue, 0, 2)
if strings.Contains(namespace, ".") && !strings.HasSuffix(namespace, "."+properties) && if strings.Contains(namespace, ".") && !strings.Contains(namespace, properties) &&
(format(namespace) == yaml || format(namespace) == yml || format(namespace) == json) { (format(namespace) == yaml || format(namespace) == yml || format(namespace) == json) {
value, err := c.apollo.client.GetConfigCache(namespace).Get("content") value, err := c.apollo.client.GetConfigCache(namespace).Get("content")
if err != nil { if err != nil {
@ -72,7 +72,7 @@ func (c *customChangeListener) OnChange(changeEvent *storage.ChangeEvent) {
c.in <- change c.in <- change
} }
func (c *customChangeListener) OnNewestChange(_ *storage.FullChangeEvent) {} func (c *customChangeListener) OnNewestChange(changeEvent *storage.FullChangeEvent) {}
func newWatcher(a *apollo) (config.Watcher, error) { func newWatcher(a *apollo) (config.Watcher, error) {
changeCh := make(chan []*config.KeyValue) changeCh := make(chan []*config.KeyValue)

@ -3,13 +3,8 @@ module github.com/go-kratos/kratos/contrib/config/consul/v2
go 1.15 go 1.15
require ( require (
github.com/armon/go-metrics v0.3.10 // indirect github.com/go-kratos/kratos/v2 v2.4.0
github.com/go-kratos/kratos/v2 v2.6.3 github.com/hashicorp/consul/api v1.15.3
github.com/hashicorp/consul/api v1.20.0
github.com/hashicorp/go-hclog v0.14.1 // indirect
github.com/hashicorp/go-immutable-radix v1.3.0 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -18,7 +18,7 @@ type watcher struct {
cancel context.CancelFunc cancel context.CancelFunc
} }
func (w *watcher) handle(_ uint64, data interface{}) { func (w *watcher) handle(idx uint64, data interface{}) {
if data == nil { if data == nil {
return return
} }

@ -3,9 +3,9 @@ module github.com/go-kratos/kratos/contrib/config/etcd/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.4.0
go.etcd.io/etcd/client/v3 v3.5.8 go.etcd.io/etcd/client/v3 v3.5.4
google.golang.org/grpc v1.56.1 google.golang.org/grpc v1.50.1
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -3,10 +3,10 @@ module github.com/go-kratos/kratos/contrib/config/kubernetes/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.4.0
k8s.io/api v0.26.3 k8s.io/api v0.24.3
k8s.io/apimachinery v0.26.3 k8s.io/apimachinery v0.24.3
k8s.io/client-go v0.26.3 k8s.io/client-go v0.24.3
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -3,10 +3,14 @@ module github.com/go-kratos/kratos/contrib/config/nacos/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.4.0
github.com/nacos-group/nacos-sdk-go v1.0.9 github.com/nacos-group/nacos-sdk-go v1.0.9
) )
require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../
replace github.com/buger/jsonparser => github.com/buger/jsonparser v1.1.1 replace github.com/buger/jsonparser => github.com/buger/jsonparser v1.1.1

File diff suppressed because it is too large Load Diff

@ -1,28 +1,26 @@
package polaris package config
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"time"
"github.com/go-kratos/kratos/v2/config"
"github.com/polarismesh/polaris-go" "github.com/polarismesh/polaris-go"
) )
var ( var (
testNamespace = "default" namespace = "default"
testFileGroup = "test" fileGroup = "test"
testOriginContent = `server: originContent = `server:
port: 8080` port: 8080`
testUpdatedContent = `server: updatedContent = `server:
port: 8090` port: 8090`
testCenterURL = "http://127.0.0.1:8090" configCenterURL = "http://127.0.0.1:8090"
) )
func makeJSONRequest(uri string, data string, method string, headers map[string]string) ([]byte, error) { func makeJSONRequest(uri string, data string, method string, headers map[string]string) ([]byte, error) {
@ -59,7 +57,7 @@ type configClient struct {
} }
func newConfigClient() (*configClient, error) { func newConfigClient() (*configClient, error) {
token, err := getToken(testCenterURL) token, err := getToken()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -68,7 +66,7 @@ func newConfigClient() (*configClient, error) {
}, nil }, nil
} }
func getToken(testCenterURL string) (string, error) { func getToken() (string, error) {
data, err := json.Marshal(map[string]string{ data, err := json.Marshal(map[string]string{
"name": "polaris", "name": "polaris",
"password": "polaris", "password": "polaris",
@ -77,7 +75,7 @@ func getToken(testCenterURL string) (string, error) {
return "", err return "", err
} }
// login use default user // login use default user
res, err := makeJSONRequest(fmt.Sprintf("%s/core/v1/user/login", testCenterURL), string(data), http.MethodPost, map[string]string{}) res, err := makeJSONRequest(fmt.Sprintf("%s/core/v1/user/login", configCenterURL), string(data), http.MethodPost, map[string]string{})
if err != nil { if err != nil {
return "", nil return "", nil
} }
@ -91,16 +89,16 @@ func getToken(testCenterURL string) (string, error) {
func (client *configClient) createConfigFile(name string) error { func (client *configClient) createConfigFile(name string) error {
data, err := json.Marshal(map[string]string{ data, err := json.Marshal(map[string]string{
"name": name, "name": name,
"namespace": testNamespace, "namespace": namespace,
"group": testFileGroup, "group": fileGroup,
"content": testOriginContent, "content": originContent,
"modifyBy": "polaris", "modifyBy": "polaris",
"format": "yaml", "format": "yaml",
}) })
if err != nil { if err != nil {
return err return err
} }
res, err := makeJSONRequest(fmt.Sprintf("%s/config/v1/configfiles", testCenterURL), string(data), http.MethodPost, map[string]string{ res, err := makeJSONRequest(fmt.Sprintf("%s/config/v1/configfiles", configCenterURL), string(data), http.MethodPost, map[string]string{
"X-Polaris-Token": client.token, "X-Polaris-Token": client.token,
}) })
if err != nil { if err != nil {
@ -113,7 +111,7 @@ func (client *configClient) createConfigFile(name string) error {
return err return err
} }
if resJSON.Code != 200000 { if resJSON.Code != 200000 {
return fmt.Errorf("create error, res: %s", string(res)) return errors.New("create error")
} }
return nil return nil
} }
@ -121,16 +119,16 @@ func (client *configClient) createConfigFile(name string) error {
func (client *configClient) updateConfigFile(name string) error { func (client *configClient) updateConfigFile(name string) error {
data, err := json.Marshal(map[string]string{ data, err := json.Marshal(map[string]string{
"name": name, "name": name,
"namespace": testNamespace, "namespace": namespace,
"group": testFileGroup, "group": fileGroup,
"content": testUpdatedContent, "content": updatedContent,
"modifyBy": "polaris", "modifyBy": "polaris",
"format": "yaml", "format": "yaml",
}) })
if err != nil { if err != nil {
return err return err
} }
res, err := makeJSONRequest(fmt.Sprintf("%s/config/v1/configfiles", testCenterURL), string(data), http.MethodPut, map[string]string{ res, err := makeJSONRequest(fmt.Sprintf("%s/config/v1/configfiles", configCenterURL), string(data), http.MethodPut, map[string]string{
"X-Polaris-Token": client.token, "X-Polaris-Token": client.token,
}) })
if err != nil { if err != nil {
@ -142,7 +140,7 @@ func (client *configClient) updateConfigFile(name string) error {
return err return err
} }
if resJSON.Code != 200000 { if resJSON.Code != 200000 {
return fmt.Errorf("update error, res: %s", string(res)) return errors.New("update error")
} }
return nil return nil
} }
@ -152,7 +150,7 @@ func (client *configClient) deleteConfigFile(name string) error {
if err != nil { if err != nil {
return err return err
} }
url := fmt.Sprintf("%s/config/v1/configfiles?namespace=%s&group=%s&name=%s", testCenterURL, testNamespace, testFileGroup, name) url := fmt.Sprintf("%s/config/v1/configfiles?namespace=%s&group=%s&name=%s", configCenterURL, namespace, fileGroup, name)
res, err := makeJSONRequest(url, string(data), http.MethodDelete, map[string]string{ res, err := makeJSONRequest(url, string(data), http.MethodDelete, map[string]string{
"X-Polaris-Token": client.token, "X-Polaris-Token": client.token,
}) })
@ -165,22 +163,22 @@ func (client *configClient) deleteConfigFile(name string) error {
return err return err
} }
if resJSON.Code != 200000 { if resJSON.Code != 200000 {
return fmt.Errorf("delete error, res: %s", string(res)) return errors.New("delete error")
} }
return nil return nil
} }
func (client *configClient) publishConfigFile(name string) error { func (client *configClient) publishConfigFile(name string) error {
data, err := json.Marshal(map[string]string{ data, err := json.Marshal(map[string]string{
"namespace": testNamespace, "namespace": namespace,
"group": testFileGroup, "group": fileGroup,
"fileName": name, "fileName": name,
"name": name, "name": name,
}) })
if err != nil { if err != nil {
return err return err
} }
res, err := makeJSONRequest(fmt.Sprintf("%s/config/v1/configfiles/release", testCenterURL), string(data), http.MethodPost, map[string]string{ res, err := makeJSONRequest(fmt.Sprintf("%s/config/v1/configfiles/release", configCenterURL), string(data), http.MethodPost, map[string]string{
"X-Polaris-Token": client.token, "X-Polaris-Token": client.token,
}) })
if err != nil { if err != nil {
@ -192,35 +190,30 @@ func (client *configClient) publishConfigFile(name string) error {
return err return err
} }
if resJSON.Code != 200000 { if resJSON.Code != 200000 {
return fmt.Errorf("publish error, res: %s", string(res)) return errors.New("publish error")
} }
return nil return nil
} }
func TestConfig(t *testing.T) { func TestConfig(t *testing.T) {
name := "kratos-polaris-test.yaml" name := "test.yaml"
client, err := newConfigClient() client, err := newConfigClient()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_ = client.deleteConfigFile(name)
if err = client.createConfigFile(name); err != nil { if err = client.createConfigFile(name); err != nil {
t.Fatal(err) t.Fatal(err)
} }
time.Sleep(5 * time.Second)
if err = client.publishConfigFile(name); err != nil { if err = client.publishConfigFile(name); err != nil {
t.Fatal(err) t.Fatal(err)
} }
time.Sleep(5 * time.Second)
// Always remember clear test resource // Always remember clear test resource
sdk, err := polaris.NewSDKContextByAddress("127.0.0.1:8091") configAPI, err := polaris.NewConfigAPI()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
p := New(sdk) config, err := New(configAPI, WithNamespace(namespace), WithFileGroup(fileGroup), WithFileName(name))
config, err := p.Config(WithConfigFile(File{Name: name, Group: testFileGroup}))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -229,10 +222,7 @@ func TestConfig(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for _, value := range kv { if len(kv) != 1 || kv[0].Key != name || string(kv[0].Value) != originContent {
t.Logf("key: %s, value: %s", value.Key, value.Value)
}
if len(kv) != 1 || kv[0].Key != name || string(kv[0].Value) != testOriginContent {
t.Fatal("config error") t.Fatal("config error")
} }
@ -240,13 +230,18 @@ func TestConfig(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer func() {
t.Cleanup(func() {
err = client.deleteConfigFile(name) err = client.deleteConfigFile(name)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
}) if _, err = w.Next(); err != nil {
t.Fatal(err)
}
if err = w.Stop(); err != nil {
t.Fatal(err)
}
}()
if err = client.updateConfigFile(name); err != nil { if err = client.updateConfigFile(name); err != nil {
t.Fatal(err) t.Fatal(err)
@ -260,22 +255,17 @@ func TestConfig(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for _, value := range kv { if len(kv) != 1 || kv[0].Key != name || string(kv[0].Value) != updatedContent {
t.Log(value.Key, string(value.Value))
}
if len(kv) != 1 || kv[0].Key != name || string(kv[0].Value) != testUpdatedContent {
t.Fatal("config error") t.Fatal("config error")
} }
} }
func TestExtToFormat(t *testing.T) { func TestExtToFormat(t *testing.T) {
name := "kratos-polaris-ext.yaml" name := "ext.yaml"
client, err := newConfigClient() client, err := newConfigClient()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_ = client.deleteConfigFile(name)
if err = client.createConfigFile(name); err != nil { if err = client.createConfigFile(name); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -284,24 +274,22 @@ func TestExtToFormat(t *testing.T) {
} }
// Always remember clear test resource // Always remember clear test resource
t.Cleanup(func() { defer func() {
if err = client.deleteConfigFile(name); err != nil { if err = client.deleteConfigFile(name); err != nil {
t.Fatal(err) t.Fatal(err)
} }
}) }()
sdk, err := polaris.NewSDKContextByAddress("127.0.0.1:8091") configAPI, err := polaris.NewConfigAPI()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
p := New(sdk)
cfg, err := p.Config(WithConfigFile(File{Name: name, Group: testFileGroup})) config, err := New(configAPI, WithNamespace(namespace), WithFileGroup(fileGroup), WithFileName(name))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
kv, err := config.Load()
kv, err := cfg.Load()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -311,76 +299,10 @@ func TestExtToFormat(t *testing.T) {
if !reflect.DeepEqual(name, kv[0].Key) { if !reflect.DeepEqual(name, kv[0].Key) {
t.Errorf("kvs[0].Key is %s", kv[0].Key) t.Errorf("kvs[0].Key is %s", kv[0].Key)
} }
if !reflect.DeepEqual(testOriginContent, string(kv[0].Value)) { if !reflect.DeepEqual(originContent, string(kv[0].Value)) {
t.Errorf("kvs[0].Value is %s", kv[0].Value) t.Errorf("kvs[0].Value is %s", kv[0].Value)
} }
if !reflect.DeepEqual("yaml", kv[0].Format) { if !reflect.DeepEqual("yaml", kv[0].Format) {
t.Errorf("kvs[0].Format is %s", kv[0].Format) t.Errorf("kvs[0].Format is %s", kv[0].Format)
} }
} }
func TestGetMultipleConfig(t *testing.T) {
client, err := newConfigClient()
files := make([]File, 0, 3)
for i := 0; i < 3; i++ {
name := fmt.Sprintf("kratos-polaris-test-%d.yaml", i)
if err != nil {
t.Fatal(err)
}
_ = client.deleteConfigFile(name)
if err = client.createConfigFile(name); err != nil {
t.Fatal(err)
}
if err = client.publishConfigFile(name); err != nil {
t.Fatal(err)
}
files = append(files, File{Name: name, Group: testFileGroup})
}
sdk, err := polaris.NewSDKContextByAddress("127.0.0.1:8091")
if err != nil {
t.Fatal(err)
}
p := New(sdk, WithNamespace("default"))
cfg, err := p.Config(WithConfigFile(files...))
if err != nil {
t.Fatal(err)
}
kvs, err := cfg.Load()
if err != nil {
t.Fatal(err)
}
for _, kv := range kvs {
t.Logf("key: %s, value: %s", kv.Key, kv.Value)
}
w, err := cfg.Watch()
if err != nil {
t.Fatal(err)
}
for _, file := range files {
if err = client.publishConfigFile(file.Name); err != nil {
t.Fatal(err)
}
kvs, err := w.Next()
if err != nil {
t.Fatal(err)
}
m := make(map[string]*config.KeyValue)
for _, kv := range kvs {
m[kv.Key] = kv
}
if !reflect.DeepEqual(file.Name, m[file.Name].Key) {
t.Errorf("m[file.Name].Key is %s", m[file.Name].Key)
}
if !reflect.DeepEqual(testOriginContent, string(m[file.Name].Value)) {
t.Errorf("m[file.Name].Value is %s", m[file.Name].Value)
}
if !reflect.DeepEqual("yaml", m[file.Name].Format) {
t.Errorf("m[file.Name].Format is %s", m[file.Name].Format)
}
}
}

@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/config/polaris/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.4.0
github.com/polarismesh/polaris-go v1.1.0 github.com/polarismesh/polaris-go v1.1.0
) )
@ -14,6 +14,10 @@ require (
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect go.uber.org/zap v1.21.0 // indirect
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b // indirect
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/encoding/msgpack/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
github.com/vmihailenco/msgpack/v5 v5.3.5 github.com/vmihailenco/msgpack/v5 v5.3.5
) )

File diff suppressed because it is too large Load Diff

@ -58,7 +58,7 @@ func TestWithAccessSecret(t *testing.T) {
} }
} }
func TestLogger(_ *testing.T) { func TestLogger(t *testing.T) {
project := "foo" project := "foo"
logger := NewAliyunLog(WithProject(project)) logger := NewAliyunLog(WithProject(project))
defer logger.Close() defer logger.Close()

@ -3,9 +3,9 @@ module github.com/go-kratos/kratos/contrib/log/aliyun/v2
go 1.16 go 1.16
require ( require (
github.com/aliyun/aliyun-log-go-sdk v0.1.44 github.com/aliyun/aliyun-log-go-sdk v0.1.40
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.28.1
) )
replace ( replace (

File diff suppressed because it is too large Load Diff

@ -5,7 +5,8 @@ go 1.16
require ( require (
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/fluent/fluent-logger-golang v1.9.0 github.com/fluent/fluent-logger-golang v1.9.0
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
github.com/kr/pretty v0.3.0 // indirect
github.com/tinylib/msgp v1.1.6 // indirect github.com/tinylib/msgp v1.1.6 // indirect
) )

File diff suppressed because it is too large Load Diff

@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/log/logrus/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
) )

File diff suppressed because it is too large Load Diff

@ -3,9 +3,9 @@ module github.com/go-kratos/kratos/contrib/log/tencent/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
github.com/tencentcloud/tencentcloud-cls-sdk-go v1.0.2 github.com/tencentcloud/tencentcloud-cls-sdk-go v1.0.2
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.28.0
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -103,7 +103,6 @@ func NewLogger(options ...Option) (Logger, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
producerInst.Start()
return &tencentLog{ return &tencentLog{
producer: producerInst, producer: producerInst,
opts: opts, opts: opts,

@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/log/zap/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
go.uber.org/zap v1.23.0 go.uber.org/zap v1.23.0
) )

File diff suppressed because it is too large Load Diff

@ -19,14 +19,13 @@ func NewLogger(zlog *zap.Logger) *Logger {
} }
func (l *Logger) Log(level log.Level, keyvals ...interface{}) error { func (l *Logger) Log(level log.Level, keyvals ...interface{}) error {
keylen := len(keyvals) if len(keyvals) == 0 || len(keyvals)%2 != 0 {
if keylen == 0 || keylen%2 != 0 {
l.log.Warn(fmt.Sprint("Keyvalues must appear in pairs: ", keyvals)) l.log.Warn(fmt.Sprint("Keyvalues must appear in pairs: ", keyvals))
return nil return nil
} }
data := make([]zap.Field, 0, (keylen/2)+1) var data []zap.Field
for i := 0; i < keylen; i += 2 { for i := 0; i < len(keyvals); i += 2 {
data = append(data, zap.Any(fmt.Sprint(keyvals[i]), keyvals[i+1])) data = append(data, zap.Any(fmt.Sprint(keyvals[i]), keyvals[i+1]))
} }

@ -39,8 +39,8 @@ func (d *gauge) Set(value float64) {
_ = d.opts.client.Gauge(d.name, value, d.lvs, d.opts.sampleRate) _ = d.opts.client.Gauge(d.name, value, d.lvs, d.opts.sampleRate)
} }
func (d *gauge) Add(_ float64) { func (d *gauge) Add(delta float64) {
} }
func (d *gauge) Sub(_ float64) { func (d *gauge) Sub(delta float64) {
} }

@ -4,9 +4,11 @@ go 1.16
require ( require (
github.com/DataDog/datadog-go v4.8.3+incompatible github.com/DataDog/datadog-go v4.8.3+incompatible
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
) )
require github.com/Microsoft/go-winio v0.5.2 // indirect require (
github.com/Microsoft/go-winio v0.5.2 // indirect
)
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -3,9 +3,9 @@ module github.com/go-kratos/kratos/contrib/metrics/prometheus/v2
go 1.16 go 1.16
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
github.com/prometheus/client_golang v1.15.1 github.com/prometheus/client_golang v1.13.1
github.com/prometheus/common v0.44.0 github.com/prometheus/common v0.37.0
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -3,25 +3,22 @@ module github.com/go-kratos/kratos/contrib/opensergo/v2
go 1.17 go 1.17
require ( require (
github.com/go-kratos/kratos/v2 v2.6.3 github.com/go-kratos/kratos/v2 v2.5.3
github.com/opensergo/opensergo-go v0.0.0-20220331070310-e5b01fee4d1c github.com/opensergo/opensergo-go v0.0.0-20220331070310-e5b01fee4d1c
golang.org/x/net v0.10.0 golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
google.golang.org/grpc v1.56.1 google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.28.1
) )
require ( require (
github.com/go-playground/form/v4 v4.2.0 // indirect github.com/go-playground/form/v4 v4.2.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/kr/text v0.2.0 // indirect golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.3.7 // indirect
golang.org/x/text v0.9.0 // indirect gopkg.in/yaml.v3 v3.0.0 // indirect
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )
replace github.com/go-kratos/kratos/v2 => ../../ replace github.com/go-kratos/kratos/v2 => ../../

File diff suppressed because it is too large Load Diff

@ -9,6 +9,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/go-kratos/kratos/v2"
v1 "github.com/opensergo/opensergo-go/proto/service_contract/v1" v1 "github.com/opensergo/opensergo-go/proto/service_contract/v1"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/genproto/googleapis/api/annotations" "google.golang.org/genproto/googleapis/api/annotations"
@ -17,8 +19,6 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
"github.com/go-kratos/kratos/v2"
) )
type Option func(*options) type Option func(*options)

@ -23,7 +23,7 @@ type testMetadataServiceServer struct {
srvContractPb.UnimplementedMetadataServiceServer srvContractPb.UnimplementedMetadataServiceServer
} }
func (m *testMetadataServiceServer) ReportMetadata(_ context.Context, _ *srvContractPb.ReportMetadataRequest) (*srvContractPb.ReportMetadataReply, error) { func (m *testMetadataServiceServer) ReportMetadata(ctx context.Context, req *srvContractPb.ReportMetadataRequest) (*srvContractPb.ReportMetadataReply, error) {
return &srvContractPb.ReportMetadataReply{}, nil return &srvContractPb.ReportMetadataReply{}, nil
} }

@ -1,119 +0,0 @@
package polaris
import (
"path/filepath"
"strings"
"github.com/polarismesh/polaris-go"
"github.com/polarismesh/polaris-go/pkg/model"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/log"
)
// ConfigOption is polaris config option.
type ConfigOption func(o *configOptions)
type configOptions struct {
namespace string
files []File
configFile []polaris.ConfigFile
}
// WithConfigFile with polaris config file
func WithConfigFile(file ...File) ConfigOption {
return func(o *configOptions) {
o.files = file
}
}
type File struct {
Name string
Group string
}
type source struct {
client polaris.ConfigAPI
options *configOptions
}
// Load return the config values
func (s *source) Load() ([]*config.KeyValue, error) {
kv := make([]*config.KeyValue, 0)
for _, file := range s.options.files {
configFile, err := s.client.GetConfigFile(s.options.namespace, file.Group, file.Name)
if err != nil {
return nil, err
}
s.options.configFile = append(s.options.configFile, configFile)
kv = append(kv, &config.KeyValue{
Key: file.Name,
Value: []byte(configFile.GetContent()),
Format: strings.TrimPrefix(filepath.Ext(file.Name), "."),
})
}
return kv, nil
}
// Watch return the watcher
func (s *source) Watch() (config.Watcher, error) {
return newConfigWatcher(s.options.configFile), nil
}
type ConfigWatcher struct {
event chan model.ConfigFileChangeEvent
cfg []*config.KeyValue
}
func receive(event chan model.ConfigFileChangeEvent) func(m model.ConfigFileChangeEvent) {
return func(m model.ConfigFileChangeEvent) {
defer func() {
if err := recover(); err != nil {
log.Error(err)
}
}()
event <- m
}
}
func newConfigWatcher(configFile []polaris.ConfigFile) *ConfigWatcher {
w := &ConfigWatcher{
event: make(chan model.ConfigFileChangeEvent, len(configFile)),
}
for _, file := range configFile {
w.cfg = append(w.cfg, &config.KeyValue{
Key: file.GetFileName(),
Value: []byte(file.GetContent()),
Format: strings.TrimPrefix(filepath.Ext(file.GetFileName()), "."),
})
}
for _, file := range configFile {
file.AddChangeListener(receive(w.event))
}
return w
}
func (w *ConfigWatcher) Next() ([]*config.KeyValue, error) {
if event, ok := <-w.event; ok {
m := make(map[string]*config.KeyValue)
for _, file := range w.cfg {
m[file.Key] = file
}
m[event.ConfigFileMetadata.GetFileName()] = &config.KeyValue{
Key: event.ConfigFileMetadata.GetFileName(),
Value: []byte(event.NewValue),
Format: strings.TrimPrefix(filepath.Ext(event.ConfigFileMetadata.GetFileName()), "."),
}
w.cfg = make([]*config.KeyValue, 0, len(m))
for _, kv := range m {
w.cfg = append(w.cfg, kv)
}
return w.cfg, nil
}
return w.cfg, nil
}
func (w *ConfigWatcher) Stop() error {
close(w.event)
return nil
}

@ -1,45 +0,0 @@
module github.com/go-kratos/kratos/contrib/polaris/v2
go 1.18
require (
github.com/go-kratos/aegis v0.2.0
github.com/go-kratos/kratos/v2 v2.6.3
github.com/google/uuid v1.3.0
github.com/polarismesh/polaris-go v1.3.0
google.golang.org/protobuf v1.31.0
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/go-playground/form/v4 v4.2.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/grpc v1.56.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/go-kratos/kratos/v2 => ../../

@ -1,593 +0,0 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
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/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ=
github.com/go-kratos/aegis v0.2.0/go.mod h1:v0R2m73WgEEYB3XYu6aE2WcMwsZkJ/Rzuf5eVccm7bI=
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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
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/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic=
github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
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/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
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/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2/go.mod h1:pDgmNM6seYpwvPos3q+zxlXMsbve6mOIPucUnUOrI7Y=
github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks=
github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A=
github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs=
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/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
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/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
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=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
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=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
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/konsorten/go-windows-terminal-sequences v1.0.3/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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
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/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/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
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/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polarismesh/polaris-go v1.3.0 h1:KZKX//ow4OPPoS5+s7h07ptprg+2AcNVGrN6WakC9QM=
github.com/polarismesh/polaris-go v1.3.0/go.mod h1:HsN0ierETIujHpmnnYJ3qkwQw4QGAECuHvBZTDaw1tI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
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=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
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/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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/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.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
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-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
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/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao=
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
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.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ=
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/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=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
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/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

@ -1,105 +0,0 @@
package polaris
import (
"time"
"github.com/go-kratos/aegis/ratelimit"
"github.com/polarismesh/polaris-go"
"github.com/polarismesh/polaris-go/pkg/model"
)
type (
// LimiterOption function for polaris limiter
LimiterOption func(*limiterOptions)
)
type limiterOptions struct {
// required, polaris limit namespace
namespace string
// required, polaris limit service name
service string
// optional, polaris limit request timeout
// max value is (1+RetryCount) * Timeout
timeout time.Duration
// optional, polaris limit retryCount
// init by polaris config
retryCount int
// optional, request limit quota
token uint32
}
// WithLimiterNamespace with limiter namespace.
func WithLimiterNamespace(namespace string) LimiterOption {
return func(o *limiterOptions) {
o.namespace = namespace
}
}
// WithLimiterService with limiter service.
func WithLimiterService(service string) LimiterOption {
return func(o *limiterOptions) {
o.service = service
}
}
// WithLimiterTimeout with limiter arguments.
func WithLimiterTimeout(timeout time.Duration) LimiterOption {
return func(o *limiterOptions) {
o.timeout = timeout
}
}
// WithLimiterRetryCount with limiter retryCount.
func WithLimiterRetryCount(retryCount int) LimiterOption {
return func(o *limiterOptions) {
o.retryCount = retryCount
}
}
// WithLimiterToken with limiter token.
func WithLimiterToken(token uint32) LimiterOption {
return func(o *limiterOptions) {
o.token = token
}
}
type Limiter struct {
// polaris limit api
limitAPI polaris.LimitAPI
opts limiterOptions
}
// init quotaRequest
func buildRequest(opts limiterOptions) polaris.QuotaRequest {
quotaRequest := polaris.NewQuotaRequest()
quotaRequest.SetNamespace(opts.namespace)
quotaRequest.SetRetryCount(opts.retryCount)
quotaRequest.SetService(opts.service)
quotaRequest.SetTimeout(opts.timeout)
quotaRequest.SetToken(opts.token)
return quotaRequest
}
// Allow interface impl
func (l *Limiter) Allow(method string, argument ...model.Argument) (ratelimit.DoneFunc, error) {
request := buildRequest(l.opts)
request.SetMethod(method)
for _, arg := range argument {
request.AddArgument(arg)
}
resp, err := l.limitAPI.GetQuota(request)
if err != nil {
// ignore err
return func(ratelimit.DoneInfo) {}, nil
}
if resp.Get().Code == model.QuotaResultOk {
return func(ratelimit.DoneInfo) {}, nil
}
return nil, ratelimit.ErrLimitExceed
}

@ -1,101 +0,0 @@
package polaris
import (
"errors"
"github.com/polarismesh/polaris-go"
"github.com/polarismesh/polaris-go/api"
"github.com/go-kratos/kratos/v2/config"
)
type Polaris struct {
router polaris.RouterAPI
config polaris.ConfigAPI
limit polaris.LimitAPI
registry polaris.ProviderAPI
discovery polaris.ConsumerAPI
namespace string
service string
}
// Option is polaris option.
type Option func(o *Polaris)
// WithNamespace with polaris global testNamespace
func WithNamespace(ns string) Option {
return func(o *Polaris) {
o.namespace = ns
}
}
// WithService set the current service name
func WithService(service string) Option {
return func(o *Polaris) {
o.service = service
}
}
// New polaris Service governance.
func New(sdk api.SDKContext, opts ...Option) Polaris {
op := Polaris{
router: polaris.NewRouterAPIByContext(sdk),
config: polaris.NewConfigAPIByContext(sdk),
limit: polaris.NewLimitAPIByContext(sdk),
registry: polaris.NewProviderAPIByContext(sdk),
discovery: polaris.NewConsumerAPIByContext(sdk),
namespace: "default",
}
for _, option := range opts {
option(&op)
}
return op
}
func (p *Polaris) Config(opts ...ConfigOption) (config.Source, error) {
options := &configOptions{
namespace: p.namespace,
}
for _, opt := range opts {
opt(options)
}
if len(options.files) == 0 {
return nil, errors.New("fileNames invalid")
}
return &source{
client: p.config,
options: options,
}, nil
}
func (p *Polaris) Registry(opts ...RegistryOption) (r *Registry) {
op := registryOptions{
Namespace: p.namespace,
Healthy: true,
}
for _, option := range opts {
option(&op)
}
return &Registry{
opt: op,
provider: p.registry,
consumer: p.discovery,
}
}
func (p *Polaris) Limiter(opts ...LimiterOption) (r Limiter) {
op := limiterOptions{
namespace: p.namespace,
service: p.service,
}
for _, option := range opts {
option(&op)
}
return Limiter{
limitAPI: p.limit,
opts: op,
}
}

@ -1,53 +0,0 @@
package polaris
import (
"context"
"strings"
"github.com/go-kratos/aegis/ratelimit"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
"github.com/go-kratos/kratos/v2/transport/http"
"github.com/polarismesh/polaris-go/pkg/model"
)
// ErrLimitExceed is service unavailable due to rate limit exceeded.
var (
ErrLimitExceed = errors.New(429, "RATELIMIT", "service unavailable due to rate limit exceeded")
)
// Ratelimit Request rate limit middleware
func Ratelimit(l Limiter) middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
if tr, ok := transport.FromServerContext(ctx); ok {
var args []model.Argument
headers := tr.RequestHeader()
// handle header
for _, header := range headers.Keys() {
args = append(args, model.BuildHeaderArgument(header, headers.Get(header)))
}
// handle http
if ht, ok := tr.(*http.Transport); ok {
// url query
for key, values := range ht.Request().URL.Query() {
args = append(args, model.BuildQueryArgument(key, strings.Join(values, ",")))
}
}
done, e := l.Allow(tr.Operation(), args...)
if e != nil {
// rejected
return nil, ErrLimitExceed
}
// allowed
reply, err = handler(ctx, req)
done(ratelimit.DoneInfo{Err: err})
return
}
return reply, nil
}
}
}

@ -1,380 +0,0 @@
package polaris
import (
"context"
"fmt"
"net"
"net/url"
"strconv"
"time"
"github.com/google/uuid"
"github.com/polarismesh/polaris-go"
"github.com/polarismesh/polaris-go/pkg/model"
"github.com/go-kratos/kratos/v2/registry"
)
var (
_ registry.Registrar = (*Registry)(nil)
_ registry.Discovery = (*Registry)(nil)
)
type registryOptions struct {
// required, testNamespace in polaris
Namespace string
// required, service access token
ServiceToken string
// service weight in polaris. Default value is 100, 0 <= weight <= 10000
Weight int
// service priority. Default value is 0. The smaller the value, the lower the priority
Priority int
// To show service is healthy or not. Default value is True .
Healthy bool
// To show service is isolate or not. Default value is False .
Isolate bool
// TTL timeout. if node needs to use heartbeat to report,required. If not set,server will throw ErrorCode-400141
TTL int
// optional, Timeout for single query. Default value is global config
// Total is (1+RetryCount) * Timeout
Timeout time.Duration
// optional, retry count. Default value is global config
RetryCount int
}
// RegistryOption is polaris option.
type RegistryOption func(o *registryOptions)
// Registry is polaris registry.
type Registry struct {
opt registryOptions
provider polaris.ProviderAPI
consumer polaris.ConsumerAPI
}
// WithRegistryServiceToken with ServiceToken option.
func WithRegistryServiceToken(serviceToken string) RegistryOption {
return func(o *registryOptions) { o.ServiceToken = serviceToken }
}
// WithRegistryWeight with Weight option.
func WithRegistryWeight(weight int) RegistryOption {
return func(o *registryOptions) { o.Weight = weight }
}
// WithRegistryHealthy with Healthy option.
func WithRegistryHealthy(healthy bool) RegistryOption {
return func(o *registryOptions) { o.Healthy = healthy }
}
// WithRegistryIsolate with Isolate option.
func WithRegistryIsolate(isolate bool) RegistryOption {
return func(o *registryOptions) { o.Isolate = isolate }
}
// WithRegistryTTL with TTL option.
func WithRegistryTTL(TTL int) RegistryOption {
return func(o *registryOptions) { o.TTL = TTL }
}
// WithRegistryTimeout with Timeout option.
func WithRegistryTimeout(timeout time.Duration) RegistryOption {
return func(o *registryOptions) { o.Timeout = timeout }
}
// WithRegistryRetryCount with RetryCount option.
func WithRegistryRetryCount(retryCount int) RegistryOption {
return func(o *registryOptions) { o.RetryCount = retryCount }
}
// Register the registration.
func (r *Registry) Register(_ context.Context, instance *registry.ServiceInstance) error {
id := uuid.NewString()
for _, endpoint := range instance.Endpoints {
u, err := url.Parse(endpoint)
if err != nil {
return err
}
host, port, err := net.SplitHostPort(u.Host)
if err != nil {
return err
}
portNum, err := strconv.Atoi(port)
if err != nil {
return err
}
// metadata
if instance.Metadata == nil {
instance.Metadata = make(map[string]string)
}
instance.Metadata["merge"] = id
if _, ok := instance.Metadata["weight"]; !ok {
instance.Metadata["weight"] = strconv.Itoa(r.opt.Weight)
}
weight, _ := strconv.Atoi(instance.Metadata["weight"])
_, err = r.provider.RegisterInstance(
&polaris.InstanceRegisterRequest{
InstanceRegisterRequest: model.InstanceRegisterRequest{
Service: instance.Name,
ServiceToken: r.opt.ServiceToken,
Namespace: r.opt.Namespace,
Host: host,
Port: portNum,
Protocol: &u.Scheme,
Weight: &weight,
Priority: &r.opt.Priority,
Version: &instance.Version,
Metadata: instance.Metadata,
Healthy: &r.opt.Healthy,
Isolate: &r.opt.Isolate,
TTL: &r.opt.TTL,
Timeout: &r.opt.Timeout,
RetryCount: &r.opt.RetryCount,
},
},
)
if err != nil {
return err
}
}
return nil
}
// Deregister the registration.
func (r *Registry) Deregister(_ context.Context, serviceInstance *registry.ServiceInstance) error {
for _, endpoint := range serviceInstance.Endpoints {
// get url
u, err := url.Parse(endpoint)
if err != nil {
return err
}
// get host and port
host, port, err := net.SplitHostPort(u.Host)
if err != nil {
return err
}
// port to int
portNum, err := strconv.Atoi(port)
if err != nil {
return err
}
// Deregister
err = r.provider.Deregister(
&polaris.InstanceDeRegisterRequest{
InstanceDeRegisterRequest: model.InstanceDeRegisterRequest{
Service: serviceInstance.Name,
ServiceToken: r.opt.ServiceToken,
Namespace: r.opt.Namespace,
Host: host,
Port: portNum,
Timeout: &r.opt.Timeout,
RetryCount: &r.opt.RetryCount,
},
},
)
if err != nil {
return err
}
}
return nil
}
// GetService return the service instances in memory according to the service name.
func (r *Registry) GetService(_ context.Context, serviceName string) ([]*registry.ServiceInstance, error) {
// get all instances
instancesResponse, err := r.consumer.GetInstances(&polaris.GetInstancesRequest{
GetInstancesRequest: model.GetInstancesRequest{
Service: serviceName,
Namespace: r.opt.Namespace,
Timeout: &r.opt.Timeout,
RetryCount: &r.opt.RetryCount,
SkipRouteFilter: true,
},
})
if err != nil {
return nil, err
}
serviceInstances := instancesToServiceInstances(merge(instancesResponse.GetInstances()))
return serviceInstances, nil
}
func merge(instances []model.Instance) map[string][]model.Instance {
m := make(map[string][]model.Instance)
for _, instance := range instances {
if v, ok := m[instance.GetMetadata()["merge"]]; ok {
m[instance.GetMetadata()["merge"]] = append(v, instance)
} else {
m[instance.GetMetadata()["merge"]] = []model.Instance{instance}
}
}
return m
}
// Watch creates a watcher according to the service name.
func (r *Registry) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) {
return newWatcher(ctx, r.opt.Namespace, serviceName, r.consumer)
}
type Watcher struct {
ServiceName string
Namespace string
Ctx context.Context
Cancel context.CancelFunc
Channel <-chan model.SubScribeEvent
service *model.InstancesResponse
ServiceInstances map[string][]model.Instance
first bool
}
func newWatcher(ctx context.Context, namespace string, serviceName string, consumer polaris.ConsumerAPI) (*Watcher, error) {
watchServiceResponse, err := consumer.WatchService(&polaris.WatchServiceRequest{
WatchServiceRequest: model.WatchServiceRequest{
Key: model.ServiceKey{
Namespace: namespace,
Service: serviceName,
},
},
})
if err != nil {
return nil, err
}
w := &Watcher{
Namespace: namespace,
ServiceName: serviceName,
Channel: watchServiceResponse.EventChannel,
service: watchServiceResponse.GetAllInstancesResp,
ServiceInstances: merge(watchServiceResponse.GetAllInstancesResp.GetInstances()),
}
w.Ctx, w.Cancel = context.WithCancel(ctx)
return w, nil
}
// Next returns services in the following two cases:
// 1.the first time to watch and the service instance list is not empty.
// 2.any service instance changes found.
// if the above two conditions are not met, it will block until context deadline exceeded or canceled
func (w *Watcher) Next() ([]*registry.ServiceInstance, error) {
if !w.first {
w.first = true
if len(w.ServiceInstances) > 0 {
return instancesToServiceInstances(w.ServiceInstances), nil
}
}
select {
case <-w.Ctx.Done():
return nil, w.Ctx.Err()
case event := <-w.Channel:
if event.GetSubScribeEventType() == model.EventInstance {
// this always true, but we need to check it to make sure EventType not change
if instanceEvent, ok := event.(*model.InstanceEvent); ok {
// handle DeleteEvent
if instanceEvent.DeleteEvent != nil {
for _, instance := range instanceEvent.DeleteEvent.Instances {
delete(w.ServiceInstances, instance.GetMetadata()["merge"])
}
}
// handle UpdateEvent
if instanceEvent.UpdateEvent != nil {
for _, update := range instanceEvent.UpdateEvent.UpdateList {
if v, ok := w.ServiceInstances[update.After.GetMetadata()["merge"]]; ok {
var nv []model.Instance
m := map[string]model.Instance{}
for _, ins := range v {
m[ins.GetId()] = ins
}
m[update.After.GetId()] = update.After
for _, ins := range m {
if ins.IsHealthy() {
nv = append(nv, ins)
}
}
w.ServiceInstances[update.After.GetMetadata()["merge"]] = nv
if len(nv) == 0 {
delete(w.ServiceInstances, update.After.GetMetadata()["merge"])
}
} else {
if update.After.IsHealthy() {
w.ServiceInstances[update.After.GetMetadata()["merge"]] = []model.Instance{update.After}
}
}
}
}
// handle AddEvent
if instanceEvent.AddEvent != nil {
for _, instance := range instanceEvent.AddEvent.Instances {
if v, ok := w.ServiceInstances[instance.GetMetadata()["merge"]]; ok {
var nv []model.Instance
m := map[string]model.Instance{}
for _, ins := range v {
m[ins.GetId()] = ins
}
m[instance.GetId()] = instance
for _, ins := range m {
if ins.IsHealthy() {
nv = append(nv, ins)
}
}
if len(nv) != 0 {
w.ServiceInstances[instance.GetMetadata()["merge"]] = nv
}
} else {
if instance.IsHealthy() {
w.ServiceInstances[instance.GetMetadata()["merge"]] = []model.Instance{instance}
}
}
}
}
}
return instancesToServiceInstances(w.ServiceInstances), nil
}
}
return instancesToServiceInstances(w.ServiceInstances), nil
}
// Stop close the watcher.
func (w *Watcher) Stop() error {
w.Cancel()
return nil
}
func instancesToServiceInstances(instances map[string][]model.Instance) []*registry.ServiceInstance {
serviceInstances := make([]*registry.ServiceInstance, 0, len(instances))
for _, inss := range instances {
if len(inss) == 0 {
continue
}
ins := &registry.ServiceInstance{
ID: inss[0].GetId(),
Name: inss[0].GetService(),
Version: inss[0].GetVersion(),
Metadata: inss[0].GetMetadata(),
}
for _, item := range inss {
if item.IsHealthy() {
ins.Endpoints = append(ins.Endpoints, fmt.Sprintf("%s://%s:%d", item.GetProtocol(), item.GetHost(), item.GetPort()))
}
}
if len(ins.Endpoints) != 0 {
serviceInstances = append(serviceInstances, ins)
}
}
return serviceInstances
}

@ -1,58 +0,0 @@
package polaris
import (
"context"
"testing"
"time"
"github.com/polarismesh/polaris-go"
"github.com/go-kratos/kratos/v2/registry"
)
// TestRegistry
func TestRegistry(t *testing.T) {
sdk, err := polaris.NewSDKContextByAddress("127.0.0.1:8091")
if err != nil {
t.Fatal(err)
}
p := New(sdk)
r := p.Registry(
WithRegistryTimeout(time.Second),
WithRegistryHealthy(true),
WithRegistryIsolate(false),
WithRegistryRetryCount(3),
WithRegistryWeight(100),
WithRegistryTTL(1000),
)
ins := &registry.ServiceInstance{
ID: "test-ut",
Name: "test-ut",
Version: "v1.0.0",
Endpoints: []string{
"grpc://127.0.0.1:8080",
"http://127.0.0.1:9090",
},
}
err = r.Register(context.Background(), ins)
t.Cleanup(func() {
if err = r.Deregister(context.Background(), ins); err != nil {
t.Fatal(err)
}
})
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second * 3)
service, err := r.GetService(context.Background(), "test-ut")
if err != nil {
t.Fatal(err)
}
t.Log(service)
}

@ -1,144 +0,0 @@
package polaris
import (
"context"
"fmt"
"net"
"strconv"
"strings"
"github.com/polarismesh/polaris-go"
"github.com/polarismesh/polaris-go/pkg/model"
"github.com/polarismesh/polaris-go/pkg/model/local"
"github.com/polarismesh/polaris-go/pkg/model/pb"
v1 "github.com/polarismesh/polaris-go/pkg/model/pb/v1"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/selector"
"github.com/go-kratos/kratos/v2/transport"
"github.com/go-kratos/kratos/v2/transport/http"
)
type router struct {
service string
}
type RouterOption func(o *router)
// WithRouterService set the caller service name used by the route
func WithRouterService(service string) RouterOption {
return func(o *router) {
o.service = service
}
}
// NodeFilter polaris dynamic router selector
func (p *Polaris) NodeFilter(opts ...RouterOption) selector.NodeFilter {
o := router{service: p.service}
for _, opt := range opts {
opt(&o)
}
return func(ctx context.Context, nodes []selector.Node) []selector.Node {
if len(nodes) == 0 {
return nodes
}
req := &polaris.ProcessRoutersRequest{
ProcessRoutersRequest: model.ProcessRoutersRequest{
SourceService: model.ServiceInfo{Namespace: p.namespace, Service: o.service},
DstInstances: buildPolarisInstance(p.namespace, nodes),
},
}
if appInfo, ok := kratos.FromContext(ctx); ok {
req.SourceService.Service = appInfo.Name()
}
req.AddArguments(model.BuildCallerServiceArgument(p.namespace, req.ProcessRoutersRequest.SourceService.Service))
// process transport
if tr, ok := transport.FromClientContext(ctx); ok {
req.AddArguments(model.BuildMethodArgument(tr.Operation()))
req.AddArguments(model.BuildPathArgument(tr.Operation()))
for _, key := range tr.RequestHeader().Keys() {
req.AddArguments(model.BuildHeaderArgument(strings.ToLower(key), tr.RequestHeader().Get(key)))
}
// http
if ht, ok := tr.(http.Transporter); ok {
req.AddArguments(model.BuildPathArgument(ht.Request().URL.Path))
req.AddArguments(model.BuildCallerIPArgument(ht.Request().RemoteAddr))
// cookie
for _, cookie := range ht.Request().Cookies() {
req.AddArguments(model.BuildCookieArgument(cookie.Name, cookie.Value))
}
// url query
for key, values := range ht.Request().URL.Query() {
req.AddArguments(model.BuildQueryArgument(key, strings.Join(values, ",")))
}
}
}
n := make(map[string]selector.Node, len(nodes))
for _, node := range nodes {
n[node.Address()] = node
}
m, err := p.router.ProcessRouters(req)
if err != nil {
log.Errorf("polaris process routers failed, err=%v", err)
return nodes
}
newNode := make([]selector.Node, 0, len(m.Instances))
for _, ins := range m.GetInstances() {
if v, ok := n[fmt.Sprintf("%s:%d", ins.GetHost(), ins.GetPort())]; ok {
newNode = append(newNode, v)
}
}
if len(newNode) == 0 {
return nodes
}
return newNode
}
}
func buildPolarisInstance(namespace string, nodes []selector.Node) *pb.ServiceInstancesInProto {
ins := make([]*v1.Instance, 0, len(nodes))
for _, node := range nodes {
host, port, err := net.SplitHostPort(node.Address())
if err != nil {
return nil
}
portInt, err := strconv.Atoi(port)
if err != nil {
return nil
}
ins = append(ins, &v1.Instance{
Id: wrapperspb.String(node.Metadata()["merge"]),
Service: wrapperspb.String(node.ServiceName()),
Namespace: wrapperspb.String(namespace),
Host: wrapperspb.String(host),
Port: wrapperspb.UInt32(uint32(portInt)),
Protocol: wrapperspb.String(node.Scheme()),
Version: wrapperspb.String(node.Version()),
Weight: wrapperspb.UInt32(uint32(*node.InitialWeight())),
Metadata: node.Metadata(),
})
}
d := &v1.DiscoverResponse{
Code: wrapperspb.UInt32(1),
Info: wrapperspb.String("ok"),
Type: v1.DiscoverResponse_INSTANCE,
Service: &v1.Service{Name: wrapperspb.String(nodes[0].ServiceName()), Namespace: wrapperspb.String("default")},
Instances: ins,
}
return pb.NewServiceInstancesInProto(d, func(s string) local.InstanceLocalValue {
return local.NewInstanceLocalValue()
}, &pb.SvcPluginValues{Routers: nil, Loadbalancer: nil}, nil)
}

@ -1,206 +0,0 @@
package polaris
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"time"
"github.com/polarismesh/polaris-go"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/registry"
"github.com/go-kratos/kratos/v2/selector"
)
func TestRouter(t *testing.T) {
token, err := getToken("http://127.0.0.1:8090")
if err != nil {
t.Fatal(err)
}
data := `
[
{
"name":"kratos",
"enable":false,
"description":"123",
"priority":2,
"routing_config":{
"@type":"type.googleapis.com/v2.RuleRoutingConfig",
"sources":[
{
"service":"*",
"namespace":"*",
"arguments":[
]
}
],
"destinations":[
{
"labels":{
"az":{
"value":"1",
"value_type":"TEXT",
"type":"EXACT"
}
},
"weight":100,
"priority":1,
"isolate":false,
"name":"实例分组1",
"namespace":"default",
"service":"test-ut"
}
]
}
}
]
`
res, err := makeJSONRequest("http://127.0.0.1:8090/naming/v2/routings", data, http.MethodPost, map[string]string{
"X-Polaris-Token": token,
})
if err != nil {
t.Fatal(err)
}
resJSON := struct {
Code int `json:"code"`
Responses []struct {
Data struct {
ID string `json:"id"`
}
} `json:"responses"`
}{}
err = json.Unmarshal(res, &resJSON)
if err != nil {
t.Fatal(err, string(res))
}
if resJSON.Code != 200000 {
t.Fatal("create failed", string(res))
}
// enable router
enableData := fmt.Sprintf(`[{"id":"%s","enable":true}]`, resJSON.Responses[0].Data.ID)
res, err = makeJSONRequest("http://127.0.0.1:8090/naming/v2/routings/enable", enableData, http.MethodPut, map[string]string{
"X-Polaris-Token": token,
})
if err != nil {
t.Fatal(err)
}
err = json.Unmarshal(res, &resJSON)
if err != nil {
t.Fatal(err)
}
if resJSON.Code != 200000 {
t.Fatal("enable failed", string(res))
}
t.Cleanup(func() {
enableData := fmt.Sprintf(`[{"id":"%s"}]`, resJSON.Responses[0].Data.ID)
res, err = makeJSONRequest("http://127.0.0.1:8090/naming/v2/routings/delete", enableData, http.MethodPost, map[string]string{
"X-Polaris-Token": token,
})
resJSON := &commonRes{}
err = json.Unmarshal(res, resJSON)
if err != nil {
t.Fatal(err, string(res))
}
if resJSON.Code != 200000 {
t.Fatal("delete failed", string(res))
}
})
sdk, err := polaris.NewSDKContextByAddress("127.0.0.1:8091")
if err != nil {
t.Fatal(err)
}
p := New(sdk)
r := p.Registry(
WithRegistryTimeout(time.Second),
WithRegistryHealthy(true),
WithRegistryIsolate(false),
WithRegistryRetryCount(0),
WithRegistryWeight(100),
WithRegistryTTL(10),
)
ins := &registry.ServiceInstance{
ID: "kratos",
Name: "kratos",
Version: "v1.0.0",
Endpoints: []string{
"grpc://127.0.0.1:8080",
"http://127.0.0.1:9090",
},
}
err = r.Register(context.Background(), ins)
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second * 5)
nodes := []selector.Node{
selector.NewNode("grpc", "127.0.0.1:9000", &registry.ServiceInstance{
ID: "123",
Name: "test-ut",
Version: "v1.0.0",
Metadata: map[string]string{"weight": "100", "az": "1"},
Endpoints: []string{"grpc://127.0.0.1:9000"},
}),
selector.NewNode("grpc", "127.0.0.2:9000", &registry.ServiceInstance{
ID: "123",
Name: "test-ut",
Version: "v1.0.0",
Metadata: map[string]string{"weight": "100", "az": "2"},
Endpoints: []string{"grpc://127.0.0.2:9000"},
}),
selector.NewNode("grpc", "127.0.0.3:9000", &registry.ServiceInstance{
ID: "123",
Name: "test-ut",
Version: "v1.0.0",
Metadata: map[string]string{"weight": "100", "az": "1"},
Endpoints: []string{"grpc://127.0.0.3:9000"},
}),
}
f := p.NodeFilter()
ctx := kratos.NewContext(context.Background(), &mockApp{})
n := f(ctx, nodes)
for _, node := range n {
if node.Metadata()["az"] != "1" {
t.Fatal("node filter result wrong")
}
t.Log(node)
}
if len(n) != 2 {
t.Fatal("node filter result wrong")
}
}
type mockApp struct{}
func (m mockApp) ID() string {
return "1"
}
func (m mockApp) Name() string {
return "kratos"
}
func (m mockApp) Version() string {
return "v2.0.0"
}
func (m mockApp) Metadata() map[string]string {
return map[string]string{}
}
func (m mockApp) Endpoint() []string {
return []string{"grpc://123.123.123.123:9090"}
}

@ -2,9 +2,7 @@ package consul
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"math/rand"
"net" "net"
"net/url" "net/url"
"strconv" "strconv"
@ -17,16 +15,8 @@ import (
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
) )
type Datacenter string
const (
SingleDatacenter Datacenter = "SINGLE"
MultiDatacenter Datacenter = "MULTI"
)
// Client is consul client config // Client is consul client config
type Client struct { type Client struct {
dc Datacenter
cli *api.Client cli *api.Client
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
@ -43,6 +33,19 @@ type Client struct {
serviceChecks api.AgentServiceChecks serviceChecks api.AgentServiceChecks
} }
// NewClient creates consul client
func NewClient(cli *api.Client) *Client {
c := &Client{
cli: cli,
resolver: defaultResolver,
healthcheckInterval: 10,
heartbeat: true,
deregisterCriticalServiceAfter: 600,
}
c.ctx, c.cancel = context.WithCancel(context.Background())
return c
}
func defaultResolver(_ context.Context, entries []*api.ServiceEntry) []*registry.ServiceInstance { func defaultResolver(_ context.Context, entries []*api.ServiceEntry) []*registry.ServiceInstance {
services := make([]*registry.ServiceInstance, 0, len(entries)) services := make([]*registry.ServiceInstance, 0, len(entries))
for _, entry := range entries { for _, entry := range entries {
@ -80,68 +83,18 @@ type ServiceResolver func(ctx context.Context, entries []*api.ServiceEntry) []*r
// Service get services from consul // Service get services from consul
func (c *Client) Service(ctx context.Context, service string, index uint64, passingOnly bool) ([]*registry.ServiceInstance, uint64, error) { func (c *Client) Service(ctx context.Context, service string, index uint64, passingOnly bool) ([]*registry.ServiceInstance, uint64, error) {
if c.dc == MultiDatacenter {
return c.multiDCService(ctx, service, index, passingOnly)
}
opts := &api.QueryOptions{ opts := &api.QueryOptions{
WaitIndex: index, WaitIndex: index,
WaitTime: time.Second * 55, WaitTime: time.Second * 55,
Datacenter: string(c.dc),
} }
opts = opts.WithContext(ctx) opts = opts.WithContext(ctx)
entries, meta, err := c.cli.Health().Service(service, "", passingOnly, opts)
if c.dc == SingleDatacenter {
opts.Datacenter = ""
}
entries, meta, err := c.singleDCEntries(service, "", passingOnly, opts)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
return c.resolver(ctx, entries), meta.LastIndex, nil return c.resolver(ctx, entries), meta.LastIndex, nil
} }
func (c *Client) multiDCService(ctx context.Context, service string, index uint64, passingOnly bool) ([]*registry.ServiceInstance, uint64, error) {
opts := &api.QueryOptions{
WaitIndex: index,
WaitTime: time.Second * 55,
}
opts = opts.WithContext(ctx)
var instances []*registry.ServiceInstance
dcs, err := c.cli.Catalog().Datacenters()
if err != nil {
return nil, 0, err
}
for _, dc := range dcs {
opts.Datacenter = dc
e, m, err := c.singleDCEntries(service, "", passingOnly, opts)
if err != nil {
return nil, 0, err
}
ins := c.resolver(ctx, e)
for _, in := range ins {
if in.Metadata == nil {
in.Metadata = make(map[string]string, 1)
}
in.Metadata["dc"] = dc
}
instances = append(instances, ins...)
opts.WaitIndex = m.LastIndex
}
return instances, opts.WaitIndex, nil
}
func (c *Client) singleDCEntries(service, tag string, passingOnly bool, opts *api.QueryOptions) ([]*api.ServiceEntry, *api.QueryMeta, error) {
return c.cli.Health().Service(service, tag, passingOnly, opts)
}
// Register register service instance to consul // Register register service instance to consul
func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enableHealthCheck bool) error { func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enableHealthCheck bool) error {
addresses := make(map[string]api.ServiceAddress, len(svc.Endpoints)) addresses := make(map[string]api.ServiceAddress, len(svc.Endpoints))
@ -205,32 +158,13 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
defer ticker.Stop() defer ticker.Stop()
for { for {
select { select {
case <-c.ctx.Done():
_ = c.cli.Agent().ServiceDeregister(svc.ID)
return
default:
}
select {
case <-c.ctx.Done():
_ = c.cli.Agent().ServiceDeregister(svc.ID)
return
case <-ticker.C: case <-ticker.C:
// ensure that unregistered services will not be re-registered by mistake
if errors.Is(c.ctx.Err(), context.Canceled) || errors.Is(c.ctx.Err(), context.DeadlineExceeded) {
_ = c.cli.Agent().ServiceDeregister(svc.ID)
return
}
err = c.cli.Agent().UpdateTTL("service:"+svc.ID, "pass", "pass") err = c.cli.Agent().UpdateTTL("service:"+svc.ID, "pass", "pass")
if err != nil { if err != nil {
log.Errorf("[Consul] update ttl heartbeat to consul failed! err=%v", err) log.Errorf("[Consul]update ttl heartbeat to consul failed!err:=%v", err)
// when the previous report fails, try to re register the service
time.Sleep(time.Duration(rand.Intn(5)) * time.Second)
if err := c.cli.Agent().ServiceRegister(asr); err != nil {
log.Errorf("[Consul] re registry service failed!, err=%v", err)
} else {
log.Warn("[Consul] re registry of service occurred success")
}
} }
case <-c.ctx.Done():
return
} }
} }
}() }()
@ -240,6 +174,6 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
// Deregister service by service ID // Deregister service by service ID
func (c *Client) Deregister(_ context.Context, serviceID string) error { func (c *Client) Deregister(_ context.Context, serviceID string) error {
defer c.cancel() c.cancel()
return c.cli.Agent().ServiceDeregister(serviceID) return c.cli.Agent().ServiceDeregister(serviceID)
} }

@ -3,13 +3,8 @@ module github.com/go-kratos/kratos/contrib/registry/consul/v2
go 1.16 go 1.16
require ( require (
github.com/armon/go-metrics v0.3.10 // indirect github.com/go-kratos/kratos/v2 v2.5.3
github.com/go-kratos/kratos/v2 v2.6.3 github.com/hashicorp/consul/api v1.15.3
github.com/hashicorp/consul/api v1.20.0
github.com/hashicorp/go-hclog v0.14.1 // indirect
github.com/hashicorp/go-immutable-radix v1.3.0 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
) )
replace github.com/go-kratos/kratos/v2 => ../../../ replace github.com/go-kratos/kratos/v2 => ../../../

File diff suppressed because it is too large Load Diff

@ -27,20 +27,6 @@ func WithHealthCheck(enable bool) Option {
} }
} }
// WithTimeout with get services timeout option.
func WithTimeout(timeout time.Duration) Option {
return func(o *Registry) {
o.timeout = timeout
}
}
// WithDatacenter with registry datacenter option
func WithDatacenter(dc Datacenter) Option {
return func(o *Registry) {
o.cli.dc = dc
}
}
// WithHeartbeat enable or disable heartbeat // WithHeartbeat enable or disable heartbeat
func WithHeartbeat(enable bool) Option { func WithHeartbeat(enable bool) Option {
return func(o *Registry) { return func(o *Registry) {
@ -97,28 +83,18 @@ type Registry struct {
enableHealthCheck bool enableHealthCheck bool
registry map[string]*serviceSet registry map[string]*serviceSet
lock sync.RWMutex lock sync.RWMutex
timeout time.Duration
} }
// New creates consul registry // New creates consul registry
func New(apiClient *api.Client, opts ...Option) *Registry { func New(apiClient *api.Client, opts ...Option) *Registry {
r := &Registry{ r := &Registry{
cli: NewClient(apiClient),
registry: make(map[string]*serviceSet), registry: make(map[string]*serviceSet),
enableHealthCheck: true, enableHealthCheck: true,
timeout: 10 * time.Second,
cli: &Client{
dc: SingleDatacenter,
cli: apiClient,
resolver: defaultResolver,
healthcheckInterval: 10,
heartbeat: true,
deregisterCriticalServiceAfter: 600,
},
} }
for _, o := range opts { for _, o := range opts {
o(r) o(r)
} }
r.cli.ctx, r.cli.cancel = context.WithCancel(context.Background())
return r return r
} }
@ -193,11 +169,11 @@ func (r *Registry) Watch(ctx context.Context, name string) (registry.Watcher, er
r.registry[name] = set r.registry[name] = set
} }
// init watcher // 初始化watcher
w := &watcher{ w := &watcher{
event: make(chan struct{}, 1), event: make(chan struct{}, 1),
} }
w.ctx, w.cancel = context.WithCancel(ctx) w.ctx, w.cancel = context.WithCancel(context.Background())
w.set = set w.set = set
set.lock.Lock() set.lock.Lock()
set.watcher[w] = struct{}{} set.watcher[w] = struct{}{}
@ -210,7 +186,7 @@ func (r *Registry) Watch(ctx context.Context, name string) (registry.Watcher, er
} }
if !ok { if !ok {
err := r.resolve(ctx, set) err := r.resolve(set)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -218,26 +194,22 @@ func (r *Registry) Watch(ctx context.Context, name string) (registry.Watcher, er
return w, nil return w, nil
} }
func (r *Registry) resolve(ctx context.Context, ss *serviceSet) error { func (r *Registry) resolve(ss *serviceSet) error {
timeoutCtx, cancel := context.WithTimeout(ctx, r.timeout) ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel() services, idx, err := r.cli.Service(ctx, ss.serviceName, 0, true)
cancel()
services, idx, err := r.cli.Service(timeoutCtx, ss.serviceName, 0, true)
if err != nil { if err != nil {
return err return err
} } else if len(services) > 0 {
if len(services) > 0 {
ss.broadcast(services) ss.broadcast(services)
} }
go func() { go func() {
ticker := time.NewTicker(time.Second) ticker := time.NewTicker(time.Second)
defer ticker.Stop() defer ticker.Stop()
for { for {
select { <-ticker.C
case <-ticker.C: ctx, cancel := context.WithTimeout(context.Background(), time.Second*120)
timeoutCtx, cancel := context.WithTimeout(context.Background(), r.timeout) tmpService, tmpIdx, err := r.cli.Service(ctx, ss.serviceName, idx, true)
tmpService, tmpIdx, err := r.cli.Service(timeoutCtx, ss.serviceName, idx, true)
cancel() cancel()
if err != nil { if err != nil {
time.Sleep(time.Second) time.Sleep(time.Second)
@ -248,9 +220,6 @@ func (r *Registry) resolve(ctx context.Context, ss *serviceSet) error {
ss.broadcast(services) ss.broadcast(services)
} }
idx = tmpIdx idx = tmpIdx
case <-ctx.Done():
return
}
} }
}() }()

@ -13,7 +13,7 @@ import (
"github.com/go-kratos/kratos/v2/registry" "github.com/go-kratos/kratos/v2/registry"
) )
func tcpServer(lis net.Listener) { func tcpServer(t *testing.T, lis net.Listener) {
for { for {
conn, err := lis.Accept() conn, err := lis.Accept()
if err != nil { if err != nil {
@ -74,14 +74,14 @@ func TestRegistry_Register(t *testing.T) {
serverName: "server-1", serverName: "server-1",
server: []*registry.ServiceInstance{ server: []*registry.ServiceInstance{
{ {
ID: "2", ID: "1",
Name: "server-1", Name: "server-1",
Version: "v0.0.1", Version: "v0.0.1",
Metadata: nil, Metadata: nil,
Endpoints: []string{"http://127.0.0.1:8000"}, Endpoints: []string{"http://127.0.0.1:8000"},
}, },
{ {
ID: "2", ID: "1",
Name: "server-1", Name: "server-1",
Version: "v0.0.2", Version: "v0.0.2",
Metadata: nil, Metadata: nil,
@ -91,7 +91,7 @@ func TestRegistry_Register(t *testing.T) {
}, },
want: []*registry.ServiceInstance{ want: []*registry.ServiceInstance{
{ {
ID: "2", ID: "1",
Name: "server-1", Name: "server-1",
Version: "v0.0.2", Version: "v0.0.2",
Metadata: nil, Metadata: nil,
@ -148,7 +148,7 @@ func TestRegistry_GetService(t *testing.T) {
t.Fail() t.Fail()
} }
defer lis.Close() defer lis.Close()
go tcpServer(lis) go tcpServer(t, lis)
time.Sleep(time.Millisecond * 100) time.Sleep(time.Millisecond * 100)
cli, err := api.NewClient(&api.Config{Address: "127.0.0.1:8500"}) cli, err := api.NewClient(&api.Config{Address: "127.0.0.1:8500"})
if err != nil { if err != nil {
@ -168,13 +168,6 @@ func TestRegistry_GetService(t *testing.T) {
Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)}, Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)},
} }
instance2 := &registry.ServiceInstance{
ID: "2",
Name: "server-1",
Version: "v0.0.1",
Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)},
}
type fields struct { type fields struct {
registry *Registry registry *Registry
} }
@ -230,10 +223,10 @@ func TestRegistry_GetService(t *testing.T) {
want: nil, want: nil,
wantErr: true, wantErr: true,
preFunc: func(t *testing.T) { preFunc: func(t *testing.T) {
if err := r.Register(context.Background(), instance2); err != nil { if err := r.Register(context.Background(), instance1); err != nil {
t.Error(err) t.Error(err)
} }
watch, err := r.Watch(context.Background(), instance2.Name) watch, err := r.Watch(context.Background(), instance1.Name)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -243,7 +236,7 @@ func TestRegistry_GetService(t *testing.T) {
} }
}, },
deferFunc: func(t *testing.T) { deferFunc: func(t *testing.T) {
err := r.Deregister(context.Background(), instance2) err := r.Deregister(context.Background(), instance1)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -289,28 +282,11 @@ func TestRegistry_Watch(t *testing.T) {
Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)}, Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)},
} }
instance2 := &registry.ServiceInstance{
ID: "2",
Name: "server-1",
Version: "v0.0.1",
Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)},
}
instance3 := &registry.ServiceInstance{
ID: "3",
Name: "server-1",
Version: "v0.0.1",
Endpoints: []string{fmt.Sprintf("tcp://%s?isSecure=false", addr)},
}
type args struct { type args struct {
ctx context.Context ctx context.Context
cancel func()
opts []Option opts []Option
instance *registry.ServiceInstance instance *registry.ServiceInstance
} }
canceledCtx, cancel := context.WithCancel(context.Background())
tests := []struct { tests := []struct {
name string name string
args args args args
@ -332,41 +308,25 @@ func TestRegistry_Watch(t *testing.T) {
preFunc: func(t *testing.T) { preFunc: func(t *testing.T) {
}, },
}, },
{
name: "ctx has been cancelled",
args: args{
ctx: canceledCtx,
cancel: cancel,
instance: instance2,
opts: []Option{
WithHealthCheck(false),
},
},
want: nil,
wantErr: true,
preFunc: func(t *testing.T) {
},
},
{ {
name: "register with healthCheck", name: "register with healthCheck",
args: args{ args: args{
ctx: context.Background(), ctx: context.Background(),
instance: instance3, instance: instance1,
opts: []Option{ opts: []Option{
WithHeartbeat(true), WithHeartbeat(true),
WithHealthCheck(true), WithHealthCheck(true),
WithHealthCheckInterval(5), WithHealthCheckInterval(5),
}, },
}, },
want: []*registry.ServiceInstance{instance3}, want: []*registry.ServiceInstance{instance1},
wantErr: false, wantErr: false,
preFunc: func(t *testing.T) { preFunc: func(t *testing.T) {
lis, err := net.Listen("tcp", addr) lis, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
t.Errorf("listen tcp %s failed!", addr) t.Errorf("listen tcp %s failed!", addr)
return
} }
go tcpServer(lis) go tcpServer(t, lis)
}, },
}, },
} }
@ -395,10 +355,6 @@ func TestRegistry_Watch(t *testing.T) {
t.Error(err) t.Error(err)
} }
if tt.args.cancel != nil {
tt.args.cancel()
}
service, err := watch.Next() service, err := watch.Next()
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save