Full Code of why444216978/gin-api for AI

master 9bc770ba26dd cached
167 files
466.5 KB
165.4k tokens
739 symbols
1 requests
Download .txt
Showing preview only (513K chars total). Download the full file or copy to clipboard to get everything.
Repository: why444216978/gin-api
Branch: master
Commit: 9bc770ba26dd
Files: 167
Total size: 466.5 KB

Directory structure:
gitextract_sf1jmaii/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── app/
│   ├── Dockerfile
│   ├── Makefile
│   ├── conf/
│   │   ├── dev/
│   │   │   ├── app.toml
│   │   │   ├── default_rabbitmq.toml
│   │   │   ├── default_redis.toml
│   │   │   ├── etcd.toml
│   │   │   ├── jaeger.toml
│   │   │   ├── log/
│   │   │   │   ├── gorm.toml
│   │   │   │   ├── queue.toml
│   │   │   │   ├── redis.toml
│   │   │   │   ├── rpc.toml
│   │   │   │   └── service.toml
│   │   │   ├── registry.toml
│   │   │   ├── services/
│   │   │   │   └── gin-api.toml
│   │   │   └── test_mysql.toml
│   │   ├── liantiao/
│   │   │   ├── app.toml
│   │   │   ├── default_rabbitmq.toml
│   │   │   ├── default_redis.toml
│   │   │   ├── etcd.toml
│   │   │   ├── jaeger.toml
│   │   │   ├── log/
│   │   │   │   ├── gorm.toml
│   │   │   │   ├── queue.toml
│   │   │   │   ├── redis.toml
│   │   │   │   ├── rpc.toml
│   │   │   │   └── service.toml
│   │   │   ├── services/
│   │   │   │   └── gin-api.toml
│   │   │   └── test_mysql.toml
│   │   ├── online/
│   │   │   ├── app.toml
│   │   │   ├── default_rabbitmq.toml
│   │   │   ├── default_redis.toml
│   │   │   ├── etcd.toml
│   │   │   ├── jaeger.toml
│   │   │   ├── log/
│   │   │   │   ├── gorm.toml
│   │   │   │   ├── queue.toml
│   │   │   │   ├── redis.toml
│   │   │   │   ├── rpc.toml
│   │   │   │   └── service.toml
│   │   │   ├── services/
│   │   │   │   └── gin-api.toml
│   │   │   └── test_mysql.toml
│   │   └── qa/
│   │       ├── app.toml
│   │       ├── default_rabbitmq.toml
│   │       ├── default_redis.toml
│   │       ├── etcd.toml
│   │       ├── jaeger.toml
│   │       ├── log/
│   │       │   ├── gorm.toml
│   │       │   ├── queue.toml
│   │       │   ├── redis.toml
│   │       │   ├── rpc.toml
│   │       │   └── service.toml
│   │       ├── services/
│   │       │   └── gin-api.toml
│   │       └── test_mysql.toml
│   ├── loader/
│   │   └── loader.go
│   ├── main.go
│   ├── module/
│   │   ├── goods/
│   │   │   ├── api/
│   │   │   │   └── conn.go
│   │   │   ├── job/
│   │   │   │   └── job.go
│   │   │   ├── respository/
│   │   │   │   └── respository.go
│   │   │   └── service/
│   │   │       └── service.go
│   │   ├── ping/
│   │   │   ├── api/
│   │   │   │   └── ping.go
│   │   │   ├── job/
│   │   │   │   └── job.go
│   │   │   ├── responsitory/
│   │   │   │   └── responsitory.go
│   │   │   └── service/
│   │   │       └── service.go
│   │   └── test/
│   │       ├── api/
│   │       │   └── test.go
│   │       ├── job/
│   │       │   └── grpc/
│   │       │       └── job.go
│   │       ├── respository/
│   │       │   └── respository.go
│   │       └── service/
│   │           └── grpc/
│   │               ├── google/
│   │               │   ├── api/
│   │               │   │   ├── annotations.proto
│   │               │   │   ├── http.proto
│   │               │   │   └── httpbody.proto
│   │               │   └── protobuf/
│   │               │       └── descriptor.proto
│   │               ├── grpc.go
│   │               └── helloworld/
│   │                   ├── hello_world.pb.go
│   │                   ├── hello_world.pb.gw.go
│   │                   ├── hello_world.proto
│   │                   └── hello_world_grpc.pb.go
│   ├── resource/
│   │   └── resource.go
│   ├── response/
│   │   └── response.go
│   ├── router/
│   │   └── router.go
│   └── rpc/
│       └── gin-api/
│           └── test.go
├── bootstrap/
│   ├── app.go
│   └── init.go
├── client/
│   ├── grpc/
│   │   └── conn.go
│   └── http/
│       ├── client.go
│       ├── plugin.go
│       └── transport/
│           └── transport.go
├── go.mod
├── go.sum
├── library/
│   ├── apollo/
│   │   ├── agollo/
│   │   │   ├── README.md
│   │   │   ├── agollo.go
│   │   │   ├── agollo_test.go
│   │   │   ├── listener/
│   │   │   │   ├── listener.go
│   │   │   │   ├── mock/
│   │   │   │   │   └── listener.go
│   │   │   │   └── structlistener/
│   │   │   │       └── listener.go
│   │   │   └── util/
│   │   │       └── util.go
│   │   └── http/
│   │       └── apollo.go
│   ├── app/
│   │   └── app.go
│   ├── cache/
│   │   ├── cache.go
│   │   └── redis/
│   │       └── redis_cache.go
│   ├── config/
│   │   └── viper.go
│   ├── cron/
│   │   ├── cron.go
│   │   └── cron_test.go
│   ├── endless/
│   │   └── endless.go
│   ├── etcd/
│   │   └── etcd.go
│   ├── jaeger/
│   │   ├── gorm/
│   │   │   ├── gorm.go
│   │   │   └── gorm_test.go
│   │   ├── http/
│   │   │   ├── http.go
│   │   │   └── http_test.go
│   │   ├── jaeger.go
│   │   └── redis/
│   │       ├── redis.go
│   │       └── redis_test.go
│   ├── job/
│   │   └── job.go
│   ├── lock/
│   │   ├── lock.go
│   │   ├── mock/
│   │   │   └── lock.go
│   │   └── redis/
│   │       ├── redis_lock.go
│   │       └── redis_lock_test.go
│   ├── logger/
│   │   ├── context.go
│   │   ├── fields.go
│   │   ├── http.go
│   │   ├── level.go
│   │   ├── logger.go
│   │   ├── logid.go
│   │   ├── rotate.go
│   │   ├── rotate_test.go
│   │   └── zap/
│   │       ├── gorm/
│   │       │   └── gorm.go
│   │       ├── redis/
│   │       │   └── redis.go
│   │       ├── rpc/
│   │       │   └── rpc.go
│   │       ├── service/
│   │       │   └── service.go
│   │       └── zap.go
│   ├── orm/
│   │   └── orm.go
│   ├── queue/
│   │   ├── queue.go
│   │   └── rabbitmq/
│   │       └── rabbitmq.go
│   ├── redis/
│   │   └── conn.go
│   ├── registry/
│   │   ├── etcd/
│   │   │   ├── discovery.go
│   │   │   └── registrar.go
│   │   └── registry.go
│   ├── reliablequeue/
│   │   ├── reliablequeue.go
│   │   ├── reliablequeue_test.go
│   │   ├── table.go
│   │   └── table.sql
│   ├── selector/
│   │   ├── dwrr/
│   │   │   └── cwrr.go
│   │   ├── icmp/
│   │   │   └── icmp.go
│   │   ├── p2c/
│   │   │   └── p2c.go
│   │   ├── selector.go
│   │   ├── wr/
│   │   │   ├── wr.go
│   │   │   └── wr_test.go
│   │   └── wrr/
│   │       └── wrr.go
│   └── servicer/
│       ├── service/
│       │   └── service.go
│       └── servicer.go
└── server/
    ├── grpc/
    │   ├── cmux/
    │   │   └── cmux.go
    │   ├── h2c/
    │   │   └── h2c.go
    │   ├── middleware/
    │   │   └── log/
    │   │       └── log.go
    │   ├── option.go
    │   └── server.go
    ├── http/
    │   ├── middleware/
    │   │   ├── cors/
    │   │   │   └── cors.go
    │   │   ├── csrf/
    │   │   │   └── csrf.go
    │   │   ├── limiter/
    │   │   │   └── limiter.go
    │   │   ├── log/
    │   │   │   └── log.go
    │   │   ├── panic/
    │   │   │   ├── mail_template.go
    │   │   │   └── panic.go
    │   │   └── timeout/
    │   │       └── timeout.go
    │   ├── response/
    │   │   ├── error.go
    │   │   └── response.go
    │   ├── server.go
    │   └── util/
    │       └── util.go
    └── server.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.svn
.svn/*
*.swp
*.swn
*.swo
*.tmp
*.swm
app/logs/*
app/log/*
logs/*
log/*
development
.tags*
.idea
.vscode
.DS_Store
__debug_bin
cover.out
cover.html
cover.txt
.apollo_config
go.work
*.log


================================================
FILE: LICENSE
================================================

The MIT License (MIT)

Copyright (c) 2021 AirGo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

================================================
FILE: Makefile
================================================
.PHONY: all build test clean

all: build test

format:
	go vet ./...
	gofmt -w .
	golint ./...
build:
	go mod download 

test:
	go test -race -cover -coverpkg=./... ./...  -gcflags="-N -l"

clean:
	go clean -i -n -r



================================================
FILE: README.md
================================================
<!--
 * @Descripttion:
 * @Author: weihaoyu
-->

# gin-api
Go 微服务框架,同时支持 gRPC 和 HTTP,封装各种常用组件,开箱即用,专注业务。
<br>
本代码库已停止维护,请移步:<a href="https://github.com/air-go/rpc">air-go/rpc</a>
<br><br>


================================================
FILE: app/Dockerfile
================================================
# 使用最新golang镜像
FROM golang:latest

# 作者
MAINTAINER AirGo

# 环境变量配置
ENV GOPROXY https://goproxy.cn,direct
ENV GO111MODULE on

# 指定工作目录,用于保存文件
WORKDIR /tmp

# 移动代码到容器中
COPY . .

# 指定工作目录,用于保存执行文件和配置文件
WORKDIR /app/

# 移动执行文件和配置文件
RUN cp /tmp/gin-api/app/app .
RUN cp -rf /tmp/gin-api/app/conf ./

# 向外暴露8888端口
EXPOSE 8888

# 启动容器时运行的命令
ENTRYPOINT ["./app -env online"]

================================================
FILE: app/Makefile
================================================
.PHONY: all build test clean

all: build test

format:
	go vet ./...
	gofmt -w .
	golint ./...
build:
	go mod download 
	GOOS=linux GOARCH=386 go build -o app main.go

test:
	go test -race -cover -coverpkg=./... ./...  -gcflags="-N -l"

clean:
	go clean -i -n -r



================================================
FILE: app/conf/dev/app.toml
================================================
AppName = "gin-api-dev"
AppPort = 8777
Pprof = true
IsDebug = true
ContextTimeout = 100000
ConnectTimeout = 100000
WriteTimeout =  100000
ReadTimeout =  100000

================================================
FILE: app/conf/dev/default_rabbitmq.toml
================================================
ServiceName = "default_rabbitmq"
Host = "127.0.0.1"
Port = 5672
Virtual = "why"
User = "why"
Pass = "why"
ExchangeType = "direct"
ExchangeName = "why_exchange"
QueueName = "why_queue"
RouteName = "why_route"

================================================
FILE: app/conf/dev/default_redis.toml
================================================
ServiceName = "default_redis"
Host = "127.0.0.1"
Port = 6379
Auth = ""
DB = 0
ConnectTimeout = 1
ReadTimeout = 1
WriteTimeout = 1
MaxActive = 30
MaxIdle = 10
IsLog = true
ExecTimeout = 100000

================================================
FILE: app/conf/dev/etcd.toml
================================================
Endpoints = "localhost:23790;localhost:23791;localhost:23792"
DialTimeout = 5


================================================
FILE: app/conf/dev/jaeger.toml
================================================
Host = "127.0.0.1"
Port = "6831"

================================================
FILE: app/conf/dev/log/gorm.toml
================================================
SlowThreshold = 1000
InfoFile = "./log/gorm/info.log"
ErrorFile = "./log/gorm/error.wf.log"
Level = 4 # Silent(1) < Error(2) < Warn(3) < Info(4)
SkipCallerLookup = false
IgnoreRecordNotFoundError = true

================================================
FILE: app/conf/dev/log/queue.toml
================================================
InfoFile = "./log/queue/info.log"
ErrorFile = "./log/queue/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/dev/log/redis.toml
================================================
InfoFile = "./log/redis/info.log"
ErrorFile = "./log/redis/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/dev/log/rpc.toml
================================================
InfoFile = "./log/rpc/info.log"
ErrorFile = "./log/rpc/error.wf.log"
Level = "info" # debug < info < warn < error < fatal

================================================
FILE: app/conf/dev/log/service.toml
================================================
InfoFile = "./log/service/info.log"
ErrorFile = "./log/service/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/dev/registry.toml
================================================
Lease = 5


================================================
FILE: app/conf/dev/services/gin-api.toml
================================================
ServiceName = "gin-api-dev"
Type = 2 # 1-注册发现,2-IP+PORT,3-域名
Host = "127.0.0.1"
Port = 8777
Selector = "wr" #参考selector
RefreshSecond = 10

================================================
FILE: app/conf/dev/test_mysql.toml
================================================
ServiceName = "test_mysql"

[master]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

[slave]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

================================================
FILE: app/conf/liantiao/app.toml
================================================
AppName = "gin-api-liantiao"
AppPort = 888
Pprof = true
IsDebug = true
ContextTimeout = 100000
ConnectTimeout = 100000
WriteTimeout =  100000
ReadTimeout =  100000

================================================
FILE: app/conf/liantiao/default_rabbitmq.toml
================================================
ServiceName = "default_rabbitmq"
Host = "127.0.0.1"
Port = 5672
Virtual = "why"
User = "why"
Pass = "why"
ExchangeType = "direct"
ExchangeName = "why_exchange"
QueueName = "why_queue"
RouteName = "why_route"

================================================
FILE: app/conf/liantiao/default_redis.toml
================================================
ServiceName = "default_redis"
Host = "127.0.0.1"
Port = 6379
Auth = ""
DB = 0
ConnectTimeout = 1
ReadTimeout = 1
WriteTimeout = 1
MaxActive = 30
MaxIdle = 10
IsLog = true
ExecTimeout = 100000

================================================
FILE: app/conf/liantiao/etcd.toml
================================================
Endpoints = "localhost:23790;localhost:23791;localhost:23792"
DialTimeout = 5


================================================
FILE: app/conf/liantiao/jaeger.toml
================================================
Host = "127.0.0.1"
Port = "6831"

================================================
FILE: app/conf/liantiao/log/gorm.toml
================================================
SlowThreshold = 1000
InfoFile = "./log/gorm/info.log"
ErrorFile = "./log/gorm/error.wf.log"
Level = 4 # Silent(1) < Error(2) < Warn(3) < Info(4)
SkipCallerLookup = false
IgnoreRecordNotFoundError = true

================================================
FILE: app/conf/liantiao/log/queue.toml
================================================
InfoFile = "./log/queue/info.log"
ErrorFile = "./log/queue/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/liantiao/log/redis.toml
================================================
InfoFile = "./log/redis/info.log"
ErrorFile = "./log/redis/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/liantiao/log/rpc.toml
================================================
InfoFile = "./log/rpc/info.log"
ErrorFile = "./log/rpc/error.wf.log"
Level = "info" # debug < info < warn < error < fatal

================================================
FILE: app/conf/liantiao/log/service.toml
================================================
InfoFile = "./log/service/info.log"
ErrorFile = "./log/service/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/liantiao/services/gin-api.toml
================================================
ServiceName = "gin-api"
Type = 2 # 1-注册发现,2-IP+PORT,3-域名
Host = "127.0.0.1"
Port = 777
Selector = "wr" #参考selector
RefreshSecond = 10

================================================
FILE: app/conf/liantiao/test_mysql.toml
================================================
[master]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

[slave]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

================================================
FILE: app/conf/online/app.toml
================================================
AppName = "gin-api-online"
AppPort = 1000
Pprof = false
IsDebug = false
ContextTimeout = 100000
ConnectTimeout = 100000
WriteTimeout =  100000
ReadTimeout =  100000

================================================
FILE: app/conf/online/default_rabbitmq.toml
================================================
ServiceName = "default_rabbitmq"
Host = "127.0.0.1"
Port = 5672
Virtual = "why"
User = "why"
Pass = "why"
ExchangeType = "direct"
ExchangeName = "why_exchange"
QueueName = "why_queue"
RouteName = "why_route"

================================================
FILE: app/conf/online/default_redis.toml
================================================
ServiceName = "default_redis"
Host = "127.0.0.1"
Port = 6379
Auth = ""
DB = 0
ConnectTimeout = 1
ReadTimeout = 1
WriteTimeout = 1
MaxActive = 30
MaxIdle = 10
IsLog = true
ExecTimeout = 100000

================================================
FILE: app/conf/online/etcd.toml
================================================
Endpoints = "localhost:23790;localhost:23791;localhost:23792"
DialTimeout = 5


================================================
FILE: app/conf/online/jaeger.toml
================================================
Host = "127.0.0.1"
Port = "6831"

================================================
FILE: app/conf/online/log/gorm.toml
================================================
SlowThreshold = 1000
InfoFile = "./log/gorm/info.log"
ErrorFile = "./log/gorm/error.wf.log"
Level = 4 # Silent(1) < Error(2) < Warn(3) < Info(4)
SkipCallerLookup = false
IgnoreRecordNotFoundError = true

================================================
FILE: app/conf/online/log/queue.toml
================================================
InfoFile = "./log/queue/info.log"
ErrorFile = "./log/queue/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/online/log/redis.toml
================================================
InfoFile = "./log/redis/info.log"
ErrorFile = "./log/redis/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/online/log/rpc.toml
================================================
InfoFile = "./log/rpc/info.log"
ErrorFile = "./log/rpc/error.wf.log"
Level = "info" # debug < info < warn < error < fatal

================================================
FILE: app/conf/online/log/service.toml
================================================
InfoFile = "./log/service/info.log"
ErrorFile = "./log/service/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/online/services/gin-api.toml
================================================
ServiceName = "gin-api"
Type = 2 # 1-注册发现,2-IP+PORT,3-域名
Host = "127.0.0.1"
Port = 777
Selector = "wr" #参考selector
RefreshSecond = 10

================================================
FILE: app/conf/online/test_mysql.toml
================================================
[master]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

[slave]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

================================================
FILE: app/conf/qa/app.toml
================================================
AppName = "gin-api-qa"
AppPort = 999
Pprof = true
IsDebug = true
ContextTimeout = 100000
ConnectTimeout = 100000
WriteTimeout =  100000
ReadTimeout =  100000

================================================
FILE: app/conf/qa/default_rabbitmq.toml
================================================
ServiceName = "default_rabbitmq"
Host = "127.0.0.1"
Port = 5672
Virtual = "why"
User = "why"
Pass = "why"
ExchangeType = "direct"
ExchangeName = "why_exchange"
QueueName = "why_queue"
RouteName = "why_route"

================================================
FILE: app/conf/qa/default_redis.toml
================================================
ServiceName = "default_redis"
Host = "127.0.0.1"
Port = 6379
Auth = ""
DB = 0
ConnectTimeout = 1
ReadTimeout = 1
WriteTimeout = 1
MaxActive = 30
MaxIdle = 10
IsLog = true
ExecTimeout = 100000

================================================
FILE: app/conf/qa/etcd.toml
================================================
Endpoints = "localhost:23790;localhost:23791;localhost:23792"
DialTimeout = 5


================================================
FILE: app/conf/qa/jaeger.toml
================================================
Host = "127.0.0.1"
Port = "6831"

================================================
FILE: app/conf/qa/log/gorm.toml
================================================
SlowThreshold = 1000
InfoFile = "./log/gorm/info.log"
ErrorFile = "./log/gorm/error.wf.log"
Level = 4 # Silent(1) < Error(2) < Warn(3) < Info(4)
SkipCallerLookup = false
IgnoreRecordNotFoundError = true

================================================
FILE: app/conf/qa/log/queue.toml
================================================
InfoFile = "./log/queue/info.log"
ErrorFile = "./log/queue/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/qa/log/redis.toml
================================================
InfoFile = "./log/redis/info.log"
ErrorFile = "./log/redis/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/qa/log/rpc.toml
================================================
InfoFile = "./log/rpc/info.log"
ErrorFile = "./log/rpc/error.wf.log"
Level = "info" # debug < info < warn < error < fatal

================================================
FILE: app/conf/qa/log/service.toml
================================================
InfoFile = "./log/service/info.log"
ErrorFile = "./log/service/error.wf.log"
Level = "debug" # debug < info < warn < error < fatal

================================================
FILE: app/conf/qa/services/gin-api.toml
================================================
ServiceName = "gin-api"
Type = 2 # 1-注册发现,2-IP+PORT,3-域名
Host = "127.0.0.1"
Port = 777
Selector = "wr" #参考selector
RefreshSecond = 10

================================================
FILE: app/conf/qa/test_mysql.toml
================================================
[master]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

[slave]
Host = "127.0.0.1"
Port = "3306"
User = "root"
Password = "123456"
DB = "test"
Charset = "utf8mb4"
MaxOpen = 8
MaxIdle = 4

================================================
FILE: app/loader/loader.go
================================================
package loader

import (
	"strings"

	"github.com/pkg/errors"
	"github.com/why444216978/go-util/assert"
	"github.com/why444216978/go-util/sys"

	"github.com/why444216978/gin-api/app/resource"
	httpClient "github.com/why444216978/gin-api/client/http"
	"github.com/why444216978/gin-api/client/http/transport"
	"github.com/why444216978/gin-api/library/app"
	redisCache "github.com/why444216978/gin-api/library/cache/redis"
	"github.com/why444216978/gin-api/library/config"
	"github.com/why444216978/gin-api/library/etcd"
	"github.com/why444216978/gin-api/library/jaeger"
	jaegerGorm "github.com/why444216978/gin-api/library/jaeger/gorm"
	jaegerRedis "github.com/why444216978/gin-api/library/jaeger/redis"
	redisLock "github.com/why444216978/gin-api/library/lock/redis"
	loggerGorm "github.com/why444216978/gin-api/library/logger/zap/gorm"
	loggerRedis "github.com/why444216978/gin-api/library/logger/zap/redis"
	loggerRPC "github.com/why444216978/gin-api/library/logger/zap/rpc"
	serviceLogger "github.com/why444216978/gin-api/library/logger/zap/service"
	"github.com/why444216978/gin-api/library/orm"
	"github.com/why444216978/gin-api/library/queue/rabbitmq"
	"github.com/why444216978/gin-api/library/redis"
	"github.com/why444216978/gin-api/library/registry"
	etcdRegistry "github.com/why444216978/gin-api/library/registry/etcd"
	"github.com/why444216978/gin-api/library/servicer/service"
	"github.com/why444216978/gin-api/server"
)

func Load() (err error) {
	// TODO
	// ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
	// defer cancel()

	if err = loadLogger(); err != nil {
		return
	}
	if err = loadClientHTTP(); err != nil {
		return
	}
	// TODO 避免用户第一次使用运行panic,留给用户自己打开需要的依赖
	// if err = loadMysql("test_mysql"); err != nil {
	// 	return
	// }
	// if err = loadRedis("default_redis"); err != nil {
	// 	return
	// }
	// if err = loadRabbitMQ("default_rabbitmq"); err != nil {
	// 	return
	// }
	// if err = loadJaeger(); err != nil {
	// 	return
	// }
	// if err = loadLock(); err != nil {
	// 	return
	// }
	// if err = loadCache(); err != nil {
	// 	return
	// }
	// if err = loadEtcd(); err != nil {
	// 	return
	// }
	// if err = loadRegistry(); err != nil {
	// 	return
	// }
	if err = service.LoadGlobPattern("services", "toml", resource.Etcd); err != nil {
		return
	}

	return
}

func loadLogger() (err error) {
	cfg := &serviceLogger.Config{}

	if err = config.ReadConfig("log/service", "toml", &cfg); err != nil {
		return
	}

	if resource.ServiceLogger, err = serviceLogger.NewServiceLogger(app.Name(), cfg); err != nil {
		return
	}

	server.RegisterCloseFunc(resource.ServiceLogger.Close())

	return
}

func loadMysql(db string) (err error) {
	cfg := &orm.Config{}
	logCfg := &loggerGorm.GormConfig{}

	if err = config.ReadConfig(db, "toml", cfg); err != nil {
		return
	}

	if err = config.ReadConfig("log/gorm", "toml", logCfg); err != nil {
		return
	}

	logCfg.ServiceName = cfg.ServiceName
	logger, err := loggerGorm.NewGorm(logCfg)
	if err != nil {
		return
	}
	server.RegisterCloseFunc(logger.Close())

	if resource.TestDB, err = orm.NewOrm(cfg,
		orm.WithTrace(jaegerGorm.GormTrace),
		orm.WithLogger(logger),
	); err != nil {
		return
	}

	return
}

func loadRedis(db string) (err error) {
	cfg := &redis.Config{}
	logCfg := &loggerRedis.RedisConfig{}

	if err = config.ReadConfig(db, "toml", cfg); err != nil {
		return
	}
	if err = config.ReadConfig("log/redis", "toml", &logCfg); err != nil {
		return
	}

	logCfg.ServiceName = cfg.ServiceName
	logCfg.Host = cfg.Host
	logCfg.Port = cfg.Port

	logger, err := loggerRedis.NewRedisLogger(logCfg)
	if err != nil {
		return
	}
	server.RegisterCloseFunc(logger.Close())

	rc := redis.NewClient(cfg)
	rc.AddHook(jaegerRedis.NewJaegerHook())
	rc.AddHook(logger)
	resource.RedisDefault = rc

	return
}

func loadRabbitMQ(service string) (err error) {
	cfg := &rabbitmq.Config{}
	if err = config.ReadConfig(service, "toml", cfg); err != nil {
		return
	}

	if resource.RabbitMQ, err = rabbitmq.New(cfg); err != nil {
		return
	}

	return
}

func loadLock() (err error) {
	resource.RedisLock, err = redisLock.New(resource.RedisDefault)
	return
}

func loadCache() (err error) {
	resource.RedisCache, err = redisCache.New(resource.RedisDefault, resource.RedisLock)
	return
}

func loadJaeger() (err error) {
	cfg := &jaeger.Config{}

	if err = config.ReadConfig("jaeger", "toml", cfg); err != nil {
		return
	}

	if _, _, err = jaeger.NewJaegerTracer(cfg, app.Name()); err != nil {
		return
	}

	return
}

func loadEtcd() (err error) {
	cfg := &etcd.Config{}

	if err = config.ReadConfig("etcd", "toml", cfg); err != nil {
		return
	}

	if resource.Etcd, err = etcd.NewClient(
		etcd.WithEndpoints(strings.Split(cfg.Endpoints, ";")),
		etcd.WithDialTimeout(cfg.DialTimeout),
	); err != nil {
		return
	}

	return
}

func loadRegistry() (err error) {
	var (
		localIP string
		cfg     = &registry.RegistryConfig{}
	)

	if err = config.ReadConfig("registry", "toml", cfg); err != nil {
		return
	}

	if localIP, err = sys.LocalIP(); err != nil {
		return
	}

	if assert.IsNil(resource.Etcd) {
		err = errors.New("resource.Etcd is nil")
		return
	}

	if resource.Registrar, err = etcdRegistry.NewRegistry(
		etcdRegistry.WithRegistrarClient(resource.Etcd.Client),
		etcdRegistry.WithRegistrarServiceName(app.Name()),
		etcdRegistry.WithRegistarHost(localIP),
		etcdRegistry.WithRegistarPort(app.Port()),
		etcdRegistry.WithRegistrarLease(cfg.Lease)); err != nil {
		return
	}

	if err = server.RegisterCloseFunc(resource.Registrar.DeRegister); err != nil {
		return
	}

	return
}

func loadClientHTTP() (err error) {
	cfg := &loggerRPC.RPCConfig{}
	if err = config.ReadConfig("log/rpc", "toml", cfg); err != nil {
		return
	}

	logger, err := loggerRPC.NewRPCLogger(cfg)
	if err != nil {
		return
	}
	server.RegisterCloseFunc(logger.Close())

	resource.ClientHTTP = transport.New(
		transport.WithLogger(logger),
		transport.WithBeforePlugins(&httpClient.JaegerBeforePlugin{}))
	if err != nil {
		return
	}

	return
}


================================================
FILE: app/main.go
================================================
package main

import (
	"flag"
	"fmt"
	"log"

	"github.com/why444216978/gin-api/app/loader"
	jobGRPC "github.com/why444216978/gin-api/app/module/test/job/grpc"
	serviceGRPC "github.com/why444216978/gin-api/app/module/test/service/grpc"
	"github.com/why444216978/gin-api/app/resource"
	"github.com/why444216978/gin-api/app/router"
	"github.com/why444216978/gin-api/bootstrap"
	"github.com/why444216978/gin-api/library/app"
	jobLib "github.com/why444216978/gin-api/library/job"
	serverGRPC "github.com/why444216978/gin-api/server/grpc"
	serverH2C "github.com/why444216978/gin-api/server/grpc/h2c"
	httpServer "github.com/why444216978/gin-api/server/http"
	logMiddleware "github.com/why444216978/gin-api/server/http/middleware/log"
	panicMiddleware "github.com/why444216978/gin-api/server/http/middleware/panic"
	timeoutMiddleware "github.com/why444216978/gin-api/server/http/middleware/timeout"
)

var (
	env    = flag.String("env", "dev", "config path")
	job    = flag.String("job", "", "is job")
	server = flag.String("server", "http", "is server type")
)

func main() {
	flag.Parse()

	var err error

	if err = bootstrap.Init(*env, loader.Load); err != nil {
		log.Printf("bootstrap.Init err %s", err.Error())
		return
	}

	if *job != "" {
		jobLib.Handlers = map[string]jobLib.HandleFunc{
			"grpc-test": jobGRPC.Start,
		}
		jobLib.Handle(*job, resource.ServiceLogger)
		return
	}

	port := app.Port()
	if *server == "http" {
		log.Printf("start http, port %d", port)
		startHTTP(port)
	} else {
		log.Printf("start grpc, port %d", port)
		startGRPC(port)
	}
}

func startHTTP(port int) {
	srv := httpServer.New(fmt.Sprintf(":%d", port),
		httpServer.WithReadTimeout(app.ReadTimeout()),
		httpServer.WithWriteTimeout(app.WriteTimeout()),
		httpServer.WithRegisterRouter(router.RegisterRouter),
		httpServer.WithMiddlewares(
			panicMiddleware.ThrowPanic(resource.ServiceLogger),
			timeoutMiddleware.TimeoutMiddleware(app.ContextTimeout()),
			logMiddleware.LoggerMiddleware(resource.ServiceLogger),
		),
		httpServer.WithPprof(app.Pprof()),
		httpServer.WithDebug(app.Debug()),
	)

	if err := bootstrap.NewApp(srv, resource.Registrar).Start(); err != nil {
		log.Println(err)
	}
}

func startGRPC(port int) {
	srv := serverH2C.NewH2C(fmt.Sprintf(":%d", port),
		[]serverGRPC.Register{serviceGRPC.NewService()},
	)

	if err := bootstrap.NewApp(srv, resource.Registrar).Start(); err != nil {
		log.Println(err)
	}
}


================================================
FILE: app/module/goods/api/conn.go
================================================
package api

import (
	"context"
	"errors"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
	"golang.org/x/sync/errgroup"

	"github.com/why444216978/gin-api/app/module/goods/respository"
	goodsService "github.com/why444216978/gin-api/app/module/goods/service"
	"github.com/why444216978/gin-api/app/resource"
	"github.com/why444216978/gin-api/app/response"
	httpResponse "github.com/why444216978/gin-api/server/http/response"
)

func Do(c *gin.Context) {
	var (
		err   error
		goods respository.Test
	)

	ctx := c.Request.Context()

	goods, err = goodsService.Instance.CrudGoods(ctx)
	if err != nil {
		resource.ServiceLogger.Error(ctx, err.Error())
		response.ResponseJSON(c, response.CodeServer, goods, httpResponse.WrapToast(err, err.Error()))
		return
	}

	data := &Data{}

	g, _ := errgroup.WithContext(ctx)
	g.Go(func() (err error) {
		goods.Name = "golang"
		_, err = goodsService.Instance.GetGoodsName(ctx, 1)
		return
	})
	g.Go(func() (err error) {
		err = resource.RedisCache.GetData(ctx, "cache_key", time.Hour, time.Hour, GetDataA, data)
		return
	})
	g.Go(func() (err error) {
		result := make([]*redis.StringCmd, 0)
		pipe := resource.RedisDefault.Pipeline()
		result = append(result, pipe.Get(ctx, "test"))
		result = append(result, pipe.Get(ctx, "test"))
		result = append(result, pipe.Get(ctx, "test"))
		_, _ = pipe.Exec(ctx)
		return
	})
	err = g.Wait()
	if err != nil {
		resource.ServiceLogger.Error(ctx, err.Error())
		response.ResponseJSON(c, response.CodeServer, goods, httpResponse.WrapToast(err, err.Error()))
		return
	}

	response.ResponseJSON(c, response.CodeSuccess, goods, nil)
}

type Data struct {
	A string `json:"a"`
}

func GetDataA(ctx context.Context, _data interface{}) (err error) {
	data, ok := _data.(*Data)
	if !ok {
		err = errors.New("err assert")
		return
	}
	data.A = "a"
	return
}


================================================
FILE: app/module/goods/job/job.go
================================================
package job


================================================
FILE: app/module/goods/respository/respository.go
================================================
package respository

type Test struct {
	Id      uint   `gorm:"column:id" json:"id"`
	GoodsId uint64 `gorm:"column:goods_id" json:"goods_id"`
	Name    string `gorm:"column:name" json:"name"`
}

func (Test) TableName() string {
	return "test"
}


================================================
FILE: app/module/goods/service/service.go
================================================
package goods

import (
	"context"
	"strconv"

	"github.com/go-redis/redis/v8"
	"github.com/pkg/errors"
	"github.com/why444216978/go-util/assert"
	"github.com/why444216978/go-util/orm"

	"github.com/why444216978/gin-api/app/module/goods/respository"
	"github.com/why444216978/gin-api/app/resource"
)

type GoodsInterface interface {
	GetGoodsName(ctx context.Context, id int) (string, error)
	CrudGoods(ctx context.Context) (goods respository.Test, err error)
}

var Instance GoodsInterface

type GoodsService struct{}

func init() {
	Instance = &GoodsService{}
}

const (
	GOODS_NAME_KEY  = "goods::name::"
	GOODS_PRICE_KEY = "goods::price::"
)

func (gs *GoodsService) GetGoodsName(ctx context.Context, id int) (string, error) {
	data, err := resource.RedisDefault.Get(ctx, GOODS_NAME_KEY+strconv.Itoa(id)).Result()
	if errors.Is(err, redis.Nil) {
		return "", nil
	}
	if err != nil {
		return "", errors.Wrap(err, "redis get goods price error:")
	}
	return data, nil
}

func (gs *GoodsService) CrudGoods(ctx context.Context) (goods respository.Test, err error) {
	if assert.IsNil(resource.TestDB) {
		err = errors.New("db is nil")
		return
	}
	db := resource.TestDB.DB.WithContext(ctx).Begin()

	defer func() {
		if err != nil {
			db.WithContext(ctx).Rollback()
			return
		}
		err = db.WithContext(ctx).Commit().Error
	}()

	err = db.WithContext(ctx).Select("*").First(&goods).Error
	if err != nil {
		return
	}

	_, err = orm.Insert(ctx, db, &respository.Test{
		GoodsId: 333,
		Name:    "a",
	})
	if err != nil {
		return
	}

	where := map[string]interface{}{"goods_id": 333}
	update := map[string]interface{}{"name": 333}

	_, err = orm.Update(ctx, db, &respository.Test{}, where, update)
	if err != nil {
		return
	}

	_, err = orm.Delete(ctx, db, &respository.Test{}, where)
	if err != nil {
		return
	}

	var name string
	err = db.WithContext(ctx).Table("test").Where("id = ?", 1).Select("name").Row().Scan(&name)
	if err != nil {
		return
	}

	err = db.WithContext(ctx).Raw("select * from test where id = 1 limit 1").Scan(&goods).Error
	if err != nil {
		return
	}

	return
}


================================================
FILE: app/module/ping/api/ping.go
================================================
package api

import (
	"github.com/gin-gonic/gin"

	"github.com/why444216978/gin-api/app/response"
	gin_api "github.com/why444216978/gin-api/app/rpc/gin-api"
	httpResponse "github.com/why444216978/gin-api/server/http/response"
)

func Ping(c *gin.Context) {
	response.ResponseJSON(c, response.CodeSuccess, nil, nil)
}

func RPC(c *gin.Context) {
	ret, err := gin_api.Ping(c.Request.Context())
	if err != nil {
		response.ResponseJSON(c, response.CodeServer, ret, httpResponse.WrapToast(err, err.Error()))
		return
	}
	response.ResponseJSON(c, response.CodeSuccess, ret, nil)
}


================================================
FILE: app/module/ping/job/job.go
================================================
package job


================================================
FILE: app/module/ping/responsitory/responsitory.go
================================================
package responsitory


================================================
FILE: app/module/ping/service/service.go
================================================
package service


================================================
FILE: app/module/test/api/test.go
================================================
package api

import (
	"time"

	"github.com/gin-gonic/gin"

	"github.com/why444216978/gin-api/app/response"
	gin_api "github.com/why444216978/gin-api/app/rpc/gin-api"
	httpResponse "github.com/why444216978/gin-api/server/http/response"
	"github.com/why444216978/go-util/http"
)

func Rpc(c *gin.Context) {
	time.Sleep(time.Millisecond * 30)
	ret, err := gin_api.RPC(c.Request.Context())
	if err != nil {
		response.ResponseJSON(c, response.CodeServer, ret, httpResponse.WrapToast(err, err.Error()))
		return
	}

	response.ResponseJSON(c, response.CodeSuccess, ret, nil)
}

type RPC1Request struct {
	A string `json:"a"`
}

func Rpc1(c *gin.Context) {
	time.Sleep(time.Millisecond * 99)
	var req RPC1Request
	if err := http.ParseAndValidateBody(c.Request, &req); err != nil {
		response.ResponseJSON(c, response.CodeParams, nil, httpResponse.WrapToast(err, err.Error()))
		return
	}

	ret, err := gin_api.RPC1(c.Request.Context())
	if err != nil {
		response.ResponseJSON(c, response.CodeServer, ret, httpResponse.WrapToast(err, err.Error()))
		return
	}

	response.ResponseJSON(c, response.CodeSuccess, ret, nil)
}

func Panic(c *gin.Context) {
	panic("test err")
}


================================================
FILE: app/module/test/job/grpc/job.go
================================================
package grpc

import (
	"context"
	"fmt"
	"log"
	"time"

	pb "github.com/why444216978/gin-api/app/module/test/service/grpc/helloworld"
	client "github.com/why444216978/gin-api/client/grpc"
	"github.com/why444216978/gin-api/library/app"
)

func Start(ctx context.Context) (err error) {
	call()
	return
}

func call() {
	cc, err := client.Conn(context.Background(), fmt.Sprintf(":%d", app.Port()))
	if err != nil {
		return
	}
	if err != nil {
		log.Fatal(err)
	}
	client := pb.NewGreeterClient(cc)

	ticker := time.NewTicker(time.Second)
	for range ticker.C {
		reply, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "why"})
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(reply)
	}
}


================================================
FILE: app/module/test/respository/respository.go
================================================
package respository


================================================
FILE: app/module/test/service/grpc/google/api/annotations.proto
================================================
// Copyright (c) 2015, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.api;

import "google/api/http.proto";
import "google/protobuf/descriptor.proto";

option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
option java_multiple_files = true;
option java_outer_classname = "AnnotationsProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";

extend google.protobuf.MethodOptions {
  // See `HttpRule`.
  HttpRule http = 72295728;
}


================================================
FILE: app/module/test/service/grpc/google/api/http.proto
================================================
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.api;

option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
option java_multiple_files = true;
option java_outer_classname = "HttpProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";


// Defines the HTTP configuration for an API service. It contains a list of
// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
// to one or more HTTP REST API methods.
message Http {
  // A list of HTTP configuration rules that apply to individual API methods.
  //
  // **NOTE:** All service configuration rules follow "last one wins" order.
  repeated HttpRule rules = 1;

  // When set to true, URL path parmeters will be fully URI-decoded except in
  // cases of single segment matches in reserved expansion, where "%2F" will be
  // left encoded.
  //
  // The default behavior is to not decode RFC 6570 reserved characters in multi
  // segment matches.
  bool fully_decode_reserved_expansion = 2;
}

// `HttpRule` defines the mapping of an RPC method to one or more HTTP
// REST API methods. The mapping specifies how different portions of the RPC
// request message are mapped to URL path, URL query parameters, and
// HTTP request body. The mapping is typically specified as an
// `google.api.http` annotation on the RPC method,
// see "google/api/annotations.proto" for details.
//
// The mapping consists of a field specifying the path template and
// method kind.  The path template can refer to fields in the request
// message, as in the example below which describes a REST GET
// operation on a resource collection of messages:
//
//
//     service Messaging {
//       rpc GetMessage(GetMessageRequest) returns (Message) {
//         option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}";
//       }
//     }
//     message GetMessageRequest {
//       message SubMessage {
//         string subfield = 1;
//       }
//       string message_id = 1; // mapped to the URL
//       SubMessage sub = 2;    // `sub.subfield` is url-mapped
//     }
//     message Message {
//       string text = 1; // content of the resource
//     }
//
// The same http annotation can alternatively be expressed inside the
// `GRPC API Configuration` YAML file.
//
//     http:
//       rules:
//         - selector: <proto_package_name>.Messaging.GetMessage
//           get: /v1/messages/{message_id}/{sub.subfield}
//
// This definition enables an automatic, bidrectional mapping of HTTP
// JSON to RPC. Example:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456/foo`  | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))`
//
// In general, not only fields but also field paths can be referenced
// from a path pattern. Fields mapped to the path pattern cannot be
// repeated and must have a primitive (non-message) type.
//
// Any fields in the request message which are not bound by the path
// pattern automatically become (optional) HTTP query
// parameters. Assume the following definition of the request message:
//
//
//     service Messaging {
//       rpc GetMessage(GetMessageRequest) returns (Message) {
//         option (google.api.http).get = "/v1/messages/{message_id}";
//       }
//     }
//     message GetMessageRequest {
//       message SubMessage {
//         string subfield = 1;
//       }
//       string message_id = 1; // mapped to the URL
//       int64 revision = 2;    // becomes a parameter
//       SubMessage sub = 3;    // `sub.subfield` becomes a parameter
//     }
//
//
// This enables a HTTP JSON to RPC mapping as below:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))`
//
// Note that fields which are mapped to HTTP parameters must have a
// primitive type or a repeated primitive type. Message types are not
// allowed. In the case of a repeated type, the parameter can be
// repeated in the URL, as in `...?param=A&param=B`.
//
// For HTTP method kinds which allow a request body, the `body` field
// specifies the mapping. Consider a REST update method on the
// message resource collection:
//
//
//     service Messaging {
//       rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
//         option (google.api.http) = {
//           put: "/v1/messages/{message_id}"
//           body: "message"
//         };
//       }
//     }
//     message UpdateMessageRequest {
//       string message_id = 1; // mapped to the URL
//       Message message = 2;   // mapped to the body
//     }
//
//
// The following HTTP JSON to RPC mapping is enabled, where the
// representation of the JSON in the request body is determined by
// protos JSON encoding:
//
// HTTP | RPC
// -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })`
//
// The special name `*` can be used in the body mapping to define that
// every field not bound by the path template should be mapped to the
// request body.  This enables the following alternative definition of
// the update method:
//
//     service Messaging {
//       rpc UpdateMessage(Message) returns (Message) {
//         option (google.api.http) = {
//           put: "/v1/messages/{message_id}"
//           body: "*"
//         };
//       }
//     }
//     message Message {
//       string message_id = 1;
//       string text = 2;
//     }
//
//
// The following HTTP JSON to RPC mapping is enabled:
//
// HTTP | RPC
// -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")`
//
// Note that when using `*` in the body mapping, it is not possible to
// have HTTP parameters, as all fields not bound by the path end in
// the body. This makes this option more rarely used in practice of
// defining REST APIs. The common usage of `*` is in custom methods
// which don't use the URL at all for transferring data.
//
// It is possible to define multiple HTTP methods for one RPC by using
// the `additional_bindings` option. Example:
//
//     service Messaging {
//       rpc GetMessage(GetMessageRequest) returns (Message) {
//         option (google.api.http) = {
//           get: "/v1/messages/{message_id}"
//           additional_bindings {
//             get: "/v1/users/{user_id}/messages/{message_id}"
//           }
//         };
//       }
//     }
//     message GetMessageRequest {
//       string message_id = 1;
//       string user_id = 2;
//     }
//
//
// This enables the following two alternative HTTP JSON to RPC
// mappings:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")`
//
// # Rules for HTTP mapping
//
// The rules for mapping HTTP path, query parameters, and body fields
// to the request message are as follows:
//
// 1. The `body` field specifies either `*` or a field path, or is
//    omitted. If omitted, it indicates there is no HTTP request body.
// 2. Leaf fields (recursive expansion of nested messages in the
//    request) can be classified into three types:
//     (a) Matched in the URL template.
//     (b) Covered by body (if body is `*`, everything except (a) fields;
//         else everything under the body field)
//     (c) All other fields.
// 3. URL query parameters found in the HTTP request are mapped to (c) fields.
// 4. Any body sent with an HTTP request can contain only (b) fields.
//
// The syntax of the path template is as follows:
//
//     Template = "/" Segments [ Verb ] ;
//     Segments = Segment { "/" Segment } ;
//     Segment  = "*" | "**" | LITERAL | Variable ;
//     Variable = "{" FieldPath [ "=" Segments ] "}" ;
//     FieldPath = IDENT { "." IDENT } ;
//     Verb     = ":" LITERAL ;
//
// The syntax `*` matches a single path segment. The syntax `**` matches zero
// or more path segments, which must be the last part of the path except the
// `Verb`. The syntax `LITERAL` matches literal text in the path.
//
// The syntax `Variable` matches part of the URL path as specified by its
// template. A variable template must not contain other variables. If a variable
// matches a single path segment, its template may be omitted, e.g. `{var}`
// is equivalent to `{var=*}`.
//
// If a variable contains exactly one path segment, such as `"{var}"` or
// `"{var=*}"`, when such a variable is expanded into a URL path, all characters
// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the
// Discovery Document as `{var}`.
//
// If a variable contains one or more path segments, such as `"{var=foo/*}"`
// or `"{var=**}"`, when such a variable is expanded into a URL path, all
// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables
// show up in the Discovery Document as `{+var}`.
//
// NOTE: While the single segment variable matches the semantics of
// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2
// Simple String Expansion, the multi segment variable **does not** match
// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion
// does not expand special characters like `?` and `#`, which would lead
// to invalid URLs.
//
// NOTE: the field paths in variables and in the `body` must not refer to
// repeated fields or map fields.
message HttpRule {
  // Selects methods to which this rule applies.
  //
  // Refer to [selector][google.api.DocumentationRule.selector] for syntax details.
  string selector = 1;

  // Determines the URL pattern is matched by this rules. This pattern can be
  // used with any of the {get|put|post|delete|patch} methods. A custom method
  // can be defined using the 'custom' field.
  oneof pattern {
    // Used for listing and getting information about resources.
    string get = 2;

    // Used for updating a resource.
    string put = 3;

    // Used for creating a resource.
    string post = 4;

    // Used for deleting a resource.
    string delete = 5;

    // Used for updating a resource.
    string patch = 6;

    // The custom pattern is used for specifying an HTTP method that is not
    // included in the `pattern` field, such as HEAD, or "*" to leave the
    // HTTP method unspecified for this rule. The wild-card rule is useful
    // for services that provide content to Web (HTML) clients.
    CustomHttpPattern custom = 8;
  }

  // The name of the request field whose value is mapped to the HTTP body, or
  // `*` for mapping all fields not captured by the path pattern to the HTTP
  // body. NOTE: the referred field must not be a repeated field and must be
  // present at the top-level of request message type.
  string body = 7;

  // Optional. The name of the response field whose value is mapped to the HTTP
  // body of response. Other response fields are ignored. When
  // not set, the response message will be used as HTTP body of response.
  string response_body = 12;

  // Additional HTTP bindings for the selector. Nested bindings must
  // not contain an `additional_bindings` field themselves (that is,
  // the nesting may only be one level deep).
  repeated HttpRule additional_bindings = 11;
}

// A custom pattern is used for defining custom HTTP verb.
message CustomHttpPattern {
  // The name of this custom HTTP verb.
  string kind = 1;

  // The path matched by this custom verb.
  string path = 2;
}


================================================
FILE: app/module/test/service/grpc/google/api/httpbody.proto
================================================
// Copyright 2018 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

syntax = "proto3";

package google.api;

import "google/protobuf/any.proto";

option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody";
option java_multiple_files = true;
option java_outer_classname = "HttpBodyProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";

// Message that represents an arbitrary HTTP body. It should only be used for
// payload formats that can't be represented as JSON, such as raw binary or
// an HTML page.
//
//
// This message can be used both in streaming and non-streaming API methods in
// the request as well as the response.
//
// It can be used as a top-level request field, which is convenient if one
// wants to extract parameters from either the URL or HTTP template into the
// request fields and also want access to the raw HTTP body.
//
// Example:
//
//     message GetResourceRequest {
//       // A unique request id.
//       string request_id = 1;
//
//       // The raw HTTP body is bound to this field.
//       google.api.HttpBody http_body = 2;
//     }
//
//     service ResourceService {
//       rpc GetResource(GetResourceRequest) returns (google.api.HttpBody);
//       rpc UpdateResource(google.api.HttpBody) returns
//       (google.protobuf.Empty);
//     }
//
// Example with streaming methods:
//
//     service CaldavService {
//       rpc GetCalendar(stream google.api.HttpBody)
//         returns (stream google.api.HttpBody);
//       rpc UpdateCalendar(stream google.api.HttpBody)
//         returns (stream google.api.HttpBody);
//     }
//
// Use of this type only changes how the request and response bodies are
// handled, all other features will continue to work unchanged.
message HttpBody {
  // The HTTP Content-Type header value specifying the content type of the body.
  string content_type = 1;

  // The HTTP request/response body as raw binary.
  bytes data = 2;

  // Application specific response metadata. Must be set in the first response
  // for streaming APIs.
  repeated google.protobuf.Any extensions = 3;
}

================================================
FILE: app/module/test/service/grpc/google/protobuf/descriptor.proto
================================================
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.
//
// The messages in this file describe the definitions found in .proto files.
// A valid .proto file can be translated directly to a FileDescriptorProto
// without any other information (e.g. without reading its imports).


syntax = "proto2";

package google.protobuf;

option go_package = "google.golang.org/protobuf/types/descriptorpb";
option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.Reflection";
option objc_class_prefix = "GPB";
option cc_enable_arenas = true;

// descriptor.proto must be optimized for speed because reflection-based
// algorithms don't work during bootstrapping.
option optimize_for = SPEED;

// The protocol compiler can output a FileDescriptorSet containing the .proto
// files it parses.
message FileDescriptorSet {
  repeated FileDescriptorProto file = 1;
}

// Describes a complete .proto file.
message FileDescriptorProto {
  optional string name = 1;     // file name, relative to root of source tree
  optional string package = 2;  // e.g. "foo", "foo.bar", etc.

  // Names of files imported by this file.
  repeated string dependency = 3;
  // Indexes of the public imported files in the dependency list above.
  repeated int32 public_dependency = 10;
  // Indexes of the weak imported files in the dependency list.
  // For Google-internal migration only. Do not use.
  repeated int32 weak_dependency = 11;

  // All top-level definitions in this file.
  repeated DescriptorProto message_type = 4;
  repeated EnumDescriptorProto enum_type = 5;
  repeated ServiceDescriptorProto service = 6;
  repeated FieldDescriptorProto extension = 7;

  optional FileOptions options = 8;

  // This field contains optional information about the original source code.
  // You may safely remove this entire field without harming runtime
  // functionality of the descriptors -- the information is needed only by
  // development tools.
  optional SourceCodeInfo source_code_info = 9;

  // The syntax of the proto file.
  // The supported values are "proto2" and "proto3".
  optional string syntax = 12;
}

// Describes a message type.
message DescriptorProto {
  optional string name = 1;

  repeated FieldDescriptorProto field = 2;
  repeated FieldDescriptorProto extension = 6;

  repeated DescriptorProto nested_type = 3;
  repeated EnumDescriptorProto enum_type = 4;

  message ExtensionRange {
    optional int32 start = 1;  // Inclusive.
    optional int32 end = 2;    // Exclusive.

    optional ExtensionRangeOptions options = 3;
  }
  repeated ExtensionRange extension_range = 5;

  repeated OneofDescriptorProto oneof_decl = 8;

  optional MessageOptions options = 7;

  // Range of reserved tag numbers. Reserved tag numbers may not be used by
  // fields or extension ranges in the same message. Reserved ranges may
  // not overlap.
  message ReservedRange {
    optional int32 start = 1;  // Inclusive.
    optional int32 end = 2;    // Exclusive.
  }
  repeated ReservedRange reserved_range = 9;
  // Reserved field names, which may not be used by fields in the same message.
  // A given name may only be reserved once.
  repeated string reserved_name = 10;
}

message ExtensionRangeOptions {
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;


  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}

// Describes a field within a message.
message FieldDescriptorProto {
  enum Type {
    // 0 is reserved for errors.
    // Order is weird for historical reasons.
    TYPE_DOUBLE = 1;
    TYPE_FLOAT = 2;
    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
    // negative values are likely.
    TYPE_INT64 = 3;
    TYPE_UINT64 = 4;
    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
    // negative values are likely.
    TYPE_INT32 = 5;
    TYPE_FIXED64 = 6;
    TYPE_FIXED32 = 7;
    TYPE_BOOL = 8;
    TYPE_STRING = 9;
    // Tag-delimited aggregate.
    // Group type is deprecated and not supported in proto3. However, Proto3
    // implementations should still be able to parse the group wire format and
    // treat group fields as unknown fields.
    TYPE_GROUP = 10;
    TYPE_MESSAGE = 11;  // Length-delimited aggregate.

    // New in version 2.
    TYPE_BYTES = 12;
    TYPE_UINT32 = 13;
    TYPE_ENUM = 14;
    TYPE_SFIXED32 = 15;
    TYPE_SFIXED64 = 16;
    TYPE_SINT32 = 17;  // Uses ZigZag encoding.
    TYPE_SINT64 = 18;  // Uses ZigZag encoding.
  }

  enum Label {
    // 0 is reserved for errors
    LABEL_OPTIONAL = 1;
    LABEL_REQUIRED = 2;
    LABEL_REPEATED = 3;
  }

  optional string name = 1;
  optional int32 number = 3;
  optional Label label = 4;

  // If type_name is set, this need not be set.  If both this and type_name
  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
  optional Type type = 5;

  // For message and enum types, this is the name of the type.  If the name
  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
  // rules are used to find the type (i.e. first the nested types within this
  // message are searched, then within the parent, on up to the root
  // namespace).
  optional string type_name = 6;

  // For extensions, this is the name of the type being extended.  It is
  // resolved in the same manner as type_name.
  optional string extendee = 2;

  // For numeric types, contains the original text representation of the value.
  // For booleans, "true" or "false".
  // For strings, contains the default text contents (not escaped in any way).
  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
  // TODO(kenton):  Base-64 encode?
  optional string default_value = 7;

  // If set, gives the index of a oneof in the containing type's oneof_decl
  // list.  This field is a member of that oneof.
  optional int32 oneof_index = 9;

  // JSON name of this field. The value is set by protocol compiler. If the
  // user has set a "json_name" option on this field, that option's value
  // will be used. Otherwise, it's deduced from the field's name by converting
  // it to camelCase.
  optional string json_name = 10;

  optional FieldOptions options = 8;

  // If true, this is a proto3 "optional". When a proto3 field is optional, it
  // tracks presence regardless of field type.
  //
  // When proto3_optional is true, this field must be belong to a oneof to
  // signal to old proto3 clients that presence is tracked for this field. This
  // oneof is known as a "synthetic" oneof, and this field must be its sole
  // member (each proto3 optional field gets its own synthetic oneof). Synthetic
  // oneofs exist in the descriptor only, and do not generate any API. Synthetic
  // oneofs must be ordered after all "real" oneofs.
  //
  // For message fields, proto3_optional doesn't create any semantic change,
  // since non-repeated message fields always track presence. However it still
  // indicates the semantic detail of whether the user wrote "optional" or not.
  // This can be useful for round-tripping the .proto file. For consistency we
  // give message fields a synthetic oneof also, even though it is not required
  // to track presence. This is especially important because the parser can't
  // tell if a field is a message or an enum, so it must always create a
  // synthetic oneof.
  //
  // Proto2 optional fields do not set this flag, because they already indicate
  // optional with `LABEL_OPTIONAL`.
  optional bool proto3_optional = 17;
}

// Describes a oneof.
message OneofDescriptorProto {
  optional string name = 1;
  optional OneofOptions options = 2;
}

// Describes an enum type.
message EnumDescriptorProto {
  optional string name = 1;

  repeated EnumValueDescriptorProto value = 2;

  optional EnumOptions options = 3;

  // Range of reserved numeric values. Reserved values may not be used by
  // entries in the same enum. Reserved ranges may not overlap.
  //
  // Note that this is distinct from DescriptorProto.ReservedRange in that it
  // is inclusive such that it can appropriately represent the entire int32
  // domain.
  message EnumReservedRange {
    optional int32 start = 1;  // Inclusive.
    optional int32 end = 2;    // Inclusive.
  }

  // Range of reserved numeric values. Reserved numeric values may not be used
  // by enum values in the same enum declaration. Reserved ranges may not
  // overlap.
  repeated EnumReservedRange reserved_range = 4;

  // Reserved enum value names, which may not be reused. A given name may only
  // be reserved once.
  repeated string reserved_name = 5;
}

// Describes a value within an enum.
message EnumValueDescriptorProto {
  optional string name = 1;
  optional int32 number = 2;

  optional EnumValueOptions options = 3;
}

// Describes a service.
message ServiceDescriptorProto {
  optional string name = 1;
  repeated MethodDescriptorProto method = 2;

  optional ServiceOptions options = 3;
}

// Describes a method of a service.
message MethodDescriptorProto {
  optional string name = 1;

  // Input and output type names.  These are resolved in the same way as
  // FieldDescriptorProto.type_name, but must refer to a message type.
  optional string input_type = 2;
  optional string output_type = 3;

  optional MethodOptions options = 4;

  // Identifies if client streams multiple client messages
  optional bool client_streaming = 5 [default = false];
  // Identifies if server streams multiple server messages
  optional bool server_streaming = 6 [default = false];
}


// ===================================================================
// Options

// Each of the definitions above may have "options" attached.  These are
// just annotations which may cause code to be generated slightly differently
// or may contain hints for code that manipulates protocol messages.
//
// Clients may define custom options as extensions of the *Options messages.
// These extensions may not yet be known at parsing time, so the parser cannot
// store the values in them.  Instead it stores them in a field in the *Options
// message called uninterpreted_option. This field must have the same name
// across all *Options messages. We then use this field to populate the
// extensions when we build a descriptor, at which point all protos have been
// parsed and so all extensions are known.
//
// Extension numbers for custom options may be chosen as follows:
// * For options which will only be used within a single application or
//   organization, or for experimental options, use field numbers 50000
//   through 99999.  It is up to you to ensure that you do not use the
//   same number for multiple options.
// * For options which will be published and used publicly by multiple
//   independent entities, e-mail protobuf-global-extension-registry@google.com
//   to reserve extension numbers. Simply provide your project name (e.g.
//   Objective-C plugin) and your project website (if available) -- there's no
//   need to explain how you intend to use them. Usually you only need one
//   extension number. You can declare multiple options with only one extension
//   number by putting them in a sub-message. See the Custom Options section of
//   the docs for examples:
//   https://developers.google.com/protocol-buffers/docs/proto#options
//   If this turns out to be popular, a web service will be set up
//   to automatically assign option numbers.

message FileOptions {

  // Sets the Java package where classes generated from this .proto will be
  // placed.  By default, the proto package is used, but this is often
  // inappropriate because proto packages do not normally start with backwards
  // domain names.
  optional string java_package = 1;


  // Controls the name of the wrapper Java class generated for the .proto file.
  // That class will always contain the .proto file's getDescriptor() method as
  // well as any top-level extensions defined in the .proto file.
  // If java_multiple_files is disabled, then all the other classes from the
  // .proto file will be nested inside the single wrapper outer class.
  optional string java_outer_classname = 8;

  // If enabled, then the Java code generator will generate a separate .java
  // file for each top-level message, enum, and service defined in the .proto
  // file.  Thus, these types will *not* be nested inside the wrapper class
  // named by java_outer_classname.  However, the wrapper class will still be
  // generated to contain the file's getDescriptor() method as well as any
  // top-level extensions defined in the file.
  optional bool java_multiple_files = 10 [default = false];

  // This option does nothing.
  optional bool java_generate_equals_and_hash = 20 [deprecated=true];

  // If set true, then the Java2 code generator will generate code that
  // throws an exception whenever an attempt is made to assign a non-UTF-8
  // byte sequence to a string field.
  // Message reflection will do the same.
  // However, an extension field still accepts non-UTF-8 byte sequences.
  // This option has no effect on when used with the lite runtime.
  optional bool java_string_check_utf8 = 27 [default = false];


  // Generated classes can be optimized for speed or code size.
  enum OptimizeMode {
    SPEED = 1;         // Generate complete code for parsing, serialization,
                       // etc.
    CODE_SIZE = 2;     // Use ReflectionOps to implement these methods.
    LITE_RUNTIME = 3;  // Generate code using MessageLite and the lite runtime.
  }
  optional OptimizeMode optimize_for = 9 [default = SPEED];

  // Sets the Go package where structs generated from this .proto will be
  // placed. If omitted, the Go package will be derived from the following:
  //   - The basename of the package import path, if provided.
  //   - Otherwise, the package statement in the .proto file, if present.
  //   - Otherwise, the basename of the .proto file, without extension.
  optional string go_package = 11;




  // Should generic services be generated in each language?  "Generic" services
  // are not specific to any particular RPC system.  They are generated by the
  // main code generators in each language (without additional plugins).
  // Generic services were the only kind of service generation supported by
  // early versions of google.protobuf.
  //
  // Generic services are now considered deprecated in favor of using plugins
  // that generate code specific to your particular RPC system.  Therefore,
  // these default to false.  Old code which depends on generic services should
  // explicitly set them to true.
  optional bool cc_generic_services = 16 [default = false];
  optional bool java_generic_services = 17 [default = false];
  optional bool py_generic_services = 18 [default = false];
  optional bool php_generic_services = 42 [default = false];

  // Is this file deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for everything in the file, or it will be completely ignored; in the very
  // least, this is a formalization for deprecating files.
  optional bool deprecated = 23 [default = false];

  // Enables the use of arenas for the proto messages in this file. This applies
  // only to generated classes for C++.
  optional bool cc_enable_arenas = 31 [default = true];


  // Sets the objective c class prefix which is prepended to all objective c
  // generated classes from this .proto. There is no default.
  optional string objc_class_prefix = 36;

  // Namespace for generated classes; defaults to the package.
  optional string csharp_namespace = 37;

  // By default Swift generators will take the proto package and CamelCase it
  // replacing '.' with underscore and use that to prefix the types/symbols
  // defined. When this options is provided, they will use this value instead
  // to prefix the types/symbols defined.
  optional string swift_prefix = 39;

  // Sets the php class prefix which is prepended to all php generated classes
  // from this .proto. Default is empty.
  optional string php_class_prefix = 40;

  // Use this option to change the namespace of php generated classes. Default
  // is empty. When this option is empty, the package name will be used for
  // determining the namespace.
  optional string php_namespace = 41;

  // Use this option to change the namespace of php generated metadata classes.
  // Default is empty. When this option is empty, the proto file name will be
  // used for determining the namespace.
  optional string php_metadata_namespace = 44;

  // Use this option to change the package of ruby generated classes. Default
  // is empty. When this option is not set, the package name will be used for
  // determining the ruby package.
  optional string ruby_package = 45;


  // The parser stores options it doesn't recognize here.
  // See the documentation for the "Options" section above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message.
  // See the documentation for the "Options" section above.
  extensions 1000 to max;

  reserved 38;
}

message MessageOptions {
  // Set true to use the old proto1 MessageSet wire format for extensions.
  // This is provided for backwards-compatibility with the MessageSet wire
  // format.  You should not use this for any other reason:  It's less
  // efficient, has fewer features, and is more complicated.
  //
  // The message must be defined exactly as follows:
  //   message Foo {
  //     option message_set_wire_format = true;
  //     extensions 4 to max;
  //   }
  // Note that the message cannot have any defined fields; MessageSets only
  // have extensions.
  //
  // All extensions of your type must be singular messages; e.g. they cannot
  // be int32s, enums, or repeated messages.
  //
  // Because this is an option, the above two restrictions are not enforced by
  // the protocol compiler.
  optional bool message_set_wire_format = 1 [default = false];

  // Disables the generation of the standard "descriptor()" accessor, which can
  // conflict with a field of the same name.  This is meant to make migration
  // from proto1 easier; new code should avoid fields named "descriptor".
  optional bool no_standard_descriptor_accessor = 2 [default = false];

  // Is this message deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for the message, or it will be completely ignored; in the very least,
  // this is a formalization for deprecating messages.
  optional bool deprecated = 3 [default = false];

  reserved 4, 5, 6;

  // Whether the message is an automatically generated map entry type for the
  // maps field.
  //
  // For maps fields:
  //     map<KeyType, ValueType> map_field = 1;
  // The parsed descriptor looks like:
  //     message MapFieldEntry {
  //         option map_entry = true;
  //         optional KeyType key = 1;
  //         optional ValueType value = 2;
  //     }
  //     repeated MapFieldEntry map_field = 1;
  //
  // Implementations may choose not to generate the map_entry=true message, but
  // use a native map in the target language to hold the keys and values.
  // The reflection APIs in such implementations still need to work as
  // if the field is a repeated message field.
  //
  // NOTE: Do not set the option in .proto files. Always use the maps syntax
  // instead. The option should only be implicitly set by the proto compiler
  // parser.
  optional bool map_entry = 7;

  reserved 8;  // javalite_serializable
  reserved 9;  // javanano_as_lite


  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}

message FieldOptions {
  // The ctype option instructs the C++ code generator to use a different
  // representation of the field than it normally would.  See the specific
  // options below.  This option is not yet implemented in the open source
  // release -- sorry, we'll try to include it in a future version!
  optional CType ctype = 1 [default = STRING];
  enum CType {
    // Default mode.
    STRING = 0;

    CORD = 1;

    STRING_PIECE = 2;
  }
  // The packed option can be enabled for repeated primitive fields to enable
  // a more efficient representation on the wire. Rather than repeatedly
  // writing the tag and type for each element, the entire array is encoded as
  // a single length-delimited blob. In proto3, only explicit setting it to
  // false will avoid using packed encoding.
  optional bool packed = 2;

  // The jstype option determines the JavaScript type used for values of the
  // field.  The option is permitted only for 64 bit integral and fixed types
  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
  // is represented as JavaScript string, which avoids loss of precision that
  // can happen when a large value is converted to a floating point JavaScript.
  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
  // use the JavaScript "number" type.  The behavior of the default option
  // JS_NORMAL is implementation dependent.
  //
  // This option is an enum to permit additional types to be added, e.g.
  // goog.math.Integer.
  optional JSType jstype = 6 [default = JS_NORMAL];
  enum JSType {
    // Use the default type.
    JS_NORMAL = 0;

    // Use JavaScript strings.
    JS_STRING = 1;

    // Use JavaScript numbers.
    JS_NUMBER = 2;
  }

  // Should this field be parsed lazily?  Lazy applies only to message-type
  // fields.  It means that when the outer message is initially parsed, the
  // inner message's contents will not be parsed but instead stored in encoded
  // form.  The inner message will actually be parsed when it is first accessed.
  //
  // This is only a hint.  Implementations are free to choose whether to use
  // eager or lazy parsing regardless of the value of this option.  However,
  // setting this option true suggests that the protocol author believes that
  // using lazy parsing on this field is worth the additional bookkeeping
  // overhead typically needed to implement it.
  //
  // This option does not affect the public interface of any generated code;
  // all method signatures remain the same.  Furthermore, thread-safety of the
  // interface is not affected by this option; const methods remain safe to
  // call from multiple threads concurrently, while non-const methods continue
  // to require exclusive access.
  //
  //
  // Note that implementations may choose not to check required fields within
  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
  // may return true even if the inner message has missing required fields.
  // This is necessary because otherwise the inner message would have to be
  // parsed in order to perform the check, defeating the purpose of lazy
  // parsing.  An implementation which chooses not to check required fields
  // must be consistent about it.  That is, for any particular sub-message, the
  // implementation must either *always* check its required fields, or *never*
  // check its required fields, regardless of whether or not the message has
  // been parsed.
  optional bool lazy = 5 [default = false];

  // Is this field deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for accessors, or it will be completely ignored; in the very least, this
  // is a formalization for deprecating fields.
  optional bool deprecated = 3 [default = false];

  // For Google-internal migration only. Do not use.
  optional bool weak = 10 [default = false];


  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;

  reserved 4;  // removed jtype
}

message OneofOptions {
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}

message EnumOptions {

  // Set this option to true to allow mapping different tag names to the same
  // value.
  optional bool allow_alias = 2;

  // Is this enum deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for the enum, or it will be completely ignored; in the very least, this
  // is a formalization for deprecating enums.
  optional bool deprecated = 3 [default = false];

  reserved 5;  // javanano_as_lite

  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}

message EnumValueOptions {
  // Is this enum value deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for the enum value, or it will be completely ignored; in the very least,
  // this is a formalization for deprecating enum values.
  optional bool deprecated = 1 [default = false];

  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}

message ServiceOptions {

  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
  //   framework.  We apologize for hoarding these numbers to ourselves, but
  //   we were already using them long before we decided to release Protocol
  //   Buffers.

  // Is this service deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for the service, or it will be completely ignored; in the very least,
  // this is a formalization for deprecating services.
  optional bool deprecated = 33 [default = false];

  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}

message MethodOptions {

  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
  //   framework.  We apologize for hoarding these numbers to ourselves, but
  //   we were already using them long before we decided to release Protocol
  //   Buffers.

  // Is this method deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for the method, or it will be completely ignored; in the very least,
  // this is a formalization for deprecating methods.
  optional bool deprecated = 33 [default = false];

  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
  // or neither? HTTP based RPC implementation may choose GET verb for safe
  // methods, and PUT verb for idempotent methods instead of the default POST.
  enum IdempotencyLevel {
    IDEMPOTENCY_UNKNOWN = 0;
    NO_SIDE_EFFECTS = 1;  // implies idempotent
    IDEMPOTENT = 2;       // idempotent, but may have side effects
  }
  optional IdempotencyLevel idempotency_level = 34
      [default = IDEMPOTENCY_UNKNOWN];

  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;

  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
}


// A message representing a option the parser does not recognize. This only
// appears in options protos created by the compiler::Parser class.
// DescriptorPool resolves these when building Descriptor objects. Therefore,
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
// in them.
message UninterpretedOption {
  // The name of the uninterpreted option.  Each string represents a segment in
  // a dot-separated name.  is_extension is true iff a segment represents an
  // extension (denoted with parentheses in options specs in .proto files).
  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
  // "foo.(bar.baz).qux".
  message NamePart {
    required string name_part = 1;
    required bool is_extension = 2;
  }
  repeated NamePart name = 2;

  // The value of the uninterpreted option, in whatever type the tokenizer
  // identified it as during parsing. Exactly one of these should be set.
  optional string identifier_value = 3;
  optional uint64 positive_int_value = 4;
  optional int64 negative_int_value = 5;
  optional double double_value = 6;
  optional bytes string_value = 7;
  optional string aggregate_value = 8;
}

// ===================================================================
// Optional source code info

// Encapsulates information about the original source file from which a
// FileDescriptorProto was generated.
message SourceCodeInfo {
  // A Location identifies a piece of source code in a .proto file which
  // corresponds to a particular definition.  This information is intended
  // to be useful to IDEs, code indexers, documentation generators, and similar
  // tools.
  //
  // For example, say we have a file like:
  //   message Foo {
  //     optional string foo = 1;
  //   }
  // Let's look at just the field definition:
  //   optional string foo = 1;
  //   ^       ^^     ^^  ^  ^^^
  //   a       bc     de  f  ghi
  // We have the following locations:
  //   span   path               represents
  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
  //
  // Notes:
  // - A location may refer to a repeated field itself (i.e. not to any
  //   particular index within it).  This is used whenever a set of elements are
  //   logically enclosed in a single code segment.  For example, an entire
  //   extend block (possibly containing multiple extension definitions) will
  //   have an outer location whose path refers to the "extensions" repeated
  //   field without an index.
  // - Multiple locations may have the same path.  This happens when a single
  //   logical declaration is spread out across multiple places.  The most
  //   obvious example is the "extend" block again -- there may be multiple
  //   extend blocks in the same scope, each of which will have the same path.
  // - A location's span is not always a subset of its parent's span.  For
  //   example, the "extendee" of an extension declaration appears at the
  //   beginning of the "extend" block and is shared by all extensions within
  //   the block.
  // - Just because a location's span is a subset of some other location's span
  //   does not mean that it is a descendant.  For example, a "group" defines
  //   both a type and a field in a single declaration.  Thus, the locations
  //   corresponding to the type and field and their components will overlap.
  // - Code which tries to interpret locations should probably be designed to
  //   ignore those that it doesn't understand, as more types of locations could
  //   be recorded in the future.
  repeated Location location = 1;
  message Location {
    // Identifies which part of the FileDescriptorProto was defined at this
    // location.
    //
    // Each element is a field number or an index.  They form a path from
    // the root FileDescriptorProto to the place where the definition.  For
    // example, this path:
    //   [ 4, 3, 2, 7, 1 ]
    // refers to:
    //   file.message_type(3)  // 4, 3
    //       .field(7)         // 2, 7
    //       .name()           // 1
    // This is because FileDescriptorProto.message_type has field number 4:
    //   repeated DescriptorProto message_type = 4;
    // and DescriptorProto.field has field number 2:
    //   repeated FieldDescriptorProto field = 2;
    // and FieldDescriptorProto.name has field number 1:
    //   optional string name = 1;
    //
    // Thus, the above path gives the location of a field name.  If we removed
    // the last element:
    //   [ 4, 3, 2, 7 ]
    // this path refers to the whole field declaration (from the beginning
    // of the label to the terminating semicolon).
    repeated int32 path = 1 [packed = true];

    // Always has exactly three or four elements: start line, start column,
    // end line (optional, otherwise assumed same as start line), end column.
    // These are packed into a single field for efficiency.  Note that line
    // and column numbers are zero-based -- typically you will want to add
    // 1 to each before displaying to a user.
    repeated int32 span = 2 [packed = true];

    // If this SourceCodeInfo represents a complete declaration, these are any
    // comments appearing before and after the declaration which appear to be
    // attached to the declaration.
    //
    // A series of line comments appearing on consecutive lines, with no other
    // tokens appearing on those lines, will be treated as a single comment.
    //
    // leading_detached_comments will keep paragraphs of comments that appear
    // before (but not connected to) the current element. Each paragraph,
    // separated by empty lines, will be one comment element in the repeated
    // field.
    //
    // Only the comment content is provided; comment markers (e.g. //) are
    // stripped out.  For block comments, leading whitespace and an asterisk
    // will be stripped from the beginning of each line other than the first.
    // Newlines are included in the output.
    //
    // Examples:
    //
    //   optional int32 foo = 1;  // Comment attached to foo.
    //   // Comment attached to bar.
    //   optional int32 bar = 2;
    //
    //   optional string baz = 3;
    //   // Comment attached to baz.
    //   // Another line attached to baz.
    //
    //   // Comment attached to qux.
    //   //
    //   // Another line attached to qux.
    //   optional double qux = 4;
    //
    //   // Detached comment for corge. This is not leading or trailing comments
    //   // to qux or corge because there are blank lines separating it from
    //   // both.
    //
    //   // Detached comment for corge paragraph 2.
    //
    //   optional string corge = 5;
    //   /* Block comment attached
    //    * to corge.  Leading asterisks
    //    * will be removed. */
    //   /* Block comment attached to
    //    * grault. */
    //   optional int32 grault = 6;
    //
    //   // ignored detached comments.
    optional string leading_comments = 3;
    optional string trailing_comments = 4;
    repeated string leading_detached_comments = 6;
  }
}

// Describes the relationship between generated code and its original source
// file. A GeneratedCodeInfo message is associated with only one generated
// source file, but may contain references to different source .proto files.
message GeneratedCodeInfo {
  // An Annotation connects some span of text in generated code to an element
  // of its generating .proto file.
  repeated Annotation annotation = 1;
  message Annotation {
    // Identifies the element in the original source .proto file. This field
    // is formatted the same as SourceCodeInfo.Location.path.
    repeated int32 path = 1 [packed = true];

    // Identifies the filesystem path to the original source .proto.
    optional string source_file = 2;

    // Identifies the starting offset in bytes in the generated code
    // that relates to the identified object.
    optional int32 begin = 3;

    // Identifies the ending offset in bytes in the generated code that
    // relates to the identified offset. The end offset should be one past
    // the last relevant byte (so the length of the text = end - begin).
    optional int32 end = 4;
  }
}


================================================
FILE: app/module/test/service/grpc/grpc.go
================================================
package grpc

import (
	"context"

	"google.golang.org/grpc"

	pb "github.com/why444216978/gin-api/app/module/test/service/grpc/helloworld"
	serverGRPC "github.com/why444216978/gin-api/server/grpc"
)

type Server struct {
	pb.UnimplementedGreeterServer
}

func (s *Server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	return &pb.HelloReply{Message: in.Name + " world"}, nil
}

func RegisterServer(s *grpc.Server) {
	pb.RegisterGreeterServer(s, &Server{})
}

func NewService() serverGRPC.Register {
	return serverGRPC.NewRegister(RegisterServer, pb.RegisterGreeterHandlerFromEndpoint)
}


================================================
FILE: app/module/test/service/grpc/helloworld/hello_world.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.27.1
// 	protoc        v3.18.0
// source: helloworld/hello_world.proto

package helloworld

import (
	_ "google.golang.org/genproto/googleapis/api/annotations"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// The request message containing the user's name
type HelloRequest struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}

func (x *HelloRequest) Reset() {
	*x = HelloRequest{}
	if protoimpl.UnsafeEnabled {
		mi := &file_helloworld_hello_world_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *HelloRequest) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*HelloRequest) ProtoMessage() {}

func (x *HelloRequest) ProtoReflect() protoreflect.Message {
	mi := &file_helloworld_hello_world_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
	return file_helloworld_hello_world_proto_rawDescGZIP(), []int{0}
}

func (x *HelloRequest) GetName() string {
	if x != nil {
		return x.Name
	}
	return ""
}

// The response message containing the greetings
type HelloReply struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}

func (x *HelloReply) Reset() {
	*x = HelloReply{}
	if protoimpl.UnsafeEnabled {
		mi := &file_helloworld_hello_world_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *HelloReply) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*HelloReply) ProtoMessage() {}

func (x *HelloReply) ProtoReflect() protoreflect.Message {
	mi := &file_helloworld_hello_world_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) {
	return file_helloworld_hello_world_proto_rawDescGZIP(), []int{1}
}

func (x *HelloReply) GetMessage() string {
	if x != nil {
		return x.Message
	}
	return ""
}

var File_helloworld_hello_world_proto protoreflect.FileDescriptor

var file_helloworld_hello_world_proto_rawDesc = []byte{
	0x0a, 0x1c, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65, 0x6c,
	0x6c, 0x6f, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a,
	0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67,
	0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
	0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c,
	0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a,
	0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
	0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
	0x73, 0x61, 0x67, 0x65, 0x32, 0x61, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65, 0x72, 0x12,
	0x56, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x18, 0x2e, 0x68, 0x65,
	0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65,
	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72,
	0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82,
	0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70,
	0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x42, 0x19, 0x5a, 0x17, 0x2e, 0x2f, 0x68, 0x65, 0x6c,
	0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x3b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72,
	0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_helloworld_hello_world_proto_rawDescOnce sync.Once
	file_helloworld_hello_world_proto_rawDescData = file_helloworld_hello_world_proto_rawDesc
)

func file_helloworld_hello_world_proto_rawDescGZIP() []byte {
	file_helloworld_hello_world_proto_rawDescOnce.Do(func() {
		file_helloworld_hello_world_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_hello_world_proto_rawDescData)
	})
	return file_helloworld_hello_world_proto_rawDescData
}

var file_helloworld_hello_world_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_helloworld_hello_world_proto_goTypes = []interface{}{
	(*HelloRequest)(nil), // 0: helloworld.HelloRequest
	(*HelloReply)(nil),   // 1: helloworld.HelloReply
}
var file_helloworld_hello_world_proto_depIdxs = []int32{
	0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest
	1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply
	1, // [1:2] is the sub-list for method output_type
	0, // [0:1] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_helloworld_hello_world_proto_init() }
func file_helloworld_hello_world_proto_init() {
	if File_helloworld_hello_world_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_helloworld_hello_world_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*HelloRequest); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_helloworld_hello_world_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*HelloReply); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_helloworld_hello_world_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   2,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_helloworld_hello_world_proto_goTypes,
		DependencyIndexes: file_helloworld_hello_world_proto_depIdxs,
		MessageInfos:      file_helloworld_hello_world_proto_msgTypes,
	}.Build()
	File_helloworld_hello_world_proto = out.File
	file_helloworld_hello_world_proto_rawDesc = nil
	file_helloworld_hello_world_proto_goTypes = nil
	file_helloworld_hello_world_proto_depIdxs = nil
}


================================================
FILE: app/module/test/service/grpc/helloworld/hello_world.pb.gw.go
================================================
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: helloworld/hello_world.proto

/*
Package helloworld is a reverse proxy.

It translates gRPC into RESTful JSON APIs.
*/
package helloworld

import (
	"context"
	"io"
	"net/http"

	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/grpclog"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/proto"
)

// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join

var (
	filter_Greeter_SayHello_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)

func request_Greeter_SayHello_0(ctx context.Context, marshaler runtime.Marshaler, client GreeterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
	var protoReq HelloRequest
	var metadata runtime.ServerMetadata

	if err := req.ParseForm(); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Greeter_SayHello_0); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}

	msg, err := client.SayHello(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
	return msg, metadata, err

}

func local_request_Greeter_SayHello_0(ctx context.Context, marshaler runtime.Marshaler, server GreeterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
	var protoReq HelloRequest
	var metadata runtime.ServerMetadata

	if err := req.ParseForm(); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Greeter_SayHello_0); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}

	msg, err := server.SayHello(ctx, &protoReq)
	return msg, metadata, err

}

// RegisterGreeterHandlerServer registers the http handlers for service Greeter to "mux".
// UnaryRPC     :call GreeterServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterGreeterHandlerFromEndpoint instead.
func RegisterGreeterHandlerServer(ctx context.Context, mux *runtime.ServeMux, server GreeterServer) error {

	mux.Handle("GET", pattern_Greeter_SayHello_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
		ctx, cancel := context.WithCancel(req.Context())
		defer cancel()
		var stream runtime.ServerTransportStream
		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/helloworld.Greeter/SayHello", runtime.WithHTTPPathPattern("/v1/example/echo"))
		if err != nil {
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
			return
		}
		resp, md, err := local_request_Greeter_SayHello_0(rctx, inboundMarshaler, server, req, pathParams)
		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
		ctx = runtime.NewServerMetadataContext(ctx, md)
		if err != nil {
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
			return
		}

		forward_Greeter_SayHello_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)

	})

	return nil
}

// RegisterGreeterHandlerFromEndpoint is same as RegisterGreeterHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterGreeterHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
	conn, err := grpc.Dial(endpoint, opts...)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			if cerr := conn.Close(); cerr != nil {
				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
			}
			return
		}
		go func() {
			<-ctx.Done()
			if cerr := conn.Close(); cerr != nil {
				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
			}
		}()
	}()

	return RegisterGreeterHandler(ctx, mux, conn)
}

// RegisterGreeterHandler registers the http handlers for service Greeter to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterGreeterHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
	return RegisterGreeterHandlerClient(ctx, mux, NewGreeterClient(conn))
}

// RegisterGreeterHandlerClient registers the http handlers for service Greeter
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "GreeterClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "GreeterClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "GreeterClient" to call the correct interceptors.
func RegisterGreeterHandlerClient(ctx context.Context, mux *runtime.ServeMux, client GreeterClient) error {

	mux.Handle("GET", pattern_Greeter_SayHello_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
		ctx, cancel := context.WithCancel(req.Context())
		defer cancel()
		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/helloworld.Greeter/SayHello", runtime.WithHTTPPathPattern("/v1/example/echo"))
		if err != nil {
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
			return
		}
		resp, md, err := request_Greeter_SayHello_0(rctx, inboundMarshaler, client, req, pathParams)
		ctx = runtime.NewServerMetadataContext(ctx, md)
		if err != nil {
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
			return
		}

		forward_Greeter_SayHello_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)

	})

	return nil
}

var (
	pattern_Greeter_SayHello_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo"}, ""))
)

var (
	forward_Greeter_SayHello_0 = runtime.ForwardResponseMessage
)


================================================
FILE: app/module/test/service/grpc/helloworld/hello_world.proto
================================================
syntax = "proto3";

option go_package="./helloworld;helloworld";
package helloworld;

import "google/api/annotations.proto";

service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/example/echo"
    };
  }
}

// The request message containing the user's name
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

================================================
FILE: app/module/test/service/grpc/helloworld/hello_world_grpc.pb.go
================================================
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package helloworld

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7

// GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type GreeterClient interface {
	// Sends a greeting
	SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}

type greeterClient struct {
	cc grpc.ClientConnInterface
}

func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
	return &greeterClient{cc}
}

func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
	out := new(HelloReply)
	err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// GreeterServer is the server API for Greeter service.
// All implementations must embed UnimplementedGreeterServer
// for forward compatibility
type GreeterServer interface {
	// Sends a greeting
	SayHello(context.Context, *HelloRequest) (*HelloReply, error)
	mustEmbedUnimplementedGreeterServer()
}

// UnimplementedGreeterServer must be embedded to have forward compatible implementations.
type UnimplementedGreeterServer struct {
}

func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}
func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {}

// UnsafeGreeterServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to GreeterServer will
// result in compilation errors.
type UnsafeGreeterServer interface {
	mustEmbedUnimplementedGreeterServer()
}

func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
	s.RegisterService(&Greeter_ServiceDesc, srv)
}

func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HelloRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GreeterServer).SayHello(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/helloworld.Greeter/SayHello",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// Greeter_ServiceDesc is the grpc.ServiceDesc for Greeter service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Greeter_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "helloworld.Greeter",
	HandlerType: (*GreeterServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "SayHello",
			Handler:    _Greeter_SayHello_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "helloworld/hello_world.proto",
}


================================================
FILE: app/resource/resource.go
================================================
package resource

import (
	"github.com/go-redis/redis/v8"

	httpClient "github.com/why444216978/gin-api/client/http"
	"github.com/why444216978/gin-api/library/cache"
	"github.com/why444216978/gin-api/library/etcd"
	"github.com/why444216978/gin-api/library/lock"
	"github.com/why444216978/gin-api/library/logger"
	"github.com/why444216978/gin-api/library/orm"
	"github.com/why444216978/gin-api/library/queue"
	"github.com/why444216978/gin-api/library/registry"
)

var (
	TestDB        *orm.Orm
	RedisDefault  *redis.Client
	Etcd          *etcd.Etcd
	ClientHTTP    httpClient.Client
	ServiceLogger logger.Logger
	RedisLock     lock.Locker
	RedisCache    cache.Cacher
	Registrar     registry.Registrar
	RabbitMQ      queue.Queue
)


================================================
FILE: app/response/response.go
================================================
package response

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"github.com/why444216978/gin-api/server/http/response"
)

const (
	CodeSuccess     response.Code = 0
	CodeParams      response.Code = 1
	CodeUriNotFound response.Code = http.StatusNotFound
	CodeServer      response.Code = http.StatusInternalServerError
	CodeUnavailable response.Code = http.StatusServiceUnavailable
	CodeTimeout     response.Code = http.StatusGatewayTimeout
)

var codeToast = map[response.Code]string{
	CodeSuccess:     "success",
	CodeParams:      "参数错误",
	CodeUriNotFound: "资源不存在",
	CodeUnavailable: "服务器暂时不可用",
	CodeTimeout:     "请求超时",
	CodeServer:      "服务器错误",
}

func ResponseJSON(c *gin.Context, code response.Code, data interface{}, err *response.ResponseError) {
	if err == nil {
		err = response.WrapToast(nil, codeToast[code])
	}

	response.ResponseJSON(c, code, data, err)
}


================================================
FILE: app/router/router.go
================================================
package router

import (
	"github.com/gin-gonic/gin"

	conn "github.com/why444216978/gin-api/app/module/goods/api"
	ping "github.com/why444216978/gin-api/app/module/ping/api"
	test "github.com/why444216978/gin-api/app/module/test/api"
)

func RegisterRouter(server *gin.Engine) {
	pingGroup := server.Group("/ping")
	{
		pingGroup.GET("", ping.Ping)
		pingGroup.GET("/rpc", ping.RPC)
	}

	testGroup := server.Group("/test")
	{
		testGroup.POST("/rpc", test.Rpc)
		testGroup.POST("/rpc1", test.Rpc1)
		testGroup.POST("/panic", test.Panic)
		testGroup.POST("/conn", conn.Do)
	}
}


================================================
FILE: app/rpc/gin-api/test.go
================================================
package gin_api

import (
	"context"
	"fmt"
	"net/http"
	"time"

	jsonCodec "github.com/why444216978/codec/json"

	"github.com/why444216978/gin-api/app/resource"
	httpClient "github.com/why444216978/gin-api/client/http"
	"github.com/why444216978/gin-api/library/logger"
)

const (
	serviceName = "gin-api-dev"
)

func RPC(ctx context.Context) (resp *httpClient.Response, err error) {
	req := httpClient.Request{
		URI:     fmt.Sprintf("/test/rpc1?logid=%s", logger.ValueLogID(ctx)),
		Method:  http.MethodPost,
		Header:  nil,
		Timeout: time.Second,
		Body:    map[string]interface{}{"rpc": "rpc"},
		Codec:   jsonCodec.JSONCodec{},
	}
	resp = &httpClient.Response{
		Body:  new(map[string]interface{}),
		Codec: jsonCodec.JSONCodec{},
	}

	if err = resource.ClientHTTP.Send(ctx, serviceName, req, resp); err != nil {
		return
	}

	return
}

func RPC1(ctx context.Context) (resp *httpClient.Response, err error) {
	req := httpClient.Request{
		URI:     fmt.Sprintf("/test/conn?logid=%s", logger.ValueLogID(ctx)),
		Method:  http.MethodPost,
		Header:  nil,
		Timeout: time.Second,
		Body:    map[string]interface{}{"rpc1": "rpc1"},
		Codec:   jsonCodec.JSONCodec{},
	}

	resp = &httpClient.Response{
		Body:  new(map[string]interface{}),
		Codec: jsonCodec.JSONCodec{},
	}

	if err = resource.ClientHTTP.Send(ctx, serviceName, req, resp); err != nil {
		return
	}

	return
}

func Ping(ctx context.Context) (resp *httpClient.Response, err error) {
	req := httpClient.Request{
		URI:     fmt.Sprintf("/ping?logid=%s", logger.ValueLogID(ctx)),
		Method:  http.MethodGet,
		Header:  nil,
		Timeout: time.Second,
		Body:    map[string]interface{}{"rpc1": "rpc1"},
		Codec:   jsonCodec.JSONCodec{},
	}

	resp = &httpClient.Response{
		Body:  new(map[string]interface{}),
		Codec: jsonCodec.JSONCodec{},
	}

	if err = resource.ClientHTTP.Send(ctx, serviceName, req, resp); err != nil {
		return
	}

	return
}


================================================
FILE: bootstrap/app.go
================================================
package bootstrap

import (
	"context"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/pkg/errors"
	"github.com/why444216978/go-util/assert"
	"golang.org/x/sync/errgroup"

	"github.com/why444216978/gin-api/library/registry"
	"github.com/why444216978/gin-api/server"
)

type Option struct{}

func defaultOption() *Option {
	return &Option{}
}

type OptionFunc func(*Option)

type App struct {
	opt       *Option
	ctx       context.Context
	server    server.Server
	registrar registry.Registrar
	cancel    func()
}

func NewApp(srv server.Server, registrar registry.Registrar, opts ...OptionFunc) *App {
	opt := defaultOption()
	for _, o := range opts {
		o(opt)
	}

	ctx, cancel := context.WithCancel(context.Background())

	app := &App{
		opt:    opt,
		ctx:    ctx,
		cancel: cancel,
		server: srv,
	}

	return app
}

func (app *App) Start() error {
	g, _ := errgroup.WithContext(app.ctx)
	g.Go(func() (err error) {
		return app.start()
	})
	g.Go(func() (err error) {
		return app.registerSignal()
	})
	g.Go(func() (err error) {
		return app.registerService()
	})
	g.Go(func() (err error) {
		return app.shutdown()
	})
	return g.Wait()
}

func (a *App) start() error {
	return a.server.Start()
}

func (a *App) registerSignal() (err error) {
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)

	err = errors.Errorf("%s: exit by signal %v\n", time.Now().Format("2006-01-02 15:04:05"), <-ch)

	// trigger shutdown
	a.cancel()

	return
}

func (a *App) registerService() (err error) {
	if assert.IsNil(a.registrar) {
		return
	}

	return a.registrar.Register(a.ctx)
}

func (a *App) shutdown() (err error) {
	<-a.ctx.Done()

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()

	// server shutdown
	err = a.server.Close()

	// clean resource
	for _, f := range server.CloseFunc {
		_ = f(ctx)
	}

	return
}


================================================
FILE: bootstrap/init.go
================================================
package bootstrap

import (
	"log"
	"syscall"

	"github.com/why444216978/gin-api/library/app"
	"github.com/why444216978/gin-api/library/config"
)

func Init(env string, load func() error) (err error) {
	log.Printf("Actual pid is %d", syscall.Getpid())

	config.Init(env)

	if err = app.InitApp(); err != nil {
		return
	}

	if err = load(); err != nil {
		return
	}

	return
}


================================================
FILE: client/grpc/conn.go
================================================
package client

import (
	"context"

	"google.golang.org/grpc"

	serverGRPC "github.com/why444216978/gin-api/server/grpc"
)

func Conn(ctx context.Context, target string) (cc *grpc.ClientConn, err error) {
	// TODO resolver
	cc, err = grpc.DialContext(ctx, target, serverGRPC.NewDialOption()...)
	if err != nil {
		return
	}

	return
}


================================================
FILE: client/http/client.go
================================================
package http

import (
	"context"
	"net/http"
	"time"

	"github.com/why444216978/codec"
)

type Request struct {
	URI     string
	Method  string
	Header  http.Header
	Timeout time.Duration
	Body    interface{}
	Codec   codec.Codec
}

type Response struct {
	HTTPCode int
	Body     interface{}
	Codec    codec.Codec
}

type Client interface {
	Send(ctx context.Context, serviceName string, request Request, response *Response) (err error)
}


================================================
FILE: client/http/plugin.go
================================================
package http

import (
	"context"
	"net/http"

	jaeger "github.com/why444216978/gin-api/library/jaeger/http"
	"github.com/why444216978/gin-api/library/logger"
)

type BeforeRequestPlugin interface {
	Handle(ctx context.Context, req *http.Request) error
}

type AfterRequestPlugin interface {
	Handle(ctx context.Context, req *http.Request, resp *http.Response) error
}

type JaegerBeforePlugin struct{}

var _ BeforeRequestPlugin = (*JaegerBeforePlugin)(nil)

func (*JaegerBeforePlugin) Handle(ctx context.Context, req *http.Request) error {
	logID := logger.ValueLogID(ctx)
	req.Header.Add(logger.LogHeader, logID)
	return jaeger.InjectHTTP(ctx, req, logID)
}


================================================
FILE: client/http/transport/transport.go
================================================
package transport

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"net"
	"net/http"
	"strconv"
	"time"

	"github.com/why444216978/go-util/assert"

	client "github.com/why444216978/gin-api/client/http"
	"github.com/why444216978/gin-api/library/logger"
	loggerRPC "github.com/why444216978/gin-api/library/logger/zap/rpc"
	"github.com/why444216978/gin-api/library/servicer"
	timeoutLib "github.com/why444216978/gin-api/server/http/middleware/timeout"
)

type RPC struct {
	logger        logger.Logger
	beforePlugins []client.BeforeRequestPlugin
	afterPlugins  []client.AfterRequestPlugin
}

type Option func(r *RPC)

func WithLogger(logger *loggerRPC.RPCLogger) Option {
	return func(r *RPC) { r.logger = logger }
}

func WithBeforePlugins(plugins ...client.BeforeRequestPlugin) Option {
	return func(r *RPC) { r.beforePlugins = plugins }
}

func WithAfterPlugins(plugins ...client.AfterRequestPlugin) Option {
	return func(r *RPC) { r.afterPlugins = plugins }
}

func New(opts ...Option) *RPC {
	r := &RPC{}
	for _, o := range opts {
		o(r)
	}

	return r
}

// Send is send HTTP request
func (r *RPC) Send(ctx context.Context, serviceName string, request client.Request, response *client.Response) (err error) {
	var (
		cost int64
		node = &servicer.Node{}
	)

	if response == nil {
		return errors.New("response is nil")
	}

	if assert.IsNil(request.Codec) {
		return errors.New("request.Codec is nil")
	}

	if assert.IsNil(response.Codec) {
		return errors.New("request.Codec is nil")
	}

	if request.Header == nil {
		request.Header = http.Header{}
	}

	defer func() {
		if r.logger == nil {
			return
		}
		fields := []logger.Field{
			logger.Reflect(logger.ServiceName, serviceName),
			logger.Reflect(logger.Header, request.Header),
			logger.Reflect(logger.Method, request.Method),
			logger.Reflect(logger.API, request.URI),
			logger.Reflect(logger.Request, request.Body),
			logger.Reflect(logger.Response, response.Body),
			logger.Reflect(logger.ServerIP, node.Host),
			logger.Reflect(logger.ServerPort, node.Port),
			logger.Reflect(logger.Code, response.HTTPCode),
			logger.Reflect(logger.Cost, cost),
			logger.Reflect(logger.Timeout, request.Timeout),
		}
		if err == nil {
			r.logger.Info(ctx, "rpc success", fields...)
			return
		}
		r.logger.Error(ctx, err.Error(), fields...)
	}()

	reqReader, err := request.Codec.Encode(request.Body)
	if err != nil {
		return
	}

	var (
		client *http.Client
		req    *http.Request
	)

	service, ok := servicer.GetServicer(serviceName)
	if !ok {
		err = errors.New("service is nil")
		return
	}

	client, node, err = r.getClient(ctx, serviceName, service)
	if err != nil {
		return
	}

	// 构建req
	url := fmt.Sprintf("http://%s:%d%s", node.Host, node.Port, request.URI)
	req, err = http.NewRequestWithContext(ctx, request.Method, url, reqReader)
	if err != nil {
		return
	}

	// 超时传递
	remain, err := timeoutLib.CalcRemainTimeout(ctx)
	if err != nil {
		return
	}
	request.Header.Set(timeoutLib.TimeoutKey, strconv.FormatInt(remain, 10))

	// 设置请求header
	req.Header = request.Header

	// 请求结束前插件
	for _, plugin := range r.beforePlugins {
		_ = plugin.Handle(ctx, req)
	}

	// 请求开始时间
	start := time.Now()

	// 判断是否cancel
	if err = ctx.Err(); err != nil {
		return
	}

	// 发送请求
	resp, err := client.Do(req)

	_ = service.Done(ctx, node, err)

	// 请求结束后插件
	for _, plugin := range r.afterPlugins {
		_ = plugin.Handle(ctx, req, resp)
	}

	cost = time.Since(start).Milliseconds()
	if err != nil {
		return
	}
	defer resp.Body.Close()

	response.HTTPCode = resp.StatusCode
	if resp.StatusCode != http.StatusOK {
		err = fmt.Errorf("http code is %d", resp.StatusCode)
		return
	}

	err = response.Codec.Decode(resp.Body, response.Body)

	return
}

func (r *RPC) getClient(ctx context.Context, serviceName string, service servicer.Servicer) (client *http.Client, node *servicer.Node, err error) {
	node, err = service.Pick(ctx)
	if err != nil {
		return
	}

	address := fmt.Sprintf("%s:%d", node.Host, node.Port)

	tp := &http.Transport{
		MaxIdleConnsPerHost: 30,
		MaxConnsPerHost:     30,
		IdleConnTimeout:     time.Minute,
		DialContext: func(ctx context.Context, network, _ string) (net.Conn, error) {
			conn, err := (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 60 * time.Second,
			}).DialContext(context.TODO(), "tcp", address)
			if err != nil {
				return nil, err
			}
			return conn, nil
		},
		DialTLSContext: func(ctx context.Context, network, _ string) (net.Conn, error) {
			pool := x509.NewCertPool()
			pool.AppendCertsFromPEM(service.GetCaCrt())
			cliCrt, err := tls.X509KeyPair(service.GetClientPem(), service.GetClientKey())
			if err != nil {
				err = errors.New("server pem error " + err.Error())
				return nil, err
			}

			conn, err := (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 60 * time.Second,
			}).DialContext(context.TODO(), "tcp", address)
			if err != nil {
				return nil, err
			}

			return tls.Client(conn, &tls.Config{
				RootCAs:      pool,
				Certificates: []tls.Certificate{cliCrt},
				ServerName:   serviceName,
			}), err
		},
	}
	client = &http.Client{Transport: tp}

	return
}


================================================
FILE: go.mod
================================================
module github.com/why444216978/gin-api

go 1.16

require (
	github.com/HdrHistogram/hdrhistogram-go v1.1.0 // indirect
	github.com/agiledragon/gomonkey/v2 v2.4.0 // indirect
	github.com/antihax/optional v1.0.0 // indirect
	github.com/apolloconfig/agollo/v4 v4.1.1 // indirect
	github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect
	github.com/cespare/xxhash v1.1.0 // indirect
	github.com/coreos/bbolt v1.3.2 // indirect
	github.com/coreos/go-etcd v2.0.0+incompatible // indirect
	github.com/coreos/go-semver v0.3.0 // indirect
	github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
	github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
	github.com/dustin/go-humanize v1.0.0 // indirect
	github.com/fsnotify/fsnotify v1.5.4 // indirect
	github.com/gin-contrib/cors v1.3.1 // indirect
	github.com/gin-contrib/pprof v1.3.0 // indirect
	github.com/gin-contrib/sse v0.1.0 // indirect
	github.com/gin-gonic/gin v1.8.1
	github.com/go-playground/validator/v10 v10.11.0 // indirect
	github.com/go-redis/redis/v8 v8.11.4
	github.com/go-redis/redismock/v8 v8.0.6
	github.com/golang/glog v1.0.0 // indirect
	github.com/golang/mock v1.6.0 // indirect
	github.com/golang/protobuf v1.5.2 // indirect
	github.com/google/btree v1.0.0 // indirect
	github.com/gorilla/csrf v1.7.1 // indirect
	github.com/gorilla/websocket v1.4.2 // indirect
	github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
	github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0
	github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
	github.com/jonboulle/clockwork v0.1.0 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
	github.com/lestrrat-go/strftime v1.0.4 // indirect
	github.com/mitchellh/mapstructure v1.5.0 // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/opentracing/opentracing-go v1.2.0
	github.com/pelletier/go-toml v1.9.5 // indirect
	github.com/pelletier/go-toml/v2 v2.0.2 // indirect
	github.com/pkg/errors v0.9.1
	github.com/robfig/cron/v3 v3.0.0 // indirect
	github.com/smartystreets/assertions v1.2.0 // indirect
	github.com/smartystreets/goconvey v1.7.2
	github.com/soheilhy/cmux v0.1.5
	github.com/spf13/pflag v1.0.5 // indirect
	github.com/spf13/viper v1.11.0
	github.com/streadway/amqp v1.0.0
	github.com/stretchr/testify v1.7.4 // indirect
	github.com/turtlemonvh/gin-wraphh v0.0.0-20160304035037-ea8e4927b3a6 // indirect
	github.com/uber/jaeger-client-go v2.25.0+incompatible
	github.com/uber/jaeger-lib v2.4.0+incompatible // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/why444216978/codec v1.0.2 // indirect
	github.com/why444216978/go-util v1.0.20
	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
	github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 // indirect
	go.etcd.io/etcd/api/v3 v3.5.2
	go.etcd.io/etcd/client/v3 v3.5.0
	go.uber.org/zap v1.17.0
	golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
	golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 // indirect
	golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
	golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
	golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect
	golang.org/x/text v0.3.7 // indirect
	golang.org/x/time v0.0.0-20191024005414-555d28b269f0
	google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac
	google.golang.org/grpc v1.47.0
	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 // indirect
	google.golang.org/protobuf v1.28.0
	gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
	gorm.io/driver/mysql v1.1.0
	gorm.io/gorm v1.21.9
	gorm.io/plugin/dbresolver v1.1.0
	honnef.co/go/tools v0.0.1-2020.1.4 // indirect
	rsc.io/quote/v3 v3.1.0 // indirect
	sigs.k8s.io/yaml v1.2.0 // indirect
)


================================================
FILE: go.sum
================================================
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.44.3/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 v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
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 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU=
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/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
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=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/agiledragon/gomonkey/v2 v2.4.0 h1:YDQJYiSQ8o78dCMXehU1E4F/Kh4jPX+MV+/iK/yfL7s=
github.com/agiledragon/gomonkey/v2 v2.4.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
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/apolloconfig/agollo/v4 v4.0.11 h1:7NSDLZzcaIe5UwcpFhk1/ojmSCeuv9198PjN0lj1KBk=
github.com/apolloconfig/agollo/v4 v4.0.11/go.mod h1:SuvTjtg0p4UlSzSbik+ibLRr6oR1xRsfy65QzP3GEAs=
github.com/apolloconfig/agollo/v4 v4.1.1 h1:bYD60nI5oVXZw3YTgr9EtU2ptCaNC8qw1gRj8LFhYsE=
github.com/apolloconfig/agollo/v4 v4.1.1/go.mod h1:SuvTjtg0p4UlSzSbik+ibLRr6oR1xRsfy65QzP3GEAs=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/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/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
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-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
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-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
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/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.25+incompatible h1:0GQEw6h3YnuOVdtwygkIfJ+Omx0tZ8/QkVyXI4LkbeY=
github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
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.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA=
github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk=
github.com/gin-contrib/pprof v1.3.0 h1:G9eK6HnbkSqDZBYbzG4wrjCsA4e+cvYAHUZw6W+W9K0=
github.com/gin-contrib/pprof v1.3.0/go.mod h1:waMjT1H9b179t3CxuG1cV3DHpga6ybizwfBaM5OXaB0=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
github.com/gin-gonic/gin v1.6.2 h1:88crIK23zO6TqlQBt+f9FrPJNKm9ZEr7qjp9vl/d5TM=
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
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-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/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-redis/redis/v8 v8.8.0/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8=
github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-redis/redismock/v8 v8.0.6 h1:rtuijPgGynsRB2Y7KDACm09WvjHWS4RaG44Nm7rcj4Y=
github.com/go-redis/redismock/v8 v8.0.6/go.mod h1:sDIF73OVsmaKzYe/1FJXGiCQ4+oHYbzjpaL9Vor0sS4=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
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/groupcache v0.0.0-20210331224755-41bb18bfe9da/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/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
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.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
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.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
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/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
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/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
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.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I=
github.com/google/uuid v1.1.5/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/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
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/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE=
github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0 h1:rgxjzoDmDXw5q8HONgyHhBas4to0/XWRo/gPpJhsUNQ=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q85nr0w1lIRikTl4JlhdDH5w=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
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/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hexops/valast v1.4.1/go.mod h1:G+D6TExWuKs5he+hYlPMfYyhQ8w8qbc2vm4gDWwLdDg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
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/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
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.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8=
github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.0 h1:P7Bq0SaI8nsexyay5UAyDo+ICWy5MQPgEZ5+l8JQTKo=
github.com/pelletier/go-toml/v2 v2.0.0/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw=
github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
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/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
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_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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
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/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
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/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=
github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/go-goon v0.0.0-20210110234559-7585751d9a17/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
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/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
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/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44=
github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo=
github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
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/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.7.4 h1:wZRexSlwd7ZXfKINDLsO4r7WBt3gTKONc6K/VesHvHM=
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/turtlemonvh/gin-wraphh v0.0.0-20160304035037-ea8e4927b3a6 h1:LXn2Epw3+6TJxFwYbUo0M32riVbVfSTqCf41kJCmLb8=
github.com/turtlemonvh/gin-wraphh v0.0.0-20160304035037-ea8e4927b3a6/go.mod h1:9ACh8xdjPLhq9E8Rp80s6QqYzuAAx75ZNPLnjgtei6Q=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.4.0+incompatible h1:fY7QsGQWiCt8pajv4r7JEvmATdCVaWxXbjwyYwsNaLQ=
github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/why444216978/codec v1.0.1 h1:BK2IhwlhfXPeIlS0cIpb+lcO22HG9SGUJJO+cyDwgE8=
github.com/why444216978/codec v1.0.1/go.mod h1:L9NF37yg7sTsYf5qxzlVy8pMKtc4IFAhruw/d1Mc4KQ=
github.com/why444216978/codec v1.0.2 h1:yW6OgRDPbK2/a/W7h95hVjmt6kI3a7lZ08dXAaJ8ilA=
github.com/why444216978/codec v1.0.2/go.mod h1:nPjhT8IFTCjduNEntyUD/G73E4FDayWxWJTG8edBoC4=
github.com/why444216978/go-util v1.0.12 h1:aMMY4lBSfXyPMmzdLK9adBhiHb7xLHMamtZAqsa1tRA=
github.com/why444216978/go-util v1.0.12/go.mod h1:Ig1wkItwcPRQGjpAzv5+i3NRIUBadmyKCdV/Nl1OKLc=
github.com/why444216978/go-util v1.0.15 h1:nfXzb0neAe70tQWhDSKpL1r2DIJW171cD6/LUxb+wRk=
github.com/why444216978/go-util v1.0.15/go.mod h1:eOQgFhp/KyB6QtJAG0PuwLDMs7wCtBWQRwFAW0VDD48=
github.com/why444216978/go-util v1.0.16 h1:P6Rjrj+kALXRQHmL6Xo+DG8cx/tcD6p9DOPLKTaFOg0=
github.com/why444216978/go-util v1.0.16/go.mod h1:ICoXMJruQGu3eJkh26R+Eeinc8Cw+AvAY/zscpSXQ/A=
github.com/why444216978/go-util v1.0.17 h1:9teRuYd6/LuMqrJkwQnCYJ9WZSchq/Rtkr24CU4cbII=
github.com/why444216978/go-util v1.0.17/go.mod h1:YNkAVzpl2y7ZhTeDnn8TJT+d0OZEjswObwdEghwnlGo=
github.com/why444216978/go-util v1.0.19 h1:Q3gMncwWSFwWEk0bL0YwBHKdge8A/Hyo+srKN+s+6wA=
github.com/why444216978/go-util v1.0.19/go.mod h1:YgFaoou91kwsOQsV2IuWNYCadnlFWVr0dmloeI4fgGQ=
github.com/why444216978/go-util v1.0.20 h1:SWHwT5HaVYRuVakkaZUijDDuaIxwpl9922KOIiLF1pQ=
github.com/why444216978/go-util v1.0.20/go.mod h1:YgFaoou91kwsOQsV2IuWNYCadnlFWVr0dmloeI4fgGQ=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
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.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.2 h1:tXok5yLlKyuQ/SXSjtqHc4uzNaMqZi2XsoSPr/LlJXI=
go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.2 h1:4hzqQ6hIb3blLyQ8usCU4h3NghkqcsohEQ3o3VetYxE=
go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI=
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
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.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
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.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
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/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/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-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190923162816-aa69164e4478/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-20200520004742-59133d7f0dd7/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-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpN
Download .txt
gitextract_sf1jmaii/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── app/
│   ├── Dockerfile
│   ├── Makefile
│   ├── conf/
│   │   ├── dev/
│   │   │   ├── app.toml
│   │   │   ├── default_rabbitmq.toml
│   │   │   ├── default_redis.toml
│   │   │   ├── etcd.toml
│   │   │   ├── jaeger.toml
│   │   │   ├── log/
│   │   │   │   ├── gorm.toml
│   │   │   │   ├── queue.toml
│   │   │   │   ├── redis.toml
│   │   │   │   ├── rpc.toml
│   │   │   │   └── service.toml
│   │   │   ├── registry.toml
│   │   │   ├── services/
│   │   │   │   └── gin-api.toml
│   │   │   └── test_mysql.toml
│   │   ├── liantiao/
│   │   │   ├── app.toml
│   │   │   ├── default_rabbitmq.toml
│   │   │   ├── default_redis.toml
│   │   │   ├── etcd.toml
│   │   │   ├── jaeger.toml
│   │   │   ├── log/
│   │   │   │   ├── gorm.toml
│   │   │   │   ├── queue.toml
│   │   │   │   ├── redis.toml
│   │   │   │   ├── rpc.toml
│   │   │   │   └── service.toml
│   │   │   ├── services/
│   │   │   │   └── gin-api.toml
│   │   │   └── test_mysql.toml
│   │   ├── online/
│   │   │   ├── app.toml
│   │   │   ├── default_rabbitmq.toml
│   │   │   ├── default_redis.toml
│   │   │   ├── etcd.toml
│   │   │   ├── jaeger.toml
│   │   │   ├── log/
│   │   │   │   ├── gorm.toml
│   │   │   │   ├── queue.toml
│   │   │   │   ├── redis.toml
│   │   │   │   ├── rpc.toml
│   │   │   │   └── service.toml
│   │   │   ├── services/
│   │   │   │   └── gin-api.toml
│   │   │   └── test_mysql.toml
│   │   └── qa/
│   │       ├── app.toml
│   │       ├── default_rabbitmq.toml
│   │       ├── default_redis.toml
│   │       ├── etcd.toml
│   │       ├── jaeger.toml
│   │       ├── log/
│   │       │   ├── gorm.toml
│   │       │   ├── queue.toml
│   │       │   ├── redis.toml
│   │       │   ├── rpc.toml
│   │       │   └── service.toml
│   │       ├── services/
│   │       │   └── gin-api.toml
│   │       └── test_mysql.toml
│   ├── loader/
│   │   └── loader.go
│   ├── main.go
│   ├── module/
│   │   ├── goods/
│   │   │   ├── api/
│   │   │   │   └── conn.go
│   │   │   ├── job/
│   │   │   │   └── job.go
│   │   │   ├── respository/
│   │   │   │   └── respository.go
│   │   │   └── service/
│   │   │       └── service.go
│   │   ├── ping/
│   │   │   ├── api/
│   │   │   │   └── ping.go
│   │   │   ├── job/
│   │   │   │   └── job.go
│   │   │   ├── responsitory/
│   │   │   │   └── responsitory.go
│   │   │   └── service/
│   │   │       └── service.go
│   │   └── test/
│   │       ├── api/
│   │       │   └── test.go
│   │       ├── job/
│   │       │   └── grpc/
│   │       │       └── job.go
│   │       ├── respository/
│   │       │   └── respository.go
│   │       └── service/
│   │           └── grpc/
│   │               ├── google/
│   │               │   ├── api/
│   │               │   │   ├── annotations.proto
│   │               │   │   ├── http.proto
│   │               │   │   └── httpbody.proto
│   │               │   └── protobuf/
│   │               │       └── descriptor.proto
│   │               ├── grpc.go
│   │               └── helloworld/
│   │                   ├── hello_world.pb.go
│   │                   ├── hello_world.pb.gw.go
│   │                   ├── hello_world.proto
│   │                   └── hello_world_grpc.pb.go
│   ├── resource/
│   │   └── resource.go
│   ├── response/
│   │   └── response.go
│   ├── router/
│   │   └── router.go
│   └── rpc/
│       └── gin-api/
│           └── test.go
├── bootstrap/
│   ├── app.go
│   └── init.go
├── client/
│   ├── grpc/
│   │   └── conn.go
│   └── http/
│       ├── client.go
│       ├── plugin.go
│       └── transport/
│           └── transport.go
├── go.mod
├── go.sum
├── library/
│   ├── apollo/
│   │   ├── agollo/
│   │   │   ├── README.md
│   │   │   ├── agollo.go
│   │   │   ├── agollo_test.go
│   │   │   ├── listener/
│   │   │   │   ├── listener.go
│   │   │   │   ├── mock/
│   │   │   │   │   └── listener.go
│   │   │   │   └── structlistener/
│   │   │   │       └── listener.go
│   │   │   └── util/
│   │   │       └── util.go
│   │   └── http/
│   │       └── apollo.go
│   ├── app/
│   │   └── app.go
│   ├── cache/
│   │   ├── cache.go
│   │   └── redis/
│   │       └── redis_cache.go
│   ├── config/
│   │   └── viper.go
│   ├── cron/
│   │   ├── cron.go
│   │   └── cron_test.go
│   ├── endless/
│   │   └── endless.go
│   ├── etcd/
│   │   └── etcd.go
│   ├── jaeger/
│   │   ├── gorm/
│   │   │   ├── gorm.go
│   │   │   └── gorm_test.go
│   │   ├── http/
│   │   │   ├── http.go
│   │   │   └── http_test.go
│   │   ├── jaeger.go
│   │   └── redis/
│   │       ├── redis.go
│   │       └── redis_test.go
│   ├── job/
│   │   └── job.go
│   ├── lock/
│   │   ├── lock.go
│   │   ├── mock/
│   │   │   └── lock.go
│   │   └── redis/
│   │       ├── redis_lock.go
│   │       └── redis_lock_test.go
│   ├── logger/
│   │   ├── context.go
│   │   ├── fields.go
│   │   ├── http.go
│   │   ├── level.go
│   │   ├── logger.go
│   │   ├── logid.go
│   │   ├── rotate.go
│   │   ├── rotate_test.go
│   │   └── zap/
│   │       ├── gorm/
│   │       │   └── gorm.go
│   │       ├── redis/
│   │       │   └── redis.go
│   │       ├── rpc/
│   │       │   └── rpc.go
│   │       ├── service/
│   │       │   └── service.go
│   │       └── zap.go
│   ├── orm/
│   │   └── orm.go
│   ├── queue/
│   │   ├── queue.go
│   │   └── rabbitmq/
│   │       └── rabbitmq.go
│   ├── redis/
│   │   └── conn.go
│   ├── registry/
│   │   ├── etcd/
│   │   │   ├── discovery.go
│   │   │   └── registrar.go
│   │   └── registry.go
│   ├── reliablequeue/
│   │   ├── reliablequeue.go
│   │   ├── reliablequeue_test.go
│   │   ├── table.go
│   │   └── table.sql
│   ├── selector/
│   │   ├── dwrr/
│   │   │   └── cwrr.go
│   │   ├── icmp/
│   │   │   └── icmp.go
│   │   ├── p2c/
│   │   │   └── p2c.go
│   │   ├── selector.go
│   │   ├── wr/
│   │   │   ├── wr.go
│   │   │   └── wr_test.go
│   │   └── wrr/
│   │       └── wrr.go
│   └── servicer/
│       ├── service/
│       │   └── service.go
│       └── servicer.go
└── server/
    ├── grpc/
    │   ├── cmux/
    │   │   └── cmux.go
    │   ├── h2c/
    │   │   └── h2c.go
    │   ├── middleware/
    │   │   └── log/
    │   │       └── log.go
    │   ├── option.go
    │   └── server.go
    ├── http/
    │   ├── middleware/
    │   │   ├── cors/
    │   │   │   └── cors.go
    │   │   ├── csrf/
    │   │   │   └── csrf.go
    │   │   ├── limiter/
    │   │   │   └── limiter.go
    │   │   ├── log/
    │   │   │   └── log.go
    │   │   ├── panic/
    │   │   │   ├── mail_template.go
    │   │   │   └── panic.go
    │   │   └── timeout/
    │   │       └── timeout.go
    │   ├── response/
    │   │   ├── error.go
    │   │   └── response.go
    │   ├── server.go
    │   └── util/
    │       └── util.go
    └── server.go
Download .txt
SYMBOL INDEX (739 symbols across 93 files)

FILE: app/loader/loader.go
  function Load (line 34) | func Load() (err error) {
  function loadLogger (line 77) | func loadLogger() (err error) {
  function loadMysql (line 93) | func loadMysql(db string) (err error) {
  function loadRedis (line 122) | func loadRedis(db string) (err error) {
  function loadRabbitMQ (line 151) | func loadRabbitMQ(service string) (err error) {
  function loadLock (line 164) | func loadLock() (err error) {
  function loadCache (line 169) | func loadCache() (err error) {
  function loadJaeger (line 174) | func loadJaeger() (err error) {
  function loadEtcd (line 188) | func loadEtcd() (err error) {
  function loadRegistry (line 205) | func loadRegistry() (err error) {
  function loadClientHTTP (line 240) | func loadClientHTTP() (err error) {

FILE: app/main.go
  function main (line 30) | func main() {
  function startHTTP (line 58) | func startHTTP(port int) {
  function startGRPC (line 77) | func startGRPC(port int) {

FILE: app/module/goods/api/conn.go
  function Do (line 19) | func Do(c *gin.Context) {
  type Data (line 65) | type Data struct
  function GetDataA (line 69) | func GetDataA(ctx context.Context, _data interface{}) (err error) {

FILE: app/module/goods/respository/respository.go
  type Test (line 3) | type Test struct
    method TableName (line 9) | func (Test) TableName() string {

FILE: app/module/goods/service/service.go
  type GoodsInterface (line 16) | type GoodsInterface interface
  type GoodsService (line 23) | type GoodsService struct
    method GetGoodsName (line 34) | func (gs *GoodsService) GetGoodsName(ctx context.Context, id int) (str...
    method CrudGoods (line 45) | func (gs *GoodsService) CrudGoods(ctx context.Context) (goods resposit...
  function init (line 25) | func init() {
  constant GOODS_NAME_KEY (line 30) | GOODS_NAME_KEY  = "goods::name::"
  constant GOODS_PRICE_KEY (line 31) | GOODS_PRICE_KEY = "goods::price::"

FILE: app/module/ping/api/ping.go
  function Ping (line 11) | func Ping(c *gin.Context) {
  function RPC (line 15) | func RPC(c *gin.Context) {

FILE: app/module/test/api/test.go
  function Rpc (line 14) | func Rpc(c *gin.Context) {
  type RPC1Request (line 25) | type RPC1Request struct
  function Rpc1 (line 29) | func Rpc1(c *gin.Context) {
  function Panic (line 46) | func Panic(c *gin.Context) {

FILE: app/module/test/job/grpc/job.go
  function Start (line 14) | func Start(ctx context.Context) (err error) {
  function call (line 19) | func call() {

FILE: app/module/test/service/grpc/grpc.go
  type Server (line 12) | type Server struct
    method SayHello (line 16) | func (s *Server) SayHello(ctx context.Context, in *pb.HelloRequest) (*...
  function RegisterServer (line 20) | func RegisterServer(s *grpc.Server) {
  function NewService (line 24) | func NewService() serverGRPC.Register {

FILE: app/module/test/service/grpc/helloworld/hello_world.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type HelloRequest (line 25) | type HelloRequest struct
    method Reset (line 33) | func (x *HelloRequest) Reset() {
    method String (line 42) | func (x *HelloRequest) String() string {
    method ProtoMessage (line 46) | func (*HelloRequest) ProtoMessage() {}
    method ProtoReflect (line 48) | func (x *HelloRequest) ProtoReflect() protoreflect.Message {
    method Descriptor (line 61) | func (*HelloRequest) Descriptor() ([]byte, []int) {
    method GetName (line 65) | func (x *HelloRequest) GetName() string {
  type HelloReply (line 73) | type HelloReply struct
    method Reset (line 81) | func (x *HelloReply) Reset() {
    method String (line 90) | func (x *HelloReply) String() string {
    method ProtoMessage (line 94) | func (*HelloReply) ProtoMessage() {}
    method ProtoReflect (line 96) | func (x *HelloReply) ProtoReflect() protoreflect.Message {
    method Descriptor (line 109) | func (*HelloReply) Descriptor() ([]byte, []int) {
    method GetMessage (line 113) | func (x *HelloReply) GetMessage() string {
  function file_helloworld_hello_world_proto_rawDescGZIP (line 148) | func file_helloworld_hello_world_proto_rawDescGZIP() []byte {
  function init (line 170) | func init() { file_helloworld_hello_world_proto_init() }
  function file_helloworld_hello_world_proto_init (line 171) | func file_helloworld_hello_world_proto_init() {

FILE: app/module/test/service/grpc/helloworld/hello_world.pb.gw.go
  function request_Greeter_SayHello_0 (line 38) | func request_Greeter_SayHello_0(ctx context.Context, marshaler runtime.M...
  function local_request_Greeter_SayHello_0 (line 54) | func local_request_Greeter_SayHello_0(ctx context.Context, marshaler run...
  function RegisterGreeterHandlerServer (line 74) | func RegisterGreeterHandlerServer(ctx context.Context, mux *runtime.Serv...
  function RegisterGreeterHandlerFromEndpoint (line 104) | func RegisterGreeterHandlerFromEndpoint(ctx context.Context, mux *runtim...
  function RegisterGreeterHandler (line 129) | func RegisterGreeterHandler(ctx context.Context, mux *runtime.ServeMux, ...
  function RegisterGreeterHandlerClient (line 138) | func RegisterGreeterHandlerClient(ctx context.Context, mux *runtime.Serv...

FILE: app/module/test/service/grpc/helloworld/hello_world_grpc.pb.go
  constant _ (line 15) | _ = grpc.SupportPackageIsVersion7
  type GreeterClient (line 20) | type GreeterClient interface
  type greeterClient (line 25) | type greeterClient struct
    method SayHello (line 33) | func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest...
  function NewGreeterClient (line 29) | func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
  type GreeterServer (line 45) | type GreeterServer interface
  type UnimplementedGreeterServer (line 52) | type UnimplementedGreeterServer struct
    method SayHello (line 55) | func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequ...
    method mustEmbedUnimplementedGreeterServer (line 58) | func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer(...
  type UnsafeGreeterServer (line 63) | type UnsafeGreeterServer interface
  function RegisterGreeterServer (line 67) | func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
  function _Greeter_SayHello_Handler (line 71) | func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec...

FILE: app/response/response.go
  constant CodeSuccess (line 12) | CodeSuccess     response.Code = 0
  constant CodeParams (line 13) | CodeParams      response.Code = 1
  constant CodeUriNotFound (line 14) | CodeUriNotFound response.Code = http.StatusNotFound
  constant CodeServer (line 15) | CodeServer      response.Code = http.StatusInternalServerError
  constant CodeUnavailable (line 16) | CodeUnavailable response.Code = http.StatusServiceUnavailable
  constant CodeTimeout (line 17) | CodeTimeout     response.Code = http.StatusGatewayTimeout
  function ResponseJSON (line 29) | func ResponseJSON(c *gin.Context, code response.Code, data interface{}, ...

FILE: app/router/router.go
  function RegisterRouter (line 11) | func RegisterRouter(server *gin.Engine) {

FILE: app/rpc/gin-api/test.go
  constant serviceName (line 17) | serviceName = "gin-api-dev"
  function RPC (line 20) | func RPC(ctx context.Context) (resp *httpClient.Response, err error) {
  function RPC1 (line 41) | func RPC1(ctx context.Context) (resp *httpClient.Response, err error) {
  function Ping (line 63) | func Ping(ctx context.Context) (resp *httpClient.Response, err error) {

FILE: bootstrap/app.go
  type Option (line 18) | type Option struct
  function defaultOption (line 20) | func defaultOption() *Option {
  type OptionFunc (line 24) | type OptionFunc
  type App (line 26) | type App struct
    method Start (line 52) | func (app *App) Start() error {
    method start (line 69) | func (a *App) start() error {
    method registerSignal (line 73) | func (a *App) registerSignal() (err error) {
    method registerService (line 85) | func (a *App) registerService() (err error) {
    method shutdown (line 93) | func (a *App) shutdown() (err error) {
  function NewApp (line 34) | func NewApp(srv server.Server, registrar registry.Registrar, opts ...Opt...

FILE: bootstrap/init.go
  function Init (line 11) | func Init(env string, load func() error) (err error) {

FILE: client/grpc/conn.go
  function Conn (line 11) | func Conn(ctx context.Context, target string) (cc *grpc.ClientConn, err ...

FILE: client/http/client.go
  type Request (line 11) | type Request struct
  type Response (line 20) | type Response struct
  type Client (line 26) | type Client interface

FILE: client/http/plugin.go
  type BeforeRequestPlugin (line 11) | type BeforeRequestPlugin interface
  type AfterRequestPlugin (line 15) | type AfterRequestPlugin interface
  type JaegerBeforePlugin (line 19) | type JaegerBeforePlugin struct
    method Handle (line 23) | func (*JaegerBeforePlugin) Handle(ctx context.Context, req *http.Reque...

FILE: client/http/transport/transport.go
  type RPC (line 23) | type RPC struct
    method Send (line 53) | func (r *RPC) Send(ctx context.Context, serviceName string, request cl...
    method getClient (line 177) | func (r *RPC) getClient(ctx context.Context, serviceName string, servi...
  type Option (line 29) | type Option
  function WithLogger (line 31) | func WithLogger(logger *loggerRPC.RPCLogger) Option {
  function WithBeforePlugins (line 35) | func WithBeforePlugins(plugins ...client.BeforeRequestPlugin) Option {
  function WithAfterPlugins (line 39) | func WithAfterPlugins(plugins ...client.AfterRequestPlugin) Option {
  function New (line 43) | func New(opts ...Option) *RPC {

FILE: library/apollo/agollo/agollo.go
  constant envIP (line 21) | envIP      = "APOLLO_IP"
  constant envSecret (line 22) | envSecret  = "APOLLO_SECRET"
  constant envCluster (line 23) | envCluster = "APOLLO_CLUSTER"
  constant defaultBackupConfigFileMode (line 27) | defaultBackupConfigFileMode fs.FileMode = 0744
  constant defaultIsBackupConfig (line 28) | defaultIsBackupConfig                   = true
  constant defaultBackupConfigPath (line 29) | defaultBackupConfigPath                 = ".apollo_config"
  type Option (line 32) | type Option
  function WithIsBackupConfig (line 34) | func WithIsBackupConfig(isBackup bool) Option {
  function WithBackupConfigPath (line 38) | func WithBackupConfigPath(backupPath string) Option {
  function WithSyncServerTimeout (line 42) | func WithSyncServerTimeout(syncServerTimeout int) Option {
  function WithCustomListeners (line 46) | func WithCustomListeners(listeners []listener.CustomListener) Option {
  function WithLogger (line 50) | func WithLogger(logger log.LoggerInterface) Option {
  function WithCache (line 54) | func WithCache(cache agcache.CacheFactory) Option {
  function WithAuth (line 58) | func WithAuth(auth auth.HTTPAuth) Option {
  function WithLoadBalance (line 62) | func WithLoadBalance(loadBalance cluster.LoadBalance) Option {
  function WithFileHandler (line 66) | func WithFileHandler(fileHandler file.FileHandler) Option {
  type ApolloClient (line 70) | type ApolloClient struct
    method setHandler (line 133) | func (ac *ApolloClient) setHandler() {
  function New (line 94) | func New(ctx context.Context, appID string, namespaces []string, opts .....

FILE: library/apollo/agollo/agollo_test.go
  type Conf (line 13) | type Conf struct
  function TestNew (line 17) | func TestNew(t *testing.T) {

FILE: library/apollo/agollo/listener/listener.go
  type CustomListener (line 8) | type CustomListener struct
  type Listener (line 14) | type Listener interface

FILE: library/apollo/agollo/listener/mock/listener.go
  type MockListener (line 16) | type MockListener struct
    method EXPECT (line 34) | func (m *MockListener) EXPECT() *MockListenerMockRecorder {
    method GetNamespace (line 39) | func (m *MockListener) GetNamespace(namespace string) (interface{}, bo...
    method InitConfig (line 54) | func (m *MockListener) InitConfig(client agollo.Client, namespaceStruc...
    method OnChange (line 66) | func (m *MockListener) OnChange(event *storage.ChangeEvent) {
    method OnNewestChange (line 78) | func (m *MockListener) OnNewestChange(event *storage.FullChangeEvent) {
  type MockListenerMockRecorder (line 22) | type MockListenerMockRecorder struct
    method GetNamespace (line 48) | func (mr *MockListenerMockRecorder) GetNamespace(namespace interface{}...
    method InitConfig (line 60) | func (mr *MockListenerMockRecorder) InitConfig(client, namespaceStruct...
    method OnChange (line 72) | func (mr *MockListenerMockRecorder) OnChange(event interface{}) *gomoc...
    method OnNewestChange (line 84) | func (mr *MockListenerMockRecorder) OnNewestChange(event interface{}) ...
  function NewMockListener (line 27) | func NewMockListener(ctrl *gomock.Controller) *MockListener {

FILE: library/apollo/agollo/listener/structlistener/listener.go
  type StructChangeListener (line 14) | type StructChangeListener struct
    method OnChange (line 20) | func (c *StructChangeListener) OnChange(changeEvent *storage.ChangeEve...
    method OnNewestChange (line 22) | func (c *StructChangeListener) OnNewestChange(event *storage.FullChang...
    method InitConfig (line 46) | func (c *StructChangeListener) InitConfig(client agollo.Client, namesp...
    method GetNamespace (line 62) | func (c *StructChangeListener) GetNamespace(namespace string) (interfa...

FILE: library/apollo/agollo/util/util.go
  function ExtractConf (line 21) | func ExtractConf(namespace, content string, conf interface{}) error {

FILE: library/apollo/http/apollo.go
  type AppoloConf (line 26) | type AppoloConf struct
  function DoLoadApolloConf (line 37) | func DoLoadApolloConf(host, service, cluster, token string, space []stri...
  function LoadApolloConf (line 79) | func LoadApolloConf(service string, space []string) (map[string]string, ...

FILE: library/app/app.go
  function InitApp (line 20) | func InitApp() (err error) {
  function Name (line 24) | func Name() string {
  function Port (line 28) | func Port() int {
  function Pprof (line 32) | func Pprof() bool {
  function Debug (line 36) | func Debug() bool {
  function ContextTimeout (line 40) | func ContextTimeout() time.Duration {
  function ConnectTimeout (line 47) | func ConnectTimeout() time.Duration {
  function WriteTimeout (line 54) | func WriteTimeout() time.Duration {
  function ReadTimeout (line 61) | func ReadTimeout() time.Duration {

FILE: library/cache/cache.go
  type CacheData (line 12) | type CacheData struct
  type LoadFunc (line 18) | type LoadFunc
  type Cacher (line 21) | type Cacher interface
  type panicError (line 34) | type panicError struct
    method Error (line 40) | func (p *panicError) Error() string {
  function newPanicError (line 45) | func newPanicError(v interface{}) error {
  function HandleLoad (line 58) | func HandleLoad(ctx context.Context, f LoadFunc, data interface{}) (err ...

FILE: library/cache/redis/redis_cache.go
  type RedisCache (line 18) | type RedisCache struct
    method GetData (line 40) | func (rc *RedisCache) GetData(ctx context.Context, key string, ttl tim...
    method FlushCache (line 67) | func (rc *RedisCache) FlushCache(ctx context.Context, key string, ttl ...
    method getCache (line 107) | func (rc *RedisCache) getCache(ctx context.Context, key string) (data ...
    method setCache (line 130) | func (rc *RedisCache) setCache(ctx context.Context, key, val string, t...
  function New (line 25) | func New(c *redis.Client, locker lock.Locker) (*RedisCache, error) {

FILE: library/config/viper.go
  type Viper (line 11) | type Viper struct
    method ReadConfig (line 66) | func (v *Viper) ReadConfig(file, typ string, data interface{}) (err er...
    method Path (line 76) | func (v *Viper) Path() string {
  function ReadConfig (line 25) | func ReadConfig(file, typ string, data interface{}) (err error) {
  function Path (line 29) | func Path() string {
  function Dir (line 33) | func Dir() (string, error) {
  function Config (line 37) | func Config() *Viper {
  function Init (line 41) | func Init(env string) {
  function New (line 45) | func New(env string) *Viper {

FILE: library/cron/cron.go
  type Cron (line 30) | type Cron struct
    method AddJob (line 100) | func (c *Cron) AddJob(spec string, cmd func()) (cron.EntryID, error) {
    method Start (line 104) | func (c *Cron) Start() {
    method Stop (line 108) | func (c *Cron) Stop() {
    method Name (line 112) | func (c *Cron) Name() string {
    method addJob (line 116) | func (c *Cron) addJob(spec string, cmd cron.Job) (cron.EntryID, error) {
    method handle (line 128) | func (c *Cron) handle(ctx context.Context, cmd cron.Job, funcName, spe...
    method getLockDuration (line 182) | func (c *Cron) getLockDuration(schedule cron.Schedule) time.Duration {
    method getLockKey (line 193) | func (c *Cron) getLockKey(funcName string) string {
    method setFuncEntity (line 197) | func (c *Cron) setFuncEntity(funcName string, entityID cron.EntryID) {
    method getFuncEntity (line 204) | func (c *Cron) getFuncEntity(funcName string) cron.Entry {
  type Options (line 40) | type Options struct
  function defaultOptions (line 47) | func defaultOptions() *Options {
  type Option (line 54) | type Option
  function WithLocker (line 56) | func WithLocker(l lock.Locker) Option {
  function WithErrCallback (line 60) | func WithErrCallback(f func(error)) Option {
  function WithMiniLockTTL (line 64) | func WithMiniLockTTL(ttl time.Duration) Option {
  function WithLockFormat (line 68) | func WithLockFormat(lockFormat string) Option {
  function NewCron (line 72) | func NewCron(name string, l logger.Logger, options ...Option) (c *Cron, ...
  type FuncJob (line 211) | type FuncJob
    method Run (line 213) | func (f FuncJob) Run() { f() }
    method Function (line 215) | func (f FuncJob) Function() func() { return f }
    method FunctionName (line 217) | func (f FuncJob) FunctionName() string {

FILE: library/cron/cron_test.go
  function JobFunc (line 15) | func JobFunc() {
  function TestCron_AddJob (line 19) | func TestCron_AddJob(t *testing.T) {

FILE: library/endless/endless.go
  constant PRE_SIGNAL (line 22) | PRE_SIGNAL = iota
  constant POST_SIGNAL (line 23) | POST_SIGNAL
  constant STATE_INIT (line 25) | STATE_INIT
  constant STATE_RUNNING (line 26) | STATE_RUNNING
  constant STATE_SHUTTING_DOWN (line 27) | STATE_SHUTTING_DOWN
  constant STATE_TERMINATE (line 28) | STATE_TERMINATE
  function init (line 49) | func init() {
  type endlessServer (line 71) | type endlessServer struct
    method getState (line 167) | func (srv *endlessServer) getState() uint8 {
    method setState (line 174) | func (srv *endlessServer) setState(st uint8) {
    method Serve (line 191) | func (srv *endlessServer) Serve() (err error) {
    method ListenAndServe (line 206) | func (srv *endlessServer) ListenAndServe() (err error) {
    method ListenAndServeTLS (line 242) | func (srv *endlessServer) ListenAndServeTLS(certFile, keyFile string) ...
    method getListener (line 285) | func (srv *endlessServer) getListener(laddr string) (l net.Listener, e...
    method handleSignals (line 315) | func (srv *endlessServer) handleSignals() {
    method signalHooks (line 354) | func (srv *endlessServer) signalHooks(ppFlag int, sig os.Signal) {
    method shutdown (line 369) | func (srv *endlessServer) shutdown() {
    method hammerTime (line 397) | func (srv *endlessServer) hammerTime(d time.Duration) {
    method fork (line 420) | func (srv *endlessServer) fork() (err error) {
    method RegisterSignalHook (line 549) | func (srv *endlessServer) RegisterSignalHook(prePost int, sig os.Signa...
  function NewServer (line 88) | func NewServer(addr string, handler http.Handler) (srv *endlessServer) {
  function ListenAndServe (line 150) | func ListenAndServe(addr string, handler http.Handler) error {
  function ListenAndServeTLS (line 162) | func ListenAndServeTLS(addr string, certFile string, keyFile string, han...
  type endlessListener (line 482) | type endlessListener struct
    method Accept (line 488) | func (el *endlessListener) Accept() (c net.Conn, err error) {
    method Close (line 515) | func (el *endlessListener) Close() error {
    method File (line 524) | func (el *endlessListener) File() *os.File {
  function newEndlessListener (line 506) | func newEndlessListener(l net.Listener, srv *endlessServer) (el *endless...
  type endlessConn (line 531) | type endlessConn struct
    method Close (line 536) | func (w endlessConn) Close() error {

FILE: library/etcd/etcd.go
  type Config (line 9) | type Config struct
  type Etcd (line 15) | type Etcd struct
  type Option (line 21) | type Option
  function WithEndpoints (line 23) | func WithEndpoints(endpoints []string) Option {
  function WithDialTimeout (line 27) | func WithDialTimeout(duration time.Duration) Option {
  function NewClient (line 32) | func NewClient(opts ...Option) (*Etcd, error) {

FILE: library/jaeger/gorm/gorm.go
  constant componentGorm (line 15) | componentGorm      = "Gorm"
  constant gormSpanKey (line 16) | gormSpanKey        = "gorm_span"
  constant callBackBeforeName (line 17) | callBackBeforeName = "opentracing:before"
  constant callBackAfterName (line 18) | callBackAfterName  = "opentracing:after"
  function before (line 22) | func before(db *gorm.DB) {
  function after (line 32) | func after(db *gorm.DB) {
  type opentracingPlugin (line 57) | type opentracingPlugin struct
    method Name (line 61) | func (op *opentracingPlugin) Name() string {
    method Initialize (line 65) | func (op *opentracingPlugin) Initialize(db *gorm.DB) (err error) {

FILE: library/jaeger/gorm/gorm_test.go
  type TestTable (line 15) | type TestTable struct
    method TableName (line 21) | func (TestTable) TableName() string {
  function Test_before (line 25) | func Test_before(t *testing.T) {
  function Test_after (line 56) | func Test_after(t *testing.T) {
  function TestOpentracingPlugin_Name (line 135) | func TestOpentracingPlugin_Name(t *testing.T) {
  function TestOpentracingPlugin_Initialize (line 144) | func TestOpentracingPlugin_Initialize(t *testing.T) {

FILE: library/jaeger/http/http.go
  constant httpClientComponentPrefix (line 16) | httpClientComponentPrefix = "HTTP-Client-"
  constant httpServerComponentPrefix (line 17) | httpServerComponentPrefix = "HTTP-Server-"
  function ExtractHTTP (line 23) | func ExtractHTTP(ctx context.Context, req *http.Request, logID string) (...
  function InjectHTTP (line 50) | func InjectHTTP(ctx context.Context, req *http.Request, logID string) er...
  function SetHTTPLog (line 64) | func SetHTTPLog(span opentracing.Span, req, resp string) {

FILE: library/jaeger/http/http_test.go
  function TestExtractHTTP (line 17) | func TestExtractHTTP(t *testing.T) {
  function TestInjectHTTP (line 66) | func TestInjectHTTP(t *testing.T) {
  function TestSetHTTPLog (line 96) | func TestSetHTTPLog(t *testing.T) {

FILE: library/jaeger/jaeger.go
  constant FieldLogID (line 14) | FieldLogID   = "Log-Id"
  constant FieldTraceID (line 15) | FieldTraceID = "Trace-Id"
  constant FieldSpanID (line 16) | FieldSpanID  = "Span-Id"
  constant LogFieldsRequest (line 20) | LogFieldsRequest  = "request"
  constant LogFieldsResponse (line 21) | LogFieldsResponse = "response"
  constant LogFieldsArgs (line 22) | LogFieldsArgs     = "args"
  type Config (line 27) | type Config struct
  function NewJaegerTracer (line 32) | func NewJaegerTracer(connCfg *Config, serviceName string) (opentracing.T...
  function SetError (line 56) | func SetError(span opentracing.Span, err error) {
  function SetRequest (line 60) | func SetRequest(span opentracing.Span, request string) {
  function SetResponse (line 64) | func SetResponse(span opentracing.Span, resp string) {
  function SetCommonTag (line 68) | func SetCommonTag(ctx context.Context, span opentracing.Span) {
  function GetTraceID (line 74) | func GetTraceID(span opentracing.Span) string {
  function GetSpanID (line 79) | func GetSpanID(span opentracing.Span) string {
  function spanContextToJaegerContext (line 84) | func spanContextToJaegerContext(spanContext opentracing.SpanContext) jae...

FILE: library/jaeger/redis/redis.go
  constant operationRedis (line 17) | operationRedis = "Redis-"
  constant logCmdName (line 18) | logCmdName     = "command"
  constant logCmdArgs (line 19) | logCmdArgs     = "args"
  constant logCmdResult (line 20) | logCmdResult   = "result"
  type contextKey (line 23) | type contextKey
  constant cmdStart (line 26) | cmdStart contextKey = iota
  type jaegerHook (line 30) | type jaegerHook struct
    method BeforeProcess (line 38) | func (jh *jaegerHook) BeforeProcess(ctx context.Context, cmd redis.Cmd...
    method AfterProcess (line 51) | func (jh *jaegerHook) AfterProcess(ctx context.Context, cmd redis.Cmde...
    method BeforeProcessPipeline (line 74) | func (jh *jaegerHook) BeforeProcessPipeline(ctx context.Context, cmds ...
    method AfterProcessPipeline (line 87) | func (jh *jaegerHook) AfterProcessPipeline(ctx context.Context, cmds [...
    method getPipeLineLogKey (line 114) | func (jh *jaegerHook) getPipeLineLogKey(logField string, idx int) stri...
  function NewJaegerHook (line 33) | func NewJaegerHook() redis.Hook {
  function isRedisError (line 118) | func isRedisError(err error) bool {

FILE: library/jaeger/redis/redis_test.go
  function TestNewJaegerHook (line 16) | func TestNewJaegerHook(t *testing.T) {
  function Test_jaegerHook_BeforeProcess (line 24) | func Test_jaegerHook_BeforeProcess(t *testing.T) {
  function Test_jaegerHook_AfterProcess (line 47) | func Test_jaegerHook_AfterProcess(t *testing.T) {
  function Test_jaegerHook_BeforeProcessPipeline (line 97) | func Test_jaegerHook_BeforeProcessPipeline(t *testing.T) {
  function Test_jaegerHook_AfterProcessPipeline (line 120) | func Test_jaegerHook_AfterProcessPipeline(t *testing.T) {
  function Test_jaegerHook_getPipeLineLogKey (line 170) | func Test_jaegerHook_getPipeLineLogKey(t *testing.T) {
  function Test_isRedisError (line 178) | func Test_isRedisError(t *testing.T) {

FILE: library/job/job.go
  type HandleFunc (line 15) | type HandleFunc
  function Handle (line 19) | func Handle(job string, l logger.Logger) {

FILE: library/lock/lock.go
  type Locker (line 18) | type Locker interface

FILE: library/lock/mock/lock.go
  type MockLocker (line 16) | type MockLocker struct
    method EXPECT (line 34) | func (m *MockLocker) EXPECT() *MockLockerMockRecorder {
    method Lock (line 39) | func (m *MockLocker) Lock(ctx context.Context, key string, random inte...
    method Unlock (line 53) | func (m *MockLocker) Unlock(ctx context.Context, key string, random in...
  type MockLockerMockRecorder (line 22) | type MockLockerMockRecorder struct
    method Lock (line 47) | func (mr *MockLockerMockRecorder) Lock(ctx, key, random, duration inte...
    method Unlock (line 61) | func (mr *MockLockerMockRecorder) Unlock(ctx, key, random interface{})...
  function NewMockLocker (line 27) | func NewMockLocker(ctrl *gomock.Controller) *MockLocker {

FILE: library/lock/redis/redis_lock.go
  constant lockSuccess (line 13) | lockSuccess = 1
  constant lockFail (line 14) | lockFail    = 0
  constant lockLua (line 15) | lockLua     = `if redis.call("GET", KEYS[1]) == ARGV[1] then redis.call(...
  type RedisLock (line 20) | type RedisLock struct
    method Lock (line 34) | func (rl *RedisLock) Lock(ctx context.Context, key string, random inte...
    method Unlock (line 47) | func (rl *RedisLock) Unlock(ctx context.Context, key string, random in...
  function New (line 24) | func New(c *redis.Client) (*RedisLock, error) {

FILE: library/lock/redis/redis_lock_test.go
  function TestNew (line 22) | func TestNew(t *testing.T) {
  function TestRedisLock_Lock (line 41) | func TestRedisLock_Lock(t *testing.T) {
  function TestRedisLock_Unlock (line 66) | func TestRedisLock_Unlock(t *testing.T) {

FILE: library/logger/context.go
  type contextKey (line 7) | type contextKey
  constant contextLogID (line 10) | contextLogID contextKey = iota
  constant contextHTTPLogFields (line 11) | contextHTTPLogFields
  constant contextTraceID (line 12) | contextTraceID
  function WithLogID (line 16) | func WithLogID(ctx context.Context, val interface{}) context.Context {
  function ValueLogID (line 21) | func ValueLogID(ctx context.Context) string {
  function WithTraceID (line 31) | func WithTraceID(ctx context.Context, val interface{}) context.Context {
  function ValueTraceID (line 36) | func ValueTraceID(ctx context.Context) string {
  function WithFields (line 46) | func WithFields(ctx context.Context, fields []Field) context.Context {
  function ValueFields (line 51) | func ValueFields(ctx context.Context) []Field {
  function AddField (line 60) | func AddField(ctx context.Context, fields ...Field) context.Context {

FILE: library/logger/fields.go
  constant LogHeader (line 9) | LogHeader = "Log-Id"
  constant ModuleHTTP (line 13) | ModuleHTTP  = "HTTP"
  constant ModuleRPC (line 14) | ModuleRPC   = "RPC"
  constant ModuleMySQL (line 15) | ModuleMySQL = "MySQL"
  constant ModuleRedis (line 16) | ModuleRedis = "Redis"
  constant ModuleQueue (line 17) | ModuleQueue = "Queue"
  constant ModuleCron (line 18) | ModuleCron  = "Cron"
  constant AppName (line 22) | AppName     = "app_name"
  constant Module (line 23) | Module      = "module"
  constant ServiceName (line 24) | ServiceName = "service_name"
  constant LogID (line 25) | LogID       = "log_id"
  constant TraceID (line 26) | TraceID     = "trace_id"
  constant Header (line 27) | Header      = "header"
  constant Method (line 28) | Method      = "method"
  constant Request (line 29) | Request     = "request"
  constant Response (line 30) | Response    = "response"
  constant Code (line 31) | Code        = "code"
  constant ClientIP (line 32) | ClientIP    = "client_ip"
  constant ClientPort (line 33) | ClientPort  = "client_port"
  constant ServerIP (line 34) | ServerIP    = "server_ip"
  constant ServerPort (line 35) | ServerPort  = "server_port"
  constant API (line 36) | API         = "api"
  constant Cost (line 37) | Cost        = "cost"
  constant Timeout (line 38) | Timeout     = "timeout"
  constant Trace (line 39) | Trace       = "trace"
  type Fields (line 42) | type Fields struct
  type Field (line 63) | type Field interface
  type field (line 68) | type field struct
    method Key (line 73) | func (f *field) Key() string {
    method Value (line 77) | func (f *field) Value() interface{} {
  function Reflect (line 81) | func Reflect(key string, value interface{}) Field {
  function Error (line 85) | func Error(err error) Field {
  function Find (line 89) | func Find(key string, fields []Field) interface{} {

FILE: library/logger/http.go
  function ExtractLogID (line 13) | func ExtractLogID(req *http.Request) string {
  function GetRequestBody (line 26) | func GetRequestBody(req *http.Request) map[string]interface{} {

FILE: library/logger/level.go
  type Level (line 3) | type Level
    method String (line 19) | func (l Level) String() string {
  constant UnknownLevel (line 6) | UnknownLevel Level = iota - 1
  constant DebugLevel (line 8) | DebugLevel
  constant InfoLevel (line 10) | InfoLevel
  constant WarnLevel (line 12) | WarnLevel
  constant ErrorLevel (line 14) | ErrorLevel
  constant FatalLevel (line 16) | FatalLevel
  function StringToLevel (line 36) | func StringToLevel(l string) Level {

FILE: library/logger/logger.go
  type Logger (line 7) | type Logger interface

FILE: library/logger/logid.go
  type ObjectId (line 19) | type ObjectId
    method Hex (line 113) | func (id ObjectId) Hex() string {
    method Time (line 119) | func (id ObjectId) Time() time.Time {
    method Machine (line 127) | func (id ObjectId) Machine() []byte {
    method Pid (line 133) | func (id ObjectId) Pid() uint16 {
    method Counter (line 139) | func (id ObjectId) Counter() int32 {
  function StrToObjectId (line 32) | func StrToObjectId(str string) (ObjectId, error) {
  function initMachineId (line 54) | func initMachineId() []byte {
  function NewObjectId (line 72) | func NewObjectId() ObjectId {
  function NewObjectIdWithTime (line 97) | func NewObjectIdWithTime(t time.Time) ObjectId {
  function NewObjectIdWithHexString (line 103) | func NewObjectIdWithHexString(s string) (o ObjectId, err error) {

FILE: library/logger/rotate.go
  function RotateWriter (line 11) | func RotateWriter(infoFile, errFile string) (infoWriter io.Writer, errWr...
  function rotateWriter (line 23) | func rotateWriter(filename string) (io.Writer, error) {

FILE: library/logger/rotate_test.go
  function TestRotateWriter (line 10) | func TestRotateWriter(t *testing.T) {
  function Test_rotateWriter (line 19) | func Test_rotateWriter(t *testing.T) {

FILE: library/logger/zap/gorm/gorm.go
  type GormConfig (line 21) | type GormConfig struct
  type GormLogger (line 31) | type GormLogger struct
    method LogMode (line 91) | func (l *GormLogger) LogMode(level gormLogger.LogLevel) gormLogger.Int...
    method Info (line 101) | func (l *GormLogger) Info(ctx context.Context, msg string, args ...int...
    method Warn (line 103) | func (l *GormLogger) Warn(ctx context.Context, msg string, args ...int...
    method Error (line 105) | func (l *GormLogger) Error(ctx context.Context, msg string, args ...in...
    method Trace (line 107) | func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc fu...
    method logger (line 144) | func (l *GormLogger) logger() *zap.Logger {
    method Close (line 158) | func (l *GormLogger) Close() error {
  type GormOption (line 40) | type GormOption
  function NewGorm (line 44) | func NewGorm(config *GormConfig, opts ...GormOption) (gl *GormLogger, er...

FILE: library/logger/zap/redis/redis.go
  type contextKey (line 16) | type contextKey
  constant cmdStart (line 19) | cmdStart contextKey = iota
  type RedisConfig (line 24) | type RedisConfig struct
  type RedisLogger (line 34) | type RedisLogger struct
    method BeforeProcess (line 71) | func (rl *RedisLogger) BeforeProcess(ctx context.Context, cmd redis.Cm...
    method AfterProcess (line 77) | func (rl *RedisLogger) AfterProcess(ctx context.Context, cmd redis.Cmd...
    method BeforeProcessPipeline (line 94) | func (rl *RedisLogger) BeforeProcessPipeline(ctx context.Context, cmds...
    method AfterProcessPipeline (line 100) | func (rl *RedisLogger) AfterProcessPipeline(ctx context.Context, cmds ...
    method Info (line 122) | func (rl *RedisLogger) Info(ctx context.Context, isPipeline bool, cmds...
    method Error (line 127) | func (rl *RedisLogger) Error(ctx context.Context, isPipeline bool, cmd...
    method fields (line 140) | func (rl *RedisLogger) fields(ctx context.Context, isPipeline bool, cm...
    method logger (line 176) | func (rl *RedisLogger) logger() *zapLogger.ZapLogger {
    method setCmdStart (line 180) | func (rl *RedisLogger) setCmdStart(ctx context.Context) context.Context {
    method getCmdCost (line 184) | func (rl *RedisLogger) getCmdCost(ctx context.Context) int64 {
  type RedisOption (line 39) | type RedisOption
  function NewRedisLogger (line 42) | func NewRedisLogger(config *RedisConfig, opts ...RedisOption) (rl *Redis...

FILE: library/logger/zap/rpc/rpc.go
  type RPCConfig (line 12) | type RPCConfig struct
  type RPCLogger (line 19) | type RPCLogger struct
    method Info (line 54) | func (rl *RPCLogger) Info(ctx context.Context, msg string, fields ...l...
    method Error (line 59) | func (rl *RPCLogger) Error(ctx context.Context, msg string, fields ......
    method logger (line 64) | func (rl *RPCLogger) logger() *zapLogger.ZapLogger {
  type RPCOption (line 24) | type RPCOption
  function NewRPCLogger (line 27) | func NewRPCLogger(config *RPCConfig, opts ...RPCOption) (rl *RPCLogger, ...

FILE: library/logger/zap/service/service.go
  type Config (line 8) | type Config struct
  type ServiceLogger (line 14) | type ServiceLogger struct
  function NewServiceLogger (line 19) | func NewServiceLogger(serviceName string, config *Config) (*ServiceLogge...

FILE: library/logger/zap/zap.go
  type ZapLogger (line 16) | type ZapLogger struct
    method infoEnabler (line 105) | func (l *ZapLogger) infoEnabler() zap.LevelEnablerFunc {
    method errorEnabler (line 114) | func (l *ZapLogger) errorEnabler() zap.LevelEnablerFunc {
    method formatEncoder (line 123) | func (l *ZapLogger) formatEncoder() zapcore.Encoder {
    method GetLevel (line 142) | func (l *ZapLogger) GetLevel() logger.Level {
    method Debug (line 163) | func (l *ZapLogger) Debug(ctx context.Context, msg string, fields ...l...
    method Info (line 167) | func (l *ZapLogger) Info(ctx context.Context, msg string, fields ...lo...
    method Warn (line 171) | func (l *ZapLogger) Warn(ctx context.Context, msg string, fields ...lo...
    method Error (line 175) | func (l *ZapLogger) Error(ctx context.Context, msg string, fields ...l...
    method Fatal (line 179) | func (l *ZapLogger) Fatal(ctx context.Context, msg string, fields ...l...
    method extractFields (line 184) | func (l *ZapLogger) extractFields(ctx context.Context, fields ...logge...
    method Close (line 203) | func (l *ZapLogger) Close() error {
  type Options (line 21) | type Options struct
  type Option (line 32) | type Option
  function defaultOptions (line 34) | func defaultOptions() *Options {
  function WithCallerSkip (line 45) | func WithCallerSkip(skip int) Option {
  function WithModule (line 49) | func WithModule(module string) Option {
  function WithServiceName (line 53) | func WithServiceName(serviceName string) Option {
  function WithInfoWriter (line 57) | func WithInfoWriter(w io.Writer) Option {
  function WithErrorWriter (line 61) | func WithErrorWriter(w io.Writer) Option {
  function WithLevel (line 65) | func WithLevel(l string) Option {
  function NewLogger (line 69) | func NewLogger(options ...Option) (l *ZapLogger, err error) {
  function zapLevel (line 146) | func zapLevel(level logger.Level) zapcore.Level {

FILE: library/orm/orm.go
  type Config (line 13) | type Config struct
  type instanceConfig (line 19) | type instanceConfig struct
  type Orm (line 30) | type Orm struct
    method UseWrite (line 89) | func (orm *Orm) UseWrite() *gorm.DB {
    method UseRead (line 93) | func (orm *Orm) UseRead() *gorm.DB {
  type Option (line 36) | type Option
  function WithTrace (line 38) | func WithTrace(tracer gorm.Plugin) Option {
  function WithLogger (line 44) | func WithLogger(logger logger.Interface) Option {
  function NewOrm (line 50) | func NewOrm(cfg *Config, opts ...Option) (orm *Orm, err error) {
  function getDSN (line 97) | func getDSN(cfg *instanceConfig) string {

FILE: library/queue/queue.go
  type ProduceOption (line 7) | type ProduceOption struct
  type ProduceOptionFunc (line 9) | type ProduceOptionFunc
  type ConsumeOption (line 11) | type ConsumeOption struct
  type ConsumeOptionFunc (line 13) | type ConsumeOptionFunc
  type Consumer (line 15) | type Consumer
  type Queue (line 17) | type Queue interface

FILE: library/queue/rabbitmq/rabbitmq.go
  constant ExchangeTypeDirect (line 15) | ExchangeTypeDirect  = "direct"
  constant ExchangeTypeFanout (line 16) | ExchangeTypeFanout  = "fanout"
  constant ExchangeTypeTopic (line 17) | ExchangeTypeTopic   = "topic"
  constant ExchangeTypeHeaders (line 18) | ExchangeTypeHeaders = "headers"
  type Config (line 21) | type Config struct
  type Option (line 34) | type Option struct
  type OptionFunc (line 41) | type OptionFunc
  function defaultOption (line 43) | func defaultOption() *Option {
  function WithDeclareExchange (line 52) | func WithDeclareExchange(turn bool) OptionFunc {
  function WithDeclareQueue (line 56) | func WithDeclareQueue(turn bool) OptionFunc {
  function WithBindQueue (line 60) | func WithBindQueue(turn bool) OptionFunc {
  function WithQos (line 64) | func WithQos(qos int) OptionFunc {
  type RabbitMQ (line 68) | type RabbitMQ struct
    method Produce (line 101) | func (q *RabbitMQ) Produce(ctx context.Context, msg interface{}, opts ...
    method Consume (line 128) | func (q *RabbitMQ) Consume(consumer queue.Consumer) {
    method Shutdown (line 176) | func (q *RabbitMQ) Shutdown() (err error) {
    method connect (line 188) | func (q *RabbitMQ) connect() (err error) {
  function New (line 80) | func New(cfg *Config, opts ...OptionFunc) (*RabbitMQ, error) {

FILE: library/redis/conn.go
  type Config (line 9) | type Config struct
  function NewClient (line 24) | func NewClient(cfg *Config) *redis.Client {

FILE: library/registry/etcd/discovery.go
  constant defaultRefreshDuration (line 17) | defaultRefreshDuration = time.Second * 10
  type EtcdDiscovery (line 20) | type EtcdDiscovery struct
    method GetNodes (line 83) | func (s *EtcdDiscovery) GetNodes() []*registry.Node {
    method GetUpdateTime (line 95) | func (s *EtcdDiscovery) GetUpdateTime() time.Time {
    method Close (line 100) | func (s *EtcdDiscovery) Close() error {
    method init (line 111) | func (s *EtcdDiscovery) init() error {
    method loadKVs (line 125) | func (s *EtcdDiscovery) loadKVs() (kvs []*mvccpb.KeyValue) {
    method watcher (line 139) | func (s *EtcdDiscovery) watcher() {
    method refresh (line 168) | func (s *EtcdDiscovery) refresh() {
    method setNodes (line 185) | func (s *EtcdDiscovery) setNodes() {
    method setNode (line 207) | func (s *EtcdDiscovery) setNode(key string, node *registry.Node) {
    method delNode (line 215) | func (s *EtcdDiscovery) delNode(key string) {
    method logErr (line 222) | func (s *EtcdDiscovery) logErr(action, key, val string, err error) {
    method log (line 226) | func (s *EtcdDiscovery) log(action, key string) {
    method context (line 230) | func (s *EtcdDiscovery) context() (context.Context, context.CancelFunc) {
  type DiscoverOption (line 34) | type DiscoverOption
  function WithServierName (line 36) | func WithServierName(serviceName string) DiscoverOption {
  function WithDiscoverClient (line 40) | func WithDiscoverClient(cli *clientv3.Client) DiscoverOption {
  function WithRefreshDuration (line 44) | func WithRefreshDuration(d int) DiscoverOption {
  function WithCmdTimeOut (line 48) | func WithCmdTimeOut(t time.Duration) DiscoverOption {
  function NewDiscovery (line 53) | func NewDiscovery(opts ...DiscoverOption) (registry.Discovery, error) {
  function JSONDecode (line 234) | func JSONDecode(val string) (*registry.Node, error) {

FILE: library/registry/etcd/registrar.go
  type EtcdRegistrar (line 15) | type EtcdRegistrar struct
    method Register (line 76) | func (s *EtcdRegistrar) Register(ctx context.Context) error {
    method putKeyWithRegistrarLease (line 93) | func (s *EtcdRegistrar) putKeyWithRegistrarLease(ctx context.Context, ...
    method listenLeaseRespChan (line 115) | func (s *EtcdRegistrar) listenLeaseRespChan() {
    method DeRegister (line 123) | func (s *EtcdRegistrar) DeRegister(ctx context.Context) error {
  type RegistrarOption (line 30) | type RegistrarOption
  function WithRegistrarClient (line 32) | func WithRegistrarClient(cli *clientv3.Client) RegistrarOption {
  function WithRegistrarServiceName (line 36) | func WithRegistrarServiceName(serviceName string) RegistrarOption {
  function WithRegistarHost (line 40) | func WithRegistarHost(host string) RegistrarOption {
  function WithRegistarPort (line 44) | func WithRegistarPort(port int) RegistrarOption {
  function WithRegistrarLease (line 48) | func WithRegistrarLease(lease int64) RegistrarOption {
  function NewRegistry (line 53) | func NewRegistry(opts ...RegistrarOption) (*EtcdRegistrar, error) {
  function JSONEncode (line 131) | func JSONEncode(node *registry.Node) (string, error) {

FILE: library/registry/registry.go
  type Node (line 8) | type Node struct
  type RegistryConfig (line 14) | type RegistryConfig struct
  type Registrar (line 19) | type Registrar interface
  type Discovery (line 25) | type Discovery interface
  type Encode (line 32) | type Encode
  type Decode (line 35) | type Decode

FILE: library/reliablequeue/reliablequeue.go
  type ReliableQueue (line 25) | type ReliableQueue struct
    method Publish (line 82) | func (rq *ReliableQueue) Publish(ctx context.Context, tx *gorm.DB, msg...
    method generateMessage (line 116) | func (rq *ReliableQueue) generateMessage(ctx context.Context, tx *gorm...
    method getDistributeList (line 146) | func (rq *ReliableQueue) getDistributeList(ctx context.Context, tx *go...
    method Retry (line 157) | func (rq *ReliableQueue) Retry(ctx context.Context, tx *gorm.DB, recor...
    method Republish (line 180) | func (rq *ReliableQueue) Republish(ctx context.Context, tx *gorm.DB) (...
    method getUnsuccessRecords (line 189) | func (rq *ReliableQueue) getUnsuccessRecords(ctx context.Context, tx *...
    method publish (line 203) | func (rq *ReliableQueue) publish(ctx context.Context, records []Reliab...
    method SetSuccess (line 215) | func (rq *ReliableQueue) SetSuccess(ctx context.Context, tx *gorm.DB, ...
  type Option (line 30) | type Option struct
  type ReliableQueueOption (line 35) | type ReliableQueueOption
  function defaultOption (line 37) | func defaultOption() *Option {
  function WithFirstDelaySecond (line 44) | func WithFirstDelaySecond(t time.Duration) ReliableQueueOption {
  function WithRetryDelaySecondMultiple (line 50) | func WithRetryDelaySecondMultiple(i int64) ReliableQueueOption {
  function NewReliableQueue (line 56) | func NewReliableQueue(q queue.Queue, opts ...ReliableQueueOption) (*Reli...
  type PublishParams (line 75) | type PublishParams struct

FILE: library/reliablequeue/reliablequeue_test.go
  type Queue (line 17) | type Queue struct
    method Produce (line 19) | func (*Queue) Produce(ctx context.Context, msg interface{}, opts ...qu...
    method Consume (line 23) | func (*Queue) Consume(consumer queue.Consumer) {}
    method Shutdown (line 25) | func (*Queue) Shutdown() error { return nil }
  function createTable (line 27) | func createTable() (db *gorm.DB, err error) {
  function Test_defaultOption (line 41) | func Test_defaultOption(t *testing.T) {
  function TestNewReliableQueue (line 51) | func TestNewReliableQueue(t *testing.T) {
  function TestReliableQueue_Publish (line 66) | func TestReliableQueue_Publish(t *testing.T) {
  function TestReliableQueue_generateMessage (line 114) | func TestReliableQueue_generateMessage(t *testing.T) {
  function TestReliableQueue_getDistributeList (line 148) | func TestReliableQueue_getDistributeList(t *testing.T) {
  function TestReliableQueue_Retry (line 183) | func TestReliableQueue_Retry(t *testing.T) {
  function TestReliableQueue_Republish (line 234) | func TestReliableQueue_Republish(t *testing.T) {
  function TestReliableQueue_getUnsuccessRecords (line 259) | func TestReliableQueue_getUnsuccessRecords(t *testing.T) {
  function TestReliableQueue_publish (line 287) | func TestReliableQueue_publish(t *testing.T) {
  function TestReliableQueue_SetSuccess (line 310) | func TestReliableQueue_SetSuccess(t *testing.T) {

FILE: library/reliablequeue/table.go
  constant RecordStatusUnsuccess (line 6) | RecordStatusUnsuccess uint8 = 0
  constant RecordStatusSuccess (line 7) | RecordStatusSuccess   uint8 = 1
  type ReliableMqMessage (line 11) | type ReliableMqMessage struct
    method TableName (line 23) | func (ReliableMqMessage) TableName() string {
  type ReliableMqMessageDistribute (line 28) | type ReliableMqMessageDistribute struct
    method TableName (line 43) | func (ReliableMqMessageDistribute) TableName() string {
  type ReliableMqMessageRecord (line 48) | type ReliableMqMessageRecord struct
    method TableName (line 70) | func (ReliableMqMessageRecord) TableName() string {

FILE: library/reliablequeue/table.sql
  type `reliable_mq_message` (line 1) | CREATE TABLE `reliable_mq_message` (
  type `reliable_mq_message_distribute` (line 15) | CREATE TABLE `reliable_mq_message_distribute` (
  type `reliable_mq_message_record` (line 33) | CREATE TABLE `reliable_mq_message_record` (

FILE: library/selector/selector.go
  constant TypeWR (line 10) | TypeWR   = "wr"
  constant TypeWrr (line 11) | TypeWrr  = "wrr"
  constant TypeDwrr (line 12) | TypeDwrr = "dwrr"
  constant TypeP2C (line 13) | TypeP2C  = "p2c"
  constant TypeICMP (line 14) | TypeICMP = "icmp"
  type Statistics (line 17) | type Statistics struct
  type Meta (line 22) | type Meta struct
  type Node (line 24) | type Node interface
  type NewNodeFunc (line 31) | type NewNodeFunc
  type HandleInfo (line 33) | type HandleInfo struct
  type Selector (line 38) | type Selector interface
  function GenerateAddress (line 48) | func GenerateAddress(host string, port int) string {
  function ExtractAddress (line 52) | func ExtractAddress(address string) (string, int) {

FILE: library/selector/wr/wr.go
  type Node (line 13) | type Node struct
    method Address (line 35) | func (n *Node) Address() string {
    method Meta (line 39) | func (n *Node) Meta() selector.Meta {
    method Statistics (line 43) | func (n *Node) Statistics() selector.Statistics {
    method Weight (line 49) | func (n *Node) Weight() int {
    method incrSuccess (line 53) | func (n *Node) incrSuccess() {
    method incrFail (line 59) | func (n *Node) incrFail() {
  function NewNode (line 26) | func NewNode(host string, port, weight int, meta selector.Meta) selector...
  type nodeOffset (line 65) | type nodeOffset struct
  type Selector (line 72) | type Selector struct
    method ServiceName (line 105) | func (s *Selector) ServiceName() string {
    method AddNode (line 109) | func (s *Selector) AddNode(node selector.Node) (err error) {
    method DeleteNode (line 148) | func (s *Selector) DeleteNode(host string, port int) (err error) {
    method GetNodes (line 187) | func (s *Selector) GetNodes() (nodes []selector.Node, err error) {
    method GetNode (line 198) | func (s *Selector) GetNode(host string, port int) (node selector.Node,...
    method Select (line 206) | func (s *Selector) Select() (node selector.Node, err error) {
    method AfterHandle (line 234) | func (s *Selector) AfterHandle(address string, err error) {
    method checkSameWeight (line 252) | func (s *Selector) checkSameWeight() {
    method sortOffset (line 271) | func (s *Selector) sortOffset() {
    method node2WRNode (line 277) | func (s *Selector) node2WRNode(node selector.Node) *Node {
  type SelectorOption (line 85) | type SelectorOption
  function WithServiceName (line 87) | func WithServiceName(name string) SelectorOption {
  function NewSelector (line 91) | func NewSelector(opts ...SelectorOption) *Selector {

FILE: library/selector/wr/wr_test.go
  function TestNewNode (line 15) | func TestNewNode(t *testing.T) {
  function TestNode_Address (line 30) | func TestNode_Address(t *testing.T) {
  function TestNode_Meta (line 33) | func TestNode_Meta(t *testing.T) {
  function TestNode_Statistics (line 36) | func TestNode_Statistics(t *testing.T) {
  function TestNode_Weight (line 39) | func TestNode_Weight(t *testing.T) {
  function TestNode_incrSuccess (line 42) | func TestNode_incrSuccess(t *testing.T) {
  function TestNode_incrFail (line 45) | func TestNode_incrFail(t *testing.T) {
  function TestWithServiceName (line 48) | func TestWithServiceName(t *testing.T) {
  function TestNewSelector (line 51) | func TestNewSelector(t *testing.T) {
  function TestSelector_ServiceName (line 54) | func TestSelector_ServiceName(t *testing.T) {
  function TestSelector_AddNode (line 64) | func TestSelector_AddNode(t *testing.T) {
  function TestSelector_DeleteNode (line 67) | func TestSelector_DeleteNode(t *testing.T) {
  function TestSelector_GetNodes (line 70) | func TestSelector_GetNodes(t *testing.T) {
  function TestSelector_Select (line 73) | func TestSelector_Select(t *testing.T) {
  function TestSelector_AfterHandle (line 76) | func TestSelector_AfterHandle(t *testing.T) {
  function TestSelector_checkSameWeight (line 79) | func TestSelector_checkSameWeight(t *testing.T) {
  function TestSelector_sortOffset (line 82) | func TestSelector_sortOffset(t *testing.T) {
  function TestSelector_node2WRNode (line 85) | func TestSelector_node2WRNode(t *testing.T) {
  function TestWR (line 88) | func TestWR(t *testing.T) {
  function testNoDeleteHandle (line 171) | func testNoDeleteHandle(t *testing.T, nodes []*Node) []selector.Node {
  function testDeleteHandle (line 198) | func testDeleteHandle(t *testing.T, nodes []*Node) []selector.Node {

FILE: library/servicer/service/service.go
  function LoadGlobPattern (line 25) | func LoadGlobPattern(path, suffix string, etcd *etcd.Etcd) (err error) {
  function LoadService (line 72) | func LoadService(config *Config, opts ...Option) (err error) {
  type Config (line 83) | type Config struct
  type Service (line 95) | type Service struct
    method Name (line 138) | func (s *Service) Name() string {
    method Pick (line 142) | func (s *Service) Pick(ctx context.Context) (node *servicer.Node, err ...
    method initSelector (line 174) | func (s *Service) initSelector() (err error) {
    method adjustSelectorNode (line 194) | func (s *Service) adjustSelectorNode() {
    method Done (line 242) | func (s *Service) Done(ctx context.Context, node *servicer.Node, err e...
    method GetCaCrt (line 250) | func (s *Service) GetCaCrt() []byte {
    method GetClientPem (line 254) | func (s *Service) GetClientPem() []byte {
    method GetClientKey (line 258) | func (s *Service) GetClientKey() []byte {
  type Option (line 108) | type Option
  function WithDiscovery (line 110) | func WithDiscovery(discovery registry.Discovery) Option {
  function NewService (line 114) | func NewService(config *Config, opts ...Option) (*Service, error) {

FILE: library/servicer/servicer.go
  constant TypeRegistry (line 9) | TypeRegistry uint8 = 1
  constant TypeIPPort (line 10) | TypeIPPort   uint8 = 2
  constant TypeDomain (line 11) | TypeDomain   uint8 = 3
  type Node (line 14) | type Node struct
  type DoneInfo (line 19) | type DoneInfo struct
  function SetServicer (line 29) | func SetServicer(s Servicer) {
  function DelServicer (line 35) | func DelServicer(s Servicer) {
  function GetServicer (line 41) | func GetServicer(serviceName string) (Servicer, bool) {
  type Servicer (line 46) | type Servicer interface

FILE: server/grpc/cmux/cmux.go
  type RegisterHTTP (line 20) | type RegisterHTTP
  type Option (line 23) | type Option struct
  type OptionFunc (line 29) | type OptionFunc
  function WithHTTP (line 31) | func WithHTTP(httpServer *http.Server, registerHTTP RegisterHTTP) Option...
  type CMUXServer (line 38) | type CMUXServer struct
    method Start (line 68) | func (s *CMUXServer) Start() (err error) {
    method startGRPC (line 81) | func (s *CMUXServer) startGRPC() {
    method startHTTP (line 99) | func (s *CMUXServer) startHTTP() (err error) {
    method Close (line 144) | func (s *CMUXServer) Close() (err error) {
  function NewCMUX (line 48) | func NewCMUX(endpoint string, registers []serverGRPC.Register, opts ...O...

FILE: server/grpc/h2c/h2c.go
  type Option (line 20) | type Option struct
  type OptionFunc (line 24) | type OptionFunc
  function WithLogger (line 26) | func WithLogger(l logger.Logger) OptionFunc {
  type H2CServer (line 30) | type H2CServer struct
    method Start (line 61) | func (s *H2CServer) Start() (err error) {
    method Close (line 97) | func (s *H2CServer) Close() (err error) {
  function NewH2C (line 41) | func NewH2C(endpoint string, registers []serverGRPC.Register, opts ...Op...

FILE: server/grpc/middleware/log/log.go
  function LogIDFromMD (line 16) | func LogIDFromMD(md metadata.MD) string {
  function GetPeerAddr (line 25) | func GetPeerAddr(ctx context.Context) string {
  function UnaryServerInterceptor (line 37) | func UnaryServerInterceptor(l logger.Logger) grpc.UnaryServerInterceptor {
  function UnaryClientInterceptor (line 71) | func UnaryClientInterceptor() grpc.UnaryClientInterceptor {

FILE: server/grpc/option.go
  type DialOption (line 44) | type DialOption struct
  type DialOptionFunc (line 46) | type DialOptionFunc
  function NewDialOption (line 48) | func NewDialOption(opts ...DialOptionFunc) []grpc.DialOption {
  type ServerOption (line 76) | type ServerOption struct
  type ServerOptionFunc (line 80) | type ServerOptionFunc
  function ServerOptionLogger (line 82) | func ServerOptionLogger(l logger.Logger) ServerOptionFunc {
  function NewServerOption (line 86) | func NewServerOption(opts ...ServerOptionFunc) []grpc.ServerOption {
  type CallOption (line 124) | type CallOption struct
  type CallOptionFunc (line 126) | type CallOptionFunc
  function NewCallOption (line 128) | func NewCallOption(opts ...CallOption) []grpc.CallOption {

FILE: server/grpc/server.go
  type RegisterGRPC (line 13) | type RegisterGRPC
  type RegisterMux (line 14) | type RegisterMux
  type Register (line 17) | type Register struct
  function NewRegister (line 22) | func NewRegister(registerGRPC RegisterGRPC, registerMux RegisterMux) Reg...
  function RegisterTools (line 29) | func RegisterTools(s *grpc.Server) {

FILE: server/http/middleware/cors/cors.go
  function CORS (line 20) | func CORS(c cors.Config) gin.HandlerFunc {

FILE: server/http/middleware/csrf/csrf.go
  function CSRF (line 11) | func CSRF(authKey []byte, domain string) gin.HandlerFunc {

FILE: server/http/middleware/limiter/limiter.go
  function Limiter (line 14) | func Limiter(maxBurstSize int, l logger.Logger) gin.HandlerFunc {

FILE: server/http/middleware/log/log.go
  function LoggerMiddleware (line 21) | func LoggerMiddleware(l logger.Logger) gin.HandlerFunc {

FILE: server/http/middleware/panic/panic.go
  function ThrowPanic (line 13) | func ThrowPanic(l logger.Logger) gin.HandlerFunc {

FILE: server/http/middleware/timeout/timeout.go
  constant TimeoutKey (line 13) | TimeoutKey = "Timeout-Millisecond"
  constant startKey (line 14) | startKey   = "Timeout-StartAt"
  function TimeoutMiddleware (line 18) | func TimeoutMiddleware(timeout time.Duration) func(c *gin.Context) {
  function SetStart (line 38) | func SetStart(ctx context.Context, timeout int64) context.Context {
  function CalcRemainTimeout (line 43) | func CalcRemainTimeout(ctx context.Context) (int64, error) {
  function nowMillisecond (line 62) | func nowMillisecond() int64 {

FILE: server/http/response/error.go
  type ResponseError (line 9) | type ResponseError struct
    method Toast (line 15) | func (r *ResponseError) Toast() string { return r.toast }
    method SetToast (line 18) | func (r *ResponseError) SetToast(toast string) { r.toast = toast }
    method Error (line 21) | func (r *ResponseError) Error() string { return r.err.Error() }
    method SetError (line 24) | func (r *ResponseError) SetError(err error) { r.err = err }
    method Unwrap (line 27) | func (r *ResponseError) Unwrap() error { return r.err }
    method Cause (line 30) | func (r *ResponseError) Cause() error { return r.err }
  function WrapToast (line 33) | func WrapToast(err error, toast string) *ResponseError {
  function WrapToastf (line 48) | func WrapToastf(err error, toast string, args ...interface{}) *ResponseE...

FILE: server/http/response/response.go
  type Code (line 12) | type Code
  type response (line 14) | type response struct
  function ResponseJSON (line 22) | func ResponseJSON(c *gin.Context, code Code, data interface{}, err *Resp...

FILE: server/http/server.go
  type Server (line 16) | type Server struct
    method Start (line 79) | func (s *Server) Start() (err error) {
    method Close (line 87) | func (s *Server) Close() (err error) {
    method initHandler (line 92) | func (s *Server) initHandler() *gin.Engine {
    method startPprof (line 115) | func (s *Server) startPprof(server *gin.Engine) {
  type RegisterRouter (line 27) | type RegisterRouter
  type Option (line 29) | type Option
  function WithReadTimeout (line 31) | func WithReadTimeout(timeout time.Duration) Option {
  function WithWriteTimeout (line 35) | func WithWriteTimeout(timeout time.Duration) Option {
  function WithMiddlewares (line 39) | func WithMiddlewares(middlewares ...gin.HandlerFunc) Option {
  function WithRegisterRouter (line 43) | func WithRegisterRouter(r RegisterRouter) Option {
  function WithPprof (line 47) | func WithPprof(pprofTurn bool) Option {
  function WithDebug (line 51) | func WithDebug(isDebug bool) Option {
  function WithOnShutDown (line 55) | func WithOnShutDown(onShutdown []func()) Option {
  function New (line 59) | func New(addr string, opts ...Option) *Server {

FILE: server/http/util/util.go
  type BodyWriter (line 11) | type BodyWriter struct
    method Write (line 18) | func (w BodyWriter) Write(b []byte) (int, error) {

FILE: server/server.go
  type Server (line 8) | type Server interface
  function RegisterCloseFunc (line 17) | func RegisterCloseFunc(cf interface{}) error {
Condensed preview — 167 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (518K chars).
[
  {
    "path": ".gitignore",
    "chars": 191,
    "preview": ".svn\n.svn/*\n*.swp\n*.swn\n*.swo\n*.tmp\n*.swm\napp/logs/*\napp/log/*\nlogs/*\nlog/*\ndevelopment\n.tags*\n.idea\n.vscode\n.DS_Store\n_"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "\nThe MIT License (MIT)\n\nCopyright (c) 2021 AirGo\n\nPermission is hereby granted, free of charge, to any person obtaining "
  },
  {
    "path": "Makefile",
    "chars": 217,
    "preview": ".PHONY: all build test clean\n\nall: build test\n\nformat:\n\tgo vet ./...\n\tgofmt -w .\n\tgolint ./...\nbuild:\n\tgo mod download \n"
  },
  {
    "path": "README.md",
    "chars": 188,
    "preview": "<!--\n * @Descripttion:\n * @Author: weihaoyu\n-->\n\n# gin-api\nGo 微服务框架,同时支持 gRPC 和 HTTP,封装各种常用组件,开箱即用,专注业务。\n<br>\n本代码库已停止维护,"
  },
  {
    "path": "app/Dockerfile",
    "chars": 366,
    "preview": "# 使用最新golang镜像\nFROM golang:latest\n\n# 作者\nMAINTAINER AirGo\n\n# 环境变量配置\nENV GOPROXY https://goproxy.cn,direct\nENV GO111MODULE"
  },
  {
    "path": "app/Makefile",
    "chars": 264,
    "preview": ".PHONY: all build test clean\n\nall: build test\n\nformat:\n\tgo vet ./...\n\tgofmt -w .\n\tgolint ./...\nbuild:\n\tgo mod download \n"
  },
  {
    "path": "app/conf/dev/app.toml",
    "chars": 159,
    "preview": "AppName = \"gin-api-dev\"\nAppPort = 8777\nPprof = true\nIsDebug = true\nContextTimeout = 100000\nConnectTimeout = 100000\nWrite"
  },
  {
    "path": "app/conf/dev/default_rabbitmq.toml",
    "chars": 207,
    "preview": "ServiceName = \"default_rabbitmq\"\nHost = \"127.0.0.1\"\nPort = 5672\nVirtual = \"why\"\nUser = \"why\"\nPass = \"why\"\nExchangeType ="
  },
  {
    "path": "app/conf/dev/default_redis.toml",
    "chars": 191,
    "preview": "ServiceName = \"default_redis\"\nHost = \"127.0.0.1\"\nPort = 6379\nAuth = \"\"\nDB = 0\nConnectTimeout = 1\nReadTimeout = 1\nWriteTi"
  },
  {
    "path": "app/conf/dev/etcd.toml",
    "chars": 78,
    "preview": "Endpoints = \"localhost:23790;localhost:23791;localhost:23792\"\nDialTimeout = 5\n"
  },
  {
    "path": "app/conf/dev/jaeger.toml",
    "chars": 32,
    "preview": "Host = \"127.0.0.1\"\nPort = \"6831\""
  },
  {
    "path": "app/conf/dev/log/gorm.toml",
    "chars": 202,
    "preview": "SlowThreshold = 1000\nInfoFile = \"./log/gorm/info.log\"\nErrorFile = \"./log/gorm/error.wf.log\"\nLevel = 4 # Silent(1) < Erro"
  },
  {
    "path": "app/conf/dev/log/queue.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/queue/info.log\"\nErrorFile = \"./log/queue/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/dev/log/redis.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/redis/info.log\"\nErrorFile = \"./log/redis/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/dev/log/rpc.toml",
    "chars": 121,
    "preview": "InfoFile = \"./log/rpc/info.log\"\nErrorFile = \"./log/rpc/error.wf.log\"\nLevel = \"info\" # debug < info < warn < error < fata"
  },
  {
    "path": "app/conf/dev/log/service.toml",
    "chars": 130,
    "preview": "InfoFile = \"./log/service/info.log\"\nErrorFile = \"./log/service/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < err"
  },
  {
    "path": "app/conf/dev/registry.toml",
    "chars": 10,
    "preview": "Lease = 5\n"
  },
  {
    "path": "app/conf/dev/services/gin-api.toml",
    "chars": 138,
    "preview": "ServiceName = \"gin-api-dev\"\nType = 2 # 1-注册发现,2-IP+PORT,3-域名\nHost = \"127.0.0.1\"\nPort = 8777\nSelector = \"wr\" #参考selector\n"
  },
  {
    "path": "app/conf/dev/test_mysql.toml",
    "chars": 291,
    "preview": "ServiceName = \"test_mysql\"\n\n[master]\nHost = \"127.0.0.1\"\nPort = \"3306\"\nUser = \"root\"\nPassword = \"123456\"\nDB = \"test\"\nChar"
  },
  {
    "path": "app/conf/liantiao/app.toml",
    "chars": 163,
    "preview": "AppName = \"gin-api-liantiao\"\nAppPort = 888\nPprof = true\nIsDebug = true\nContextTimeout = 100000\nConnectTimeout = 100000\nW"
  },
  {
    "path": "app/conf/liantiao/default_rabbitmq.toml",
    "chars": 207,
    "preview": "ServiceName = \"default_rabbitmq\"\nHost = \"127.0.0.1\"\nPort = 5672\nVirtual = \"why\"\nUser = \"why\"\nPass = \"why\"\nExchangeType ="
  },
  {
    "path": "app/conf/liantiao/default_redis.toml",
    "chars": 191,
    "preview": "ServiceName = \"default_redis\"\nHost = \"127.0.0.1\"\nPort = 6379\nAuth = \"\"\nDB = 0\nConnectTimeout = 1\nReadTimeout = 1\nWriteTi"
  },
  {
    "path": "app/conf/liantiao/etcd.toml",
    "chars": 78,
    "preview": "Endpoints = \"localhost:23790;localhost:23791;localhost:23792\"\nDialTimeout = 5\n"
  },
  {
    "path": "app/conf/liantiao/jaeger.toml",
    "chars": 32,
    "preview": "Host = \"127.0.0.1\"\nPort = \"6831\""
  },
  {
    "path": "app/conf/liantiao/log/gorm.toml",
    "chars": 202,
    "preview": "SlowThreshold = 1000\nInfoFile = \"./log/gorm/info.log\"\nErrorFile = \"./log/gorm/error.wf.log\"\nLevel = 4 # Silent(1) < Erro"
  },
  {
    "path": "app/conf/liantiao/log/queue.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/queue/info.log\"\nErrorFile = \"./log/queue/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/liantiao/log/redis.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/redis/info.log\"\nErrorFile = \"./log/redis/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/liantiao/log/rpc.toml",
    "chars": 121,
    "preview": "InfoFile = \"./log/rpc/info.log\"\nErrorFile = \"./log/rpc/error.wf.log\"\nLevel = \"info\" # debug < info < warn < error < fata"
  },
  {
    "path": "app/conf/liantiao/log/service.toml",
    "chars": 130,
    "preview": "InfoFile = \"./log/service/info.log\"\nErrorFile = \"./log/service/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < err"
  },
  {
    "path": "app/conf/liantiao/services/gin-api.toml",
    "chars": 133,
    "preview": "ServiceName = \"gin-api\"\nType = 2 # 1-注册发现,2-IP+PORT,3-域名\nHost = \"127.0.0.1\"\nPort = 777\nSelector = \"wr\" #参考selector\nRefre"
  },
  {
    "path": "app/conf/liantiao/test_mysql.toml",
    "chars": 263,
    "preview": "[master]\nHost = \"127.0.0.1\"\nPort = \"3306\"\nUser = \"root\"\nPassword = \"123456\"\nDB = \"test\"\nCharset = \"utf8mb4\"\nMaxOpen = 8\n"
  },
  {
    "path": "app/conf/online/app.toml",
    "chars": 164,
    "preview": "AppName = \"gin-api-online\"\nAppPort = 1000\nPprof = false\nIsDebug = false\nContextTimeout = 100000\nConnectTimeout = 100000\n"
  },
  {
    "path": "app/conf/online/default_rabbitmq.toml",
    "chars": 207,
    "preview": "ServiceName = \"default_rabbitmq\"\nHost = \"127.0.0.1\"\nPort = 5672\nVirtual = \"why\"\nUser = \"why\"\nPass = \"why\"\nExchangeType ="
  },
  {
    "path": "app/conf/online/default_redis.toml",
    "chars": 191,
    "preview": "ServiceName = \"default_redis\"\nHost = \"127.0.0.1\"\nPort = 6379\nAuth = \"\"\nDB = 0\nConnectTimeout = 1\nReadTimeout = 1\nWriteTi"
  },
  {
    "path": "app/conf/online/etcd.toml",
    "chars": 78,
    "preview": "Endpoints = \"localhost:23790;localhost:23791;localhost:23792\"\nDialTimeout = 5\n"
  },
  {
    "path": "app/conf/online/jaeger.toml",
    "chars": 32,
    "preview": "Host = \"127.0.0.1\"\nPort = \"6831\""
  },
  {
    "path": "app/conf/online/log/gorm.toml",
    "chars": 202,
    "preview": "SlowThreshold = 1000\nInfoFile = \"./log/gorm/info.log\"\nErrorFile = \"./log/gorm/error.wf.log\"\nLevel = 4 # Silent(1) < Erro"
  },
  {
    "path": "app/conf/online/log/queue.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/queue/info.log\"\nErrorFile = \"./log/queue/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/online/log/redis.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/redis/info.log\"\nErrorFile = \"./log/redis/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/online/log/rpc.toml",
    "chars": 121,
    "preview": "InfoFile = \"./log/rpc/info.log\"\nErrorFile = \"./log/rpc/error.wf.log\"\nLevel = \"info\" # debug < info < warn < error < fata"
  },
  {
    "path": "app/conf/online/log/service.toml",
    "chars": 130,
    "preview": "InfoFile = \"./log/service/info.log\"\nErrorFile = \"./log/service/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < err"
  },
  {
    "path": "app/conf/online/services/gin-api.toml",
    "chars": 133,
    "preview": "ServiceName = \"gin-api\"\nType = 2 # 1-注册发现,2-IP+PORT,3-域名\nHost = \"127.0.0.1\"\nPort = 777\nSelector = \"wr\" #参考selector\nRefre"
  },
  {
    "path": "app/conf/online/test_mysql.toml",
    "chars": 263,
    "preview": "[master]\nHost = \"127.0.0.1\"\nPort = \"3306\"\nUser = \"root\"\nPassword = \"123456\"\nDB = \"test\"\nCharset = \"utf8mb4\"\nMaxOpen = 8\n"
  },
  {
    "path": "app/conf/qa/app.toml",
    "chars": 157,
    "preview": "AppName = \"gin-api-qa\"\nAppPort = 999\nPprof = true\nIsDebug = true\nContextTimeout = 100000\nConnectTimeout = 100000\nWriteTi"
  },
  {
    "path": "app/conf/qa/default_rabbitmq.toml",
    "chars": 207,
    "preview": "ServiceName = \"default_rabbitmq\"\nHost = \"127.0.0.1\"\nPort = 5672\nVirtual = \"why\"\nUser = \"why\"\nPass = \"why\"\nExchangeType ="
  },
  {
    "path": "app/conf/qa/default_redis.toml",
    "chars": 191,
    "preview": "ServiceName = \"default_redis\"\nHost = \"127.0.0.1\"\nPort = 6379\nAuth = \"\"\nDB = 0\nConnectTimeout = 1\nReadTimeout = 1\nWriteTi"
  },
  {
    "path": "app/conf/qa/etcd.toml",
    "chars": 78,
    "preview": "Endpoints = \"localhost:23790;localhost:23791;localhost:23792\"\nDialTimeout = 5\n"
  },
  {
    "path": "app/conf/qa/jaeger.toml",
    "chars": 32,
    "preview": "Host = \"127.0.0.1\"\nPort = \"6831\""
  },
  {
    "path": "app/conf/qa/log/gorm.toml",
    "chars": 202,
    "preview": "SlowThreshold = 1000\nInfoFile = \"./log/gorm/info.log\"\nErrorFile = \"./log/gorm/error.wf.log\"\nLevel = 4 # Silent(1) < Erro"
  },
  {
    "path": "app/conf/qa/log/queue.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/queue/info.log\"\nErrorFile = \"./log/queue/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/qa/log/redis.toml",
    "chars": 126,
    "preview": "InfoFile = \"./log/redis/info.log\"\nErrorFile = \"./log/redis/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < error <"
  },
  {
    "path": "app/conf/qa/log/rpc.toml",
    "chars": 121,
    "preview": "InfoFile = \"./log/rpc/info.log\"\nErrorFile = \"./log/rpc/error.wf.log\"\nLevel = \"info\" # debug < info < warn < error < fata"
  },
  {
    "path": "app/conf/qa/log/service.toml",
    "chars": 130,
    "preview": "InfoFile = \"./log/service/info.log\"\nErrorFile = \"./log/service/error.wf.log\"\nLevel = \"debug\" # debug < info < warn < err"
  },
  {
    "path": "app/conf/qa/services/gin-api.toml",
    "chars": 133,
    "preview": "ServiceName = \"gin-api\"\nType = 2 # 1-注册发现,2-IP+PORT,3-域名\nHost = \"127.0.0.1\"\nPort = 777\nSelector = \"wr\" #参考selector\nRefre"
  },
  {
    "path": "app/conf/qa/test_mysql.toml",
    "chars": 263,
    "preview": "[master]\nHost = \"127.0.0.1\"\nPort = \"3306\"\nUser = \"root\"\nPassword = \"123456\"\nDB = \"test\"\nCharset = \"utf8mb4\"\nMaxOpen = 8\n"
  },
  {
    "path": "app/loader/loader.go",
    "chars": 6011,
    "preview": "package loader\n\nimport (\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/why444216978/go-util/assert\"\n\t\"github.com/why"
  },
  {
    "path": "app/main.go",
    "chars": 2418,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/why444216978/gin-api/app/loader\"\n\tjobGRPC \"github.com/why4442"
  },
  {
    "path": "app/module/goods/api/conn.go",
    "chars": 1849,
    "preview": "package api\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/go-redis/redis/v8\"\n\t\"golang"
  },
  {
    "path": "app/module/goods/job/job.go",
    "chars": 12,
    "preview": "package job\n"
  },
  {
    "path": "app/module/goods/respository/respository.go",
    "chars": 244,
    "preview": "package respository\n\ntype Test struct {\n\tId      uint   `gorm:\"column:id\" json:\"id\"`\n\tGoodsId uint64 `gorm:\"column:goods"
  },
  {
    "path": "app/module/goods/service/service.go",
    "chars": 2088,
    "preview": "package goods\n\nimport (\n\t\"context\"\n\t\"strconv\"\n\n\t\"github.com/go-redis/redis/v8\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/why"
  },
  {
    "path": "app/module/ping/api/ping.go",
    "chars": 577,
    "preview": "package api\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/why444216978/gin-api/app/response\"\n\tgin_api \"github.com/"
  },
  {
    "path": "app/module/ping/job/job.go",
    "chars": 12,
    "preview": "package job\n"
  },
  {
    "path": "app/module/ping/responsitory/responsitory.go",
    "chars": 21,
    "preview": "package responsitory\n"
  },
  {
    "path": "app/module/ping/service/service.go",
    "chars": 16,
    "preview": "package service\n"
  },
  {
    "path": "app/module/test/api/test.go",
    "chars": 1166,
    "preview": "package api\n\nimport (\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/why444216978/gin-api/app/response\"\n\tgin_api \"gi"
  },
  {
    "path": "app/module/test/job/grpc/job.go",
    "chars": 710,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\tpb \"github.com/why444216978/gin-api/app/module/test/service/gr"
  },
  {
    "path": "app/module/test/respository/respository.go",
    "chars": 20,
    "preview": "package respository\n"
  },
  {
    "path": "app/module/test/service/grpc/google/api/annotations.proto",
    "chars": 1051,
    "preview": "// Copyright (c) 2015, Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "app/module/test/service/grpc/google/api/http.proto",
    "chars": 12099,
    "preview": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
  },
  {
    "path": "app/module/test/service/grpc/google/api/httpbody.proto",
    "chars": 2674,
    "preview": "// Copyright 2018 Google LLC.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use t"
  },
  {
    "path": "app/module/test/service/grpc/google/protobuf/descriptor.proto",
    "chars": 38043,
    "preview": "// Protocol Buffers - Google's data interchange format\n// Copyright 2008 Google Inc.  All rights reserved.\n// https://de"
  },
  {
    "path": "app/module/test/service/grpc/grpc.go",
    "chars": 619,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n\n\tpb \"github.com/why444216978/gin-api/app/module/test/servi"
  },
  {
    "path": "app/module/test/service/grpc/helloworld/hello_world.pb.go",
    "chars": 7532,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc        v3.18.0\n// sou"
  },
  {
    "path": "app/module/test/service/grpc/helloworld/hello_world.pb.gw.go",
    "chars": 6553,
    "preview": "// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.\n// source: helloworld/hello_world.proto\n\n/*\nPackage helloworl"
  },
  {
    "path": "app/module/test/service/grpc/helloworld/hello_world.proto",
    "chars": 484,
    "preview": "syntax = \"proto3\";\n\noption go_package=\"./helloworld;helloworld\";\npackage helloworld;\n\nimport \"google/api/annotations.pro"
  },
  {
    "path": "app/module/test/service/grpc/helloworld/hello_world_grpc.pb.go",
    "chars": 3445,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage helloworld\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.gol"
  },
  {
    "path": "app/resource/resource.go",
    "chars": 729,
    "preview": "package resource\n\nimport (\n\t\"github.com/go-redis/redis/v8\"\n\n\thttpClient \"github.com/why444216978/gin-api/client/http\"\n\t\""
  },
  {
    "path": "app/response/response.go",
    "chars": 876,
    "preview": "package response\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/why444216978/gin-api/server/http/respo"
  },
  {
    "path": "app/router/router.go",
    "chars": 578,
    "preview": "package router\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\n\tconn \"github.com/why444216978/gin-api/app/module/goods/api\"\n\tping"
  },
  {
    "path": "app/rpc/gin-api/test.go",
    "chars": 1904,
    "preview": "package gin_api\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\tjsonCodec \"github.com/why444216978/codec/json\"\n\n\t\"gith"
  },
  {
    "path": "bootstrap/app.go",
    "chars": 1895,
    "preview": "package bootstrap\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/why4"
  },
  {
    "path": "bootstrap/init.go",
    "chars": 377,
    "preview": "package bootstrap\n\nimport (\n\t\"log\"\n\t\"syscall\"\n\n\t\"github.com/why444216978/gin-api/library/app\"\n\t\"github.com/why444216978/"
  },
  {
    "path": "client/grpc/conn.go",
    "chars": 336,
    "preview": "package client\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n\n\tserverGRPC \"github.com/why444216978/gin-api/server/grpc"
  },
  {
    "path": "client/http/client.go",
    "chars": 440,
    "preview": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/why444216978/codec\"\n)\n\ntype Request struct {\n\tURI   "
  },
  {
    "path": "client/http/plugin.go",
    "chars": 661,
    "preview": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\n\tjaeger \"github.com/why444216978/gin-api/library/jaeger/http\"\n\t\"github.co"
  },
  {
    "path": "client/http/transport/transport.go",
    "chars": 5135,
    "preview": "package transport\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"tim"
  },
  {
    "path": "go.mod",
    "chars": 4033,
    "preview": "module github.com/why444216978/gin-api\n\ngo 1.16\n\nrequire (\n\tgithub.com/HdrHistogram/hdrhistogram-go v1.1.0 // indirect\n\t"
  },
  {
    "path": "go.sum",
    "chars": 122571,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
  },
  {
    "path": "library/apollo/agollo/README.md",
    "chars": 570,
    "preview": "### Example\n\n```golang\npackage agollo\n\nimport (\n\t\"context\"\n\n\t\"github.com/why444216978/gin-api/library/apollo/agollo/list"
  },
  {
    "path": "library/apollo/agollo/agollo.go",
    "chars": 3787,
    "preview": "package agollo\n\nimport (\n\t\"context\"\n\t\"io/fs\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/apolloconfig/agollo/v4\"\n\t\"github.com/apolloc"
  },
  {
    "path": "library/apollo/agollo/agollo_test.go",
    "chars": 669,
    "preview": "package agollo\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\n\t\"github.com/why444216978/gin-api/libr"
  },
  {
    "path": "library/apollo/agollo/listener/listener.go",
    "chars": 494,
    "preview": "package listener\n\nimport (\n\t\"github.com/apolloconfig/agollo/v4\"\n\t\"github.com/apolloconfig/agollo/v4/storage\"\n)\n\ntype Cus"
  },
  {
    "path": "library/apollo/agollo/listener/mock/listener.go",
    "chars": 2984,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: library/apollo/agollo/listener/listener.go\n\n// Package mock is a g"
  },
  {
    "path": "library/apollo/agollo/listener/structlistener/listener.go",
    "chars": 1703,
    "preview": "package structlistener\n\nimport (\n\t\"sync\"\n\n\t\"github.com/apolloconfig/agollo/v4\"\n\t\"github.com/apolloconfig/agollo/v4/compo"
  },
  {
    "path": "library/apollo/agollo/util/util.go",
    "chars": 911,
    "preview": "package util\n\nimport (\n\t\"bytes\"\n\t\"path\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/why444216978/codec/json\"\n\t\"github.com/why"
  },
  {
    "path": "library/apollo/http/apollo.go",
    "chars": 2300,
    "preview": "//vim ~/.bash_profile\n//export RUNTIME_CLUSTER=development     #填写对应的集群名称\n//export CONFIG_CENTER_URL=http://development."
  },
  {
    "path": "library/app/app.go",
    "chars": 1241,
    "preview": "package app\n\nimport (\n\t\"time\"\n\n\t\"github.com/why444216978/gin-api/library/config\"\n)\n\nvar app struct {\n\tAppName        str"
  },
  {
    "path": "library/cache/cache.go",
    "chars": 1843,
    "preview": "package cache\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"runtime/debug\"\n\t\"time\"\n)\n\n// CacheData is cache data struct\ntype Ca"
  },
  {
    "path": "library/cache/redis/redis_cache.go",
    "chars": 2802,
    "preview": "package cache\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/go-redis/redis/v8\"\n\t\"github.com/why4"
  },
  {
    "path": "library/config/viper.go",
    "chars": 1161,
    "preview": "package config\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/spf13/viper\"\n)\n\ntype Viper struct {\n\t*viper.Viper\n\t"
  },
  {
    "path": "library/cron/cron.go",
    "chars": 4970,
    "preview": "package cron\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/ro"
  },
  {
    "path": "library/cron/cron_test.go",
    "chars": 933,
    "preview": "package cron\n\nimport (\n\t\"log\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/mock/gomock\"\n\t\"github.com/stretchr/testify/assert\""
  },
  {
    "path": "library/endless/endless.go",
    "chars": 13853,
    "preview": "package endless\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"runti"
  },
  {
    "path": "library/etcd/etcd.go",
    "chars": 782,
    "preview": "package etcd\n\nimport (\n\t\"time\"\n\n\tclientv3 \"go.etcd.io/etcd/client/v3\"\n)\n\ntype Config struct {\n\tEndpoints   string\n\tDialT"
  },
  {
    "path": "library/jaeger/gorm/gorm.go",
    "chars": 3358,
    "preview": "package gorm\n\nimport (\n\t\"github.com/opentracing/opentracing-go\"\n\t\"github.com/opentracing/opentracing-go/ext\"\n\topentracin"
  },
  {
    "path": "library/jaeger/gorm/gorm_test.go",
    "chars": 3502,
    "preview": "package gorm\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/opentracing/opentracing-go\"\n\t\"github.com/opentracing/opentraci"
  },
  {
    "path": "library/jaeger/http/http.go",
    "chars": 2168,
    "preview": "package http\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/opentracing/opentracing-go\"\n\t\"github.com/opentraci"
  },
  {
    "path": "library/jaeger/http/http_test.go",
    "chars": 2660,
    "preview": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n\n\t\"github.com/opentracing/opentracing-go\"\n\t\"github.c"
  },
  {
    "path": "library/jaeger/jaeger.go",
    "chars": 2182,
    "preview": "package jaeger\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/opentracing/opentracing-go\"\n\topentracingLog \"github.com/opentrac"
  },
  {
    "path": "library/jaeger/redis/redis.go",
    "chars": 3057,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"strconv\"\n\n\t\"github.com/why444216978/gin-api/library/jaeger\"\n\t\"github.com/why4442169"
  },
  {
    "path": "library/jaeger/redis/redis_test.go",
    "chars": 5556,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/agiledragon/gomonkey/v2\"\n\t\"github.com/go-redis/redis/v8\"\n\t\"g"
  },
  {
    "path": "library/job/job.go",
    "chars": 700,
    "preview": "package job\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/why444216978/go-util/assert\"\n\t\"gith"
  },
  {
    "path": "library/lock/lock.go",
    "chars": 440,
    "preview": "package lock\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n)\n\nvar (\n\t// ErrClientNil 客户端nil\n\tErrClientNil = errors.New(\"client "
  },
  {
    "path": "library/lock/mock/lock.go",
    "chars": 1930,
    "preview": "// Code generated by MockGen. DO NOT EDIT.\n// Source: library/lock/lock.go\n\n// Package redis is a generated GoMock packa"
  },
  {
    "path": "library/lock/redis/redis_lock.go",
    "chars": 1069,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/why444216978/gin-api/library/lock\"\n\n\t\"github.com/go-redis/redis"
  },
  {
    "path": "library/lock/redis/redis_lock_test.go",
    "chars": 1996,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\tredismock \"github.com/go-redis/redismock/v8\"\n\t\"github."
  },
  {
    "path": "library/logger/context.go",
    "chars": 1429,
    "preview": "package logger\n\nimport (\n\t\"context\"\n)\n\ntype contextKey uint64\n\nconst (\n\tcontextLogID contextKey = iota\n\tcontextHTTPLogFi"
  },
  {
    "path": "library/logger/fields.go",
    "chars": 2043,
    "preview": "package logger\n\nimport (\n\t\"net/http\"\n\t\"time\"\n)\n\nconst (\n\tLogHeader = \"Log-Id\"\n)\n\nconst (\n\tModuleHTTP  = \"HTTP\"\n\tModuleRP"
  },
  {
    "path": "library/logger/http.go",
    "chars": 719,
    "preview": "package logger\n\nimport (\n\t\"bytes\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\n\t\"github.com/why444216978/go-util/conversion\"\n\t\"github.com/w"
  },
  {
    "path": "library/logger/level.go",
    "chars": 646,
    "preview": "package logger\n\ntype Level int8\n\nconst (\n\tUnknownLevel Level = iota - 1\n\n\tDebugLevel\n\n\tInfoLevel\n\n\tWarnLevel\n\n\tErrorLeve"
  },
  {
    "path": "library/logger/logger.go",
    "chars": 381,
    "preview": "package logger\n\nimport (\n\t\"context\"\n)\n\ntype Logger interface {\n\tDebug(ctx context.Context, msg string, fields ...Field)\n"
  },
  {
    "path": "library/logger/logid.go",
    "chars": 3731,
    "preview": "package logger\n\nimport (\n\t\"crypto/md5\"\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sync/atomi"
  },
  {
    "path": "library/logger/rotate.go",
    "chars": 721,
    "preview": "package logger\n\nimport (\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\trotatelogs \"github.com/lestrrat-go/file-rotatelogs\"\n)\n\nfunc RotateWr"
  },
  {
    "path": "library/logger/rotate_test.go",
    "chars": 520,
    "preview": "package logger\n\nimport (\n\t\"testing\"\n\n\t\"github.com/smartystreets/goconvey/convey\"\n\t\"github.com/stretchr/testify/assert\"\n)"
  },
  {
    "path": "library/logger/zap/gorm/gorm.go",
    "chars": 4251,
    "preview": "package gorm\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"go.uber.org/zap\"\n\t\"go.uber.org/zap/zapcore\""
  },
  {
    "path": "library/logger/zap/redis/redis.go",
    "chars": 4681,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/go-redis/redis/v8\"\n\n\t\"github."
  },
  {
    "path": "library/logger/zap/rpc/rpc.go",
    "chars": 1473,
    "preview": "package rpc\n\nimport (\n\t\"context\"\n\n\t\"github.com/why444216978/gin-api/library/logger\"\n\tzapLogger \"github.com/why444216978/"
  },
  {
    "path": "library/logger/zap/service/service.go",
    "chars": 783,
    "preview": "package service\n\nimport (\n\t\"github.com/why444216978/gin-api/library/logger\"\n\t\"github.com/why444216978/gin-api/library/lo"
  },
  {
    "path": "library/logger/zap/zap.go",
    "chars": 4797,
    "preview": "package zap\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"go.uber.org/zap\"\n\t\"go.uber.org/zap/zapcore\"\n\n\t\"github.com/why444"
  },
  {
    "path": "library/orm/orm.go",
    "chars": 1828,
    "preview": "package orm\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n\t\"gorm.io/driver/mysql\"\n\t\"gorm.io/gorm\"\n\t\"gorm.io/gorm/logger\"\n\t\""
  },
  {
    "path": "library/queue/queue.go",
    "chars": 415,
    "preview": "package queue\n\nimport (\n\t\"context\"\n)\n\ntype ProduceOption struct{}\n\ntype ProduceOptionFunc func(o *ProduceOption)\n\ntype C"
  },
  {
    "path": "library/queue/rabbitmq/rabbitmq.go",
    "chars": 5459,
    "preview": "package rabbitmq\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/streadway/am"
  },
  {
    "path": "library/redis/conn.go",
    "chars": 483,
    "preview": "package redis\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/go-redis/redis/v8\"\n)\n\ntype Config struct {\n\tServiceName    string\n\tHost    "
  },
  {
    "path": "library/registry/etcd/discovery.go",
    "chars": 5003,
    "preview": "package etcd\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"log\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/why444216978/gin-api/l"
  },
  {
    "path": "library/registry/etcd/registrar.go",
    "chars": 2879,
    "preview": "package etcd\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/why444216978/gin-api/library/registry\""
  },
  {
    "path": "library/registry/registry.go",
    "chars": 670,
    "preview": "package registry\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\ntype Node struct {\n\tHost   string\n\tPort   int\n\tWeight int //TODO suppor"
  },
  {
    "path": "library/reliablequeue/reliablequeue.go",
    "chars": 5881,
    "preview": "package reliablequeue\n\nimport (\n\t\"context\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"golang.org/x/sync/errgroup\"\n\t\"gor"
  },
  {
    "path": "library/reliablequeue/reliablequeue_test.go",
    "chars": 8524,
    "preview": "package reliablequeue\n\nimport (\n\t\"context\"\n\t\"math\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\t\"g"
  },
  {
    "path": "library/reliablequeue/table.go",
    "chars": 4415,
    "preview": "package reliablequeue\n\nimport \"time\"\n\nconst (\n\tRecordStatusUnsuccess uint8 = 0\n\tRecordStatusSuccess   uint8 = 1\n)\n\n// Re"
  },
  {
    "path": "library/reliablequeue/table.sql",
    "chars": 3160,
    "preview": "CREATE TABLE `reliable_mq_message` (\n  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',\n  `create_user` "
  },
  {
    "path": "library/selector/dwrr/cwrr.go",
    "chars": 1951,
    "preview": "// dwrr is Dynamic Weighted Round Robin\npackage dwrr\n\n// import (\n// \t\"math\"\n// \t\"sync\"\n\n// \t\"github.com/why444216978/gi"
  },
  {
    "path": "library/selector/icmp/icmp.go",
    "chars": 49,
    "preview": "// icmp is load balance by ping rtt\npackage icmp\n"
  },
  {
    "path": "library/selector/p2c/p2c.go",
    "chars": 130,
    "preview": "// p2c is reference https://exceting.github.io/2020/08/13/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1-P2C%E7%AE%97%E6%B3%95/\npa"
  },
  {
    "path": "library/selector/selector.go",
    "chars": 1031,
    "preview": "package selector\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst (\n\tTypeWR   = \"wr\"\n\tTypeWrr  = \"wrr\"\n\tTypeDwrr = \"dwrr\""
  },
  {
    "path": "library/selector/wr/wr.go",
    "chars": 5058,
    "preview": "// wr is Weighted random\npackage wr\n\nimport (\n\t\"errors\"\n\t\"math/rand\"\n\t\"sort\"\n\t\"sync\"\n\n\t\"github.com/why444216978/gin-api/"
  },
  {
    "path": "library/selector/wr/wr_test.go",
    "chars": 4550,
    "preview": "// wr is Weighted random\npackage wr\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"testing\"\n\n\t\"github.com/smartystreets/gocon"
  },
  {
    "path": "library/selector/wrr/wrr.go",
    "chars": 118,
    "preview": "// wrr is Weighted Round Robin\n// reference Nginx https://blog.csdn.net/zhangskd/article/details/50194069\npackage wrr\n"
  },
  {
    "path": "library/servicer/service/service.go",
    "chars": 5613,
    "preview": "package service\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/why4"
  },
  {
    "path": "library/servicer/servicer.go",
    "chars": 803,
    "preview": "package servicer\n\nimport (\n\t\"context\"\n\t\"sync\"\n)\n\nconst (\n\tTypeRegistry uint8 = 1\n\tTypeIPPort   uint8 = 2\n\tTypeDomain   u"
  },
  {
    "path": "server/grpc/cmux/cmux.go",
    "chars": 3062,
    "preview": "package cmux\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/runtime\"\n\t\"github.com/"
  },
  {
    "path": "server/grpc/h2c/h2c.go",
    "chars": 2167,
    "preview": "package h2c\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/r"
  },
  {
    "path": "server/grpc/middleware/log/log.go",
    "chars": 1765,
    "preview": "package log\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/why444216978/go-util/snowflake\"\n\t\"google.golang.org/grpc\"\n"
  },
  {
    "path": "server/grpc/option.go",
    "chars": 4050,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\tgrpc_recovery \"github.com/grpc-ecosystem/go-grpc-mid"
  },
  {
    "path": "server/grpc/server.go",
    "chars": 701,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/runtime\"\n\t\"google.golang.org/grpc\"\n\t\"goog"
  },
  {
    "path": "server/http/middleware/cors/cors.go",
    "chars": 585,
    "preview": "package cors\n\nimport (\n\t\"github.com/gin-contrib/cors\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// CORS middleware\n// router.Use(co"
  },
  {
    "path": "server/http/middleware/csrf/csrf.go",
    "chars": 519,
    "preview": "package csrf\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/gorilla/csrf\"\n\twraphh \"github.com/turtlemon"
  },
  {
    "path": "server/http/middleware/limiter/limiter.go",
    "chars": 1113,
    "preview": "package limiter\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"golang.org/x/time/rate\"\n\n\t\"github.com/why44"
  },
  {
    "path": "server/http/middleware/log/log.go",
    "chars": 2905,
    "preview": "package log\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"net/http/httputil\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gi"
  },
  {
    "path": "server/http/middleware/panic/mail_template.go",
    "chars": 61655,
    "preview": "package panic\n\nvar MailTemplate = `<html>\n <head>\n  <meta charset=\"utf-8\" />\n </head>\n <body>\n  <div class=\"content-wrap"
  },
  {
    "path": "server/http/middleware/panic/panic.go",
    "chars": 2213,
    "preview": "package panic\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/why444216978/gin-api/library/logge"
  },
  {
    "path": "server/http/middleware/timeout/timeout.go",
    "chars": 1340,
    "preview": "package timeout\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nconst (\n\tTimeoutKey = "
  },
  {
    "path": "server/http/response/error.go",
    "chars": 1189,
    "preview": "package response\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n)\n\ntype ResponseError struct {\n\ttoast string\n\terr   error\n}\n"
  },
  {
    "path": "server/http/response/response.go",
    "chars": 795,
    "preview": "package response\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/why444216978/go-util/assert\"\n\n\t\"github."
  },
  {
    "path": "server/http/server.go",
    "chars": 2455,
    "preview": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/gin-contrib/pprof\"\n\t\"github.com/gin-gonic"
  },
  {
    "path": "server/http/util/util.go",
    "chars": 383,
    "preview": "package util\n\nimport (\n\t\"bytes\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n//定义新的struck,继承gin的ResponseWriter\n//添加body字段,用于将response"
  },
  {
    "path": "server/server.go",
    "chars": 413,
    "preview": "package server\n\nimport (\n\t\"context\"\n\t\"errors\"\n)\n\ntype Server interface {\n\tStart() error\n\tClose() error\n}\n\n// CloseFunc 资"
  }
]

About this extraction

This page contains the full source code of the why444216978/gin-api GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 167 files (466.5 KB), approximately 165.4k tokens, and a symbol index with 739 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!