From 57a0d8ae819c0c6a4fcd62245b4bc0166d63319c Mon Sep 17 00:00:00 2001 From: zhaoxiaorong Date: Fri, 7 Feb 2025 13:01:38 +0800 Subject: [PATCH] init --- cache/mem/mem.go | 14 + cache/redis/redis.go | 64 +++ conf/new.go | 92 ++++ conf/types.go | 62 +++ crypto/aes/aes.go | 104 ++++ crypto/rsa/rsa.go | 104 ++++ database/elastic/elasticsearch.go | 220 ++++++++ database/gorm-cache/README.MD | 97 ++++ database/gorm-cache/cache.go | 200 +++++++ database/gorm-cache/context.go | 88 +++ database/gorm-cache/example/go.sum | 11 + database/gorm-cache/example/main.go.demo | 92 ++++ database/gorm-cache/json.go | 23 + database/gorm-cache/store/redis/redis.go | 68 +++ database/kv/pebble.go | 66 +++ database/sql/ext.go | 30 ++ database/sql/postgresql.go | 54 ++ env/env.go | 13 + errcode/errcode.go | 85 +++ go.mod | 92 ++++ go.sum | 653 +++++++++++++++++++++++ mq/nats.go | 72 +++ print/print.go | 30 ++ queue/nats/nats.go | 65 +++ queue/pulsar/pulsar.go | 88 +++ types/db.go | 71 +++ types/encipher.go | 16 + types/env.go | 8 + types/mq.go | 8 + types/resp.go | 36 ++ utils/array.go | 38 ++ utils/convert.go | 106 ++++ utils/crypto.go | 25 + utils/dir.go | 35 ++ utils/ext.go | 35 ++ utils/file.go | 20 + utils/identity.go | 10 + utils/json.go | 13 + utils/net.go | 213 ++++++++ utils/random.go | 49 ++ utils/ticker.go | 39 ++ vars/build.go | 10 + vars/cache.go | 11 + vars/content.go | 12 + vars/elastic.go | 8 + vars/jwt.go | 8 + vars/queue.go | 9 + vars/service.go | 7 + vars/sql.go | 17 + vars/status.go | 8 + vars/ticker.go | 7 + vars/time.go | 7 + 52 files changed, 3313 insertions(+) create mode 100644 cache/mem/mem.go create mode 100644 cache/redis/redis.go create mode 100644 conf/new.go create mode 100644 conf/types.go create mode 100644 crypto/aes/aes.go create mode 100644 crypto/rsa/rsa.go create mode 100644 database/elastic/elasticsearch.go create mode 100644 database/gorm-cache/README.MD create mode 100644 database/gorm-cache/cache.go create mode 100644 database/gorm-cache/context.go create mode 100644 database/gorm-cache/example/go.sum create mode 100644 database/gorm-cache/example/main.go.demo create mode 100644 database/gorm-cache/json.go create mode 100644 database/gorm-cache/store/redis/redis.go create mode 100644 database/kv/pebble.go create mode 100644 database/sql/ext.go create mode 100644 database/sql/postgresql.go create mode 100644 env/env.go create mode 100644 errcode/errcode.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 mq/nats.go create mode 100644 print/print.go create mode 100644 queue/nats/nats.go create mode 100644 queue/pulsar/pulsar.go create mode 100644 types/db.go create mode 100644 types/encipher.go create mode 100644 types/env.go create mode 100644 types/mq.go create mode 100644 types/resp.go create mode 100644 utils/array.go create mode 100644 utils/convert.go create mode 100644 utils/crypto.go create mode 100644 utils/dir.go create mode 100644 utils/ext.go create mode 100644 utils/file.go create mode 100644 utils/identity.go create mode 100644 utils/json.go create mode 100644 utils/net.go create mode 100644 utils/random.go create mode 100644 utils/ticker.go create mode 100644 vars/build.go create mode 100644 vars/cache.go create mode 100644 vars/content.go create mode 100644 vars/elastic.go create mode 100644 vars/jwt.go create mode 100644 vars/queue.go create mode 100644 vars/service.go create mode 100644 vars/sql.go create mode 100644 vars/status.go create mode 100644 vars/ticker.go create mode 100644 vars/time.go diff --git a/cache/mem/mem.go b/cache/mem/mem.go new file mode 100644 index 0000000..0de3b98 --- /dev/null +++ b/cache/mem/mem.go @@ -0,0 +1,14 @@ +package mem + +import ( + "git.apinb.com/bsm-sdk/core/vars" + "github.com/FishGoddess/cachego" +) + +func New() cachego.Cache { + return cachego.NewCache( + cachego.WithGC(vars.MemGcDuration), + cachego.WithShardings(vars.MemShardings), + cachego.WithLFU(vars.MemLRUMaxNumber), + ) +} diff --git a/cache/redis/redis.go b/cache/redis/redis.go new file mode 100644 index 0000000..5dcdca2 --- /dev/null +++ b/cache/redis/redis.go @@ -0,0 +1,64 @@ +package redis + +import ( + "context" + "hash/fnv" + "net/url" + "strconv" + "strings" + + "git.apinb.com/bsm-sdk/core/vars" + cacheRedis "github.com/redis/go-redis/v9" +) + +const ( + Nil = cacheRedis.Nil +) + +// RedisClient . +type RedisClient struct { + DB int + Client *cacheRedis.Client + Ctx context.Context +} + +func New(dsn string, hashRadix string) *RedisClient { + arg, err := url.Parse(dsn) + if err != nil { + panic(err) + } + pwd, _ := arg.User.Password() + + //get db number,default:0 + var db int = 0 + arg.Path = strings.ReplaceAll(arg.Path, "/", "") + if arg.Path == "" { + db = Hash(hashRadix) + } else { + db, _ = strconv.Atoi(arg.Path) + } + + //connect redis server + client := cacheRedis.NewClient(&cacheRedis.Options{ + Addr: arg.Host, + Password: pwd, // no password set + DB: db, // use default DB + Protocol: 3, + }) + _, err = client.Ping(context.Background()).Result() + if err != nil { + panic(err) + } + + return &RedisClient{ + DB: db, + Client: client, + Ctx: context.Background(), + } +} + +func Hash(s string) int { + h := fnv.New32a() + h.Write([]byte(s)) + return int(h.Sum32()) % vars.RedisShardings +} diff --git a/conf/new.go b/conf/new.go new file mode 100644 index 0000000..ddd9279 --- /dev/null +++ b/conf/new.go @@ -0,0 +1,92 @@ +package conf + +import ( + "fmt" + "log" + "os" + "path/filepath" + "strings" + "time" + + "git.apinb.com/bsm-sdk/core/env" + "git.apinb.com/bsm-sdk/core/print" + "git.apinb.com/bsm-sdk/core/vars" + "golang.org/x/exp/rand" + yaml "gopkg.in/yaml.v3" +) + +func New(srvKey string, cfg any) *Runtime { + var run Runtime + // 设置服务键 + vars.ServiceKey = srvKey + + // 获取主机名 + vars.HostName, _ = os.Hostname() + + // 获取根目录路径,优先使用环境变量设置的路径,如果未设置则使用当前工作目录 + rootDir := strings.ToLower(env.GetEnvDefault("CORE_Path", "")) + if rootDir == "" { + rootDir, _ = os.Getwd() + } + + // 获取运行模式,如果环境变量未设置,则默认为"dev" + run.Mode = strings.ToLower(env.GetEnvDefault("CORE_Mode", "dev")) + + // 获取JWT密钥,用于身份验证 + run.JwtKey = strings.ToLower(env.GetEnvDefault("CORE_JwtKey", "")) + + // 获取许可证路径,如果环境变量未设置,则默认在根目录下的"etc"文件夹 + run.LicencePath = strings.ToLower(env.GetEnvDefault("CORE_LicencePath", "")) + if run.LicencePath == "" { + run.LicencePath = filepath.Join(rootDir, "etc") + } + + // 如果JWT密钥未设置,则记录错误并终止程序 + if run.JwtKey == "" { + log.Fatalf("ENV: CORE_JwtKey Not Nil !") + } + + // 构造配置文件路径,输出配置文件信息 + cfp := fmt.Sprintf("%s_%s.yaml", srvKey, run.Mode) + cfp = filepath.Join(rootDir, "etc", cfp) + print.Info("[CORE - %s] Config File: %s", srvKey, cfp) + + // 读取配置文件内容 + yamlFile, err := os.ReadFile(cfp) + if err != nil { + log.Fatalf("ERROR: %v", err) + } + + // 检查配置文件中是否存在Service和Addr字段 + if !strings.Contains(string(yamlFile), "Service:") { + log.Fatalln("ERROR: Service Not Nil", cfp) + } + + if !strings.Contains(string(yamlFile), "Port:") { + log.Fatalln("ERROR: Port Not Nil", cfp) + } + + // 解析YAML + err = yaml.Unmarshal(yamlFile, cfg) + if err != nil { + log.Fatalf("ERROR: %v", err) + } + + return &run +} + +func NotNil(values ...string) { + for _, value := range values { + if strings.TrimSpace(value) == "" { + log.Fatalln("ERROR:Must config not nil") + } + } +} + +func CheckPort(port int) int { + if port <= 0 || port >= 65535 { + rand.Seed(uint64(time.Now().UnixNano())) + return rand.Intn(65535-1024) + 1024 // 生成1024到65535之间的随机端口 + } + return port +} diff --git a/conf/types.go b/conf/types.go new file mode 100644 index 0000000..0c974f7 --- /dev/null +++ b/conf/types.go @@ -0,0 +1,62 @@ +package conf + +type Base struct { + Service string `yaml:"Service"` // 服务名称 + Port int `yaml:"Port"` // 服务监听端口,0为自动随机端口 + Cache string `yaml:"Cache"` // REDIS缓存 + OnMicroService bool `yaml:"OnMicroService"` // 是否启用微服务 + SecretKey string `yaml:"SecretKey"` // 服务秘钥 +} + +type DBConf struct { + Driver string `yaml:"Driver"` // 数据库驱动:mysql,sqlite,postgres,sqlserver,dm,kingbase + Source []string `yaml:"Source"` // 数据库连接 +} + +type ApmConf struct { + Name string // APM服务名称 + Platform string `yaml:"Platform"` // APM平台:apm,skywalking + Endpoint string `yaml:"Endpoint"` // APM服务接入地址 +} + +type EtcdConf struct { + Endpoints []string `yaml:"Endpoints"` // etcd服务接入地址 + Passwd *PasswdConf `yaml:"Passwd"` // etcd账号密码 + TLS *TlsConf `yaml:"TLS"` // tls 安全连接 +} + +type PasswdConf struct { + Account string `yaml:"Account"` // etcd账号 + Password string `yaml:"Password"` // etcd密码 +} + +type RpcConf struct { + Key string `yaml:"Key"` // 微服务名称 + Endpoint string `yaml:"Endpoint"` // 服务接入地址 + SecretKey string `yaml:"SecretKey"` // 秘钥 +} + +type OssConf struct { + Site string `yaml:"Site"` // oss站点HOST + Endpoint string `yaml:"Endpoint"` // oss服务接入地址 + Region string `yaml:"Region"` // oss服务区域 + AccessKeyID string `yaml:"AccessKeyId"` // oss AccessKeyId + AccessKeySecret string `yaml:"AccessKeySecret"` // oss AccessKeySecret +} + +type MqConf struct { + Endpoints []string `yaml:"Endpoints"` // MQ服务接入地址 + Space string `yaml:"Space"` // MQ服务空间 +} + +type Runtime struct { + Mode string // 运行模式:dev,test,prod + JwtKey string // JWT密钥 + LicencePath string // Licence文件路径 +} + +type TlsConf struct { + CaFile string // CA文件路径 + CertFile string // 证书文件路径 + KeyFile string // 密钥文件路径 +} diff --git a/crypto/aes/aes.go b/crypto/aes/aes.go new file mode 100644 index 0000000..4839fc3 --- /dev/null +++ b/crypto/aes/aes.go @@ -0,0 +1,104 @@ +package aes + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "encoding/base64" +) + +// AES加密 +func Encrypt(key string, iv string, data string) string { + if len(data) == 0 { + return "" + } + key2, _ := base64.StdEncoding.DecodeString(key) + iv2, _ := base64.StdEncoding.DecodeString(iv) + + block, _ := aes.NewCipher(key2) + bs := block.BlockSize() + originData := _PKCS5Padding([]byte(data), bs) + cipher.NewCBCEncrypter(block, iv2).CryptBlocks(originData, originData) + + data = base64.StdEncoding.EncodeToString(originData) + return data +} + +// AES解密 +func Decrypt(key string, iv string, data string) string { + if len(data) == 0 { + return "" + } + key2, _ := base64.StdEncoding.DecodeString(key) + iv2, _ := base64.StdEncoding.DecodeString(iv) + + block, _ := aes.NewCipher(key2) + originData, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return "" + } + cipher.NewCBCDecrypter(block, iv2).CryptBlocks(originData, originData) + + data = string(_PKCS5UnPadding(originData)) + return data +} + +func _PKCS5Padding(cipherText []byte, blockSize int) []byte { + padding := blockSize - len(cipherText)%blockSize + padText := bytes.Repeat([]byte{byte(padding)}, padding) + return append(cipherText, padText...) +} +func _PKCS5UnPadding(origData []byte) []byte { + length := len(origData) + unpadding := int(origData[length-1]) + if length-unpadding < 0 { + return origData + } + return origData[:(length - unpadding)] +} + +// =================== ECB ====================== +func AesEncryptECB(origData []byte, key []byte) (data string) { + cipher, _ := aes.NewCipher(generateKey(key)) + length := (len(origData) + aes.BlockSize) / aes.BlockSize + plain := make([]byte, length*aes.BlockSize) + copy(plain, origData) + pad := byte(len(plain) - len(origData)) + for i := len(origData); i < len(plain); i++ { + plain[i] = pad + } + encrypted := make([]byte, len(plain)) + // 分组分块加密 + for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { + cipher.Encrypt(encrypted[bs:be], plain[bs:be]) + } + + data = base64.StdEncoding.EncodeToString(encrypted) + return data +} +func AesDecryptECB(encrypted string, key []byte) (decrypted []byte) { + decodedCiphertext, _ := base64.StdEncoding.DecodeString(encrypted) + cipher, _ := aes.NewCipher(generateKey(key)) + decrypted = make([]byte, len(decodedCiphertext)) + // + for bs, be := 0, cipher.BlockSize(); bs < len(decodedCiphertext); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { + cipher.Decrypt(decrypted[bs:be], decodedCiphertext[bs:be]) + } + + trim := 0 + if len(decrypted) > 0 { + trim = len(decrypted) - int(decrypted[len(decrypted)-1]) + } + + return decrypted[:trim] +} +func generateKey(key []byte) (genKey []byte) { + genKey = make([]byte, 16) + copy(genKey, key) + for i := 16; i < len(key); { + for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 { + genKey[j] ^= key[i] + } + } + return genKey +} diff --git a/crypto/rsa/rsa.go b/crypto/rsa/rsa.go new file mode 100644 index 0000000..034bcef --- /dev/null +++ b/crypto/rsa/rsa.go @@ -0,0 +1,104 @@ +package rsa + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" +) + +// RSA生成公私密钥 +func RSAGenKey(bits int) (pub string, pri string, ok bool) { + if bits%1024 != 0 { + return + } + privateKey, err := rsa.GenerateKey(rand.Reader, bits) + if err != nil { + return + } + privateStream := x509.MarshalPKCS1PrivateKey(privateKey) + block1 := pem.Block{Type: "private key", Bytes: privateStream} + pri = string(pem.EncodeToMemory(&block1)) + publicKey := privateKey.PublicKey + publicStream, err := x509.MarshalPKIXPublicKey(&publicKey) + if err != nil { + return + } + block2 := pem.Block{Type: "public key", Bytes: publicStream} + pub = string(pem.EncodeToMemory(&block2)) + ok = true + return +} + +// RSA加密 +func Encrypt(pubkey, data string) string { + block, _ := pem.Decode([]byte(pubkey)) + if block == nil { + return "" + } + pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return "" + } + pub := pubInterface.(*rsa.PublicKey) + res, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(data)) + if err != nil { + return "" + } + return base64.StdEncoding.EncodeToString(res) +} +func EncryptWithPublicKey(publicKeyPEM string, plaintext string) (string, error) { + // 解码PEM格式的公钥 + // block, _ := pem.Decode([]byte(publicKeyPEM)) + // if block == nil { + // return "", nil + // } + pubKey := []byte(publicKeyPEM) + // 解析公钥 + pub, err := x509.ParsePKIXPublicKey(pubKey) + if err != nil { + return "", err + } + rsaPub, ok := pub.(*rsa.PublicKey) + if !ok { + return "", errors.New("not a valid RSA public key") + } + // 将字符串转换为字节数组 + message := []byte(plaintext) + // 使用OAEP填充和SHA-256哈希函数进行加密 + label := []byte("") // OAEP label, 可以根据需要设置 + hash := sha256.New() + ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, rsaPub, message, label) + if err != nil { + return "", err + } + // 将密文编码为base64字符串 + return base64.StdEncoding.EncodeToString(ciphertext), nil +} + +// RSA解密 +func Decrypt(prikey, data string) string { + if len(data) < 4 { + return "" + } + ciphertext, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return "" + } + block, _ := pem.Decode([]byte(prikey)) + if block == nil { + return "" + } + priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return "" + } + text, err := rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext) + if err != nil { + return "" + } + return string(text) +} diff --git a/database/elastic/elasticsearch.go b/database/elastic/elasticsearch.go new file mode 100644 index 0000000..00c0296 --- /dev/null +++ b/database/elastic/elasticsearch.go @@ -0,0 +1,220 @@ +package elastic + +import ( + "bytes" + "context" + "encoding/json" + "log" + "sync/atomic" + "time" + + "git.apinb.com/bsm-sdk/core/vars" + "github.com/elastic/go-elasticsearch/v8" + "github.com/elastic/go-elasticsearch/v8/esapi" + "github.com/elastic/go-elasticsearch/v8/esutil" +) + +type ES struct { + Client *elasticsearch.Client +} + +func NewElastic(endpoints []string, username, password string) (*ES, error) { + + cfg := elasticsearch.Config{ + Addresses: endpoints, + Username: username, + Password: password, + } + var err error + client, err := elasticsearch.NewClient(cfg) + if err != nil { + return nil, err + } + + return &ES{ + Client: client, + }, nil +} + +// idx 为空,默认随机唯一字符串 +// +// doc := map[string]interface{}{ +// "title": "中国", +// "content": "中国早日统一台湾", +// "time": time.Now().Unix(), +// "date": time.Now(), +// } +func (es *ES) CreateDocument(index string, id string, doc *interface{}) { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(doc); err != nil { + log.Println("Elastic NewEncoder:", err) + } + // Set up the request object. + req := esapi.IndexRequest{ + Index: index, + DocumentID: id, + Body: &buf, + Refresh: "true", + } + + // Perform the request with the client. + res, err := req.Do(context.Background(), es.Client) + if err != nil { + log.Println("Elastic Error:", res.String()) + } + defer res.Body.Close() + + if res.IsError() { + log.Println("Elastic Error:", res.String()) + } +} + +// 批量写入文档。 +// Action field configures the operation to perform (index, create, delete, update) +// create 如果文档不存在就创建,但如果文档存在就返回错误 +// index 如果文档不存在就创建,如果文档存在就更新 +// update 更新一个文档,如果文档不存在就返回错误 +// delete 删除一个文档,如果要删除的文档id不存在,就返回错误 +func (es *ES) Batch(index string, documens []map[string]interface{}, action string) { + log.SetFlags(0) + + var ( + countSuccessful uint64 + + err error + ) + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // + // Create the BulkIndexer + // + // NOTE: For optimal performance, consider using a third-party JSON decoding package. + // See an example in the "benchmarks" folder. + // + bi, err := esutil.NewBulkIndexer(esutil.BulkIndexerConfig{ + Index: index, // The default index name + Client: es.Client, // The Elasticsearch client + NumWorkers: vars.ESNumWorkers, // The number of worker goroutines + FlushBytes: vars.ESFlushBytes, // The flush threshold in bytes + FlushInterval: 30 * time.Second, // The periodic flush interval + }) + if err != nil { + log.Fatalf("Error creating the indexer: %s", err) + } + + for _, doc := range documens { + id := doc["id"].(string) + // Prepare the data payload: encode article to JSON + data, err := json.Marshal(doc) + if err != nil { + log.Fatalf("Cannot encode documen %s: %s", id, err) + } + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // + // Add an item to the BulkIndexer + // + err = bi.Add( + context.Background(), + esutil.BulkIndexerItem{ + + Action: action, + + // DocumentID is the (optional) document ID + DocumentID: id, + + // Body is an `io.Reader` with the payload + Body: bytes.NewReader(data), + + // OnSuccess is called for each successful operation + OnSuccess: func(ctx context.Context, item esutil.BulkIndexerItem, res esutil.BulkIndexerResponseItem) { + atomic.AddUint64(&countSuccessful, 1) + }, + + // OnFailure is called for each failed operation + OnFailure: func(ctx context.Context, item esutil.BulkIndexerItem, res esutil.BulkIndexerResponseItem, err error) { + if err != nil { + log.Printf("ERROR: %s", err) + } else { + log.Printf("ERROR: %s: %s", res.Error.Type, res.Error.Reason) + } + }, + }, + ) + if err != nil { + log.Printf("Unexpected error: %s", err) + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + } + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Close the indexer + // + if err := bi.Close(context.Background()); err != nil { + log.Printf("Unexpected error: %s", err) + } + + stats := bi.Stats() + if stats.NumFailed > 0 { + log.Printf("Indexed [%d] documents with [%d] errors", stats.NumFlushed, stats.NumFailed) + } else { + log.Printf("Successfully indexed [%d] documents", stats.NumFlushed) + } +} + +func (es *ES) Search(index string, query map[string]interface{}) (res *esapi.Response, err error) { + var buf bytes.Buffer + if err = json.NewEncoder(&buf).Encode(query); err != nil { + return + } + // Perform the search request. + res, err = es.Client.Search( + es.Client.Search.WithContext(context.Background()), + es.Client.Search.WithIndex(index), + es.Client.Search.WithBody(&buf), + es.Client.Search.WithTrackTotalHits(true), + es.Client.Search.WithFrom(0), + es.Client.Search.WithSize(10), + es.Client.Search.WithSort("time:desc"), + es.Client.Search.WithPretty(), + ) + if err != nil { + return + } + defer res.Body.Close() + + return +} + +// 删除 index 根据 索引名 id +func (es *ES) Delete(index, idx string) (res *esapi.Response, err error) { + res, err = es.Client.Delete( + index, // Index name + idx, // Document ID + es.Client.Delete.WithRefresh("true"), + ) + if err != nil { + return + } + defer res.Body.Close() + + return +} + +func (es *ES) DeleteByQuery(index []string, query map[string]interface{}) (res *esapi.Response, err error) { + var buf bytes.Buffer + if err = json.NewEncoder(&buf).Encode(query); err != nil { + return + } + // Perform the search request. + res, err = es.Client.DeleteByQuery( + index, + &buf, + ) + if err != nil { + return + } + defer res.Body.Close() + + return +} diff --git a/database/gorm-cache/README.MD b/database/gorm-cache/README.MD new file mode 100644 index 0000000..9c7f3d1 --- /dev/null +++ b/database/gorm-cache/README.MD @@ -0,0 +1,97 @@ +fork from https://github.com/liyuan1125/gorm-cache + +```go +package main + +import ( + "context" + "fmt" + "github.com/go-redis/redis/v8" + "github.com/liyuan1125/gorm-cache" + redis2 "github.com/liyuan1125/gorm-cache/store/redis" + "gorm.io/driver/mysql" + "gorm.io/gorm" + "os" + "time" +) + +var ( + db *gorm.DB + + redisClient *redis.Client + + cachePlugin *cache.Cache +) + +func newDb() { + dsn := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" + var err error + + db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) + if err != nil { + fmt.Println(err.Error()) + return + } + + redisClient = redis.NewClient(&redis.Options{Addr: ":6379"}) + + cacheConfig := &cache.Config{ + Store: redis2.NewWithDb(redisClient), // OR redis2.New(&redis.Options{Addr:"6379"}) + Serializer: &cache.DefaultJSONSerializer{}, + } + + cachePlugin = cache.New(cacheConfig) + + if err = db.Use(cachePlugin); err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } +} + +func basic() { + var username string + ctx := context.Background() + ctx = cache.NewExpiration(ctx, time.Hour) + + db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("username", &username) + fmt.Println(username) + // output gorm +} + +func customKey() { + var nickname string + ctx := context.Background() + ctx = cache.NewExpiration(ctx, time.Hour) + ctx = cache.NewKey(ctx, "nickname") + + db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("nickname", &nickname) + + fmt.Println(nickname) + // output gormwithmysql +} + +func useTag() { + var nickname string + ctx := context.Background() + ctx = cache.NewExpiration(ctx, time.Hour) + ctx = cache.NewTag(ctx, "users") + + db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("nickname", &nickname) + + fmt.Println(nickname) + // output gormwithmysql +} + +func main() { + newDb() + basic() + customKey() + useTag() + + ctx := context.Background() + fmt.Println(redisClient.Keys(ctx, "*").Val()) + + fmt.Println(cachePlugin.RemoveFromTag(ctx, "users")) +} + +``` \ No newline at end of file diff --git a/database/gorm-cache/cache.go b/database/gorm-cache/cache.go new file mode 100644 index 0000000..a8ce48a --- /dev/null +++ b/database/gorm-cache/cache.go @@ -0,0 +1,200 @@ +package cache + +import ( + "context" + "hash/fnv" + "os" + "strconv" + "time" + + "gorm.io/gorm" + "gorm.io/gorm/callbacks" +) + +type Config struct { + Store Store + + Prefix string + + Serializer Serializer +} + +type ( + Serializer interface { + Serialize(v any) ([]byte, error) + + Deserialize(data []byte, v any) error + } + + Store interface { + // Set 写入缓存数据 + Set(ctx context.Context, key string, value any, ttl time.Duration) error + + // Get 获取缓存数据 + Get(ctx context.Context, key string) ([]byte, error) + + // SaveTagKey 将缓存key写入tag + SaveTagKey(ctx context.Context, tag, key string) error + + // RemoveFromTag 根据缓存tag删除缓存 + RemoveFromTag(ctx context.Context, tag string) error + } +) + +type Cache struct { + store Store + + // Serializer 序列化 + Serializer Serializer + + // prefix 缓存前缀 + prefix string +} + +// New +// @param conf +// @date 2022-07-02 08:09:52 +func New(conf *Config) *Cache { + if conf.Store == nil { + os.Exit(1) + } + + if conf.Serializer == nil { + conf.Serializer = &DefaultJSONSerializer{} + } + + return &Cache{ + store: conf.Store, + prefix: conf.Prefix, + Serializer: conf.Serializer, + } +} + +// Name +// @date 2022-07-02 08:09:48 +func (p *Cache) Name() string { + return "gorm:cache" +} + +// Initialize +// @param tx +// @date 2022-07-02 08:09:47 +func (p *Cache) Initialize(tx *gorm.DB) error { + return tx.Callback().Query().Replace("gorm:query", p.Query) +} + +// generateKey +// @param key +// @date 2022-07-02 08:09:46 +func generateKey(key string) string { + hash := fnv.New64a() + _, _ = hash.Write([]byte(key)) + + return strconv.FormatUint(hash.Sum64(), 36) +} + +// Query +// @param tx +// @date 2022-07-02 08:09:38 +func (p *Cache) Query(tx *gorm.DB) { + ctx := tx.Statement.Context + + var ttl time.Duration + var hasTTL bool + + if ttl, hasTTL = FromExpiration(ctx); !hasTTL { + callbacks.Query(tx) + return + } + + var ( + key string + hasKey bool + ) + + // 调用 Gorm的方法生产SQL + callbacks.BuildQuerySQL(tx) + + // 是否有自定义key + if key, hasKey = FromKey(ctx); !hasKey { + key = p.prefix + generateKey(tx.Statement.SQL.String()) + } + + // 查询缓存数据 + + if err := p.QueryCache(ctx, key, tx.Statement.Dest); err == nil { + return + } + + // 查询数据库 + p.QueryDB(tx) + if tx.Error != nil { + return + } + + // 写入缓存 + if err := p.SaveCache(ctx, key, tx.Statement.Dest, ttl); err != nil { + tx.Logger.Error(ctx, err.Error()) + return + } + + if tag, hasTag := FromTag(ctx); hasTag { + _ = p.store.SaveTagKey(ctx, tag, key) + } +} + +// QueryDB 查询数据库数据 +// 这里重写Query方法 是不想执行 callbacks.BuildQuerySQL 两遍 +func (p *Cache) QueryDB(tx *gorm.DB) { + if tx.Error != nil || tx.DryRun { + return + } + + rows, err := tx.Statement.ConnPool.QueryContext(tx.Statement.Context, tx.Statement.SQL.String(), tx.Statement.Vars...) + if err != nil { + _ = tx.AddError(err) + return + } + + defer func() { + _ = tx.AddError(rows.Close()) + }() + + gorm.Scan(rows, tx, 0) +} + +// QueryCache 查询缓存数据 +// @param ctx +// @param key +// @param dest +func (p *Cache) QueryCache(ctx context.Context, key string, dest any) error { + + values, err := p.store.Get(ctx, key) + if err != nil { + return err + } + + switch dest.(type) { + case *int64: + dest = 0 + } + return p.Serializer.Deserialize(values, dest) +} + +// SaveCache 写入缓存数据 +func (p *Cache) SaveCache(ctx context.Context, key string, dest any, ttl time.Duration) error { + values, err := p.Serializer.Serialize(dest) + if err != nil { + return err + } + + return p.store.Set(ctx, key, values, ttl) +} + +// RemoveFromTag 根据tag删除缓存数据 +// @param ctx +// @param tag +// @date 2022-07-02 08:08:59 +func (p *Cache) RemoveFromTag(ctx context.Context, tag string) error { + return p.store.RemoveFromTag(ctx, tag) +} diff --git a/database/gorm-cache/context.go b/database/gorm-cache/context.go new file mode 100644 index 0000000..87d8ee4 --- /dev/null +++ b/database/gorm-cache/context.go @@ -0,0 +1,88 @@ +package cache + +import ( + "context" + "time" +) + +type ( + // queryCacheCtx + queryCacheCtx struct{} + + // queryCacheKeyCtx + queryCacheKeyCtx struct{} + + // queryCacheTagCtx + queryCacheTagCtx struct{} +) + +// NewKey +// @param ctx +// @param key +// @date 2022-07-02 08:11:44 +func NewKey(ctx context.Context, key string) context.Context { + return context.WithValue(ctx, queryCacheKeyCtx{}, key) +} + +// NewTag +// @param ctx +// @param key +// @date 2022-07-02 08:11:43 +func NewTag(ctx context.Context, key string) context.Context { + return context.WithValue(ctx, queryCacheTagCtx{}, key) +} + +// NewExpiration +// @param ctx +// @param ttl +// @date 2022-07-02 08:11:41 +func NewExpiration(ctx context.Context, ttl time.Duration) context.Context { + return context.WithValue(ctx, queryCacheCtx{}, ttl) +} + +// FromExpiration +// @param ctx +// @date 2022-07-02 08:11:40 +func FromExpiration(ctx context.Context) (time.Duration, bool) { + value := ctx.Value(queryCacheCtx{}) + + if value != nil { + if t, ok := value.(time.Duration); ok { + return t, true + } + } + + return 0, false +} + +// FromKey +// @param ctx +// @date 2022-07-02 08:11:39 +func FromKey(ctx context.Context) (string, bool) { + value := ctx.Value(queryCacheKeyCtx{}) + + if value != nil { + if t, ok := value.(string); ok { + return t, true + } + + } + + return "", false +} + +// FromTag +// @param ctx +// @date 2022-07-02 08:11:37 +func FromTag(ctx context.Context) (string, bool) { + value := ctx.Value(queryCacheTagCtx{}) + + if value != nil { + if t, ok := value.(string); ok { + return t, true + } + + } + + return "", false +} diff --git a/database/gorm-cache/example/go.sum b/database/gorm-cache/example/go.sum new file mode 100644 index 0000000..1e68e30 --- /dev/null +++ b/database/gorm-cache/example/go.sum @@ -0,0 +1,11 @@ +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +gorm.io/driver/mysql v1.3.4 h1:/KoBMgsUHC3bExsekDcmNYaBnfH2WNeFuXqqrqMc98Q= +gorm.io/driver/mysql v1.3.4/go.mod h1:s4Tq0KmD0yhPGHbZEwg1VPlH0vT/GBHJZorPzhcxBUE= +gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.6 h1:KFLdNgri4ExFFGTRGGFWON2P1ZN28+9SJRN8voOoYe0= +gorm.io/gorm v1.23.6/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= diff --git a/database/gorm-cache/example/main.go.demo b/database/gorm-cache/example/main.go.demo new file mode 100644 index 0000000..10bac45 --- /dev/null +++ b/database/gorm-cache/example/main.go.demo @@ -0,0 +1,92 @@ +package main + +import ( + "context" + "fmt" + "github.com/go-redis/redis/v8" + "github.com/liyuan1125/gorm-cache" + redis2 "github.com/liyuan1125/gorm-cache/store/redis" + "gorm.io/driver/mysql" + "gorm.io/gorm" + "os" + "time" +) + +var ( + db *gorm.DB + + redisClient *redis.Client + + cachePlugin *cache.Cache +) + +func newDb() { + dsn := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local" + var err error + + db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) + if err != nil { + fmt.Println(err.Error()) + return + } + + redisClient = redis.NewClient(&redis.Options{Addr: ":6379"}) + + cacheConfig := &cache.Config{ + Store: redis2.NewWithDb(redisClient), // OR redis2.New(&redis.Options{Addr:"6379"}) + Serializer: &cache.DefaultJSONSerializer{}, + } + + cachePlugin = cache.New(cacheConfig) + + if err = db.Use(cachePlugin); err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } +} + +func basic() { + var username string + ctx := context.Background() + ctx = cache.NewExpiration(ctx, time.Hour) + + db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("username", &username) + fmt.Println(username) + // output gorm +} + +func customKey() { + var nickname string + ctx := context.Background() + ctx = cache.NewExpiration(ctx, time.Hour) + ctx = cache.NewKey(ctx, "nickname") + + db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("nickname", &nickname) + + fmt.Println(nickname) + // output gormwithmysql +} + +func useTag() { + var nickname string + ctx := context.Background() + ctx = cache.NewExpiration(ctx, time.Hour) + ctx = cache.NewTag(ctx, "users") + + db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("nickname", &nickname) + + fmt.Println(nickname) + // output gormwithmysql +} + +func main() { + newDb() + basic() + customKey() + useTag() + + ctx := context.Background() + fmt.Println(redisClient.Keys(ctx, "*").Val()) + + fmt.Println(cachePlugin.RemoveFromTag(ctx, "users")) +} diff --git a/database/gorm-cache/json.go b/database/gorm-cache/json.go new file mode 100644 index 0000000..ebdfaf4 --- /dev/null +++ b/database/gorm-cache/json.go @@ -0,0 +1,23 @@ +package cache + +import ( + "encoding/json" +) + +type DefaultJSONSerializer struct{} + +// Serialize +// @param v +// @date 2022-07-02 08:12:26 +func (d *DefaultJSONSerializer) Serialize(v any) ([]byte, error) { + return json.Marshal(v) +} + +// Deserialize +// @param data +// @param v +// @date 2022-07-02 08:12:25 +func (d *DefaultJSONSerializer) Deserialize(data []byte, v any) error { + + return json.Unmarshal(data, v) +} diff --git a/database/gorm-cache/store/redis/redis.go b/database/gorm-cache/store/redis/redis.go new file mode 100644 index 0000000..1e80bc0 --- /dev/null +++ b/database/gorm-cache/store/redis/redis.go @@ -0,0 +1,68 @@ +package redis + +import ( + "context" + "time" + + "github.com/redis/go-redis/v9" +) + +type Store struct { + store *redis.Client +} + +// New +// @param conf +// @date 2022-07-02 08:12:14 +func New(conf *redis.Options) *Store { + cli := redis.NewClient(conf) + + return &Store{store: cli} +} + +// NewWithDb +// @param tx +// @date 2022-07-02 08:12:12 +func NewWithDb(tx *redis.Client) *Store { + return &Store{store: tx} +} + +// Set +// @param ctx +// @param key +// @param value +// @param ttl +// @date 2022-07-02 08:12:11 +func (r *Store) Set(ctx context.Context, key string, value any, ttl time.Duration) error { + return r.store.Set(ctx, key, value, ttl).Err() +} + +// Get +// @param ctx +// @param key +// @date 2022-07-02 08:12:09 +func (r *Store) Get(ctx context.Context, key string) ([]byte, error) { + return r.store.Get(ctx, key).Bytes() +} + +// RemoveFromTag +// @param ctx +// @param tag +// @date 2022-07-02 08:12:08 +func (r *Store) RemoveFromTag(ctx context.Context, tag string) error { + keys, err := r.store.SMembers(ctx, tag).Result() + if err != nil { + return err + } + + return r.store.Del(ctx, keys...).Err() +} + +// SaveTagKey +// @param ctx +// @param tag +// @param key +// @date 2022-07-02 08:12:05 +func (r *Store) SaveTagKey(ctx context.Context, tag, key string) error { + return r.store.SAdd(ctx, tag, key).Err() +} diff --git a/database/kv/pebble.go b/database/kv/pebble.go new file mode 100644 index 0000000..e17d16b --- /dev/null +++ b/database/kv/pebble.go @@ -0,0 +1,66 @@ +package kv + +import ( + "github.com/cockroachdb/pebble" +) + +var Impl *KvImpl + +type KvImpl struct { + PebbleDB *pebble.DB +} + +func NewPebble(datadir string) *KvImpl { + db, err := pebble.Open(datadir, &pebble.Options{}) + if err != nil { + panic(err) + } + return &KvImpl{ + PebbleDB: db, + } +} + +func (db *KvImpl) PebbleSet(key, val string) error { + return db.PebbleDB.Set([]byte(key), []byte(val), pebble.Sync) +} + +func (db *KvImpl) PebbleGet(key string) ([]byte, error) { + value, _, err := db.PebbleDB.Get([]byte(key)) + if err != nil { + return nil, err + } + + return value, nil +} + +func (db *KvImpl) PebbleFetch(prefixKey string) (result map[string]string, err error) { + keyUpperBound := func(b []byte) []byte { + end := make([]byte, len(b)) + copy(end, b) + for i := len(end) - 1; i >= 0; i-- { + end[i] = end[i] + 1 + if end[i] != 0 { + return end[:i+1] + } + } + return nil // no upper-bound + } + + prefixIterOptions := func(prefix []byte) *pebble.IterOptions { + return &pebble.IterOptions{ + LowerBound: prefix, + UpperBound: keyUpperBound(prefix), + } + } + + iter, err := db.PebbleDB.NewIter(prefixIterOptions([]byte(prefixKey))) + + if err != nil { + return nil, err + } + + for iter.First(); iter.Valid(); iter.Next() { + result[string(iter.Key())] = string(iter.Value()) + } + return +} diff --git a/database/sql/ext.go b/database/sql/ext.go new file mode 100644 index 0000000..4ee3acd --- /dev/null +++ b/database/sql/ext.go @@ -0,0 +1,30 @@ +package sql + +import "strings" + +// key,value To like sql +func Like(key, val string) string { + if val == "" { + return "" + } + key = strings.TrimSpace(key) + val = strings.TrimSpace(val) + return key + " LIKE '%" + val + "%'" +} + +// map strings to like sqls +func Likes(in map[string]string) string { + var ar []string + for key, val := range in { + sql := Like(key, val) + if sql != "" { + ar = append(ar, sql) + } + } + + if len(ar) == 0 { + return "" + } + + return strings.Join(ar, " AND ") +} diff --git a/database/sql/postgresql.go b/database/sql/postgresql.go new file mode 100644 index 0000000..6d2ec41 --- /dev/null +++ b/database/sql/postgresql.go @@ -0,0 +1,54 @@ +package sql + +import ( + "git.apinb.com/bsm-sdk/core/types" + "git.apinb.com/bsm-sdk/core/vars" + "gorm.io/driver/postgres" + "gorm.io/gorm" + "gorm.io/gorm/schema" +) + +// new grom db. +func NewPostgreSql(dsn string, options *types.SqlOptions) (*gorm.DB, error) { + var err error + + //set connection default val. + if options == nil { + options = &types.SqlOptions{ + MaxIdleConns: vars.SqlOptionMaxIdleConns, + MaxOpenConns: vars.SqlOptionMaxIdleConns, + ConnMaxLifetime: vars.SqlOptionConnMaxLifetime, + LogStdout: false, + Debug: true, + } + } + + gormDb, err := gorm.Open(postgres.New(postgres.Config{ + DSN: dsn, + // PreferSimpleProtocol: true, disables implicit prepared statement usage + + }), &gorm.Config{ + //Logger:newLogger, + DisableForeignKeyConstraintWhenMigrating: true, + NamingStrategy: schema.NamingStrategy{ + SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user` + }}) + if err != nil { + return nil, err + } + + if options.Debug { + gormDb = gormDb.Debug() + } + + // 获取通用数据库对象 sql.DB ,然后使用其提供的功能 + sqlDB, _ := gormDb.DB() + // SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。 + sqlDB.SetMaxIdleConns(options.MaxIdleConns) + // SetMaxOpenConns 设置打开数据库连接的最大数量。 + sqlDB.SetMaxOpenConns(options.MaxOpenConns) + // SetConnMaxLifetime 设置了连接可复用的最大时间。 + sqlDB.SetConnMaxLifetime(options.ConnMaxLifetime) + + return gormDb, nil +} diff --git a/env/env.go b/env/env.go new file mode 100644 index 0000000..e64c949 --- /dev/null +++ b/env/env.go @@ -0,0 +1,13 @@ +package env + +import ( + "os" +) + +func GetEnvDefault(key string, def string) string { + value := os.Getenv(key) + if value == "" { + return def + } + return value +} diff --git a/errcode/errcode.go b/errcode/errcode.go new file mode 100644 index 0000000..052f9d0 --- /dev/null +++ b/errcode/errcode.go @@ -0,0 +1,85 @@ +package errcode + +import ( + "github.com/gofiber/fiber/v2" +) + +// header error code ,start:100 +var ( + ErrHeaderRequestId = NewError(101, "Header Request-Id Not Found") + ErrHeaderAuthorization = NewError(102, "Header Authorization Not Found") + ErrHeaderSecretKey = NewError(103, "Header Secret-Key Not Found") +) + +// standard error code ,start:110 +var ( + ErrRequestParse = NewError(111, "Request Parse Fail") + ErrRequestMust = NewError(112, "Request Params Required") + ErrPermission = NewError(113, "Permission Denied") + ErrJsonUnmarshal = NewError(114, "Json Unmarshal Fail") + ErrJsonMarshal = NewError(115, "Json Marshal Fail") + ErrInternal = NewError(116, "Internal Server Error") +) + +// jwt error code ,start:130 +var ( + ErrJWTAuthNotFound = NewError(131, "JWT Authorization Not Found") + ErrJWTBase64Decode = NewError(132, "JWT Authorization Base64 Decode Error") + ErrJWTAuthParseFail = NewError(133, "JWT Authorization Fail") + ErrJWTAuthKeyId = NewError(134, "JWT Key:Id Incorrect") + ErrJWTAuthKeyIdentity = NewError(135, "JWT Key:Identity Incorrect") + ErrJWTAuthTokenChanged = NewError(136, "JWT Authorization Changed") + ErrJWTAuthExpire = NewError(137, "JWT Authorization Expire") + ErrJWTJsonDecode = NewError(138, "JWT Authorization JSON Decode Error") + ErrJWTJsonEncode = NewError(139, "JWT Authorization JSON Encode Error") +) + +// model error code ,start:150 +var ( + ErrDB = NewError(151, "DB Fatal Error") + ErrRedis = NewError(152, "Redis Fatal Error") + ErrMq = NewError(153, "MQ Fatal Error") + ErrOss = NewError(154, "OSS Fatal Error") + ErrRpc = NewError(155, "RPC Fatal Error") + ErrApm = NewError(156, "APM Fatal Error") + ErrEtcd = NewError(157, "Etcd Fatal Error") +) + +// google grpc error status. +var ( + OK = NewError(171, "OK") + ErrCanceled = NewError(172, "Canceled") + ErrUnknown = NewError(173, "Unknown") + ErrInvalidArgument = NewError(174, "Invalid Argument") + ErrDeadlineExceeded = NewError(175, "Deadline Exceeded") + ErrAlreadyExists = NewError(176, "Already Exists") + ErrPermissionDenied = NewError(177, "Permission Denied") + ErrResourceExhausted = NewError(178, "Resource Exhausted") + ErrFailedPrecondition = NewError(179, "Failed Precondition") + ErrAborted = NewError(181, "Aborted") + ErrOutOfRange = NewError(182, "Out Of Range") + ErrUnimplemented = NewError(183, "Unimplemented") + ErrUnavailable = NewError(184, "Unavailable") + ErrDataLoss = NewError(185, "Data Loss") + ErrUnauthenticated = NewError(186, "Unauthenticated") + ErrJSONMarshal = NewError(187, "Marshal JSON") + ErrJSONUnmarshal = NewError(188, "Unmarshal JSON") + ErrPasswd = NewError(189, "Password Error") + + ErrSmsCode = NewError(191, "SMS Code Invalid") + ErrIdArgument = NewError(192, "ID Invalid Argument") + ErrIdentityArgument = NewError(193, "Identity Invalid Argument") +) + +func NewError(code int, msg string) error { + return fiber.NewError(code, msg) +} + +// custom error,status code:500 +func ErrFatal(msg string) error { + return fiber.NewError(500, msg) +} + +func ErrNotFound(msg string) error { + return fiber.NewError(404, msg+" Not Found") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e138e89 --- /dev/null +++ b/go.mod @@ -0,0 +1,92 @@ +module git.apinb.com/bsm-sdk/core + +go 1.23.6 + +require ( + github.com/FishGoddess/cachego v0.6.1 + github.com/cockroachdb/pebble v1.1.4 + github.com/elastic/go-elasticsearch/v8 v8.17.0 + github.com/gofiber/fiber/v2 v2.52.6 + github.com/gofiber/jwt/v4 v4.0.0 + github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/nats-io/nats.go v1.39.0 + github.com/oklog/ulid/v2 v2.1.0 + github.com/redis/go-redis/v9 v9.7.0 + github.com/shirou/gopsutil v3.21.11+incompatible + go.etcd.io/etcd/client/v3 v3.5.18 + golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 + gopkg.in/yaml.v3 v3.0.1 + gorm.io/driver/postgres v1.5.11 + gorm.io/gorm v1.25.12 +) + +require ( + github.com/DataDog/zstd v1.4.5 // indirect + github.com/MicahParks/keyfunc/v2 v2.0.3 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/nats-io/nkeys v0.4.9 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.12.0 // indirect + github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/tklauser/go-sysconf v0.3.14 // indirect + github.com/tklauser/numcpus v0.8.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.etcd.io/etcd/api/v3 v3.5.18 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.18 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.17.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ac8c521 --- /dev/null +++ b/go.sum @@ -0,0 +1,653 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/FishGoddess/cachego v0.6.1 h1:mbytec3loqw5dcO177LyRGyStKG0AngP5g2GR3SzSh0= +github.com/FishGoddess/cachego v0.6.1/go.mod h1:VLSMwWRlRPazjGYer8pq+4aDrIe1Otj3Yy9HAb0eo3c= +github.com/MicahParks/keyfunc/v2 v2.0.3 h1:uKUEOc+knRO0UoucONisgNPiT85V2s/W5c0FQYsd9kc= +github.com/MicahParks/keyfunc/v2 v2.0.3/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.4 h1:5II1uEP4MyHLDnsrbv/EZ36arcb9Mxg3n+owhZ3GrG8= +github.com/cockroachdb/pebble v1.1.4/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= +github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.17.0 h1:e9cWksE/Fr7urDRmGPGp47Nsp4/mvNOrU8As1l2HQQ0= +github.com/elastic/go-elasticsearch/v8 v8.17.0/go.mod h1:lGMlgKIbYoRvay3xWBeKahAiJOgmFDsjZC39nmO3H64= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI= +github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= +github.com/gofiber/jwt/v4 v4.0.0 h1:XlZ4H1omUZxX0AIE/esDBMNGiyI0kfaaHVAj8+7izAk= +github.com/gofiber/jwt/v4 v4.0.0/go.mod h1:vcEMSaWmPyP06Emfy5aBtqss8+t6gYkdX0pGytzdNbM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/nats.go v1.39.0 h1:2/yg2JQjiYYKLwDuBzV0FbB2sIV+eFNkEevlRi4n9lI= +github.com/nats-io/nats.go v1.39.0/go.mod h1:MgRb8oOdigA6cYpEPhXJuRVH6UE/V4jblJ2jQ27IXYM= +github.com/nats-io/nkeys v0.4.9 h1:qe9Faq2Gxwi6RZnZMXfmGMZkg3afLLOtrU+gDZJ35b0= +github.com/nats-io/nkeys v0.4.9/go.mod h1:jcMqs+FLG+W5YO36OX6wFIFcmpdAns+w1Wm6D3I/evE= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= +github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= +github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= +github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= +github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.etcd.io/etcd/api/v3 v3.5.18 h1:Q4oDAKnmwqTo5lafvB+afbgCDF7E35E4EYV2g+FNGhs= +go.etcd.io/etcd/api/v3 v3.5.18/go.mod h1:uY03Ob2H50077J7Qq0DeehjM/A9S8PhVfbQ1mSaMopU= +go.etcd.io/etcd/client/pkg/v3 v3.5.18 h1:mZPOYw4h8rTk7TeJ5+3udUkfVGBqc+GCjOJYd68QgNM= +go.etcd.io/etcd/client/pkg/v3 v3.5.18/go.mod h1:BxVf2o5wXG9ZJV+/Cu7QNUiJYk4A29sAhoI5tIRsCu4= +go.etcd.io/etcd/client/v3 v3.5.18 h1:nvvYmNHGumkDjZhTHgVU36A9pykGa2K4lAJ0yY7hcXA= +go.etcd.io/etcd/client/v3 v3.5.18/go.mod h1:kmemwOsPU9broExyhYsBxX4spCTDX3yLgPMWtpBXG6E= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 h1:qNgPs5exUA+G0C96DrPwNrvLSj7GT/9D+3WMWUcUg34= +golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314= +gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= +gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/mq/nats.go b/mq/nats.go new file mode 100644 index 0000000..f0f6f59 --- /dev/null +++ b/mq/nats.go @@ -0,0 +1,72 @@ +package nats + +import ( + "errors" + "strings" + + "git.apinb.com/bsm-sdk/core/vars" + natsgo "github.com/nats-io/nats.go" +) + +type Nats struct { + Client natsgo.JetStreamContext +} + +func NewNats(endpoints []string, space string) (*Nats, error) { + if len(endpoints) == 0 { + return nil, errors.New("endpoints is empty") + } + if space == "" { + space = vars.MQSpaceName + } + jetStream, err := NatsNew(endpoints, space) + if err != nil { + return nil, err + } + + return &Nats{ + Client: jetStream, + }, nil +} + +func NatsNew(endpoints []string, space string) (natsgo.JetStreamContext, error) { + var serverUrl string + if len(endpoints) > 1 { + serverUrl = strings.Join(endpoints, ",") + } else { + serverUrl = endpoints[0] + } + + conn, err := natsgo.Connect(serverUrl, natsgo.DontRandomize()) + if err != nil { + return nil, err + } + defer conn.Close() + + js, err := conn.JetStream(natsgo.PublishAsyncMaxPending(256)) + if err != nil { + return nil, err + } + + js.AddStream(&natsgo.StreamConfig{ + Name: space, + Subjects: []string{space}, //jetstream不支持通配符 + Retention: natsgo.WorkQueuePolicy, + MaxBytes: 8, + }) + + return js, nil +} + +func (mq *Nats) Subscribe(topic string, do func([]byte)) (err error) { + _, err = mq.Client.Subscribe(topic, func(m *natsgo.Msg) { + do(m.Data) + m.Ack() + }) + return +} + +func (mq *Nats) Producer(topic string, data []byte) (err error) { + _, err = mq.Client.Publish(topic, data) + return +} diff --git a/print/print.go b/print/print.go new file mode 100644 index 0000000..6a413e4 --- /dev/null +++ b/print/print.go @@ -0,0 +1,30 @@ +package print + +import ( + "fmt" + "log" +) + +// record INFO message. Color White +func Info(format string, a ...interface{}) { + message := fmt.Sprintf("\033[37m[Info] "+format+"\033[0m\n", a...) + log.Print(message) +} + +// record Warn message. Color Orange +func Warn(format string, a ...interface{}) { + message := fmt.Sprintf("\033[33m[Warn] "+format+"\033[0m\n", a...) + log.Print(message) +} + +// record Success message. Color Green +func Success(format string, a ...interface{}) { + message := fmt.Sprintf("\033[32m[Success] "+format+"\033[0m\n", a...) + log.Print(message) +} + +// record ERROR message. Color Red +func Error(format string, a ...interface{}) { + message := fmt.Sprintf("\033[31m[Error] "+format+"\033[0m\n", a...) + log.Print(message) +} diff --git a/queue/nats/nats.go b/queue/nats/nats.go new file mode 100644 index 0000000..71b9140 --- /dev/null +++ b/queue/nats/nats.go @@ -0,0 +1,65 @@ +package nats + +import ( + "strings" + + "git.apinb.com/bsm-sdk/engine/vars" + natsgo "github.com/nats-io/nats.go" +) + +type Nats struct { + Client natsgo.JetStreamContext +} + +func NewNats(endpoints []string) (*Nats, error) { + jetStream, err := NatsNew(endpoints) + if err != nil { + return nil, err + } + + return &Nats{ + Client: jetStream, + }, nil +} + +func NatsNew(endpoints []string) (natsgo.JetStreamContext, error) { + var serverUrl string + if len(endpoints) > 1 { + serverUrl = strings.Join(endpoints, ",") + } else { + serverUrl = endpoints[0] + } + + conn, err := natsgo.Connect(serverUrl, natsgo.DontRandomize()) + if err != nil { + return nil, err + } + defer conn.Close() + + js, err := conn.JetStream(natsgo.PublishAsyncMaxPending(256)) + if err != nil { + return nil, err + } + + js.AddStream(&natsgo.StreamConfig{ + Name: vars.MQSpaceName, + Subjects: []string{vars.MQSpaceName}, //jetstream不支持通配符 + Retention: natsgo.WorkQueuePolicy, + MaxBytes: 8, + }) + + return js, nil +} + +func (mq *Nats) Subscribe(topic string, do func([]byte)) (err error) { + _, err = mq.Client.Subscribe(topic, func(m *natsgo.Msg) { + do(m.Data) + m.Ack() + }) + return +} + +func (mq *Nats) Producer(topic string, data []byte) (err error) { + _, err = mq.Client.Publish(topic, data) + return +} diff --git a/queue/pulsar/pulsar.go b/queue/pulsar/pulsar.go new file mode 100644 index 0000000..ea1ef59 --- /dev/null +++ b/queue/pulsar/pulsar.go @@ -0,0 +1,88 @@ +package pulsar + +import ( + "context" + "errors" + + "git.apinb.com/bsm-sdk/engine/types" + "git.apinb.com/bsm-sdk/engine/vars" + pulsargo "github.com/apache/pulsar-client-go/pulsar" +) + +type Pulsar struct { + Client pulsargo.Client +} + +func NewPulsar(cfg *types.PulsarConf) (*Pulsar, error) { + client, err := pulsargo.NewClient(pulsargo.ClientOptions{ + URL: cfg.Endpoints, //TODO: 更换为接入点地址(控制台集群管理页完整复制) + Authentication: pulsargo.NewAuthenticationToken(cfg.Token), + OperationTimeout: vars.OperationTimeout, + ConnectionTimeout: vars.ConnectionTimeout, + }) + if err != nil { + return nil, err + } + + return &Pulsar{ + Client: client, + }, nil +} + +// push to pulsar server, return messageid. +func (mq *Pulsar) Producer(topic, msg string) (MessageID string, err error) { + if msg == "" { + return "", errors.New("Message is nil.") + } + + producer, err := mq.Client.CreateProducer(pulsargo.ProducerOptions{ + Topic: topic, + CompressionType: pulsargo.ZSTD, + }) + + if err != nil { + return "", err + } + + msgID, err := producer.Send(context.Background(), &pulsargo.ProducerMessage{ + Payload: []byte(msg), + }) + + if err != nil { + return "", err + } + + return msgID.String(), nil +} + +func (mq *Pulsar) Subscribe(topic, subscription string, subType pulsargo.SubscriptionType, do func([]byte)) error { + // we can listen this channel + channel := make(chan pulsargo.ConsumerMessage, 100) + + options := pulsargo.ConsumerOptions{ + Topic: topic, + SubscriptionName: subscription, + Type: subType, + // fill `MessageChannel` field will create a listener + MessageChannel: channel, + } + + consumer, err := mq.Client.Subscribe(options) + if err != nil { + return err + } + + defer consumer.Close() + + // Receive messages from channel. The channel returns a struct `ConsumerMessage` which contains message and the consumer from where + // the message was received. It's not necessary here since we have 1 single consumer, but the channel could be + // shared across multiple consumers as well + for cm := range channel { + consumer := cm.Consumer + msg := cm.Message + + do(msg.Payload()) + consumer.Ack(msg) + } + return nil +} diff --git a/types/db.go b/types/db.go new file mode 100644 index 0000000..35b4370 --- /dev/null +++ b/types/db.go @@ -0,0 +1,71 @@ +package types + +import ( + "time" + + "gorm.io/gorm" +) + +type ( + + // sql options + SqlOptions struct { + MaxIdleConns int + MaxOpenConns int + ConnMaxLifetime time.Duration + + LogStdout bool + Debug bool + } + + // standard ID,Identity definition. + Std_IDIdentity struct { + ID uint `gorm:"primarykey;" json:"id"` + Identity string `gorm:"column:identity;type:varchar(36);uniqueIndex;" json:"identity"` // 唯一标识,24位NanoID,36位为ULID + } + + // standard ID,Created,Updated,Deleted definition. + Std_IICUDS struct { + ID uint `gorm:"primarykey;" json:"id"` + Identity string `gorm:"column:identity;type:varchar(36);uniqueIndex;" json:"identity"` // 唯一标识,24位NanoID,36位为ULID + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt gorm.DeletedAt `gorm:"index;" json:"deleted_at"` + Status int8 `gorm:"default:0;index;" json:"status"` // 状态:默认为0,-1禁止,1为正常 + } + + // standard ID,Identity,Created,Updated,Deleted,Status definition. + Std_ICUD struct { + ID uint `gorm:"primarykey;" json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt gorm.DeletedAt `gorm:"index;" json:"deleted_at"` + } + + // standard ID,Created definition. + Std_IdCreated struct { + ID uint `gorm:"primarykey;" json:"id"` + CreatedAt time.Time `json:"created_at"` + } + + // standard PassportID,PassportIdentity definition. + Std_Passport struct { + PassportID uint `gorm:"column:passport_id;Index;" json:"passport_id"` + PassportIdentity string `gorm:"column:passport_identity;type:varchar(36);Index;" json:"passport_identity"` // 用户唯一标识,24位NanoID,36位为ULID + } + + // standard ID definition. + Std_ID struct { + ID uint `gorm:"primarykey;" json:"id"` + } + + // standard Identity definition. + Std_Identity struct { + Identity string `gorm:"column:identity;type:varchar(36);uniqueIndex;" json:"identity"` // 唯一标识,24位NanoID,36位为ULID + } + + // standard Status definition. + Std_Status struct { + Status int8 `gorm:"default:0;index;" json:"status"` // 状态:默认为0,-1禁止,1为正常 + } +) diff --git a/types/encipher.go b/types/encipher.go new file mode 100644 index 0000000..620199b --- /dev/null +++ b/types/encipher.go @@ -0,0 +1,16 @@ +package types + +type CertFileBytes struct { + Private []byte + Public []byte +} + +type JwtClaims struct { + ID uint `json:"id"` + Identity string `json:"identity"` + Extend map[string]string `json:"extend"` + Client string `json:"client"` + Owner any `json:"owner"` + Role string `json:"role"` + ExpiresAt int64 `json:"exp"` +} diff --git a/types/env.go b/types/env.go new file mode 100644 index 0000000..a3a4751 --- /dev/null +++ b/types/env.go @@ -0,0 +1,8 @@ +package types + +const ( + Run_Time_Mode_Dev = iota + Run_Time_Mode_Test + Run_Time_Mode_Pre + Run_Time_Mode_Product +) diff --git a/types/mq.go b/types/mq.go new file mode 100644 index 0000000..ec9c169 --- /dev/null +++ b/types/mq.go @@ -0,0 +1,8 @@ +package types + +type Message struct { + Identity string + Action string + Args string + Payload string +} diff --git a/types/resp.go b/types/resp.go new file mode 100644 index 0000000..815f900 --- /dev/null +++ b/types/resp.go @@ -0,0 +1,36 @@ +package types + +type Empty struct { +} + +type Base struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data interface{} `json:"data"` +} + +type Paginate struct { + Offset int `form:"offset,default=0,range=[0:)"` + Size int `form:"size,default=10,range=[1:50]"` +} + +type ID struct { + ID uint `path:"id"` +} + +type Identity struct { + Identity string `path:"identity"` +} + +type GormModel struct { + ID uint `json:"id,optional"` + CreatedAt string `json:"created_at,optional"` + UpdatedAt string `json:"updated_at,optional"` + DeletedAt string `json:"deleted_at,optional"` +} + +type FetchRequest struct { + Params map[string]string `json:"params,optional"` + TimeRange string `json:"time_range,optional"` + Paginate +} diff --git a/utils/array.go b/utils/array.go new file mode 100644 index 0000000..4829351 --- /dev/null +++ b/utils/array.go @@ -0,0 +1,38 @@ +package utils + +import "strings" + +func In(target string, array []string) bool { + target = strings.Trim(target, "") + for _, v := range array { + if strings.Trim(v, "") == target { + return true + } + } + return false +} + +// 字符串数组是否存在 +func StrArrayIndex(items []string, item string) int { + for i, eachItem := range items { + if eachItem == item { + return i + } + } + return -1 +} + +func RemoveRepeatSlice(in []string) (out []string) { + _map := make(map[string]bool) + for i := 0; i < len(in); i++ { + if in[i] != "" { + _map[in[i]] = true + } + } + + for key, _ := range _map { + out = append(out, key) + } + + return out +} diff --git a/utils/convert.go b/utils/convert.go new file mode 100644 index 0000000..763673b --- /dev/null +++ b/utils/convert.go @@ -0,0 +1,106 @@ +package utils + +import ( + "math" + "strconv" + "strings" +) + +// 字符串转Int +// +// intStr:数字的字符串 +func String2Int(intStr string) (intNum int) { + intNum, _ = strconv.Atoi(intStr) + return +} + +// 字符串转Int64 +// +// intStr:数字的字符串 +func String2Int64(intStr string) (int64Num int64) { + intNum, _ := strconv.Atoi(intStr) + int64Num = int64(intNum) + return +} + +// 字符串转Float64 +// +// floatStr:小数点数字的字符串 +func String2Float64(floatStr string) (floatNum float64) { + floatNum, _ = strconv.ParseFloat(floatStr, 64) + return +} + +// 字符串转Float32 +// +// floatStr:小数点数字的字符串 +func String2Float32(floatStr string) (floatNum float32) { + floatNum64, _ := strconv.ParseFloat(floatStr, 32) + floatNum = float32(floatNum64) + return +} + +// Int转字符串 +// +// intNum:数字字符串 +func Int2String(intNum int) (intStr string) { + intStr = strconv.Itoa(intNum) + return +} + +// Int64转字符串 +// +// intNum:数字字符串 +func Int642String(intNum int64) (int64Str string) { + //10, 代表10进制 + int64Str = strconv.FormatInt(intNum, 10) + return +} + +// Float64转字符串 +// +// floatNum:float64数字 +// prec:精度位数(不传则默认float数字精度) +func Float64ToString(floatNum float64, prec ...int) (floatStr string) { + if len(prec) > 0 { + floatStr = strconv.FormatFloat(floatNum, 'f', prec[0], 64) + return + } + floatStr = strconv.FormatFloat(floatNum, 'f', -1, 64) + return +} + +// Float32转字符串 +// +// floatNum:float32数字 +// prec:精度位数(不传则默认float数字精度) +func Float32ToString(floatNum float32, prec ...int) (floatStr string) { + if len(prec) > 0 { + floatStr = strconv.FormatFloat(float64(floatNum), 'f', prec[0], 32) + return + } + floatStr = strconv.FormatFloat(float64(floatNum), 'f', -1, 32) + return +} + +// 二进制转10进制 +func BinaryToDecimal(bit string) (num int) { + fields := strings.Split(bit, "") + lens := len(fields) + var tempF float64 = 0 + for i := 0; i < lens; i++ { + floatNum := String2Float64(fields[i]) + tempF += floatNum * math.Pow(2, float64(lens-i-1)) + } + num = int(tempF) + return +} + +// interface to string +func AnyToString(in any) (s string) { + if in == nil { + return "" + } + + return in.(string) +} diff --git a/utils/crypto.go b/utils/crypto.go new file mode 100644 index 0000000..f30b766 --- /dev/null +++ b/utils/crypto.go @@ -0,0 +1,25 @@ +package utils + +import ( + "crypto/hmac" + "crypto/md5" + "crypto/sha256" + "encoding/hex" + "fmt" +) + +//Md5 . +func Md5(src string) string { + data := []byte(src) + has := md5.Sum(data) + md5str := fmt.Sprintf("%x", has) + return md5str +} + +func Sha256(src, privateKey string) string { + s := []byte(src) + key := []byte(privateKey) + m := hmac.New(sha256.New, key) + m.Write(s) + return hex.EncodeToString(m.Sum(nil)) +} diff --git a/utils/dir.go b/utils/dir.go new file mode 100644 index 0000000..cd96406 --- /dev/null +++ b/utils/dir.go @@ -0,0 +1,35 @@ +package utils + +import ( + "os" +) + +func PathExists(path string) bool { + _, err := os.Stat(path) + if err != nil { + if os.IsExist(err) { + return true + } + return false + } + return true +} + +// 创建文件夹 +func CreateDir(dirName string) bool { + err := os.Mkdir(dirName, 0755) + if err != nil { + return false + } + return true +} + +func GetRunPath() string { + path, _ := os.Executable() + return path +} + +func GetCurrentPath() string { + path, _ := os.Getwd() + return path +} diff --git a/utils/ext.go b/utils/ext.go new file mode 100644 index 0000000..72298cf --- /dev/null +++ b/utils/ext.go @@ -0,0 +1,35 @@ +package utils + +import ( + "strconv" + "strings" +) + +func If(condition bool, trueValue, falseValue interface{}) interface{} { + if condition { + return trueValue + } + return falseValue +} + +//如果首字母是小写字母, 则变换为大写字母 +func FirstToUpper(str string) string { + if str == "" { + return "" + } + + return strings.ToUpper(str[:1]) + strings.ToLower(str[1:]) +} + +func ParseParams(in map[string]string) map[string]interface{} { + out := make(map[string]interface{}) + for k, v := range in { + fv, err := strconv.ParseFloat(v, 64) + if err != nil { + out[k] = fv + } else { + out[k] = v + } + } + return out +} diff --git a/utils/file.go b/utils/file.go new file mode 100644 index 0000000..28926da --- /dev/null +++ b/utils/file.go @@ -0,0 +1,20 @@ +package utils + +import ( + "errors" + "io" + "os" +) + +func StringToFile(path, content string) error { + startF, err := os.Create(path) + if err != nil { + return errors.New("os.Create create file " + path + " error:" + err.Error()) + } + defer startF.Close() + _, err = io.WriteString(startF, content) + if err != nil { + return errors.New("io.WriteString to " + path + " error:" + err.Error()) + } + return nil +} diff --git a/utils/identity.go b/utils/identity.go new file mode 100644 index 0000000..4aa0a33 --- /dev/null +++ b/utils/identity.go @@ -0,0 +1,10 @@ +package utils + +import ( + ulid "github.com/oklog/ulid/v2" +) + +// remove nanoid,uuid,replace to ulid +func ULID() string { + return ulid.Make().String() +} diff --git a/utils/json.go b/utils/json.go new file mode 100644 index 0000000..b55cb3e --- /dev/null +++ b/utils/json.go @@ -0,0 +1,13 @@ +package utils + +import "strings" + +func JsonEscape(in string) string { + in = strings.ReplaceAll(in, "\n", "") + in = strings.ReplaceAll(in, "\t", "") + in = strings.ReplaceAll(in, "\r", "") + in = strings.ReplaceAll(in, "\r\n", "") + in = strings.ReplaceAll(in, "\\\"", "\"") + in = strings.ReplaceAll(in, "\\\\", "\\") + return in +} diff --git a/utils/net.go b/utils/net.go new file mode 100644 index 0000000..285d77d --- /dev/null +++ b/utils/net.go @@ -0,0 +1,213 @@ +package utils + +import ( + "bytes" + "errors" + "fmt" + "io" + "net" + "net/http" + "os" + "strconv" +) + +func IsPublicIP(ipString string) bool { + ip := net.ParseIP(ipString) + if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() { + return false + } + if ip4 := ip.To4(); ip4 != nil { + switch true { + case ip4[0] == 10: + return false + case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31: + return false + case ip4[0] == 192 && ip4[1] == 168: + return false + default: + return true + } + } + return false +} + +// Get Location IP . +func GetLocationIP() string { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "" + } + ip := "" + for _, a := range addrs { + if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + ip = ipnet.IP.String() + break + } + } + } + if ip == "" { + return "" + } + return ip +} + +func LocalIPv4s() ([]string, error) { + + var ips []string + addrs, _ := net.InterfaceAddrs() + + for _, addr := range addrs { + if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + locIP := ipnet.IP.To4().String() + if locIP[0:7] != "169.254" { + ips = append(ips, locIP) + } + } + } + } + + return ips, nil +} + +func GetOutBoundIP() (ip string, err error) { + body, err := HttpGet("http://ip.dhcp.cn/?ip") // 获取外网 IP + return string(body), err +} + +func HttpGet(url string) ([]byte, error) { + resp, err := http.Get(url) + if err != nil { + // handle error + return nil, err + } + + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + + return body, err +} + +func HttpPost(url string, header map[string]string, data []byte) ([]byte, error) { + var err error + reader := bytes.NewBuffer(data) + request, err := http.NewRequest("POST", url, reader) + + if err != nil { + return nil, err + } + + request.Header.Set("Content-Type", "application/json;charset=UTF-8") + request.Header.Set("Request-Id", ULID()) + + for key, val := range header { + request.Header.Set(key, val) + } + + client := http.Client{} + resp, err := client.Do(request) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + respBytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + return nil, errors.New(string(respBytes)) + } + + return respBytes, nil +} + +func HttpRequest(r *http.Request) ([]byte, error) { + var err error + client := http.Client{} + resp, err := client.Do(r) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + respBytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return respBytes, nil +} + +func DownloadFile(url, saveTo string, fb func(length, downLen int64)) { + var ( + fsize int64 + buf = make([]byte, 32*1024) + written int64 + ) + //创建一个http client + client := new(http.Client) + //get方法获取资源 + resp, err := client.Get(url) + if err != nil { + fmt.Printf("download %s error:%s\n", url, err) + os.Exit(0) + } + //读取服务器返回的文件大小 + fsize, err = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 32) + if err != nil { + fmt.Println(err) + } + //创建文件 + file, err := os.Create(saveTo) + file.Chmod(0777) + if err != nil { + fmt.Printf("Create %s error:%s\n", saveTo, err) + os.Exit(0) + } + defer file.Close() + if resp.Body == nil { + fmt.Printf("resp %s error:%s\n", url, err) + os.Exit(0) + } + defer resp.Body.Close() + //下面是 io.copyBuffer() 的简化版本 + for { + //读取bytes + nr, er := resp.Body.Read(buf) + if nr > 0 { + //写入bytes + nw, ew := file.Write(buf[0:nr]) + //数据长度大于0 + if nw > 0 { + written += int64(nw) + } + //写入出错 + if ew != nil { + err = ew + break + } + //读取是数据长度不等于写入的数据长度 + if nr != nw { + err = io.ErrShortWrite + break + } + } + if er != nil { + if er != io.EOF { + err = er + } + break + } + //没有错误了快使用 callback + + fb(fsize, written) + } + + if err != nil { + fmt.Printf("callback error:%s\n", err) + os.Exit(0) + } +} diff --git a/utils/random.go b/utils/random.go new file mode 100644 index 0000000..176bb2b --- /dev/null +++ b/utils/random.go @@ -0,0 +1,49 @@ +package utils + +import ( + "math/rand/v2" +) + +// 随机生成字符串 +func RandomString(l int) string { + str := "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" + bytes := []byte(str) + var result []byte = make([]byte, 0, l) + for i := 0; i < l; i++ { + result = append(result, bytes[rand.IntN(len(bytes))]) + } + return string(result) +} + +// 随机生成纯字符串 +func RandomPureString(l int) string { + str := "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" + bytes := []byte(str) + var result []byte = make([]byte, 0, l) + for i := 0; i < l; i++ { + result = append(result, bytes[rand.IntN(len(bytes))]) + } + return string(result) +} + +// 随机生成纯大写字符串 +func RandomPureUpString(l int) string { + str := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + bytes := []byte(str) + var result []byte = make([]byte, 0, l) + for i := 0; i < l; i++ { + result = append(result, bytes[rand.IntN(len(bytes))]) + } + return string(result) +} + +// 随机生成数字字符串 +func RandomNumber(l int) string { + str := "0123456789" + bytes := []byte(str) + var result []byte + for i := 0; i < l; i++ { + result = append(result, bytes[rand.IntN(len(bytes))]) + } + return string(result) +} diff --git a/utils/ticker.go b/utils/ticker.go new file mode 100644 index 0000000..e623669 --- /dev/null +++ b/utils/ticker.go @@ -0,0 +1,39 @@ +package utils + +import ( + "context" + "time" +) + +func SetTimeout(f func(), timeout int) context.CancelFunc { + ctx, cancelFunc := context.WithCancel(context.Background()) + go func() { + select { + case <-ctx.Done(): + case <-time.After(time.Duration(timeout) * time.Second): + f() + } + }() + return cancelFunc +} + +func SetInterval(what func(), delay time.Duration) chan bool { + ticker := time.NewTicker(delay) + stopIt := make(chan bool) + go func() { + + for { + + select { + case <-stopIt: + return + case <-ticker.C: + what() + } + } + + }() + + // return the bool channel to use it as a stopper + return stopIt +} diff --git a/vars/build.go b/vars/build.go new file mode 100644 index 0000000..d008e6b --- /dev/null +++ b/vars/build.go @@ -0,0 +1,10 @@ +package vars + +// build ldflags -x +var ( + VERSION string = "0.0" + BUILD_TIME string = "2006-01-02 15:04:05" //time.Now().Format("2006-01-02 15:04:05") + GO_VERSION string = "unset" // runtime.GOOS + "/" + runtime.GOARCH + " " + runtime.Version() + ServiceKey string = "unset" + HostName string = "unset" +) diff --git a/vars/cache.go b/vars/cache.go new file mode 100644 index 0000000..2efae41 --- /dev/null +++ b/vars/cache.go @@ -0,0 +1,11 @@ +package vars + +import "time" + +var ( + // cache def value + MemGcDuration time.Duration = 10 * time.Minute + MemLRUMaxNumber int = 1024 + MemShardings int = 64 + RedisShardings int = 256 +) diff --git a/vars/content.go b/vars/content.go new file mode 100644 index 0000000..cfed91e --- /dev/null +++ b/vars/content.go @@ -0,0 +1,12 @@ +package vars + +type ContentType int32 + +const ( + CONTENT_TYPE_TEXT ContentType = iota + 1 // 1.文本 + CONTENT_TYPE_IMAGE // 2.图片 + CONTENT_TYPE_VIDEO // 3.视频 + CONTENT_TYPE_AUDIO // 4.音频 + CONTENT_TYPE_LINK // 5.连接 + CONTENT_TYPE_LOCATION // 6.定位 +) diff --git a/vars/elastic.go b/vars/elastic.go new file mode 100644 index 0000000..b43d074 --- /dev/null +++ b/vars/elastic.go @@ -0,0 +1,8 @@ +package vars + +import "runtime" + +var ( + ESNumWorkers int = runtime.NumCPU() + ESFlushBytes int = 5e+6 +) diff --git a/vars/jwt.go b/vars/jwt.go new file mode 100644 index 0000000..800e9e9 --- /dev/null +++ b/vars/jwt.go @@ -0,0 +1,8 @@ +package vars + +import "time" + +var ( + // cache def value + JwtExpireDay time.Duration = 1 * 24 * time.Hour +) diff --git a/vars/queue.go b/vars/queue.go new file mode 100644 index 0000000..eed824d --- /dev/null +++ b/vars/queue.go @@ -0,0 +1,9 @@ +package vars + +import "time" + +var ( + MQSpaceName = "Traingo" + OperationTimeout time.Duration = 30 * time.Second + ConnectionTimeout time.Duration = 30 * time.Second +) diff --git a/vars/service.go b/vars/service.go new file mode 100644 index 0000000..da0004c --- /dev/null +++ b/vars/service.go @@ -0,0 +1,7 @@ +package vars + +var ( + RUN_MODE_DEV = "dev" + RUN_MODE_TEST = "test" + RUN_MODE_PROD = "prod" +) diff --git a/vars/sql.go b/vars/sql.go new file mode 100644 index 0000000..3fa0bb6 --- /dev/null +++ b/vars/sql.go @@ -0,0 +1,17 @@ +package vars + +import "time" + +var ( + // sql options def val + SqlOptionMaxIdleConns int = 64 + SqlOptionMaxOpenConns int = 64 + SqlOptionConnMaxLifetime time.Duration = 60 * time.Second + SqlOptionLogStdout bool = true + SqlOptionDebug bool = true + + // sql log def val + SqlLogStdout bool = true + SqlLogDir = "logs" + SqlLogFileExt = "log" +) diff --git a/vars/status.go b/vars/status.go new file mode 100644 index 0000000..3e54a1c --- /dev/null +++ b/vars/status.go @@ -0,0 +1,8 @@ +package vars + +const ( + // NormalStatus . + NormalStatus = 1 + // DisabledStatus . + DisabledStatus = -1 +) diff --git a/vars/ticker.go b/vars/ticker.go new file mode 100644 index 0000000..2e67bc6 --- /dev/null +++ b/vars/ticker.go @@ -0,0 +1,7 @@ +package vars + +import "time" + +var ( + ServiceRuntimeDuration time.Duration = 1 * time.Minute +) diff --git a/vars/time.go b/vars/time.go new file mode 100644 index 0000000..bc6ca73 --- /dev/null +++ b/vars/time.go @@ -0,0 +1,7 @@ +package vars + +var ( + YYYYMMDD string = "20060102" + YYYY_MM_DD string = "2006-01-02" + YYYY_MM_DD_HH_MM_SS string = "2006-01-02 15:04:05" +)