新建
This commit is contained in:
parent
5342989d8c
commit
394e3ba4b1
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "exhibition-register"]
|
||||
path = exhibition-register
|
||||
url = http://192.168.12.3:3000/exhibition/exhibition-register.git
|
||||
branch = main
|
22
DockerfileProd
Normal file
22
DockerfileProd
Normal file
@ -0,0 +1,22 @@
|
||||
FROM testhub.szjixun.cn:9043/public/golang:1.18-alpine AS builder
|
||||
|
||||
LABEL stage=gobuilder
|
||||
ENV CGO_ENABLED 0
|
||||
ENV GOPROXY https://goproxy.cn,direct
|
||||
WORKDIR /build
|
||||
COPY exhibition-register-server /app/exhibition-register-server
|
||||
|
||||
#FROM 172.16.100.99:9006/alpine
|
||||
#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||
#RUN apk update --no-cache
|
||||
#RUN apk add --no-cache ca-certificates
|
||||
#RUN apk add --no-cache tzdata
|
||||
FROM testhub.szjixun.cn:9043/public/self-alpine
|
||||
COPY ./conf /app/conf
|
||||
|
||||
ENV TZ Asia/Shanghai
|
||||
ENV MODE_ENV prod
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/exhibition-register-server .
|
||||
EXPOSE 20301
|
||||
CMD ["/app/exhibition-register-server"]
|
16
DockerfileSlim
Normal file
16
DockerfileSlim
Normal file
@ -0,0 +1,16 @@
|
||||
FROM busybox:glibc
|
||||
|
||||
COPY ./conf/Shanghai /usr/share/zoneinfo/Asia/Shanghai
|
||||
COPY ./conf/certs /etc/ssl/certs
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
|
||||
#ENV TZ Asia/Shanghai
|
||||
|
||||
WORKDIR /app/main-client
|
||||
#通过名称引用
|
||||
COPY ./build/app ./bin/mainServer
|
||||
COPY ./conf/ /app/conf/
|
||||
COPY ./conf/ ./conf/
|
||||
COPY ./conf/ /app/main-client/bin/conf/
|
||||
|
||||
WORKDIR /app/main-client/bin
|
||||
CMD ["./mainServer"]
|
22
DockerfileTest
Normal file
22
DockerfileTest
Normal file
@ -0,0 +1,22 @@
|
||||
FROM testhub.szjixun.cn:9043/public/golang:1.18-alpine AS builder
|
||||
|
||||
LABEL stage=gobuilder
|
||||
ENV CGO_ENABLED 0
|
||||
ENV GOPROXY https://goproxy.cn,direct
|
||||
WORKDIR /build
|
||||
COPY exhibition-register-server /app/exhibition-register-server
|
||||
|
||||
#FROM 172.16.100.99:9006/alpine
|
||||
#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||
#RUN apk update --no-cache
|
||||
#RUN apk add --no-cache ca-certificates
|
||||
#RUN apk add --no-cache tzdata
|
||||
FROM testhub.szjixun.cn:9043/public/self-alpine
|
||||
COPY ./conf /app/conf
|
||||
|
||||
ENV TZ Asia/Shanghai
|
||||
ENV MODE_ENV k8stest
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/exhibition-register-server .
|
||||
EXPOSE 20301
|
||||
CMD ["/app/exhibition-register-server"]
|
2
clear.sh
Normal file
2
clear.sh
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
ls pb/exhibition/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}';
|
48
cmd/app.go
Normal file
48
cmd/app.go
Normal file
@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "dubbo.apache.org/dubbo-go/v3/filter/tps/strategy"
|
||||
_ "dubbo.apache.org/dubbo-go/v3/imports"
|
||||
_ "exhibition-register/internal/handler"
|
||||
"exhibition-register/pkg/app"
|
||||
"exhibition-register/pkg/tracing"
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewApp(Lg *zap.Logger, JaegerTracer *tracing.JaegerProvider, SfNode *snowflake.Node, ExhibitionRegister *gorm.DB) *app.App {
|
||||
return &app.App{
|
||||
Lg: Lg,
|
||||
JaegerTracer: JaegerTracer,
|
||||
SfNode: SfNode,
|
||||
ExhibitionRegister: ExhibitionRegister,
|
||||
}
|
||||
}
|
||||
|
||||
//func main() {
|
||||
// var err error
|
||||
// exhibitionConfig.GetOptions()
|
||||
// app.ModuleClients, err = InitApp()
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// //l, err := net.Listen("tcp", ":8883")
|
||||
// //if err != nil {
|
||||
// // fmt.Printf("failed to listen: %v", err)
|
||||
// // return
|
||||
// //}
|
||||
// //
|
||||
// //s := grpc.NewServer() // 创建gRPC服务器
|
||||
// //dci.RegisterDciServer(s, &controller.DciProvider{}) // 在gRPC服务端注册服务
|
||||
// // 启动服务
|
||||
// //err = s.Serve(l)
|
||||
// //注册服务
|
||||
// config.SetProviderService(&controller.ExamProvider{})
|
||||
// common.Init()
|
||||
// if err = config.Load(); err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// select {}
|
||||
//}
|
19
cmd/wire.go
Normal file
19
cmd/wire.go
Normal file
@ -0,0 +1,19 @@
|
||||
// go:build wireinject
|
||||
//go:build wireinject
|
||||
// +build wireinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"exhibition-register/pkg/app"
|
||||
"exhibition-register/pkg/db"
|
||||
"exhibition-register/pkg/logger"
|
||||
"exhibition-register/pkg/snowf"
|
||||
"exhibition-register/pkg/tracing"
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
func InitApp() (*app.App, error) {
|
||||
wire.Build(logger.Provider, tracing.Provider, snowf.Provider, db.Provider, NewApp)
|
||||
return &app.App{}, nil
|
||||
}
|
27
conf/config.yaml
Normal file
27
conf/config.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
system:
|
||||
mode: dev #正式 prod #测试 test # 开发 dev
|
||||
config_source: config
|
||||
exhibitionRegister:
|
||||
host: 121.229.45.214
|
||||
port: 9007
|
||||
user: artuser
|
||||
password: C250PflXIWv2SQm8
|
||||
db_name: "exhibition_register"
|
||||
zapLog:
|
||||
level: "info"
|
||||
filename: "logs/exhibition_register.log"
|
||||
max_size: 5
|
||||
max_age: 30
|
||||
max_backups: 30
|
||||
snowflake:
|
||||
node_num: 4
|
||||
start_time: "2024-01-29"
|
||||
jaeger:
|
||||
addr: "127.0.0.1:6831"
|
||||
open: false
|
||||
#rabbitmq:
|
||||
# user: "myuser"
|
||||
# password: "mypass"
|
||||
# host: "localhost"
|
||||
# port: 5672
|
||||
# vhost: "oa"
|
@ -15,7 +15,7 @@ zapLog:
|
||||
max_backups: 30
|
||||
snowflake:
|
||||
node_num: 4
|
||||
start_time: "2023-12-20"
|
||||
start_time: "2024-01-29"
|
||||
jaeger:
|
||||
addr: "127.0.0.1:6831"
|
||||
open: false
|
||||
|
69
conf/dubbogo.yaml
Normal file
69
conf/dubbogo.yaml
Normal file
@ -0,0 +1,69 @@
|
||||
dubbo:
|
||||
metrics:
|
||||
enable: true # default is true
|
||||
path: /metrics # default is /metrics
|
||||
port: 9092 # default is 9090
|
||||
namespace: dubboExhibition # default is dubbo 作为数据上报 metrics 的前缀
|
||||
registries:
|
||||
demoZK:
|
||||
protocol: zookeeper
|
||||
timeout: 10s
|
||||
address: 127.0.0.1:2181 #本地
|
||||
# address: 114.218.158.24:2181 #测试环境
|
||||
protocols:
|
||||
triple: #triple
|
||||
name: tri
|
||||
port: 21501
|
||||
provider:
|
||||
filter: tracing
|
||||
services:
|
||||
ExhibitionProvider:
|
||||
interface: com.fontree.microservices.common.Exhibition
|
||||
retries: 0
|
||||
filter: tps,tracing
|
||||
tps.limiter: method-service
|
||||
tps.limit.strategy: fixedWindow
|
||||
tps.limit.rejected.handler: DefaultValueHandler
|
||||
tps.limit.interval: 1000 # 间隔时间
|
||||
tps.limit.rate: 30 # 间隔时间内次数
|
||||
warmup: 100 #预热时间
|
||||
logger:
|
||||
zap-config:
|
||||
level: info # 日志级别
|
||||
development: false
|
||||
disableCaller: false
|
||||
disableStacktrace: false
|
||||
encoding: "json"
|
||||
# zap encoder 配置
|
||||
encoderConfig:
|
||||
messageKey: "message"
|
||||
levelKey: "level"
|
||||
timeKey: "time"
|
||||
nameKey: "logger"
|
||||
callerKey: "caller"
|
||||
stacktraceKey: "stacktrace"
|
||||
lineEnding: ""
|
||||
levelEncoder: "capitalColor"
|
||||
timeEncoder: "iso8601"
|
||||
durationEncoder: "seconds"
|
||||
callerEncoder: "short"
|
||||
nameEncoder: ""
|
||||
EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"),
|
||||
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||
outputPaths:
|
||||
- "stderr"
|
||||
errorOutputPaths:
|
||||
- "stderr"
|
||||
lumberjack-config:
|
||||
# 写日志的文件名称
|
||||
filename: "runtime/logs/exhibition_register.log"
|
||||
# 每个日志文件长度的最大大小,单位是 MiB。默认 100MiB
|
||||
maxSize: 5
|
||||
# 日志保留的最大天数(只保留最近多少天的日志)
|
||||
maxAge: 30
|
||||
# 只保留最近多少个日志文件,用于控制程序总日志的大小
|
||||
maxBackups: 30
|
||||
# 是否使用本地时间,默认使用 UTC 时间
|
||||
localTime: true
|
||||
# 是否压缩日志文件,压缩方法 gzip
|
||||
compress: false
|
@ -19,7 +19,7 @@ zapLog:
|
||||
max_backups: 30
|
||||
snowflake:
|
||||
node_num: 4
|
||||
start_time: "2023-12-20"
|
||||
start_time: "2024-01-29"
|
||||
jaeger:
|
||||
addr: "127.0.0.1:6831"
|
||||
open: false
|
||||
|
@ -19,7 +19,7 @@ zapLog:
|
||||
max_backups: 30
|
||||
snowflake:
|
||||
node_num: 4
|
||||
start_time: "2023-12-20"
|
||||
start_time: "2024-01-29"
|
||||
jaeger:
|
||||
addr: "127.0.0.1:6831"
|
||||
open: false
|
||||
|
@ -19,7 +19,7 @@ zapLog:
|
||||
max_backups: 30
|
||||
snowflake:
|
||||
node_num: 4
|
||||
start_time: "2023-12-20"
|
||||
start_time: "2024-01-29"
|
||||
jaeger:
|
||||
addr: "127.0.0.1:6831"
|
||||
open: false
|
||||
|
152
config/config.go
Normal file
152
config/config.go
Normal file
@ -0,0 +1,152 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||||
"exhibition-register/pkg/msg"
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Data = new(AppConfig)
|
||||
|
||||
type AppConfig struct {
|
||||
System struct {
|
||||
Mode string
|
||||
ConfigSource string `mapstructure:"config_source"`
|
||||
}
|
||||
ExhibitionRegister struct {
|
||||
Host string
|
||||
Port string
|
||||
User string
|
||||
Password string
|
||||
DbName string `mapstructure:"db_name"`
|
||||
}
|
||||
Redis struct {
|
||||
DB string
|
||||
Addr string
|
||||
Password string
|
||||
}
|
||||
ZapLog struct {
|
||||
Level string `mapstructure:"level"`
|
||||
Filename string `mapstructure:"filename"`
|
||||
MaxSize string `mapstructure:"max_size"`
|
||||
MaxAge string `mapstructure:"max_age"`
|
||||
MaxBackups string `mapstructure:"max_backups"`
|
||||
}
|
||||
SnowFlake struct {
|
||||
NodeNum string `mapstructure:"node_num"`
|
||||
StartTime string `mapstructure:"start_time"`
|
||||
}
|
||||
Jaeger struct {
|
||||
Addr string `mapstructure:"host"`
|
||||
Open string `mapstructure:"open"`
|
||||
}
|
||||
RabbitMq struct {
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
Host string `mapstructure:"host"`
|
||||
Port string `mapstructure:"port"`
|
||||
Vhost string `mapstructure:"vhost"`
|
||||
}
|
||||
}
|
||||
|
||||
func GetConf() (iniConf string, err error) {
|
||||
if os.Getenv(msg.MODE_ENV) != "" {
|
||||
if err = os.Setenv(constant.ConfigFileEnvKey, fmt.Sprintf("./conf/%s/%s", os.Getenv(msg.MODE_ENV), msg.SERVER_DUBBOGO_CONFIG)); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if os.Getenv(msg.MODE_ENV) == "" {
|
||||
iniConf = fmt.Sprintf("./conf/%s", msg.SERVER_CONFIG)
|
||||
} else {
|
||||
iniConf = fmt.Sprintf("./conf/%s/%s", os.Getenv(msg.MODE_ENV), msg.SERVER_CONFIG)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetOptions() {
|
||||
iniConf, err := GetConf()
|
||||
if err != nil {
|
||||
panic("GetOptions err" + err.Error())
|
||||
}
|
||||
if err = Viper(iniConf); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func Viper(iniConf string) (err error) {
|
||||
viper.SetConfigFile(iniConf)
|
||||
err = viper.ReadInConfig()
|
||||
if err != nil {
|
||||
panic("viper.ReadInConfig failed" + err.Error())
|
||||
return
|
||||
}
|
||||
if err = viper.Unmarshal(Data); err != nil {
|
||||
panic("viper.Unmarshal failed" + err.Error())
|
||||
return
|
||||
}
|
||||
// 如果是configmap模式再修改
|
||||
fmt.Println(Data.System)
|
||||
if Data.System.ConfigSource == "configmap" {
|
||||
traverseFields(reflect.ValueOf(*Data), "", Data)
|
||||
}
|
||||
return
|
||||
}
|
||||
func traverseFields(value reflect.Value, prefix string, configPtr interface{}) {
|
||||
valueType := value.Type()
|
||||
prefixEnv := "${"
|
||||
suffixEnv := "}"
|
||||
// 遍历结构体的字段
|
||||
for i := 0; i < valueType.NumField(); i++ {
|
||||
field := valueType.Field(i)
|
||||
fieldValue := value.Field(i)
|
||||
// 拼接字段名(带有前缀)
|
||||
fieldName := prefix + field.Name
|
||||
// 判断字段的类型
|
||||
if fieldValue.Kind() == reflect.Struct {
|
||||
// 递归遍历嵌套结构体字段
|
||||
traverseFields(fieldValue, fieldName+".", configPtr)
|
||||
} else {
|
||||
// 获取字段的值
|
||||
fieldValueStr := fmt.Sprintf("%v", fieldValue.Interface())
|
||||
// 判断是不是需要通过环境变量获取
|
||||
if len(fieldValueStr) > 3 && strings.HasPrefix(fieldValueStr, prefixEnv) && strings.HasSuffix(fieldValueStr, suffixEnv) {
|
||||
end := len(fieldValueStr) - len(suffixEnv)
|
||||
var hasDefault bool
|
||||
if strings.Index(fieldValueStr, "|") > 0 {
|
||||
hasDefault = true
|
||||
end = strings.Index(fieldValueStr, "|")
|
||||
}
|
||||
envStr := fieldValueStr[len(prefixEnv):end]
|
||||
getValue := os.Getenv(envStr)
|
||||
if getValue == "" && hasDefault {
|
||||
getValue = fieldValueStr[end+1 : len(fieldValueStr)-len(suffixEnv)]
|
||||
}
|
||||
setSubFieldValue(configPtr, fieldName, getValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setSubFieldValue(configPtr interface{}, fieldPath string, newValue interface{}) {
|
||||
value := reflect.ValueOf(configPtr).Elem()
|
||||
fields := strings.Split(fieldPath, ".")
|
||||
for _, field := range fields {
|
||||
value = value.FieldByName(field)
|
||||
if !value.IsValid() {
|
||||
return // 字段不存在,直接返回
|
||||
}
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem() // 解引用指针类型的字段
|
||||
}
|
||||
}
|
||||
// 检查字段是否可设置
|
||||
if value.CanSet() {
|
||||
// 根据字段类型,将新值转换为对应类型并设置字段的值
|
||||
newValue := reflect.ValueOf(newValue).Convert(value.Type())
|
||||
value.Set(newValue)
|
||||
}
|
||||
}
|
157
go.mod
Normal file
157
go.mod
Normal file
@ -0,0 +1,157 @@
|
||||
module exhibition-register
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
dubbo.apache.org/dubbo-go/v3 v3.0.5
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/google/wire v0.5.0
|
||||
github.com/nacos-group/nacos-sdk-go v1.1.4
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/spf13/viper v1.17.0
|
||||
github.com/streadway/amqp v1.1.0
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
go.uber.org/zap v1.26.0
|
||||
gorm.io/driver/mysql v1.5.2
|
||||
gorm.io/gorm v1.25.5
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.1 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.2.3 // indirect
|
||||
github.com/Workiva/go-datastructures v1.0.52 // indirect
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
|
||||
github.com/alibaba/sentinel-golang v1.0.4 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
|
||||
github.com/apache/dubbo-getty v1.4.9-0.20221022181821-4dc6252ce98c // indirect
|
||||
github.com/apache/dubbo-go-hessian2 v1.11.5 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/creasty/defaults v1.5.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dlclark/regexp2 v1.7.0 // indirect
|
||||
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 // indirect
|
||||
github.com/dubbogo/gost v1.13.2 // indirect
|
||||
github.com/dubbogo/grpc-go v1.42.10 // indirect
|
||||
github.com/dubbogo/triple v1.2.2-rc2 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.11.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-co-op/gocron v1.9.0 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-kit/log v0.1.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.7.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.7.0 // indirect
|
||||
github.com/jinzhu/copier v0.3.5 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/k0kubun/pp v3.0.1+incompatible // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/knadh/koanf v1.5.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/polarismesh/polaris-go v1.3.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/prometheus/statsd_exporter v0.21.0 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.3.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.11.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.11.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/net v0.15.0 // indirect
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
google.golang.org/grpc v1.58.2 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
1
internal/controller/register.go
Normal file
1
internal/controller/register.go
Normal file
@ -0,0 +1 @@
|
||||
package controller
|
57
internal/handler/default_handler.go
Normal file
57
internal/handler/default_handler.go
Normal file
@ -0,0 +1,57 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"dubbo.apache.org/dubbo-go/v3/common"
|
||||
"dubbo.apache.org/dubbo-go/v3/common/extension"
|
||||
"dubbo.apache.org/dubbo-go/v3/filter"
|
||||
"dubbo.apache.org/dubbo-go/v3/protocol"
|
||||
)
|
||||
|
||||
func init() {
|
||||
extension.SetRejectedExecutionHandler("DefaultValueHandler", GetDefaultValueRejectedExecutionHandlerSingleton)
|
||||
}
|
||||
|
||||
type DefaultValueRejectedExecutionHandler struct {
|
||||
defaultResult sync.Map
|
||||
}
|
||||
|
||||
func (mh *DefaultValueRejectedExecutionHandler) RejectedExecution(url *common.URL, invocation protocol.Invocation) protocol.Result {
|
||||
key := url.ServiceKey() + "#" + invocation.MethodName()
|
||||
result, loaded := mh.defaultResult.Load(key)
|
||||
if !loaded {
|
||||
// we didn't configure any default value for this invocation
|
||||
return &protocol.RPCResult{
|
||||
Err: errors.New("请求太频繁"),
|
||||
}
|
||||
}
|
||||
return result.(*protocol.RPCResult)
|
||||
}
|
||||
|
||||
func GetCustomRejectedExecutionHandler() filter.RejectedExecutionHandler {
|
||||
return &DefaultValueRejectedExecutionHandler{}
|
||||
}
|
||||
|
||||
var (
|
||||
customHandlerOnce sync.Once
|
||||
customHandlerInstance *DefaultValueRejectedExecutionHandler
|
||||
)
|
||||
|
||||
/**
|
||||
* the better way is designing the RejectedExecutionHandler as singleton.
|
||||
*/
|
||||
func GetDefaultValueRejectedExecutionHandlerSingleton() filter.RejectedExecutionHandler {
|
||||
customHandlerOnce.Do(func() {
|
||||
customHandlerInstance = &DefaultValueRejectedExecutionHandler{}
|
||||
})
|
||||
|
||||
initDefaultValue()
|
||||
|
||||
return customHandlerInstance
|
||||
}
|
||||
|
||||
func initDefaultValue() {
|
||||
// setting your default value
|
||||
}
|
1
internal/logic/register.go
Normal file
1
internal/logic/register.go
Normal file
@ -0,0 +1 @@
|
||||
package logic
|
1
internal/model/register.go
Normal file
1
internal/model/register.go
Normal file
@ -0,0 +1 @@
|
||||
package model
|
923
pb/descriptor.proto
Normal file
923
pb/descriptor.proto
Normal file
@ -0,0 +1,923 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// The messages in this file describe the definitions found in .proto files.
|
||||
// A valid .proto file can be translated directly to a FileDescriptorProto
|
||||
// without any other information (e.g. without reading its imports).
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option go_package = "google.golang.org/protobuf/types/descriptorpb";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "DescriptorProtos";
|
||||
option csharp_namespace = "Google.Protobuf.Reflection";
|
||||
option objc_class_prefix = "GPB";
|
||||
option cc_enable_arenas = true;
|
||||
|
||||
// descriptor.proto must be optimized for speed because reflection-based
|
||||
// algorithms don't work during bootstrapping.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
// The protocol compiler can output a FileDescriptorSet containing the .proto
|
||||
// files it parses.
|
||||
message FileDescriptorSet {
|
||||
repeated FileDescriptorProto file = 1;
|
||||
}
|
||||
|
||||
// Describes a complete .proto file.
|
||||
message FileDescriptorProto {
|
||||
optional string name = 1; // file name, relative to root of source tree
|
||||
optional string package = 2; // e.g. "foo", "foo.bar", etc.
|
||||
|
||||
// Names of files imported by this file.
|
||||
repeated string dependency = 3;
|
||||
// Indexes of the public imported files in the dependency list above.
|
||||
repeated int32 public_dependency = 10;
|
||||
// Indexes of the weak imported files in the dependency list.
|
||||
// For Google-internal migration only. Do not use.
|
||||
repeated int32 weak_dependency = 11;
|
||||
|
||||
// All top-level definitions in this file.
|
||||
repeated DescriptorProto message_type = 4;
|
||||
repeated EnumDescriptorProto enum_type = 5;
|
||||
repeated ServiceDescriptorProto service = 6;
|
||||
repeated FieldDescriptorProto extension = 7;
|
||||
|
||||
optional FileOptions options = 8;
|
||||
|
||||
// This field contains optional information about the original source code.
|
||||
// You may safely remove this entire field without harming runtime
|
||||
// functionality of the descriptors -- the information is needed only by
|
||||
// development tools.
|
||||
optional SourceCodeInfo source_code_info = 9;
|
||||
|
||||
// The syntax of the proto file.
|
||||
// The supported values are "proto2", "proto3", and "editions".
|
||||
//
|
||||
// If `edition` is present, this value must be "editions".
|
||||
optional string syntax = 12;
|
||||
|
||||
// The edition of the proto file, which is an opaque string.
|
||||
optional string edition = 13;
|
||||
}
|
||||
|
||||
// Describes a message type.
|
||||
message DescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated FieldDescriptorProto field = 2;
|
||||
repeated FieldDescriptorProto extension = 6;
|
||||
|
||||
repeated DescriptorProto nested_type = 3;
|
||||
repeated EnumDescriptorProto enum_type = 4;
|
||||
|
||||
message ExtensionRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Exclusive.
|
||||
|
||||
optional ExtensionRangeOptions options = 3;
|
||||
}
|
||||
repeated ExtensionRange extension_range = 5;
|
||||
|
||||
repeated OneofDescriptorProto oneof_decl = 8;
|
||||
|
||||
optional MessageOptions options = 7;
|
||||
|
||||
// Range of reserved tag numbers. Reserved tag numbers may not be used by
|
||||
// fields or extension ranges in the same message. Reserved ranges may
|
||||
// not overlap.
|
||||
message ReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Exclusive.
|
||||
}
|
||||
repeated ReservedRange reserved_range = 9;
|
||||
// Reserved field names, which may not be used by fields in the same message.
|
||||
// A given name may only be reserved once.
|
||||
repeated string reserved_name = 10;
|
||||
}
|
||||
|
||||
message ExtensionRangeOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
// Describes a field within a message.
|
||||
message FieldDescriptorProto {
|
||||
enum Type {
|
||||
// 0 is reserved for errors.
|
||||
// Order is weird for historical reasons.
|
||||
TYPE_DOUBLE = 1;
|
||||
TYPE_FLOAT = 2;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
|
||||
// negative values are likely.
|
||||
TYPE_INT64 = 3;
|
||||
TYPE_UINT64 = 4;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
|
||||
// negative values are likely.
|
||||
TYPE_INT32 = 5;
|
||||
TYPE_FIXED64 = 6;
|
||||
TYPE_FIXED32 = 7;
|
||||
TYPE_BOOL = 8;
|
||||
TYPE_STRING = 9;
|
||||
// Tag-delimited aggregate.
|
||||
// Group type is deprecated and not supported in proto3. However, Proto3
|
||||
// implementations should still be able to parse the group wire format and
|
||||
// treat group fields as unknown fields.
|
||||
TYPE_GROUP = 10;
|
||||
TYPE_MESSAGE = 11; // Length-delimited aggregate.
|
||||
|
||||
// New in version 2.
|
||||
TYPE_BYTES = 12;
|
||||
TYPE_UINT32 = 13;
|
||||
TYPE_ENUM = 14;
|
||||
TYPE_SFIXED32 = 15;
|
||||
TYPE_SFIXED64 = 16;
|
||||
TYPE_SINT32 = 17; // Uses ZigZag encoding.
|
||||
TYPE_SINT64 = 18; // Uses ZigZag encoding.
|
||||
}
|
||||
|
||||
enum Label {
|
||||
// 0 is reserved for errors
|
||||
LABEL_OPTIONAL = 1;
|
||||
LABEL_REQUIRED = 2;
|
||||
LABEL_REPEATED = 3;
|
||||
}
|
||||
|
||||
optional string name = 1;
|
||||
optional int32 number = 3;
|
||||
optional Label label = 4;
|
||||
|
||||
// If type_name is set, this need not be set. If both this and type_name
|
||||
// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
|
||||
optional Type type = 5;
|
||||
|
||||
// For message and enum types, this is the name of the type. If the name
|
||||
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
|
||||
// rules are used to find the type (i.e. first the nested types within this
|
||||
// message are searched, then within the parent, on up to the root
|
||||
// namespace).
|
||||
optional string type_name = 6;
|
||||
|
||||
// For extensions, this is the name of the type being extended. It is
|
||||
// resolved in the same manner as type_name.
|
||||
optional string extendee = 2;
|
||||
|
||||
// For numeric types, contains the original text representation of the value.
|
||||
// For booleans, "true" or "false".
|
||||
// For strings, contains the default text contents (not escaped in any way).
|
||||
// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
|
||||
optional string default_value = 7;
|
||||
|
||||
// If set, gives the index of a oneof in the containing type's oneof_decl
|
||||
// list. This field is a member of that oneof.
|
||||
optional int32 oneof_index = 9;
|
||||
|
||||
// JSON name of this field. The value is set by protocol compiler. If the
|
||||
// user has set a "json_name" option on this field, that option's value
|
||||
// will be used. Otherwise, it's deduced from the field's name by converting
|
||||
// it to camelCase.
|
||||
optional string json_name = 10;
|
||||
|
||||
optional FieldOptions options = 8;
|
||||
|
||||
// If true, this is a proto3 "optional". When a proto3 field is optional, it
|
||||
// tracks presence regardless of field type.
|
||||
//
|
||||
// When proto3_optional is true, this field must be belong to a oneof to
|
||||
// signal to old proto3 clients that presence is tracked for this field. This
|
||||
// oneof is known as a "synthetic" oneof, and this field must be its sole
|
||||
// member (each proto3 optional field gets its own synthetic oneof). Synthetic
|
||||
// oneofs exist in the descriptor only, and do not generate any API. Synthetic
|
||||
// oneofs must be ordered after all "real" oneofs.
|
||||
//
|
||||
// For message fields, proto3_optional doesn't create any semantic change,
|
||||
// since non-repeated message fields always track presence. However it still
|
||||
// indicates the semantic detail of whether the user wrote "optional" or not.
|
||||
// This can be useful for round-tripping the .proto file. For consistency we
|
||||
// give message fields a synthetic oneof also, even though it is not required
|
||||
// to track presence. This is especially important because the parser can't
|
||||
// tell if a field is a message or an enum, so it must always create a
|
||||
// synthetic oneof.
|
||||
//
|
||||
// Proto2 optional fields do not set this flag, because they already indicate
|
||||
// optional with `LABEL_OPTIONAL`.
|
||||
optional bool proto3_optional = 17;
|
||||
}
|
||||
|
||||
// Describes a oneof.
|
||||
message OneofDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional OneofOptions options = 2;
|
||||
}
|
||||
|
||||
// Describes an enum type.
|
||||
message EnumDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated EnumValueDescriptorProto value = 2;
|
||||
|
||||
optional EnumOptions options = 3;
|
||||
|
||||
// Range of reserved numeric values. Reserved values may not be used by
|
||||
// entries in the same enum. Reserved ranges may not overlap.
|
||||
//
|
||||
// Note that this is distinct from DescriptorProto.ReservedRange in that it
|
||||
// is inclusive such that it can appropriately represent the entire int32
|
||||
// domain.
|
||||
message EnumReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Inclusive.
|
||||
}
|
||||
|
||||
// Range of reserved numeric values. Reserved numeric values may not be used
|
||||
// by enum values in the same enum declaration. Reserved ranges may not
|
||||
// overlap.
|
||||
repeated EnumReservedRange reserved_range = 4;
|
||||
|
||||
// Reserved enum value names, which may not be reused. A given name may only
|
||||
// be reserved once.
|
||||
repeated string reserved_name = 5;
|
||||
}
|
||||
|
||||
// Describes a value within an enum.
|
||||
message EnumValueDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional int32 number = 2;
|
||||
|
||||
optional EnumValueOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a service.
|
||||
message ServiceDescriptorProto {
|
||||
optional string name = 1;
|
||||
repeated MethodDescriptorProto method = 2;
|
||||
|
||||
optional ServiceOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a method of a service.
|
||||
message MethodDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
// Input and output type names. These are resolved in the same way as
|
||||
// FieldDescriptorProto.type_name, but must refer to a message type.
|
||||
optional string input_type = 2;
|
||||
optional string output_type = 3;
|
||||
|
||||
optional MethodOptions options = 4;
|
||||
|
||||
// Identifies if client streams multiple client messages
|
||||
optional bool client_streaming = 5 [default = false];
|
||||
// Identifies if server streams multiple server messages
|
||||
optional bool server_streaming = 6 [default = false];
|
||||
}
|
||||
|
||||
|
||||
// ===================================================================
|
||||
// Options
|
||||
|
||||
// Each of the definitions above may have "options" attached. These are
|
||||
// just annotations which may cause code to be generated slightly differently
|
||||
// or may contain hints for code that manipulates protocol messages.
|
||||
//
|
||||
// Clients may define custom options as extensions of the *Options messages.
|
||||
// These extensions may not yet be known at parsing time, so the parser cannot
|
||||
// store the values in them. Instead it stores them in a field in the *Options
|
||||
// message called uninterpreted_option. This field must have the same name
|
||||
// across all *Options messages. We then use this field to populate the
|
||||
// extensions when we build a descriptor, at which point all protos have been
|
||||
// parsed and so all extensions are known.
|
||||
//
|
||||
// Extension numbers for custom options may be chosen as follows:
|
||||
// * For options which will only be used within a single application or
|
||||
// organization, or for experimental options, use field numbers 50000
|
||||
// through 99999. It is up to you to ensure that you do not use the
|
||||
// same number for multiple options.
|
||||
// * For options which will be published and used publicly by multiple
|
||||
// independent entities, e-mail protobuf-global-extension-registry@google.com
|
||||
// to reserve extension numbers. Simply provide your project name (e.g.
|
||||
// Objective-C plugin) and your project website (if available) -- there's no
|
||||
// need to explain how you intend to use them. Usually you only need one
|
||||
// extension number. You can declare multiple options with only one extension
|
||||
// number by putting them in a sub-message. See the Custom Options section of
|
||||
// the docs for examples:
|
||||
// https://developers.google.com/protocol-buffers/docs/proto#options
|
||||
// If this turns out to be popular, a web service will be set up
|
||||
// to automatically assign option numbers.
|
||||
|
||||
message FileOptions {
|
||||
|
||||
// Sets the Java package where classes generated from this .proto will be
|
||||
// placed. By default, the proto package is used, but this is often
|
||||
// inappropriate because proto packages do not normally start with backwards
|
||||
// domain names.
|
||||
optional string java_package = 1;
|
||||
|
||||
|
||||
// Controls the name of the wrapper Java class generated for the .proto file.
|
||||
// That class will always contain the .proto file's getDescriptor() method as
|
||||
// well as any top-level extensions defined in the .proto file.
|
||||
// If java_multiple_files is disabled, then all the other classes from the
|
||||
// .proto file will be nested inside the single wrapper outer class.
|
||||
optional string java_outer_classname = 8;
|
||||
|
||||
// If enabled, then the Java code generator will generate a separate .java
|
||||
// file for each top-level message, enum, and service defined in the .proto
|
||||
// file. Thus, these types will *not* be nested inside the wrapper class
|
||||
// named by java_outer_classname. However, the wrapper class will still be
|
||||
// generated to contain the file's getDescriptor() method as well as any
|
||||
// top-level extensions defined in the file.
|
||||
optional bool java_multiple_files = 10 [default = false];
|
||||
|
||||
// This option does nothing.
|
||||
optional bool java_generate_equals_and_hash = 20 [deprecated=true];
|
||||
|
||||
// If set true, then the Java2 code generator will generate code that
|
||||
// throws an exception whenever an attempt is made to assign a non-UTF-8
|
||||
// byte sequence to a string field.
|
||||
// Message reflection will do the same.
|
||||
// However, an extension field still accepts non-UTF-8 byte sequences.
|
||||
// This option has no effect on when used with the lite runtime.
|
||||
optional bool java_string_check_utf8 = 27 [default = false];
|
||||
|
||||
|
||||
// Generated classes can be optimized for speed or code size.
|
||||
enum OptimizeMode {
|
||||
SPEED = 1; // Generate complete code for parsing, serialization,
|
||||
// etc.
|
||||
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
|
||||
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
|
||||
}
|
||||
optional OptimizeMode optimize_for = 9 [default = SPEED];
|
||||
|
||||
// Sets the Go package where structs generated from this .proto will be
|
||||
// placed. If omitted, the Go package will be derived from the following:
|
||||
// - The basename of the package import path, if provided.
|
||||
// - Otherwise, the package statement in the .proto file, if present.
|
||||
// - Otherwise, the basename of the .proto file, without extension.
|
||||
optional string go_package = 11;
|
||||
|
||||
|
||||
|
||||
|
||||
// Should generic services be generated in each language? "Generic" services
|
||||
// are not specific to any particular RPC system. They are generated by the
|
||||
// main code generators in each language (without additional plugins).
|
||||
// Generic services were the only kind of service generation supported by
|
||||
// early versions of google.protobuf.
|
||||
//
|
||||
// Generic services are now considered deprecated in favor of using plugins
|
||||
// that generate code specific to your particular RPC system. Therefore,
|
||||
// these default to false. Old code which depends on generic services should
|
||||
// explicitly set them to true.
|
||||
optional bool cc_generic_services = 16 [default = false];
|
||||
optional bool java_generic_services = 17 [default = false];
|
||||
optional bool py_generic_services = 18 [default = false];
|
||||
optional bool php_generic_services = 42 [default = false];
|
||||
|
||||
// Is this file deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for everything in the file, or it will be completely ignored; in the very
|
||||
// least, this is a formalization for deprecating files.
|
||||
optional bool deprecated = 23 [default = false];
|
||||
|
||||
// Enables the use of arenas for the proto messages in this file. This applies
|
||||
// only to generated classes for C++.
|
||||
optional bool cc_enable_arenas = 31 [default = true];
|
||||
|
||||
|
||||
// Sets the objective c class prefix which is prepended to all objective c
|
||||
// generated classes from this .proto. There is no default.
|
||||
optional string objc_class_prefix = 36;
|
||||
|
||||
// Namespace for generated classes; defaults to the package.
|
||||
optional string csharp_namespace = 37;
|
||||
|
||||
// By default Swift generators will take the proto package and CamelCase it
|
||||
// replacing '.' with underscore and use that to prefix the types/symbols
|
||||
// defined. When this options is provided, they will use this value instead
|
||||
// to prefix the types/symbols defined.
|
||||
optional string swift_prefix = 39;
|
||||
|
||||
// Sets the php class prefix which is prepended to all php generated classes
|
||||
// from this .proto. Default is empty.
|
||||
optional string php_class_prefix = 40;
|
||||
|
||||
// Use this option to change the namespace of php generated classes. Default
|
||||
// is empty. When this option is empty, the package name will be used for
|
||||
// determining the namespace.
|
||||
optional string php_namespace = 41;
|
||||
|
||||
// Use this option to change the namespace of php generated metadata classes.
|
||||
// Default is empty. When this option is empty, the proto file name will be
|
||||
// used for determining the namespace.
|
||||
optional string php_metadata_namespace = 44;
|
||||
|
||||
// Use this option to change the package of ruby generated classes. Default
|
||||
// is empty. When this option is not set, the package name will be used for
|
||||
// determining the ruby package.
|
||||
optional string ruby_package = 45;
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here.
|
||||
// See the documentation for the "Options" section above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message.
|
||||
// See the documentation for the "Options" section above.
|
||||
extensions 1000 to max;
|
||||
|
||||
reserved 38;
|
||||
}
|
||||
|
||||
message MessageOptions {
|
||||
// Set true to use the old proto1 MessageSet wire format for extensions.
|
||||
// This is provided for backwards-compatibility with the MessageSet wire
|
||||
// format. You should not use this for any other reason: It's less
|
||||
// efficient, has fewer features, and is more complicated.
|
||||
//
|
||||
// The message must be defined exactly as follows:
|
||||
// message Foo {
|
||||
// option message_set_wire_format = true;
|
||||
// extensions 4 to max;
|
||||
// }
|
||||
// Note that the message cannot have any defined fields; MessageSets only
|
||||
// have extensions.
|
||||
//
|
||||
// All extensions of your type must be singular messages; e.g. they cannot
|
||||
// be int32s, enums, or repeated messages.
|
||||
//
|
||||
// Because this is an option, the above two restrictions are not enforced by
|
||||
// the protocol compiler.
|
||||
optional bool message_set_wire_format = 1 [default = false];
|
||||
|
||||
// Disables the generation of the standard "descriptor()" accessor, which can
|
||||
// conflict with a field of the same name. This is meant to make migration
|
||||
// from proto1 easier; new code should avoid fields named "descriptor".
|
||||
optional bool no_standard_descriptor_accessor = 2 [default = false];
|
||||
|
||||
// Is this message deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the message, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating messages.
|
||||
optional bool deprecated = 3 [default = false];
|
||||
|
||||
reserved 4, 5, 6;
|
||||
|
||||
// Whether the message is an automatically generated map entry type for the
|
||||
// maps field.
|
||||
//
|
||||
// For maps fields:
|
||||
// map<KeyType, ValueType> map_field = 1;
|
||||
// The parsed descriptor looks like:
|
||||
// message MapFieldEntry {
|
||||
// option map_entry = true;
|
||||
// optional KeyType key = 1;
|
||||
// optional ValueType value = 2;
|
||||
// }
|
||||
// repeated MapFieldEntry map_field = 1;
|
||||
//
|
||||
// Implementations may choose not to generate the map_entry=true message, but
|
||||
// use a native map in the target language to hold the keys and values.
|
||||
// The reflection APIs in such implementations still need to work as
|
||||
// if the field is a repeated message field.
|
||||
//
|
||||
// NOTE: Do not set the option in .proto files. Always use the maps syntax
|
||||
// instead. The option should only be implicitly set by the proto compiler
|
||||
// parser.
|
||||
optional bool map_entry = 7;
|
||||
|
||||
reserved 8; // javalite_serializable
|
||||
reserved 9; // javanano_as_lite
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message FieldOptions {
|
||||
// The ctype option instructs the C++ code generator to use a different
|
||||
// representation of the field than it normally would. See the specific
|
||||
// options below. This option is not yet implemented in the open source
|
||||
// release -- sorry, we'll try to include it in a future version!
|
||||
optional CType ctype = 1 [default = STRING];
|
||||
enum CType {
|
||||
// Default mode.
|
||||
STRING = 0;
|
||||
|
||||
CORD = 1;
|
||||
|
||||
STRING_PIECE = 2;
|
||||
}
|
||||
// The packed option can be enabled for repeated primitive fields to enable
|
||||
// a more efficient representation on the wire. Rather than repeatedly
|
||||
// writing the tag and type for each element, the entire array is encoded as
|
||||
// a single length-delimited blob. In proto3, only explicit setting it to
|
||||
// false will avoid using packed encoding.
|
||||
optional bool packed = 2;
|
||||
|
||||
// The jstype option determines the JavaScript type used for values of the
|
||||
// field. The option is permitted only for 64 bit integral and fixed types
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
|
||||
// is represented as JavaScript string, which avoids loss of precision that
|
||||
// can happen when a large value is converted to a floating point JavaScript.
|
||||
// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
|
||||
// use the JavaScript "number" type. The behavior of the default option
|
||||
// JS_NORMAL is implementation dependent.
|
||||
//
|
||||
// This option is an enum to permit additional types to be added, e.g.
|
||||
// goog.math.Integer.
|
||||
optional JSType jstype = 6 [default = JS_NORMAL];
|
||||
enum JSType {
|
||||
// Use the default type.
|
||||
JS_NORMAL = 0;
|
||||
|
||||
// Use JavaScript strings.
|
||||
JS_STRING = 1;
|
||||
|
||||
// Use JavaScript numbers.
|
||||
JS_NUMBER = 2;
|
||||
}
|
||||
|
||||
// Should this field be parsed lazily? Lazy applies only to message-type
|
||||
// fields. It means that when the outer message is initially parsed, the
|
||||
// inner message's contents will not be parsed but instead stored in encoded
|
||||
// form. The inner message will actually be parsed when it is first accessed.
|
||||
//
|
||||
// This is only a hint. Implementations are free to choose whether to use
|
||||
// eager or lazy parsing regardless of the value of this option. However,
|
||||
// setting this option true suggests that the protocol author believes that
|
||||
// using lazy parsing on this field is worth the additional bookkeeping
|
||||
// overhead typically needed to implement it.
|
||||
//
|
||||
// This option does not affect the public interface of any generated code;
|
||||
// all method signatures remain the same. Furthermore, thread-safety of the
|
||||
// interface is not affected by this option; const methods remain safe to
|
||||
// call from multiple threads concurrently, while non-const methods continue
|
||||
// to require exclusive access.
|
||||
//
|
||||
//
|
||||
// Note that implementations may choose not to check required fields within
|
||||
// a lazy sub-message. That is, calling IsInitialized() on the outer message
|
||||
// may return true even if the inner message has missing required fields.
|
||||
// This is necessary because otherwise the inner message would have to be
|
||||
// parsed in order to perform the check, defeating the purpose of lazy
|
||||
// parsing. An implementation which chooses not to check required fields
|
||||
// must be consistent about it. That is, for any particular sub-message, the
|
||||
// implementation must either *always* check its required fields, or *never*
|
||||
// check its required fields, regardless of whether or not the message has
|
||||
// been parsed.
|
||||
//
|
||||
// As of May 2022, lazy verifies the contents of the byte stream during
|
||||
// parsing. An invalid byte stream will cause the overall parsing to fail.
|
||||
optional bool lazy = 5 [default = false];
|
||||
|
||||
// unverified_lazy does no correctness checks on the byte stream. This should
|
||||
// only be used where lazy with verification is prohibitive for performance
|
||||
// reasons.
|
||||
optional bool unverified_lazy = 15 [default = false];
|
||||
|
||||
// Is this field deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for accessors, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating fields.
|
||||
optional bool deprecated = 3 [default = false];
|
||||
|
||||
// For Google-internal migration only. Do not use.
|
||||
optional bool weak = 10 [default = false];
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
|
||||
reserved 4; // removed jtype
|
||||
}
|
||||
|
||||
message OneofOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumOptions {
|
||||
|
||||
// Set this option to true to allow mapping different tag names to the same
|
||||
// value.
|
||||
optional bool allow_alias = 2;
|
||||
|
||||
// Is this enum deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating enums.
|
||||
optional bool deprecated = 3 [default = false];
|
||||
|
||||
reserved 5; // javanano_as_lite
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumValueOptions {
|
||||
// Is this enum value deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum value, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating enum values.
|
||||
optional bool deprecated = 1 [default = false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message ServiceOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this service deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the service, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating services.
|
||||
optional bool deprecated = 33 [default = false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message MethodOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this method deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the method, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating methods.
|
||||
optional bool deprecated = 33 [default = false];
|
||||
|
||||
// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
|
||||
// or neither? HTTP based RPC implementation may choose GET verb for safe
|
||||
// methods, and PUT verb for idempotent methods instead of the default POST.
|
||||
enum IdempotencyLevel {
|
||||
IDEMPOTENCY_UNKNOWN = 0;
|
||||
NO_SIDE_EFFECTS = 1; // implies idempotent
|
||||
IDEMPOTENT = 2; // idempotent, but may have side effects
|
||||
}
|
||||
optional IdempotencyLevel idempotency_level = 34
|
||||
[default = IDEMPOTENCY_UNKNOWN];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
|
||||
// A message representing a option the parser does not recognize. This only
|
||||
// appears in options protos created by the compiler::Parser class.
|
||||
// DescriptorPool resolves these when building Descriptor objects. Therefore,
|
||||
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
|
||||
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
|
||||
// in them.
|
||||
message UninterpretedOption {
|
||||
// The name of the uninterpreted option. Each string represents a segment in
|
||||
// a dot-separated name. is_extension is true iff a segment represents an
|
||||
// extension (denoted with parentheses in options specs in .proto files).
|
||||
// E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents
|
||||
// "foo.(bar.baz).moo".
|
||||
message NamePart {
|
||||
required string name_part = 1;
|
||||
required bool is_extension = 2;
|
||||
}
|
||||
repeated NamePart name = 2;
|
||||
|
||||
// The value of the uninterpreted option, in whatever type the tokenizer
|
||||
// identified it as during parsing. Exactly one of these should be set.
|
||||
optional string identifier_value = 3;
|
||||
optional uint64 positive_int_value = 4;
|
||||
optional int64 negative_int_value = 5;
|
||||
optional double double_value = 6;
|
||||
optional bytes string_value = 7;
|
||||
optional string aggregate_value = 8;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Optional source code info
|
||||
|
||||
// Encapsulates information about the original source file from which a
|
||||
// FileDescriptorProto was generated.
|
||||
message SourceCodeInfo {
|
||||
// A Location identifies a piece of source code in a .proto file which
|
||||
// corresponds to a particular definition. This information is intended
|
||||
// to be useful to IDEs, code indexers, documentation generators, and similar
|
||||
// tools.
|
||||
//
|
||||
// For example, say we have a file like:
|
||||
// message Foo {
|
||||
// optional string foo = 1;
|
||||
// }
|
||||
// Let's look at just the field definition:
|
||||
// optional string foo = 1;
|
||||
// ^ ^^ ^^ ^ ^^^
|
||||
// a bc de f ghi
|
||||
// We have the following locations:
|
||||
// span path represents
|
||||
// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
|
||||
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
|
||||
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
|
||||
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
|
||||
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
|
||||
//
|
||||
// Notes:
|
||||
// - A location may refer to a repeated field itself (i.e. not to any
|
||||
// particular index within it). This is used whenever a set of elements are
|
||||
// logically enclosed in a single code segment. For example, an entire
|
||||
// extend block (possibly containing multiple extension definitions) will
|
||||
// have an outer location whose path refers to the "extensions" repeated
|
||||
// field without an index.
|
||||
// - Multiple locations may have the same path. This happens when a single
|
||||
// logical declaration is spread out across multiple places. The most
|
||||
// obvious example is the "extend" block again -- there may be multiple
|
||||
// extend blocks in the same scope, each of which will have the same path.
|
||||
// - A location's span is not always a subset of its parent's span. For
|
||||
// example, the "extendee" of an extension declaration appears at the
|
||||
// beginning of the "extend" block and is shared by all extensions within
|
||||
// the block.
|
||||
// - Just because a location's span is a subset of some other location's span
|
||||
// does not mean that it is a descendant. For example, a "group" defines
|
||||
// both a type and a field in a single declaration. Thus, the locations
|
||||
// corresponding to the type and field and their components will overlap.
|
||||
// - Code which tries to interpret locations should probably be designed to
|
||||
// ignore those that it doesn't understand, as more types of locations could
|
||||
// be recorded in the future.
|
||||
repeated Location location = 1;
|
||||
message Location {
|
||||
// Identifies which part of the FileDescriptorProto was defined at this
|
||||
// location.
|
||||
//
|
||||
// Each element is a field number or an index. They form a path from
|
||||
// the root FileDescriptorProto to the place where the definition occurs.
|
||||
// For example, this path:
|
||||
// [ 4, 3, 2, 7, 1 ]
|
||||
// refers to:
|
||||
// file.message_type(3) // 4, 3
|
||||
// .field(7) // 2, 7
|
||||
// .name() // 1
|
||||
// This is because FileDescriptorProto.message_type has field number 4:
|
||||
// repeated DescriptorProto message_type = 4;
|
||||
// and DescriptorProto.field has field number 2:
|
||||
// repeated FieldDescriptorProto field = 2;
|
||||
// and FieldDescriptorProto.name has field number 1:
|
||||
// optional string name = 1;
|
||||
//
|
||||
// Thus, the above path gives the location of a field name. If we removed
|
||||
// the last element:
|
||||
// [ 4, 3, 2, 7 ]
|
||||
// this path refers to the whole field declaration (from the beginning
|
||||
// of the label to the terminating semicolon).
|
||||
repeated int32 path = 1 [packed = true];
|
||||
|
||||
// Always has exactly three or four elements: start line, start column,
|
||||
// end line (optional, otherwise assumed same as start line), end column.
|
||||
// These are packed into a single field for efficiency. Note that line
|
||||
// and column numbers are zero-based -- typically you will want to add
|
||||
// 1 to each before displaying to a user.
|
||||
repeated int32 span = 2 [packed = true];
|
||||
|
||||
// If this SourceCodeInfo represents a complete declaration, these are any
|
||||
// comments appearing before and after the declaration which appear to be
|
||||
// attached to the declaration.
|
||||
//
|
||||
// A series of line comments appearing on consecutive lines, with no other
|
||||
// tokens appearing on those lines, will be treated as a single comment.
|
||||
//
|
||||
// leading_detached_comments will keep paragraphs of comments that appear
|
||||
// before (but not connected to) the current element. Each paragraph,
|
||||
// separated by empty lines, will be one comment element in the repeated
|
||||
// field.
|
||||
//
|
||||
// Only the comment content is provided; comment markers (e.g. //) are
|
||||
// stripped out. For block comments, leading whitespace and an asterisk
|
||||
// will be stripped from the beginning of each line other than the first.
|
||||
// Newlines are included in the output.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// optional int32 foo = 1; // Comment attached to foo.
|
||||
// // Comment attached to bar.
|
||||
// optional int32 bar = 2;
|
||||
//
|
||||
// optional string baz = 3;
|
||||
// // Comment attached to baz.
|
||||
// // Another line attached to baz.
|
||||
//
|
||||
// // Comment attached to moo.
|
||||
// //
|
||||
// // Another line attached to moo.
|
||||
// optional double moo = 4;
|
||||
//
|
||||
// // Detached comment for corge. This is not leading or trailing comments
|
||||
// // to moo or corge because there are blank lines separating it from
|
||||
// // both.
|
||||
//
|
||||
// // Detached comment for corge paragraph 2.
|
||||
//
|
||||
// optional string corge = 5;
|
||||
// /* Block comment attached
|
||||
// * to corge. Leading asterisks
|
||||
// * will be removed. */
|
||||
// /* Block comment attached to
|
||||
// * grault. */
|
||||
// optional int32 grault = 6;
|
||||
//
|
||||
// // ignored detached comments.
|
||||
optional string leading_comments = 3;
|
||||
optional string trailing_comments = 4;
|
||||
repeated string leading_detached_comments = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the relationship between generated code and its original source
|
||||
// file. A GeneratedCodeInfo message is associated with only one generated
|
||||
// source file, but may contain references to different source .proto files.
|
||||
message GeneratedCodeInfo {
|
||||
// An Annotation connects some span of text in generated code to an element
|
||||
// of its generating .proto file.
|
||||
repeated Annotation annotation = 1;
|
||||
message Annotation {
|
||||
// Identifies the element in the original source .proto file. This field
|
||||
// is formatted the same as SourceCodeInfo.Location.path.
|
||||
repeated int32 path = 1 [packed = true];
|
||||
|
||||
// Identifies the filesystem path to the original source .proto.
|
||||
optional string source_file = 2;
|
||||
|
||||
// Identifies the starting offset in bytes in the generated code
|
||||
// that relates to the identified object.
|
||||
optional int32 begin = 3;
|
||||
|
||||
// Identifies the ending offset in bytes in the generated code that
|
||||
// relates to the identified offset. The end offset should be one past
|
||||
// the last relevant byte (so the length of the text = end - begin).
|
||||
optional int32 end = 4;
|
||||
}
|
||||
}
|
11
pb/exhibition.proto
Normal file
11
pb/exhibition.proto
Normal file
@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package exhibition;
|
||||
option go_package = "./exhibition";
|
||||
|
||||
import "pb/descriptor.proto";
|
||||
import "pb/validator.proto";
|
||||
|
||||
service Exhibition {
|
||||
|
||||
}
|
80
pb/validator.proto
Normal file
80
pb/validator.proto
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||
// See LICENSE for licensing terms.
|
||||
|
||||
// Protocol Buffers extensions for defining auto-generateable validators for messages.
|
||||
|
||||
// TODO(mwitkow): Add example.
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
package validator;
|
||||
|
||||
import "pb/descriptor.proto";
|
||||
|
||||
option go_package = "github.com/mwitkow/go-proto-validators;validator";
|
||||
|
||||
// TODO(mwitkow): Email protobuf-global-extension-registry@google.com to get an extension ID.
|
||||
|
||||
extend google.protobuf.FieldOptions {
|
||||
optional FieldValidator field = 65020;
|
||||
}
|
||||
|
||||
extend google.protobuf.OneofOptions {
|
||||
optional OneofValidator oneof = 65021;
|
||||
}
|
||||
|
||||
message FieldValidator {
|
||||
// Uses a Golang RE2-syntax regex to match the field contents.
|
||||
optional string regex = 1;
|
||||
// Field value of integer strictly greater than this value.
|
||||
optional int64 int_gt = 2;
|
||||
// Field value of integer strictly smaller than this value.
|
||||
optional int64 int_lt = 3;
|
||||
// Used for nested message types, requires that the message type exists.
|
||||
optional bool msg_exists = 4;
|
||||
// Human error specifies a user-customizable error that is visible to the user.
|
||||
optional string human_error = 5;
|
||||
// Field value of double strictly greater than this value.
|
||||
// Note that this value can only take on a valid floating point
|
||||
// value. Use together with float_epsilon if you need something more specific.
|
||||
optional double float_gt = 6;
|
||||
// Field value of double strictly smaller than this value.
|
||||
// Note that this value can only take on a valid floating point
|
||||
// value. Use together with float_epsilon if you need something more specific.
|
||||
optional double float_lt = 7;
|
||||
// Field value of double describing the epsilon within which
|
||||
// any comparison should be considered to be true. For example,
|
||||
// when using float_gt = 0.35, using a float_epsilon of 0.05
|
||||
// would mean that any value above 0.30 is acceptable. It can be
|
||||
// thought of as a {float_value_condition} +- {float_epsilon}.
|
||||
// If unset, no correction for floating point inaccuracies in
|
||||
// comparisons will be attempted.
|
||||
optional double float_epsilon = 8;
|
||||
// Floating-point value compared to which the field content should be greater or equal.
|
||||
optional double float_gte = 9;
|
||||
// Floating-point value compared to which the field content should be smaller or equal.
|
||||
optional double float_lte = 10;
|
||||
// Used for string fields, requires the string to be not empty (i.e different from "").
|
||||
optional bool string_not_empty = 11;
|
||||
// Repeated field with at least this number of elements.
|
||||
optional int64 repeated_count_min = 12;
|
||||
// Repeated field with at most this number of elements.
|
||||
optional int64 repeated_count_max = 13;
|
||||
// Field value of length greater than this value.
|
||||
optional int64 length_gt = 14;
|
||||
// Field value of length smaller than this value.
|
||||
optional int64 length_lt = 15;
|
||||
// Field value of length strictly equal to this value.
|
||||
optional int64 length_eq = 16;
|
||||
// Requires that the value is in the enum.
|
||||
optional bool is_in_enum = 17;
|
||||
// Ensures that a string value is in UUID format.
|
||||
// uuid_ver specifies the valid UUID versions. Valid values are: 0-5.
|
||||
// If uuid_ver is 0 all UUID versions are accepted.
|
||||
optional int32 uuid_ver = 18;
|
||||
}
|
||||
|
||||
message OneofValidator {
|
||||
// Require that one of the oneof fields is set.
|
||||
optional bool required = 1;
|
||||
}
|
20
pkg/amqp/rabbitmq.go
Normal file
20
pkg/amqp/rabbitmq.go
Normal file
@ -0,0 +1,20 @@
|
||||
package amqp
|
||||
|
||||
import (
|
||||
"github.com/google/wire"
|
||||
"github.com/streadway/amqp"
|
||||
)
|
||||
|
||||
var RabbitMqConn *amqp.Connection
|
||||
|
||||
var Provider = wire.NewSet(NewRabbitMq)
|
||||
|
||||
func NewRabbitMq() *amqp.Connection {
|
||||
//var err error
|
||||
// 创建连接
|
||||
/*RabbitMqConn, err = amqp.Dial(fmt.Sprintf("amqp://%s:%s@%s:%d/%s", appConfig.Data.RabbitMq.User, appConfig.Data.RabbitMq.Password, appConfig.Data.RabbitMq.Host, appConfig.Data.RabbitMq.Port, appConfig.Data.RabbitMq.Vhost))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to connect RabbitMQ: %v", err)
|
||||
}*/
|
||||
return RabbitMqConn
|
||||
}
|
18
pkg/app/app.go
Normal file
18
pkg/app/app.go
Normal file
@ -0,0 +1,18 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"exhibition-register/pkg/tracing"
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var ModuleClients *App
|
||||
|
||||
type App struct {
|
||||
Lg *zap.Logger
|
||||
//RedisClient *redis.Client
|
||||
JaegerTracer *tracing.JaegerProvider
|
||||
ExhibitionRegister *gorm.DB
|
||||
SfNode *snowflake.Node
|
||||
}
|
24
pkg/cache/redis.go
vendored
Normal file
24
pkg/cache/redis.go
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/go-redis/redis"
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
var RedisProvider = wire.NewSet(NewRedis)
|
||||
|
||||
// TODO 添加连接池
|
||||
func NewRedis() *redis.Client {
|
||||
//redisDb, _ := strconv.Atoi(dciConfig.Data.Redis.DB)
|
||||
//RedisClient := redis.NewClient(&redis.Options{
|
||||
// Addr: dciConfig.Data.Redis.Addr,
|
||||
// Password: dciConfig.Data.Redis.Password,
|
||||
// DB: redisDb,
|
||||
//})
|
||||
//_, err := RedisClient.Ping().Result()
|
||||
//if err != nil {
|
||||
// logger.Errorf("connRedis err", err)
|
||||
// panic(err)
|
||||
//}
|
||||
return nil
|
||||
}
|
18
pkg/db/exhibition_register.go
Normal file
18
pkg/db/exhibition_register.go
Normal file
@ -0,0 +1,18 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
exhibitionConfig "exhibition-register/config"
|
||||
"github.com/google/wire"
|
||||
"gorm.io/gorm"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Provider = wire.NewSet(NewDB)
|
||||
|
||||
func NewDB() *gorm.DB {
|
||||
connDci := strings.Join([]string{exhibitionConfig.Data.ExhibitionRegister.User, ":", exhibitionConfig.Data.ExhibitionRegister.Password,
|
||||
"@tcp(", exhibitionConfig.Data.ExhibitionRegister.Host, ":", exhibitionConfig.Data.ExhibitionRegister.Port, ")/",
|
||||
exhibitionConfig.Data.ExhibitionRegister.DbName, "?charset=utf8mb4&parseTime=true&loc=Local"}, "")
|
||||
ExhibitionRegister := loadMysqlConn(connDci)
|
||||
return ExhibitionRegister
|
||||
}
|
62
pkg/db/mysql.go
Normal file
62
pkg/db/mysql.go
Normal file
@ -0,0 +1,62 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
"time"
|
||||
)
|
||||
|
||||
func loadMysqlConn(conn string) *gorm.DB {
|
||||
var ormLogger logger.Interface
|
||||
if gin.Mode() == "debug" {
|
||||
ormLogger = logger.Default.LogMode(logger.Info)
|
||||
} else {
|
||||
ormLogger = logger.Default
|
||||
}
|
||||
db, err := gorm.Open(mysql.New(mysql.Config{
|
||||
DSN: conn, // DSN data source name
|
||||
DefaultStringSize: 256, // string 类型字段的默认长度
|
||||
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
|
||||
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
|
||||
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
|
||||
SkipInitializeWithVersion: false, // 根据版本自动配置
|
||||
}), &gorm.Config{
|
||||
Logger: ormLogger,
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
SingularTable: true,
|
||||
},
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB.SetMaxIdleConns(20) //设置连接池,空闲
|
||||
sqlDB.SetMaxOpenConns(100) //打开
|
||||
sqlDB.SetConnMaxLifetime(time.Second * 30)
|
||||
err = db.AutoMigrate() //自迁移
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func addColumn(db *gorm.DB, dst interface{}, column string) {
|
||||
exist := db.Migrator().HasColumn(dst, column)
|
||||
if !exist {
|
||||
err := db.Migrator().AddColumn(dst, column)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func addTable(db *gorm.DB, dst interface{}) {
|
||||
|
||||
return
|
||||
}
|
28
pkg/err/common.go
Normal file
28
pkg/err/common.go
Normal file
@ -0,0 +1,28 @@
|
||||
package err
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"exhibition-register/pkg/app"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func ReturnError(err error, msg, print string) error {
|
||||
if err != nil {
|
||||
field := zap.Field{}
|
||||
field.String = err.Error()
|
||||
//app.ModuleClients.Lg.Error(print, field)
|
||||
fmt.Printf(print+"%+v\n", err)
|
||||
return errors.New(msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NoReturnError(err error, print string) {
|
||||
if err != nil {
|
||||
field := zap.Field{}
|
||||
field.String = err.Error()
|
||||
app.ModuleClients.Lg.Error(print, field)
|
||||
fmt.Printf(print+"%+v\n", err)
|
||||
}
|
||||
}
|
9
pkg/err/resultCode.go
Normal file
9
pkg/err/resultCode.go
Normal file
@ -0,0 +1,9 @@
|
||||
package err
|
||||
|
||||
var ResultCode = map[string]string{
|
||||
"OK": "正常返回",
|
||||
"BAD_REQUEST": "请求参数错误",
|
||||
"PERMISSION_ERROR": "权限错误",
|
||||
"BUSINESS_ERROR": "业务内容错误",
|
||||
"SERVER_ERROR": "服务器错误",
|
||||
}
|
3
pkg/err/resultMsg.go
Normal file
3
pkg/err/resultMsg.go
Normal file
@ -0,0 +1,3 @@
|
||||
package err
|
||||
|
||||
var ResultMsg = map[string]string{}
|
5
pkg/init/start.go
Normal file
5
pkg/init/start.go
Normal file
@ -0,0 +1,5 @@
|
||||
package common
|
||||
|
||||
func Init() {
|
||||
//db.DBMigration()
|
||||
}
|
63
pkg/logger/zap_logger.go
Normal file
63
pkg/logger/zap_logger.go
Normal file
@ -0,0 +1,63 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
exhibitionConfig "exhibition-register/config"
|
||||
"github.com/google/wire"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/natefinch/lumberjack"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
var Provider = wire.NewSet(ZapInit)
|
||||
|
||||
// ZapInit 初始化lg
|
||||
func ZapInit() *zap.Logger {
|
||||
var err error
|
||||
maxSize, _ := strconv.Atoi(exhibitionConfig.Data.ZapLog.MaxSize)
|
||||
maxAge, _ := strconv.Atoi(exhibitionConfig.Data.ZapLog.MaxAge)
|
||||
maxBackups, _ := strconv.Atoi(exhibitionConfig.Data.ZapLog.MaxAge)
|
||||
writeSyncer := getLogWriter(exhibitionConfig.Data.ZapLog.Filename, maxSize, maxBackups, maxAge)
|
||||
encoder := getEncoder()
|
||||
var l = new(zapcore.Level)
|
||||
err = l.UnmarshalText([]byte(exhibitionConfig.Data.ZapLog.Level))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var core zapcore.Core
|
||||
if exhibitionConfig.Data.System.Mode == "dev" {
|
||||
// 进入开发模式,日志输出到终端
|
||||
consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
|
||||
core = zapcore.NewTee(
|
||||
zapcore.NewCore(encoder, writeSyncer, l),
|
||||
zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), zapcore.DebugLevel),
|
||||
)
|
||||
} else {
|
||||
core = zapcore.NewCore(encoder, writeSyncer, l)
|
||||
}
|
||||
lg := zap.New(core, zap.AddCaller())
|
||||
zap.ReplaceGlobals(lg)
|
||||
return lg
|
||||
}
|
||||
|
||||
func getEncoder() zapcore.Encoder {
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
encoderConfig.TimeKey = "time"
|
||||
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
|
||||
encoderConfig.EncodeDuration = zapcore.SecondsDurationEncoder
|
||||
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder
|
||||
return zapcore.NewJSONEncoder(encoderConfig)
|
||||
}
|
||||
|
||||
func getLogWriter(filename string, maxSize, maxBackup, maxAge int) zapcore.WriteSyncer {
|
||||
lumberJackLogger := &lumberjack.Logger{
|
||||
Filename: filename,
|
||||
MaxSize: maxSize,
|
||||
MaxBackups: maxBackup,
|
||||
MaxAge: maxAge,
|
||||
}
|
||||
return zapcore.AddSync(lumberJackLogger)
|
||||
}
|
122
pkg/msg/msg.go
Normal file
122
pkg/msg/msg.go
Normal file
@ -0,0 +1,122 @@
|
||||
package msg
|
||||
|
||||
const (
|
||||
SERVER_CONFIG = "config.yaml"
|
||||
SERVER_DUBBOGO_CONFIG = "dubbogo.yaml"
|
||||
MODE_ENV = "MODE_ENV"
|
||||
)
|
||||
|
||||
const (
|
||||
Success = "操作成功"
|
||||
Failed = "操作失败"
|
||||
)
|
||||
|
||||
const (
|
||||
WholeTimeFormat = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
const (
|
||||
//ExamWaiting = 1 //未开始
|
||||
ExamDoing = 1 //进行中
|
||||
ExamFinished = 2 //已结束
|
||||
|
||||
TrainWaiting = 1 //未开始
|
||||
TrainDoing = 2 //进行中
|
||||
TrainFinished = 3 //已结束
|
||||
|
||||
IsRight = 1 //正确
|
||||
IsErr = 2 //正确
|
||||
|
||||
IsPass = 3 // 通过
|
||||
NotPass = 2 // 未通过
|
||||
IsNotStart = 1 // 未完成
|
||||
|
||||
NotGot = 1
|
||||
IsGot = 2
|
||||
|
||||
IsGift = 2
|
||||
IsNotGift = 1
|
||||
|
||||
IsTrain = 1 // 完成培训 及 录制了视频
|
||||
|
||||
IsNeedAnswer = 1 // 需要答题
|
||||
|
||||
IsNeedTrain = 1 // 需要培训
|
||||
|
||||
IsAll = 1 // 全部都需要参加
|
||||
)
|
||||
|
||||
const (
|
||||
Http = 200
|
||||
)
|
||||
|
||||
const (
|
||||
ErrorLogin = "账号或密码错误"
|
||||
ErrorJSONParse = "json解析失败"
|
||||
ErrorJSONMarshal = "json序列化失败"
|
||||
ErrorForUpdate = "锁定错误"
|
||||
ErrorInsert = "插入异常"
|
||||
ErrorDelete = "删除异常"
|
||||
ErrorUpdate = "更新异常"
|
||||
ErrorSelect = "查询异常"
|
||||
ErrorEmptyParam = "值为空"
|
||||
ErrorCopierStruct = "拷贝结构体错误"
|
||||
ErrorNoAction = "无需操作"
|
||||
ErrorInvalidParam = "参数不合法"
|
||||
ErrorNoData = "没有数据"
|
||||
ErrorDatetime = "时间格式错误"
|
||||
|
||||
ErrorSha256Write = "sha256加密错误"
|
||||
)
|
||||
|
||||
const (
|
||||
ErrOperate = "操作错误"
|
||||
|
||||
ErrCreateUser = "创建用户失败"
|
||||
ErrUpdateUser = "更新用户失败"
|
||||
ErrGetUserInfo = "查询用户信息失败"
|
||||
ErrGetUserInfoExam = "查询答题用户信息失败"
|
||||
ErrUserNotRegister = "用户未注册"
|
||||
ErrVerifyUser = "校验用户信息失败"
|
||||
ErrUserHad = "当前用户信息已存在"
|
||||
|
||||
ErrCreateExam = "创建考试失败"
|
||||
ErrUpdateExam = "更新考试失败"
|
||||
ErrGetExamInfoData = "查询考试信息失败"
|
||||
ErrGetExamInfoCount = "查询考试信息失败"
|
||||
ErrGetExamInfoNoParams = "查询考试信息条件错误"
|
||||
ErUpdateExamStatus = "更新考试状态错误"
|
||||
|
||||
ErrCreateTrain = "创建培训失败"
|
||||
ErrUpdateTrain = "更新培训失败"
|
||||
ErrGetTrainInfoData = "查询培训信息失败"
|
||||
ErrGetTrainInfoCount = "查询培训信息失败"
|
||||
ErrGetTrainInfoNoParams = "查询培训信息条件错误"
|
||||
|
||||
ErrCreateQuestion = "创建题目失败"
|
||||
ErrUpdateQuestion = "更新题目失败"
|
||||
ErrQuestionInUse = "题目正在被使用,无法修改"
|
||||
ErrGetQuestionInfoData = "查询题目信息失败"
|
||||
ErrGetQuestionInfoCount = "查询题目信息失败"
|
||||
|
||||
ErrCreateGift = "创建礼品失败"
|
||||
ErrUpdateGift = "更新礼品失败"
|
||||
ErrGetGiftInfoData = "查询礼品信息失败"
|
||||
ErrGetGiftInfoCount = "查询礼品信息失败"
|
||||
|
||||
ErrCreateUserHis = "创建考试成绩失败"
|
||||
ErrQueryUserHis = "查询考试成绩失败"
|
||||
ErrQueryAnswerScore = "查询答案分值失败"
|
||||
ErrQueryAnswer = "查询答案失败"
|
||||
ErrCreateUserAnswerHis = "创建作答记录失败"
|
||||
ErrCreateUserTrainHis = "创建培训记录失败"
|
||||
ErrUpdateUserTrainHis = "更新培训记录失败"
|
||||
ErrCreateUserGiftHis = "创建礼品记录失败"
|
||||
ErrUpdateUserGiftHis = "更新礼品状态失败"
|
||||
ErrCheckAnswer = "答案核对失败"
|
||||
ErrUpdateUserHis = "更新考试成绩失败"
|
||||
ErrUpdateParticipantNum = "更新参与人数失败"
|
||||
ErrUpdateParticipantPassNum = "更新通过人数失败"
|
||||
ErrQueryVideo = "查询视频信息失败"
|
||||
ErrQueryUserAnswerHis = "查询答题记录失败"
|
||||
)
|
4
pkg/service/init.go
Normal file
4
pkg/service/init.go
Normal file
@ -0,0 +1,4 @@
|
||||
package service
|
||||
|
||||
func init() {
|
||||
}
|
36
pkg/snowf/snowflake.go
Normal file
36
pkg/snowf/snowflake.go
Normal file
@ -0,0 +1,36 @@
|
||||
package snowf
|
||||
|
||||
import (
|
||||
exhibitionConfig "exhibition-register/config"
|
||||
"exhibition-register/pkg/app"
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/google/wire"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Provider = wire.NewSet(NewSf)
|
||||
|
||||
func NewSf() *snowflake.Node {
|
||||
var err error
|
||||
var st time.Time
|
||||
nodeNum, _ := strconv.Atoi(exhibitionConfig.Data.SnowFlake.NodeNum)
|
||||
st, err = time.Parse("2006-01-02", exhibitionConfig.Data.SnowFlake.StartTime)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
snowflake.Epoch = st.UnixNano() / 1000000
|
||||
node, errS := snowflake.NewNode(int64(nodeNum))
|
||||
if errS != nil {
|
||||
panic(errS)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func GenIDInt64() int64 {
|
||||
return app.ModuleClients.SfNode.Generate().Int64()
|
||||
}
|
||||
|
||||
func GetIDBase64() string {
|
||||
return app.ModuleClients.SfNode.Generate().Base64()
|
||||
}
|
51
pkg/tracing/jaeger.go
Normal file
51
pkg/tracing/jaeger.go
Normal file
@ -0,0 +1,51 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
exhibitionConfig "exhibition-register/config"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/google/wire"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/uber/jaeger-client-go"
|
||||
jaegerConfig "github.com/uber/jaeger-client-go/config"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var Provider = wire.NewSet(NewTracing)
|
||||
|
||||
type JaegerProvider struct {
|
||||
Tracer opentracing.Tracer
|
||||
Closer io.Closer
|
||||
}
|
||||
|
||||
//var JaegerPoint *JaegerProvider
|
||||
|
||||
func NewTracing() (jaegerProvider *JaegerProvider) {
|
||||
if exhibitionConfig.Data.Jaeger.Open != "true" {
|
||||
return
|
||||
}
|
||||
jaegerProvider = &JaegerProvider{}
|
||||
cfg := jaegerConfig.Configuration{
|
||||
ServiceName: "exhibition-register",
|
||||
Sampler: &jaegerConfig.SamplerConfig{
|
||||
Type: jaeger.SamplerTypeRemote,
|
||||
Param: 1,
|
||||
},
|
||||
Reporter: &jaegerConfig.ReporterConfig{
|
||||
LocalAgentHostPort: exhibitionConfig.Data.Jaeger.Addr,
|
||||
LogSpans: true,
|
||||
BufferFlushInterval: 5 * time.Second,
|
||||
},
|
||||
}
|
||||
nativeTracerIo, closerIo, err := cfg.NewTracer(jaegerConfig.Logger(jaeger.StdLogger))
|
||||
if err != nil {
|
||||
zap.L().Error("nativeTracer err", zap.Error(err))
|
||||
return
|
||||
}
|
||||
opentracing.SetGlobalTracer(nativeTracerIo)
|
||||
jaegerProvider.Tracer = nativeTracerIo
|
||||
jaegerProvider.Closer = closerIo
|
||||
//JaegerPoint = jaegerProvider
|
||||
return
|
||||
}
|
75
pkg/utils/http.go
Normal file
75
pkg/utils/http.go
Normal file
@ -0,0 +1,75 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func Post(url string, jsonStr []byte) (statusCode int, result string) {
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
statusCode = resp.StatusCode
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println("post url:", url)
|
||||
fmt.Println("response Headers:", resp.Header)
|
||||
fmt.Println("response Body:", string(body))
|
||||
result = string(body)
|
||||
zap.L().Info("post", zap.Any("url", url), zap.Any("jsonStr", jsonStr), zap.Any("result", result))
|
||||
return
|
||||
}
|
||||
|
||||
func Get(url string) (statusCode int, result string) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
statusCode = resp.StatusCode
|
||||
fmt.Println("response StatusCode:", resp.StatusCode)
|
||||
fmt.Println("response Status:", resp.Status)
|
||||
fmt.Println("response Headers:", resp.Header)
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
result = string(body)
|
||||
fmt.Println("response Body:", string(body))
|
||||
zap.L().Info("Get", zap.Any("url", url), zap.Any("result", result))
|
||||
return
|
||||
}
|
||||
|
||||
func PutFromFileUrlWithStream(url, fileName, fileUrl string) (statusCode int, result string) {
|
||||
file, err := http.Get(fileUrl)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Body.Close()
|
||||
fileBody, _ := ioutil.ReadAll(file.Body)
|
||||
|
||||
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(fileBody))
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
req.Header.Set("x-oss-meta-rawfilename", fileName)
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
//panic(err)
|
||||
return 400, "执行文件上传失败"
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
statusCode = resp.StatusCode
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
result = string(body)
|
||||
fmt.Println("put url:", url)
|
||||
fmt.Println("fileName :", fileName)
|
||||
fmt.Println("response Headers:", resp.Header)
|
||||
//fmt.Println("response Body:", string(body))
|
||||
fmt.Println("response StatusCode:", statusCode)
|
||||
//zap.L().Info("post", zap.Any("url", url), zap.Any("jsonStr", bytes.NewBuffer(fileBody).String()), zap.Any("result", result))
|
||||
return
|
||||
}
|
11
pkg/utils/msg.go
Normal file
11
pkg/utils/msg.go
Normal file
@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
import "strings"
|
||||
import "errors"
|
||||
|
||||
func SubstrError(err error) (sErr error) {
|
||||
start := strings.Index(err.Error(), ":")
|
||||
msg := err.Error()[start+2:]
|
||||
sErr = errors.New(msg)
|
||||
return
|
||||
}
|
50
pkg/utils/time.go
Normal file
50
pkg/utils/time.go
Normal file
@ -0,0 +1,50 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"exhibition-register/pkg/msg"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
DateTimeFormat = "2006-01-02 15:04:05"
|
||||
DateFormat = "2006-01-02"
|
||||
DateFormatYmdHisDot = "2006.01.02 15:04"
|
||||
DateFormatMonth = "2006年01月02日 15:04"
|
||||
)
|
||||
|
||||
func DatetimeToTimes(datetime string, dateFormat string) (times int32, err error) {
|
||||
if datetime == "" {
|
||||
times = 0
|
||||
return
|
||||
}
|
||||
loc, _ := time.LoadLocation("Asia/Shanghai")
|
||||
t, err := time.ParseInLocation(dateFormat, datetime, loc)
|
||||
if err != nil {
|
||||
zap.L().Error("DatetimeToTimes err:"+datetime+":", zap.Error(err))
|
||||
err = errors.New(msg.ErrorDatetime)
|
||||
return
|
||||
}
|
||||
times = int32(t.Unix())
|
||||
return
|
||||
}
|
||||
|
||||
func TimesToDatetime(times int32, format string) string {
|
||||
if times == 0 {
|
||||
return ""
|
||||
}
|
||||
t := time.Unix(int64(times), 0)
|
||||
if format == "" {
|
||||
format = DateTimeFormat
|
||||
}
|
||||
return t.Format(format)
|
||||
}
|
||||
|
||||
func MonthInfo() (startTime int64, endTime int64) {
|
||||
timeNow := time.Now()
|
||||
timeToday := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 0, 0, 0, 0, timeNow.Location()) // 获取当天0点时间 time类型
|
||||
startTime = timeToday.AddDate(0, 0, -timeToday.Day()+1).Unix() // 获取本月第一天0点 时间戳类型
|
||||
endTime = timeToday.AddDate(0, 1, -timeToday.Day()+1).Unix()
|
||||
return
|
||||
}
|
8
pkg/utils/uuid.go
Normal file
8
pkg/utils/uuid.go
Normal file
@ -0,0 +1,8 @@
|
||||
package utils
|
||||
|
||||
import "github.com/nacos-group/nacos-sdk-go/inner/uuid"
|
||||
|
||||
func GetUUID() string {
|
||||
id, _ := uuid.NewV4()
|
||||
return id.String()
|
||||
}
|
Loading…
Reference in New Issue
Block a user