mirror of
https://github.com/zhufuyi/sponge.git
synced 2025-10-17 22:30:46 +08:00
adjustment code
This commit is contained in:
1
Makefile
1
Makefile
@@ -14,6 +14,7 @@ install:
|
||||
go install github.com/envoyproxy/protoc-gen-validate@latest
|
||||
go install github.com/srikrsna/protoc-gen-gotag@latest
|
||||
go install github.com/zhufuyi/sponge/cmd/protoc-gen-go-gin@latest
|
||||
go install github.com/zhufuyi/sponge/cmd/protoc-gen-go-rpc-tmpl@latest
|
||||
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
|
||||
go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@latest
|
||||
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
@@ -79,13 +79,13 @@ type CreateUserExampleRequest struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // 名称
|
||||
Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` // 邮件
|
||||
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` // 密码
|
||||
Phone string `protobuf:"bytes,4,opt,name=phone,proto3" json:"phone,omitempty"` // 手机号码
|
||||
Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
|
||||
Age int32 `protobuf:"varint,6,opt,name=age,proto3" json:"age,omitempty"` // 年龄
|
||||
Gender GenderType `protobuf:"varint,7,opt,name=gender,proto3,enum=api.serverNameExample.v1.GenderType" json:"gender,omitempty"` // 性别,0:未知,1:男,2:女
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // name
|
||||
Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` // email
|
||||
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` // password
|
||||
Phone string `protobuf:"bytes,4,opt,name=phone,proto3" json:"phone,omitempty"` // phone number
|
||||
Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // avatar
|
||||
Age int32 `protobuf:"varint,6,opt,name=age,proto3" json:"age,omitempty"` // age
|
||||
Gender GenderType `protobuf:"varint,7,opt,name=gender,proto3,enum=api.serverNameExample.v1.GenderType" json:"gender,omitempty"` // gender, 1:Male, 2:Female, other values:unknown
|
||||
}
|
||||
|
||||
func (x *CreateUserExampleRequest) Reset() {
|
||||
@@ -307,15 +307,15 @@ type UpdateUserExampleByIDRequest struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty" uri:"id"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // 名称
|
||||
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` // 邮件
|
||||
Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` // 密码
|
||||
Phone string `protobuf:"bytes,5,opt,name=phone,proto3" json:"phone,omitempty"` // 手机号码
|
||||
Avatar string `protobuf:"bytes,6,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
|
||||
Age int32 `protobuf:"varint,7,opt,name=age,proto3" json:"age,omitempty"` // 年龄
|
||||
Gender GenderType `protobuf:"varint,8,opt,name=gender,proto3,enum=api.serverNameExample.v1.GenderType" json:"gender,omitempty"` // 性别,1:男,2:女
|
||||
Status int32 `protobuf:"varint,9,opt,name=status,proto3" json:"status,omitempty"` // 账号状态
|
||||
LoginAt int64 `protobuf:"varint,10,opt,name=login_at,json=loginAt,proto3" json:"login_at,omitempty"` // 登录时间戳
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // name
|
||||
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` // email
|
||||
Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` // password
|
||||
Phone string `protobuf:"bytes,5,opt,name=phone,proto3" json:"phone,omitempty"` // phone number
|
||||
Avatar string `protobuf:"bytes,6,opt,name=avatar,proto3" json:"avatar,omitempty"` // avatar
|
||||
Age int32 `protobuf:"varint,7,opt,name=age,proto3" json:"age,omitempty"` // age
|
||||
Gender GenderType `protobuf:"varint,8,opt,name=gender,proto3,enum=api.serverNameExample.v1.GenderType" json:"gender,omitempty"` // gender, 1:Male, 2:Female, other values:unknown
|
||||
Status int32 `protobuf:"varint,9,opt,name=status,proto3" json:"status,omitempty"` // account status
|
||||
LoginAt int64 `protobuf:"varint,10,opt,name=login_at,json=loginAt,proto3" json:"login_at,omitempty"` // login timestamp
|
||||
}
|
||||
|
||||
func (x *UpdateUserExampleByIDRequest) Reset() {
|
||||
@@ -464,16 +464,16 @@ type UserExample struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // 名称
|
||||
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` // 邮件
|
||||
Phone string `protobuf:"bytes,4,opt,name=phone,proto3" json:"phone,omitempty"` // 手机号码
|
||||
Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
|
||||
Age int32 `protobuf:"varint,6,opt,name=age,proto3" json:"age,omitempty"` // 年龄
|
||||
Gender GenderType `protobuf:"varint,7,opt,name=gender,proto3,enum=api.serverNameExample.v1.GenderType" json:"gender,omitempty"` // 性别,1:男,2:女
|
||||
Status int32 `protobuf:"varint,8,opt,name=status,proto3" json:"status,omitempty"` // 账号状态
|
||||
LoginAt int64 `protobuf:"varint,9,opt,name=login_at,json=loginAt,proto3" json:"login_at,omitempty"` // 登录时间戳
|
||||
CreatedAt int64 `protobuf:"varint,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // 创建时间
|
||||
UpdatedAt int64 `protobuf:"varint,11,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // 更新时间
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // name
|
||||
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` // email
|
||||
Phone string `protobuf:"bytes,4,opt,name=phone,proto3" json:"phone,omitempty"` // phone number
|
||||
Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // avatar
|
||||
Age int32 `protobuf:"varint,6,opt,name=age,proto3" json:"age,omitempty"` // age
|
||||
Gender GenderType `protobuf:"varint,7,opt,name=gender,proto3,enum=api.serverNameExample.v1.GenderType" json:"gender,omitempty"` // gender, 1:Male, 2:Female, other values:unknown
|
||||
Status int32 `protobuf:"varint,8,opt,name=status,proto3" json:"status,omitempty"` // account status
|
||||
LoginAt int64 `protobuf:"varint,9,opt,name=login_at,json=loginAt,proto3" json:"login_at,omitempty"` // login timestamp
|
||||
CreatedAt int64 `protobuf:"varint,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // creation time
|
||||
UpdatedAt int64 `protobuf:"varint,11,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // update time
|
||||
}
|
||||
|
||||
func (x *UserExample) Reset() {
|
||||
@@ -996,105 +996,108 @@ var file_api_serverNameExample_v1_userExample_proto_rawDesc = []byte{
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2a, 0x2f, 0x0a, 0x0a, 0x47, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54,
|
||||
0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00,
|
||||
0x12, 0x08, 0x0a, 0x04, 0x4d, 0x41, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x45,
|
||||
0x4d, 0x41, 0x4c, 0x45, 0x10, 0x02, 0x32, 0xff, 0x0a, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x45,
|
||||
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xd0, 0x01,
|
||||
0x4d, 0x41, 0x4c, 0x45, 0x10, 0x02, 0x32, 0xb3, 0x0b, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x45,
|
||||
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xde, 0x01,
|
||||
0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x32, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x60,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x6e,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x01, 0x2a, 0x92, 0x41,
|
||||
0x3f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x11,
|
||||
0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x1a, 0x1d, 0xe6, 0x8f, 0x90, 0xe4, 0xba, 0xa4, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0xe5,
|
||||
0x88, 0x9b, 0xe5, 0xbb, 0xba, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x12, 0xda, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x12,
|
||||
0x36, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x5e, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75,
|
||||
0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92,
|
||||
0x41, 0x3b, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12,
|
||||
0x11, 0xe5, 0x88, 0xa0, 0xe9, 0x99, 0xa4, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x1a, 0x19, 0xe6, 0xa0, 0xb9, 0xe6, 0x8d, 0xae, 0x69, 0x64, 0xe5, 0x88, 0xa0, 0xe9,
|
||||
0x99, 0xa4, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0xe9, 0x01,
|
||||
0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x12, 0x36, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x6d, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x1d, 0x1a, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72,
|
||||
0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x01, 0x2a, 0x92,
|
||||
0x41, 0x47, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12,
|
||||
0x17, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0x1a, 0x1f, 0xe6, 0xa0, 0xb9, 0xe6, 0x8d, 0xae,
|
||||
0x69, 0x64, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0x12, 0xdd, 0x01, 0x0a, 0x07, 0x47, 0x65,
|
||||
0x74, 0x42, 0x79, 0x49, 0x44, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x4d, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x12,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x1a, 0x2a, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72,
|
||||
0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0xda,
|
||||
0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x12, 0x36, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55,
|
||||
0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42,
|
||||
0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x5e, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65,
|
||||
0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92, 0x41, 0x3b,
|
||||
0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x12, 0x64,
|
||||
0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x1a, 0x18, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x62, 0x79, 0x20, 0x69, 0x64, 0x12, 0xef, 0x01, 0x0a, 0x0a,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x12, 0x36, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x6a, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75,
|
||||
0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92,
|
||||
0x41, 0x47, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12,
|
||||
0x17, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0xe8, 0xaf, 0xa6, 0xe6, 0x83, 0x85, 0x1a, 0x1f, 0xe6, 0xa0, 0xb9, 0xe6, 0x8d, 0xae,
|
||||
0x69, 0x64, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0xe8, 0xaf, 0xa6, 0xe6, 0x83, 0x85, 0x12, 0x8e, 0x02, 0x0a, 0x09, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x42, 0x79, 0x49, 0x44, 0x73, 0x12, 0x35, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33,
|
||||
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
|
||||
0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42,
|
||||
0x79, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d,
|
||||
0x1a, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x01, 0x2a, 0x92, 0x41, 0x4d,
|
||||
0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x12, 0x75,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x1a, 0x2a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x12, 0xdb, 0x01,
|
||||
0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, 0x44, 0x12, 0x33, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45,
|
||||
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
|
||||
0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x70, 0x6c,
|
||||
0x79, 0x22, 0x68, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x7b,
|
||||
0x69, 0x64, 0x7d, 0x92, 0x41, 0x45, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x12, 0x17, 0x67, 0x65, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x1d, 0x67, 0x65,
|
||||
0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x64, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x62, 0x79, 0x20, 0x69, 0x64, 0x12, 0xa5, 0x02, 0x0a, 0x09,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x49, 0x44, 0x73, 0x12, 0x35, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x33, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x73,
|
||||
0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0xab, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x64, 0x73, 0x3a, 0x01, 0x2a, 0x92, 0x41, 0x84, 0x01, 0x0a,
|
||||
0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x2f, 0x67, 0x65,
|
||||
0x74, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x72,
|
||||
0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e,
|
||||
0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x64, 0x73, 0x1a, 0x44, 0x67,
|
||||
0x65, 0x74, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65,
|
||||
0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f,
|
||||
0x6e, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x64, 0x73, 0x20, 0x75,
|
||||
0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x20, 0x72, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0xe6, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x30, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72,
|
||||
0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45,
|
||||
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x73, 0x52, 0x65,
|
||||
0x70, 0x6c, 0x79, 0x22, 0x94, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x73, 0x2f, 0x69, 0x64, 0x73, 0x3a, 0x01, 0x2a, 0x92, 0x41, 0x6e, 0x0a, 0x0b, 0x75, 0x73,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x25, 0xe6, 0xa0, 0xb9, 0xe6, 0x8d,
|
||||
0xae, 0xe5, 0xa4, 0x9a, 0xe4, 0xb8, 0xaa, 0x69, 0x64, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0x75,
|
||||
0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8,
|
||||
0x1a, 0x38, 0xe4, 0xbd, 0xbf, 0xe7, 0x94, 0xa8, 0x70, 0x6f, 0x73, 0x74, 0xe8, 0xaf, 0xb7, 0xe6,
|
||||
0xb1, 0x82, 0xef, 0xbc, 0x8c, 0xe6, 0xa0, 0xb9, 0xe6, 0x8d, 0xae, 0xe5, 0xa4, 0x9a, 0xe4, 0xb8,
|
||||
0xaa, 0x69, 0x64, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8, 0x12, 0xdb, 0x01, 0x0a, 0x04, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x12, 0x30, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x71, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x14, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x92, 0x41, 0x4f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45,
|
||||
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x17, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0x75, 0x73,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8, 0x1a,
|
||||
0x27, 0xe4, 0xbd, 0xbf, 0xe7, 0x94, 0xa8, 0x70, 0x6f, 0x73, 0x74, 0xe8, 0xaf, 0xb7, 0xe6, 0xb1,
|
||||
0x82, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8, 0x42, 0x98, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x7a, 0x68, 0x75, 0x66, 0x75, 0x79, 0x69, 0x2f,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x67, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b,
|
||||
0x76, 0x31, 0x92, 0x41, 0x5e, 0x12, 0x24, 0x0a, 0x1a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x61, 0x70, 0x69, 0x20, 0x64,
|
||||
0x6f, 0x63, 0x73, 0x32, 0x06, 0x76, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x1a, 0x0e, 0x6c, 0x6f, 0x63,
|
||||
0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32,
|
||||
0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f,
|
||||
0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a,
|
||||
0x73, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x7c,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0x92,
|
||||
0x41, 0x5a, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12,
|
||||
0x1a, 0x67, 0x65, 0x74, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x75,
|
||||
0x73, 0x65, 0x72, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x1a, 0x2f, 0x67, 0x65, 0x74,
|
||||
0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x72, 0x45,
|
||||
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20,
|
||||
0x70, 0x6f, 0x73, 0x74, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x98, 0x01, 0x5a,
|
||||
0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x7a, 0x68, 0x75, 0x66,
|
||||
0x75, 0x79, 0x69, 0x2f, 0x73, 0x70, 0x6f, 0x6e, 0x67, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x92, 0x41, 0x5e, 0x12, 0x24, 0x0a, 0x1a, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x61,
|
||||
0x70, 0x69, 0x20, 0x64, 0x6f, 0x63, 0x73, 0x32, 0x06, 0x76, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x1a,
|
||||
0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x38, 0x30, 0x38, 0x30, 0x2a,
|
||||
0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@@ -13,7 +13,7 @@ import "tagger/tagger.proto";
|
||||
|
||||
option go_package = "github.com/zhufuyi/sponge/api/serverNameExample/v1;v1";
|
||||
|
||||
// 生成*.swagger.json文档的默认设置
|
||||
// default settings for generating *.swagger.json documents
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
host: "localhost:8080"
|
||||
base_path: ""
|
||||
@@ -34,8 +34,8 @@ service userExampleService {
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "创建userExample",
|
||||
description: "提交信息创建userExample",
|
||||
summary: "create userExample",
|
||||
description: "submit information to create a userExample",
|
||||
tags: "userExample",
|
||||
};
|
||||
}
|
||||
@@ -45,8 +45,8 @@ service userExampleService {
|
||||
delete: "/api/v1/userExample/{id}"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "删除userExample",
|
||||
description: "根据id删除userExample",
|
||||
summary: "delete userExample",
|
||||
description: "delete userExample by id",
|
||||
tags: "userExample",
|
||||
};
|
||||
}
|
||||
@@ -57,8 +57,8 @@ service userExampleService {
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "更新userExample信息",
|
||||
description: "根据id更新userExample信息",
|
||||
summary: "update userExample",
|
||||
description: "update userExample information based on id",
|
||||
tags: "userExample",
|
||||
};
|
||||
}
|
||||
@@ -68,8 +68,8 @@ service userExampleService {
|
||||
get: "/api/v1/userExample/{id}"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "获取userExample详情",
|
||||
description: "根据id获取userExample详情",
|
||||
summary: "get userExample details",
|
||||
description: "get userExample details by id",
|
||||
tags: "userExample",
|
||||
};
|
||||
}
|
||||
@@ -80,8 +80,8 @@ service userExampleService {
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "根据多个id获取userExample列表",
|
||||
description: "使用post请求,根据多个id获取userExample列表",
|
||||
summary: "get a list of userExample based on multiple ids",
|
||||
description: "get a list of userExample based on multiple ids using a post request",
|
||||
tags: "userExample",
|
||||
};
|
||||
}
|
||||
@@ -92,8 +92,8 @@ service userExampleService {
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "获取userExample列表",
|
||||
description: "使用post请求获取userExample列表",
|
||||
summary: "get a list of userExamples",
|
||||
description: "get a list of userExamples using a post request",
|
||||
tags: "userExample",
|
||||
};
|
||||
}
|
||||
@@ -105,17 +105,17 @@ enum GenderType {
|
||||
FEMALE = 2;
|
||||
};
|
||||
|
||||
// 如果使用grpc gateway,建议添加target,请求时可以自动校验,
|
||||
// 例如 string email = 2 [(tagger.tags) = "binding:\"email\"" ];
|
||||
// if using a grpc gateway, it is recommended to add target, which can be automatically verified on request.
|
||||
// example: 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]; // 邮件
|
||||
string password = 3 [(validate.rules).string.min_len = 10]; // 密码
|
||||
string phone=4 [(validate.rules).string = {pattern: "^1[3456789]\\d{9}$"}]; // 手机号码
|
||||
string avatar=5 [(validate.rules).string.uri = true]; // 头像
|
||||
int32 age=6 [(validate.rules).int32 = {gte:0, lte: 120}]; // 年龄
|
||||
GenderType gender=7 [(validate.rules).enum.defined_only = true]; // 性别,0:未知,1:男,2:女
|
||||
string name = 1 [(validate.rules).string.min_len = 2]; // name
|
||||
string email = 2 [(validate.rules).string.email = true]; // email
|
||||
string password = 3 [(validate.rules).string.min_len = 10]; // password
|
||||
string phone=4 [(validate.rules).string = {pattern: "^1[3456789]\\d{9}$"}]; // phone number
|
||||
string avatar=5 [(validate.rules).string.uri = true]; // avatar
|
||||
int32 age=6 [(validate.rules).int32 = {gte:0, lte: 120}]; // age
|
||||
GenderType gender=7 [(validate.rules).enum.defined_only = true]; // gender, 1:Male, 2:Female, other values:unknown
|
||||
}
|
||||
|
||||
message CreateUserExampleReply {
|
||||
@@ -132,15 +132,15 @@ message DeleteUserExampleByIDReply {
|
||||
|
||||
message UpdateUserExampleByIDRequest {
|
||||
uint64 id = 1 [(validate.rules).uint64.gte = 1 , (tagger.tags) = "uri:\"id\"" ];
|
||||
string name = 2; // 名称
|
||||
string email = 3; // 邮件
|
||||
string password = 4; // 密码
|
||||
string phone=5; // 手机号码
|
||||
string avatar=6; // 头像
|
||||
int32 age=7; // 年龄
|
||||
GenderType gender=8; // 性别,1:男,2:女
|
||||
int32 status=9; // 账号状态
|
||||
int64 login_at=10; // 登录时间戳
|
||||
string name = 2; // name
|
||||
string email = 3; // email
|
||||
string password = 4; // password
|
||||
string phone=5; // phone number
|
||||
string avatar=6; // avatar
|
||||
int32 age=7; // age
|
||||
GenderType gender=8; // gender, 1:Male, 2:Female, other values:unknown
|
||||
int32 status=9; // account status
|
||||
int64 login_at=10; // login timestamp
|
||||
}
|
||||
|
||||
message UpdateUserExampleByIDReply {
|
||||
@@ -149,16 +149,16 @@ message UpdateUserExampleByIDReply {
|
||||
|
||||
message UserExample {
|
||||
uint64 id = 1;
|
||||
string name = 2; // 名称
|
||||
string email = 3; // 邮件
|
||||
string phone=4; // 手机号码
|
||||
string avatar=5; // 头像
|
||||
int32 age=6; // 年龄
|
||||
GenderType gender=7; // 性别,1:男,2:女
|
||||
int32 status=8; // 账号状态
|
||||
int64 login_at=9; // 登录时间戳
|
||||
int64 created_at=10; // 创建时间
|
||||
int64 updated_at=11; // 更新时间
|
||||
string name = 2; // name
|
||||
string email = 3; // email
|
||||
string phone=4; // phone number
|
||||
string avatar=5; // avatar
|
||||
int32 age=6; // age
|
||||
GenderType gender=7; // gender, 1:Male, 2:Female, other values:unknown
|
||||
int32 status=8; // account status
|
||||
int64 login_at=9; // login timestamp
|
||||
int64 created_at=10; // creation time
|
||||
int64 updated_at=11; // update time
|
||||
}
|
||||
|
||||
message GetUserExampleByIDRequest {
|
||||
|
@@ -25,10 +25,10 @@ type Column struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // 列名
|
||||
Exp string `protobuf:"bytes,2,opt,name=exp,proto3" json:"exp,omitempty"` // 表达式,值为空时默认为=,有=、!=、>、>=、<、<=、like七种类型
|
||||
Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` // 列值
|
||||
Logic string `protobuf:"bytes,4,opt,name=logic,proto3" json:"logic,omitempty"` // 逻辑类型,值为空时默认为and,只有&(and)、||(or)两种类型
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // column name
|
||||
Exp string `protobuf:"bytes,2,opt,name=exp,proto3" json:"exp,omitempty"` // expressions, which default to = when the value is null, have =, ! =, >, >=, <, <=, like
|
||||
Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` // column value
|
||||
Logic string `protobuf:"bytes,4,opt,name=logic,proto3" json:"logic,omitempty"` // logical type, defaults to and when value is null, only &(and), ||(or)
|
||||
}
|
||||
|
||||
func (x *Column) Reset() {
|
||||
@@ -96,10 +96,10 @@ type Params struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` // 页码,从0开始
|
||||
Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` // 每页行数
|
||||
Sort string `protobuf:"bytes,3,opt,name=sort,proto3" json:"sort,omitempty"` // 排序字段,多列排序用逗号分隔
|
||||
Columns []*Column `protobuf:"bytes,4,rep,name=columns,proto3" json:"columns,omitempty"` // 查询条件
|
||||
Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` // page number, starting from 0
|
||||
Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` // lines per page
|
||||
Sort string `protobuf:"bytes,3,opt,name=sort,proto3" json:"sort,omitempty"` // sorted fields, multi-column sorting separated by commas
|
||||
Columns []*Column `protobuf:"bytes,4,rep,name=columns,proto3" json:"columns,omitempty"` // query conditions
|
||||
}
|
||||
|
||||
func (x *Params) Reset() {
|
||||
|
@@ -4,16 +4,16 @@ package types;
|
||||
|
||||
option go_package = "github.com/zhufuyi/sponge/api/types;types";
|
||||
|
||||
message Column {
|
||||
string name=1; // 列名
|
||||
string exp=2; // 表达式,值为空时默认为=,有=、!=、>、>=、<、<=、like七种类型
|
||||
string value=3; // 列值
|
||||
string logic=4; // 逻辑类型,值为空时默认为and,只有&(and)、||(or)两种类型
|
||||
message Params {
|
||||
int32 page = 1; // page number, starting from 0
|
||||
int32 limit = 2; // lines per page
|
||||
string sort = 3; // sorted fields, multi-column sorting separated by commas
|
||||
repeated Column columns = 4; // query conditions
|
||||
}
|
||||
|
||||
message Params {
|
||||
int32 page = 1; // 页码,从0开始
|
||||
int32 limit = 2; // 每页行数
|
||||
string sort = 3; // 排序字段,多列排序用逗号分隔
|
||||
repeated Column columns = 4; // 查询条件
|
||||
message Column {
|
||||
string name=1; // column name
|
||||
string exp=2; // expressions, which default to = when the value is null, have =, ! =, >, >=, <, <=, like
|
||||
string value=3; // column value
|
||||
string logic=4; // logical type, defaults to and when value is null, only &(and), ||(or)
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ const (
|
||||
|
||||
var methodSets = make(map[string]int)
|
||||
|
||||
// GenerateFile generates a _router.pb.go file.
|
||||
// GenerateFile generates a *_router.pb.go file.
|
||||
func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile {
|
||||
if len(file.Services) == 0 {
|
||||
return nil
|
||||
@@ -74,7 +74,7 @@ func genService(file *protogen.File, g *protogen.GeneratedFile, s *protogen.Serv
|
||||
func genMethod(m *protogen.Method) []*method {
|
||||
var methods []*method
|
||||
|
||||
// 存在 http rule 配置
|
||||
// http rule config
|
||||
rule, ok := proto.GetExtension(m.Desc.Options(), annotations.E_Http).(*annotations.HttpRule)
|
||||
if rule != nil && ok {
|
||||
for _, bind := range rule.AdditionalBindings {
|
||||
@@ -84,14 +84,13 @@ func genMethod(m *protogen.Method) []*method {
|
||||
return methods
|
||||
}
|
||||
|
||||
// 不存在走默认流程
|
||||
// default http method mapping
|
||||
methods = append(methods, defaultMethod(m))
|
||||
return methods
|
||||
}
|
||||
|
||||
// defaultMethodPath 根据函数名生成 http 路由
|
||||
// 例如: GetBlogArticles ==> get: /blog/articles
|
||||
// 如果方法名首个单词不是 http method 映射,那么默认返回 POST
|
||||
// defaultMethodPath generates an http route based on the function name
|
||||
// If the first word of the method name is not an http method mapping, then POST is returned by default
|
||||
func defaultMethod(m *protogen.Method) *method {
|
||||
names := strings.Split(toSnakeCase(m.GoName), "_")
|
||||
var (
|
||||
@@ -212,11 +211,11 @@ func (s *tmplField) execute() string {
|
||||
|
||||
type method struct {
|
||||
Name string // SayHello
|
||||
Num int // 一个 rpc 方法可以对应多个 http 请求
|
||||
Num int // one rpc method can correspond to multiple http requests
|
||||
Request string // SayHelloReq
|
||||
Reply string // SayHelloResp
|
||||
// http_rule
|
||||
Path string // 路由
|
||||
Path string // rule
|
||||
Method string // HTTP Method
|
||||
Body string
|
||||
ResponseBody string
|
||||
@@ -227,7 +226,7 @@ func (m *method) HandlerName() string {
|
||||
return fmt.Sprintf("%s_%d", m.Name, m.Num)
|
||||
}
|
||||
|
||||
// HasPathParams 是否包含路由参数
|
||||
// HasPathParams whether to include routing parameters
|
||||
func (m *method) HasPathParams() bool {
|
||||
paths := strings.Split(m.Path, "/")
|
||||
for _, p := range paths {
|
||||
@@ -238,7 +237,7 @@ func (m *method) HasPathParams() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// initPathParams 转换参数路由 {xx} --> :xx
|
||||
// initPathParams conversion parameter routing {xx} --> :xx
|
||||
func (m *method) initPathParams() {
|
||||
paths := strings.Split(m.Path, "/")
|
||||
for i, p := range paths {
|
||||
|
@@ -23,23 +23,23 @@ var (
|
||||
enableConfigCenter bool
|
||||
)
|
||||
|
||||
// Config 初始化配置
|
||||
// Config initial app configuration
|
||||
func Config() {
|
||||
initConfig()
|
||||
cfg := config.Get()
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
_, _ = logger.Init(
|
||||
logger.WithLevel(cfg.Logger.Level),
|
||||
logger.WithFormat(cfg.Logger.Format),
|
||||
logger.WithSave(cfg.Logger.IsSave),
|
||||
)
|
||||
|
||||
// 初始化数据库
|
||||
// initializing database
|
||||
model.InitMysql()
|
||||
model.InitCache(cfg.App.CacheType)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
if cfg.App.EnableTracing {
|
||||
tracer.InitWithConfig(
|
||||
cfg.App.Name,
|
||||
@@ -51,13 +51,12 @@ func Config() {
|
||||
)
|
||||
}
|
||||
|
||||
// 初始化打印系统和进程资源
|
||||
// initializing the print system and process resources
|
||||
if cfg.App.EnableStat {
|
||||
stat.Init(stat.WithLog(logger.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
func initConfig() {
|
||||
flag.StringVar(&version, "version", "", "service Version Number")
|
||||
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
|
||||
@@ -66,7 +65,8 @@ func initConfig() {
|
||||
flag.Parse()
|
||||
|
||||
if enableConfigCenter {
|
||||
// 从配置中心获取配置(先获取nacos配置,再根据nacos配置中心读取服务配置)
|
||||
// get the configuration from the configuration center (first get the nacos configuration,
|
||||
// then read the service configuration according to the nacos configuration center)
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample_cc.yml")
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func initConfig() {
|
||||
}
|
||||
config.Set(appConfig)
|
||||
} else {
|
||||
// 从本地配置文件获取配置
|
||||
// get configuration from local configuration file
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample.yml")
|
||||
}
|
||||
|
@@ -11,28 +11,28 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/tracer"
|
||||
)
|
||||
|
||||
// RegisterClose 注册app需要释放的资源
|
||||
// RegisterClose register for released resources
|
||||
func RegisterClose(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, s := range servers {
|
||||
closes = append(closes, s.Stop)
|
||||
}
|
||||
|
||||
// 关闭mysql
|
||||
// close mysql
|
||||
closes = append(closes, func() error {
|
||||
return model.CloseMysql()
|
||||
})
|
||||
|
||||
// 关闭redis
|
||||
// close redis
|
||||
if config.Get().App.CacheType == "redis" {
|
||||
closes = append(closes, func() error {
|
||||
return model.CloseRedis()
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭trace
|
||||
// close tracing
|
||||
if config.Get().App.EnableTracing {
|
||||
closes = append(closes, func() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
|
||||
|
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
|
||||
)
|
||||
|
||||
// RegisterServers 注册app服务
|
||||
// RegisterServers register for the app service
|
||||
func RegisterServers() []app.IServer {
|
||||
var cfg = config.Get()
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建grpc服务
|
||||
// creating grpc service
|
||||
grpcAddr := ":" + strconv.Itoa(cfg.Grpc.Port)
|
||||
grpcRegistry, grpcInstance := registryService("grpc", cfg.App.Host, cfg.Grpc.Port)
|
||||
grpcServer := server.NewGRPCServer(grpcAddr,
|
||||
@@ -38,7 +38,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -50,7 +50,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -62,7 +62,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -23,19 +23,19 @@ var (
|
||||
enableConfigCenter bool
|
||||
)
|
||||
|
||||
// Config 初始化配置
|
||||
// Config initial app configuration
|
||||
func Config() {
|
||||
initConfig()
|
||||
cfg := config.Get()
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
_, _ = logger.Init(
|
||||
logger.WithLevel(cfg.Logger.Level),
|
||||
logger.WithFormat(cfg.Logger.Format),
|
||||
logger.WithSave(cfg.Logger.IsSave),
|
||||
)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
if cfg.App.EnableTracing {
|
||||
tracer.InitWithConfig(
|
||||
cfg.App.Name,
|
||||
@@ -47,16 +47,15 @@ func Config() {
|
||||
)
|
||||
}
|
||||
|
||||
// 初始化rpc服务连接
|
||||
// initializing the rpc service connection
|
||||
rpcclient.NewServerNameExampleRPCConn()
|
||||
|
||||
// 初始化打印系统和进程资源
|
||||
// initializing the print system and process resources
|
||||
if cfg.App.EnableStat {
|
||||
stat.Init(stat.WithLog(logger.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
func initConfig() {
|
||||
flag.StringVar(&version, "version", "", "service Version Number")
|
||||
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
|
||||
@@ -65,7 +64,8 @@ func initConfig() {
|
||||
flag.Parse()
|
||||
|
||||
if enableConfigCenter {
|
||||
// 从配置中心获取配置(先获取nacos配置,再根据nacos配置中心读取服务配置)
|
||||
// get the configuration from the configuration center (first get the nacos configuration,
|
||||
// then read the service configuration according to the nacos configuration center)
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample_cc.yml")
|
||||
}
|
||||
@@ -85,7 +85,7 @@ func initConfig() {
|
||||
}
|
||||
config.Set(appConfig)
|
||||
} else {
|
||||
// 从本地配置文件获取配置
|
||||
// get configuration from local configuration file
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample.yml")
|
||||
}
|
||||
|
@@ -11,21 +11,21 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/tracer"
|
||||
)
|
||||
|
||||
// RegisterClose 注册app需要释放的资源
|
||||
// RegisterClose register for released resources
|
||||
func RegisterClose(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, s := range servers {
|
||||
closes = append(closes, s.Stop)
|
||||
}
|
||||
|
||||
// 关闭rpc client连接
|
||||
// close the rpc client connection
|
||||
closes = append(closes, func() error {
|
||||
return rpcclient.CloseServerNameExampleRPCConn()
|
||||
})
|
||||
|
||||
// 关闭trace
|
||||
// close tracing
|
||||
if config.Get().App.EnableTracing {
|
||||
closes = append(closes, func() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
|
||||
|
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
|
||||
)
|
||||
|
||||
// RegisterServers 注册app服务
|
||||
// RegisterServers register for the app service
|
||||
func RegisterServers() []app.IServer {
|
||||
var cfg = config.Get()
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建http服务
|
||||
// creating http service
|
||||
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
|
||||
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
|
||||
httpServer := server.NewHTTPServer_pbExample(httpAddr,
|
||||
@@ -39,7 +39,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -51,7 +51,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -63,7 +63,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -24,23 +24,23 @@ var (
|
||||
enableConfigCenter bool
|
||||
)
|
||||
|
||||
// Config 初始化配置
|
||||
// Config initial app configuration
|
||||
func Config() {
|
||||
initConfig()
|
||||
cfg := config.Get()
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
_, _ = logger.Init(
|
||||
logger.WithLevel(cfg.Logger.Level),
|
||||
logger.WithFormat(cfg.Logger.Format),
|
||||
logger.WithSave(cfg.Logger.IsSave),
|
||||
)
|
||||
|
||||
// 初始化数据库
|
||||
// initializing database
|
||||
//model.InitMysql()
|
||||
//model.InitCache(cfg.App.CacheType)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
if cfg.App.EnableTracing {
|
||||
tracer.InitWithConfig(
|
||||
cfg.App.Name,
|
||||
@@ -52,13 +52,12 @@ func Config() {
|
||||
)
|
||||
}
|
||||
|
||||
// 初始化打印系统和进程资源
|
||||
// initializing the print system and process resources
|
||||
if cfg.App.EnableStat {
|
||||
stat.Init(stat.WithLog(logger.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
func initConfig() {
|
||||
flag.StringVar(&version, "version", "", "service Version Number")
|
||||
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
|
||||
@@ -67,7 +66,8 @@ func initConfig() {
|
||||
flag.Parse()
|
||||
|
||||
if enableConfigCenter {
|
||||
// 从配置中心获取配置(先获取nacos配置,再根据nacos配置中心读取服务配置)
|
||||
// get the configuration from the configuration center (first get the nacos configuration,
|
||||
// then read the service configuration according to the nacos configuration center)
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample_cc.yml")
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func initConfig() {
|
||||
}
|
||||
config.Set(appConfig)
|
||||
} else {
|
||||
// 从本地配置文件获取配置
|
||||
// get configuration from local configuration file
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample.yml")
|
||||
}
|
||||
|
@@ -11,28 +11,28 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/tracer"
|
||||
)
|
||||
|
||||
// RegisterClose 注册app需要释放的资源
|
||||
// RegisterClose register for released resources
|
||||
func RegisterClose(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, s := range servers {
|
||||
closes = append(closes, s.Stop)
|
||||
}
|
||||
|
||||
// 关闭mysql
|
||||
// close mysql
|
||||
//closes = append(closes, func() error {
|
||||
// return model.CloseMysql()
|
||||
//})
|
||||
|
||||
// 关闭redis
|
||||
// close redis
|
||||
//if config.Get().App.CacheType == "redis" {
|
||||
// closes = append(closes, func() error {
|
||||
// return model.CloseRedis()
|
||||
// })
|
||||
//}
|
||||
|
||||
// 关闭trace
|
||||
// close tracing
|
||||
if config.Get().App.EnableTracing {
|
||||
closes = append(closes, func() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
|
||||
|
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
|
||||
)
|
||||
|
||||
// RegisterServers 注册app服务
|
||||
// RegisterServers register for the app service
|
||||
func RegisterServers() []app.IServer {
|
||||
var cfg = config.Get()
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建grpc服务
|
||||
// creating grpc service
|
||||
grpcAddr := ":" + strconv.Itoa(cfg.Grpc.Port)
|
||||
grpcRegistry, grpcInstance := registryService("grpc", cfg.App.Host, cfg.Grpc.Port)
|
||||
grpcServer := server.NewGRPCServer(grpcAddr,
|
||||
@@ -38,7 +38,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -50,7 +50,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -62,7 +62,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -23,23 +23,23 @@ var (
|
||||
enableConfigCenter bool
|
||||
)
|
||||
|
||||
// Config 初始化配置
|
||||
// Config initial app configuration
|
||||
func Config() {
|
||||
initConfig()
|
||||
cfg := config.Get()
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
_, _ = logger.Init(
|
||||
logger.WithLevel(cfg.Logger.Level),
|
||||
logger.WithFormat(cfg.Logger.Format),
|
||||
logger.WithSave(cfg.Logger.IsSave),
|
||||
)
|
||||
|
||||
// 初始化数据库
|
||||
// initializing database
|
||||
model.InitMysql()
|
||||
model.InitCache(cfg.App.CacheType)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
if cfg.App.EnableTracing {
|
||||
tracer.InitWithConfig(
|
||||
cfg.App.Name,
|
||||
@@ -51,13 +51,12 @@ func Config() {
|
||||
)
|
||||
}
|
||||
|
||||
// 初始化打印系统和进程资源
|
||||
// initializing the print system and process resources
|
||||
if cfg.App.EnableStat {
|
||||
stat.Init(stat.WithLog(logger.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
func initConfig() {
|
||||
flag.StringVar(&version, "version", "", "service Version Number")
|
||||
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
|
||||
@@ -66,7 +65,8 @@ func initConfig() {
|
||||
flag.Parse()
|
||||
|
||||
if enableConfigCenter {
|
||||
// 从配置中心获取配置(先获取nacos配置,再根据nacos配置中心读取服务配置)
|
||||
// get the configuration from the configuration center (first get the nacos configuration,
|
||||
// then read the service configuration according to the nacos configuration center)
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample_cc.yml")
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func initConfig() {
|
||||
}
|
||||
config.Set(appConfig)
|
||||
} else {
|
||||
// 从本地配置文件获取配置
|
||||
// get configuration from local configuration file
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample.yml")
|
||||
}
|
||||
|
@@ -11,28 +11,28 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/tracer"
|
||||
)
|
||||
|
||||
// RegisterClose 注册app需要释放的资源
|
||||
// RegisterClose register for released resources
|
||||
func RegisterClose(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, s := range servers {
|
||||
closes = append(closes, s.Stop)
|
||||
}
|
||||
|
||||
// 关闭mysql
|
||||
// close mysql
|
||||
closes = append(closes, func() error {
|
||||
return model.CloseMysql()
|
||||
})
|
||||
|
||||
// 关闭redis
|
||||
// close redis
|
||||
if config.Get().App.CacheType == "redis" {
|
||||
closes = append(closes, func() error {
|
||||
return model.CloseRedis()
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭trace
|
||||
// close tracing
|
||||
if config.Get().App.EnableTracing {
|
||||
closes = append(closes, func() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
|
||||
|
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
|
||||
)
|
||||
|
||||
// RegisterServers 注册app服务
|
||||
// RegisterServers register for the app service
|
||||
func RegisterServers() []app.IServer {
|
||||
var cfg = config.Get()
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建http服务
|
||||
// creating http service
|
||||
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
|
||||
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
|
||||
httpServer := server.NewHTTPServer(httpAddr,
|
||||
@@ -39,7 +39,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -51,7 +51,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -63,7 +63,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -24,23 +24,23 @@ var (
|
||||
enableConfigCenter bool
|
||||
)
|
||||
|
||||
// Config 初始化配置
|
||||
// Config initial app configuration
|
||||
func Config() {
|
||||
initConfig()
|
||||
cfg := config.Get()
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
_, _ = logger.Init(
|
||||
logger.WithLevel(cfg.Logger.Level),
|
||||
logger.WithFormat(cfg.Logger.Format),
|
||||
logger.WithSave(cfg.Logger.IsSave),
|
||||
)
|
||||
|
||||
// 初始化数据库
|
||||
// initializing database
|
||||
//model.InitMysql()
|
||||
//model.InitCache(cfg.App.CacheType)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
if cfg.App.EnableTracing {
|
||||
tracer.InitWithConfig(
|
||||
cfg.App.Name,
|
||||
@@ -52,13 +52,12 @@ func Config() {
|
||||
)
|
||||
}
|
||||
|
||||
// 初始化打印系统和进程资源
|
||||
// initializing the print system and process resources
|
||||
if cfg.App.EnableStat {
|
||||
stat.Init(stat.WithLog(logger.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
func initConfig() {
|
||||
flag.StringVar(&version, "version", "", "service Version Number")
|
||||
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
|
||||
@@ -67,7 +66,8 @@ func initConfig() {
|
||||
flag.Parse()
|
||||
|
||||
if enableConfigCenter {
|
||||
// 从配置中心获取配置(先获取nacos配置,再根据nacos配置中心读取服务配置)
|
||||
// get the configuration from the configuration center (first get the nacos configuration,
|
||||
// then read the service configuration according to the nacos configuration center)
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample_cc.yml")
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func initConfig() {
|
||||
}
|
||||
config.Set(appConfig)
|
||||
} else {
|
||||
// 从本地配置文件获取配置
|
||||
// get configuration from local configuration file
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample.yml")
|
||||
}
|
||||
|
@@ -11,28 +11,28 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/tracer"
|
||||
)
|
||||
|
||||
// RegisterClose 注册app需要释放的资源
|
||||
// RegisterClose register for released resources
|
||||
func RegisterClose(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, s := range servers {
|
||||
closes = append(closes, s.Stop)
|
||||
}
|
||||
|
||||
// 关闭mysql
|
||||
// close mysql
|
||||
//closes = append(closes, func() error {
|
||||
// return model.CloseMysql()
|
||||
//})
|
||||
|
||||
// 关闭redis
|
||||
// close redis
|
||||
//if config.Get().App.CacheType == "redis" {
|
||||
// closes = append(closes, func() error {
|
||||
// return model.CloseRedis()
|
||||
// })
|
||||
//}
|
||||
|
||||
// 关闭trace
|
||||
// close tracing
|
||||
if config.Get().App.EnableTracing {
|
||||
closes = append(closes, func() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
|
||||
|
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
|
||||
)
|
||||
|
||||
// RegisterServers 注册app服务
|
||||
// RegisterServers register for the app service
|
||||
func RegisterServers() []app.IServer {
|
||||
var cfg = config.Get()
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建http服务
|
||||
// creating http service
|
||||
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
|
||||
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
|
||||
httpServer := server.NewHTTPServer_pbExample(httpAddr,
|
||||
@@ -39,7 +39,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -51,7 +51,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -63,7 +63,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -23,23 +23,23 @@ var (
|
||||
enableConfigCenter bool
|
||||
)
|
||||
|
||||
// Config 初始化配置
|
||||
// Config initial app configuration
|
||||
func Config() {
|
||||
initConfig()
|
||||
cfg := config.Get()
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
_, _ = logger.Init(
|
||||
logger.WithLevel(cfg.Logger.Level),
|
||||
logger.WithFormat(cfg.Logger.Format),
|
||||
logger.WithSave(cfg.Logger.IsSave),
|
||||
)
|
||||
|
||||
// 初始化数据库
|
||||
// initializing database
|
||||
model.InitMysql()
|
||||
model.InitCache(cfg.App.CacheType)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
if cfg.App.EnableTracing {
|
||||
tracer.InitWithConfig(
|
||||
cfg.App.Name,
|
||||
@@ -51,13 +51,12 @@ func Config() {
|
||||
)
|
||||
}
|
||||
|
||||
// 初始化打印系统和进程资源
|
||||
// initializing the print system and process resources
|
||||
if cfg.App.EnableStat {
|
||||
stat.Init(stat.WithLog(logger.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
func initConfig() {
|
||||
flag.StringVar(&version, "version", "", "service Version Number")
|
||||
flag.BoolVar(&enableConfigCenter, "enable-cc", false, "whether to get from the configuration center, "+
|
||||
@@ -66,7 +65,8 @@ func initConfig() {
|
||||
flag.Parse()
|
||||
|
||||
if enableConfigCenter {
|
||||
// 从配置中心获取配置(先获取nacos配置,再根据nacos配置中心读取服务配置)
|
||||
// get the configuration from the configuration center (first get the nacos configuration,
|
||||
// then read the service configuration according to the nacos configuration center)
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample_cc.yml")
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func initConfig() {
|
||||
}
|
||||
config.Set(appConfig)
|
||||
} else {
|
||||
// 从本地配置文件获取配置
|
||||
// get configuration from local configuration file
|
||||
if configFile == "" {
|
||||
configFile = configs.Path("serverNameExample.yml")
|
||||
}
|
||||
|
@@ -11,28 +11,28 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/tracer"
|
||||
)
|
||||
|
||||
// RegisterClose 注册app需要释放的资源
|
||||
// RegisterClose register for released resources
|
||||
func RegisterClose(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, s := range servers {
|
||||
closes = append(closes, s.Stop)
|
||||
}
|
||||
|
||||
// 关闭mysql
|
||||
// close mysql
|
||||
closes = append(closes, func() error {
|
||||
return model.CloseMysql()
|
||||
})
|
||||
|
||||
// 关闭redis
|
||||
// close redis
|
||||
if config.Get().App.CacheType == "redis" {
|
||||
closes = append(closes, func() error {
|
||||
return model.CloseRedis()
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭trace
|
||||
// close tracing
|
||||
if config.Get().App.EnableTracing {
|
||||
closes = append(closes, func() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) //nolint
|
||||
|
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/servicerd/registry/nacos"
|
||||
)
|
||||
|
||||
// RegisterServers 注册app服务
|
||||
// RegisterServers register for the app service
|
||||
func RegisterServers() []app.IServer {
|
||||
var cfg = config.Get()
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建http服务
|
||||
// creating http service
|
||||
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
|
||||
httpRegistry, httpInstance := registryService("http", cfg.App.Host, cfg.HTTP.Port)
|
||||
httpServer := server.NewHTTPServer(httpAddr,
|
||||
@@ -31,7 +31,7 @@ func RegisterServers() []app.IServer {
|
||||
)
|
||||
servers = append(servers, httpServer)
|
||||
|
||||
// 创建grpc服务
|
||||
// creating grpc service
|
||||
grpcAddr := ":" + strconv.Itoa(cfg.Grpc.Port)
|
||||
grpcRegistry, grpcInstance := registryService("grpc", cfg.App.Host, cfg.Grpc.Port)
|
||||
grpcServer := server.NewGRPCServer(grpcAddr,
|
||||
@@ -49,7 +49,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -61,7 +61,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -73,7 +73,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -14,12 +14,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// TplNameSponge 模板目录名称
|
||||
// TplNameSponge name of the template
|
||||
TplNameSponge = "sponge"
|
||||
)
|
||||
|
||||
var (
|
||||
// 指定文件替换标记
|
||||
modelFile = "model/userExample.go"
|
||||
modelFileMark = "// todo generate model codes to here"
|
||||
|
||||
@@ -63,7 +62,7 @@ var (
|
||||
makeFile = "sponge/Makefile"
|
||||
gitIgnoreFile = "sponge/.gitignore"
|
||||
|
||||
// 清除标记的模板代码片段标记
|
||||
// clear marker for template code marker
|
||||
startMark = []byte("// delete the templates code start")
|
||||
endMark = []byte("// delete the templates code end")
|
||||
wellStartMark = bytes.ReplaceAll(startMark, []byte("//"), []byte("#"))
|
||||
@@ -73,7 +72,7 @@ var (
|
||||
wellOnlyGrpcStartMark = bytes.ReplaceAll(onlyGrpcStartMark, []byte("//"), []byte("#"))
|
||||
wellOnlyGrpcEndMark = bytes.ReplaceAll(onlyGrpcEndMark, []byte("//"), []byte("#"))
|
||||
|
||||
// embed FS模板文件时使用
|
||||
// embed FS template file when using
|
||||
selfPackageName = "github.com/zhufuyi/sponge"
|
||||
)
|
||||
|
||||
@@ -115,7 +114,7 @@ func deleteFieldsMark(r replacer.Replacer, filename string, startMark []byte, en
|
||||
}
|
||||
if subBytes := gofile.FindSubBytes(data, startMark, endMark); len(subBytes) > 0 {
|
||||
fields = append(fields,
|
||||
replacer.Field{ // 清除标记的模板代码
|
||||
replacer.Field{ // clear marked template code
|
||||
Old: string(subBytes),
|
||||
New: "",
|
||||
},
|
||||
@@ -142,16 +141,16 @@ func replaceFileContentMark(r replacer.Replacer, filename string, newContent str
|
||||
return fields
|
||||
}
|
||||
|
||||
// 解析镜像仓库host和name
|
||||
// resolving mirror repository host and name
|
||||
func parseImageRepoAddr(addr string) (string, string) {
|
||||
splits := strings.Split(addr, "/")
|
||||
|
||||
// 官方仓库地址
|
||||
// default docker hub official repo address
|
||||
if len(splits) == 1 {
|
||||
return "https://index.docker.io/v1", addr
|
||||
}
|
||||
|
||||
// 非官方仓库地址
|
||||
// unofficial repo address
|
||||
l := len(splits)
|
||||
return strings.Join(splits[:l-1], "/"), splits[l-1]
|
||||
}
|
||||
@@ -185,8 +184,8 @@ func parseProtobufFiles(protobufFile string) ([]string, bool, error) {
|
||||
return protobufFiles, countImportTypes > 0, nil
|
||||
}
|
||||
|
||||
// save the moduleName and serverName to the specified file for external use
|
||||
func saveGenInfo(moduleName string, serverName string, outputDir string) error {
|
||||
// 保存moduleName和serverName到指定文件,给外部使用
|
||||
genInfo := moduleName + "," + serverName
|
||||
dir := outputDir + "/docs"
|
||||
_ = os.MkdirAll(dir, 0666)
|
||||
@@ -217,7 +216,6 @@ func getNamesFromOutDir(dir string) (string, string) {
|
||||
}
|
||||
|
||||
func saveProtobufFiles(moduleName string, serverName string, outputDir string, protobufFiles []string) error {
|
||||
// 保存protobuf文件
|
||||
for _, pbFile := range protobufFiles {
|
||||
pbContent, err := os.ReadFile(pbFile)
|
||||
if err != nil {
|
||||
|
@@ -84,9 +84,9 @@ type configType struct {
|
||||
isConfigCenter bool
|
||||
}
|
||||
|
||||
// 从configs目录读取所有yaml文件目录,一个是.yml,另一个是cc.yml
|
||||
// read all yaml file directories from the config directory, one is .yml and the other is cc.yml
|
||||
func getYAMLFile(serverDir string) (map[string]configType, error) {
|
||||
// 生成目标文件:配置文件
|
||||
// generate target file:configuration file
|
||||
files := make(map[string]configType)
|
||||
configsDir := serverDir + gofile.GetPathDelimiter() + "configs"
|
||||
goConfigDir := serverDir + gofile.GetPathDelimiter() + "internal" + gofile.GetPathDelimiter() + "config"
|
||||
|
@@ -14,8 +14,8 @@ import (
|
||||
// DaoCommand generate dao codes
|
||||
func DaoCommand(parentName string) *cobra.Command {
|
||||
var (
|
||||
moduleName string // 服务名称,也就是包名称
|
||||
outPath string // 输出目录
|
||||
moduleName string // go.mod module name
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{
|
||||
Package: "model",
|
||||
JSONTag: true,
|
||||
@@ -78,10 +78,14 @@ func runGenDaoCommand(moduleName string, codes map[string]string, outPath string
|
||||
return errors.New("r is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{"internal/model", "internal/cache", "internal/dao"} // 只处理的指定子目录,如果为空或者没有指定的子目录,表示所有文件
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{"init.go", "init_test.go"} // 指定子目录下忽略处理的文件
|
||||
// setting up template information
|
||||
subDirs := []string{ // only the specified subdirectory is processed, if empty or no subdirectory is specified, it means all files
|
||||
"internal/model", "internal/cache", "internal/dao",
|
||||
}
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"init.go", "init_test.go",
|
||||
}
|
||||
|
||||
r.SetSubDirsAndFiles(subDirs)
|
||||
r.SetIgnoreSubDirs(ignoreDirs...)
|
||||
@@ -97,6 +101,7 @@ func runGenDaoCommand(moduleName string, codes map[string]string, outPath string
|
||||
return nil
|
||||
}
|
||||
|
||||
// set fields
|
||||
func addDAOFields(moduleName string, r replacer.Replacer, codes map[string]string) []replacer.Field {
|
||||
var fields []replacer.Field
|
||||
|
||||
@@ -104,11 +109,11 @@ func addDAOFields(moduleName string, r replacer.Replacer, codes map[string]strin
|
||||
fields = append(fields, deleteFieldsMark(r, daoFile, startMark, endMark)...)
|
||||
fields = append(fields, deleteFieldsMark(r, daoTestFile, startMark, endMark)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换model/userExample.go文件内容
|
||||
{
|
||||
Old: modelFileMark,
|
||||
New: codes[parser.CodeTypeModel],
|
||||
},
|
||||
{ // 替换dao/userExample.go文件内容
|
||||
{
|
||||
Old: daoFileMark,
|
||||
New: codes[parser.CodeTypeDAO],
|
||||
},
|
||||
|
@@ -15,8 +15,8 @@ import (
|
||||
// HandlerCommand generate handler codes
|
||||
func HandlerCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
outPath string // 输出目录
|
||||
moduleName string // module name for go.mod
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{
|
||||
Package: "model",
|
||||
JSONTag: true,
|
||||
@@ -80,11 +80,11 @@ func runGenHandlerCommand(moduleName string, codes map[string]string, outPath st
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
// setting up template information
|
||||
subDirs := []string{"internal/model", "internal/cache", "internal/dao",
|
||||
"internal/ecode", "internal/handler", "internal/routers", "internal/types"} // 只处理的指定子目录,如果为空或者没有指定的子目录,表示所有文件
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
"internal/ecode", "internal/handler", "internal/routers", "internal/types"} // only the specified subdirectory is processed, if empty or no subdirectory is specified, it means all files
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"systemCode_http.go", "systemCode_rpc.go", "userExample_rpc.go", // internal/ecode
|
||||
"init.go", "init_test.go", // internal/model
|
||||
"routers.go", "routers_test.go", "routers_pbExample.go", "routers_pbExample_test.go", "userExample_service.pb.go", // internal/routers
|
||||
@@ -114,15 +114,15 @@ func addHandlerFields(moduleName string, r replacer.Replacer, codes map[string]s
|
||||
fields = append(fields, deleteFieldsMark(r, handlerFile, startMark, endMark)...)
|
||||
fields = append(fields, deleteFieldsMark(r, handlerTestFile, startMark, endMark)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换model/userExample.go文件内容
|
||||
{ // replace the contents of the model/userExample.go file
|
||||
Old: modelFileMark,
|
||||
New: codes[parser.CodeTypeModel],
|
||||
},
|
||||
{ // 替换dao/userExample.go文件内容
|
||||
{ // replace the contents of the dao/userExample.go file
|
||||
Old: daoFileMark,
|
||||
New: codes[parser.CodeTypeDAO],
|
||||
},
|
||||
{ // 替换handler/userExample.go文件内容
|
||||
{ // replace the contents of the handler/userExample.go file
|
||||
Old: handlerFileMark,
|
||||
New: adjustmentOfIDType(codes[parser.CodeTypeHandler]),
|
||||
},
|
||||
|
@@ -13,12 +13,12 @@ import (
|
||||
// HTTPServerCommand generate http server codes based on protobuf file
|
||||
func HTTPServerCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
projectName string // 所属项目名称
|
||||
repoAddr string // 镜像仓库地址
|
||||
outPath string // 输出目录
|
||||
protobufFile string // proto file文件
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
projectName string // project name for deployment name
|
||||
repoAddr string // image repo address
|
||||
outPath string // output directory
|
||||
protobufFile string // protobuf file, support * matching
|
||||
)
|
||||
|
||||
//nolint
|
||||
@@ -71,18 +71,18 @@ func runGenHTTPServerCommand(moduleName string, serverName string, projectName s
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{ // 只处理的子目录
|
||||
// setting up template information
|
||||
subDirs := []string{ // processing-only subdirectories
|
||||
"api/types", "cmd/serverNameExample_httpPbExample",
|
||||
"sponge/build", "sponge/configs", "sponge/deployments", "sponge/docs", "sponge/scripts", "sponge/third_party",
|
||||
"internal/config", "internal/ecode", "internal/routers", "internal/server",
|
||||
}
|
||||
subFiles := []string{ // 只处理子文件
|
||||
subFiles := []string{ // processing of sub-documents only
|
||||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"types.pb.validate.go", "types.pb.go", // api/types
|
||||
"swagger.json", "swagger.yaml", "apis.swagger.json", "apis.html", "docs.go", // sponge/docs
|
||||
"userExample_rpc.go", "systemCode_rpc.go", "userExample_http.go", // internal/ecode
|
||||
@@ -130,27 +130,27 @@ func addHTTPServerFields(moduleName string, serverName string, projectName strin
|
||||
fields = append(fields, deleteFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+serverName)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换Dockerfile文件内容
|
||||
{ // replace the contents of the Dockerfile file
|
||||
Old: dockerFileMark,
|
||||
New: dockerFileHTTPCode,
|
||||
},
|
||||
{ // 替换Dockerfile_build文件内容
|
||||
{ // replace the contents of the Dockerfile_build file
|
||||
Old: dockerFileBuildMark,
|
||||
New: dockerFileBuildHTTPCode,
|
||||
},
|
||||
{ // 替换docker-compose.yml文件内容
|
||||
{ // replace the contents of the docker-compose.yml file
|
||||
Old: dockerComposeFileMark,
|
||||
New: dockerComposeFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-deployment.yml文件内容
|
||||
{ // replace the contents of the *-deployment.yml file
|
||||
Old: k8sDeploymentFileMark,
|
||||
New: k8sDeploymentFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-svc.yml文件内容
|
||||
{ // replace the contents of the *-svc.yml file
|
||||
Old: k8sServiceFileMark,
|
||||
New: k8sServiceFileHTTPCode,
|
||||
},
|
||||
{ // 替换proto.sh文件内容
|
||||
{ // replace the contents of the proto.sh file
|
||||
Old: protoShellFileMark,
|
||||
New: protoShellHandlerCode,
|
||||
},
|
||||
@@ -170,7 +170,7 @@ func addHTTPServerFields(moduleName string, serverName string, projectName strin
|
||||
Old: "serverNameExample",
|
||||
New: serverName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "server-name-example",
|
||||
New: xstrings.ToKebabCase(serverName),
|
||||
@@ -179,7 +179,7 @@ func addHTTPServerFields(moduleName string, serverName string, projectName strin
|
||||
Old: "projectNameExample",
|
||||
New: projectName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "project-name-example",
|
||||
New: xstrings.ToKebabCase(projectName),
|
||||
|
@@ -16,11 +16,11 @@ import (
|
||||
// HTTPCommand generate http server codes
|
||||
func HTTPCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
projectName string // 项目名称
|
||||
repoAddr string // 镜像仓库地址
|
||||
outPath string // 输出目录
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
projectName string // project name for deployment name
|
||||
repoAddr string // image repo address
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{
|
||||
Package: "model",
|
||||
JSONTag: true,
|
||||
@@ -84,19 +84,19 @@ func runGenHTTPCommand(moduleName string, serverName string, projectName string,
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{ // 指定处理的子目录
|
||||
// setting up template information
|
||||
subDirs := []string{ // specify the subdirectory for processing
|
||||
"cmd/serverNameExample_httpExample", "sponge/build", "sponge/configs", "sponge/deployments",
|
||||
"sponge/docs", "sponge/scripts", "sponge/internal",
|
||||
}
|
||||
subFiles := []string{ // 指定处理的子文件
|
||||
subFiles := []string{ // specify the sub-documents to be processed
|
||||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
ignoreDirs := []string{ // 指定子目录下忽略处理的目录
|
||||
ignoreDirs := []string{ // specify the directory in the subdirectory where processing is ignored
|
||||
"internal/service", "internal/rpcclient",
|
||||
}
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"swagger.json", "swagger.yaml", "apis.swagger.json", "apis.html", "apis.go", // sponge/docs
|
||||
"userExample_rpc.go", "systemCode_rpc.go", // internal/ecode
|
||||
"routers_pbExample.go", "routers_pbExample_test.go", "userExample_service.pb.go", // internal/routers
|
||||
@@ -141,39 +141,39 @@ func addHTTPFields(moduleName string, serverName string, projectName string, rep
|
||||
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+serverName)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换model/userExample.go文件内容
|
||||
{ // replace the contents of the model/userExample.go file
|
||||
Old: modelFileMark,
|
||||
New: codes[parser.CodeTypeModel],
|
||||
},
|
||||
{ // 替换dao/userExample.go文件内容
|
||||
{ // replace the contents of the dao/userExample.go file
|
||||
Old: daoFileMark,
|
||||
New: codes[parser.CodeTypeDAO],
|
||||
},
|
||||
{ // 替换handler/userExample.go文件内容
|
||||
{ // replace the contents of the handler/userExample.go file
|
||||
Old: handlerFileMark,
|
||||
New: adjustmentOfIDType(codes[parser.CodeTypeHandler]),
|
||||
},
|
||||
{ // 替换Dockerfile文件内容
|
||||
{ // replace the contents of the Dockerfile file
|
||||
Old: dockerFileMark,
|
||||
New: dockerFileHTTPCode,
|
||||
},
|
||||
{ // 替换Dockerfile_build文件内容
|
||||
{ // replace the contents of the Dockerfile_build file
|
||||
Old: dockerFileBuildMark,
|
||||
New: dockerFileBuildHTTPCode,
|
||||
},
|
||||
{ // 替换docker-compose.yml文件内容
|
||||
{ // replace the contents of the docker-compose.yml file
|
||||
Old: dockerComposeFileMark,
|
||||
New: dockerComposeFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-deployment.yml文件内容
|
||||
{ // replace the contents of the *-deployment.yml file
|
||||
Old: k8sDeploymentFileMark,
|
||||
New: k8sDeploymentFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-svc.yml文件内容
|
||||
{ // replace the contents of the *-svc.yml file
|
||||
Old: k8sServiceFileMark,
|
||||
New: k8sServiceFileHTTPCode,
|
||||
},
|
||||
// 替换github.com/zhufuyi/sponge/templates/sponge
|
||||
// replace github.com/zhufuyi/sponge/templates/sponge
|
||||
{
|
||||
Old: selfPackageName + "/" + r.GetSourcePath(),
|
||||
New: moduleName,
|
||||
@@ -198,7 +198,7 @@ func addHTTPFields(moduleName string, serverName string, projectName string, rep
|
||||
Old: "serverNameExample",
|
||||
New: serverName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "server-name-example",
|
||||
New: xstrings.ToKebabCase(serverName),
|
||||
@@ -207,7 +207,7 @@ func addHTTPFields(moduleName string, serverName string, projectName string, rep
|
||||
Old: "projectNameExample",
|
||||
New: projectName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "project-name-example",
|
||||
New: xstrings.ToKebabCase(projectName),
|
||||
|
@@ -18,19 +18,19 @@ func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
// Replacers 模板名称对应的接口
|
||||
// Replacers replacer name
|
||||
var Replacers = map[string]replacer.Replacer{}
|
||||
|
||||
// Template 模板信息
|
||||
// Template information
|
||||
type Template struct {
|
||||
Name string
|
||||
FS embed.FS
|
||||
FilePath string
|
||||
}
|
||||
|
||||
// Init 初始化模板
|
||||
// Init initializing the template
|
||||
func Init(name string, filepath string) error {
|
||||
// 判断模板文件是否存在,不存在,提示先更新
|
||||
// determine if the template file exists, if not, prompt to initialize first
|
||||
if !gofile.IsExists(filepath) {
|
||||
if isShowCommand() {
|
||||
return nil
|
||||
@@ -50,7 +50,7 @@ func Init(name string, filepath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitFS 初始化FS模板
|
||||
// InitFS initializing th FS templates
|
||||
func InitFS(name string, filepath string, fs embed.FS) {
|
||||
var err error
|
||||
if _, ok := Replacers[name]; ok {
|
||||
|
@@ -14,7 +14,7 @@ import (
|
||||
// ModelCommand generate model codes
|
||||
func ModelCommand(parentName string) *cobra.Command {
|
||||
var (
|
||||
outPath string // 输出目录
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{
|
||||
Package: "model",
|
||||
JSONTag: true,
|
||||
@@ -66,10 +66,12 @@ func runGenModelCommand(codes map[string]string, outPath string) error {
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{"internal/model"} // 只处理的指定子目录,如果为空或者没有指定的子目录,表示所有文件
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{"init.go", "init_test.go"} // 指定子目录下忽略处理的文件
|
||||
// setting up template information
|
||||
subDirs := []string{"internal/model"} // only the specified subdirectory is processed, if empty or no subdirectory is specified, it means all files
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"init.go", "init_test.go",
|
||||
}
|
||||
|
||||
r.SetSubDirsAndFiles(subDirs)
|
||||
r.SetIgnoreSubDirs(ignoreDirs...)
|
||||
@@ -90,7 +92,7 @@ func addModelFields(r replacer.Replacer, codes map[string]string) []replacer.Fie
|
||||
|
||||
fields = append(fields, deleteFieldsMark(r, modelFile, startMark, endMark)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换model/userExample.go文件内容
|
||||
{ // replace the contents of the model/userExample.go file
|
||||
Old: modelFileMark,
|
||||
New: codes[parser.CodeTypeModel],
|
||||
},
|
||||
|
@@ -16,9 +16,9 @@ import (
|
||||
// ProtoBufCommand generate protobuf codes
|
||||
func ProtoBufCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
outPath string // 输出目录
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{}
|
||||
)
|
||||
|
||||
@@ -84,11 +84,14 @@ func runGenProtoCommand(moduleName string, serverName string, codes map[string]s
|
||||
serverName = moduleName
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{"api/serverNameExample"} // 只处理的指定子目录,如果为空或者没有指定的子目录,表示所有文件
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{"userExample.pb.go", "userExample.pb.validate.go",
|
||||
"userExample_grpc.pb.go", "userExample_router.pb.go"} // 指定子目录下忽略处理的文件
|
||||
// setting up template information
|
||||
subDirs := []string{ // only the specified subdirectory is processed, if empty or no subdirectory is specified, it means all files
|
||||
"api/serverNameExample",
|
||||
}
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"userExample.pb.go", "userExample.pb.validate.go",
|
||||
"userExample_grpc.pb.go", "userExample_router.pb.go"}
|
||||
|
||||
r.SetSubDirsAndFiles(subDirs)
|
||||
r.SetIgnoreSubDirs(ignoreDirs...)
|
||||
@@ -109,7 +112,7 @@ func addProtoFields(moduleName string, serverName string, r replacer.Replacer, c
|
||||
|
||||
fields = append(fields, deleteFieldsMark(r, protoFile, startMark, endMark)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换v1/userExample.proto文件内容
|
||||
{ // replace the contents of the v1/userExample.proto file
|
||||
Old: protoFileMark,
|
||||
New: codes[parser.CodeTypeProto],
|
||||
},
|
||||
@@ -117,7 +120,7 @@ func addProtoFields(moduleName string, serverName string, r replacer.Replacer, c
|
||||
Old: "github.com/zhufuyi/sponge",
|
||||
New: moduleName,
|
||||
},
|
||||
// 替换目录名称
|
||||
// replace directory name
|
||||
{
|
||||
Old: strings.Join([]string{"api", "serverNameExample", "v1"}, gofile.GetPathDelimiter()),
|
||||
New: strings.Join([]string{"api", serverName, "v1"}, gofile.GetPathDelimiter()),
|
||||
@@ -128,7 +131,7 @@ func addProtoFields(moduleName string, serverName string, r replacer.Replacer, c
|
||||
},
|
||||
{
|
||||
Old: "api.serverNameExample.v1",
|
||||
New: fmt.Sprintf("api.%s.v1", strings.ReplaceAll(serverName, "-", "_")), // protobuf package 不能存在"-"号
|
||||
New: fmt.Sprintf("api.%s.v1", strings.ReplaceAll(serverName, "-", "_")), // protobuf package no "-" signs allowed
|
||||
},
|
||||
{
|
||||
Old: "UserExample",
|
||||
|
@@ -13,12 +13,12 @@ import (
|
||||
// RPCGwPbCommand generate rpc gateway server codes base on protobuf file
|
||||
func RPCGwPbCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
projectName string // 项目名称
|
||||
repoAddr string // 镜像仓库地址
|
||||
outPath string // 输出目录
|
||||
protobufFile string // proto file文件
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
projectName string // project name for deployment name
|
||||
repoAddr string // image repo address
|
||||
outPath string // output directory
|
||||
protobufFile string // protobuf file, support * matching
|
||||
)
|
||||
|
||||
//nolint
|
||||
@@ -71,18 +71,18 @@ func runGenRPCGwCommand(moduleName string, serverName string, projectName string
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{ // 只处理的子目录
|
||||
// setting up template information
|
||||
subDirs := []string{ // processing-only subdirectories
|
||||
"api/types", "cmd/serverNameExample_grpcGwPbExample",
|
||||
"sponge/build", "sponge/configs", "sponge/deployments", "sponge/docs", "sponge/scripts", "sponge/third_party",
|
||||
"internal/config", "internal/ecode", "internal/routers", "internal/rpcclient", "internal/server",
|
||||
}
|
||||
subFiles := []string{ // 只处理子文件
|
||||
subFiles := []string{ // processing of sub-documents only
|
||||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"types.pb.validate.go", "types.pb.go", // api/types
|
||||
"swagger.json", "swagger.yaml", "apis.swagger.json", "apis.html", "docs.go", // sponge/docs
|
||||
"userExample_rpc.go", "systemCode_http.go", "userExample_http.go", // internal/ecode
|
||||
@@ -130,27 +130,27 @@ func addRPCGwFields(moduleName string, serverName string, projectName string, re
|
||||
fields = append(fields, deleteFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+serverName)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换Dockerfile文件内容
|
||||
{ // replace the contents of the Dockerfile file
|
||||
Old: dockerFileMark,
|
||||
New: dockerFileHTTPCode,
|
||||
},
|
||||
{ // 替换Dockerfile_build文件内容
|
||||
{ // replace the contents of the Dockerfile_build file
|
||||
Old: dockerFileBuildMark,
|
||||
New: dockerFileBuildHTTPCode,
|
||||
},
|
||||
{ // 替换docker-compose.yml文件内容
|
||||
{ // replace the contents of the docker-compose.yml file
|
||||
Old: dockerComposeFileMark,
|
||||
New: dockerComposeFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-deployment.yml文件内容
|
||||
{ // replace the contents of the *-deployment.yml file
|
||||
Old: k8sDeploymentFileMark,
|
||||
New: k8sDeploymentFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-svc.yml文件内容
|
||||
{ // replace the contents of the *-svc.yml file
|
||||
Old: k8sServiceFileMark,
|
||||
New: k8sServiceFileHTTPCode,
|
||||
},
|
||||
{ // 替换proto.sh文件内容
|
||||
{ // replace the contents of the proto.sh file
|
||||
Old: protoShellFileMark,
|
||||
New: protoShellServiceCode,
|
||||
},
|
||||
@@ -170,7 +170,7 @@ func addRPCGwFields(moduleName string, serverName string, projectName string, re
|
||||
Old: "serverNameExample",
|
||||
New: serverName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "server-name-example",
|
||||
New: xstrings.ToKebabCase(serverName),
|
||||
@@ -179,7 +179,7 @@ func addRPCGwFields(moduleName string, serverName string, projectName string, re
|
||||
Old: "projectNameExample",
|
||||
New: projectName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "project-name-example",
|
||||
New: xstrings.ToKebabCase(projectName),
|
||||
|
@@ -13,12 +13,12 @@ import (
|
||||
// RPCPbCommand generate rpc server codes bash on protobuf file
|
||||
func RPCPbCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
projectName string // 项目名称
|
||||
repoAddr string // 镜像仓库地址
|
||||
outPath string // 输出目录
|
||||
protobufFile string // proto file文件
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
projectName string // project name for deployment name
|
||||
repoAddr string // image repo address
|
||||
outPath string // output directory
|
||||
protobufFile string // protobuf file, support * matching
|
||||
)
|
||||
|
||||
//nolint
|
||||
@@ -70,18 +70,18 @@ func runGenRPCPbCommand(moduleName string, serverName string, projectName string
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{ // 只处理的子目录
|
||||
// setting up template information
|
||||
subDirs := []string{ // processing-only subdirectories
|
||||
"api/types", "cmd/serverNameExample_grpcPbExample",
|
||||
"sponge/build", "sponge/configs", "sponge/deployments", "sponge/scripts", "sponge/third_party",
|
||||
"internal/config", "internal/ecode", "internal/server", "internal/service",
|
||||
}
|
||||
subFiles := []string{ // 只处理子文件
|
||||
subFiles := []string{ // processing of sub-documents only
|
||||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"types.pb.validate.go", "types.pb.go", // api/types
|
||||
"userExample_rpc.go", "systemCode_http.go", "userExample_http.go", // internal/ecode
|
||||
"http.go", "http_option.go", "http_test.go", // internal/server
|
||||
@@ -126,27 +126,27 @@ func addRPCPbFields(moduleName string, serverName string, projectName string, re
|
||||
fields = append(fields, deleteFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+serverName)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换Dockerfile文件内容
|
||||
{ // replace the contents of the Dockerfile file
|
||||
Old: dockerFileMark,
|
||||
New: dockerFileHTTPCode,
|
||||
},
|
||||
{ // 替换Dockerfile_build文件内容
|
||||
{ // replace the contents of the Dockerfile_build file
|
||||
Old: dockerFileBuildMark,
|
||||
New: dockerFileBuildHTTPCode,
|
||||
},
|
||||
{ // 替换docker-compose.yml文件内容
|
||||
{ // replace the contents of the docker-compose.yml file
|
||||
Old: dockerComposeFileMark,
|
||||
New: dockerComposeFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-deployment.yml文件内容
|
||||
{ // replace the contents of the *-deployment.yml file
|
||||
Old: k8sDeploymentFileMark,
|
||||
New: k8sDeploymentFileHTTPCode,
|
||||
},
|
||||
{ // 替换*-svc.yml文件内容
|
||||
{ // replace the contents of the *-svc.yml file
|
||||
Old: k8sServiceFileMark,
|
||||
New: k8sServiceFileHTTPCode,
|
||||
},
|
||||
{ // 替换proto.sh文件内容
|
||||
{ // replace the contents of the proto.sh file
|
||||
Old: protoShellFileMark,
|
||||
New: protoShellServiceTmplCode,
|
||||
},
|
||||
@@ -166,7 +166,7 @@ func addRPCPbFields(moduleName string, serverName string, projectName string, re
|
||||
Old: "serverNameExample",
|
||||
New: serverName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "server-name-example",
|
||||
New: xstrings.ToKebabCase(serverName),
|
||||
@@ -175,7 +175,7 @@ func addRPCPbFields(moduleName string, serverName string, projectName string, re
|
||||
Old: "projectNameExample",
|
||||
New: projectName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "project-name-example",
|
||||
New: xstrings.ToKebabCase(projectName),
|
||||
|
@@ -18,11 +18,11 @@ import (
|
||||
// RPCCommand generate rpc server codes
|
||||
func RPCCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
projectName string // 项目名称
|
||||
repoAddr string // 镜像仓库地址
|
||||
outPath string // 输出目录
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
projectName string // project name for deployment name
|
||||
repoAddr string // image repo address
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{
|
||||
Package: "model",
|
||||
JSONTag: true,
|
||||
@@ -86,19 +86,19 @@ func runGenRPCCommand(moduleName string, serverName string, projectName string,
|
||||
return errors.New("replacer is nil")
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
subDirs := []string{ // 指定处理的子目录
|
||||
// setting up template information
|
||||
subDirs := []string{ // specify the subdirectory for processing
|
||||
"sponge/api", "sponge/build", "cmd/serverNameExample_grpcExample", "sponge/configs", "sponge/deployments",
|
||||
"sponge/scripts", "sponge/internal", "sponge/third_party",
|
||||
}
|
||||
subFiles := []string{ // 指定处理的子文件
|
||||
subFiles := []string{ // specify the sub-documents to be processed
|
||||
"sponge/.gitignore", "sponge/.golangci.yml", "sponge/go.mod", "sponge/go.sum",
|
||||
"sponge/Jenkinsfile", "sponge/Makefile", "sponge/README.md",
|
||||
}
|
||||
ignoreDirs := []string{ // 指定子目录下忽略处理的目录
|
||||
ignoreDirs := []string{ // specify the directory in the subdirectory where processing is ignored
|
||||
"internal/handler", "internal/rpcclient", "internal/routers", "internal/types",
|
||||
}
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"types.pb.validate.go", "types.pb.go", // api/types
|
||||
"userExample.pb.go", "userExample.pb.validate.go", "userExample_grpc.pb.go", "userExample_router.pb.go", // api/serverNameExample/v1
|
||||
"userExample_http.go", "systemCode_http.go", // internal/ecode
|
||||
@@ -145,52 +145,52 @@ func addRPCFields(moduleName string, serverName string, projectName string, repo
|
||||
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
|
||||
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+serverName)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换model/userExample.go文件内容
|
||||
{ // replace the contents of the model/userExample.go file
|
||||
Old: modelFileMark,
|
||||
New: codes[parser.CodeTypeModel],
|
||||
},
|
||||
{ // 替换dao/userExample.go文件内容
|
||||
{ // replace the contents of the dao/userExample.go file
|
||||
Old: daoFileMark,
|
||||
New: codes[parser.CodeTypeDAO],
|
||||
},
|
||||
{ // 替换v1/userExample.proto文件内容
|
||||
{ // replace the contents of the v1/userExample.proto file
|
||||
Old: protoFileMark,
|
||||
New: codes[parser.CodeTypeProto],
|
||||
},
|
||||
{ // 替换scripts/proto.sh文件内容
|
||||
{ // replace the contents of the scripts/proto.sh file
|
||||
Old: protoShellFileMark,
|
||||
New: "",
|
||||
},
|
||||
{ // 替换service/userExample_client_test.go文件内容
|
||||
{ // replace the contents of the service/userExample_client_test.go file
|
||||
Old: serviceFileMark,
|
||||
New: adjustmentOfIDType(codes[parser.CodeTypeService]),
|
||||
},
|
||||
{ // 替换Dockerfile文件内容
|
||||
{ // replace the contents of the Dockerfile file
|
||||
Old: dockerFileMark,
|
||||
New: dockerFileGrpcCode,
|
||||
},
|
||||
{ // 替换Dockerfile_build文件内容
|
||||
{ // replace the contents of the Dockerfile_build file
|
||||
Old: dockerFileBuildMark,
|
||||
New: dockerFileBuildGrpcCode,
|
||||
},
|
||||
{ // 替换docker-compose.yml文件内容
|
||||
{ // replace the contents of the docker-compose.yml file
|
||||
Old: dockerComposeFileMark,
|
||||
New: dockerComposeFileGrpcCode,
|
||||
},
|
||||
{ // 替换*-deployment.yml文件内容
|
||||
{ // replace the contents of the *-deployment.yml file
|
||||
Old: k8sDeploymentFileMark,
|
||||
New: k8sDeploymentFileGrpcCode,
|
||||
},
|
||||
{ // 替换*-svc.yml文件内容
|
||||
{ // replace the contents of the *-svc.yml file
|
||||
Old: k8sServiceFileMark,
|
||||
New: k8sServiceFileGrpcCode,
|
||||
},
|
||||
// 替换github.com/zhufuyi/sponge/templates/sponge
|
||||
// replace github.com/zhufuyi/sponge/templates/sponge
|
||||
{
|
||||
Old: selfPackageName + "/" + r.GetSourcePath(),
|
||||
New: moduleName,
|
||||
},
|
||||
// 替换目录名称
|
||||
// replace directory name
|
||||
{
|
||||
Old: strings.Join([]string{"api", "userExample", "v1"}, gofile.GetPathDelimiter()),
|
||||
New: strings.Join([]string{"api", serverName, "v1"}, gofile.GetPathDelimiter()),
|
||||
@@ -209,7 +209,7 @@ func addRPCFields(moduleName string, serverName string, projectName string, repo
|
||||
},
|
||||
{
|
||||
Old: "api.userExample.v1",
|
||||
New: fmt.Sprintf("api.%s.v1", strings.ReplaceAll(serverName, "-", "_")), // protobuf package 不能存在"-"号
|
||||
New: fmt.Sprintf("api.%s.v1", strings.ReplaceAll(serverName, "-", "_")), // protobuf package no "-" signs allowed
|
||||
},
|
||||
{
|
||||
Old: "sponge api docs",
|
||||
@@ -223,7 +223,7 @@ func addRPCFields(moduleName string, serverName string, projectName string, repo
|
||||
Old: "serverNameExample",
|
||||
New: serverName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "server-name-example",
|
||||
New: xstrings.ToKebabCase(serverName),
|
||||
@@ -232,7 +232,7 @@ func addRPCFields(moduleName string, serverName string, projectName string, repo
|
||||
Old: "projectNameExample",
|
||||
New: projectName,
|
||||
},
|
||||
// docker镜像和k8s部署脚本替换
|
||||
// docker image and k8s deployment script replacement
|
||||
{
|
||||
Old: "project-name-example",
|
||||
New: xstrings.ToKebabCase(projectName),
|
||||
|
@@ -17,9 +17,9 @@ import (
|
||||
// ServiceCommand generate service codes
|
||||
func ServiceCommand() *cobra.Command {
|
||||
var (
|
||||
moduleName string // go.mod文件的module名称
|
||||
serverName string // 服务名称
|
||||
outPath string // 输出目录
|
||||
moduleName string // module name for go.mod
|
||||
serverName string // server name
|
||||
outPath string // output directory
|
||||
sqlArgs = sql2code.Args{
|
||||
Package: "model",
|
||||
JSONTag: true,
|
||||
@@ -93,11 +93,11 @@ func runGenServiceCommand(moduleName string, serverName string, codes map[string
|
||||
serverName = moduleName
|
||||
}
|
||||
|
||||
// 设置模板信息
|
||||
// setting up template information
|
||||
subDirs := []string{"internal/model", "internal/cache", "internal/dao",
|
||||
"internal/ecode", "internal/service", "api/serverNameExample"} // 只处理的指定子目录,如果为空或者没有指定的子目录,表示所有文件
|
||||
ignoreDirs := []string{} // 指定子目录下忽略处理的目录
|
||||
ignoreFiles := []string{ // 指定子目录下忽略处理的文件
|
||||
"internal/ecode", "internal/service", "api/serverNameExample"} // only the specified subdirectory is processed, if empty or no subdirectory is specified, it means all files
|
||||
ignoreDirs := []string{} // specify the directory in the subdirectory where processing is ignored
|
||||
ignoreFiles := []string{ // specify the files in the subdirectory to be ignored for processing
|
||||
"userExample.pb.go", "userExample.pb.validate.go", "userExample_grpc.pb.go", "userExample_router.pb.go", // api/serverNameExample
|
||||
"systemCode_http.go", "systemCode_rpc.go", "userExample_http.go", // internal/ecode
|
||||
"init.go", "init_test.go", // internal/model
|
||||
@@ -128,19 +128,19 @@ func addServiceFields(moduleName string, serverName string, r replacer.Replacer,
|
||||
fields = append(fields, deleteFieldsMark(r, serviceClientFile, startMark, endMark)...)
|
||||
fields = append(fields, deleteFieldsMark(r, serviceTestFile, startMark, endMark)...)
|
||||
fields = append(fields, []replacer.Field{
|
||||
{ // 替换model/userExample.go文件内容
|
||||
{ // replace the contents of the model/userExample.go file
|
||||
Old: modelFileMark,
|
||||
New: codes[parser.CodeTypeModel],
|
||||
},
|
||||
{ // 替换dao/userExample.go文件内容
|
||||
{ // replace the contents of the dao/userExample.go file
|
||||
Old: daoFileMark,
|
||||
New: codes[parser.CodeTypeDAO],
|
||||
},
|
||||
{ // 替换v1/userExample.proto文件内容
|
||||
{ // replace the contents of the v1/userExample.proto file
|
||||
Old: protoFileMark,
|
||||
New: codes[parser.CodeTypeProto],
|
||||
},
|
||||
{ // 替换service/userExample_client_test.go文件内容
|
||||
{ // replace the contents of the service/userExample_client_test.go file
|
||||
Old: serviceFileMark,
|
||||
New: adjustmentOfIDType(codes[parser.CodeTypeService]),
|
||||
},
|
||||
@@ -152,7 +152,7 @@ func addServiceFields(moduleName string, serverName string, r replacer.Replacer,
|
||||
Old: "github.com/zhufuyi/sponge",
|
||||
New: moduleName,
|
||||
},
|
||||
// 替换目录名称
|
||||
// replace directory name
|
||||
{
|
||||
Old: strings.Join([]string{"api", "serverNameExample", "v1"}, gofile.GetPathDelimiter()),
|
||||
New: strings.Join([]string{"api", serverName, "v1"}, gofile.GetPathDelimiter()),
|
||||
@@ -163,7 +163,7 @@ func addServiceFields(moduleName string, serverName string, r replacer.Replacer,
|
||||
},
|
||||
{
|
||||
Old: "api.serverNameExample.v1",
|
||||
New: fmt.Sprintf("api.%s.v1", strings.ReplaceAll(serverName, "-", "_")), // protobuf package 不能存在"-"号
|
||||
New: fmt.Sprintf("api.%s.v1", strings.ReplaceAll(serverName, "-", "_")), // protobuf package no "-" signs allowed
|
||||
},
|
||||
{
|
||||
Old: "userExampleNO = 1",
|
||||
|
@@ -1,17 +1,17 @@
|
||||
package generate
|
||||
|
||||
const (
|
||||
dockerFileHTTPCode = `# 添加curl,用在http服务的检查,如果用部署在k8s,可以不用安装
|
||||
dockerFileHTTPCode = `# add curl, used for http service checking, can be installed without it if deployed in k8s
|
||||
RUN apk add curl
|
||||
|
||||
COPY configs/ /app/configs/
|
||||
COPY serverNameExample /app/serverNameExample
|
||||
RUN chmod +x /app/serverNameExample
|
||||
|
||||
# http端口
|
||||
# http port
|
||||
EXPOSE 8080`
|
||||
|
||||
dockerFileGrpcCode = `# 添加grpc_health_probe,用在grpc服务的健康检查
|
||||
dockerFileGrpcCode = `# add grpc_health_probe for health check of grpc services
|
||||
COPY grpc_health_probe /bin/grpc_health_probe
|
||||
RUN chmod +x /bin/grpc_health_probe
|
||||
|
||||
@@ -19,31 +19,31 @@ COPY configs/ /app/configs/
|
||||
COPY serverNameExample /app/serverNameExample
|
||||
RUN chmod +x /app/serverNameExample`
|
||||
|
||||
dockerFileBuildHTTPCode = `# 添加curl,用在http服务的检查,如果用部署在k8s,可以不用安装
|
||||
dockerFileBuildHTTPCode = `# add curl, used for http service checking, can be installed without it if deployed in k8s
|
||||
RUN apk add curl
|
||||
|
||||
COPY --from=build /serverNameExample /app/serverNameExample
|
||||
COPY --from=build /go/src/serverNameExample/configs/serverNameExample.yml /app/configs/serverNameExample.yml
|
||||
|
||||
# http端口
|
||||
# http port
|
||||
EXPOSE 8080`
|
||||
|
||||
dockerFileBuildGrpcCode = `# 添加grpc_health_probe,用在grpc服务的健康检查
|
||||
dockerFileBuildGrpcCode = `# add grpc_health_probe for health check of grpc services
|
||||
COPY --from=build /grpc_health_probe /bin/grpc_health_probe
|
||||
COPY --from=build /serverNameExample /app/serverNameExample
|
||||
COPY --from=build /go/src/serverNameExample/configs/serverNameExample.yml /app/configs/serverNameExample.yml`
|
||||
|
||||
dockerComposeFileHTTPCode = ` ports:
|
||||
- "8080:8080" # http端口
|
||||
- "8080:8080" # http port
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"] # http健康检查,注:镜像必须包含curl命令`
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"] # http health check, note: mirror must contain curl command`
|
||||
|
||||
dockerComposeFileGrpcCode = `
|
||||
ports:
|
||||
- "8282:8282" # grpc服务端口
|
||||
- "8283:8283" # grpc metrics端口
|
||||
- "8282:8282" # grpc port
|
||||
- "8283:8283" # grpc metrics or pprof port
|
||||
healthcheck:
|
||||
test: ["CMD", "grpc_health_probe", "-addr=localhost:8282"] # grpc健康检查,注:镜像必须包含grpc_health_probe命令`
|
||||
test: ["CMD", "grpc_health_probe", "-addr=localhost:8282"] # grpc health check, note: the image must contain the grpc_health_probe command`
|
||||
|
||||
k8sDeploymentFileHTTPCode = `
|
||||
ports:
|
||||
@@ -143,7 +143,7 @@ func NewCenter(configFile string) (*Center, error) {
|
||||
`
|
||||
|
||||
protoShellHandlerCode = `
|
||||
# 生成swagger文档,所有文件合并到docs/apis.swagger.json
|
||||
# generate the swagger document and merge all files into 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
|
||||
@@ -152,8 +152,9 @@ checkResult $?
|
||||
|
||||
moduleName=$(cat docs/gen.info | head -1 | cut -d , -f 1)
|
||||
serverName=$(cat docs/gen.info | head -1 | cut -d , -f 2)
|
||||
# 共生成4个文件,分别是注册路由文件_*router.pb.go(保存在protobuf文件同一目录)、注入路由文件*_handler.pb.go(默认保存路径在internal/routers)、
|
||||
# 逻辑代码模板文件*_logic.go(默认保存路径在internal/handler), 返回错误码模板文件*_http.go(默认保存路径在internal/ecode)
|
||||
# A total of four files are generated, namely the registration route file _*router.pb.go (saved in the same directory as the protobuf file),
|
||||
# the injection route file *_handler.pb.go (saved by default in the path internal/routers), the logical code template file*_logic.go (default path is in internal/handler),
|
||||
# return error code template file*_http.go (default path is in internal/ecode)
|
||||
protoc --proto_path=. --proto_path=./third_party \
|
||||
--go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=handler \
|
||||
--go-gin_opt=moduleName=${moduleName} --go-gin_opt=serverName=${serverName} \
|
||||
@@ -162,7 +163,7 @@ protoc --proto_path=. --proto_path=./third_party \
|
||||
checkResult $?`
|
||||
|
||||
protoShellServiceCode = `
|
||||
# 生成swagger文档,所有文件合并到docs/apis.swagger.json
|
||||
# Generate the swagger document and merge all files into 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
|
||||
@@ -171,8 +172,9 @@ checkResult $?
|
||||
|
||||
moduleName=$(cat docs/gen.info | head -1 | cut -d , -f 1)
|
||||
serverName=$(cat docs/gen.info | head -1 | cut -d , -f 2)
|
||||
# 共生成4个文件,分别是注册路由文件_*router.pb.go(保存在protobuf文件同一目录)、注入路由文件*_service.pb.go(默认保存路径在internal/routers)、
|
||||
# 逻辑代码模板文件*_logic.go(默认保存路径在internal/service), 返回错误码模板文件*_rpc.go(默认保存路径在internal/ecode)
|
||||
# A total of 4 files are generated, namely the registration route file _*router.pb.go (saved in the same directory as the protobuf file),
|
||||
# the injection route file *_service.pb.go (default save path in internal/routers), the logical code template file*_logic.go (saved in internal/service by default),
|
||||
# return error code template file*_rpc.go (saved in internal/ecode by default)
|
||||
protoc --proto_path=. --proto_path=./third_party \
|
||||
--go-gin_out=. --go-gin_opt=paths=source_relative --go-gin_opt=plugin=service \
|
||||
--go-gin_opt=moduleName=${moduleName} --go-gin_opt=serverName=${serverName} \
|
||||
@@ -181,16 +183,9 @@ protoc --proto_path=. --proto_path=./third_party \
|
||||
checkResult $?`
|
||||
|
||||
protoShellServiceTmplCode = `
|
||||
# 生成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 $?
|
||||
|
||||
moduleName=$(cat docs/gen.info | head -1 | cut -d , -f 1)
|
||||
serverName=$(cat docs/gen.info | head -1 | cut -d , -f 2)
|
||||
# 共生成2个文件,分别是逻辑代码模板文件*.go(默认保存路径在internal/service), 返回错误码模板文件*_rpc.go(默认保存路径在internal/ecode)
|
||||
# Generate 2 files, a logic code template file *.go (default save path in internal/service), a return error code template file *_rpc.go (default save path in internal/ecode)
|
||||
protoc --proto_path=. --proto_path=./third_party \
|
||||
--go-rpc-tmpl_out=. --go-rpc-tmpl_opt=paths=source_relative \
|
||||
--go-rpc-tmpl_opt=moduleName=${moduleName} --go-rpc-tmpl_opt=serverName=${serverName} \
|
||||
|
@@ -35,7 +35,7 @@ Examples:
|
||||
gobash.SetExecutorPath(executor)
|
||||
}
|
||||
fmt.Println("initialize sponge codes ......")
|
||||
// 下载sponge模板代码
|
||||
// download sponge template code
|
||||
err := runUpdateCommand(enableCNGoProxy)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -45,7 +45,7 @@ Examples:
|
||||
return err
|
||||
}
|
||||
|
||||
// 安装依赖插件
|
||||
// installing dependent plug-ins
|
||||
_, lackNames := checkInstallTools()
|
||||
installTools(lackNames, enableCNGoProxy)
|
||||
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// MicroCommand micro命令
|
||||
// MicroCommand micro commands
|
||||
func MicroCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "micro",
|
||||
|
@@ -8,13 +8,12 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Version 命令版本号
|
||||
var (
|
||||
version = "v0.0.0"
|
||||
versionFile = os.TempDir() + "/sponge/.github/version"
|
||||
)
|
||||
|
||||
// NewRootCMD 命令入口
|
||||
// NewRootCMD command entry
|
||||
func NewRootCMD() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "sponge",
|
||||
|
@@ -76,7 +76,7 @@ func runUpdateCommand(enableCNGoProxy bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 复制模板文件到临时目录下
|
||||
// copy the template files to a temporary directory
|
||||
func copyToTempDir() (string, error) {
|
||||
result, err := gobash.Exec("go env GOPATH")
|
||||
if err != nil {
|
||||
@@ -87,7 +87,7 @@ func copyToTempDir() (string, error) {
|
||||
return "", fmt.Errorf("$GOPATH is empty, you need set $GOPATH in your $PATH")
|
||||
}
|
||||
|
||||
// 找出新版本sponge代码文件夹
|
||||
// find the new version of the sponge code directory
|
||||
command := "ls $(go env GOPATH)/pkg/mod/github.com/zhufuyi | grep sponge@ | sort -r | head -1"
|
||||
result, err = gobash.Exec(command)
|
||||
if err != nil {
|
||||
@@ -100,7 +100,7 @@ func copyToTempDir() (string, error) {
|
||||
srcDir := fmt.Sprintf("%s/pkg/mod/github.com/zhufuyi/%s", gopath, latestSpongeDirName)
|
||||
destDir := os.TempDir() + "/sponge"
|
||||
|
||||
// 复制到临时目录
|
||||
// copy to temporary directory
|
||||
_ = os.RemoveAll(adaptPathDelimiter(destDir))
|
||||
command = fmt.Sprintf(`cp -rf %s %s`, adaptPathDelimiter(srcDir), adaptPathDelimiter(destDir))
|
||||
_, err = gobash.Exec(command)
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewWebCommand web代码命令
|
||||
// NewWebCommand web commands
|
||||
func NewWebCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "web",
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// 用来定位目录
|
||||
// used to locate a directory
|
||||
|
||||
var basePath string
|
||||
|
||||
@@ -15,7 +15,7 @@ func init() {
|
||||
basePath = filepath.Dir(currentFile)
|
||||
}
|
||||
|
||||
// Path 返回绝对路径
|
||||
// Path return absolute path
|
||||
func Path(rel string) string {
|
||||
if filepath.IsAbs(rel) {
|
||||
return rel
|
||||
|
@@ -1,90 +1,90 @@
|
||||
# 生成go struct命令:sponge config --server-dir=./serverDir
|
||||
# Generate the go struct command: sponge config --server-dir=./serverDir
|
||||
|
||||
# app 设置
|
||||
# app settings
|
||||
app:
|
||||
name: "serverNameExample" # 服务名称
|
||||
env: "dev" # 运行环境,dev:开发环境,prod:生产环境,test:测试环境
|
||||
version: "v0.0.0" # 版本
|
||||
host: "192.168.3.27" # 主机名称或ip
|
||||
enablePprof: true # 是否开启性能分析功能,true:开启,false:关闭
|
||||
enableStat: true # 是否开启打印统计信息,true:开启,false:关闭
|
||||
enableMetrics: true # 是否开启指标采集,true:开启,false:关闭
|
||||
enableLimit: false # 是否开启限流(自适应),true:开启,false:关闭
|
||||
enableCircuitBreaker: false # 是否开启熔断(自适应),true:开启,false:关闭
|
||||
enableTracing: false # 是否开启链路跟踪,true:开启,false:关闭,如果为true必须设置jaeger配置
|
||||
tracingSamplingRate: 1.0 # 链路采样率,0~1之间,0表示禁止采样,1表示采样所有链路
|
||||
registryDiscoveryType: "" # 注册与发现类型:consul、etcd、nacos,如果为空,不使用注册与发现
|
||||
cacheType: "memory" # 缓存类型,memory、redis,如果设置为redis,必须设置redis配置
|
||||
name: "serverNameExample" # server name
|
||||
env: "dev" # runtime environment, dev: development environment, prod: production environment, test: test environment
|
||||
version: "v0.0.0"
|
||||
host: "192.168.3.27" # host name or ip
|
||||
enablePprof: true # whether to enable performance analysis, true:enable, false:disable
|
||||
enableStat: true # whether to enable printing statistics, true:enable, false:disable
|
||||
enableMetrics: true # whether to enable indicator collection, true:enable, false:disable
|
||||
enableLimit: false # whether to turn on rate limiting (adaptive), true:on, false:off
|
||||
enableCircuitBreaker: false # whether to turn on circuit breaker(adaptive), true:on, false:off
|
||||
enableTracing: false # whether to enable tracking, true:enable, false:disable, if true jaeger configuration must be set
|
||||
tracingSamplingRate: 1.0 # tracing sampling rate, between 0 and 1, 0 means no sampling, 1 means sampling all links
|
||||
registryDiscoveryType: "" # registry and discovery types: consul, etcd, nacos, if empty, registration and discovery are not used
|
||||
cacheType: "memory" # cache type, memory, redis, if set to redis, must set redis configuration
|
||||
|
||||
|
||||
# http 设置
|
||||
# http server settings
|
||||
http:
|
||||
port: 8080 # 监听端口
|
||||
readTimeout: 3 # 读超时,单位(秒)
|
||||
writeTimeout: 60 # 写超时,单位(秒),如果enablePprof为true,需要大于60s,pprof做profiling的默认值是60s
|
||||
port: 8080 # listening port
|
||||
readTimeout: 3 # read timeout, unit(second)
|
||||
writeTimeout: 60 # write timeout, unit(second), if enablePprof is true, it needs to be greater than 60s, the default value for pprof to do profiling is 60s
|
||||
|
||||
|
||||
# grpc server 设置
|
||||
# grpc server settings
|
||||
grpc:
|
||||
port: 8282 # rpc监听端口
|
||||
httpPort: 8283 # 获取pprof和监控指标http端口
|
||||
readTimeout: 3 # 读超时,单位(秒)
|
||||
writeTimeout: 3 # 写超时,单位(秒)
|
||||
port: 8282 # listening port
|
||||
httpPort: 8283 # get pprof and monitor indicator ports
|
||||
readTimeout: 3 # read timeout, unit(second)
|
||||
writeTimeout: 3 # write timeout, unit(second)
|
||||
|
||||
|
||||
# grpc client 设置,可以设置多个rpc服务
|
||||
# grpc client settings, multiple rpc services can be set up
|
||||
grpcClient:
|
||||
- name: "serverNameExample" # rpc服务名称,用来服务发现使用
|
||||
host: "192.168.3.27" # rpc服务地址,直连时使用
|
||||
port: 8282 # rpc服务端口
|
||||
registryDiscoveryType: "" # 注册与发现类型:consul、etcd、nacos,如果为空,不使用注册与发现
|
||||
- name: "serverNameExample" # rpc service name, used for service discovery
|
||||
host: "192.168.3.27" # rpc service address, used for direct connection
|
||||
port: 8282 # rpc service port
|
||||
registryDiscoveryType: "" # registration and discovery types: consul, etcd, nacos, if empty, registration and discovery are not used
|
||||
|
||||
|
||||
# logger 设置
|
||||
# logger settings
|
||||
logger:
|
||||
level: "info" # 输出日志级别 debug, info, warn, error,默认是debug
|
||||
format: "console" # 输出格式,console或json,默认是console
|
||||
isSave: false # false:输出到终端,true:输出到文件,默认是false
|
||||
level: "info" # output log levels debug, info, warn, error, default is debug
|
||||
format: "console" # output format, console or json, default is console
|
||||
isSave: false # false:output to terminal, true:output to file, default is false
|
||||
|
||||
|
||||
# mysql 设置
|
||||
# mysql settings
|
||||
mysql:
|
||||
# dsn格式:<user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
|
||||
# dsn format, <user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
|
||||
dsn: "root:123456@(192.168.3.37:3306)/account?parseTime=true&loc=Local&charset=utf8,utf8mb4"
|
||||
enableLog: true # 是否开启打印所有日志
|
||||
slowThreshold: 0 # 如果大于0,只打印时间大于阈值的日志,优先级比enableLog高,单位(毫秒)
|
||||
maxIdleConns: 3 # 设置空闲连接池中连接的最大数量
|
||||
maxOpenConns: 100 # 设置打开数据库连接的最大数量
|
||||
connMaxLifetime: 30 # 设置了连接可复用的最大时间,单位(分钟)
|
||||
enableLog: true # whether to turn on printing of all logs
|
||||
slowThreshold: 0 # if greater than 0, only print logs with a time greater than the threshold, with a higher priority than enableLog, in (ms)
|
||||
maxIdleConns: 3 # set the maximum number of connections in the idle connection pool
|
||||
maxOpenConns: 100 # set the maximum number of open database connections
|
||||
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes
|
||||
|
||||
|
||||
# redis 设置
|
||||
# redis settings
|
||||
redis:
|
||||
# dsn格式 [user]:<pass>@]127.0.0.1:6379/[db],默认用户为default
|
||||
# dsn format, [user]:<pass>@]127.0.0.1:6379/[db], the default user is default
|
||||
dsn: "default:123456@192.168.3.37:6379/0"
|
||||
dialTimeout: 10 # 链接超时,单位(秒)
|
||||
readTimeout: 2 # 读超时,单位(秒)
|
||||
writeTimeout: 2 # 写超时,单位(秒)
|
||||
dialTimeout: 10 # connection timeout, unit(second)
|
||||
readTimeout: 2 # read timeout, unit(second)
|
||||
writeTimeout: 2 # write timeout, unit(second)
|
||||
|
||||
|
||||
# jaeger 配置
|
||||
# jaeger settings
|
||||
jaeger:
|
||||
agentHost: "192.168.3.37"
|
||||
agentPort: 6831
|
||||
|
||||
|
||||
# consul 配置
|
||||
# consul settings
|
||||
consul:
|
||||
addr: "192.168.3.37:8500"
|
||||
|
||||
|
||||
# etcd 配置
|
||||
# etcd settings
|
||||
etcd:
|
||||
addrs: ["192.168.3.37:2379"]
|
||||
|
||||
|
||||
# nacos 设置,用在服务注册发现
|
||||
# nacos settings, used in service registration discovery
|
||||
nacosRd:
|
||||
ipAddr: "192.168.3.37"
|
||||
port: 8848
|
||||
namespaceID: "3454d2b5-2455-4d0e-bf6d-e033b086bb4c" # 名称空间id
|
||||
namespaceID: "3454d2b5-2455-4d0e-bf6d-e033b086bb4c" # namespace id
|
||||
|
@@ -1,12 +1,12 @@
|
||||
# 生成go struct命令:sponge config --server-dir=./serverDir
|
||||
# Generate the go struct command: sponge config --server-dir=./serverDir
|
||||
|
||||
# nacos 设置
|
||||
# nacos settings
|
||||
nacos:
|
||||
ipAddr: "192.168.3.37" # 服务地址
|
||||
port: 8848 # 服务端口
|
||||
scheme: "http" # http或https
|
||||
ipAddr: "192.168.3.37" # server address
|
||||
port: 8848 # listening port
|
||||
scheme: "http" # http or https
|
||||
contextPath: "/nacos" # path
|
||||
namespaceID: "3454d2b5-2455-4d0e-bf6d-e033b086bb4c" # 名称空间id
|
||||
group: "dev" # 分组,dev, prod, test
|
||||
dataID: "serverNameExample.yml" # 配置文件id
|
||||
format: "yaml" # 配置文件类型: json,yaml,toml
|
||||
namespaceID: "3454d2b5-2455-4d0e-bf6d-e033b086bb4c" # namespace id
|
||||
group: "dev" # group name: dev, prod, test
|
||||
dataID: "serverNameExample.yml" # config file id
|
||||
format: "yaml" # configuration file type: json,yaml,toml
|
||||
|
@@ -1,11 +1,12 @@
|
||||
|
||||
启动服务之前先把配置文件复制到configs目录下
|
||||
copy the configuration file to the configs directory before starting the service
|
||||
|
||||
```
|
||||
├── configs
|
||||
│ └── serverNameExample.yml
|
||||
└── docker-compose.yml
|
||||
```
|
||||
|
||||
启动服务:
|
||||
running services:
|
||||
|
||||
> docker-compose up
|
||||
|
@@ -11,15 +11,15 @@ services:
|
||||
# todo generate docker-compose.yml code for http or grpc here
|
||||
# delete the templates code start
|
||||
ports:
|
||||
- "8080:8080" # http端口
|
||||
- "8282:8282" # grpc服务端口
|
||||
- "8283:8283" # grpc metrics端口
|
||||
# todo 根据服务类型(http或grpc)选择健康检查
|
||||
- "8080:8080" # http port
|
||||
- "8282:8282" # rpc port
|
||||
- "8283:8283" # rpc metrics or pprof port
|
||||
# select health check according to service type (http or grpc)
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"] # http健康检查,注:镜像必须包含curl命令
|
||||
#test: ["CMD", "grpc_health_probe", "-addr=localhost:8282"] # grpc健康检查,注:镜像必须包含grpc_health_probe命令
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"] # http health check, note: mirror must contain curl command
|
||||
#test: ["CMD", "grpc_health_probe", "-addr=localhost:8282"] # grpc health check, note: the image must contain the grpc_health_probe command
|
||||
# delete the templates code end
|
||||
interval: 10s # 间隔时间
|
||||
timeout: 5s # 超时时间
|
||||
retries: 3 # 重试次数
|
||||
start_period: 10s # 启动多久后开始检查
|
||||
interval: 10s # interval time
|
||||
timeout: 5s # timeout time
|
||||
retries: 3 # number of retries
|
||||
start_period: 10s # how long after start-up does the check begin
|
||||
|
@@ -1,4 +1,4 @@
|
||||
部署服务到k8s前,在已经登录镜像仓库的docker主机中,创建一个为k8s拉取镜像权限的Secret,命令如下:
|
||||
Before deploying the service to k8s, create a Secret that pulls image permissions for k8s in a docker host that is already logged into the image repository, with the following command.
|
||||
|
||||
```bash
|
||||
kubectl create secret generic docker-auth-secret \
|
||||
@@ -8,20 +8,20 @@ kubectl create secret generic docker-auth-secret \
|
||||
|
||||
<br>
|
||||
|
||||
启动服务:
|
||||
run server:
|
||||
|
||||
> kubectl apply -f ./*namespace.yml
|
||||
> kubectl apply -f ./
|
||||
|
||||
查看启动状态:
|
||||
view the start-up status.
|
||||
|
||||
> kubectl get all -n project-name-example
|
||||
|
||||
<br>
|
||||
|
||||
简单测试http端口
|
||||
simple test of http port
|
||||
|
||||
```bash
|
||||
# 在本机端口映射到服务的http端口
|
||||
# mapping to the http port of the service on the local port
|
||||
kubectl port-forward --address=0.0.0.0 service/<server-name-example-svc> 8080:8080 -n <project-name-example>
|
||||
```
|
||||
|
@@ -5,88 +5,91 @@ metadata:
|
||||
namespace: project-name-example
|
||||
data:
|
||||
serverNameExample.yml: |-
|
||||
# app 设置
|
||||
# app settings
|
||||
app:
|
||||
name: "serverNameExample" # 服务名称
|
||||
env: "dev" # 运行环境,dev:开发环境,prod:生产环境,pre:预生产环境
|
||||
version: "v0.0.0" # 版本
|
||||
host: "127.0.0.1" # 主机名称或ip
|
||||
enableProfile: false # 是否开启性能分析功能,true:开启,false:关闭
|
||||
enableMetrics: true # 是否开启指标采集,true:开启,false:关闭
|
||||
enableLimit: false # 是否开启限流,true:开启,false:关闭
|
||||
enableTracing: false # 是否开启链路跟踪,true:开启,false:关闭
|
||||
enableRegistryDiscovery: false # 是否开启注册与发现,true:开启,false:关闭
|
||||
name: "serverNameExample" # server name
|
||||
env: "dev" # runtime environment, dev: development environment, prod: production environment, test: test environment
|
||||
version: "v0.0.0"
|
||||
host: "192.168.3.27" # host name or ip
|
||||
enablePprof: true # whether to enable performance analysis, true:enable, false:disable
|
||||
enableStat: true # whether to enable printing statistics, true:enable, false:disable
|
||||
enableMetrics: true # whether to enable indicator collection, true:enable, false:disable
|
||||
enableLimit: false # whether to turn on rate limiting (adaptive), true:on, false:off
|
||||
enableCircuitBreaker: false # whether to turn on circuit breaker(adaptive), true:on, false:off
|
||||
enableTracing: false # whether to enable tracking, true:enable, false:disable, if true jaeger configuration must be set
|
||||
tracingSamplingRate: 1.0 # tracing sampling rate, between 0 and 1, 0 means no sampling, 1 means sampling all links
|
||||
registryDiscoveryType: "" # registry and discovery types: consul, etcd, nacos, if empty, registration and discovery are not used
|
||||
cacheType: "memory" # cache type, memory, redis, if set to redis, must set redis configuration
|
||||
|
||||
|
||||
# http 设置
|
||||
# http server settings
|
||||
http:
|
||||
port: 8080 # 监听端口
|
||||
readTimeout: 3 # 读超时,单位(秒)
|
||||
writeTimeout: 90 # 写超时,单位(秒),如果enableProfile为true,需要大于60s,pprof做profiling的默认值是60s
|
||||
port: 8080 # listening port
|
||||
readTimeout: 3 # read timeout, unit(second)
|
||||
writeTimeout: 60 # write timeout, unit(second), if enablePprof is true, it needs to be greater than 60s, the default value for pprof to do profiling is 60s
|
||||
|
||||
|
||||
# grpc 设置
|
||||
# grpc server settings
|
||||
grpc:
|
||||
port: 8282 # 监听端口
|
||||
metricsPort: 8283 # 获取指标http端口
|
||||
readTimeout: 3 # 读超时,单位(秒)
|
||||
writeTimeout: 3 # 写超时,单位(秒)
|
||||
port: 8282 # listening port
|
||||
httpPort: 8283 # get pprof and monitor indicator ports
|
||||
readTimeout: 3 # read timeout, unit(second)
|
||||
writeTimeout: 3 # write timeout, unit(second)
|
||||
|
||||
|
||||
# logger 设置
|
||||
# grpc client settings, multiple rpc services can be set up
|
||||
grpcClient:
|
||||
- name: "serverNameExample" # rpc service name, used for service discovery
|
||||
host: "192.168.3.27" # rpc service address, used for direct connection
|
||||
port: 8282 # rpc service port
|
||||
registryDiscoveryType: "" # registration and discovery types: consul, etcd, nacos, if empty, registration and discovery are not used
|
||||
|
||||
|
||||
# logger settings
|
||||
logger:
|
||||
level: "info" # 输出日志级别 debug, info, warn, error,默认是debug
|
||||
format: "console" # 输出格式,console或json,默认是console
|
||||
isSave: false # false:输出到终端,true:输出到文件,默认是false
|
||||
logFileConfig: # isSave=true时有效
|
||||
filename: "out.log" # 文件名称,默认值out.log
|
||||
maxSize: 20 # 最大文件大小(MB),默认值10MB
|
||||
maxBackups: 50 # 保留旧文件的最大个数,默认值100个
|
||||
maxAge: 15 # 保留旧文件的最大天数,默认值30天
|
||||
isCompression: true # 是否压缩/归档旧文件,默认值false
|
||||
level: "info" # output log levels debug, info, warn, error, default is debug
|
||||
format: "console" # output format, console or json, default is console
|
||||
isSave: false # false:output to terminal, true:output to file, default is false
|
||||
|
||||
|
||||
# mysql 设置
|
||||
# mysql settings
|
||||
mysql:
|
||||
# dsn格式:<user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
|
||||
# dsn format, <user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
|
||||
dsn: "root:123456@(192.168.3.37:3306)/account?parseTime=true&loc=Local&charset=utf8,utf8mb4"
|
||||
enableLog: true # 是否开启打印所有日志
|
||||
slowThreshold: 0 # 如果大于0,只打印时间大于阈值的日志,优先级比enableLog高,单位(毫秒)
|
||||
maxIdleConns: 3 #设置空闲连接池中连接的最大数量
|
||||
maxOpenConns: 50 # 设置打开数据库连接的最大数量
|
||||
connMaxLifetime: 30 # 设置了连接可复用的最大时间,单位(分钟)
|
||||
enableLog: true # whether to turn on printing of all logs
|
||||
slowThreshold: 0 # if greater than 0, only print logs with a time greater than the threshold, with a higher priority than enableLog, in (ms)
|
||||
maxIdleConns: 3 # set the maximum number of connections in the idle connection pool
|
||||
maxOpenConns: 100 # set the maximum number of open database connections
|
||||
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes
|
||||
|
||||
|
||||
# redis 设置
|
||||
# redis settings
|
||||
redis:
|
||||
# dsn只适合redis6版本以上,默认用户为default,url格式 [user]:<pass>@]127.0.0.1:6379/[db]
|
||||
dsn: "default:123456@192.168.3.37:6379"
|
||||
# 适合各个版本redis
|
||||
addr: 127.0.0.1:6379
|
||||
password: "123456"
|
||||
dB: 0
|
||||
minIdleConn: 20
|
||||
dialTimeout: 30 # 链接超时,单位(秒)
|
||||
readTimeout: 500 # 读超时,单位(毫秒)
|
||||
writeTimeout: 500 # 写超时,单位(毫秒)
|
||||
poolSize: 100
|
||||
poolTimeout: 200 # 连接池超时,单位(秒)
|
||||
# dsn format, [user]:<pass>@]127.0.0.1:6379/[db], the default user is default
|
||||
dsn: "default:123456@192.168.3.37:6379/0"
|
||||
dialTimeout: 10 # connection timeout, unit(second)
|
||||
readTimeout: 2 # read timeout, unit(second)
|
||||
writeTimeout: 2 # write timeout, unit(second)
|
||||
|
||||
|
||||
# jaeger配置
|
||||
# jaeger settings
|
||||
jaeger:
|
||||
agentHost: "192.168.3.37"
|
||||
agentPort: "6831"
|
||||
samplingRate: 1.0 # 采样率,0~1之间,0表示禁止采样,大于等于1表示采样所有链路
|
||||
agentPort: 6831
|
||||
|
||||
|
||||
# etcd配置
|
||||
# consul settings
|
||||
consul:
|
||||
addr: "192.168.3.37:8500"
|
||||
|
||||
|
||||
# etcd settings
|
||||
etcd:
|
||||
addrs: ["192.168.3.37:2379"]
|
||||
|
||||
|
||||
# limit配置
|
||||
rateLimiter:
|
||||
dimension: "path" # 限流维度,支持path和ip两种,默认是path
|
||||
qpsLimit: 1000 # 持续每秒允许成功请求数,默认是500
|
||||
maxLimit: 2000 # 瞬时最大允许峰值,默认是1000,通常大于qpsLimit
|
||||
# nacos settings, used in service registration discovery
|
||||
nacosRd:
|
||||
ipAddr: "192.168.3.37"
|
||||
port: 8848
|
||||
namespaceID: "3454d2b5-2455-4d0e-bf6d-e033b086bb4c" # namespace id
|
||||
|
@@ -40,8 +40,8 @@ spec:
|
||||
containerPort: 8282
|
||||
- name: metrics-port
|
||||
containerPort: 8283
|
||||
# 根据服务类型(http或grpc)选择健康检查
|
||||
# 就绪探测
|
||||
# select health check according to service type (http or grpc)
|
||||
# emotional Detection
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
port: http-port
|
||||
@@ -53,7 +53,7 @@ spec:
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
# 容器存活探测
|
||||
# container Survival Detection
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
port: http-port
|
||||
@@ -66,7 +66,7 @@ spec:
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
# todo 对于私有仓库,需要先创建Secret(这里名称docker-auth-secret)存放登录docker的账号和密码
|
||||
# todo for private repositories, you need to create a secret (here docker-auth-secret) to store the account and password to log into docker
|
||||
imagePullSecrets:
|
||||
- name: docker-auth-secret
|
||||
volumes:
|
||||
|
@@ -313,49 +313,49 @@
|
||||
<td>name</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>名称 </p></td>
|
||||
<td><p>name </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>email</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>邮件 </p></td>
|
||||
<td><p>email </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>password</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>密码 </p></td>
|
||||
<td><p>password </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>phone</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>手机号码 </p></td>
|
||||
<td><p>phone number </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>avatar</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>头像 </p></td>
|
||||
<td><p>avatar </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>age</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>年龄 </p></td>
|
||||
<td><p>age </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>gender</td>
|
||||
<td><a href="#api.serverNameExample.v1.GenderType">GenderType</a></td>
|
||||
<td></td>
|
||||
<td><p>性别,0:未知,1:男,2:女 </p></td>
|
||||
<td><p>gender, 1:Male, 2:Female, other values:unknown </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
@@ -751,63 +751,63 @@
|
||||
<td>name</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>名称 </p></td>
|
||||
<td><p>name </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>email</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>邮件 </p></td>
|
||||
<td><p>email </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>password</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>密码 </p></td>
|
||||
<td><p>password </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>phone</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>手机号码 </p></td>
|
||||
<td><p>phone number </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>avatar</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>头像 </p></td>
|
||||
<td><p>avatar </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>age</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>年龄 </p></td>
|
||||
<td><p>age </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>gender</td>
|
||||
<td><a href="#api.serverNameExample.v1.GenderType">GenderType</a></td>
|
||||
<td></td>
|
||||
<td><p>性别,1:男,2:女 </p></td>
|
||||
<td><p>gender, 1:Male, 2:Female, other values:unknown </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>status</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>账号状态 </p></td>
|
||||
<td><p>account status </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>login_at</td>
|
||||
<td><a href="#int64">int64</a></td>
|
||||
<td></td>
|
||||
<td><p>登录时间戳 </p></td>
|
||||
<td><p>login timestamp </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
@@ -865,70 +865,70 @@
|
||||
<td>name</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>名称 </p></td>
|
||||
<td><p>name </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>email</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>邮件 </p></td>
|
||||
<td><p>email </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>phone</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>手机号码 </p></td>
|
||||
<td><p>phone number </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>avatar</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>头像 </p></td>
|
||||
<td><p>avatar </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>age</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>年龄 </p></td>
|
||||
<td><p>age </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>gender</td>
|
||||
<td><a href="#api.serverNameExample.v1.GenderType">GenderType</a></td>
|
||||
<td></td>
|
||||
<td><p>性别,1:男,2:女 </p></td>
|
||||
<td><p>gender, 1:Male, 2:Female, other values:unknown </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>status</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>账号状态 </p></td>
|
||||
<td><p>account status </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>login_at</td>
|
||||
<td><a href="#int64">int64</a></td>
|
||||
<td></td>
|
||||
<td><p>登录时间戳 </p></td>
|
||||
<td><p>login timestamp </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>created_at</td>
|
||||
<td><a href="#int64">int64</a></td>
|
||||
<td></td>
|
||||
<td><p>创建时间 </p></td>
|
||||
<td><p>creation time </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>updated_at</td>
|
||||
<td><a href="#int64">int64</a></td>
|
||||
<td></td>
|
||||
<td><p>更新时间 </p></td>
|
||||
<td><p>update time </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
@@ -1127,28 +1127,28 @@
|
||||
<td>name</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>列名 </p></td>
|
||||
<td><p>column name </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>exp</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>表达式,值为空时默认为=,有=、!=、>、>=、<、<=、like七种类型 </p></td>
|
||||
<td><p>expressions, which default to = when the value is null, have =, ! =, >, >=, <, <=, like </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>value</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>列值 </p></td>
|
||||
<td><p>column value </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>logic</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>逻辑类型,值为空时默认为and,只有&(and)、||(or)两种类型 </p></td>
|
||||
<td><p>logical type, defaults to and when value is null, only &(and), ||(or) </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
@@ -1172,28 +1172,28 @@
|
||||
<td>page</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>页码,从0开始 </p></td>
|
||||
<td><p>page number, starting from 0 </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>limit</td>
|
||||
<td><a href="#int32">int32</a></td>
|
||||
<td></td>
|
||||
<td><p>每页行数 </p></td>
|
||||
<td><p>lines per page </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>sort</td>
|
||||
<td><a href="#string">string</a></td>
|
||||
<td></td>
|
||||
<td><p>排序字段,多列排序用逗号分隔 </p></td>
|
||||
<td><p>sorted fields, multi-column sorting separated by commas </p></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>columns</td>
|
||||
<td><a href="#types.Column">Column</a></td>
|
||||
<td>repeated</td>
|
||||
<td><p>查询条件 </p></td>
|
||||
<td><p>query conditions </p></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
|
@@ -23,8 +23,8 @@
|
||||
"paths": {
|
||||
"/api/v1/userExample": {
|
||||
"post": {
|
||||
"summary": "创建userExample",
|
||||
"description": "提交信息创建userExample",
|
||||
"summary": "create userExample",
|
||||
"description": "submit information to create a userExample",
|
||||
"operationId": "userExampleService_Create",
|
||||
"responses": {
|
||||
"200": {
|
||||
@@ -57,8 +57,8 @@
|
||||
},
|
||||
"/api/v1/userExample/{id}": {
|
||||
"get": {
|
||||
"summary": "获取userExample详情",
|
||||
"description": "根据id获取userExample详情",
|
||||
"summary": "get userExample details",
|
||||
"description": "get userExample details by id",
|
||||
"operationId": "userExampleService_GetByID",
|
||||
"responses": {
|
||||
"200": {
|
||||
@@ -88,8 +88,8 @@
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"summary": "删除userExample",
|
||||
"description": "根据id删除userExample",
|
||||
"summary": "delete userExample",
|
||||
"description": "delete userExample by id",
|
||||
"operationId": "userExampleService_DeleteByID",
|
||||
"responses": {
|
||||
"200": {
|
||||
@@ -119,8 +119,8 @@
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"summary": "更新userExample信息",
|
||||
"description": "根据id更新userExample信息",
|
||||
"summary": "update userExample",
|
||||
"description": "update userExample information based on id",
|
||||
"operationId": "userExampleService_UpdateByID",
|
||||
"responses": {
|
||||
"200": {
|
||||
@@ -192,8 +192,8 @@
|
||||
},
|
||||
"/api/v1/userExamples": {
|
||||
"post": {
|
||||
"summary": "获取userExample列表",
|
||||
"description": "使用post请求获取userExample列表",
|
||||
"summary": "get a list of userExamples",
|
||||
"description": "get a list of userExamples using a post request",
|
||||
"operationId": "userExampleService_List",
|
||||
"responses": {
|
||||
"200": {
|
||||
@@ -226,8 +226,8 @@
|
||||
},
|
||||
"/api/v1/userExamples/ids": {
|
||||
"post": {
|
||||
"summary": "根据多个id获取userExample列表",
|
||||
"description": "使用post请求,根据多个id获取userExample列表",
|
||||
"summary": "get a list of userExample based on multiple ids",
|
||||
"description": "get a list of userExample based on multiple ids using a post request",
|
||||
"operationId": "userExampleService_ListByIDs",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
90
docs/docs.go
90
docs/docs.go
@@ -2,9 +2,7 @@
|
||||
// This file was generated by swaggo/swag
|
||||
package docs
|
||||
|
||||
import (
|
||||
"github.com/swaggo/swag"
|
||||
)
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
@@ -20,7 +18,7 @@ const docTemplate = `{
|
||||
"paths": {
|
||||
"/api/v1/userExample": {
|
||||
"post": {
|
||||
"description": "提交信息创建userExample",
|
||||
"description": "submit information to create userExample",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -30,10 +28,10 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "创建userExample",
|
||||
"summary": "create userExample",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "userExample信息",
|
||||
"description": "userExample information",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -54,7 +52,7 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/v1/userExample/{id}": {
|
||||
"get": {
|
||||
"description": "根据id获取userExample详情",
|
||||
"description": "get userExample details by id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -64,7 +62,7 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "获取userExample详情",
|
||||
"summary": "get userExample details",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -84,7 +82,7 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "根据id更新userExample信息",
|
||||
"description": "update userExample information based on id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -94,7 +92,7 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "更新userExample信息",
|
||||
"summary": "update userExample information",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -104,7 +102,7 @@ const docTemplate = `{
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "userExample信息",
|
||||
"description": "userExample information",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -123,7 +121,7 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "根据id删除userExample",
|
||||
"description": "delete userExample by id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -133,7 +131,7 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "删除userExample",
|
||||
"summary": "delete userExample",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -155,7 +153,7 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/v1/userExamples": {
|
||||
"post": {
|
||||
"description": "使用post请求获取userExample列表",
|
||||
"description": "get a list of userExamples using a post request",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -165,10 +163,10 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "获取userExample列表",
|
||||
"summary": "get a list of userExample",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "查询条件",
|
||||
"description": "query parameters",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -189,7 +187,7 @@ const docTemplate = `{
|
||||
},
|
||||
"/api/v1/userExamples/ids": {
|
||||
"post": {
|
||||
"description": "使用post请求,根据多个id获取userExample列表",
|
||||
"description": "get a list of userExample based on multiple ids using a post request",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -199,10 +197,10 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "根据多个id获取userExample列表",
|
||||
"summary": "get multiple records based on multiple ids",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "id 数组",
|
||||
"description": "id array",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -277,19 +275,19 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"exp": {
|
||||
"description": "表达式,值为空时默认为=,有=、!=、\u003e、\u003e=、\u003c、\u003c=、like七种类型",
|
||||
"description": "expressions, which default to = when the value is null, have =, ! =, \u003e, \u003e=, \u003c, \u003c=, like",
|
||||
"type": "string"
|
||||
},
|
||||
"logic": {
|
||||
"description": "逻辑类型,值为空时默认为and,有\u0026(and)、||(or)两种类型",
|
||||
"description": "logical type, defaults to and when value is null, only \u0026(and), ||(or)",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "列名",
|
||||
"description": "column name",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "列值"
|
||||
"description": "column value"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -297,35 +295,35 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {
|
||||
"description": "年龄",
|
||||
"description": "age",
|
||||
"type": "integer"
|
||||
},
|
||||
"avatar": {
|
||||
"description": "头像",
|
||||
"description": "avatar",
|
||||
"type": "string",
|
||||
"minLength": 5
|
||||
},
|
||||
"email": {
|
||||
"description": "邮件",
|
||||
"description": "email",
|
||||
"type": "string"
|
||||
},
|
||||
"gender": {
|
||||
"description": "性别,1:男,2:女",
|
||||
"description": "gender, 1:Male, 2:Female, other values:unknown",
|
||||
"type": "integer",
|
||||
"maximum": 2,
|
||||
"minimum": 0
|
||||
},
|
||||
"name": {
|
||||
"description": "名称",
|
||||
"description": "username",
|
||||
"type": "string",
|
||||
"minLength": 2
|
||||
},
|
||||
"password": {
|
||||
"description": "密码",
|
||||
"description": "password",
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"description": "手机号码,e164表示\u003c+国家编号\u003e\u003c手机号码\u003e",
|
||||
"description": "phone number, e164 means \u003c+ country code\u003e \u003ccell phone number\u003e.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -334,7 +332,7 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ids": {
|
||||
"description": "id列表",
|
||||
"description": "id list",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
@@ -347,23 +345,23 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"columns": {
|
||||
"description": "列查询条件",
|
||||
"description": "query conditions",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/types.Column"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"description": "页码",
|
||||
"description": "page number, starting from page 0",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"size": {
|
||||
"description": "每页行数",
|
||||
"description": "lines per page",
|
||||
"type": "integer"
|
||||
},
|
||||
"sort": {
|
||||
"description": "排序字段,默认值为-id,字段前面有-号表示倒序,否则升序,多个字段用逗号分隔",
|
||||
"description": "sorted fields, multi-column sorting separated by commas",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -372,14 +370,14 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"description": "返回码",
|
||||
"description": "return code",
|
||||
"type": "integer"
|
||||
},
|
||||
"data": {
|
||||
"description": "返回数据"
|
||||
"description": "return data"
|
||||
},
|
||||
"msg": {
|
||||
"description": "返回信息说明",
|
||||
"description": "return information description",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -388,19 +386,19 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {
|
||||
"description": "年龄",
|
||||
"description": "age",
|
||||
"type": "integer"
|
||||
},
|
||||
"avatar": {
|
||||
"description": "头像",
|
||||
"description": "avatar",
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"description": "邮件",
|
||||
"description": "email",
|
||||
"type": "string"
|
||||
},
|
||||
"gender": {
|
||||
"description": "性别,1:男,2:女",
|
||||
"description": "gender, 1:Male, 2:Female, other values:unknown",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
@@ -408,15 +406,15 @@ const docTemplate = `{
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"description": "名称",
|
||||
"description": "username",
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"description": "密码",
|
||||
"description": "password",
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"description": "手机号码",
|
||||
"description": "phone number",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -426,7 +424,7 @@ const docTemplate = `{
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "2.0",
|
||||
Version: "v0.0.0",
|
||||
Host: "localhost:8080",
|
||||
BasePath: "",
|
||||
Schemes: []string{"http", "https"},
|
||||
|
@@ -14,7 +14,7 @@
|
||||
"paths": {
|
||||
"/api/v1/userExample": {
|
||||
"post": {
|
||||
"description": "提交信息创建userExample",
|
||||
"description": "submit information to create userExample",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -24,10 +24,10 @@
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "创建userExample",
|
||||
"summary": "create userExample",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "userExample信息",
|
||||
"description": "userExample information",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -48,7 +48,7 @@
|
||||
},
|
||||
"/api/v1/userExample/{id}": {
|
||||
"get": {
|
||||
"description": "根据id获取userExample详情",
|
||||
"description": "get userExample details by id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -58,7 +58,7 @@
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "获取userExample详情",
|
||||
"summary": "get userExample details",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -78,7 +78,7 @@
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "根据id更新userExample信息",
|
||||
"description": "update userExample information based on id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -88,7 +88,7 @@
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "更新userExample信息",
|
||||
"summary": "update userExample information",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -98,7 +98,7 @@
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "userExample信息",
|
||||
"description": "userExample information",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -117,7 +117,7 @@
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "根据id删除userExample",
|
||||
"description": "delete userExample by id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -127,7 +127,7 @@
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "删除userExample",
|
||||
"summary": "delete userExample",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -149,7 +149,7 @@
|
||||
},
|
||||
"/api/v1/userExamples": {
|
||||
"post": {
|
||||
"description": "使用post请求获取userExample列表",
|
||||
"description": "get a list of userExamples using a post request",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -159,10 +159,10 @@
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "获取userExample列表",
|
||||
"summary": "get a list of userExample",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "查询条件",
|
||||
"description": "query parameters",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -183,7 +183,7 @@
|
||||
},
|
||||
"/api/v1/userExamples/ids": {
|
||||
"post": {
|
||||
"description": "使用post请求,根据多个id获取userExample列表",
|
||||
"description": "get a list of userExample based on multiple ids using a post request",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -193,10 +193,10 @@
|
||||
"tags": [
|
||||
"userExample"
|
||||
],
|
||||
"summary": "根据多个id获取userExample列表",
|
||||
"summary": "get multiple records based on multiple ids",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "id 数组",
|
||||
"description": "id array",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -271,19 +271,19 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"exp": {
|
||||
"description": "表达式,值为空时默认为=,有=、!=、\u003e、\u003e=、\u003c、\u003c=、like七种类型",
|
||||
"description": "expressions, which default to = when the value is null, have =, ! =, \u003e, \u003e=, \u003c, \u003c=, like",
|
||||
"type": "string"
|
||||
},
|
||||
"logic": {
|
||||
"description": "逻辑类型,值为空时默认为and,有\u0026(and)、||(or)两种类型",
|
||||
"description": "logical type, defaults to and when value is null, only \u0026(and), ||(or)",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "列名",
|
||||
"description": "column name",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "列值"
|
||||
"description": "column value"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -291,35 +291,35 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {
|
||||
"description": "年龄",
|
||||
"description": "age",
|
||||
"type": "integer"
|
||||
},
|
||||
"avatar": {
|
||||
"description": "头像",
|
||||
"description": "avatar",
|
||||
"type": "string",
|
||||
"minLength": 5
|
||||
},
|
||||
"email": {
|
||||
"description": "邮件",
|
||||
"description": "email",
|
||||
"type": "string"
|
||||
},
|
||||
"gender": {
|
||||
"description": "性别,1:男,2:女",
|
||||
"description": "gender, 1:Male, 2:Female, other values:unknown",
|
||||
"type": "integer",
|
||||
"maximum": 2,
|
||||
"minimum": 0
|
||||
},
|
||||
"name": {
|
||||
"description": "名称",
|
||||
"description": "username",
|
||||
"type": "string",
|
||||
"minLength": 2
|
||||
},
|
||||
"password": {
|
||||
"description": "密码",
|
||||
"description": "password",
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"description": "手机号码,e164表示\u003c+国家编号\u003e\u003c手机号码\u003e",
|
||||
"description": "phone number, e164 means \u003c+ country code\u003e \u003ccell phone number\u003e.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -328,7 +328,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ids": {
|
||||
"description": "id列表",
|
||||
"description": "id list",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
@@ -341,23 +341,23 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"columns": {
|
||||
"description": "列查询条件",
|
||||
"description": "query conditions",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/types.Column"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"description": "页码",
|
||||
"description": "page number, starting from page 0",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"size": {
|
||||
"description": "每页行数",
|
||||
"description": "lines per page",
|
||||
"type": "integer"
|
||||
},
|
||||
"sort": {
|
||||
"description": "排序字段,默认值为-id,字段前面有-号表示倒序,否则升序,多个字段用逗号分隔",
|
||||
"description": "sorted fields, multi-column sorting separated by commas",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -366,14 +366,14 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"description": "返回码",
|
||||
"description": "return code",
|
||||
"type": "integer"
|
||||
},
|
||||
"data": {
|
||||
"description": "返回数据"
|
||||
"description": "return data"
|
||||
},
|
||||
"msg": {
|
||||
"description": "返回信息说明",
|
||||
"description": "return information description",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -382,19 +382,19 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {
|
||||
"description": "年龄",
|
||||
"description": "age",
|
||||
"type": "integer"
|
||||
},
|
||||
"avatar": {
|
||||
"description": "头像",
|
||||
"description": "avatar",
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"description": "邮件",
|
||||
"description": "email",
|
||||
"type": "string"
|
||||
},
|
||||
"gender": {
|
||||
"description": "性别,1:男,2:女",
|
||||
"description": "gender, 1:Male, 2:Female, other values:unknown",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
@@ -402,15 +402,15 @@
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"description": "名称",
|
||||
"description": "username",
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"description": "密码",
|
||||
"description": "password",
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"description": "手机号码",
|
||||
"description": "phone number",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
@@ -9,49 +9,51 @@ definitions:
|
||||
types.Column:
|
||||
properties:
|
||||
exp:
|
||||
description: 表达式,值为空时默认为=,有=、!=、>、>=、<、<=、like七种类型
|
||||
description: expressions, which default to = when the value is null, have
|
||||
=, ! =, >, >=, <, <=, like
|
||||
type: string
|
||||
logic:
|
||||
description: 逻辑类型,值为空时默认为and,有&(and)、||(or)两种类型
|
||||
description: logical type, defaults to and when value is null, only &(and),
|
||||
||(or)
|
||||
type: string
|
||||
name:
|
||||
description: 列名
|
||||
description: column name
|
||||
type: string
|
||||
value:
|
||||
description: 列值
|
||||
description: column value
|
||||
type: object
|
||||
types.CreateUserExampleRequest:
|
||||
properties:
|
||||
age:
|
||||
description: 年龄
|
||||
description: age
|
||||
type: integer
|
||||
avatar:
|
||||
description: 头像
|
||||
description: avatar
|
||||
minLength: 5
|
||||
type: string
|
||||
email:
|
||||
description: 邮件
|
||||
description: email
|
||||
type: string
|
||||
gender:
|
||||
description: 性别,1:男,2:女
|
||||
description: gender, 1:Male, 2:Female, other values:unknown
|
||||
maximum: 2
|
||||
minimum: 0
|
||||
type: integer
|
||||
name:
|
||||
description: 名称
|
||||
description: username
|
||||
minLength: 2
|
||||
type: string
|
||||
password:
|
||||
description: 密码
|
||||
description: password
|
||||
type: string
|
||||
phone:
|
||||
description: 手机号码,e164表示<+国家编号><手机号码>
|
||||
description: phone number, e164 means <+ country code> <cell phone number>.
|
||||
type: string
|
||||
type: object
|
||||
types.GetUserExamplesByIDsRequest:
|
||||
properties:
|
||||
ids:
|
||||
description: id列表
|
||||
description: id list
|
||||
items:
|
||||
type: integer
|
||||
minItems: 1
|
||||
@@ -60,57 +62,57 @@ definitions:
|
||||
types.Params:
|
||||
properties:
|
||||
columns:
|
||||
description: 列查询条件
|
||||
description: query conditions
|
||||
items:
|
||||
$ref: '#/definitions/types.Column'
|
||||
type: array
|
||||
page:
|
||||
description: 页码
|
||||
description: page number, starting from page 0
|
||||
minimum: 0
|
||||
type: integer
|
||||
size:
|
||||
description: 每页行数
|
||||
description: lines per page
|
||||
type: integer
|
||||
sort:
|
||||
description: 排序字段,默认值为-id,字段前面有-号表示倒序,否则升序,多个字段用逗号分隔
|
||||
description: sorted fields, multi-column sorting separated by commas
|
||||
type: string
|
||||
type: object
|
||||
types.Result:
|
||||
properties:
|
||||
code:
|
||||
description: 返回码
|
||||
description: return code
|
||||
type: integer
|
||||
data:
|
||||
description: 返回数据
|
||||
description: return data
|
||||
msg:
|
||||
description: 返回信息说明
|
||||
description: return information description
|
||||
type: string
|
||||
type: object
|
||||
types.UpdateUserExampleByIDRequest:
|
||||
properties:
|
||||
age:
|
||||
description: 年龄
|
||||
description: age
|
||||
type: integer
|
||||
avatar:
|
||||
description: 头像
|
||||
description: avatar
|
||||
type: string
|
||||
email:
|
||||
description: 邮件
|
||||
description: email
|
||||
type: string
|
||||
gender:
|
||||
description: 性别,1:男,2:女
|
||||
description: gender, 1:Male, 2:Female, other values:unknown
|
||||
type: integer
|
||||
id:
|
||||
description: id
|
||||
type: integer
|
||||
name:
|
||||
description: 名称
|
||||
description: username
|
||||
type: string
|
||||
password:
|
||||
description: 密码
|
||||
description: password
|
||||
type: string
|
||||
phone:
|
||||
description: 手机号码
|
||||
description: phone number
|
||||
type: string
|
||||
type: object
|
||||
host: localhost:8080
|
||||
@@ -124,9 +126,9 @@ paths:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 提交信息创建userExample
|
||||
description: submit information to create userExample
|
||||
parameters:
|
||||
- description: userExample信息
|
||||
- description: userExample information
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
@@ -139,14 +141,14 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/types.Result'
|
||||
summary: 创建userExample
|
||||
summary: create userExample
|
||||
tags:
|
||||
- userExample
|
||||
/api/v1/userExample/{id}:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据id删除userExample
|
||||
description: delete userExample by id
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
@@ -160,13 +162,13 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/types.Result'
|
||||
summary: 删除userExample
|
||||
summary: delete userExample
|
||||
tags:
|
||||
- userExample
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据id获取userExample详情
|
||||
description: get userExample details by id
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
@@ -180,20 +182,20 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/types.Result'
|
||||
summary: 获取userExample详情
|
||||
summary: get userExample details
|
||||
tags:
|
||||
- userExample
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据id更新userExample信息
|
||||
description: update userExample information based on id
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
- description: userExample信息
|
||||
- description: userExample information
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
@@ -206,16 +208,16 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/types.Result'
|
||||
summary: 更新userExample信息
|
||||
summary: update userExample information
|
||||
tags:
|
||||
- userExample
|
||||
/api/v1/userExamples:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用post请求获取userExample列表
|
||||
description: get a list of userExamples using a post request
|
||||
parameters:
|
||||
- description: 查询条件
|
||||
- description: query parameters
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
@@ -228,16 +230,16 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/types.Result'
|
||||
summary: 获取userExample列表
|
||||
summary: get a list of userExample
|
||||
tags:
|
||||
- userExample
|
||||
/api/v1/userExamples/ids:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用post请求,根据多个id获取userExample列表
|
||||
description: get a list of userExample based on multiple ids using a post request
|
||||
parameters:
|
||||
- description: id 数组
|
||||
- description: id array
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
@@ -250,7 +252,7 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/types.Result'
|
||||
summary: 根据多个id获取userExample列表
|
||||
summary: get multiple records based on multiple ids
|
||||
tags:
|
||||
- userExample
|
||||
/health:
|
||||
|
12
internal/cache/userExample.go
vendored
12
internal/cache/userExample.go
vendored
@@ -56,7 +56,7 @@ func NewUserExampleCache(cacheType *model.CacheType) UserExampleCache {
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserExampleCacheKey 设置缓存
|
||||
// GetUserExampleCacheKey cache key
|
||||
func (c *userExampleCache) GetUserExampleCacheKey(id uint64) string {
|
||||
return PrefixUserExampleCacheKey + utils.Uint64ToStr(id)
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (c *userExampleCache) Set(ctx context.Context, id uint64, data *model.UserE
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get 获取cache
|
||||
// Get cache value
|
||||
func (c *userExampleCache) Get(ctx context.Context, id uint64) (*model.UserExample, error) {
|
||||
var data *model.UserExample
|
||||
cacheKey := c.GetUserExampleCacheKey(id)
|
||||
@@ -85,7 +85,7 @@ func (c *userExampleCache) Get(ctx context.Context, id uint64) (*model.UserExamp
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// MultiSet 批量设置cache
|
||||
// MultiSet multiple set cache
|
||||
func (c *userExampleCache) MultiSet(ctx context.Context, data []*model.UserExample, duration time.Duration) error {
|
||||
valMap := make(map[string]interface{})
|
||||
for _, v := range data {
|
||||
@@ -101,7 +101,7 @@ func (c *userExampleCache) MultiSet(ctx context.Context, data []*model.UserExamp
|
||||
return nil
|
||||
}
|
||||
|
||||
// MultiGet 批量获取cache,返回map中的key是id值
|
||||
// MultiGet multiple get cache, return key in map is id value
|
||||
func (c *userExampleCache) MultiGet(ctx context.Context, ids []uint64) (map[string]*model.UserExample, error) {
|
||||
var keys []string
|
||||
for _, v := range ids {
|
||||
@@ -126,7 +126,7 @@ func (c *userExampleCache) MultiGet(ctx context.Context, ids []uint64) (map[stri
|
||||
return retMap, nil
|
||||
}
|
||||
|
||||
// Del 删除cache
|
||||
// Del delete cache
|
||||
func (c *userExampleCache) Del(ctx context.Context, id uint64) error {
|
||||
cacheKey := c.GetUserExampleCacheKey(id)
|
||||
err := c.cache.Del(ctx, cacheKey)
|
||||
@@ -136,7 +136,7 @@ func (c *userExampleCache) Del(ctx context.Context, id uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetCacheWithNotFound 设置空缓存
|
||||
// SetCacheWithNotFound set empty cache
|
||||
func (c *userExampleCache) SetCacheWithNotFound(ctx context.Context, id uint64) error {
|
||||
cacheKey := c.GetUserExampleCacheKey(id)
|
||||
err := c.cache.SetCacheWithNotFound(ctx, cacheKey)
|
||||
|
@@ -112,11 +112,11 @@ func (d *userExampleDao) GetByID(ctx context.Context, id uint64) (*model.UserExa
|
||||
}
|
||||
|
||||
if errors.Is(err, model.ErrCacheNotFound) {
|
||||
// 从mysql获取
|
||||
// get from mysql
|
||||
table := &model.UserExample{}
|
||||
err = d.db.WithContext(ctx).Where("id = ?", id).First(table).Error
|
||||
if err != nil {
|
||||
// if data is empty, set not found cache to prevent cache penetration(防止缓存穿透)
|
||||
// if data is empty, set not found cache to prevent cache penetration(preventing Cache Penetration)
|
||||
if errors.Is(err, model.ErrRecordNotFound) {
|
||||
err = d.cache.SetCacheWithNotFound(ctx, id)
|
||||
if err != nil {
|
||||
@@ -162,7 +162,7 @@ func (d *userExampleDao) GetByIDs(ctx context.Context, ids []uint64) ([]*model.U
|
||||
|
||||
// get missed data
|
||||
if len(missedIDs) > 0 {
|
||||
// 找出主动占位符的id,也就是在mysql不存在的id
|
||||
// find the id of an active placeholder, i.e. an id that does not exist in mysql
|
||||
var realMissedIDs []uint64
|
||||
for _, id := range missedIDs {
|
||||
_, err = d.cache.Get(ctx, id)
|
||||
@@ -198,34 +198,34 @@ func (d *userExampleDao) GetByIDs(ctx context.Context, ids []uint64) ([]*model.U
|
||||
|
||||
// GetByColumns filter multiple rows based on paging and column information
|
||||
//
|
||||
// params 包括分页参数和查询参数
|
||||
// 分页参数(必须):
|
||||
// params includes paging parameters and query parameters
|
||||
// paging parameters (required):
|
||||
//
|
||||
// page: 页码,从0开始
|
||||
// size: 每页行数
|
||||
// sort: 排序字段,默认是id倒叙,可以在字段前添加-号表示倒序,没有-号表示升序,多个字段用逗号分隔
|
||||
// page: page number, starting from 0
|
||||
// size: lines per page
|
||||
// sort: sort fields, default is id backwards, you can add - sign before the field to indicate reverse order, no - sign to indicate ascending order, multiple fields separated by comma
|
||||
//
|
||||
// 查询参数(非必须):
|
||||
// query parameters (not required):
|
||||
//
|
||||
// name: 列名
|
||||
// exp: 表达式,有=、!=、>、>=、<、<=、like七种类型,值为空时默认是=
|
||||
// value: 列值
|
||||
// logic: 表示逻辑类型,有&(and)、||(or)两种类型,值为空时默认是and
|
||||
// name: column name
|
||||
// exp: expressions, which default to = when the value is null, have =, ! =, >, >=, <, <=, like
|
||||
// value: column name
|
||||
// logic: logical type, defaults to and when value is null, only &(and), ||(or)
|
||||
//
|
||||
// 示例: 查询年龄大于20的男性
|
||||
// example: search for a male over 20 years of age
|
||||
//
|
||||
// params = &query.Params{
|
||||
// Page: 0,
|
||||
// Size: 20,
|
||||
// Columns: []query.Column{
|
||||
// {
|
||||
// serviceName: "age",
|
||||
// Name: "age",
|
||||
// Exp: ">",
|
||||
// Value: 20,
|
||||
// },
|
||||
// {
|
||||
// serviceName: "gender",
|
||||
// Value: "男",
|
||||
// Name: "gender",
|
||||
// Value: "male",
|
||||
// },
|
||||
// }
|
||||
func (d *userExampleDao) GetByColumns(ctx context.Context, params *query.Params) ([]*model.UserExample, int64, error) {
|
||||
@@ -235,7 +235,7 @@ func (d *userExampleDao) GetByColumns(ctx context.Context, params *query.Params)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if params.Sort != "ignore count" { // 忽略测试标记
|
||||
if params.Sort != "ignore count" { // determine if count is required
|
||||
err = d.db.WithContext(ctx).Model(&model.UserExample{}).Select([]string{"id"}).Where(queryStr, args...).Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
|
@@ -23,15 +23,15 @@ func newUserExampleDao() *gotest.Dao {
|
||||
testData.CreatedAt = time.Now()
|
||||
testData.UpdatedAt = testData.CreatedAt
|
||||
|
||||
// 初始化mock cache
|
||||
//c := gotest.NewCache(map[string]interface{}{"no cache": testData}) // 为了测试mysql,禁止缓存
|
||||
// init mock cache
|
||||
//c := gotest.NewCache(map[string]interface{}{"no cache": testData}) // to test mysql, disable caching
|
||||
c := gotest.NewCache(map[string]interface{}{utils.Uint64ToStr(testData.ID): testData})
|
||||
c.ICache = cache.NewUserExampleCache(&model.CacheType{
|
||||
CType: "redis",
|
||||
Rdb: c.RedisClient,
|
||||
})
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := gotest.NewDao(c, testData)
|
||||
d.IDao = NewUserExampleDao(d.DB, c.ICache.(cache.UserExampleCache))
|
||||
|
||||
@@ -194,7 +194,7 @@ func Test_userExampleDao_GetByColumns(t *testing.T) {
|
||||
_, _, err := d.IDao.(UserExampleDao).GetByColumns(d.Ctx, &query.Params{
|
||||
Page: 0,
|
||||
Size: 10,
|
||||
Sort: "ignore count", // 忽略测试 select count(*)
|
||||
Sort: "ignore count", // ignore test count(*)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/errcode"
|
||||
)
|
||||
|
||||
// userExample http服务级别错误码
|
||||
// 每个资源名称对应唯一编号(http类型),编号范围1~100,如果存在编号相同,触发panic
|
||||
// userExample http service level error code
|
||||
// each resource name corresponds to a unique number (http type), the number range is 1~100, if there is the same number, trigger panic
|
||||
var (
|
||||
userExampleNO = 1
|
||||
userExampleName = "userExample"
|
||||
@@ -18,5 +18,5 @@ var (
|
||||
ErrUpdateUserExample = errcode.NewError(userExampleBaseCode+3, "failed to update "+userExampleName)
|
||||
ErrGetUserExample = errcode.NewError(userExampleBaseCode+4, "failed to get "+userExampleName+" details")
|
||||
ErrListUserExample = errcode.NewError(userExampleBaseCode+5, "failed to get list of "+userExampleName)
|
||||
// 每添加一个错误码,在上一个错误码基础上+1
|
||||
// for each error code added, add +1 to the previous error code
|
||||
)
|
||||
|
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/zhufuyi/sponge/pkg/errcode"
|
||||
)
|
||||
|
||||
// userExample rpc服务级别错误码
|
||||
// 每个资源名称对应唯一编号(rpc类型),编号范围1~100,如果存在编号相同,触发panic
|
||||
// userExample rpc service level error code
|
||||
// each resource name corresponds to a unique number (rpc type), the number range is 1~100, if there is the same number, trigger panic
|
||||
var (
|
||||
_userExampleNO = 1
|
||||
_userExampleName = "userExample"
|
||||
@@ -18,5 +18,5 @@ var (
|
||||
StatusUpdateUserExample = errcode.NewRPCStatus(_userExampleBaseCode+3, "failed to update "+_userExampleName)
|
||||
StatusGetUserExample = errcode.NewRPCStatus(_userExampleBaseCode+4, "failed to get "+_userExampleName+" details")
|
||||
StatusListUserExample = errcode.NewRPCStatus(_userExampleBaseCode+5, "failed to get list of "+_userExampleName)
|
||||
// 每添加一个错误码,在上一个错误码基础上+1
|
||||
// for each error code added, add +1 to the previous error code
|
||||
)
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
var _ UserExampleHandler = (*userExampleHandler)(nil)
|
||||
|
||||
// UserExampleHandler 定义handler接口
|
||||
// UserExampleHandler defining the handler interface
|
||||
type UserExampleHandler interface {
|
||||
Create(c *gin.Context)
|
||||
DeleteByID(c *gin.Context)
|
||||
@@ -35,7 +35,7 @@ type userExampleHandler struct {
|
||||
iDao dao.UserExampleDao
|
||||
}
|
||||
|
||||
// NewUserExampleHandler 创建handler接口
|
||||
// NewUserExampleHandler creating the handler interface
|
||||
func NewUserExampleHandler() UserExampleHandler {
|
||||
return &userExampleHandler{
|
||||
iDao: dao.NewUserExampleDao(
|
||||
@@ -45,13 +45,13 @@ func NewUserExampleHandler() UserExampleHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Create 创建一条记录
|
||||
// @Summary 创建userExample
|
||||
// @Description 提交信息创建userExample
|
||||
// Create a record
|
||||
// @Summary create userExample
|
||||
// @Description submit information to create userExample
|
||||
// @Tags userExample
|
||||
// @accept json
|
||||
// @Produce json
|
||||
// @Param data body types.CreateUserExampleRequest true "userExample信息"
|
||||
// @Param data body types.CreateUserExampleRequest true "userExample information"
|
||||
// @Success 200 {object} types.Result{}
|
||||
// @Router /api/v1/userExample [post]
|
||||
func (h *userExampleHandler) Create(c *gin.Context) {
|
||||
@@ -81,9 +81,9 @@ func (h *userExampleHandler) Create(c *gin.Context) {
|
||||
response.Success(c, gin.H{"id": userExample.ID})
|
||||
}
|
||||
|
||||
// DeleteByID 根据id删除一条记录
|
||||
// @Summary 删除userExample
|
||||
// @Description 根据id删除userExample
|
||||
// DeleteByID delete a record by ID
|
||||
// @Summary delete userExample
|
||||
// @Description delete userExample by id
|
||||
// @Tags userExample
|
||||
// @accept json
|
||||
// @Produce json
|
||||
@@ -106,14 +106,14 @@ func (h *userExampleHandler) DeleteByID(c *gin.Context) {
|
||||
response.Success(c)
|
||||
}
|
||||
|
||||
// UpdateByID 根据id更新信息
|
||||
// @Summary 更新userExample信息
|
||||
// @Description 根据id更新userExample信息
|
||||
// UpdateByID update information based on id
|
||||
// @Summary update userExample information
|
||||
// @Description update userExample information based on id
|
||||
// @Tags userExample
|
||||
// @accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "id"
|
||||
// @Param data body types.UpdateUserExampleByIDRequest true "userExample信息"
|
||||
// @Param data body types.UpdateUserExampleByIDRequest true "userExample information"
|
||||
// @Success 200 {object} types.Result{}
|
||||
// @Router /api/v1/userExample/{id} [put]
|
||||
func (h *userExampleHandler) UpdateByID(c *gin.Context) {
|
||||
@@ -149,9 +149,9 @@ func (h *userExampleHandler) UpdateByID(c *gin.Context) {
|
||||
response.Success(c)
|
||||
}
|
||||
|
||||
// GetByID 根据id获取一条记录
|
||||
// @Summary 获取userExample详情
|
||||
// @Description 根据id获取userExample详情
|
||||
// GetByID get a record based on id
|
||||
// @Summary get userExample details
|
||||
// @Description get userExample details by id
|
||||
// @Tags userExample
|
||||
// @Param id path string true "id"
|
||||
// @Accept json
|
||||
@@ -188,11 +188,11 @@ func (h *userExampleHandler) GetByID(c *gin.Context) {
|
||||
response.Success(c, gin.H{"userExample": data})
|
||||
}
|
||||
|
||||
// ListByIDs 根据多个id获取多条记录
|
||||
// @Summary 根据多个id获取userExample列表
|
||||
// @Description 使用post请求,根据多个id获取userExample列表
|
||||
// ListByIDs get multiple records based on multiple ids
|
||||
// @Summary get multiple records based on multiple ids
|
||||
// @Description get a list of userExample based on multiple ids using a post request
|
||||
// @Tags userExample
|
||||
// @Param data body types.GetUserExamplesByIDsRequest true "id 数组"
|
||||
// @Param data body types.GetUserExamplesByIDsRequest true "id array"
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} types.Result{}
|
||||
@@ -226,13 +226,13 @@ func (h *userExampleHandler) ListByIDs(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// List 通过post获取多条记录
|
||||
// @Summary 获取userExample列表
|
||||
// @Description 使用post请求获取userExample列表
|
||||
// List Get multiple records by query parameters
|
||||
// @Summary get a list of userExample
|
||||
// @Description get a list of userExamples using a post request
|
||||
// @Tags userExample
|
||||
// @accept json
|
||||
// @Produce json
|
||||
// @Param data body types.Params true "查询条件"
|
||||
// @Param data body types.Params true "query parameters"
|
||||
// @Success 200 {object} types.Result{}
|
||||
// @Router /api/v1/userExamples [post]
|
||||
func (h *userExampleHandler) List(c *gin.Context) {
|
||||
|
@@ -21,24 +21,24 @@ import (
|
||||
)
|
||||
|
||||
func newUserExampleHandler() *gotest.Handler {
|
||||
// todo 补充测试字段信息
|
||||
// todo additional test field information
|
||||
testData := &model.UserExample{}
|
||||
testData.ID = 1
|
||||
testData.CreatedAt = time.Now()
|
||||
testData.UpdatedAt = testData.CreatedAt
|
||||
|
||||
// 初始化mock cache
|
||||
// init mock cache
|
||||
c := gotest.NewCache(map[string]interface{}{utils.Uint64ToStr(testData.ID): testData})
|
||||
c.ICache = cache.NewUserExampleCache(&model.CacheType{
|
||||
CType: "redis",
|
||||
Rdb: c.RedisClient,
|
||||
})
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := gotest.NewDao(c, testData)
|
||||
d.IDao = dao.NewUserExampleDao(d.DB, c.ICache.(cache.UserExampleCache))
|
||||
|
||||
// 初始化mock handler
|
||||
// init mock handler
|
||||
h := gotest.NewHandler(d, testData)
|
||||
h.IHandler = &userExampleHandler{iDao: d.IDao.(dao.UserExampleDao)}
|
||||
|
||||
@@ -96,7 +96,7 @@ func Test_userExampleHandler_Create(t *testing.T) {
|
||||
h.MockDao.SQLMock.ExpectBegin()
|
||||
args := h.MockDao.GetAnyArgs(h.TestData)
|
||||
h.MockDao.SQLMock.ExpectExec("INSERT INTO .*").
|
||||
WithArgs(args[:len(args)-1]...). // 根据实际参数数量修改
|
||||
WithArgs(args[:len(args)-1]...). // adjusted for the amount of test data
|
||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
h.MockDao.SQLMock.ExpectCommit()
|
||||
|
||||
@@ -139,7 +139,7 @@ func Test_userExampleHandler_DeleteByID(t *testing.T) {
|
||||
|
||||
h.MockDao.SQLMock.ExpectBegin()
|
||||
h.MockDao.SQLMock.ExpectExec("UPDATE .*").
|
||||
WithArgs(h.MockDao.AnyTime, testData.ID). // 根据测试数据数量调整
|
||||
WithArgs(h.MockDao.AnyTime, testData.ID). // adjusted for the amount of test data
|
||||
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
|
||||
h.MockDao.SQLMock.ExpectCommit()
|
||||
|
||||
@@ -169,7 +169,7 @@ func Test_userExampleHandler_UpdateByID(t *testing.T) {
|
||||
|
||||
h.MockDao.SQLMock.ExpectBegin()
|
||||
h.MockDao.SQLMock.ExpectExec("UPDATE .*").
|
||||
WithArgs(h.MockDao.AnyTime, testData.ID). // 根据测试数据数量调整
|
||||
WithArgs(h.MockDao.AnyTime, testData.ID). // adjusted for the amount of test data
|
||||
WillReturnResult(sqlmock.NewResult(int64(testData.ID), 1))
|
||||
h.MockDao.SQLMock.ExpectCommit()
|
||||
|
||||
@@ -263,7 +263,7 @@ func Test_userExampleHandler_List(t *testing.T) {
|
||||
err := gohttp.Post(result, h.GetRequestURL("List"), &types.GetUserExamplesRequest{query.Params{
|
||||
Page: 0,
|
||||
Size: 10,
|
||||
Sort: "ignore count", // 忽略测试 select count(*)
|
||||
Sort: "ignore count", // ignore test count
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@@ -11,15 +11,15 @@ import (
|
||||
type UserExample struct {
|
||||
mysql.Model `gorm:"embedded"`
|
||||
|
||||
Name string `gorm:"column:name;NOT NULL" json:"name"` // 用户名
|
||||
Password string `gorm:"column:password;NOT NULL" json:"password"` // 密码
|
||||
Email string `gorm:"column:email;NOT NULL" json:"email"` // 邮件
|
||||
Phone string `gorm:"column:phone;NOT NULL" json:"phone"` // 手机号码
|
||||
Avatar string `gorm:"column:avatar;NOT NULL" json:"avatar"` // 头像
|
||||
Age int `gorm:"column:age;NOT NULL" json:"age"` // 年龄
|
||||
Gender int `gorm:"column:gender;NOT NULL" json:"gender"` // 性别,1:男,2:女,其他值:未知
|
||||
Status int `gorm:"column:status;NOT NULL" json:"status"` // 账号状态,1:未激活,2:已激活,3:封禁
|
||||
LoginAt int64 `gorm:"column:login_at;NOT NULL" json:"login_at"` // 登录时间戳
|
||||
Name string `gorm:"column:name;NOT NULL" json:"name"` // username
|
||||
Password string `gorm:"column:password;NOT NULL" json:"password"` // password
|
||||
Email string `gorm:"column:email;NOT NULL" json:"email"` // email
|
||||
Phone string `gorm:"column:phone;NOT NULL" json:"phone"` // phone number
|
||||
Avatar string `gorm:"column:avatar;NOT NULL" json:"avatar"` // avatar
|
||||
Age int `gorm:"column:age;NOT NULL" json:"age"` // age
|
||||
Gender int `gorm:"column:gender;NOT NULL" json:"gender"` // gender, 1:Male, 2:Female, other values:unknown
|
||||
Status int `gorm:"column:status;NOT NULL" json:"status"` // account status, 1:inactive, 2:activated, 3:blocked
|
||||
LoginAt int64 `gorm:"column:login_at;NOT NULL" json:"login_at"` // login timestamp
|
||||
}
|
||||
|
||||
// TableName get table name
|
||||
|
@@ -20,66 +20,67 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
routerFns []func(*gin.RouterGroup) // 路由集合
|
||||
routerFns []func(*gin.RouterGroup) // routing Collections
|
||||
)
|
||||
|
||||
// NewRouter 实例化路由
|
||||
// NewRouter create a new router
|
||||
func NewRouter() *gin.Engine {
|
||||
r := gin.New()
|
||||
|
||||
r.Use(gin.Recovery())
|
||||
r.Use(middleware.Cors())
|
||||
|
||||
// request id 中间件
|
||||
// request id middleware
|
||||
r.Use(middleware.RequestID())
|
||||
|
||||
// logger 中间件
|
||||
// logger middleware
|
||||
r.Use(middleware.Logging(
|
||||
middleware.WithLog(logger.Get()),
|
||||
middleware.WithRequestIDFromContext(),
|
||||
middleware.WithIgnoreRoutes("/metrics"), // 忽略路由
|
||||
middleware.WithIgnoreRoutes("/metrics"), // ignore path
|
||||
))
|
||||
|
||||
// metrics 中间件
|
||||
// metrics middleware
|
||||
if config.Get().App.EnableMetrics {
|
||||
r.Use(metrics.Metrics(r,
|
||||
//metrics.WithMetricsPath("/metrics"), // 默认是 /metrics
|
||||
metrics.WithIgnoreStatusCodes(http.StatusNotFound), // 忽略404状态码
|
||||
//metrics.WithMetricsPath("/metrics"), // default is /metrics
|
||||
metrics.WithIgnoreStatusCodes(http.StatusNotFound), // ignore 404 status codes
|
||||
))
|
||||
}
|
||||
|
||||
// limit 中间件
|
||||
// limit middleware
|
||||
if config.Get().App.EnableLimit {
|
||||
r.Use(middleware.RateLimit())
|
||||
}
|
||||
|
||||
// circuit breaker 中间件
|
||||
// circuit breaker middleware
|
||||
if config.Get().App.EnableCircuitBreaker {
|
||||
r.Use(middleware.CircuitBreaker())
|
||||
}
|
||||
|
||||
// trace 中间件
|
||||
// trace middleware
|
||||
if config.Get().App.EnableTracing {
|
||||
r.Use(middleware.Tracing(config.Get().App.Name))
|
||||
}
|
||||
|
||||
// pprof 性能分析
|
||||
// pprof performance analysis
|
||||
if config.Get().App.EnablePprof {
|
||||
prof.Register(r, prof.WithIOWaitTime())
|
||||
}
|
||||
|
||||
// 校验器
|
||||
// validator
|
||||
binding.Validator = validator.Init()
|
||||
|
||||
r.GET("/health", handlerfunc.CheckHealth)
|
||||
r.GET("/ping", handlerfunc.Ping)
|
||||
|
||||
// 注册swagger路由,通过swag init生成代码
|
||||
// register swagger routes, generate code via swag init
|
||||
docs.SwaggerInfo.BasePath = ""
|
||||
// access path /swagger/index.html
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
|
||||
apiV1 := r.Group("/api/v1")
|
||||
// 注册/api/v1前缀路由组
|
||||
// register/api/v1 prefix routing group
|
||||
for _, fn := range routerFns {
|
||||
fn(apiV1)
|
||||
}
|
||||
|
@@ -19,63 +19,64 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
rootRouterFns []func(engine *gin.Engine) // 根路由组,rpc gateway使用
|
||||
rootRouterFns []func(engine *gin.Engine) // root routing group, used by rpc gateway
|
||||
)
|
||||
|
||||
// NewRouter_pbExample 创建一个路由
|
||||
// NewRouter_pbExample create a new router
|
||||
func NewRouter_pbExample() *gin.Engine { //nolint
|
||||
r := gin.New()
|
||||
|
||||
r.Use(gin.Recovery())
|
||||
r.Use(middleware.Cors())
|
||||
|
||||
// request id 中间件
|
||||
// request id middleware
|
||||
r.Use(middleware.RequestID())
|
||||
|
||||
// logger 中间件
|
||||
// logger middleware
|
||||
r.Use(middleware.Logging(
|
||||
middleware.WithLog(logger.Get()),
|
||||
middleware.WithRequestIDFromContext(),
|
||||
middleware.WithIgnoreRoutes("/metrics"), // 忽略路由
|
||||
middleware.WithIgnoreRoutes("/metrics"), // ignore path
|
||||
))
|
||||
|
||||
// metrics 中间件
|
||||
// metrics middleware
|
||||
if config.Get().App.EnableMetrics {
|
||||
r.Use(metrics.Metrics(r,
|
||||
//metrics.WithMetricsPath("/metrics"), // 默认是 /metrics
|
||||
metrics.WithIgnoreStatusCodes(http.StatusNotFound), // 忽略404状态码
|
||||
//metrics.WithMetricsPath("/metrics"), // default is /metrics
|
||||
metrics.WithIgnoreStatusCodes(http.StatusNotFound), // ignore 404 status codes
|
||||
))
|
||||
}
|
||||
|
||||
// limit 中间件
|
||||
// limit middleware
|
||||
if config.Get().App.EnableLimit {
|
||||
r.Use(middleware.RateLimit())
|
||||
}
|
||||
|
||||
// circuit breaker 中间件
|
||||
// circuit breaker middleware
|
||||
if config.Get().App.EnableCircuitBreaker {
|
||||
r.Use(middleware.CircuitBreaker())
|
||||
}
|
||||
|
||||
// trace 中间件
|
||||
// trace middleware
|
||||
if config.Get().App.EnableTracing {
|
||||
r.Use(middleware.Tracing(config.Get().App.Name))
|
||||
}
|
||||
|
||||
// pprof 性能分析
|
||||
// pprof performance analysis
|
||||
if config.Get().App.EnablePprof {
|
||||
prof.Register(r, prof.WithIOWaitTime())
|
||||
}
|
||||
|
||||
// 校验器
|
||||
// validator
|
||||
binding.Validator = validator.Init()
|
||||
|
||||
r.GET("/health", handlerfunc.CheckHealth)
|
||||
r.GET("/ping", handlerfunc.Ping)
|
||||
|
||||
// access path /apis/swagger/index.html
|
||||
swagger.CustomRouter(r, "apis", docs.ApiDocs)
|
||||
|
||||
// 注册/前缀路由组
|
||||
// registration/Prefix Routing Groups
|
||||
for _, fn := range rootRouterFns {
|
||||
fn(r)
|
||||
}
|
||||
|
@@ -49,32 +49,32 @@ func NewServerNameExampleRPCConn() {
|
||||
"please change to the correct service name", serverName))
|
||||
}
|
||||
|
||||
// 如果没有使用服务发现,用ip和端口直连rpc服务
|
||||
// If service discovery is not used, connect directly to the rpc service using the ip and port
|
||||
endpoint := fmt.Sprintf("%s:%d", grpcClientCfg.Host, cfg.Grpc.Port)
|
||||
|
||||
switch grpcClientCfg.RegistryDiscoveryType {
|
||||
// 使用consul发现服务
|
||||
// discovering services using consul
|
||||
case "consul":
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // 通过服务名称连接grpc服务
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // connecting to grpc services by service name
|
||||
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发现服务
|
||||
// discovering services using etcd
|
||||
case "etcd":
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // 通过服务名称连接grpc服务
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // Connecting to grpc services by service name
|
||||
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))
|
||||
panic(fmt.Sprintf("etcdcli.Init error: %v, addr: %v", err, cfg.Etcd.Addrs))
|
||||
}
|
||||
iDiscovery := etcd.New(cli)
|
||||
cliOptions = append(cliOptions, grpccli.WithDiscovery(iDiscovery))
|
||||
// 使用nacos发现服务
|
||||
// discovering services using nacos
|
||||
case "nacos":
|
||||
// example: endpoint = "discovery:///serverName.scheme"
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name + ".grpc"
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name + ".grpc" // Connecting to grpc services by service name
|
||||
cli, err := nacoscli.NewNamingClient(
|
||||
cfg.NacosRd.IPAddr,
|
||||
cfg.NacosRd.Port,
|
||||
@@ -97,7 +97,8 @@ func NewServerNameExampleRPCConn() {
|
||||
cliOptions = append(cliOptions, grpccli.WithEnableMetrics())
|
||||
}
|
||||
|
||||
// 如果需要安全连接,使用grpccli.Dial(ctx, endpoint, cliOptions...),并且cliOptions设置WithCredentials指定证书路径
|
||||
// If a secure connection is required, use grpccli.Dial(ctx, endpoint, cliOptions...) and
|
||||
// cliOptions sets WithCredentials to specify the certificate path
|
||||
var err error
|
||||
serverNameExampleConn, err = grpccli.DialInsecure(context.Background(), endpoint, cliOptions...)
|
||||
if err != nil {
|
||||
|
@@ -30,7 +30,7 @@ type grpcServer struct {
|
||||
|
||||
mux *http.ServeMux
|
||||
httpServer *http.Server
|
||||
metricsHTTPServerFunc func() error
|
||||
registerMetricsMuxAndMethodFunc func() error
|
||||
|
||||
iRegistry registry.Registry
|
||||
instance *registry.ServiceInstance
|
||||
@@ -38,6 +38,7 @@ type grpcServer struct {
|
||||
|
||||
// Start grpc service
|
||||
func (s *grpcServer) Start() error {
|
||||
// registration Services
|
||||
if s.iRegistry != nil {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) //nolint
|
||||
if err := s.iRegistry.Register(ctx, s.instance); err != nil {
|
||||
@@ -45,21 +46,22 @@ func (s *grpcServer) Start() error {
|
||||
}
|
||||
}
|
||||
|
||||
if s.metricsHTTPServerFunc != nil {
|
||||
if err := s.metricsHTTPServerFunc(); err != nil {
|
||||
if s.registerMetricsMuxAndMethodFunc != nil {
|
||||
if err := s.registerMetricsMuxAndMethodFunc(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if s.mux != nil { // 如果启用pprof或metrics任何一个,都会启动http服务
|
||||
// if either pprof or metrics is enabled, the http service will be started
|
||||
if s.mux != nil {
|
||||
addr := fmt.Sprintf(":%d", config.Get().Grpc.HTTPPort)
|
||||
httpSrv := &http.Server{
|
||||
s.httpServer = &http.Server{
|
||||
Addr: addr,
|
||||
Handler: s.mux,
|
||||
}
|
||||
go func() {
|
||||
fmt.Printf("http address of pprof and metrics %s\n", addr)
|
||||
if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
panic("listen and serve error: " + err.Error())
|
||||
}
|
||||
}()
|
||||
@@ -119,7 +121,7 @@ func (s *grpcServer) serverOptions() []grpc.ServerOption {
|
||||
// metrics interceptor
|
||||
if config.Get().App.EnableMetrics {
|
||||
unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerMetrics())
|
||||
s.metricsHTTPServerFunc = s.registerHTTPMetrics()
|
||||
s.registerMetricsMuxAndMethodFunc = s.registerMetricsMuxAndMethod()
|
||||
}
|
||||
|
||||
// limit interceptor
|
||||
@@ -145,7 +147,7 @@ func (s *grpcServer) serverOptions() []grpc.ServerOption {
|
||||
return options
|
||||
}
|
||||
|
||||
func (s *grpcServer) registerHTTPMetrics() func() error {
|
||||
func (s *grpcServer) registerMetricsMuxAndMethod() func() error {
|
||||
return func() error {
|
||||
if s.mux == nil {
|
||||
s.mux = http.NewServeMux()
|
||||
@@ -155,7 +157,7 @@ func (s *grpcServer) registerHTTPMetrics() func() error {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *grpcServer) registerHTTPPprof() {
|
||||
func (s *grpcServer) registerProfMux() {
|
||||
if s.mux == nil {
|
||||
s.mux = http.NewServeMux()
|
||||
}
|
||||
@@ -173,7 +175,7 @@ func NewGRPCServer(addr string, opts ...GrpcOption) app.IServer {
|
||||
instance: o.instance,
|
||||
}
|
||||
if config.Get().App.EnablePprof {
|
||||
s.registerHTTPPprof()
|
||||
s.registerProfMux()
|
||||
}
|
||||
|
||||
s.listen, err = net.Listen("tcp", addr)
|
||||
|
@@ -7,13 +7,13 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// registerFns 注册方法集合
|
||||
// registerFns collection of registration methods
|
||||
registerFns []func(server *grpc.Server)
|
||||
)
|
||||
|
||||
// RegisterAllService 注册所有service到服务中
|
||||
// RegisterAllService register all services to the service
|
||||
func RegisterAllService(server *grpc.Server) {
|
||||
healthPB.RegisterHealthServer(server, health.NewServer()) // 注册健康检测
|
||||
healthPB.RegisterHealthServer(server, health.NewServer()) // Register for Health Screening
|
||||
|
||||
for _, fn := range registerFns {
|
||||
fn(server)
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
// nolint
|
||||
func init() {
|
||||
registerFns = append(registerFns, func(server *grpc.Server) {
|
||||
serverNameExampleV1.RegisterUserExampleServiceServer(server, NewUserExampleServiceServer()) // 把service注册到rpc服务中
|
||||
serverNameExampleV1.RegisterUserExampleServiceServer(server, NewUserExampleServiceServer()) // register service to the rpc service
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ type userExampleService struct {
|
||||
iDao dao.UserExampleDao
|
||||
}
|
||||
|
||||
// NewUserExampleServiceServer 创建一个实例
|
||||
// NewUserExampleServiceServer create a new service
|
||||
func NewUserExampleServiceServer() serverNameExampleV1.UserExampleServiceServer {
|
||||
return &userExampleService{
|
||||
iDao: dao.NewUserExampleDao(
|
||||
@@ -43,7 +43,7 @@ func NewUserExampleServiceServer() serverNameExampleV1.UserExampleServiceServer
|
||||
}
|
||||
}
|
||||
|
||||
// Create 创建一条记录
|
||||
// Create a record
|
||||
func (s *userExampleService) Create(ctx context.Context, req *serverNameExampleV1.CreateUserExampleRequest) (*serverNameExampleV1.CreateUserExampleReply, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
@@ -67,7 +67,7 @@ func (s *userExampleService) Create(ctx context.Context, req *serverNameExampleV
|
||||
return &serverNameExampleV1.CreateUserExampleReply{Id: userExample.ID}, nil
|
||||
}
|
||||
|
||||
// DeleteByID 根据id删除一条记录
|
||||
// DeleteByID delete a record based on id
|
||||
func (s *userExampleService) DeleteByID(ctx context.Context, req *serverNameExampleV1.DeleteUserExampleByIDRequest) (*serverNameExampleV1.DeleteUserExampleByIDReply, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
@@ -84,7 +84,7 @@ func (s *userExampleService) DeleteByID(ctx context.Context, req *serverNameExam
|
||||
return &serverNameExampleV1.DeleteUserExampleByIDReply{}, nil
|
||||
}
|
||||
|
||||
// UpdateByID 根据id更新一条记录
|
||||
// UpdateByID update a record based on id
|
||||
func (s *userExampleService) UpdateByID(ctx context.Context, req *serverNameExampleV1.UpdateUserExampleByIDRequest) (*serverNameExampleV1.UpdateUserExampleByIDReply, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
@@ -109,7 +109,7 @@ func (s *userExampleService) UpdateByID(ctx context.Context, req *serverNameExam
|
||||
return &serverNameExampleV1.UpdateUserExampleByIDReply{}, nil
|
||||
}
|
||||
|
||||
// GetByID 根据id查询一条记录
|
||||
// GetByID get a record by id
|
||||
func (s *userExampleService) GetByID(ctx context.Context, req *serverNameExampleV1.GetUserExampleByIDRequest) (*serverNameExampleV1.GetUserExampleByIDReply, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
@@ -136,7 +136,7 @@ func (s *userExampleService) GetByID(ctx context.Context, req *serverNameExample
|
||||
return &serverNameExampleV1.GetUserExampleByIDReply{UserExample: data}, nil
|
||||
}
|
||||
|
||||
// ListByIDs 根据id数组获取多条记录
|
||||
// ListByIDs get multiple records based on an array of ids
|
||||
func (s *userExampleService) ListByIDs(ctx context.Context, req *serverNameExampleV1.ListUserExampleByIDsRequest) (*serverNameExampleV1.ListUserExampleByIDsReply, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
@@ -163,7 +163,7 @@ func (s *userExampleService) ListByIDs(ctx context.Context, req *serverNameExamp
|
||||
return &serverNameExampleV1.ListUserExampleByIDsReply{UserExamples: datas}, nil
|
||||
}
|
||||
|
||||
// List 获取多条记录
|
||||
// List Get multiple records based on query parameters
|
||||
func (s *userExampleService) List(ctx context.Context, req *serverNameExampleV1.ListUserExampleRequest) (*serverNameExampleV1.ListUserExampleReply, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
// 运行rpc服务端后再进行测试,下面对userExample各个方法进行测试和压测(复制压测报告文件路径到浏览器查看)
|
||||
// After running the rpc server and then testing, the following tests and crush tests are performed on
|
||||
// each method of userExample (copy the path to the crush test report file to view it in your browser)
|
||||
|
||||
package service
|
||||
|
||||
@@ -40,9 +41,10 @@ func initUserExampleServiceClient() serverNameExampleV1.UserExampleServiceClient
|
||||
}
|
||||
if config.Get().App.RegistryDiscoveryType != "" {
|
||||
var iDiscovery registry.Discovery
|
||||
endpoint = "discovery:///" + config.Get().App.Name // 通过服务名称连接grpc服务
|
||||
endpoint = "discovery:///" + config.Get().App.Name // Connecting to grpc services by service name
|
||||
|
||||
// 使用consul做发现,注意配置文件serverNameExample.yml的字段host需要填本机ip,不是127.0.0.1,用来做健康检查
|
||||
// Use consul service discovery, note that the host field in the configuration file serverNameExample.yml
|
||||
// needs to be filled with the local ip, not 127.0.0.1, to do the health check
|
||||
if config.Get().App.RegistryDiscoveryType == "consul" {
|
||||
cli, err := consulcli.Init(config.Get().Consul.Addr, consulcli.WithWaitTime(time.Second*2))
|
||||
if err != nil {
|
||||
@@ -51,7 +53,8 @@ func initUserExampleServiceClient() serverNameExampleV1.UserExampleServiceClient
|
||||
iDiscovery = consul.New(cli)
|
||||
}
|
||||
|
||||
// 使用etcd做服务发现,测试前使用命令etcdctl get / --prefix查看是否有服务注册,注:IDE使用代理可能会造成连接etcd服务失败
|
||||
// Use etcd service discovery, use the command etcdctl get / --prefix to see if the service is registered before testing,
|
||||
// note: the IDE using a proxy may cause the connection to the etcd service to fail
|
||||
if config.Get().App.RegistryDiscoveryType == "etcd" {
|
||||
cli, err := etcdcli.Init(config.Get().Etcd.Addrs, etcdcli.WithDialTimeout(time.Second*2))
|
||||
if err != nil {
|
||||
@@ -60,7 +63,7 @@ func initUserExampleServiceClient() serverNameExampleV1.UserExampleServiceClient
|
||||
iDiscovery = etcd.New(cli)
|
||||
}
|
||||
|
||||
// 使用nacos做服务发现
|
||||
// Use nacos service discovery
|
||||
if config.Get().App.RegistryDiscoveryType == "nacos" {
|
||||
// example: endpoint = "discovery:///serverName.scheme"
|
||||
endpoint = "discovery:///" + config.Get().App.Name + ".grpc"
|
||||
@@ -95,7 +98,7 @@ func initUserExampleServiceClient() serverNameExampleV1.UserExampleServiceClient
|
||||
return serverNameExampleV1.NewUserExampleServiceClient(conn)
|
||||
}
|
||||
|
||||
// 通过客户端测试userExample的各个方法
|
||||
// Test each method of userExample via the client
|
||||
func Test_userExampleService_methods(t *testing.T) {
|
||||
cli := initUserExampleServiceClient()
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*3)
|
||||
@@ -197,7 +200,7 @@ func Test_userExampleService_methods(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.fn()
|
||||
if (err != nil) != tt.wantErr {
|
||||
// 如果没有开启rpc服务端,会报错transport: Error while dialing dial tcp......,这里忽略测试错误
|
||||
// If the rpc server is not enabled, it will report the error transport: Error while dialing dial tcp...... Ignore the test error here
|
||||
t.Logf("test '%s' error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
@@ -206,7 +209,7 @@ func Test_userExampleService_methods(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 压测userExample的各个方法,完成后复制报告路径到浏览器查看
|
||||
// Press test the individual queries of userExample and copy the press test report to your browser when finished
|
||||
func Test_userExampleService_benchmark(t *testing.T) {
|
||||
err := config.Init(configs.Path("serverNameExample.yml"))
|
||||
if err != nil {
|
||||
@@ -214,10 +217,10 @@ func Test_userExampleService_benchmark(t *testing.T) {
|
||||
}
|
||||
host := fmt.Sprintf("127.0.0.1:%d", config.Get().Grpc.Port)
|
||||
protoFile := configs.Path("../api/serverNameExample/v1/userExample.proto")
|
||||
// 如果压测过程中缺少第三方依赖,复制到项目的third_party目录下(不包括import路径)
|
||||
// If third-party dependencies are missing during the press test, copy them to the project's third_party directory (not including the import path)
|
||||
importPaths := []string{
|
||||
configs.Path("../third_party"), // third_party目录
|
||||
configs.Path(".."), // third_party的上一级目录
|
||||
configs.Path("../third_party"), // third_party directory
|
||||
configs.Path(".."), // Previous level of third_party
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@@ -19,35 +19,35 @@ import (
|
||||
)
|
||||
|
||||
func newUserExampleService() *gotest.Service {
|
||||
// todo 补充测试字段信息
|
||||
// todo additional test field information
|
||||
testData := &model.UserExample{}
|
||||
testData.ID = 1
|
||||
testData.CreatedAt = time.Now()
|
||||
testData.UpdatedAt = testData.CreatedAt
|
||||
|
||||
// 初始化mock cache
|
||||
// init mock cache
|
||||
c := gotest.NewCache(map[string]interface{}{utils.Uint64ToStr(testData.ID): testData})
|
||||
c.ICache = cache.NewUserExampleCache(&model.CacheType{
|
||||
CType: "redis",
|
||||
Rdb: c.RedisClient,
|
||||
})
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := gotest.NewDao(c, testData)
|
||||
d.IDao = dao.NewUserExampleDao(d.DB, c.ICache.(cache.UserExampleCache))
|
||||
|
||||
// 初始化mock service
|
||||
// init mock service
|
||||
s := gotest.NewService(d, testData)
|
||||
serverNameExampleV1.RegisterUserExampleServiceServer(s.Server, &userExampleService{
|
||||
UnimplementedUserExampleServiceServer: serverNameExampleV1.UnimplementedUserExampleServiceServer{},
|
||||
iDao: d.IDao.(dao.UserExampleDao),
|
||||
})
|
||||
|
||||
// 启动rpc服务
|
||||
// start up rpc server
|
||||
s.GoGrpcServer()
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
// grpc客户端
|
||||
// grpc client
|
||||
s.IServiceClient = serverNameExampleV1.NewUserExampleServiceClient(s.GetClientConn())
|
||||
|
||||
return s
|
||||
@@ -62,7 +62,7 @@ func Test_userExampleService_Create(t *testing.T) {
|
||||
s.MockDao.SQLMock.ExpectBegin()
|
||||
args := s.MockDao.GetAnyArgs(s.TestData)
|
||||
s.MockDao.SQLMock.ExpectExec("INSERT INTO .*").
|
||||
WithArgs(args[:len(args)-1]...). // 根据实际参数数量修改
|
||||
WithArgs(args[:len(args)-1]...). // Modified according to the actual number of parameters
|
||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
s.MockDao.SQLMock.ExpectCommit()
|
||||
|
||||
@@ -98,7 +98,7 @@ func Test_userExampleService_DeleteByID(t *testing.T) {
|
||||
|
||||
s.MockDao.SQLMock.ExpectBegin()
|
||||
s.MockDao.SQLMock.ExpectExec("UPDATE .*").
|
||||
WithArgs(s.MockDao.AnyTime, testData.Id). // 根据测试数据数量调整
|
||||
WithArgs(s.MockDao.AnyTime, testData.Id). // Modified according to the actual number of parameters
|
||||
WillReturnResult(sqlmock.NewResult(int64(testData.Id), 1))
|
||||
s.MockDao.SQLMock.ExpectCommit()
|
||||
|
||||
@@ -127,7 +127,7 @@ func Test_userExampleService_UpdateByID(t *testing.T) {
|
||||
|
||||
s.MockDao.SQLMock.ExpectBegin()
|
||||
s.MockDao.SQLMock.ExpectExec("UPDATE .*").
|
||||
WithArgs(s.MockDao.AnyTime, testData.Id). // 根据测试数据数量调整
|
||||
WithArgs(s.MockDao.AnyTime, testData.Id). // Modified according to the actual number of parameters
|
||||
WillReturnResult(sqlmock.NewResult(int64(testData.Id), 1))
|
||||
s.MockDao.SQLMock.ExpectCommit()
|
||||
|
||||
@@ -215,7 +215,7 @@ func Test_userExampleService_List(t *testing.T) {
|
||||
Params: &types.Params{
|
||||
Page: 0,
|
||||
Limit: 10,
|
||||
Sort: "ignore count", // 忽略测试 select count(*)
|
||||
Sort: "ignore count", // ignore test count
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
@@ -1,28 +1,28 @@
|
||||
package types
|
||||
|
||||
// swagger公共结构体,建议都写注释,生成的swagger.json也会带有注释,
|
||||
// 如果使用yapi,把swagger.json导入yapi后自动填写备注,避免重复填写注释。
|
||||
// swagger public structures, it is recommended to write comments to all of them,
|
||||
// if you use yapi, import swagger.json into yapi and fill in the notes automatically to avoid repeating the comments.
|
||||
|
||||
// Result 输出数据格式
|
||||
// Result output data format
|
||||
type Result struct {
|
||||
Code int `json:"code"` // 返回码
|
||||
Msg string `json:"msg"` // 返回信息说明
|
||||
Data interface{} `json:"data"` // 返回数据
|
||||
Code int `json:"code"` // return code
|
||||
Msg string `json:"msg"` // return information description
|
||||
Data interface{} `json:"data"` // return data
|
||||
}
|
||||
|
||||
// Params 查询原始参数
|
||||
// Params query parameters
|
||||
type Params struct {
|
||||
Page int `form:"page" binding:"gte=0" json:"page"` // 页码
|
||||
Size int `form:"size" binding:"gt=0" json:"size"` // 每页行数
|
||||
Sort string `form:"sort" binding:"" json:"sort,omitempty"` // 排序字段,默认值为-id,字段前面有-号表示倒序,否则升序,多个字段用逗号分隔
|
||||
Page int `form:"page" binding:"gte=0" json:"page"` // page number, starting from page 0
|
||||
Size int `form:"size" binding:"gt=0" json:"size"` // lines per page
|
||||
Sort string `form:"sort" binding:"" json:"sort,omitempty"` // sorted fields, multi-column sorting separated by commas
|
||||
|
||||
Columns []Column `json:"columns,omitempty"` // 列查询条件
|
||||
Columns []Column `json:"columns,omitempty"` // query conditions
|
||||
}
|
||||
|
||||
// Column 表的列查询信息
|
||||
// Column search information
|
||||
type Column struct {
|
||||
Name string `json:"name"` // 列名
|
||||
Exp string `json:"exp"` // 表达式,值为空时默认为=,有=、!=、>、>=、<、<=、like七种类型
|
||||
Value interface{} `json:"value"` // 列值
|
||||
Logic string `json:"logic"` // 逻辑类型,值为空时默认为and,有&(and)、||(or)两种类型
|
||||
Name string `json:"name"` // column name
|
||||
Exp string `json:"exp"` // expressions, which default to = when the value is null, have =, ! =, >, >=, <, <=, like
|
||||
Value interface{} `json:"value"` // column value
|
||||
Logic string `json:"logic"` // logical type, defaults to and when value is null, only &(and), ||(or)
|
||||
}
|
||||
|
@@ -11,55 +11,55 @@ var _ time.Time
|
||||
// todo generate the request and response struct to here
|
||||
// delete the templates code start
|
||||
|
||||
// CreateUserExampleRequest 创建请求参数,所有字段是必须的,并且满足binding规则
|
||||
// binding使用说明 https://github.com/go-playground/validator
|
||||
// CreateUserExampleRequest create request parameters, all fields are mandatory and meet binding rules
|
||||
// binding instructions for use https://github.com/go-playground/validator
|
||||
type CreateUserExampleRequest struct {
|
||||
Name string `json:"name" binding:"min=2"` // 名称
|
||||
Email string `json:"email" binding:"email"` // 邮件
|
||||
Password string `json:"password" binding:"md5"` // 密码
|
||||
Phone string `form:"phone" binding:"e164"` // 手机号码,e164表示<+国家编号><手机号码>
|
||||
Avatar string `form:"avatar" binding:"min=5"` // 头像
|
||||
Age int `form:"age" binding:"gt=0,lt=120"` // 年龄
|
||||
Gender int `form:"gender" binding:"gte=0,lte=2"` // 性别,1:男,2:女
|
||||
Name string `json:"name" binding:"min=2"` // username
|
||||
Email string `json:"email" binding:"email"` // email
|
||||
Password string `json:"password" binding:"md5"` // password
|
||||
Phone string `form:"phone" binding:"e164"` // phone number, e164 means <+ country code> <cell phone number>.
|
||||
Avatar string `form:"avatar" binding:"min=5"` // avatar
|
||||
Age int `form:"age" binding:"gt=0,lt=120"` // age
|
||||
Gender int `form:"gender" binding:"gte=0,lte=2"` // gender, 1:Male, 2:Female, other values:unknown
|
||||
}
|
||||
|
||||
// UpdateUserExampleByIDRequest 更新请求参数,所有字段不是必须的,字段为非零值更新
|
||||
// UpdateUserExampleByIDRequest update request parameters, all fields are not required, fields are updated with non-zero values
|
||||
type UpdateUserExampleByIDRequest struct {
|
||||
ID uint64 `json:"id" binding:"-"` // id
|
||||
Name string `json:"name" binding:""` // 名称
|
||||
Email string `json:"email" binding:""` // 邮件
|
||||
Password string `json:"password" binding:""` // 密码
|
||||
Phone string `form:"phone" binding:""` // 手机号码
|
||||
Avatar string `form:"avatar" binding:""` // 头像
|
||||
Age int `form:"age" binding:""` // 年龄
|
||||
Gender int `form:"gender" binding:""` // 性别,1:男,2:女
|
||||
Name string `json:"name" binding:""` // username
|
||||
Email string `json:"email" binding:""` // email
|
||||
Password string `json:"password" binding:""` // password
|
||||
Phone string `form:"phone" binding:""` // phone number
|
||||
Avatar string `form:"avatar" binding:""` // avatar
|
||||
Age int `form:"age" binding:""` // age
|
||||
Gender int `form:"gender" binding:""` // gender, 1:Male, 2:Female, other values:unknown
|
||||
}
|
||||
|
||||
// GetUserExampleByIDRespond 返回数据
|
||||
// GetUserExampleByIDRespond response data
|
||||
type GetUserExampleByIDRespond struct {
|
||||
ID string `json:"id"` // id
|
||||
Name string `json:"name"` // 名称
|
||||
Email string `json:"email"` // 邮件
|
||||
Phone string `json:"phone"` // 手机号码
|
||||
Avatar string `json:"avatar"` // 头像
|
||||
Age int `json:"age"` // 年龄
|
||||
Gender int `json:"gender"` // 性别,1:男,2:女
|
||||
Status int `json:"status"` // 账号状态
|
||||
LoginAt int64 `json:"login_at"` // 登录时间戳
|
||||
CreatedAt time.Time `json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `json:"updated_at"` // 更新时间
|
||||
Name string `json:"name"` // username
|
||||
Email string `json:"email"` // email
|
||||
Phone string `json:"phone"` // phone number
|
||||
Avatar string `json:"avatar"` // avatar
|
||||
Age int `json:"age"` // age
|
||||
Gender int `json:"gender"` // gender, 1:Male, 2:Female, other values:unknown
|
||||
Status int `json:"status"` // account status, 1:inactive, 2:activated, 3:blocked
|
||||
LoginAt int64 `json:"login_at"` // login timestamp
|
||||
CreatedAt time.Time `json:"created_at"` // create time
|
||||
UpdatedAt time.Time `json:"updated_at"` // update time
|
||||
}
|
||||
|
||||
// delete the templates code end
|
||||
|
||||
// GetUserExamplesByIDsRequest request form ids
|
||||
type GetUserExamplesByIDsRequest struct {
|
||||
IDs []uint64 `json:"ids" binding:"min=1"` // id列表
|
||||
IDs []uint64 `json:"ids" binding:"min=1"` // id list
|
||||
}
|
||||
|
||||
// GetUserExamplesRequest request form params
|
||||
type GetUserExamplesRequest struct {
|
||||
query.Params // 查询参数
|
||||
query.Params // query parameters
|
||||
}
|
||||
|
||||
// ListUserExamplesRespond list data
|
||||
|
@@ -1,10 +1,10 @@
|
||||
## app
|
||||
|
||||
优雅的启动和停止服务,使用[errgroup](golang.org/x/sync/errgroup)保证多个服务同时正常启动。
|
||||
Elegantly start and stop services, using [errgroup](golang.org/x/sync/errgroup) to ensure that multiple services are started properly at the same time.
|
||||
|
||||
<br>
|
||||
|
||||
### 使用示例
|
||||
### Example of use
|
||||
|
||||
```go
|
||||
func main() {
|
||||
@@ -17,16 +17,16 @@ func main() {
|
||||
}
|
||||
|
||||
func registerInits() []app.Init {
|
||||
// 读取配置文件
|
||||
// get configuration
|
||||
|
||||
var inits []app.Init
|
||||
|
||||
// 初始化日志
|
||||
// initializing log
|
||||
inits = append(inits, func() {
|
||||
|
||||
})
|
||||
|
||||
// 初始化数据库
|
||||
// initializing database
|
||||
inits = append(inits, func() {
|
||||
|
||||
})
|
||||
@@ -39,12 +39,12 @@ func registerInits() []app.Init {
|
||||
func registerServers() []app.IServer {
|
||||
var servers []app.IServer
|
||||
|
||||
// 创建http服务
|
||||
// creating http service
|
||||
servers = append(servers, server.NewHTTPServer(
|
||||
|
||||
))
|
||||
|
||||
// 创建grpc服务
|
||||
// creating grpc service
|
||||
servers = append(servers, server.NewGRPCServer(
|
||||
|
||||
))
|
||||
@@ -57,12 +57,12 @@ func registerServers() []app.IServer {
|
||||
func registerCloses(servers []app.IServer) []app.Close {
|
||||
var closes []app.Close
|
||||
|
||||
// 关闭服务
|
||||
// close server
|
||||
for _, server := range servers {
|
||||
closes = append(closes, server.Stop)
|
||||
}
|
||||
|
||||
// 关闭数据库连接
|
||||
// close other resource
|
||||
closes = append(closes, func() error {
|
||||
|
||||
})
|
||||
|
10
pkg/cache/README.md
vendored
10
pkg/cache/README.md
vendored
@@ -1,12 +1,12 @@
|
||||
## cache
|
||||
|
||||
支持memory缓存和redis缓存。
|
||||
memory and redis cache libraries.
|
||||
|
||||
## 使用示例
|
||||
## Example of use
|
||||
|
||||
```go
|
||||
|
||||
// 实例化缓存类型,根据CType字段选择使用memory或redis
|
||||
// Choose to create a memory or redis cache depending on CType
|
||||
cache := cache.NewUserExampleCache(&model.CacheType{
|
||||
CType: "redis",
|
||||
Rdb: c.RedisClient,
|
||||
@@ -32,11 +32,11 @@ func (d *userExampleDao) GetByID(ctx context.Context, id uint64) (*model.UserExa
|
||||
}
|
||||
|
||||
if errors.Is(err, model.ErrCacheNotFound) {
|
||||
// 从mysql获取
|
||||
// get from mysql
|
||||
table := &model.UserExample{}
|
||||
err = d.db.WithContext(ctx).Where("id = ?", id).First(table).Error
|
||||
if err != nil {
|
||||
// if data is empty, set not found cache to prevent cache penetration(防止缓存穿透)
|
||||
// if data is empty, set not found cache to prevent cache penetration(preventing Cache Penetration)
|
||||
if errors.Is(err, model.ErrRecordNotFound) {
|
||||
err = d.cache.SetCacheWithNotFound(ctx, id)
|
||||
if err != nil {
|
||||
|
21
pkg/cache/cache.go
vendored
21
pkg/cache/cache.go
vendored
@@ -7,14 +7,15 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultExpireTime 默认过期时间
|
||||
// DefaultExpireTime default expiry time
|
||||
DefaultExpireTime = time.Hour * 24
|
||||
// DefaultNotFoundExpireTime 结果为空时的过期时间 1分钟, 常用于数据为空时的缓存时间(缓存穿透)
|
||||
// DefaultNotFoundExpireTime expiry time when result is empty 1 minute,
|
||||
// often used for cache time when data is empty (cache pass-through)
|
||||
DefaultNotFoundExpireTime = time.Minute
|
||||
// NotFoundPlaceholder 占位符
|
||||
// NotFoundPlaceholder placeholder
|
||||
NotFoundPlaceholder = "*"
|
||||
|
||||
// DefaultClient 生成一个缓存客户端,其中keyPrefix 一般为业务前缀
|
||||
// DefaultClient generate a cache client, where keyPrefix is generally the business prefix
|
||||
DefaultClient Cache
|
||||
|
||||
// ErrPlaceholder .
|
||||
@@ -23,7 +24,7 @@ var (
|
||||
ErrSetMemoryWithNotFound = errors.New("cache: set memory cache err for not found")
|
||||
)
|
||||
|
||||
// Cache 定义cache驱动接口
|
||||
// Cache driver interface
|
||||
type Cache interface {
|
||||
Set(ctx context.Context, key string, val interface{}, expiration time.Duration) error
|
||||
Get(ctx context.Context, key string, val interface{}) error
|
||||
@@ -33,27 +34,27 @@ type Cache interface {
|
||||
SetCacheWithNotFound(ctx context.Context, key string) error
|
||||
}
|
||||
|
||||
// Set 数据
|
||||
// Set data
|
||||
func Set(ctx context.Context, key string, val interface{}, expiration time.Duration) error {
|
||||
return DefaultClient.Set(ctx, key, val, expiration)
|
||||
}
|
||||
|
||||
// Get 数据
|
||||
// Get data
|
||||
func Get(ctx context.Context, key string, val interface{}) error {
|
||||
return DefaultClient.Get(ctx, key, val)
|
||||
}
|
||||
|
||||
// MultiSet 批量set
|
||||
// MultiSet multiple set data
|
||||
func MultiSet(ctx context.Context, valMap map[string]interface{}, expiration time.Duration) error {
|
||||
return DefaultClient.MultiSet(ctx, valMap, expiration)
|
||||
}
|
||||
|
||||
// MultiGet 批量获取
|
||||
// MultiGet multiple get data
|
||||
func MultiGet(ctx context.Context, keys []string, valueMap interface{}) error {
|
||||
return DefaultClient.MultiGet(ctx, keys, valueMap)
|
||||
}
|
||||
|
||||
// Del 批量删除
|
||||
// Del multiple delete data
|
||||
func Del(ctx context.Context, keys ...string) error {
|
||||
return DefaultClient.Del(ctx, keys...)
|
||||
}
|
||||
|
9
pkg/cache/memory.go
vendored
9
pkg/cache/memory.go
vendored
@@ -38,7 +38,7 @@ func NewMemoryCache(keyPrefix string, encoding encoding.Encoding, newObject func
|
||||
}
|
||||
}
|
||||
|
||||
// Set add cache
|
||||
// Set data
|
||||
func (m *memoryCache) Set(ctx context.Context, key string, val interface{}, expiration time.Duration) error {
|
||||
buf, err := encoding.Marshal(m.encoding, val)
|
||||
if err != nil {
|
||||
@@ -80,7 +80,7 @@ func (m *memoryCache) Get(ctx context.Context, key string, val interface{}) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
// Del 删除
|
||||
// Del delete data
|
||||
func (m *memoryCache) Del(ctx context.Context, keys ...string) error {
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
@@ -95,7 +95,7 @@ func (m *memoryCache) Del(ctx context.Context, keys ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MultiSet 批量set
|
||||
// MultiSet multiple set data
|
||||
func (m *memoryCache) MultiSet(ctx context.Context, valueMap map[string]interface{}, expiration time.Duration) error {
|
||||
var err error
|
||||
for key, value := range valueMap {
|
||||
@@ -107,7 +107,7 @@ func (m *memoryCache) MultiSet(ctx context.Context, valueMap map[string]interfac
|
||||
return nil
|
||||
}
|
||||
|
||||
// MultiGet 批量获取
|
||||
// MultiGet multiple get data
|
||||
func (m *memoryCache) MultiGet(ctx context.Context, keys []string, value interface{}) error {
|
||||
valueMap := reflect.ValueOf(value)
|
||||
var err error
|
||||
@@ -123,6 +123,7 @@ func (m *memoryCache) MultiGet(ctx context.Context, keys []string, value interfa
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetCacheWithNotFound set not found
|
||||
func (m *memoryCache) SetCacheWithNotFound(ctx context.Context, key string) error {
|
||||
cacheKey, err := BuildCacheKey(m.KeyPrefix, key)
|
||||
if err != nil {
|
||||
|
18
pkg/cache/redis.go
vendored
18
pkg/cache/redis.go
vendored
@@ -25,7 +25,7 @@ type redisCache struct {
|
||||
newObject func() interface{}
|
||||
}
|
||||
|
||||
// NewRedisCache new一个cache, client 参数是可传入的,方便进行单元测试
|
||||
// NewRedisCache new a cache, client parameter can be passed in for unit testing
|
||||
func NewRedisCache(client *redis.Client, keyPrefix string, encoding encoding.Encoding, newObject func() interface{}) Cache {
|
||||
return &redisCache{
|
||||
client: client,
|
||||
@@ -70,7 +70,7 @@ func (c *redisCache) Get(ctx context.Context, key string, val interface{}) error
|
||||
return err
|
||||
}
|
||||
|
||||
// 防止data为空时,Unmarshal报错
|
||||
// prevent Unmarshal from reporting an error if data is empty
|
||||
if string(bytes) == "" {
|
||||
return nil
|
||||
}
|
||||
@@ -93,17 +93,17 @@ func (c *redisCache) MultiSet(ctx context.Context, valueMap map[string]interface
|
||||
if expiration == 0 {
|
||||
expiration = DefaultExpireTime
|
||||
}
|
||||
// key-value是成对的,所以这里的容量是map的2倍
|
||||
// the key-value is paired and has twice the capacity of a map
|
||||
paris := make([]interface{}, 0, 2*len(valueMap))
|
||||
for key, value := range valueMap {
|
||||
buf, err := encoding.Marshal(c.encoding, value)
|
||||
if err != nil {
|
||||
//logger.Warn("marshal data error", logger.Err(err), logger.Any("value", value))
|
||||
fmt.Printf("encoding.Marshal error, %v, value:%v\n", err, value)
|
||||
continue
|
||||
}
|
||||
cacheKey, err := BuildCacheKey(c.KeyPrefix, key)
|
||||
if err != nil {
|
||||
//logger.Warn("build cache key error", logger.Err(err), logger.String("key", key))
|
||||
fmt.Printf("BuildCacheKey error, %v, key:%v\n", err, key)
|
||||
continue
|
||||
}
|
||||
paris = append(paris, []byte(cacheKey))
|
||||
@@ -147,7 +147,7 @@ func (c *redisCache) MultiGet(ctx context.Context, keys []string, value interfac
|
||||
return fmt.Errorf("c.client.MGet error: %v, keys=%+v", err, cacheKeys)
|
||||
}
|
||||
|
||||
// 通过反射注入到map
|
||||
// Injection into map via reflection
|
||||
valueMap := reflect.ValueOf(value)
|
||||
for i, v := range values {
|
||||
if v == nil {
|
||||
@@ -156,7 +156,7 @@ func (c *redisCache) MultiGet(ctx context.Context, keys []string, value interfac
|
||||
object := c.newObject()
|
||||
err = encoding.Unmarshal(c.encoding, []byte(v.(string)), object)
|
||||
if err != nil {
|
||||
//logger.Warnf("unmarshal data error: %+v, key=%s, cacheKey=%s type=%v", err, keys[i], cacheKeys[i], reflect.TypeOf(value))
|
||||
fmt.Printf("unmarshal data error: %+v, key=%s, cacheKey=%s type=%v\n", err, keys[i], cacheKeys[i], reflect.TypeOf(value))
|
||||
continue
|
||||
}
|
||||
valueMap.SetMapIndex(reflect.ValueOf(cacheKeys[i]), reflect.ValueOf(object))
|
||||
@@ -170,12 +170,10 @@ func (c *redisCache) Del(ctx context.Context, keys ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 批量构建cacheKey
|
||||
cacheKeys := make([]string, len(keys))
|
||||
for index, key := range keys {
|
||||
cacheKey, err := BuildCacheKey(c.KeyPrefix, key)
|
||||
if err != nil {
|
||||
//logger.Warnf("build cache key err: %+v, key is %+v", err, key)
|
||||
continue
|
||||
}
|
||||
cacheKeys[index] = cacheKey
|
||||
@@ -197,7 +195,7 @@ func (c *redisCache) SetCacheWithNotFound(ctx context.Context, key string) error
|
||||
return c.client.Set(ctx, cacheKey, NotFoundPlaceholder, DefaultNotFoundExpireTime).Err()
|
||||
}
|
||||
|
||||
// BuildCacheKey 构建一个带有前缀的缓存key
|
||||
// BuildCacheKey construct a cache key with a prefix
|
||||
func BuildCacheKey(keyPrefix string, key string) (string, error) {
|
||||
if key == "" {
|
||||
return "", errors.New("[cache] key should not be empty")
|
||||
|
@@ -6,8 +6,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/zhufuyi/sponge/pkg/utils"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
|
@@ -93,15 +93,15 @@ func newHandler() *Handler {
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
// 初始化mock cache
|
||||
// init mock cache
|
||||
c := gotest.NewCache(map[string]interface{}{"no cache": testData})
|
||||
c.ICache = struct{}{} // instantiated cache interface
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := gotest.NewDao(c, testData)
|
||||
d.IDao = struct{}{} // instantiated dao interface
|
||||
|
||||
// 初始化mock handler
|
||||
// init mock handler
|
||||
h := gotest.NewHandler(d, testData)
|
||||
h.IHandler = struct{}{} // instantiated handler interface
|
||||
|
||||
|
@@ -150,10 +150,10 @@ func newTestUserDao() *Dao {
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
// 初始化mock cache
|
||||
// init mock cache
|
||||
c := NewCache(map[string]interface{}{"no cache": testData}) // 为了测试mysql,禁止缓存
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := NewDao(c, testData)
|
||||
d.IDao = newUserDao(d.DB)
|
||||
|
||||
|
@@ -14,15 +14,15 @@ func newHandler() *Handler {
|
||||
"2": "bar",
|
||||
}
|
||||
|
||||
// 初始化mock cache
|
||||
// init mock cache
|
||||
c := NewCache(map[string]interface{}{"no cache": testData})
|
||||
c.ICache = struct{}{} // instantiated cache interface
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := NewDao(c, testData)
|
||||
d.IDao = struct{}{} // instantiated dao interface
|
||||
|
||||
// 初始化mock handler
|
||||
// init mock handler
|
||||
h := NewHandler(d, testData)
|
||||
h.IHandler = struct{}{} // instantiated handler interface
|
||||
|
||||
|
@@ -14,15 +14,15 @@ func newService() *Service {
|
||||
"2": "bar",
|
||||
}
|
||||
|
||||
// 初始化mock cache
|
||||
// init mock cache
|
||||
c := NewCache(map[string]interface{}{"no cache": testData})
|
||||
c.ICache = struct{}{} // instantiated cache interface
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := NewDao(c, testData)
|
||||
d.IDao = struct{}{} // instantiated dao interface
|
||||
|
||||
// 初始化mock handler
|
||||
// init mock handler
|
||||
h := NewService(d, testData)
|
||||
h.IServiceClient = struct{}{} // instantiated handler interface
|
||||
|
||||
|
@@ -100,7 +100,7 @@ func getServerOptions() []grpc.ServerOption {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁用tls
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// 重试
|
||||
@@ -127,7 +127,7 @@ func getDialOptions() []grpc.DialOption {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁用tls
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// circuit breaker
|
||||
@@ -151,7 +151,7 @@ func getDialOptions() []grpc.DialOption {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁用tls
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// circuit breaker
|
||||
@@ -174,7 +174,7 @@ func getDialOptions() []grpc.DialOption {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁止tls加密
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// 超时拦截器
|
||||
@@ -214,7 +214,7 @@ func InitTrace(serviceName string) {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁用tls加密
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// tracing跟踪
|
||||
|
@@ -33,7 +33,7 @@ func main() {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁止tls加密
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// keepalive option
|
||||
|
@@ -70,7 +70,7 @@ func main() {
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁用tls
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// Metrics
|
||||
|
@@ -1,4 +1,4 @@
|
||||
## loadbalance
|
||||
## resolve
|
||||
|
||||
### 使用示例
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
func getDialOptions() []grpc.DialOption {
|
||||
var options []grpc.DialOption
|
||||
|
||||
// 禁止tls加密
|
||||
// use insecure transfer
|
||||
options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
// 负载均衡策略,轮询,https://github.com/grpc/grpc-go/tree/master/examples/features/load_balancing 和 https://github.com/grpc/grpc/blob/master/doc/service_config.md
|
||||
@@ -18,10 +18,8 @@ func getDialOptions() []grpc.DialOption {
|
||||
}
|
||||
|
||||
func main() {
|
||||
target := loadbalance.Register("grpc", "hello.grpc.io", []string{"127.0.0.1:8080", "127.0.0.1:8081", "127.0.0.1:8082"})
|
||||
fmt.Println(target)
|
||||
|
||||
roundRobinConn, err := grpc.Dial(target, getDialOptions()...)
|
||||
endpoint := resolve.Register("grpc", "hello.grpc.io", []string{"127.0.0.1:8282", "127.0.0.1:8284", "127.0.0.1:8286"})
|
||||
roundRobinConn, err := grpc.Dial(endpoint, getDialOptions()...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
@@ -1,51 +1,57 @@
|
||||
package loadbalance
|
||||
package resolve
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc/resolver"
|
||||
)
|
||||
|
||||
var mux = &sync.Mutex{}
|
||||
var mutex = &sync.Mutex{}
|
||||
|
||||
// Register 注册地址到resolver map
|
||||
func Register(schemeStr string, serviceNameStr string, address []string) string {
|
||||
mux.Lock()
|
||||
defer mux.Unlock()
|
||||
// Register address and serviceName
|
||||
func Register(scheme string, serviceName string, address []string) string {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
endpoint := fmt.Sprintf("%s:///%s", scheme, serviceName)
|
||||
u, _ := url.Parse(endpoint)
|
||||
|
||||
resolver.Register(&ResolverBuilder{
|
||||
SchemeVal: schemeStr,
|
||||
ServiceName: serviceNameStr,
|
||||
Addrs: address,
|
||||
scheme: scheme,
|
||||
serviceName: serviceName,
|
||||
addrs: address,
|
||||
path: u.Path,
|
||||
})
|
||||
|
||||
return fmt.Sprintf("%s:///%s", schemeStr, serviceNameStr)
|
||||
return endpoint
|
||||
}
|
||||
|
||||
// ResolverBuilder 解析生成器
|
||||
// ResolverBuilder resolver struct
|
||||
type ResolverBuilder struct {
|
||||
SchemeVal string // SchemeVal作为唯一标致,重复会被覆盖addrs
|
||||
ServiceName string
|
||||
Addrs []string
|
||||
scheme string
|
||||
serviceName string
|
||||
addrs []string
|
||||
path string
|
||||
}
|
||||
|
||||
// Build 创建生成器
|
||||
// Build resolver
|
||||
func (r *ResolverBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
||||
blr := &blResolver{
|
||||
target: target,
|
||||
cc: cc,
|
||||
addrsStore: map[string][]string{
|
||||
r.ServiceName: r.Addrs,
|
||||
r.path: r.addrs,
|
||||
},
|
||||
}
|
||||
blr.start()
|
||||
return blr, nil
|
||||
}
|
||||
|
||||
// Scheme 设置Scheme值
|
||||
// Scheme get scheme
|
||||
func (r *ResolverBuilder) Scheme() string {
|
||||
return r.SchemeVal
|
||||
return r.scheme
|
||||
}
|
||||
|
||||
type blResolver struct {
|
||||
@@ -63,8 +69,8 @@ func (b *blResolver) start() {
|
||||
_ = b.cc.UpdateState(resolver.State{Addresses: addrs})
|
||||
}
|
||||
|
||||
// ResolveNow 当前解析生成器
|
||||
// ResolveNow Resolve now
|
||||
func (*blResolver) ResolveNow(o resolver.ResolveNowOptions) {}
|
||||
|
||||
// Close 关闭
|
||||
// Close resolver
|
||||
func (*blResolver) Close() {}
|
@@ -1,22 +1,23 @@
|
||||
package loadbalance
|
||||
package resolve
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc/resolver"
|
||||
"google.golang.org/grpc/serviceconfig"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var r = &ResolverBuilder{
|
||||
SchemeVal: "grpc",
|
||||
ServiceName: "demo",
|
||||
Addrs: []string{"localhost:8282"},
|
||||
scheme: "grpc",
|
||||
serviceName: "demo",
|
||||
addrs: []string{"localhost:8282"},
|
||||
}
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
s := Register(r.SchemeVal, r.ServiceName, r.Addrs)
|
||||
assert.Equal(t, true, strings.Contains(s, r.ServiceName))
|
||||
s := Register(r.scheme, r.serviceName, r.addrs)
|
||||
assert.Equal(t, true, strings.Contains(s, r.serviceName))
|
||||
}
|
||||
|
||||
func TestResolverBuilder_Build(t *testing.T) {
|
@@ -29,7 +29,7 @@ func newUserExampleDao() *gotest.Dao {
|
||||
testData.CreatedAt = time.Now()
|
||||
testData.UpdatedAt = testData.CreatedAt
|
||||
|
||||
// 初始化mock dao
|
||||
// init mock dao
|
||||
d := gotest.NewDao(nil, testData)
|
||||
|
||||
return d
|
||||
|
@@ -14,7 +14,7 @@ func SetMaxSize(max int) {
|
||||
|
||||
// Page 页
|
||||
type Page struct {
|
||||
page int // 页码,从第0页开始
|
||||
page int // page number, starting from page 0
|
||||
size int // 每一页数量
|
||||
sort string // 字段排序
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ type Params struct {
|
||||
Port uint64 // nacos 服务端口
|
||||
Scheme string // http或https
|
||||
ContextPath string // path
|
||||
NamespaceID string // 名称空间id
|
||||
NamespaceID string // namespace id
|
||||
// 如果参数不为空,替换上面和ClientConfig和ServerConfig相同的字段
|
||||
clientConfig *constant.ClientConfig
|
||||
serverConfigs []constant.ServerConfig
|
||||
|
@@ -5,8 +5,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/zhufuyi/sponge/pkg/utils"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
|
@@ -33,8 +33,8 @@ func demo(){
|
||||
},
|
||||
}
|
||||
r.SetSubDirs(subPaths...) // 只处理指定子目录,优先级最高
|
||||
r.SetIgnoreDirs(ignoreDirs...) // 指定子目录下忽略处理的目录
|
||||
r.SetIgnoreFiles(ignoreFiles...) // 指定子目录下忽略处理的文件
|
||||
r.SetIgnoreDirs(ignoreDirs...) // specify the directory in the subdirectory where processing is ignored
|
||||
r.SetIgnoreFiles(ignoreFiles...) // specify the files in the subdirectory to be ignored for processing
|
||||
r.SetReplacementFields(fields) // 设置替换文本
|
||||
r.SetOutPath("", "test") // 设置输出目录,如果为空,根据名称和时间生成文件输出文件夹
|
||||
err = r.SaveFiles() // 保存替换后文件
|
||||
|
@@ -9,25 +9,25 @@ discovery 服务发现,与服务注册[registry](../registry)对应,支持et
|
||||
var endpoint string
|
||||
|
||||
switch grpcClientCfg.RegistryDiscoveryType {
|
||||
// 使用consul发现服务
|
||||
// discovering services using consul
|
||||
case "consul":
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // 通过服务名称连接grpc服务
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // Connecting to grpc services by service name
|
||||
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发现服务
|
||||
// discovering services using etcd
|
||||
case "etcd":
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // 通过服务名称连接grpc服务
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name // Connecting to grpc services by service name
|
||||
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发现服务
|
||||
// discovering services using nacos
|
||||
case "nacos":
|
||||
// example: endpoint = "discovery:///serverName.scheme"
|
||||
endpoint = "discovery:///" + grpcClientCfg.Name + ".grpc"
|
||||
|
@@ -10,7 +10,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
cfg := config.Get()
|
||||
|
||||
switch cfg.App.RegistryDiscoveryType {
|
||||
// 使用consul注册服务
|
||||
// registering service with consul
|
||||
case "consul":
|
||||
iRegistry, instance, err := consul.NewRegistry(
|
||||
cfg.Consul.Addr,
|
||||
@@ -22,7 +22,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用etcd注册服务
|
||||
// registering service with etcd
|
||||
case "etcd":
|
||||
iRegistry, instance, err := etcd.NewRegistry(
|
||||
cfg.Etcd.Addrs,
|
||||
@@ -34,7 +34,7 @@ func registryService(scheme string, host string, port int) (registry.Registry, *
|
||||
panic(err)
|
||||
}
|
||||
return iRegistry, instance
|
||||
// 使用nacos注册服务
|
||||
// registering service with nacos
|
||||
case "nacos":
|
||||
iRegistry, instance, err := nacos.NewRegistry(
|
||||
cfg.NacosRd.IPAddr,
|
||||
|
@@ -50,7 +50,7 @@ func InitWithConfig(appName string, appEnv string, appVersion string,
|
||||
WithServiceVersion(appVersion),
|
||||
)
|
||||
|
||||
// 初始化链路跟踪
|
||||
// initializing tracing
|
||||
exporter, err := NewJaegerAgentExporter(jaegerAgentHost, jaegerAgentPort)
|
||||
if err != nil {
|
||||
panic("init trace error:" + err.Error())
|
||||
|
@@ -10,13 +10,13 @@ function checkResult() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 判断文件是否存在
|
||||
# Determining whether a file exists
|
||||
if [ ! -f "${DEPLOY_FILE}" ];then
|
||||
echo "部署文件文件${DEPLOY_FILE}不存在"
|
||||
echo "Deployment file file ${DEPLOY_FILE} does not exist"
|
||||
checkResult 1
|
||||
fi
|
||||
|
||||
# 检查是否授权操作k8s
|
||||
# Check if you are authorised to operate k8s
|
||||
echo "kubectl version"
|
||||
kubectl version
|
||||
checkResult $?
|
||||
|
@@ -1,31 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 直接复制已编译的二进制文件构建出来的镜像。 优点:构建速度快,缺点:镜像体积被两阶段构建大一倍。
|
||||
# Image built by directly copying the compiled binaries. Advantage: fast build, disadvantage: the image is twice as large as a two-stage build.
|
||||
|
||||
serverName="serverNameExample_mixExample"
|
||||
# 服务的镜像名称,不能有大写字母
|
||||
# image name of the service, no capital letters
|
||||
SERVER_NAME="project-name-example.server-name-example"
|
||||
# Dockerfile文件目录
|
||||
# Dockerfile file directory
|
||||
DOCKERFILE_PATH="build"
|
||||
DOCKERFILE="${DOCKERFILE_PATH}/Dockerfile"
|
||||
|
||||
# 镜像仓库地址,REPO_HOST="ip或域名",通过第一个参数传进来
|
||||
# image repo address, REPO_HOST="ip or domain", passed in via the first parameter
|
||||
REPO_HOST=$1
|
||||
if [ "X${REPO_HOST}" = "X" ];then
|
||||
echo "param 'repo host' cannot be empty, example: ./image-build.sh hub.docker.com v1.0.0"
|
||||
exit 1
|
||||
fi
|
||||
# 版本tag,如果为空,默认为latest,通过第二个参数传进来
|
||||
# the version tag, which defaults to latest if empty, is passed in via the second parameter
|
||||
TAG=$2
|
||||
if [ "X${TAG}" = "X" ];then
|
||||
TAG="latest"
|
||||
fi
|
||||
# 镜像名称和tag
|
||||
# image name and tag
|
||||
IMAGE_NAME_TAG="${REPO_HOST}/${SERVER_NAME}:${TAG}"
|
||||
|
||||
# 二进制执行文件
|
||||
# binary executable files
|
||||
BIN_FILE="cmd/${serverName}/${serverName}"
|
||||
# 配置文件目录
|
||||
# configuration file directory
|
||||
CONFIG_PATH="configs"
|
||||
|
||||
# only grpc use start
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user