feat: add rpc gateway and optimize code

This commit is contained in:
zhuyasen 2022-10-31 23:40:40 +08:00
parent 64858269a4
commit e7afe9c5be
51 changed files with 3964 additions and 490 deletions

9
.gitignore vendored
View File

@ -5,8 +5,6 @@
*.so
*.dylib
*.log
cmd/serverNameExample/serverNameExample
cmd/sponge/sponge
# Test binary, built with `go test -c`
*.test
@ -23,3 +21,10 @@ dist/
*.iml
*.ipr
*.iws
cmd/sponge/sponge
cmd/protoc-gen-go-gin/protoc-gen-go-gin
cmd/serverNameExample/serverNameExample
cmd/serverNameExample_grpcExample/serverNameExample_grpcExample
cmd/serverNameExample_gwExample/serverNameExample_gwExample
cmd/serverNameExample_httpExample/serverNameExample_httpExample

View File

@ -4,7 +4,7 @@ run:
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 10m
# default concurrency is available CPU number
#concurrency: 4
concurrency: 4
# include test files or not, default is true
tests: false
# which dirs to skip: issues from them won't be reported;
@ -46,7 +46,7 @@ linters:
- depguard
- dogsled
- errcheck
- gochecknoinits
#- gochecknoinits
- goconst
- gocyclo
- gosimple

View File

@ -1,4 +1,4 @@
SHELL := /bin/bash
#SHELL := /bin/bash
PROJECT_NAME := "github.com/zhufuyi/sponge"
PKG := "$(PROJECT_NAME)"
@ -13,6 +13,8 @@ install:
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0
go install github.com/envoyproxy/protoc-gen-validate@v0.6.7
go install github.com/srikrsna/protoc-gen-gotag@v0.6.2
go install github.com/mohuishou/protoc-gen-go-gin@v0.1.0
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.10.0
go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v1.5.1
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.49.0
go install github.com/swaggo/swag/cmd/swag@v1.8.6
@ -53,7 +55,7 @@ test:
.PHONY: cover
# generate test coverage
cover:
go test -race -short -coverprofile=cover.out -covermode=atomic ${PKG_LIST}
go test -short -coverprofile=cover.out -covermode=atomic ${PKG_LIST}
go tool cover -html=cover.out

View File

@ -11,6 +11,7 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/zhufuyi/sponge.svg)](https://pkg.go.dev/github.com/zhufuyi/sponge)
[![Go](https://github.com/zhufuyi/sponge/workflows/Go/badge.svg?branch=main)](https://github.com/zhufuyi/sponge/actions)
[![License: MIT](https://img.shields.io/github/license/zhufuyi/sponge)](https://img.shields.io/github/license/zhufuyi/sponge)
[![Join the chat at https://gitter.im/zhufuyi/sponge](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/zhufuyi/sponge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
</div>
@ -124,11 +125,11 @@ sponge http \
--db-table=student
```
**(2) If using the default configuration, skip this step. Modify the configuration file configs/<server name>.yml**
**(2) If using the default configuration, skip this step, modify the configuration file configs/<server name>.yml**
- If the field `cacheType` is `redis`, the `redis` address must be set.
- If the field `enableTracing` is true, the `jaeger` address must be set.
- If the field `enableRegistryDiscovery` is true, the configuration of the corresponding type of `registryDiscoveryType` must be set.
- If the field `registryDiscoveryType` is not be empty, the configuration of corresponding values must be set.
**(3) Generate swagger documentation**
@ -218,7 +219,7 @@ sponge grpc \
- If the field `cacheType` is `redis`, the `redis` address must be set.
- If the field `enableTracing` is true, the `jaeger` address must be set.
- If the field `enableRegistryDiscovery` is true, the configuration of the corresponding type of `registryDiscoveryType` must be set.
- If the field `registryDiscoveryType` is not be empty, the configuration of corresponding values must be set.
**(3) Generating grpc code**

File diff suppressed because it is too large Load Diff

View File

@ -7,16 +7,96 @@ package api.serverNameExample.v1;
import "validate/validate.proto";
import "api/types/types.proto";
import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "tagger/tagger.proto";
option go_package = "github.com/zhufuyi/sponge/api/serverNameExample/v1;v1";
// *.swagger.json文档的默认设置
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
host: "localhost:8080"
base_path: ""
info: {
title: "serverNameExample api docs";
version: "v0.0.0";
};
schemes: HTTP;
schemes: HTTPS;
consumes: "application/json";
produces: "application/json";
};
service userExampleService {
rpc Create(CreateUserExampleRequest) returns (CreateUserExampleReply) {}
rpc DeleteByID(DeleteUserExampleByIDRequest) returns (DeleteUserExampleByIDReply) {}
rpc UpdateByID(UpdateUserExampleByIDRequest) returns (UpdateUserExampleByIDReply) {}
rpc GetByID(GetUserExampleByIDRequest) returns (GetUserExampleByIDReply) {}
rpc ListByIDs(ListUserExampleByIDsRequest) returns (ListUserExampleByIDsReply) {}
rpc List(ListUserExampleRequest) returns (ListUserExampleReply) {}
rpc Create(CreateUserExampleRequest) returns (CreateUserExampleReply) {
option (google.api.http) = {
post: "/api/v1/userExample"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "创建userExample",
description: "提交信息创建userExample",
tags: "userExample",
};
}
rpc DeleteByID(DeleteUserExampleByIDRequest) returns (DeleteUserExampleByIDReply) {
option (google.api.http) = {
delete: "/api/v1/userExample/{id}"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "删除userExample",
description: "根据id删除userExample",
tags: "userExample",
};
}
rpc UpdateByID(UpdateUserExampleByIDRequest) returns (UpdateUserExampleByIDReply) {
option (google.api.http) = {
put: "/api/v1/userExample/{id}"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "更新userExample信息",
description: "根据id更新userExample信息",
tags: "userExample",
};
}
rpc GetByID(GetUserExampleByIDRequest) returns (GetUserExampleByIDReply) {
option (google.api.http) = {
get: "/api/v1/userExample/{id}"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "获取userExample详情",
description: "根据id获取userExample详情",
tags: "userExample",
};
}
rpc ListByIDs(ListUserExampleByIDsRequest) returns (ListUserExampleByIDsReply) {
option (google.api.http) = {
post: "/api/v1/userExamples/ids"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "根据多个id获取userExample列表",
description: "使用post请求根据多个id获取userExample列表",
tags: "userExample",
};
}
rpc List(ListUserExampleRequest) returns (ListUserExampleReply) {
option (google.api.http) = {
post: "/api/v1/userExamples"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "获取userExample列表",
description: "使用post请求获取userExample列表",
tags: "userExample",
};
}
}
enum GenderType {
@ -25,6 +105,9 @@ enum GenderType {
FEMALE = 2;
};
// 使grpc gatewaytarget
// string email = 2 [(tagger.tags) = "binding:\"email\"" ];
message CreateUserExampleRequest {
string name = 1 [(validate.rules).string.min_len = 2]; //
string email = 2 [(validate.rules).string.email = true]; //
@ -40,7 +123,7 @@ message CreateUserExampleReply {
}
message DeleteUserExampleByIDRequest {
uint64 id = 1 [(validate.rules).uint64.gte = 1];
uint64 id = 1 [(validate.rules).uint64.gte = 1, (tagger.tags) = "uri:\"id\"" ];
}
message DeleteUserExampleByIDReply {
@ -48,7 +131,7 @@ message DeleteUserExampleByIDReply {
}
message UpdateUserExampleByIDRequest {
uint64 id = 1 [(validate.rules).uint64.gte = 1];
uint64 id = 1 [(validate.rules).uint64.gte = 1 , (tagger.tags) = "uri:\"id\"" ];
string name = 2; //
string email = 3; //
string password = 4; //
@ -79,7 +162,7 @@ message UserExample {
}
message GetUserExampleByIDRequest {
uint64 id = 1 [(validate.rules).uint64.gte = 1];
uint64 id = 1 [(validate.rules).uint64.gte = 1, (tagger.tags) = "uri:\"id\"" ];
}
message GetUserExampleByIDReply {

View File

@ -0,0 +1,272 @@
// Code generated by protoc-gen-go-gin. DO NOT EDIT.
package v1
import (
context "context"
gin "github.com/gin-gonic/gin"
errcode "github.com/zhufuyi/sponge/pkg/errcode"
middleware "github.com/zhufuyi/sponge/pkg/gin/middleware"
zap "go.uber.org/zap"
metadata "google.golang.org/grpc/metadata"
)
// import packages: context. errcode. middleware. zap. gin. metadata.
type UserExampleServiceLogicer interface {
Create(ctx context.Context, req *CreateUserExampleRequest) (*CreateUserExampleReply, error)
DeleteByID(ctx context.Context, req *DeleteUserExampleByIDRequest) (*DeleteUserExampleByIDReply, error)
GetByID(ctx context.Context, req *GetUserExampleByIDRequest) (*GetUserExampleByIDReply, error)
List(ctx context.Context, req *ListUserExampleRequest) (*ListUserExampleReply, error)
ListByIDs(ctx context.Context, req *ListUserExampleByIDsRequest) (*ListUserExampleByIDsReply, error)
UpdateByID(ctx context.Context, req *UpdateUserExampleByIDRequest) (*UpdateUserExampleByIDReply, error)
}
type UserExampleServiceOption func(*userExampleServiceOptions)
type userExampleServiceOptions struct {
isFromRPC bool
responser errcode.Responser
zapLog *zap.Logger
}
func (o *userExampleServiceOptions) apply(opts ...UserExampleServiceOption) {
for _, opt := range opts {
opt(o)
}
}
func WithUserExampleServiceHTTPResponse() UserExampleServiceOption {
return func(o *userExampleServiceOptions) {
o.isFromRPC = false
}
}
func WithUserExampleServiceRPCResponse() UserExampleServiceOption {
return func(o *userExampleServiceOptions) {
o.isFromRPC = true
}
}
func WithUserExampleServiceResponser(responser errcode.Responser) UserExampleServiceOption {
return func(o *userExampleServiceOptions) {
o.responser = responser
}
}
func WithUserExampleServiceLogger(zapLog *zap.Logger) UserExampleServiceOption {
return func(o *userExampleServiceOptions) {
o.zapLog = zapLog
}
}
func RegisterUserExampleServiceRouter(iRouter gin.IRouter, iLogic UserExampleServiceLogicer, opts ...UserExampleServiceOption) {
o := &userExampleServiceOptions{}
o.apply(opts...)
if o.responser == nil {
o.responser = errcode.NewResponse(o.isFromRPC)
}
if o.zapLog == nil {
o.zapLog, _ = zap.NewProduction()
}
r := &userExampleServiceRouter{
iRouter: iRouter,
iLogic: iLogic,
iResponse: o.responser,
zapLog: o.zapLog,
}
r.register()
}
type userExampleServiceRouter struct {
iRouter gin.IRouter
iLogic UserExampleServiceLogicer
iResponse errcode.Responser
zapLog *zap.Logger
}
func (r *userExampleServiceRouter) register() {
r.iRouter.Handle("POST", "/api/v1/userExample", r.Create_0)
r.iRouter.Handle("DELETE", "/api/v1/userExample/:id", r.DeleteByID_0)
r.iRouter.Handle("PUT", "/api/v1/userExample/:id", r.UpdateByID_0)
r.iRouter.Handle("GET", "/api/v1/userExample/:id", r.GetByID_0)
r.iRouter.Handle("POST", "/api/v1/userExamples/ids", r.ListByIDs_0)
r.iRouter.Handle("POST", "/api/v1/userExamples", r.List_0)
}
func (r *userExampleServiceRouter) Create_0(c *gin.Context) {
req := &CreateUserExampleRequest{}
if err := c.ShouldBindJSON(req); err != nil {
r.zapLog.Warn("ShouldBindJSON error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
md := metadata.New(nil)
for k, v := range c.Request.Header {
md.Set(k, v...)
}
newCtx := metadata.NewIncomingContext(c, md)
out, err := r.iLogic.Create(newCtx, req)
if err != nil {
isIgnore := r.iResponse.Error(c, err)
if !isIgnore {
r.zapLog.Error("Create error", zap.Error(err), middleware.GCtxRequestIDField(c))
}
return
}
r.iResponse.Success(c, out)
}
func (r *userExampleServiceRouter) DeleteByID_0(c *gin.Context) {
req := &DeleteUserExampleByIDRequest{}
if err := c.ShouldBindUri(req); err != nil {
r.zapLog.Warn("ShouldBindUri error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
if err := c.ShouldBindQuery(req); err != nil {
r.zapLog.Warn("ShouldBindQuery error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
md := metadata.New(nil)
for k, v := range c.Request.Header {
md.Set(k, v...)
}
newCtx := metadata.NewIncomingContext(c, md)
out, err := r.iLogic.DeleteByID(newCtx, req)
if err != nil {
isIgnore := r.iResponse.Error(c, err)
if !isIgnore {
r.zapLog.Error("DeleteByID error", zap.Error(err), middleware.GCtxRequestIDField(c))
}
return
}
r.iResponse.Success(c, out)
}
func (r *userExampleServiceRouter) UpdateByID_0(c *gin.Context) {
req := &UpdateUserExampleByIDRequest{}
if err := c.ShouldBindUri(req); err != nil {
r.zapLog.Warn("ShouldBindUri error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
if err := c.ShouldBindJSON(req); err != nil {
r.zapLog.Warn("ShouldBindJSON error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
md := metadata.New(nil)
for k, v := range c.Request.Header {
md.Set(k, v...)
}
newCtx := metadata.NewIncomingContext(c, md)
out, err := r.iLogic.UpdateByID(newCtx, req)
if err != nil {
isIgnore := r.iResponse.Error(c, err)
if !isIgnore {
r.zapLog.Error("UpdateByID error", zap.Error(err), middleware.GCtxRequestIDField(c))
}
return
}
r.iResponse.Success(c, out)
}
func (r *userExampleServiceRouter) GetByID_0(c *gin.Context) {
req := &GetUserExampleByIDRequest{}
if err := c.ShouldBindUri(req); err != nil {
r.zapLog.Warn("ShouldBindUri error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
if err := c.ShouldBindQuery(req); err != nil {
r.zapLog.Warn("ShouldBindQuery error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
md := metadata.New(nil)
for k, v := range c.Request.Header {
md.Set(k, v...)
}
newCtx := metadata.NewIncomingContext(c, md)
out, err := r.iLogic.GetByID(newCtx, req)
if err != nil {
isIgnore := r.iResponse.Error(c, err)
if !isIgnore {
r.zapLog.Error("GetByID error", zap.Error(err), middleware.GCtxRequestIDField(c))
}
return
}
r.iResponse.Success(c, out)
}
func (r *userExampleServiceRouter) ListByIDs_0(c *gin.Context) {
req := &ListUserExampleByIDsRequest{}
if err := c.ShouldBindJSON(req); err != nil {
r.zapLog.Warn("ShouldBindJSON error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
md := metadata.New(nil)
for k, v := range c.Request.Header {
md.Set(k, v...)
}
newCtx := metadata.NewIncomingContext(c, md)
out, err := r.iLogic.ListByIDs(newCtx, req)
if err != nil {
isIgnore := r.iResponse.Error(c, err)
if !isIgnore {
r.zapLog.Error("ListByIDs error", zap.Error(err), middleware.GCtxRequestIDField(c))
}
return
}
r.iResponse.Success(c, out)
}
func (r *userExampleServiceRouter) List_0(c *gin.Context) {
req := &ListUserExampleRequest{}
if err := c.ShouldBindJSON(req); err != nil {
r.zapLog.Warn("ShouldBindJSON error", zap.Error(err), middleware.GCtxRequestIDField(c))
r.iResponse.ParamError(c, err)
return
}
md := metadata.New(nil)
for k, v := range c.Request.Header {
md.Set(k, v...)
}
newCtx := metadata.NewIncomingContext(c, md)
out, err := r.iLogic.List(newCtx, req)
if err != nil {
isIgnore := r.iResponse.Error(c, err)
if !isIgnore {
r.zapLog.Error("List error", zap.Error(err), middleware.GCtxRequestIDField(c))
}
return
}
r.iResponse.Success(c, out)
}

View File

@ -0,0 +1,96 @@
package initial
import (
"flag"
"fmt"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"strconv"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/tracer"
"github.com/jinzhu/copier"
)
var (
version string
configFile string
enableConfigCenter bool
)
// Config 初始化配置
func Config() {
initConfig()
cfg := config.Get()
// 初始化日志
_, _ = logger.Init(
logger.WithLevel(cfg.Logger.Level),
logger.WithFormat(cfg.Logger.Format),
logger.WithSave(cfg.Logger.IsSave),
)
// 初始化数据库
model.InitMysql()
model.InitCache(cfg.App.CacheType)
// 初始化链路跟踪
if cfg.App.EnableTracing {
tracer.InitWithConfig(
cfg.App.Name,
cfg.App.Env,
cfg.App.Version,
cfg.Jaeger.AgentHost,
strconv.Itoa(cfg.Jaeger.AgentPort),
cfg.App.TracingSamplingRate,
)
}
}
// 初始化配置
func initConfig() {
flag.StringVar(&version, "version", "", "service Version Number")
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
"if true, the '-c' parameter indicates the configuration center")
flag.StringVar(&configFile, "c", "", "configuration file")
flag.Parse()
if enableConfigCenter {
// 从配置中心获取配置(先获取nacos配置再根据nacos配置中心读取服务配置)
if configFile == "" {
configFile = configs.Path("serverNameExample_cc.yml")
}
nacosConfig, err := config.NewCenter(configFile)
if err != nil {
panic(err)
}
appConfig := &config.Config{}
params := &nacoscli.Params{}
_ = copier.Copy(params, &nacosConfig.Nacos)
err = nacoscli.Init(appConfig, params)
if err != nil {
panic(fmt.Sprintf("connect to configuration center err, %v", err))
}
if appConfig.App.Name == "" {
panic("read the config from center error, config data is empty")
}
config.Set(appConfig)
} else {
// 从本地配置文件获取配置
if configFile == "" {
configFile = configs.Path("serverNameExample.yml")
}
err := config.Init(configFile)
if err != nil {
panic("init config error: " + err.Error())
}
}
if version != "" {
config.Get().App.Version = version
}
//fmt.Println(config.Show())
}

View File

@ -0,0 +1,44 @@
package initial
import (
"context"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/tracer"
)
// RegisterClose 注册app需要释放的资源
func RegisterClose(servers []app.IServer) []app.Close {
var closes []app.Close
// 关闭服务
for _, s := range servers {
closes = append(closes, s.Stop)
}
// 关闭mysql
closes = append(closes, func() error {
return model.CloseMysql()
})
// 关闭redis
if config.Get().App.CacheType == "redis" {
closes = append(closes, func() error {
return model.CloseRedis()
})
}
// 关闭trace
if config.Get().App.EnableTracing {
closes = append(closes, func() error {
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
return tracer.Close(ctx)
})
}
return closes
}

View File

@ -0,0 +1,93 @@
package initial
import (
"fmt"
"strconv"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/server"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
)
// RegisterServers 注册app服务
func RegisterServers() []app.IServer {
var cfg = config.Get()
var servers []app.IServer
// 创建http服务
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
httpServer := server.NewHTTPServer(httpAddr,
server.WithHTTPReadTimeout(time.Second*time.Duration(cfg.HTTP.ReadTimeout)),
server.WithHTTPWriteTimeout(time.Second*time.Duration(cfg.HTTP.WriteTimeout)),
server.WithHTTPRegistry(httpRegistry, httpInstance),
server.WithHTTPIsProd(cfg.App.Env == "prod"),
)
servers = append(servers, httpServer)
// 创建grpc服务
grpcAddr := ":" + strconv.Itoa(cfg.Grpc.Port)
grpcRegistry, grpcInstance := registryService("grpc", cfg.App.Host, cfg.Grpc.Port)
grpcServer := server.NewGRPCServer(grpcAddr,
server.WithGrpcReadTimeout(time.Duration(cfg.Grpc.ReadTimeout)*time.Second),
server.WithGrpcWriteTimeout(time.Duration(cfg.Grpc.WriteTimeout)*time.Second),
server.WithGrpcRegistry(grpcRegistry, grpcInstance),
)
servers = append(servers, grpcServer)
return servers
}
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
instanceEndpoint := fmt.Sprintf("%s://%s:%d", scheme, host, port)
cfg := config.Get()
switch cfg.App.RegistryDiscoveryType {
// 使用consul注册服务
case "consul":
iRegistry, instance, err := consul.NewRegistry(
cfg.Consul.Addr,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用etcd注册服务
case "etcd":
iRegistry, instance, err := etcd.NewRegistry(
cfg.Etcd.Addrs,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用nacos注册服务
case "nacos":
iRegistry, instance, err := nacos.NewRegistry(
cfg.NacosRd.IPAddr,
cfg.NacosRd.Port,
cfg.NacosRd.NamespaceID,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
}
return nil, nil
}

View File

@ -0,0 +1,25 @@
package main
import (
"github.com/zhufuyi/sponge/cmd/serverNameExample/initial"
"runtime"
"github.com/zhufuyi/sponge/pkg/app"
)
// @title serverNameExample api docs
// @description http server api docs
// @schemes http https
// @version v0.0.0
// @host localhost:8080
func main() {
n := runtime.NumCPU()
runtime.GOMAXPROCS(n / 2) //设置cpu运行的数目
initial.Config()
servers := initial.RegisterServers()
closes := initial.RegisterClose(servers)
a := app.New(servers, closes)
a.Run()
}

View File

@ -0,0 +1,97 @@
package initial
import (
"flag"
"fmt"
"strconv"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/tracer"
"github.com/jinzhu/copier"
)
var (
version string
configFile string
enableConfigCenter bool
)
// Config 初始化配置
func Config() {
initConfig()
cfg := config.Get()
// 初始化日志
_, _ = logger.Init(
logger.WithLevel(cfg.Logger.Level),
logger.WithFormat(cfg.Logger.Format),
logger.WithSave(cfg.Logger.IsSave),
)
// 初始化数据库
model.InitMysql()
model.InitCache(cfg.App.CacheType)
// 初始化链路跟踪
if cfg.App.EnableTracing {
tracer.InitWithConfig(
cfg.App.Name,
cfg.App.Env,
cfg.App.Version,
cfg.Jaeger.AgentHost,
strconv.Itoa(cfg.Jaeger.AgentPort),
cfg.App.TracingSamplingRate,
)
}
}
// 初始化配置
func initConfig() {
flag.StringVar(&version, "version", "", "service Version Number")
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
"if true, the '-c' parameter indicates the configuration center")
flag.StringVar(&configFile, "c", "", "configuration file")
flag.Parse()
if enableConfigCenter {
// 从配置中心获取配置(先获取nacos配置再根据nacos配置中心读取服务配置)
if configFile == "" {
configFile = configs.Path("serverNameExample_cc.yml")
}
nacosConfig, err := config.NewCenter(configFile)
if err != nil {
panic(err)
}
appConfig := &config.Config{}
params := &nacoscli.Params{}
_ = copier.Copy(params, &nacosConfig.Nacos)
err = nacoscli.Init(appConfig, params)
if err != nil {
panic(fmt.Sprintf("connect to configuration center err, %v", err))
}
if appConfig.App.Name == "" {
panic("read the config from center error, config data is empty")
}
config.Set(appConfig)
} else {
// 从本地配置文件获取配置
if configFile == "" {
configFile = configs.Path("serverNameExample.yml")
}
err := config.Init(configFile)
if err != nil {
panic("init config error: " + err.Error())
}
}
if version != "" {
config.Get().App.Version = version
}
//fmt.Println(config.Show())
}

View File

@ -0,0 +1,44 @@
package initial
import (
"context"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/tracer"
)
// RegisterClose 注册app需要释放的资源
func RegisterClose(servers []app.IServer) []app.Close {
var closes []app.Close
// 关闭服务
for _, s := range servers {
closes = append(closes, s.Stop)
}
// 关闭mysql
closes = append(closes, func() error {
return model.CloseMysql()
})
// 关闭redis
if config.Get().App.CacheType == "redis" {
closes = append(closes, func() error {
return model.CloseRedis()
})
}
// 关闭trace
if config.Get().App.EnableTracing {
closes = append(closes, func() error {
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
return tracer.Close(ctx)
})
}
return closes
}

View File

@ -0,0 +1,82 @@
package initial
import (
"fmt"
"strconv"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/server"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
)
// RegisterServers 注册app服务
func RegisterServers() []app.IServer {
var cfg = config.Get()
var servers []app.IServer
// 创建grpc服务
grpcAddr := ":" + strconv.Itoa(cfg.Grpc.Port)
grpcRegistry, grpcInstance := registryService("grpc", cfg.App.Host, cfg.Grpc.Port)
grpcServer := server.NewGRPCServer(grpcAddr,
server.WithGrpcReadTimeout(time.Duration(cfg.Grpc.ReadTimeout)*time.Second),
server.WithGrpcWriteTimeout(time.Duration(cfg.Grpc.WriteTimeout)*time.Second),
server.WithGrpcRegistry(grpcRegistry, grpcInstance),
)
servers = append(servers, grpcServer)
return servers
}
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
instanceEndpoint := fmt.Sprintf("%s://%s:%d", scheme, host, port)
cfg := config.Get()
switch cfg.App.RegistryDiscoveryType {
// 使用consul注册服务
case "consul":
iRegistry, instance, err := consul.NewRegistry(
cfg.Consul.Addr,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用etcd注册服务
case "etcd":
iRegistry, instance, err := etcd.NewRegistry(
cfg.Etcd.Addrs,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用nacos注册服务
case "nacos":
iRegistry, instance, err := nacos.NewRegistry(
cfg.NacosRd.IPAddr,
cfg.NacosRd.Port,
cfg.NacosRd.NamespaceID,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
}
return nil, nil
}

View File

@ -1,239 +1,16 @@
package main
import (
"context"
"flag"
"fmt"
"strconv"
"time"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/internal/server"
"github.com/zhufuyi/sponge/cmd/serverNameExample_grpcExample/initial"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
"github.com/zhufuyi/sponge/pkg/tracer"
"github.com/jinzhu/copier"
)
var (
version string
configFile string
enableConfigCenter bool
)
// @title serverNameExample api docs
// @description http server api docs
// @schemes http https
// @version v0.0.0
// @host localhost:8080
func main() {
inits := registerInits()
servers := registerServers()
closes := registerCloses(servers)
initial.Config()
servers := initial.RegisterServers()
closes := initial.RegisterClose(servers)
s := app.New(inits, servers, closes)
s.Run()
}
// -------------------------------- 注册app初始化 ---------------------------------
func registerInits() []app.Init {
// 初始化配置
initConfig()
cfg := config.Get()
// 初始化日志
_, _ = logger.Init(
logger.WithLevel(cfg.Logger.Level),
logger.WithFormat(cfg.Logger.Format),
logger.WithSave(cfg.Logger.IsSave),
)
var inits []app.Init
// 初始化数据库
inits = append(inits, func() {
model.InitMysql()
model.InitCache(cfg.App.CacheType)
})
// 初始化链路跟踪
if cfg.App.EnableTracing {
inits = append(inits, func() {
tracer.InitWithConfig(
cfg.App.Name,
cfg.App.Env,
cfg.App.Version,
cfg.Jaeger.AgentHost,
strconv.Itoa(cfg.Jaeger.AgentPort),
cfg.App.TracingSamplingRate,
)
})
}
return inits
}
// 初始化配置
func initConfig() {
flag.StringVar(&version, "version", "", "service Version Number")
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
"if true, the '-c' parameter indicates the configuration center")
flag.StringVar(&configFile, "c", "", "configuration file")
flag.Parse()
if enableConfigCenter {
// 从配置中心获取配置(先获取nacos配置再根据nacos配置中心读取服务配置)
if configFile == "" {
configFile = configs.Path("serverNameExample_cc.yml")
}
nacosConfig, err := config.NewCenter(configFile)
if err != nil {
panic(err)
}
appConfig := &config.Config{}
params := &nacoscli.Params{}
_ = copier.Copy(params, &nacosConfig.Nacos)
err = nacoscli.Init(appConfig, params)
if err != nil {
panic(fmt.Sprintf("connect to configuration center err, %v", err))
}
if appConfig.App.Name == "" {
panic("read the config from center error, config data is empty")
}
config.Set(appConfig)
} else {
// 从本地配置文件获取配置
if configFile == "" {
configFile = configs.Path("serverNameExample.yml")
}
err := config.Init(configFile)
if err != nil {
panic("init config error: " + err.Error())
}
}
if version != "" {
config.Get().App.Version = version
}
//fmt.Println(config.Show())
}
// -------------------------------- 注册app服务 ---------------------------------
func registerServers() []app.IServer {
var cfg = config.Get()
var servers []app.IServer
// todo generate the code to register http and grpc services here
// delete the templates code start
// 创建http服务
//httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
//httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
//httpServer := server.NewHTTPServer(httpAddr,
// server.WithHTTPReadTimeout(time.Second*time.Duration(cfg.HTTP.ReadTimeout)),
// server.WithHTTPWriteTimeout(time.Second*time.Duration(cfg.HTTP.WriteTimeout)),
// server.WithHTTPRegistry(httpRegistry, httpInstance),
// server.WithHTTPIsProd(cfg.App.Env == "prod"),
//)
//servers = append(servers, httpServer)
// 创建grpc服务
grpcAddr := ":" + strconv.Itoa(cfg.Grpc.Port)
grpcRegistry, grpcInstance := registryService("grpc", cfg.App.Host, cfg.Grpc.Port)
grpcServer := server.NewGRPCServer(grpcAddr,
server.WithGrpcReadTimeout(time.Duration(cfg.Grpc.ReadTimeout)*time.Second),
server.WithGrpcWriteTimeout(time.Duration(cfg.Grpc.WriteTimeout)*time.Second),
server.WithGrpcRegistry(grpcRegistry, grpcInstance),
)
servers = append(servers, grpcServer)
// delete the templates code end
return servers
}
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
instanceEndpoint := fmt.Sprintf("%s://%s:%d", scheme, host, port)
cfg := config.Get()
switch cfg.App.RegistryDiscoveryType {
// 使用consul注册服务
case "consul":
iRegistry, instance, err := consul.NewRegistry(
cfg.Consul.Addr,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用etcd注册服务
case "etcd":
iRegistry, instance, err := etcd.NewRegistry(
cfg.Etcd.Addrs,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用nacos注册服务
case "nacos":
iRegistry, instance, err := nacos.NewRegistry(
cfg.NacosRd.IPAddr,
cfg.NacosRd.Port,
cfg.NacosRd.NamespaceID,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
}
return nil, nil
}
// -------------------------- 注册app需要释放的资源 -------------------------------------------
func registerCloses(servers []app.IServer) []app.Close {
var closes []app.Close
// 关闭服务
for _, s := range servers {
closes = append(closes, s.Stop)
}
// 关闭mysql
closes = append(closes, func() error {
return model.CloseMysql()
})
// 关闭redis
closes = append(closes, func() error {
return model.CloseRedis()
})
// 关闭trace
if config.Get().App.EnableTracing {
closes = append(closes, func() error {
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
return tracer.Close(ctx)
})
}
return closes
a := app.New(servers, closes)
a.Run()
}

View File

@ -0,0 +1,96 @@
package initial
import (
"flag"
"fmt"
"strconv"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/rpcclient"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/tracer"
"github.com/jinzhu/copier"
)
var (
version string
configFile string
enableConfigCenter bool
)
// Config 初始化配置
func Config() {
initConfig()
cfg := config.Get()
// 初始化日志
_, _ = logger.Init(
logger.WithLevel(cfg.Logger.Level),
logger.WithFormat(cfg.Logger.Format),
logger.WithSave(cfg.Logger.IsSave),
)
// 初始化链路跟踪
if cfg.App.EnableTracing {
tracer.InitWithConfig(
cfg.App.Name,
cfg.App.Env,
cfg.App.Version,
cfg.Jaeger.AgentHost,
strconv.Itoa(cfg.Jaeger.AgentPort),
cfg.App.TracingSamplingRate,
)
}
// 初始化rpc服务连接
rpcclient.NewServerNameExampleRPCConn()
}
// 初始化配置
func initConfig() {
flag.StringVar(&version, "version", "", "service Version Number")
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
"if true, the '-c' parameter indicates the configuration center")
flag.StringVar(&configFile, "c", "", "configuration file")
flag.Parse()
if enableConfigCenter {
// 从配置中心获取配置(先获取nacos配置再根据nacos配置中心读取服务配置)
if configFile == "" {
configFile = configs.Path("serverNameExample_cc.yml")
}
nacosConfig, err := config.NewCenter(configFile)
if err != nil {
panic(err)
}
appConfig := &config.Config{}
params := &nacoscli.Params{}
_ = copier.Copy(params, &nacosConfig.Nacos)
err = nacoscli.Init(appConfig, params)
if err != nil {
panic(fmt.Sprintf("connect to configuration center err, %v", err))
}
if appConfig.App.Name == "" {
panic("read the config from center error, config data is empty")
}
config.Set(appConfig)
} else {
// 从本地配置文件获取配置
if configFile == "" {
configFile = configs.Path("serverNameExample.yml")
}
err := config.Init(configFile)
if err != nil {
panic("init config error: " + err.Error())
}
}
if version != "" {
config.Get().App.Version = version
}
//fmt.Println(config.Show())
}

View File

@ -0,0 +1,37 @@
package initial
import (
"context"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/rpcclient"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/tracer"
)
// RegisterClose 注册app需要释放的资源
func RegisterClose(servers []app.IServer) []app.Close {
var closes []app.Close
// 关闭服务
for _, s := range servers {
closes = append(closes, s.Stop)
}
// 关闭rpc client连接
closes = append(closes, func() error {
return rpcclient.CloseServerNameExampleRPCConn()
})
// 关闭trace
if config.Get().App.EnableTracing {
closes = append(closes, func() error {
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
return tracer.Close(ctx)
})
}
return closes
}

View File

@ -0,0 +1,83 @@
package initial
import (
"fmt"
"strconv"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/server"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
)
// RegisterServers 注册app服务
func RegisterServers() []app.IServer {
var cfg = config.Get()
var servers []app.IServer
// 创建http服务
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
httpServer := server.NewHTTPServer(httpAddr,
server.WithHTTPReadTimeout(time.Second*time.Duration(cfg.HTTP.ReadTimeout)),
server.WithHTTPWriteTimeout(time.Second*time.Duration(cfg.HTTP.WriteTimeout)),
server.WithHTTPRegistry(httpRegistry, httpInstance),
server.WithHTTPIsProd(cfg.App.Env == "prod"),
)
servers = append(servers, httpServer)
return servers
}
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
instanceEndpoint := fmt.Sprintf("%s://%s:%d", scheme, host, port)
cfg := config.Get()
switch cfg.App.RegistryDiscoveryType {
// 使用consul注册服务
case "consul":
iRegistry, instance, err := consul.NewRegistry(
cfg.Consul.Addr,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用etcd注册服务
case "etcd":
iRegistry, instance, err := etcd.NewRegistry(
cfg.Etcd.Addrs,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用nacos注册服务
case "nacos":
iRegistry, instance, err := nacos.NewRegistry(
cfg.NacosRd.IPAddr,
cfg.NacosRd.Port,
cfg.NacosRd.NamespaceID,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
}
return nil, nil
}

View File

@ -0,0 +1,16 @@
package main
import (
"github.com/zhufuyi/sponge/cmd/serverNameExample_gwExample/initial"
"github.com/zhufuyi/sponge/pkg/app"
)
func main() {
initial.Config()
servers := initial.RegisterServers()
closes := initial.RegisterClose(servers)
a := app.New(servers, closes)
a.Run()
}

View File

@ -0,0 +1,97 @@
package initial
import (
"flag"
"fmt"
"strconv"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/tracer"
"github.com/jinzhu/copier"
)
var (
version string
configFile string
enableConfigCenter bool
)
// Config 初始化配置
func Config() {
initConfig()
cfg := config.Get()
// 初始化日志
_, _ = logger.Init(
logger.WithLevel(cfg.Logger.Level),
logger.WithFormat(cfg.Logger.Format),
logger.WithSave(cfg.Logger.IsSave),
)
// 初始化数据库
model.InitMysql()
model.InitCache(cfg.App.CacheType)
// 初始化链路跟踪
if cfg.App.EnableTracing {
tracer.InitWithConfig(
cfg.App.Name,
cfg.App.Env,
cfg.App.Version,
cfg.Jaeger.AgentHost,
strconv.Itoa(cfg.Jaeger.AgentPort),
cfg.App.TracingSamplingRate,
)
}
}
// 初始化配置
func initConfig() {
flag.StringVar(&version, "version", "", "service Version Number")
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
"if true, the '-c' parameter indicates the configuration center")
flag.StringVar(&configFile, "c", "", "configuration file")
flag.Parse()
if enableConfigCenter {
// 从配置中心获取配置(先获取nacos配置再根据nacos配置中心读取服务配置)
if configFile == "" {
configFile = configs.Path("serverNameExample_cc.yml")
}
nacosConfig, err := config.NewCenter(configFile)
if err != nil {
panic(err)
}
appConfig := &config.Config{}
params := &nacoscli.Params{}
_ = copier.Copy(params, &nacosConfig.Nacos)
err = nacoscli.Init(appConfig, params)
if err != nil {
panic(fmt.Sprintf("connect to configuration center err, %v", err))
}
if appConfig.App.Name == "" {
panic("read the config from center error, config data is empty")
}
config.Set(appConfig)
} else {
// 从本地配置文件获取配置
if configFile == "" {
configFile = configs.Path("serverNameExample.yml")
}
err := config.Init(configFile)
if err != nil {
panic("init config error: " + err.Error())
}
}
if version != "" {
config.Get().App.Version = version
}
//fmt.Println(config.Show())
}

View File

@ -0,0 +1,44 @@
package initial
import (
"context"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/tracer"
)
// RegisterClose 注册app需要释放的资源
func RegisterClose(servers []app.IServer) []app.Close {
var closes []app.Close
// 关闭服务
for _, s := range servers {
closes = append(closes, s.Stop)
}
// 关闭mysql
closes = append(closes, func() error {
return model.CloseMysql()
})
// 关闭redis
if config.Get().App.CacheType == "redis" {
closes = append(closes, func() error {
return model.CloseRedis()
})
}
// 关闭trace
if config.Get().App.EnableTracing {
closes = append(closes, func() error {
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
return tracer.Close(ctx)
})
}
return closes
}

View File

@ -0,0 +1,83 @@
package initial
import (
"fmt"
"strconv"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/server"
"github.com/zhufuyi/sponge/pkg/app"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
)
// RegisterServers 注册app服务
func RegisterServers() []app.IServer {
var cfg = config.Get()
var servers []app.IServer
// 创建http服务
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
httpServer := server.NewHTTPServer(httpAddr,
server.WithHTTPReadTimeout(time.Second*time.Duration(cfg.HTTP.ReadTimeout)),
server.WithHTTPWriteTimeout(time.Second*time.Duration(cfg.HTTP.WriteTimeout)),
server.WithHTTPRegistry(httpRegistry, httpInstance),
server.WithHTTPIsProd(cfg.App.Env == "prod"),
)
servers = append(servers, httpServer)
return servers
}
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
instanceEndpoint := fmt.Sprintf("%s://%s:%d", scheme, host, port)
cfg := config.Get()
switch cfg.App.RegistryDiscoveryType {
// 使用consul注册服务
case "consul":
iRegistry, instance, err := consul.NewRegistry(
cfg.Consul.Addr,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用etcd注册服务
case "etcd":
iRegistry, instance, err := etcd.NewRegistry(
cfg.Etcd.Addrs,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
// 使用nacos注册服务
case "nacos":
iRegistry, instance, err := nacos.NewRegistry(
cfg.NacosRd.IPAddr,
cfg.NacosRd.Port,
cfg.NacosRd.NamespaceID,
cfg.App.Name+"_"+scheme+"_"+host,
cfg.App.Name,
[]string{instanceEndpoint},
)
if err != nil {
panic(err)
}
return iRegistry, instance
}
return nil, nil
}

View File

@ -0,0 +1,21 @@
package main
import (
"github.com/zhufuyi/sponge/cmd/serverNameExample_httpExample/initial"
"github.com/zhufuyi/sponge/pkg/app"
)
// @title serverNameExample api docs
// @description http server api docs
// @schemes http https
// @version v0.0.0
// @host localhost:8080
func main() {
initial.Config()
servers := initial.RegisterServers()
closes := initial.RegisterClose(servers)
a := app.New(servers, closes)
a.Run()
}

View File

@ -95,17 +95,17 @@ func getYAMLFile(serverDir string) (map[string]configType, error) {
if err != nil {
return nil, err
}
if len(ymlFiles) > 2 {
return nil, fmt.Errorf("config files are allowed up to 2, currently there are %d", len(ymlFiles))
}
//if len(ymlFiles) > 2 {
// return nil, fmt.Errorf("config files are allowed up to 2, currently there are %d", len(ymlFiles))
//}
yamlFiles, err := gofile.ListFiles(configsDir, gofile.WithSuffix(".yaml"))
if err != nil {
return nil, err
}
if len(yamlFiles) > 2 {
return nil, fmt.Errorf("config files are allowed up to 2, currently there are %d", len(yamlFiles))
}
//if len(yamlFiles) > 2 {
// return nil, fmt.Errorf("config files are allowed up to 2, currently there are %d", len(yamlFiles))
//}
if len(ymlFiles) == 0 && len(yamlFiles) == 0 {
return nil, fmt.Errorf("not found config files in directory %s", configsDir)

View File

@ -12,8 +12,7 @@ app:
enableCircuitBreaker: false # 是否开启熔断(自适应)true:开启false:关闭
enableTracing: false # 是否开启链路跟踪true:开启false:关闭如果为true必须设置jaeger配置
tracingSamplingRate: 1.0 # 链路采样率0~1之间0表示禁止采样1表示采样所有链路
enableRegistryDiscovery: false # 是否开启注册与发现true:开启false:关闭如果为true必须设置registryDiscoveryType对应类型的配置例如consul配置
registryDiscoveryType: "consul" # 注册与发现类型consul、etcd、nacos
registryDiscoveryType: "" # 注册与发现类型consul、etcd、nacos如果为空不使用注册与发现
cacheType: "memory" # 缓存类型memory、redis如果设置为redis必须设置redis配置
@ -24,7 +23,7 @@ http:
writeTimeout: 60 # 写超时,单位(秒)如果enablePprof为true需要大于60spprof做profiling的默认值是60s
# grpc 设置
# grpc server 设置
grpc:
port: 8282 # rpc监听端口
metricsPort: 8283 # 获取指标http端口
@ -33,6 +32,14 @@ grpc:
writeTimeout: 3 # 写超时,单位(秒)
# grpc client 设置可以设置多个rpc服务
grpcClient:
- name: "serverNameExample" # rpc服务名称用来服务发现使用
host: "192.168.3.27" # rpc服务地址直连时使用
port: 8282 # rpc服务端口
registryDiscoveryType: "" # 注册与发现类型consul、etcd、nacos如果为空不使用注册与发现
# logger 设置
logger:
level: "info" # 输出日志级别 debug, info, warn, error默认是debug

21
docs/apis.go Normal file
View File

@ -0,0 +1,21 @@
package docs
import (
"embed"
"fmt"
)
//go:embed apis.swagger.json
var jsonFile embed.FS
// ApiDocs swagger json file content
var ApiDocs = []byte(``)
func init() {
data, err := jsonFile.ReadFile("apis.swagger.json")
if err != nil {
fmt.Printf("\nReadFile error: %v\n\n", err)
return
}
ApiDocs = data
}

479
docs/apis.swagger.json Normal file
View File

@ -0,0 +1,479 @@
{
"swagger": "2.0",
"info": {
"title": "serverNameExample api docs",
"version": "v0.0.0"
},
"tags": [
{
"name": "userExampleService"
}
],
"host": "localhost:8080",
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/api/v1/userExample": {
"post": {
"summary": "创建userExample",
"description": "提交信息创建userExample",
"operationId": "userExampleService_Create",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1CreateUserExampleReply"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1CreateUserExampleRequest"
}
}
],
"tags": [
"userExample"
]
}
},
"/api/v1/userExample/{id}": {
"get": {
"summary": "获取userExample详情",
"description": "根据id获取userExample详情",
"operationId": "userExampleService_GetByID",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetUserExampleByIDReply"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"userExample"
]
},
"delete": {
"summary": "删除userExample",
"description": "根据id删除userExample",
"operationId": "userExampleService_DeleteByID",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1DeleteUserExampleByIDReply"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
}
],
"tags": [
"userExample"
]
},
"put": {
"summary": "更新userExample信息",
"description": "根据id更新userExample信息",
"operationId": "userExampleService_UpdateByID",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1UpdateUserExampleByIDReply"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string",
"format": "uint64"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"avatar": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
},
"gender": {
"$ref": "#/definitions/v1GenderType"
},
"status": {
"type": "integer",
"format": "int32"
},
"loginAt": {
"type": "string",
"format": "int64"
}
}
}
}
],
"tags": [
"userExample"
]
}
},
"/api/v1/userExamples": {
"post": {
"summary": "获取userExample列表",
"description": "使用post请求获取userExample列表",
"operationId": "userExampleService_List",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ListUserExampleReply"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1ListUserExampleRequest"
}
}
],
"tags": [
"userExample"
]
}
},
"/api/v1/userExamples/ids": {
"post": {
"summary": "根据多个id获取userExample列表",
"description": "使用post请求根据多个id获取userExample列表",
"operationId": "userExampleService_ListByIDs",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1ListUserExampleByIDsReply"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1ListUserExampleByIDsRequest"
}
}
],
"tags": [
"userExample"
]
}
}
},
"definitions": {
"protobufAny": {
"type": "object",
"properties": {
"@type": {
"type": "string"
}
},
"additionalProperties": {}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
},
"typesColumn": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"exp": {
"type": "string"
},
"value": {
"type": "string"
},
"logic": {
"type": "string"
}
}
},
"typesParams": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"format": "int32"
},
"limit": {
"type": "integer",
"format": "int32"
},
"sort": {
"type": "string"
},
"columns": {
"type": "array",
"items": {
"$ref": "#/definitions/typesColumn"
}
}
}
},
"v1CreateUserExampleReply": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uint64"
}
}
},
"v1CreateUserExampleRequest": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"avatar": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
},
"gender": {
"$ref": "#/definitions/v1GenderType"
}
}
},
"v1DeleteUserExampleByIDReply": {
"type": "object"
},
"v1GenderType": {
"type": "string",
"enum": [
"UNKNOWN",
"MALE",
"FEMALE"
],
"default": "UNKNOWN"
},
"v1GetUserExampleByIDReply": {
"type": "object",
"properties": {
"userExample": {
"$ref": "#/definitions/v1UserExample"
}
}
},
"v1ListUserExampleByIDsReply": {
"type": "object",
"properties": {
"userExamples": {
"type": "array",
"items": {
"$ref": "#/definitions/v1UserExample"
}
}
}
},
"v1ListUserExampleByIDsRequest": {
"type": "object",
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string",
"format": "uint64"
}
}
}
},
"v1ListUserExampleReply": {
"type": "object",
"properties": {
"total": {
"type": "string",
"format": "int64"
},
"userExamples": {
"type": "array",
"items": {
"$ref": "#/definitions/v1UserExample"
}
}
}
},
"v1ListUserExampleRequest": {
"type": "object",
"properties": {
"params": {
"$ref": "#/definitions/typesParams"
}
}
},
"v1UpdateUserExampleByIDReply": {
"type": "object"
},
"v1UserExample": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uint64"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"phone": {
"type": "string"
},
"avatar": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
},
"gender": {
"$ref": "#/definitions/v1GenderType"
},
"status": {
"type": "integer",
"format": "int32"
},
"loginAt": {
"type": "string",
"format": "int64"
},
"createdAt": {
"type": "string",
"format": "int64"
},
"updatedAt": {
"type": "string",
"format": "int64"
}
}
}
}
}

View File

@ -2,7 +2,9 @@
// This file was generated by swaggo/swag
package docs
import "github.com/swaggo/swag"
import (
"github.com/swaggo/swag"
)
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
@ -424,7 +426,7 @@ const docTemplate = `{
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "v0.0.0",
Version: "2.0",
Host: "localhost:8080",
BasePath: "",
Schemes: []string{"http", "https"},

20
go.mod
View File

@ -19,10 +19,10 @@ require (
github.com/go-redis/redis/v8 v8.11.5
github.com/go-sql-driver/mysql v1.6.0
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.2
github.com/golang/snappy v0.0.3
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0
github.com/hashicorp/consul/api v1.12.0
github.com/huandu/xstrings v1.3.1
github.com/jinzhu/copier v0.3.5
@ -33,6 +33,7 @@ require (
github.com/spf13/cast v1.5.0
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.12.0
github.com/srikrsna/protoc-gen-gotag v0.6.2
github.com/stretchr/testify v1.8.0
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
github.com/swaggo/gin-swagger v1.5.2
@ -49,7 +50,8 @@ require (
go.opentelemetry.io/otel/trace v1.9.0
go.uber.org/zap v1.21.0
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde
google.golang.org/grpc v1.48.0
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a
google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.28.1
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.3.5
@ -57,7 +59,7 @@ require (
)
require (
cloud.google.com/go/compute v1.6.1 // indirect
cloud.google.com/go/compute v1.7.0 // indirect
github.com/BurntSushi/toml v1.1.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
@ -96,8 +98,9 @@ require (
github.com/go-redis/redis/extra/rediscmd v0.2.0 // indirect
github.com/goccy/go-json v0.9.7 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
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/uuid v1.3.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
@ -151,14 +154,13 @@ require (
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.8 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

63
go.sum
View File

@ -29,6 +29,7 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW
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 v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@ -39,10 +40,12 @@ cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTB
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/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
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/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
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=
@ -53,6 +56,7 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
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=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
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.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
@ -170,6 +174,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@ -248,8 +253,9 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/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-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=
@ -299,7 +305,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
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/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -325,12 +332,15 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
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/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
@ -339,6 +349,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg=
github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY=
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU=
@ -589,6 +601,7 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
@ -603,6 +616,8 @@ 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.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
github.com/srikrsna/protoc-gen-gotag v0.6.2 h1:ULdarjI7FNUA6CNlLPIzSNvjdV2P4C2LSygPLvCVtfA=
github.com/srikrsna/protoc-gen-gotag v0.6.2/go.mod h1:cplWV0ZNBhuF54gnj6rU9pLNrqjXf5vh65Xqa1Kjy+4=
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=
@ -804,8 +819,9 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -824,8 +840,10 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -837,6 +855,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -929,8 +948,12 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -942,8 +965,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1016,6 +1040,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@ -1052,6 +1078,9 @@ google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/S
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -1102,6 +1131,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
@ -1134,8 +1164,14 @@ google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I=
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a h1:GH6UPn3ixhWcKDhpnEC55S75cerLPdpp3hrhfKYjZgw=
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -1165,8 +1201,11 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

View File

@ -30,16 +30,17 @@ func Set(conf *Config) {
}
type Config struct {
App App `yaml:"app" json:"app"`
Consul Consul `yaml:"consul" json:"consul"`
Etcd Etcd `yaml:"etcd" json:"etcd"`
Grpc Grpc `yaml:"grpc" json:"grpc"`
HTTP HTTP `yaml:"http" json:"http"`
Jaeger Jaeger `yaml:"jaeger" json:"jaeger"`
Logger Logger `yaml:"logger" json:"logger"`
Mysql Mysql `yaml:"mysql" json:"mysql"`
NacosRd NacosRd `yaml:"nacosRd" json:"nacosRd"`
Redis Redis `yaml:"redis" json:"redis"`
App App `yaml:"app" json:"app"`
Consul Consul `yaml:"consul" json:"consul"`
Etcd Etcd `yaml:"etcd" json:"etcd"`
Grpc Grpc `yaml:"grpc" json:"grpc"`
GrpcClient []GrpcClient `yaml:"grpcClient" json:"grpcClient"`
HTTP HTTP `yaml:"http" json:"http"`
Jaeger Jaeger `yaml:"jaeger" json:"jaeger"`
Logger Logger `yaml:"logger" json:"logger"`
Mysql Mysql `yaml:"mysql" json:"mysql"`
NacosRd NacosRd `yaml:"nacosRd" json:"nacosRd"`
Redis Redis `yaml:"redis" json:"redis"`
}
type Consul struct {
@ -55,6 +56,21 @@ type Jaeger struct {
AgentPort int `yaml:"agentPort" json:"agentPort"`
}
type App struct {
CacheType string `yaml:"cacheType" json:"cacheType"`
EnableCircuitBreaker bool `yaml:"enableCircuitBreaker" json:"enableCircuitBreaker"`
EnableLimit bool `yaml:"enableLimit" json:"enableLimit"`
EnableMetrics bool `yaml:"enableMetrics" json:"enableMetrics"`
EnablePprof bool `yaml:"enablePprof" json:"enablePprof"`
EnableTracing bool `yaml:"enableTracing" json:"enableTracing"`
Env string `yaml:"env" json:"env"`
Host string `yaml:"host" json:"host"`
Name string `yaml:"name" json:"name"`
RegistryDiscoveryType string `yaml:"registryDiscoveryType" json:"registryDiscoveryType"`
TracingSamplingRate float64 `yaml:"tracingSamplingRate" json:"tracingSamplingRate"`
Version string `yaml:"version" json:"version"`
}
type Mysql struct {
ConnMaxLifetime int `yaml:"connMaxLifetime" json:"connMaxLifetime"`
Dsn string `yaml:"dsn" json:"dsn"`
@ -71,28 +87,19 @@ type Redis struct {
WriteTimeout int `yaml:"writeTimeout" json:"writeTimeout"`
}
type App struct {
CacheType string `yaml:"cacheType" json:"cacheType"`
EnableCircuitBreaker bool `yaml:"enableCircuitBreaker" json:"enableCircuitBreaker"`
EnableLimit bool `yaml:"enableLimit" json:"enableLimit"`
EnableMetrics bool `yaml:"enableMetrics" json:"enableMetrics"`
EnablePprof bool `yaml:"enablePprof" json:"enablePprof"`
EnableRegistryDiscovery bool `yaml:"enableRegistryDiscovery" json:"enableRegistryDiscovery"`
EnableTracing bool `yaml:"enableTracing" json:"enableTracing"`
Env string `yaml:"env" json:"env"`
Host string `yaml:"host" json:"host"`
Name string `yaml:"name" json:"name"`
RegistryDiscoveryType string `yaml:"registryDiscoveryType" json:"registryDiscoveryType"`
TracingSamplingRate float64 `yaml:"tracingSamplingRate" json:"tracingSamplingRate"`
Version string `yaml:"version" json:"version"`
}
type Logger struct {
Format string `yaml:"format" json:"format"`
IsSave bool `yaml:"isSave" json:"isSave"`
Level string `yaml:"level" json:"level"`
}
type GrpcClient struct {
Host string `yaml:"host" json:"host"`
Name string `yaml:"name" json:"name"`
Port int `yaml:"port" json:"port"`
RegistryDiscoveryType string `yaml:"registryDiscoveryType" json:"registryDiscoveryType"`
}
type NacosRd struct {
IPAddr string `yaml:"ipAddr" json:"ipAddr"`
NamespaceID string `yaml:"namespaceID" json:"namespaceID"`

View File

@ -43,11 +43,11 @@ func Test_userExampleDao_Create(t *testing.T) {
defer d.Close()
testData := d.TestData.(*model.UserExample)
d.SqlMock.ExpectBegin()
d.SqlMock.ExpectExec("INSERT INTO .*").
d.SQLMock.ExpectBegin()
d.SQLMock.ExpectExec("INSERT INTO .*").
WithArgs(d.GetAnyArgs(testData)...).
WillReturnResult(sqlmock.NewResult(1, 1))
d.SqlMock.ExpectCommit()
d.SQLMock.ExpectCommit()
err := d.IDao.(UserExampleDao).Create(d.Ctx, testData)
if err != nil {
@ -65,11 +65,11 @@ func Test_userExampleDao_DeleteByID(t *testing.T) {
Valid: false,
}
d.SqlMock.ExpectBegin()
d.SqlMock.ExpectExec("UPDATE .*").
d.SQLMock.ExpectBegin()
d.SQLMock.ExpectExec("UPDATE .*").
WithArgs(d.AnyTime, testData.ID).
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
d.SqlMock.ExpectCommit()
d.SQLMock.ExpectCommit()
err := d.IDao.(UserExampleDao).DeleteByID(d.Ctx, testData.ID)
if err != nil {
@ -86,11 +86,11 @@ func Test_userExampleDao_UpdateByID(t *testing.T) {
defer d.Close()
testData := d.TestData.(*model.UserExample)
d.SqlMock.ExpectBegin()
d.SqlMock.ExpectExec("UPDATE .*").
d.SQLMock.ExpectBegin()
d.SQLMock.ExpectExec("UPDATE .*").
WithArgs(d.AnyTime, testData.ID).
WillReturnResult(sqlmock.NewResult(1, 1))
d.SqlMock.ExpectCommit()
d.SQLMock.ExpectCommit()
err := d.IDao.(UserExampleDao).UpdateByID(d.Ctx, testData)
if err != nil {
@ -127,7 +127,7 @@ func Test_userExampleDao_GetByID(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
d.SqlMock.ExpectQuery("SELECT .*").
d.SQLMock.ExpectQuery("SELECT .*").
WithArgs(testData.ID).
WillReturnRows(rows)
@ -136,19 +136,19 @@ func Test_userExampleDao_GetByID(t *testing.T) {
t.Fatal(err)
}
err = d.SqlMock.ExpectationsWereMet()
err = d.SQLMock.ExpectationsWereMet()
if err != nil {
t.Fatal(err)
}
// notfound error
d.SqlMock.ExpectQuery("SELECT .*").
d.SQLMock.ExpectQuery("SELECT .*").
WithArgs(2).
WillReturnRows(rows)
_, err = d.IDao.(UserExampleDao).GetByID(d.Ctx, 2)
assert.Error(t, err)
d.SqlMock.ExpectQuery("SELECT .*").
d.SQLMock.ExpectQuery("SELECT .*").
WithArgs(3, 4).
WillReturnRows(rows)
_, err = d.IDao.(UserExampleDao).GetByID(d.Ctx, 4)
@ -163,7 +163,7 @@ func Test_userExampleDao_GetByIDs(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
d.SqlMock.ExpectQuery("SELECT .*").
d.SQLMock.ExpectQuery("SELECT .*").
WithArgs(testData.ID).
WillReturnRows(rows)
@ -175,7 +175,7 @@ func Test_userExampleDao_GetByIDs(t *testing.T) {
_, err = d.IDao.(UserExampleDao).GetByIDs(d.Ctx, []uint64{111})
assert.Error(t, err)
err = d.SqlMock.ExpectationsWereMet()
err = d.SQLMock.ExpectationsWereMet()
if err != nil {
t.Fatal(err)
}
@ -189,7 +189,7 @@ func Test_userExampleDao_GetByColumns(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
d.SqlMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
d.SQLMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
_, _, err := d.IDao.(UserExampleDao).GetByColumns(d.Ctx, &query.Params{
Page: 0,
@ -200,7 +200,7 @@ func Test_userExampleDao_GetByColumns(t *testing.T) {
t.Fatal(err)
}
err = d.SqlMock.ExpectationsWereMet()
err = d.SQLMock.ExpectationsWereMet()
if err != nil {
t.Fatal(err)
}

View File

@ -9,6 +9,7 @@ import (
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/internal/types"
"github.com/zhufuyi/sponge/pkg/gin/middleware"
"github.com/zhufuyi/sponge/pkg/gin/response"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/mysql/query"
@ -44,7 +45,7 @@ func NewUserExampleHandler() UserExampleHandler {
}
}
// Create 创建
// Create 创建一条记录
// @Summary 创建userExample
// @Description 提交信息创建userExample
// @Tags userExample
@ -57,7 +58,7 @@ func (h *userExampleHandler) Create(c *gin.Context) {
form := &types.CreateUserExampleRequest{}
err := c.ShouldBindJSON(form)
if err != nil {
logger.Warn("ShouldBindJSON error: ", logger.Err(err), utils.FieldRequestIDFromContext(c))
logger.Warn("ShouldBindJSON error: ", logger.Err(err), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.InvalidParams)
return
}
@ -65,14 +66,14 @@ func (h *userExampleHandler) Create(c *gin.Context) {
userExample := &model.UserExample{}
err = copier.Copy(userExample, form)
if err != nil {
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.ErrCreateUserExample)
return
}
err = h.iDao.Create(c.Request.Context(), userExample)
if err != nil {
logger.Error("Create error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Error("Create error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
return
}
@ -97,7 +98,7 @@ func (h *userExampleHandler) DeleteByID(c *gin.Context) {
err := h.iDao.DeleteByID(c.Request.Context(), id)
if err != nil {
logger.Error("DeleteByID error", logger.Err(err), logger.Any("id", id), utils.FieldRequestIDFromContext(c))
logger.Error("DeleteByID error", logger.Err(err), logger.Any("id", id), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
return
}
@ -124,7 +125,7 @@ func (h *userExampleHandler) UpdateByID(c *gin.Context) {
form := &types.UpdateUserExampleByIDRequest{}
err := c.ShouldBindJSON(form)
if err != nil {
logger.Warn("ShouldBindJSON error: ", logger.Err(err), utils.FieldRequestIDFromContext(c))
logger.Warn("ShouldBindJSON error: ", logger.Err(err), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.InvalidParams)
return
}
@ -133,14 +134,14 @@ func (h *userExampleHandler) UpdateByID(c *gin.Context) {
userExample := &model.UserExample{}
err = copier.Copy(userExample, form)
if err != nil {
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.ErrUpdateUserExample)
return
}
err = h.iDao.UpdateByID(c.Request.Context(), userExample)
if err != nil {
logger.Error("UpdateByID error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Error("UpdateByID error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
return
}
@ -166,10 +167,10 @@ func (h *userExampleHandler) GetByID(c *gin.Context) {
userExample, err := h.iDao.GetByID(c.Request.Context(), id)
if err != nil {
if errors.Is(err, query.ErrNotFound) {
logger.Warn("GetByID not found", logger.Err(err), logger.Any("id", id), utils.FieldRequestIDFromContext(c))
logger.Warn("GetByID not found", logger.Err(err), logger.Any("id", id), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.NotFound)
} else {
logger.Error("GetByID error", logger.Err(err), logger.Any("id", id), utils.FieldRequestIDFromContext(c))
logger.Error("GetByID error", logger.Err(err), logger.Any("id", id), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
}
return
@ -178,7 +179,7 @@ func (h *userExampleHandler) GetByID(c *gin.Context) {
data := &types.GetUserExampleByIDRespond{}
err = copier.Copy(data, userExample)
if err != nil {
logger.Warn("Copy error", logger.Err(err), logger.Any("id", id), utils.FieldRequestIDFromContext(c))
logger.Warn("Copy error", logger.Err(err), logger.Any("id", id), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.ErrGetUserExample)
return
}
@ -200,14 +201,14 @@ func (h *userExampleHandler) ListByIDs(c *gin.Context) {
form := &types.GetUserExamplesByIDsRequest{}
err := c.ShouldBindJSON(form)
if err != nil {
logger.Warn("ShouldBindJSON error: ", logger.Err(err), utils.FieldRequestIDFromContext(c))
logger.Warn("ShouldBindJSON error: ", logger.Err(err), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.InvalidParams)
return
}
userExamples, err := h.iDao.GetByIDs(c.Request.Context(), form.IDs)
if err != nil {
logger.Error("GetByIDs error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Error("GetByIDs error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
return
@ -215,7 +216,7 @@ func (h *userExampleHandler) ListByIDs(c *gin.Context) {
data, err := convertUserExamples(userExamples)
if err != nil {
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.ErrListUserExample)
return
}
@ -238,21 +239,21 @@ func (h *userExampleHandler) List(c *gin.Context) {
form := &types.GetUserExamplesRequest{}
err := c.ShouldBindJSON(form)
if err != nil {
logger.Warn("ShouldBindJSON error: ", logger.Err(err), utils.FieldRequestIDFromContext(c))
logger.Warn("ShouldBindJSON error: ", logger.Err(err), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.InvalidParams)
return
}
userExamples, total, err := h.iDao.GetByColumns(c.Request.Context(), &form.Params)
if err != nil {
logger.Error("GetByColumns error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Error("GetByColumns error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Output(c, ecode.InternalServerError.ToHTTPCode())
return
}
data, err := convertUserExamples(userExamples)
if err != nil {
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), utils.FieldRequestIDFromContext(c))
logger.Warn("Copy error", logger.Err(err), logger.Any("form", form), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.ErrListUserExample)
return
}
@ -267,7 +268,7 @@ func getUserExampleIDFromPath(c *gin.Context) (string, uint64, bool) {
idStr := c.Param("id")
id, err := utils.StrToUint64E(idStr)
if err != nil || id == 0 {
logger.Warn("StrToUint64E error: ", logger.String("idStr", idStr), utils.FieldRequestIDFromContext(c))
logger.Warn("StrToUint64E error: ", logger.String("idStr", idStr), middleware.GCtxRequestIDField(c))
response.Error(c, ecode.InvalidParams)
return "", 0, true
}

View File

@ -81,7 +81,7 @@ func newUserExampleHandler() *gotest.Handler {
},
}
h.GoRunHttpServer(testFns)
h.GoRunHTTPServer(testFns)
time.Sleep(time.Millisecond * 200)
return h
@ -93,12 +93,12 @@ func Test_userExampleHandler_Create(t *testing.T) {
testData := &types.CreateUserExampleRequest{}
_ = copier.Copy(testData, h.TestData.(*model.UserExample))
h.MockDao.SqlMock.ExpectBegin()
h.MockDao.SQLMock.ExpectBegin()
args := h.MockDao.GetAnyArgs(h.TestData)
h.MockDao.SqlMock.ExpectExec("INSERT INTO .*").
h.MockDao.SQLMock.ExpectExec("INSERT INTO .*").
WithArgs(args[:len(args)-1]...). // 根据实际参数数量修改
WillReturnResult(sqlmock.NewResult(1, 1))
h.MockDao.SqlMock.ExpectCommit()
h.MockDao.SQLMock.ExpectCommit()
result := &gohttp.StdResult{}
err := gohttp.Post(result, h.GetRequestURL("Create"), testData)
@ -124,8 +124,8 @@ func Test_userExampleHandler_Create(t *testing.T) {
}
t.Logf("%+v", result)
h.MockDao.SqlMock.ExpectBegin()
h.MockDao.SqlMock.ExpectCommit()
h.MockDao.SQLMock.ExpectBegin()
h.MockDao.SQLMock.ExpectCommit()
result = &gohttp.StdResult{}
err = gohttp.Post(result, h.GetRequestURL("Create"), testData)
assert.Error(t, err)
@ -137,11 +137,11 @@ func Test_userExampleHandler_DeleteByID(t *testing.T) {
defer h.Close()
testData := h.TestData.(*model.UserExample)
h.MockDao.SqlMock.ExpectBegin()
h.MockDao.SqlMock.ExpectExec("UPDATE .*").
h.MockDao.SQLMock.ExpectBegin()
h.MockDao.SQLMock.ExpectExec("UPDATE .*").
WithArgs(h.MockDao.AnyTime, testData.ID). // 根据测试数据数量调整
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
h.MockDao.SqlMock.ExpectCommit()
h.MockDao.SQLMock.ExpectCommit()
result := &gohttp.StdResult{}
err := gohttp.Delete(result, h.GetRequestURL("DeleteByID", testData.ID))
@ -167,11 +167,11 @@ func Test_userExampleHandler_UpdateByID(t *testing.T) {
testData := &types.UpdateUserExampleByIDRequest{}
_ = copier.Copy(testData, h.TestData.(*model.UserExample))
h.MockDao.SqlMock.ExpectBegin()
h.MockDao.SqlMock.ExpectExec("UPDATE .*").
h.MockDao.SQLMock.ExpectBegin()
h.MockDao.SQLMock.ExpectExec("UPDATE .*").
WithArgs(h.MockDao.AnyTime, testData.ID). // 根据测试数据数量调整
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
h.MockDao.SqlMock.ExpectCommit()
h.MockDao.SQLMock.ExpectCommit()
result := &gohttp.StdResult{}
err := gohttp.Put(result, h.GetRequestURL("UpdateByID", testData.ID), testData)
@ -199,7 +199,7 @@ func Test_userExampleHandler_GetByID(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
h.MockDao.SqlMock.ExpectQuery("SELECT .*").
h.MockDao.SQLMock.ExpectQuery("SELECT .*").
WithArgs(testData.ID).
WillReturnRows(rows)
@ -229,7 +229,7 @@ func Test_userExampleHandler_ListByIDs(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
h.MockDao.SqlMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
h.MockDao.SQLMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
result := &gohttp.StdResult{}
err := gohttp.Post(result, h.GetRequestURL("ListByIDs"), &types.GetUserExamplesByIDsRequest{IDs: []uint64{testData.ID}})
@ -257,7 +257,7 @@ func Test_userExampleHandler_List(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
h.MockDao.SqlMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
h.MockDao.SQLMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
result := &gohttp.StdResult{}
err := gohttp.Post(result, h.GetRequestURL("List"), &types.GetUserExamplesRequest{query.Params{

View File

@ -3,15 +3,15 @@ package routers
import (
"net/http"
"github.com/zhufuyi/sponge/docs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/pkg/gin/handlerfunc"
"github.com/zhufuyi/sponge/pkg/gin/middleware"
"github.com/zhufuyi/sponge/pkg/gin/middleware/metrics"
"github.com/zhufuyi/sponge/pkg/gin/validator"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/docs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
@ -20,8 +20,7 @@ import (
)
var (
routerFns []func() // 路由集合
apiV1 *gin.RouterGroup // 基础路由组
routerFns []func(*gin.RouterGroup) // 路由集合
)
// NewRouter 实例化路由
@ -72,18 +71,17 @@ func NewRouter() *gin.Engine {
// 校验器
binding.Validator = validator.Init()
r.GET("/health", handlerfunc.CheckHealth)
r.GET("/ping", handlerfunc.Ping)
// 注册swagger路由通过swag init生成代码
docs.SwaggerInfo.BasePath = ""
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.GET("/health", handlerfunc.CheckHealth)
r.GET("/ping", handlerfunc.Ping)
apiV1 = r.Group("/api/v1")
// 注册所有路由
apiV1 := r.Group("/api/v1")
// 注册/api/v1前缀路由组
for _, fn := range routerFns {
fn()
fn(apiV1)
}
return r

View File

@ -0,0 +1,84 @@
package routers
import (
"net/http"
"github.com/zhufuyi/sponge/docs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/pkg/gin/handlerfunc"
"github.com/zhufuyi/sponge/pkg/gin/middleware"
"github.com/zhufuyi/sponge/pkg/gin/middleware/metrics"
"github.com/zhufuyi/sponge/pkg/gin/swagger"
"github.com/zhufuyi/sponge/pkg/gin/validator"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
var (
rootRouterFns []func(engine *gin.Engine) // 根路由组
)
// NewRouter_gwExample 创建一个路由
func NewRouter_gwExample() *gin.Engine { //nolint
r := gin.New()
r.Use(gin.Recovery())
r.Use(middleware.Cors())
// request id 中间件
r.Use(middleware.RequestID())
// logger 中间件
r.Use(middleware.Logging(
middleware.WithLog(logger.Get()),
middleware.WithRequestIDFromContext(),
middleware.WithIgnoreRoutes("/metrics"), // 忽略路由
))
// metrics 中间件
if config.Get().App.EnableMetrics {
r.Use(metrics.Metrics(r,
//metrics.WithMetricsPath("/metrics"), // 默认是 /metrics
metrics.WithIgnoreStatusCodes(http.StatusNotFound), // 忽略404状态码
))
}
// limit 中间件
if config.Get().App.EnableLimit {
r.Use(middleware.RateLimit())
}
// circuit breaker 中间件
if config.Get().App.EnableCircuitBreaker {
r.Use(middleware.CircuitBreaker())
}
// trace 中间件
if config.Get().App.EnableTracing {
r.Use(middleware.Tracing(config.Get().App.Name))
}
// profile 性能分析
if config.Get().App.EnablePprof {
pprof.Register(r)
}
// 校验器
binding.Validator = validator.Init()
r.GET("/health", handlerfunc.CheckHealth)
r.GET("/ping", handlerfunc.Ping)
swagger.CustomRouter(r, "apis", docs.ApiDocs)
// 注册/前缀路由组
for _, fn := range rootRouterFns {
fn(r)
}
return r
}

View File

@ -0,0 +1,57 @@
package routers
import (
"context"
"testing"
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/gin-gonic/gin"
)
func TestNewRouter_gwExample(t *testing.T) {
err := config.Init(configs.Path("serverNameExample.yml"))
if err != nil {
t.Fatal(err)
}
config.Get().App.EnableMetrics = true
config.Get().App.EnableTracing = true
config.Get().App.EnablePprof = true
config.Get().App.EnableLimit = true
config.Get().App.EnableCircuitBreaker = true
gin.SetMode(gin.ReleaseMode)
r := NewRouter_gwExample()
defer func() { recover() }()
userExampleRouter_gwExample(r, &mockGw{})
}
type mockGw struct{}
func (m mockGw) Create(ctx context.Context, req *serverNameExampleV1.CreateUserExampleRequest) (*serverNameExampleV1.CreateUserExampleReply, error) {
return nil, nil
}
func (m mockGw) DeleteByID(ctx context.Context, req *serverNameExampleV1.DeleteUserExampleByIDRequest) (*serverNameExampleV1.DeleteUserExampleByIDReply, error) {
return nil, nil
}
func (m mockGw) GetByID(ctx context.Context, req *serverNameExampleV1.GetUserExampleByIDRequest) (*serverNameExampleV1.GetUserExampleByIDReply, error) {
return nil, nil
}
func (m mockGw) List(ctx context.Context, req *serverNameExampleV1.ListUserExampleRequest) (*serverNameExampleV1.ListUserExampleReply, error) {
return nil, nil
}
func (m mockGw) ListByIDs(ctx context.Context, req *serverNameExampleV1.ListUserExampleByIDsRequest) (*serverNameExampleV1.ListUserExampleByIDsReply, error) {
return nil, nil
}
func (m mockGw) UpdateByID(ctx context.Context, req *serverNameExampleV1.UpdateUserExampleByIDRequest) (*serverNameExampleV1.UpdateUserExampleByIDReply, error) {
return nil, nil
}

View File

@ -3,11 +3,9 @@ package routers
import (
"testing"
"github.com/gin-gonic/gin"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/handler"
"github.com/gin-gonic/gin"
)
func TestNewRouter(t *testing.T) {
@ -16,39 +14,23 @@ func TestNewRouter(t *testing.T) {
t.Fatal(err)
}
defer func() {
if e := recover(); e != nil {
t.Log("ignore connect mysql error info")
}
}()
config.Get().App.EnableMetrics = true
config.Get().App.EnableMetrics = false
config.Get().App.EnableTracing = true
config.Get().App.EnablePprof = true
config.Get().App.EnableLimit = true
config.Get().App.EnableCircuitBreaker = true
gin.SetMode(gin.ReleaseMode)
r := NewRouter()
userExampleRouter(r.Group("/"), handler.NewUserExampleHandler())
userExampleRouter(r.Group("/"), &mock{})
}
type mock struct{}
func (u mock) Create(c *gin.Context) { return }
func (u mock) Create(c *gin.Context) { return }
func (u mock) DeleteByID(c *gin.Context) { return }
func (u mock) UpdateByID(c *gin.Context) { return }
func (u mock) GetByID(c *gin.Context) { return }
func (u mock) ListByIDs(c *gin.Context) { return }
func (u mock) List(c *gin.Context) { return }
func Test_userExampleRouter(t *testing.T) {
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
userExampleRouter(r.Group("/"), &mock{})
}
func (u mock) GetByID(c *gin.Context) { return }
func (u mock) ListByIDs(c *gin.Context) { return }
func (u mock) List(c *gin.Context) { return }

View File

@ -8,8 +8,8 @@ import (
// nolint
func init() {
routerFns = append(routerFns, func() {
userExampleRouter(apiV1, handler.NewUserExampleHandler()) // 加入到路由组
routerFns = append(routerFns, func(group *gin.RouterGroup) {
userExampleRouter(group, handler.NewUserExampleHandler())
})
}

View File

@ -0,0 +1,24 @@
package routers
import (
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
"github.com/zhufuyi/sponge/internal/service"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/gin-gonic/gin"
)
// nolint
func init() {
rootRouterFns = append(rootRouterFns, func(r *gin.Engine) {
userExampleRouter_gwExample(r, service.NewUserExampleServiceClient())
})
}
func userExampleRouter_gwExample(r *gin.Engine, iService serverNameExampleV1.UserExampleServiceLogicer) { //nolint
serverNameExampleV1.RegisterUserExampleServiceRouter(r, iService,
serverNameExampleV1.WithUserExampleServiceRPCResponse(),
serverNameExampleV1.WithUserExampleServiceLogger(logger.Get()),
)
}

View File

@ -0,0 +1,126 @@
package rpcclient
import (
"context"
"fmt"
"strings"
"sync"
"time"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/pkg/consulcli"
"github.com/zhufuyi/sponge/pkg/etcdcli"
"github.com/zhufuyi/sponge/pkg/grpc/grpccli"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
"google.golang.org/grpc"
)
var (
serverNameExampleConn *grpc.ClientConn
serverNameExampleOnce sync.Once
)
// NewServerNameExampleRPCConn instantiate rpc client connection
func NewServerNameExampleRPCConn() {
cfg := config.Get()
var cliOptions = []grpccli.Option{
grpccli.WithEnableLog(logger.Get()),
//grpccli.WithEnableLoadBalance(),
//grpccli.WithEnableRetry(),
}
serverName := "serverNameExample"
var grpcClientCfg config.GrpcClient
for _, cli := range cfg.GrpcClient {
if strings.EqualFold(cli.Name, serverName) {
grpcClientCfg = cli
break
}
}
if grpcClientCfg.Name == "" {
panic(fmt.Sprintf("not found server name '%v' in yaml config file (field GrpcClient), "+
"please change to the correct service name", serverName))
}
// 如果没有使用服务发现用ip和端口直连rpc服务
endpoint := fmt.Sprintf("%s:%d", grpcClientCfg.Host, cfg.Grpc.Port)
switch grpcClientCfg.RegistryDiscoveryType {
// 使用consul发现服务
case "consul":
endpoint = "discovery:///" + grpcClientCfg.Name // 通过服务名称连接grpc服务
cli, err := consulcli.Init(cfg.Consul.Addr, consulcli.WithWaitTime(time.Second*5))
if err != nil {
panic(fmt.Sprintf("consulcli.Init error: %v, addr: %s", err, cfg.Consul.Addr))
}
iDiscovery := consul.New(cli)
cliOptions = append(cliOptions, grpccli.WithDiscovery(iDiscovery))
// 使用etcd发现服务
case "etcd":
endpoint = "discovery:///" + grpcClientCfg.Name // 通过服务名称连接grpc服务
cli, err := etcdcli.Init(cfg.Etcd.Addrs, etcdcli.WithDialTimeout(time.Second*5))
if err != nil {
panic(fmt.Sprintf("etcdcli.Init error: %v, addr: %s", err, cfg.Etcd.Addrs))
}
iDiscovery := etcd.New(cli)
cliOptions = append(cliOptions, grpccli.WithDiscovery(iDiscovery))
// 使用nacos发现服务
case "nacos":
// example: endpoint = "discovery:///serverName.scheme"
endpoint = "discovery:///" + grpcClientCfg.Name + ".grpc"
cli, err := nacoscli.NewNamingClient(
cfg.NacosRd.IPAddr,
cfg.NacosRd.Port,
cfg.NacosRd.NamespaceID)
if err != nil {
panic(fmt.Sprintf("nacoscli.NewNamingClient error: %v, ipAddr: %s, port: %d",
err, cfg.NacosRd.IPAddr, cfg.NacosRd.Port))
}
iDiscovery := nacos.New(cli)
cliOptions = append(cliOptions, grpccli.WithDiscovery(iDiscovery))
}
if cfg.App.EnableTracing {
cliOptions = append(cliOptions, grpccli.WithEnableTrace())
}
if cfg.App.EnableCircuitBreaker {
cliOptions = append(cliOptions, grpccli.WithEnableCircuitBreaker())
}
if cfg.App.EnableMetrics {
cliOptions = append(cliOptions, grpccli.WithEnableMetrics())
}
// 如果需要安全连接使用grpccli.Dial(ctx, endpoint, cliOptions...)并且cliOptions设置WithCredentials指定证书路径
var err error
serverNameExampleConn, err = grpccli.DialInsecure(context.Background(), endpoint, cliOptions...)
if err != nil {
panic(fmt.Sprintf("dial rpc server failed: %v, endpoint: %s", err, endpoint))
}
}
// GetServerNameExampleRPCConn get client conn
func GetServerNameExampleRPCConn() *grpc.ClientConn {
if serverNameExampleConn == nil {
serverNameExampleOnce.Do(func() {
NewServerNameExampleRPCConn()
})
}
return serverNameExampleConn
}
// CloseServerNameExampleRPCConn Close tears down the ClientConn and all underlying connections.
func CloseServerNameExampleRPCConn() error {
if serverNameExampleConn == nil {
return nil
}
return serverNameExampleConn.Close()
}

View File

@ -0,0 +1,65 @@
package rpcclient
import (
"testing"
"time"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/stretchr/testify/assert"
)
func TestNewServerNameExampleRPCConn(t *testing.T) {
err := config.Init(configs.Path("serverNameExample.yml"))
if err != nil {
t.Fatal(err)
}
go func() {
time.Sleep(time.Millisecond * 100)
config.Get().GrpcClient[0].RegistryDiscoveryType = "consul"
NewServerNameExampleRPCConn()
}()
go func() {
time.Sleep(time.Millisecond * 200)
config.Get().GrpcClient[0].RegistryDiscoveryType = "etcd"
NewServerNameExampleRPCConn()
}()
go func() {
time.Sleep(time.Millisecond * 300)
config.Get().GrpcClient[0].RegistryDiscoveryType = "nacos"
NewServerNameExampleRPCConn()
}()
go func() {
time.Sleep(time.Millisecond * 400)
defer func() { recover() }()
config.Get().GrpcClient[0].Name = "unknown name"
NewServerNameExampleRPCConn()
}()
time.Sleep(time.Second * 6)
go func() {
defer func() { recover() }()
conn := GetServerNameExampleRPCConn()
assert.NotNil(t, conn)
}()
err = CloseServerNameExampleRPCConn()
assert.NoError(t, err)
}
func TestGetServerNameExampleRPCConn(t *testing.T) {
serverNameExampleConn = nil
err := CloseServerNameExampleRPCConn()
assert.NoError(t, err)
// nil error
defer func() { recover() }()
conn := GetServerNameExampleRPCConn()
assert.NotNil(t, conn)
}

View File

@ -28,7 +28,7 @@ func TestGRPCServer(t *testing.T) {
config.Get().App.EnableTracing = true
config.Get().App.EnablePprof = true
config.Get().App.EnableLimit = true
config.Get().App.EnableRegistryDiscovery = true
config.Get().App.EnableCircuitBreaker = true
port, _ := utils.GetAvailablePort()
addr := fmt.Sprintf(":%d", port)
@ -56,7 +56,7 @@ func TestGRPCServerMock(t *testing.T) {
config.Get().App.EnableTracing = true
config.Get().App.EnablePprof = true
config.Get().App.EnableLimit = true
config.Get().App.EnableRegistryDiscovery = true
config.Get().App.EnableCircuitBreaker = true
port, _ := utils.GetAvailablePort()
addr := fmt.Sprintf(":%d", port)

View File

@ -70,7 +70,8 @@ func NewHTTPServer(addr string, opts ...HTTPOption) app.IServer {
gin.SetMode(gin.DebugMode)
}
router := routers.NewRouter()
//router := routers.NewRouter()
router := routers.NewRouter_gwExample()
server := &http.Server{
Addr: addr,
Handler: router,

View File

@ -27,6 +27,7 @@ func TestHTTPServer(t *testing.T) {
config.Get().App.EnableTracing = true
config.Get().App.EnablePprof = true
config.Get().App.EnableLimit = true
config.Get().App.EnableCircuitBreaker = true
port, _ := utils.GetAvailablePort()
addr := fmt.Sprintf(":%d", port)
@ -55,7 +56,7 @@ func TestHTTPServerMock(t *testing.T) {
config.Get().App.EnableTracing = true
config.Get().App.EnablePprof = true
config.Get().App.EnableLimit = true
config.Get().App.EnableRegistryDiscovery = true
config.Get().App.EnableCircuitBreaker = true
port, _ := utils.GetAvailablePort()
addr := fmt.Sprintf(":%d", port)

View File

@ -5,7 +5,7 @@ import (
"errors"
"strings"
pb "github.com/zhufuyi/sponge/api/serverNameExample/v1"
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
"github.com/zhufuyi/sponge/internal/cache"
"github.com/zhufuyi/sponge/internal/dao"
"github.com/zhufuyi/sponge/internal/ecode"
@ -21,20 +21,20 @@ import (
// nolint
func init() {
registerFns = append(registerFns, func(server *grpc.Server) {
pb.RegisterUserExampleServiceServer(server, NewUserExampleServiceServer()) // 把service注册到rpc服务中
serverNameExampleV1.RegisterUserExampleServiceServer(server, NewUserExampleServiceServer()) // 把service注册到rpc服务中
})
}
var _ pb.UserExampleServiceServer = (*userExampleService)(nil)
var _ serverNameExampleV1.UserExampleServiceServer = (*userExampleService)(nil)
type userExampleService struct {
pb.UnimplementedUserExampleServiceServer
serverNameExampleV1.UnimplementedUserExampleServiceServer
iDao dao.UserExampleDao
}
// NewUserExampleServiceServer 创建一个实例
func NewUserExampleServiceServer() pb.UserExampleServiceServer {
func NewUserExampleServiceServer() serverNameExampleV1.UserExampleServiceServer {
return &userExampleService{
iDao: dao.NewUserExampleDao(
model.GetDB(),
@ -44,7 +44,7 @@ func NewUserExampleServiceServer() pb.UserExampleServiceServer {
}
// Create 创建一条记录
func (s *userExampleService) Create(ctx context.Context, req *pb.CreateUserExampleRequest) (*pb.CreateUserExampleReply, error) {
func (s *userExampleService) Create(ctx context.Context, req *serverNameExampleV1.CreateUserExampleRequest) (*serverNameExampleV1.CreateUserExampleReply, error) {
err := req.Validate()
if err != nil {
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req))
@ -64,11 +64,11 @@ func (s *userExampleService) Create(ctx context.Context, req *pb.CreateUserExamp
return nil, ecode.StatusInternalServerError.ToRPCErr()
}
return &pb.CreateUserExampleReply{Id: userExample.ID}, nil
return &serverNameExampleV1.CreateUserExampleReply{Id: userExample.ID}, nil
}
// DeleteByID 根据id删除一条记录
func (s *userExampleService) DeleteByID(ctx context.Context, req *pb.DeleteUserExampleByIDRequest) (*pb.DeleteUserExampleByIDReply, error) {
func (s *userExampleService) DeleteByID(ctx context.Context, req *serverNameExampleV1.DeleteUserExampleByIDRequest) (*serverNameExampleV1.DeleteUserExampleByIDReply, error) {
err := req.Validate()
if err != nil {
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req))
@ -81,11 +81,11 @@ func (s *userExampleService) DeleteByID(ctx context.Context, req *pb.DeleteUserE
return nil, ecode.StatusInternalServerError.ToRPCErr()
}
return &pb.DeleteUserExampleByIDReply{}, nil
return &serverNameExampleV1.DeleteUserExampleByIDReply{}, nil
}
// UpdateByID 根据id更新一条记录
func (s *userExampleService) UpdateByID(ctx context.Context, req *pb.UpdateUserExampleByIDRequest) (*pb.UpdateUserExampleByIDReply, error) {
func (s *userExampleService) UpdateByID(ctx context.Context, req *serverNameExampleV1.UpdateUserExampleByIDRequest) (*serverNameExampleV1.UpdateUserExampleByIDReply, error) {
err := req.Validate()
if err != nil {
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req))
@ -106,11 +106,11 @@ func (s *userExampleService) UpdateByID(ctx context.Context, req *pb.UpdateUserE
return nil, ecode.StatusInternalServerError.ToRPCErr()
}
return &pb.UpdateUserExampleByIDReply{}, nil
return &serverNameExampleV1.UpdateUserExampleByIDReply{}, nil
}
// GetByID 根据id查询一条记录
func (s *userExampleService) GetByID(ctx context.Context, req *pb.GetUserExampleByIDRequest) (*pb.GetUserExampleByIDReply, error) {
func (s *userExampleService) GetByID(ctx context.Context, req *serverNameExampleV1.GetUserExampleByIDRequest) (*serverNameExampleV1.GetUserExampleByIDReply, error) {
err := req.Validate()
if err != nil {
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req))
@ -133,11 +133,11 @@ func (s *userExampleService) GetByID(ctx context.Context, req *pb.GetUserExample
return nil, ecode.StatusGetUserExample.Err()
}
return &pb.GetUserExampleByIDReply{UserExample: data}, nil
return &serverNameExampleV1.GetUserExampleByIDReply{UserExample: data}, nil
}
// ListByIDs 根据id数组获取多条记录
func (s *userExampleService) ListByIDs(ctx context.Context, req *pb.ListUserExampleByIDsRequest) (*pb.ListUserExampleByIDsReply, error) {
func (s *userExampleService) ListByIDs(ctx context.Context, req *serverNameExampleV1.ListUserExampleByIDsRequest) (*serverNameExampleV1.ListUserExampleByIDsReply, error) {
err := req.Validate()
if err != nil {
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req))
@ -150,7 +150,7 @@ func (s *userExampleService) ListByIDs(ctx context.Context, req *pb.ListUserExam
return nil, ecode.StatusInternalServerError.ToRPCErr()
}
datas := []*pb.UserExample{}
datas := []*serverNameExampleV1.UserExample{}
for _, record := range records {
data, err := covertUserExample(record)
if err != nil {
@ -160,11 +160,11 @@ func (s *userExampleService) ListByIDs(ctx context.Context, req *pb.ListUserExam
datas = append(datas, data)
}
return &pb.ListUserExampleByIDsReply{UserExamples: datas}, nil
return &serverNameExampleV1.ListUserExampleByIDsReply{UserExamples: datas}, nil
}
// List 获取多条记录
func (s *userExampleService) List(ctx context.Context, req *pb.ListUserExampleRequest) (*pb.ListUserExampleReply, error) {
func (s *userExampleService) List(ctx context.Context, req *serverNameExampleV1.ListUserExampleRequest) (*serverNameExampleV1.ListUserExampleReply, error) {
err := req.Validate()
if err != nil {
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req))
@ -189,7 +189,7 @@ func (s *userExampleService) List(ctx context.Context, req *pb.ListUserExampleRe
return nil, ecode.StatusInternalServerError.ToRPCErr()
}
datas := []*pb.UserExample{}
datas := []*serverNameExampleV1.UserExample{}
for _, record := range records {
data, err := covertUserExample(record)
if err != nil {
@ -199,14 +199,14 @@ func (s *userExampleService) List(ctx context.Context, req *pb.ListUserExampleRe
datas = append(datas, data)
}
return &pb.ListUserExampleReply{
return &serverNameExampleV1.ListUserExampleReply{
Total: total,
UserExamples: datas,
}, nil
}
func covertUserExample(record *model.UserExample) (*pb.UserExample, error) {
value := &pb.UserExample{}
func covertUserExample(record *model.UserExample) (*serverNameExampleV1.UserExample, error) {
value := &serverNameExampleV1.UserExample{}
err := copier.Copy(value, record)
if err != nil {
return nil, err

View File

@ -6,27 +6,28 @@ package service
import (
"context"
"fmt"
"github.com/zhufuyi/sponge/pkg/etcdcli"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
"testing"
"time"
pb "github.com/zhufuyi/sponge/api/serverNameExample/v1"
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
"github.com/zhufuyi/sponge/api/types"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/pkg/consulcli"
"github.com/zhufuyi/sponge/pkg/etcdcli"
"github.com/zhufuyi/sponge/pkg/grpc/benchmark"
"github.com/zhufuyi/sponge/pkg/grpc/grpccli"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/servicerd/registry"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/consul"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/etcd"
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
"go.uber.org/zap"
)
func initUserExampleServiceClient() pb.UserExampleServiceClient {
func initUserExampleServiceClient() serverNameExampleV1.UserExampleServiceClient {
err := config.Init(configs.Path("serverNameExample.yml"))
if err != nil {
panic(err)
@ -38,7 +39,7 @@ func initUserExampleServiceClient() pb.UserExampleServiceClient {
//grpccli.WithEnableLoadBalance(),
//grpccli.WithEnableRetry(),
}
if config.Get().App.EnableRegistryDiscovery {
if config.Get().App.RegistryDiscoveryType != "" {
var iDiscovery registry.Discovery
endpoint = "discovery:///" + config.Get().App.Name // 通过服务名称连接grpc服务
@ -63,7 +64,7 @@ func initUserExampleServiceClient() pb.UserExampleServiceClient {
// 使用nacos做服务发现
if config.Get().App.RegistryDiscoveryType == "nacos" {
// example: endpoint = "discovery:///serverName.scheme"
endpoint += ".grpc" // 在endpoint+.grpc
endpoint = "discovery:///" + config.Get().App.Name + ".grpc"
cli, err := nacoscli.NewNamingClient(
config.Get().NacosRd.IPAddr,
config.Get().NacosRd.Port,
@ -76,6 +77,7 @@ func initUserExampleServiceClient() pb.UserExampleServiceClient {
cliOptions = append(cliOptions, grpccli.WithDiscovery(iDiscovery))
}
if config.Get().App.EnableTracing {
cliOptions = append(cliOptions, grpccli.WithEnableTrace())
}
@ -90,9 +92,8 @@ func initUserExampleServiceClient() pb.UserExampleServiceClient {
if err != nil {
panic(err)
}
//defer conn.Close()
return pb.NewUserExampleServiceClient(conn)
return serverNameExampleV1.NewUserExampleServiceClient(conn)
}
// 通过客户端测试userExample的各个方法
@ -111,7 +112,7 @@ func Test_userExampleService_methods(t *testing.T) {
name: "Create",
fn: func() (interface{}, error) {
// todo test after filling in parameters
return cli.Create(ctx, &pb.CreateUserExampleRequest{
return cli.Create(ctx, &serverNameExampleV1.CreateUserExampleRequest{
Name: "foo7",
Email: "foo7@bar.com",
Password: "f447b20a7fcbf53a5d5be013ea0b15af",
@ -128,7 +129,7 @@ func Test_userExampleService_methods(t *testing.T) {
name: "UpdateByID",
fn: func() (interface{}, error) {
// todo test after filling in parameters
return cli.UpdateByID(ctx, &pb.UpdateUserExampleByIDRequest{
return cli.UpdateByID(ctx, &serverNameExampleV1.UpdateUserExampleByIDRequest{
Id: 7,
Phone: "16000000001",
Age: 11,
@ -141,7 +142,7 @@ func Test_userExampleService_methods(t *testing.T) {
name: "DeleteByID",
fn: func() (interface{}, error) {
// todo test after filling in parameters
return cli.DeleteByID(ctx, &pb.DeleteUserExampleByIDRequest{
return cli.DeleteByID(ctx, &serverNameExampleV1.DeleteUserExampleByIDRequest{
Id: 100,
})
},
@ -152,7 +153,7 @@ func Test_userExampleService_methods(t *testing.T) {
name: "GetByID",
fn: func() (interface{}, error) {
// todo test after filling in parameters
return cli.GetByID(ctx, &pb.GetUserExampleByIDRequest{
return cli.GetByID(ctx, &serverNameExampleV1.GetUserExampleByIDRequest{
Id: 1,
})
},
@ -163,7 +164,7 @@ func Test_userExampleService_methods(t *testing.T) {
name: "ListByIDs",
fn: func() (interface{}, error) {
// todo test after filling in parameters
return cli.ListByIDs(ctx, &pb.ListUserExampleByIDsRequest{
return cli.ListByIDs(ctx, &serverNameExampleV1.ListUserExampleByIDsRequest{
Ids: []uint64{1, 2, 3},
})
},
@ -174,7 +175,7 @@ func Test_userExampleService_methods(t *testing.T) {
name: "List",
fn: func() (interface{}, error) {
// todo test after filling in parameters
return cli.List(ctx, &pb.ListUserExampleRequest{
return cli.List(ctx, &serverNameExampleV1.ListUserExampleRequest{
Params: &types.Params{
Page: 0,
Limit: 10,
@ -229,7 +230,7 @@ func Test_userExampleService_benchmark(t *testing.T) {
name: "GetByID",
fn: func() error {
// todo test after filling in parameters
message := &pb.GetUserExampleByIDRequest{
message := &serverNameExampleV1.GetUserExampleByIDRequest{
Id: 1,
}
b, err := benchmark.New(host, protoFile, "GetByID", message, 1000, importPaths...)
@ -245,7 +246,7 @@ func Test_userExampleService_benchmark(t *testing.T) {
name: "ListByIDs",
fn: func() error {
// todo test after filling in parameters
message := &pb.ListUserExampleByIDsRequest{
message := &serverNameExampleV1.ListUserExampleByIDsRequest{
Ids: []uint64{1, 2, 3},
}
b, err := benchmark.New(host, protoFile, "ListByIDs", message, 1000, importPaths...)
@ -261,7 +262,7 @@ func Test_userExampleService_benchmark(t *testing.T) {
name: "List",
fn: func() error {
// todo test after filling in parameters
message := &pb.ListUserExampleRequest{
message := &serverNameExampleV1.ListUserExampleRequest{
Params: &types.Params{
Page: 0,
Limit: 10,

View File

@ -0,0 +1,59 @@
package service
import (
"context"
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
"github.com/zhufuyi/sponge/internal/rpcclient"
)
var _ serverNameExampleV1.UserExampleServiceLogicer = (*userExampleServiceClient)(nil)
type userExampleServiceClient struct {
userExampleServiceCli serverNameExampleV1.UserExampleServiceClient
// If required, fill in the definition of the other service client code here.
}
// NewUserExampleServiceClient creating rpc clients
func NewUserExampleServiceClient() serverNameExampleV1.UserExampleServiceLogicer {
return &userExampleServiceClient{
userExampleServiceCli: serverNameExampleV1.NewUserExampleServiceClient(rpcclient.GetServerNameExampleRPCConn()),
// If required, fill in the code to implement other service clients here.
}
}
func (c *userExampleServiceClient) Create(ctx context.Context, req *serverNameExampleV1.CreateUserExampleRequest) (*serverNameExampleV1.CreateUserExampleReply, error) {
// implement me
// If required, fill in the code to fetch data from other microservices here.
return c.userExampleServiceCli.Create(ctx, req)
}
func (c *userExampleServiceClient) DeleteByID(ctx context.Context, req *serverNameExampleV1.DeleteUserExampleByIDRequest) (*serverNameExampleV1.DeleteUserExampleByIDReply, error) {
// implement me
// If required, fill in the code to fetch data from other microservices here.
return c.userExampleServiceCli.DeleteByID(ctx, req)
}
func (c *userExampleServiceClient) UpdateByID(ctx context.Context, req *serverNameExampleV1.UpdateUserExampleByIDRequest) (*serverNameExampleV1.UpdateUserExampleByIDReply, error) {
// implement me
// If required, fill in the code to fetch data from other microservices here.
return c.userExampleServiceCli.UpdateByID(ctx, req)
}
func (c *userExampleServiceClient) GetByID(ctx context.Context, req *serverNameExampleV1.GetUserExampleByIDRequest) (*serverNameExampleV1.GetUserExampleByIDReply, error) {
// implement me
// If required, fill in the code to fetch data from other microservices here.
return c.userExampleServiceCli.GetByID(ctx, req)
}
func (c *userExampleServiceClient) ListByIDs(ctx context.Context, req *serverNameExampleV1.ListUserExampleByIDsRequest) (*serverNameExampleV1.ListUserExampleByIDsReply, error) {
// implement me
// If required, fill in the code to fetch data from other microservices here.
return c.userExampleServiceCli.ListByIDs(ctx, req)
}
func (c *userExampleServiceClient) List(ctx context.Context, req *serverNameExampleV1.ListUserExampleRequest) (*serverNameExampleV1.ListUserExampleReply, error) {
// implement me
// If required, fill in the code to fetch data from other microservices here.
return c.userExampleServiceCli.List(ctx, req)
}

View File

@ -0,0 +1,54 @@
package service
import (
"context"
"testing"
"time"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/rpcclient"
)
func TestNewUserExampleServiceClient(t *testing.T) {
err := config.Init(configs.Path("serverNameExample.yml"))
if err != nil {
t.Fatal(err)
}
go func() {
defer func() { recover() }()
rpcclient.NewServerNameExampleRPCConn()
}()
time.Sleep(time.Millisecond * 200)
cli := NewUserExampleServiceClient()
ctx := context.Background()
go func() {
reply, err := cli.Create(ctx, nil)
t.Log(reply, err)
}()
go func() {
reply, err := cli.DeleteByID(ctx, nil)
t.Log(reply, err)
}()
go func() {
reply, err := cli.UpdateByID(ctx, nil)
t.Log(reply, err)
}()
go func() {
reply, err := cli.GetByID(ctx, nil)
t.Log(reply, err)
}()
go func() {
reply, err := cli.ListByIDs(ctx, nil)
t.Log(reply, err)
}()
go func() {
reply, err := cli.List(ctx, nil)
t.Log(reply, err)
}()
time.Sleep(time.Second * 15)
}

View File

@ -4,7 +4,7 @@ import (
"testing"
"time"
pb "github.com/zhufuyi/sponge/api/serverNameExample/v1"
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
"github.com/zhufuyi/sponge/api/types"
"github.com/zhufuyi/sponge/internal/cache"
"github.com/zhufuyi/sponge/internal/dao"
@ -38,8 +38,8 @@ func newUserExampleService() *gotest.Service {
// 初始化mock service
s := gotest.NewService(d, testData)
pb.RegisterUserExampleServiceServer(s.Server, &userExampleService{
UnimplementedUserExampleServiceServer: pb.UnimplementedUserExampleServiceServer{},
serverNameExampleV1.RegisterUserExampleServiceServer(s.Server, &userExampleService{
UnimplementedUserExampleServiceServer: serverNameExampleV1.UnimplementedUserExampleServiceServer{},
iDao: d.IDao.(dao.UserExampleDao),
})
@ -48,7 +48,7 @@ func newUserExampleService() *gotest.Service {
time.Sleep(time.Millisecond * 100)
// grpc客户端
s.IServiceClient = pb.NewUserExampleServiceClient(s.GetClientConn())
s.IServiceClient = serverNameExampleV1.NewUserExampleServiceClient(s.GetClientConn())
return s
}
@ -56,21 +56,21 @@ func newUserExampleService() *gotest.Service {
func Test_userExampleService_Create(t *testing.T) {
s := newUserExampleService()
defer s.Close()
testData := &pb.CreateUserExampleRequest{}
testData := &serverNameExampleV1.CreateUserExampleRequest{}
_ = copier.Copy(testData, s.TestData.(*model.UserExample))
s.MockDao.SqlMock.ExpectBegin()
s.MockDao.SQLMock.ExpectBegin()
args := s.MockDao.GetAnyArgs(s.TestData)
s.MockDao.SqlMock.ExpectExec("INSERT INTO .*").
s.MockDao.SQLMock.ExpectExec("INSERT INTO .*").
WithArgs(args[:len(args)-1]...). // 根据实际参数数量修改
WillReturnResult(sqlmock.NewResult(1, 1))
s.MockDao.SqlMock.ExpectCommit()
s.MockDao.SQLMock.ExpectCommit()
reply, err := s.IServiceClient.(pb.UserExampleServiceClient).Create(s.Ctx, testData)
reply, err := s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).Create(s.Ctx, testData)
t.Log(err, reply.String())
// delete the templates code start
testData = &pb.CreateUserExampleRequest{
testData = &serverNameExampleV1.CreateUserExampleRequest{
Name: "foo",
Password: "f447b20a7fcbf53a5d5be013ea0b15af",
Email: "foo@bar.com",
@ -79,12 +79,12 @@ func Test_userExampleService_Create(t *testing.T) {
Age: 10,
Gender: 1,
}
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).Create(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).Create(s.Ctx, testData)
t.Log(err, reply.String())
s.MockDao.SqlMock.ExpectBegin()
s.MockDao.SqlMock.ExpectCommit()
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).Create(s.Ctx, testData)
s.MockDao.SQLMock.ExpectBegin()
s.MockDao.SQLMock.ExpectCommit()
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).Create(s.Ctx, testData)
assert.Error(t, err)
// delete the templates code end
}
@ -92,28 +92,28 @@ func Test_userExampleService_Create(t *testing.T) {
func Test_userExampleService_DeleteByID(t *testing.T) {
s := newUserExampleService()
defer s.Close()
testData := &pb.DeleteUserExampleByIDRequest{
testData := &serverNameExampleV1.DeleteUserExampleByIDRequest{
Id: s.TestData.(*model.UserExample).ID,
}
s.MockDao.SqlMock.ExpectBegin()
s.MockDao.SqlMock.ExpectExec("UPDATE .*").
s.MockDao.SQLMock.ExpectBegin()
s.MockDao.SQLMock.ExpectExec("UPDATE .*").
WithArgs(s.MockDao.AnyTime, testData.Id). // 根据测试数据数量调整
WillReturnResult(sqlmock.NewResult(int64(testData.Id), 1))
s.MockDao.SqlMock.ExpectCommit()
s.MockDao.SQLMock.ExpectCommit()
reply, err := s.IServiceClient.(pb.UserExampleServiceClient).DeleteByID(s.Ctx, testData)
reply, err := s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).DeleteByID(s.Ctx, testData)
assert.NoError(t, err)
t.Log(reply.String())
// zero id error test
testData.Id = 0
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).DeleteByID(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).DeleteByID(s.Ctx, testData)
assert.Error(t, err)
// delete error test
testData.Id = 111
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).DeleteByID(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).DeleteByID(s.Ctx, testData)
assert.Error(t, err)
}
@ -121,28 +121,28 @@ func Test_userExampleService_UpdateByID(t *testing.T) {
s := newUserExampleService()
defer s.Close()
data := s.TestData.(*model.UserExample)
testData := &pb.UpdateUserExampleByIDRequest{}
testData := &serverNameExampleV1.UpdateUserExampleByIDRequest{}
_ = copier.Copy(testData, s.TestData.(*model.UserExample))
testData.Id = data.ID
s.MockDao.SqlMock.ExpectBegin()
s.MockDao.SqlMock.ExpectExec("UPDATE .*").
s.MockDao.SQLMock.ExpectBegin()
s.MockDao.SQLMock.ExpectExec("UPDATE .*").
WithArgs(s.MockDao.AnyTime, testData.Id). // 根据测试数据数量调整
WillReturnResult(sqlmock.NewResult(int64(testData.Id), 1))
s.MockDao.SqlMock.ExpectCommit()
s.MockDao.SQLMock.ExpectCommit()
reply, err := s.IServiceClient.(pb.UserExampleServiceClient).UpdateByID(s.Ctx, testData)
reply, err := s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).UpdateByID(s.Ctx, testData)
assert.NoError(t, err)
t.Log(reply.String())
// zero id error test
testData.Id = 0
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).UpdateByID(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).UpdateByID(s.Ctx, testData)
assert.Error(t, err)
// upate error test
testData.Id = 111
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).UpdateByID(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).UpdateByID(s.Ctx, testData)
assert.Error(t, err)
}
@ -150,29 +150,29 @@ func Test_userExampleService_GetByID(t *testing.T) {
s := newUserExampleService()
defer s.Close()
data := s.TestData.(*model.UserExample)
testData := &pb.GetUserExampleByIDRequest{
testData := &serverNameExampleV1.GetUserExampleByIDRequest{
Id: data.ID,
}
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(data.ID, data.CreatedAt, data.UpdatedAt)
s.MockDao.SqlMock.ExpectQuery("SELECT .*").
s.MockDao.SQLMock.ExpectQuery("SELECT .*").
WithArgs(testData.Id).
WillReturnRows(rows)
reply, err := s.IServiceClient.(pb.UserExampleServiceClient).GetByID(s.Ctx, testData)
reply, err := s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).GetByID(s.Ctx, testData)
assert.NoError(t, err)
t.Log(reply.String())
// zero id error test
testData.Id = 0
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).GetByID(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).GetByID(s.Ctx, testData)
assert.Error(t, err)
// get error test
testData.Id = 111
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).GetByID(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).GetByID(s.Ctx, testData)
assert.Error(t, err)
}
@ -180,29 +180,24 @@ func Test_userExampleService_ListByIDs(t *testing.T) {
s := newUserExampleService()
defer s.Close()
data := s.TestData.(*model.UserExample)
testData := &pb.ListUserExampleByIDsRequest{
testData := &serverNameExampleV1.ListUserExampleByIDsRequest{
Ids: []uint64{data.ID},
}
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(data.ID, data.CreatedAt, data.UpdatedAt)
s.MockDao.SqlMock.ExpectQuery("SELECT .*").
s.MockDao.SQLMock.ExpectQuery("SELECT .*").
WithArgs(data.ID).
WillReturnRows(rows)
reply, err := s.IServiceClient.(pb.UserExampleServiceClient).ListByIDs(s.Ctx, testData)
reply, err := s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).ListByIDs(s.Ctx, testData)
assert.NoError(t, err)
t.Log(reply.String())
// zero id error test
//testData.Ids = []uint64{0}
//reply, err = s.IServiceClient.(pb.UserExampleServiceClient).ListByIDs(s.Ctx, testData)
//assert.Error(t, err)
// get error test
testData.Ids = []uint64{111}
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).ListByIDs(s.Ctx, testData)
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).ListByIDs(s.Ctx, testData)
assert.Error(t, err)
}
@ -214,9 +209,9 @@ func Test_userExampleService_List(t *testing.T) {
rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}).
AddRow(testData.ID, testData.CreatedAt, testData.UpdatedAt)
s.MockDao.SqlMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
s.MockDao.SQLMock.ExpectQuery("SELECT .*").WillReturnRows(rows)
reply, err := s.IServiceClient.(pb.UserExampleServiceClient).List(s.Ctx, &pb.ListUserExampleRequest{
reply, err := s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).List(s.Ctx, &serverNameExampleV1.ListUserExampleRequest{
Params: &types.Params{
Page: 0,
Limit: 10,
@ -227,7 +222,7 @@ func Test_userExampleService_List(t *testing.T) {
t.Log(reply.String())
// get error test
reply, err = s.IServiceClient.(pb.UserExampleServiceClient).List(s.Ctx, &pb.ListUserExampleRequest{
reply, err = s.IServiceClient.(serverNameExampleV1.UserExampleServiceClient).List(s.Ctx, &serverNameExampleV1.ListUserExampleRequest{
Params: &types.Params{
Page: 0,
Limit: 10,

View File

@ -37,12 +37,39 @@ function listFiles(){
# 获取所有proto文件路径
listFiles $protoBasePath
# 生成文件 *_pb.go, *_grpc_pb.go, *_pb.validate.go文件在同一目录
# 生成文件 *_pb.go, *_grpc_pb.go
protoc --proto_path=. --proto_path=./third_party \
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
--validate_out=lang=go:. --validate_opt=paths=source_relative \
$allProtoFiles
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
$allProtoFiles
checkResult $?
# 生成文件*_pb.validate.go
protoc --proto_path=. --proto_path=./third_party \
--validate_out=lang=go:. --validate_opt=paths=source_relative \
$allProtoFiles
checkResult $?
# 生成swagger文档所有文件合并到docs/apis.swagger.json
protoc --proto_path=. --proto_path=./third_party \
--openapiv2_out=. --openapiv2_opt=logtostderr=true --openapiv2_opt=allow_merge=true --openapiv2_opt=merge_file_name=docs/apis.json \
$allProtoFiles
checkResult $?
# 对*_pb.go字段嵌入tag
protoc --proto_path=. --proto_path=./third_party \
--gotag_out=:. --gotag_opt=paths=source_relative \
$allProtoFiles
checkResult $?
# 生成_*router.pb.go
protoc --proto_path=. --proto_path=./third_party \
--go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugins=service \
$allProtoFiles
checkResult $?