Compare commits
No commits in common. "main" and "feature/errv2" have entirely different histories.
main
...
feature/er
2
Makefile
2
Makefile
|
@ -9,4 +9,4 @@ test: # 進行測試
|
|||
fmt: # 格式優化
|
||||
$(GOFMT) -w $(GOFILES)
|
||||
goimports -w ./
|
||||
golangci-lint run
|
||||
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package code
|
||||
|
||||
const (
|
||||
OK uint32 = 0
|
||||
)
|
||||
|
||||
// Scope
|
||||
const (
|
||||
Unset uint32 = iota
|
||||
CloudEPPortalGW
|
||||
CloudEPMember
|
||||
CloudEPPermission
|
||||
)
|
||||
|
||||
// Category for general operations: 100 - 4900
|
||||
const (
|
||||
_ = iota
|
||||
CatInput uint32 = iota * 100
|
||||
CatDB
|
||||
CatResource
|
||||
CatGRPC
|
||||
CatAuth
|
||||
CatSystem
|
||||
CatPubSub
|
||||
)
|
||||
|
||||
// CatArk Category for specific app/service: 5000 - 9900
|
||||
const (
|
||||
CatArk uint32 = (iota + 50) * 100
|
||||
)
|
||||
|
||||
// Detail - Input 1xx
|
||||
const (
|
||||
_ = iota + CatInput
|
||||
InvalidFormat
|
||||
NotValidImplementation
|
||||
InvalidRange
|
||||
)
|
||||
|
||||
// Detail - Database 2xx
|
||||
const (
|
||||
_ = iota + CatDB
|
||||
DBError // general error
|
||||
DBDataConvert
|
||||
DBDuplicate
|
||||
)
|
||||
|
||||
// Detail - Resource 3xx
|
||||
const (
|
||||
_ = iota + CatResource
|
||||
ResourceNotFound
|
||||
InvalidResourceFormat
|
||||
ResourceAlreadyExist
|
||||
ResourceInsufficient
|
||||
InsufficientPermission
|
||||
InvalidMeasurementID
|
||||
ResourceExpired
|
||||
ResourceMigrated
|
||||
InvalidResourceState
|
||||
InsufficientQuota
|
||||
ResourceHasMultiOwner
|
||||
)
|
||||
|
||||
/* Detail - GRPC */
|
||||
// The GRPC detail code uses Go GRPC's built-in codes.
|
||||
// Refer to "google.golang.org/grpc/codes" for more detail.
|
||||
|
||||
// Detail - Auth 5xx
|
||||
const (
|
||||
_ = iota + CatAuth
|
||||
Unauthorized
|
||||
AuthExpired
|
||||
InvalidPosixTime
|
||||
SigAndPayloadNotMatched
|
||||
Forbidden
|
||||
)
|
||||
|
||||
// Detail - System 6xx
|
||||
const (
|
||||
_ = iota + CatSystem
|
||||
SystemInternalError
|
||||
SystemMaintainError
|
||||
SystemTimeoutError
|
||||
)
|
||||
|
||||
// Detail - PubSub 7xx
|
||||
const (
|
||||
_ = iota + CatPubSub
|
||||
Publish
|
||||
Consume
|
||||
MsgSizeTooLarge
|
||||
)
|
||||
|
||||
// Detail - Ark 5xxx
|
||||
const (
|
||||
_ = iota + CatArk
|
||||
ArkInternal
|
||||
ArkHTTP400
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
package code
|
||||
|
||||
// CatToStr collects general error messages for each Category
|
||||
// It is used to send back to API caller
|
||||
var CatToStr = map[uint32]string{
|
||||
CatInput: "Invalid Input Data",
|
||||
CatDB: "Database Error",
|
||||
CatResource: "Resource Error",
|
||||
CatGRPC: "Internal Service Communication Error",
|
||||
CatAuth: "Authentication Error",
|
||||
CatArk: "Internal Service Communication Error",
|
||||
CatSystem: "System Error",
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.30cm.net/digimon/library-go/errors/code"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func newErr(scope, detail uint32, msg string) *LibError {
|
||||
cat := detail / 100 * 100
|
||||
|
||||
return &LibError{
|
||||
category: cat,
|
||||
code: detail,
|
||||
scope: scope,
|
||||
msg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
func newBuiltinGRPCErr(scope, detail uint32, msg string) *LibError {
|
||||
return &LibError{
|
||||
category: code.CatGRPC,
|
||||
code: detail,
|
||||
scope: scope,
|
||||
msg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// FromError tries to let error as Err
|
||||
// it supports to unwrap error that has Err
|
||||
// return nil if failed to transfer
|
||||
func FromError(err error) *LibError {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var e *LibError
|
||||
if errors.As(err, &e) {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromCode parses code as following
|
||||
// Decimal: 120314
|
||||
// 12 represents Scope
|
||||
// 03 represents Category
|
||||
// 14 represents Detail error code
|
||||
func FromCode(code uint32) *LibError {
|
||||
scope := code / 10000
|
||||
detail := code % 10000
|
||||
|
||||
return &LibError{
|
||||
category: detail / 100 * 100,
|
||||
code: detail,
|
||||
scope: scope,
|
||||
msg: "",
|
||||
}
|
||||
}
|
||||
|
||||
// FromGRPCError transfer error to Err
|
||||
// useful for gRPC client
|
||||
func FromGRPCError(err error) *LibError {
|
||||
s, _ := status.FromError(err)
|
||||
e := FromCode(uint32(s.Code()))
|
||||
e.msg = s.Message()
|
||||
|
||||
// For GRPC built-in code
|
||||
if e.Scope() == code.Unset && e.Category() == 0 && e.Code() != code.OK {
|
||||
e = newBuiltinGRPCErr(Scope, e.Code(), s.Message())
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// Deprecated: check GRPCStatus() in Errs struct
|
||||
// ToGRPCError returns the status.Status
|
||||
// Useful to return error in gRPC server
|
||||
func ToGRPCError(e *LibError) error {
|
||||
return status.New(codes.Code(e.FullCode()), e.Error()).Err()
|
||||
}
|
||||
|
||||
/*** System ***/
|
||||
|
||||
// SystemTimeoutError returns Err
|
||||
func SystemTimeoutError(s ...string) *LibError {
|
||||
return newErr(Scope, code.SystemTimeoutError, fmt.Sprintf("system timeout: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// SystemTimeoutErrorL logs error message and returns Err
|
||||
func SystemTimeoutErrorL(l logx.Logger, s ...string) *LibError {
|
||||
e := SystemTimeoutError(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// SystemInternalError returns Err struct
|
||||
func SystemInternalError(s ...string) *LibError {
|
||||
return newErr(Scope, code.SystemInternalError, fmt.Sprintf("internal error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// SystemInternalErrorL logs error message and returns Err
|
||||
func SystemInternalErrorL(l logx.Logger, s ...string) *LibError {
|
||||
e := SystemInternalError(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// SystemMaintainErrorL logs error message and returns Err
|
||||
func SystemMaintainErrorL(l logx.Logger, s ...string) *LibError {
|
||||
e := SystemMaintainError(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// SystemMaintainError returns Err struct
|
||||
func SystemMaintainError(s ...string) *LibError {
|
||||
return newErr(Scope, code.SystemMaintainError, fmt.Sprintf("service under maintenance: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
/*** CatInput ***/
|
||||
|
||||
// InvalidFormat returns Err struct
|
||||
func InvalidFormat(s ...string) *LibError {
|
||||
return newErr(Scope, code.InvalidFormat, fmt.Sprintf("invalid format: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InvalidFormatL logs error message and returns Err
|
||||
func InvalidFormatL(l logx.Logger, s ...string) *LibError {
|
||||
e := InvalidFormat(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InvalidRange returns Err struct
|
||||
func InvalidRange(s ...string) *LibError {
|
||||
return newErr(Scope, code.InvalidRange, fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InvalidRangeL logs error message and returns Err
|
||||
func InvalidRangeL(l logx.Logger, s ...string) *LibError {
|
||||
e := InvalidRange(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// NotValidImplementation returns Err struct
|
||||
func NotValidImplementation(s ...string) *LibError {
|
||||
return newErr(Scope, code.NotValidImplementation, fmt.Sprintf("not valid implementation: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// NotValidImplementationL logs error message and returns Err
|
||||
func NotValidImplementationL(l logx.Logger, s ...string) *LibError {
|
||||
e := NotValidImplementation(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
/*** CatDB ***/
|
||||
|
||||
// DBError returns Err
|
||||
func DBError(s ...string) *LibError {
|
||||
return newErr(Scope, code.DBError, fmt.Sprintf("db error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// DBErrorL logs error message and returns Err
|
||||
func DBErrorL(l logx.Logger, s ...string) *LibError {
|
||||
e := DBError(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// DBDataConvert returns Err
|
||||
func DBDataConvert(s ...string) *LibError {
|
||||
return newErr(Scope, code.DBDataConvert, fmt.Sprintf("data from db convert error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// DBDataConvertL logs error message and returns Err
|
||||
func DBDataConvertL(l logx.Logger, s ...string) *LibError {
|
||||
e := DBDataConvert(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// DBDuplicate returns Err
|
||||
func DBDuplicate(s ...string) *LibError {
|
||||
return newErr(Scope, code.DBDuplicate, fmt.Sprintf("data Duplicate key error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// DBDuplicateL logs error message and returns Err
|
||||
func DBDuplicateL(l logx.Logger, s ...string) *LibError {
|
||||
e := DBDuplicate(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
/*** CatResource ***/
|
||||
|
||||
// ResourceNotFound returns Err and logging
|
||||
func ResourceNotFound(s ...string) *LibError {
|
||||
return newErr(Scope, code.ResourceNotFound, fmt.Sprintf("resource not found: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// ResourceNotFoundL logs error message and returns Err
|
||||
func ResourceNotFoundL(l logx.Logger, s ...string) *LibError {
|
||||
e := ResourceNotFound(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InvalidResourceFormat returns Err
|
||||
func InvalidResourceFormat(s ...string) *LibError {
|
||||
return newErr(Scope, code.InvalidResourceFormat, fmt.Sprintf("invalid resource format: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InvalidResourceFormatL logs error message and returns Err
|
||||
func InvalidResourceFormatL(l logx.Logger, s ...string) *LibError {
|
||||
e := InvalidResourceFormat(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InvalidResourceState returns status not correct.
|
||||
// for example: company should be destroy, agent should be no-sensor/fail-install ...
|
||||
func InvalidResourceState(s ...string) *LibError {
|
||||
return newErr(Scope, code.InvalidResourceState, fmt.Sprintf("invalid resource state: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InvalidResourceStateL logs error message and returns status not correct.
|
||||
func InvalidResourceStateL(l logx.Logger, s ...string) *LibError {
|
||||
e := InvalidResourceState(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func ResourceInsufficient(s ...string) *LibError {
|
||||
return newErr(Scope, code.ResourceInsufficient,
|
||||
fmt.Sprintf("insufficient resource: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
func ResourceInsufficientL(l logx.Logger, s ...string) *LibError {
|
||||
e := ResourceInsufficient(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InsufficientPermission returns Err
|
||||
func InsufficientPermission(s ...string) *LibError {
|
||||
return newErr(Scope, code.InsufficientPermission,
|
||||
fmt.Sprintf("insufficient permission: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InsufficientPermissionL returns Err and log
|
||||
func InsufficientPermissionL(l logx.Logger, s ...string) *LibError {
|
||||
e := InsufficientPermission(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ResourceAlreadyExist returns Err
|
||||
func ResourceAlreadyExist(s ...string) *LibError {
|
||||
return newErr(Scope, code.ResourceAlreadyExist, fmt.Sprintf("resource already exist: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// ResourceAlreadyExistL logs error message and returns Err
|
||||
func ResourceAlreadyExistL(l logx.Logger, s ...string) *LibError {
|
||||
e := ResourceAlreadyExist(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InvalidMeasurementID returns Err
|
||||
func InvalidMeasurementID(s ...string) *LibError {
|
||||
return newErr(Scope, code.InvalidMeasurementID, fmt.Sprintf("missing measurement id: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InvalidMeasurementIDL logs error message and returns Err
|
||||
func InvalidMeasurementIDL(l logx.Logger, s ...string) *LibError {
|
||||
e := InvalidMeasurementID(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ResourceExpired returns Err
|
||||
func ResourceExpired(s ...string) *LibError {
|
||||
return newErr(Scope, code.ResourceExpired, fmt.Sprintf("resource expired: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// ResourceExpiredL logs error message and returns Err
|
||||
func ResourceExpiredL(l logx.Logger, s ...string) *LibError {
|
||||
e := ResourceExpired(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ResourceMigrated returns Err
|
||||
func ResourceMigrated(s ...string) *LibError {
|
||||
return newErr(Scope, code.ResourceMigrated, fmt.Sprintf("resource migrated: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// ResourceMigratedL logs error message and returns Err
|
||||
func ResourceMigratedL(l logx.Logger, s ...string) *LibError {
|
||||
e := ResourceMigrated(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InsufficientQuota returns Err
|
||||
func InsufficientQuota(s ...string) *LibError {
|
||||
return newErr(Scope, code.InsufficientQuota, fmt.Sprintf("insufficient quota: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InsufficientQuotaL logs error message and returns Err
|
||||
func InsufficientQuotaL(l logx.Logger, s ...string) *LibError {
|
||||
e := InsufficientQuota(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
/*** CatAuth ***/
|
||||
|
||||
// Unauthorized returns Err
|
||||
func Unauthorized(s ...string) *LibError {
|
||||
return newErr(Scope, code.Unauthorized, fmt.Sprintf("unauthorized: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// UnauthorizedL logs error message and returns Err
|
||||
func UnauthorizedL(l logx.Logger, s ...string) *LibError {
|
||||
e := Unauthorized(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// AuthExpired returns Err
|
||||
func AuthExpired(s ...string) *LibError {
|
||||
return newErr(Scope, code.AuthExpired, fmt.Sprintf("expired: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// AuthExpiredL logs error message and returns Err
|
||||
func AuthExpiredL(l logx.Logger, s ...string) *LibError {
|
||||
e := AuthExpired(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// InvalidPosixTime returns Err
|
||||
func InvalidPosixTime(s ...string) *LibError {
|
||||
return newErr(Scope, code.InvalidPosixTime, fmt.Sprintf("invalid posix time: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// InvalidPosixTimeL logs error message and returns Err
|
||||
func InvalidPosixTimeL(l logx.Logger, s ...string) *LibError {
|
||||
e := InvalidPosixTime(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// SigAndPayloadNotMatched returns Err
|
||||
func SigAndPayloadNotMatched(s ...string) *LibError {
|
||||
return newErr(Scope, code.SigAndPayloadNotMatched, fmt.Sprintf("signature and the payload are not match: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// SigAndPayloadNotMatchedL logs error message and returns Err
|
||||
func SigAndPayloadNotMatchedL(l logx.Logger, s ...string) *LibError {
|
||||
e := SigAndPayloadNotMatched(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// Forbidden returns Err
|
||||
func Forbidden(s ...string) *LibError {
|
||||
return newErr(Scope, code.Forbidden, fmt.Sprintf("forbidden: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// ForbiddenL logs error message and returns Err
|
||||
func ForbiddenL(l logx.Logger, s ...string) *LibError {
|
||||
e := Forbidden(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// IsAuthUnauthorizedError check the err is unauthorized error
|
||||
func IsAuthUnauthorizedError(err *LibError) bool {
|
||||
switch err.Code() {
|
||||
case code.Unauthorized, code.AuthExpired, code.InvalidPosixTime,
|
||||
code.SigAndPayloadNotMatched, code.Forbidden,
|
||||
code.InvalidFormat, code.ResourceNotFound:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/*** CatXBC ***/
|
||||
|
||||
// ArkInternal returns Err
|
||||
func ArkInternal(s ...string) *LibError {
|
||||
return newErr(Scope, code.ArkInternal, fmt.Sprintf("ark internal error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// ArkInternalL logs error message and returns Err
|
||||
func ArkInternalL(l logx.Logger, s ...string) *LibError {
|
||||
e := ArkInternal(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
/*** CatPubSub ***/
|
||||
|
||||
// Publish returns Err
|
||||
func Publish(s ...string) *LibError {
|
||||
return newErr(Scope, code.Publish, fmt.Sprintf("publish: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// PublishL logs error message and returns Err
|
||||
func PublishL(l logx.Logger, s ...string) *LibError {
|
||||
e := Publish(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// Consume returns Err
|
||||
func Consume(s ...string) *LibError {
|
||||
return newErr(Scope, code.Consume, fmt.Sprintf("consume: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// MsgSizeTooLarge returns Err
|
||||
func MsgSizeTooLarge(s ...string) *LibError {
|
||||
return newErr(Scope, code.MsgSizeTooLarge, fmt.Sprintf("kafka error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
// MsgSizeTooLargeL logs error message and returns Err
|
||||
func MsgSizeTooLargeL(l logx.Logger, s ...string) *LibError {
|
||||
e := MsgSizeTooLarge(s...)
|
||||
l.WithCallerSkip(1).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,225 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
code2 "code.30cm.net/digimon/library-go/errors/code"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Scope 全域變數應由服務或模組設置
|
||||
var Scope = code2.Unset
|
||||
|
||||
// LibError 6 碼,服務 2, 大類 2, 詳細錯誤 2
|
||||
type LibError struct {
|
||||
category uint32
|
||||
code uint32
|
||||
scope uint32
|
||||
msg string
|
||||
internalErr error
|
||||
}
|
||||
|
||||
// Error 是錯誤的介面
|
||||
// 私有屬性 "msg" 的 getter 函數
|
||||
func (e *LibError) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 如果 internal err 存在,連接錯誤字串
|
||||
var internalErrStr string
|
||||
if e.internalErr != nil {
|
||||
internalErrStr = e.internalErr.Error()
|
||||
}
|
||||
|
||||
if e.msg != "" {
|
||||
if internalErrStr != "" {
|
||||
return fmt.Sprintf("%s: %s", e.msg, internalErrStr)
|
||||
}
|
||||
|
||||
return e.msg
|
||||
}
|
||||
|
||||
generalErrStr := e.GeneralError()
|
||||
if internalErrStr != "" {
|
||||
return fmt.Sprintf("%s: %s", generalErrStr, internalErrStr)
|
||||
}
|
||||
|
||||
return generalErrStr
|
||||
}
|
||||
|
||||
// Category 私有屬性 "category" 的 getter 函數
|
||||
func (e *LibError) Category() uint32 {
|
||||
if e == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return e.category
|
||||
}
|
||||
|
||||
// Scope 私有屬性 "scope" 的 getter 函數
|
||||
func (e *LibError) Scope() uint32 {
|
||||
if e == nil {
|
||||
return code2.Unset
|
||||
}
|
||||
|
||||
return e.scope
|
||||
}
|
||||
|
||||
// CodeStr 返回帶有零填充的錯誤代碼字串
|
||||
func (e *LibError) CodeStr() string {
|
||||
if e == nil {
|
||||
return "00000"
|
||||
}
|
||||
|
||||
if e.Category() == code2.CatGRPC {
|
||||
return fmt.Sprintf("%02d%04d", e.Scope(), e.Category()+e.Code())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%02d%04d", e.Scope(), e.Code())
|
||||
}
|
||||
|
||||
// Code 私有屬性 "code" 的 getter 函數
|
||||
func (e *LibError) Code() uint32 {
|
||||
if e == nil {
|
||||
return code2.OK
|
||||
}
|
||||
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e *LibError) FullCode() uint32 {
|
||||
if e == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if e.Category() == code2.CatGRPC {
|
||||
return e.Scope()*10000 + e.Category() + e.Code()
|
||||
}
|
||||
|
||||
return e.Scope()*10000 + e.Code()
|
||||
}
|
||||
|
||||
// HTTPStatus 返回對應的 HTTP 狀態碼
|
||||
func (e *LibError) HTTPStatus() int {
|
||||
if e == nil || e.Code() == code2.OK {
|
||||
return http.StatusOK
|
||||
}
|
||||
// 根據 code 判斷狀態碼
|
||||
switch e.Code() {
|
||||
case code2.ResourceInsufficient:
|
||||
// 400
|
||||
return http.StatusBadRequest
|
||||
case code2.Unauthorized, code2.InsufficientPermission:
|
||||
// 401
|
||||
return http.StatusUnauthorized
|
||||
case code2.InsufficientQuota:
|
||||
// 402
|
||||
return http.StatusPaymentRequired
|
||||
case code2.InvalidPosixTime, code2.Forbidden:
|
||||
// 403
|
||||
return http.StatusForbidden
|
||||
case code2.ResourceNotFound:
|
||||
// 404
|
||||
return http.StatusNotFound
|
||||
case code2.ResourceAlreadyExist, code2.InvalidResourceState:
|
||||
// 409
|
||||
return http.StatusConflict
|
||||
case code2.NotValidImplementation:
|
||||
// 501
|
||||
return http.StatusNotImplemented
|
||||
default:
|
||||
}
|
||||
|
||||
// 根據 category 判斷狀態碼
|
||||
switch e.Category() {
|
||||
case code2.CatInput:
|
||||
return http.StatusBadRequest
|
||||
default:
|
||||
// 如果沒有符合的條件,返回狀態碼 500
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
|
||||
// GeneralError 轉換 category 級別錯誤訊息
|
||||
// 這是給客戶或 API 調用者的一般錯誤訊息
|
||||
func (e *LibError) GeneralError() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
errStr, ok := code2.CatToStr[e.Category()]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return errStr
|
||||
}
|
||||
|
||||
// Is 在執行 errors.Is() 時調用。
|
||||
// 除非你非常確定你在做什麼,否則不要直接使用這個函數。
|
||||
// 請使用 errors.Is 代替。
|
||||
// 此函數比較兩個錯誤變量是否都是 *Err,並且具有相同的 code(不檢查包裹的內部錯誤)
|
||||
func (e *LibError) Is(f error) bool {
|
||||
var err *LibError
|
||||
ok := errors.As(f, &err)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return e.Code() == err.Code()
|
||||
}
|
||||
|
||||
// Unwrap 返回底層錯誤
|
||||
// 解除包裹錯誤的結果本身可能具有 Unwrap 方法;
|
||||
// 我們稱通過反覆解除包裹產生的錯誤序列為錯誤鏈。
|
||||
func (e *LibError) Unwrap() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return e.internalErr
|
||||
}
|
||||
|
||||
// Wrap 將內部錯誤設置到 Err 結構
|
||||
func (e *LibError) Wrap(internalErr error) *LibError {
|
||||
if e != nil {
|
||||
e.internalErr = internalErr
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *LibError) GRPCStatus() *status.Status {
|
||||
if e == nil {
|
||||
return status.New(codes.OK, "")
|
||||
}
|
||||
|
||||
return status.New(codes.Code(e.FullCode()), e.Error())
|
||||
}
|
||||
|
||||
// 工廠函數
|
||||
|
||||
// NewErr 創建新的 Err
|
||||
func NewErr(scope, category, detail uint32, msg string) *LibError {
|
||||
return &LibError{
|
||||
category: category,
|
||||
code: detail,
|
||||
scope: scope,
|
||||
msg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// NewGRPCErr 創建新的 gRPC Err
|
||||
func NewGRPCErr(scope, detail uint32, msg string) *LibError {
|
||||
return &LibError{
|
||||
category: code2.CatGRPC,
|
||||
code: detail,
|
||||
scope: scope,
|
||||
msg: msg,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
code2 "code.30cm.net/digimon/library-go/errors/code"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func TestCode_GivenNilReceiver_CodeReturnOK_CodeStrReturns00000(t *testing.T) {
|
||||
// setup
|
||||
var e *LibError = nil
|
||||
|
||||
// act & assert
|
||||
assert.Equal(t, code2.OK, e.Code())
|
||||
assert.Equal(t, "00000", e.CodeStr())
|
||||
assert.Equal(t, "", e.Error())
|
||||
}
|
||||
|
||||
func TestCode_GivenScope99DetailCode6687_ShouldReturn996687(t *testing.T) {
|
||||
// setup
|
||||
e := LibError{scope: 99, code: 6687}
|
||||
|
||||
// act & assert
|
||||
assert.Equal(t, uint32(6687), e.Code())
|
||||
assert.Equal(t, "996687", e.CodeStr())
|
||||
}
|
||||
|
||||
func TestCode_GivenScope0DetailCode87_ShouldReturn87(t *testing.T) {
|
||||
// setup
|
||||
e := LibError{scope: 0, code: 87}
|
||||
|
||||
// act & assert
|
||||
assert.Equal(t, uint32(87), e.Code())
|
||||
assert.Equal(t, "00087", e.CodeStr())
|
||||
}
|
||||
|
||||
func TestFromCode_Given870005_ShouldHasScope87_Cat0_Detail5(t *testing.T) {
|
||||
// setup
|
||||
e := FromCode(870005)
|
||||
|
||||
// assert
|
||||
assert.Equal(t, uint32(87), e.Scope())
|
||||
assert.Equal(t, uint32(0), e.Category())
|
||||
assert.Equal(t, uint32(5), e.Code())
|
||||
assert.Equal(t, "", e.Error())
|
||||
}
|
||||
|
||||
func TestFromCode_Given0_ShouldHasScope0_Cat0_Detail0(t *testing.T) {
|
||||
// setup
|
||||
e := FromCode(0)
|
||||
|
||||
// assert
|
||||
assert.Equal(t, uint32(0), e.Scope())
|
||||
assert.Equal(t, uint32(0), e.Category())
|
||||
assert.Equal(t, uint32(0), e.Code())
|
||||
assert.Equal(t, "", e.Error())
|
||||
}
|
||||
|
||||
func TestFromCode_Given9105_ShouldHasScope0_Cat9100_Detail9105(t *testing.T) {
|
||||
// setup
|
||||
e := FromCode(9105)
|
||||
|
||||
// assert
|
||||
assert.Equal(t, uint32(0), e.Scope())
|
||||
assert.Equal(t, uint32(9100), e.Category())
|
||||
assert.Equal(t, uint32(9105), e.Code())
|
||||
assert.Equal(t, "", e.Error())
|
||||
}
|
||||
|
||||
func TestErr_ShouldImplementErrorFunction(t *testing.T) {
|
||||
// setup a func return error
|
||||
f := func() error { return InvalidFormat("fake field") }
|
||||
|
||||
// act
|
||||
err := f()
|
||||
|
||||
// assert
|
||||
assert.NotNil(t, err)
|
||||
assert.Contains(t, fmt.Sprint(err), "fake field") // can be printed
|
||||
}
|
||||
|
||||
func TestGeneralError_GivenNilErr_ShouldReturnEmptyString(t *testing.T) {
|
||||
// setup
|
||||
var e *LibError = nil
|
||||
|
||||
// act & assert
|
||||
assert.Equal(t, "", e.GeneralError())
|
||||
}
|
||||
|
||||
func TestGeneralError_GivenNotExistCat_ShouldReturnEmptyString(t *testing.T) {
|
||||
// setup
|
||||
e := LibError{category: 123456}
|
||||
|
||||
// act & assert
|
||||
assert.Equal(t, "", e.GeneralError())
|
||||
}
|
||||
|
||||
func TestGeneralError_GivenCatDB_ShouldReturnDBError(t *testing.T) {
|
||||
// setup
|
||||
e := LibError{category: code2.CatDB}
|
||||
catErrStr := code2.CatToStr[code2.CatDB]
|
||||
|
||||
// act & assert
|
||||
assert.Equal(t, catErrStr, e.GeneralError())
|
||||
}
|
||||
|
||||
func TestError_GivenEmptyMsg_ShouldReturnCatGeneralErrorMessage(t *testing.T) {
|
||||
// setup
|
||||
e := LibError{category: code2.CatDB, msg: ""}
|
||||
|
||||
// act
|
||||
errMsg := e.Error()
|
||||
|
||||
// assert
|
||||
assert.Equal(t, code2.CatToStr[code2.CatDB], errMsg)
|
||||
}
|
||||
|
||||
func TestError_GivenMsg_ShouldReturnGiveMsg(t *testing.T) {
|
||||
// setup
|
||||
e := LibError{msg: "FAKE"}
|
||||
|
||||
// act
|
||||
errMsg := e.Error()
|
||||
|
||||
// assert
|
||||
assert.Equal(t, "FAKE", errMsg)
|
||||
}
|
||||
|
||||
func TestIs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
||||
var nilErrs *LibError
|
||||
// act
|
||||
result := errors.Is(nilErrs, DBError())
|
||||
result2 := errors.Is(DBError(), nilErrs)
|
||||
|
||||
// assert
|
||||
assert.False(t, result)
|
||||
assert.False(t, result2)
|
||||
}
|
||||
|
||||
func TestIs_GivenNil_ShouldReturnFalse(t *testing.T) {
|
||||
// act
|
||||
result := errors.Is(nil, DBError())
|
||||
result2 := errors.Is(DBError(), nil)
|
||||
|
||||
// assert
|
||||
assert.False(t, result)
|
||||
assert.False(t, result2)
|
||||
}
|
||||
|
||||
func TestIs_GivenNilReceiver_ShouldReturnCorrectResult(t *testing.T) {
|
||||
var nilErr *LibError = nil
|
||||
|
||||
// test 1: nilErr != DBError
|
||||
var dbErr error = DBError("fake db error")
|
||||
assert.False(t, nilErr.Is(dbErr))
|
||||
|
||||
// test 2: nilErr != nil error
|
||||
var nilError error
|
||||
assert.False(t, nilErr.Is(nilError))
|
||||
|
||||
// test 3: nilErr == another nilErr
|
||||
var nilErr2 *LibError = nil
|
||||
assert.True(t, nilErr.Is(nilErr2))
|
||||
}
|
||||
|
||||
func TestIs_GivenDBError_ShouldReturnTrue(t *testing.T) {
|
||||
// setup
|
||||
dbErr := DBError("fake db error")
|
||||
|
||||
// act
|
||||
result := errors.Is(dbErr, DBError("not care"))
|
||||
result2 := errors.Is(DBError(), dbErr)
|
||||
|
||||
// assert
|
||||
assert.True(t, result)
|
||||
assert.True(t, result2)
|
||||
}
|
||||
|
||||
func TestIs_GivenDBErrorAssignToErrorType_ShouldReturnTrue(t *testing.T) {
|
||||
// setup
|
||||
var dbErr error = DBError("fake db error")
|
||||
|
||||
// act
|
||||
result := errors.Is(dbErr, DBError("not care"))
|
||||
result2 := errors.Is(DBError(), dbErr)
|
||||
|
||||
// assert
|
||||
assert.True(t, result)
|
||||
assert.True(t, result2)
|
||||
}
|
||||
|
||||
func TestWrap_GivenNilErr_ShouldNoPanic(t *testing.T) {
|
||||
// act & assert
|
||||
assert.NotPanics(t, func() {
|
||||
var e *LibError = nil
|
||||
_ = e.Wrap(fmt.Errorf("test"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestWrap_GivenErrorToWrap_ShouldReturnErrorWithWrappedError(t *testing.T) {
|
||||
// act & assert
|
||||
wrappedErr := fmt.Errorf("test")
|
||||
wrappingErr := SystemInternalError("WrappingError").Wrap(wrappedErr)
|
||||
unWrappedErr := wrappingErr.Unwrap()
|
||||
|
||||
assert.Equal(t, wrappedErr, unWrappedErr)
|
||||
}
|
||||
|
||||
func TestUnwrap_GivenNilErr_ShouldReturnNil(t *testing.T) {
|
||||
var e *LibError = nil
|
||||
internalErr := e.Unwrap()
|
||||
assert.Nil(t, internalErr)
|
||||
}
|
||||
|
||||
func TestErrorsIs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
||||
var e *LibError = nil
|
||||
assert.False(t, errors.Is(e, fmt.Errorf("test")))
|
||||
}
|
||||
|
||||
func TestErrorsAs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
||||
var internalErr *testErr
|
||||
var e *LibError = nil
|
||||
assert.False(t, errors.As(e, &internalErr))
|
||||
}
|
||||
|
||||
func TestGRPCStatus(t *testing.T) {
|
||||
// setup table driven tests
|
||||
tests := []struct {
|
||||
name string
|
||||
given *LibError
|
||||
expect *status.Status
|
||||
expectConvert error
|
||||
}{
|
||||
{
|
||||
"nil errs.Err",
|
||||
nil,
|
||||
status.New(codes.OK, ""),
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"InvalidFormat Err",
|
||||
InvalidFormat("fake"),
|
||||
status.New(codes.Code(101), "invalid format: fake"),
|
||||
status.New(codes.Code(101), "invalid format: fake").Err(),
|
||||
},
|
||||
}
|
||||
|
||||
// act & assert
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
s := test.given.GRPCStatus()
|
||||
assert.Equal(t, test.expect.Code(), s.Code())
|
||||
assert.Equal(t, test.expect.Message(), s.Message())
|
||||
assert.Equal(t, test.expectConvert, status.Convert(test.given).Err())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestErr_HTTPStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
err *LibError
|
||||
want int
|
||||
}{
|
||||
{name: "nil error", err: nil, want: http.StatusOK},
|
||||
{name: "invalid measurement id", err: &LibError{category: code2.CatResource, code: code2.InvalidMeasurementID}, want: http.StatusInternalServerError},
|
||||
{name: "resource already exists", err: &LibError{category: code2.CatResource, code: code2.ResourceAlreadyExist}, want: http.StatusConflict},
|
||||
{name: "invalid resource state", err: &LibError{category: code2.CatResource, code: code2.InvalidResourceState}, want: http.StatusConflict},
|
||||
{name: "invalid posix time", err: &LibError{category: code2.CatAuth, code: code2.InvalidPosixTime}, want: http.StatusForbidden},
|
||||
{name: "unauthorized", err: &LibError{category: code2.CatAuth, code: code2.Unauthorized}, want: http.StatusUnauthorized},
|
||||
{name: "db error", err: &LibError{category: code2.CatDB, code: code2.DBError}, want: http.StatusInternalServerError},
|
||||
{name: "insufficient permission", err: &LibError{category: code2.CatResource, code: code2.InsufficientPermission}, want: http.StatusUnauthorized},
|
||||
{name: "resource insufficient", err: &LibError{category: code2.CatResource, code: code2.ResourceInsufficient}, want: http.StatusBadRequest},
|
||||
{name: "invalid format", err: &LibError{category: code2.CatInput, code: code2.InvalidFormat}, want: http.StatusBadRequest},
|
||||
{name: "resource not found", err: &LibError{code: code2.ResourceNotFound}, want: http.StatusNotFound},
|
||||
{name: "ok", err: &LibError{code: code2.OK}, want: http.StatusOK},
|
||||
{name: "not valid implementation", err: &LibError{category: code2.CatInput, code: code2.NotValidImplementation}, want: http.StatusNotImplemented},
|
||||
{name: "forbidden", err: &LibError{category: code2.CatAuth, code: code2.Forbidden}, want: http.StatusForbidden},
|
||||
{name: "insufficient quota", err: &LibError{category: code2.CatResource, code: code2.InsufficientQuota}, want: http.StatusPaymentRequired},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
// act
|
||||
got := tt.err.HTTPStatus()
|
||||
|
||||
// assert
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
module code.30cm.net/digimon/library-go/errors
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/zeromicro/go-zero v1.7.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
)
|
|
@ -0,0 +1,125 @@
|
|||
## Purpose of errs package
|
||||
1. compatible with `error` interface
|
||||
2. encapsulate error message with functions in `easy_function.go`
|
||||
3. easy for gRPC client/server
|
||||
4. support err's chain by [Working with Errors in Go 1.13](https://blog.golang.org/go1.13-errors)
|
||||
|
||||
|
||||
## Example - Normal function
|
||||
Using builtin functions `InvalidInput` to generate `Err struct`
|
||||
|
||||
**please add your own functions if not exist**
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "adc.github.trendmicro.com/commercial-mgcp/library-go/pkg/errs"
|
||||
|
||||
func handleParam(s string) error {
|
||||
// check user_id format
|
||||
if ok := userIDFormat(s); !ok {
|
||||
return errs.InvalidFormat("param user_id")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
## Example - gRPC Server
|
||||
`GetAgent` is a method of gRPC server, it wraps `Err` struct to `status.Status` struct
|
||||
```go
|
||||
func (as *agentService) GetAgent(ctx context.Context, req *cloudep.GetAgentRequest) (*cloudep.GetAgentResponse, error) {
|
||||
l := log.WithFields(logger.Fields{"tenant_id": req.TenantId, "agent_id": req.AgentId, "method": "GetAgent"})
|
||||
|
||||
tenantID, err := primitive.ObjectIDFromHex(req.TenantId)
|
||||
if err != nil {
|
||||
// err maybe errs.Err or general error
|
||||
// it's safe to use Convert() here
|
||||
return nil, status.Convert(err).Err()
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Example - gRPC Client
|
||||
Calling `GetAgent` and retry when Category is "DB"
|
||||
```go
|
||||
client := cloudep.NewAgentServiceClient(conn)
|
||||
req := cloudep.GetAgentRequest{
|
||||
TenantId: "not-a-valid-object-id",
|
||||
AgentId: "5eb4fa99006d53c0cb6f9cfe",
|
||||
}
|
||||
|
||||
// Retry if DB error
|
||||
for retry := 3; retry > 0 ; retry-- {
|
||||
resp, err := client.GetAgent(context.Background(), &req)
|
||||
if err != nil {
|
||||
e := errs.FromGRPCError(err)
|
||||
if e.Category() == code.CatGRPC {
|
||||
if e.Code() == uint32(codes.Unavailable) {
|
||||
log.warn("GRPC service unavailable. Retrying...")
|
||||
continue
|
||||
}
|
||||
log.errorf("GRPC built-in error: %v", e)
|
||||
}
|
||||
if e.Category() == code.CatDB {
|
||||
log.warn("retry...")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
```
|
||||
|
||||
## Example - REST server
|
||||
1. handling gRPC client error
|
||||
2. transfer to HTTP code
|
||||
3. transfer to Error body
|
||||
|
||||
```go
|
||||
func Handler(c *gin.Context) {
|
||||
|
||||
// handle error from gRPC client
|
||||
resp, err := client.GetAgent(context.Background(), &req)
|
||||
if err != nil {
|
||||
// to Err
|
||||
e := errs.FromGRPCError(err)
|
||||
|
||||
// get HTTP code & response struct
|
||||
// 2nd parameter true means return general error message to user
|
||||
c.JSON(e.HTTPStatus(), general.NewError(e, true))
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Example - Error Chain
|
||||
1. set internal error by func `Wrap`
|
||||
2. check Err has any error in err's chain matches the target by `errors.Is`
|
||||
3. finds the first error in err's chain that matches target by `errors.As`
|
||||
|
||||
```go
|
||||
// define a specific err type
|
||||
type testErr struct {
|
||||
code int
|
||||
}
|
||||
|
||||
func (e *testErr) Error() string {
|
||||
return strconv.Itoa(e.code)
|
||||
}
|
||||
|
||||
func main() {
|
||||
layer1Err := &testErr{code: 123}
|
||||
// error chain: InvalidFormat -> layer 1 err
|
||||
layer2Err := InvalidFormat("field A", "")
|
||||
layer2Err.Wrap(layer1Err) //set internal error
|
||||
|
||||
// errors.Is should report true
|
||||
hasLayer1Err := errors.Is(layer2Err, layer1Err)
|
||||
|
||||
// errors.As should return internal error
|
||||
var internalErr *testErr
|
||||
ok := errors.As(layer2Err, &internalErr)
|
||||
}
|
||||
```
|
|
@ -70,6 +70,5 @@ const (
|
|||
const (
|
||||
_ = iota + CatService
|
||||
ArkInternal // Ark 內部錯誤
|
||||
ThirdParty
|
||||
ArkHTTP400 // Ark HTTP 400 錯誤
|
||||
ArkHTTP400 // Ark HTTP 400 錯誤
|
||||
)
|
||||
|
|
|
@ -7,11 +7,4 @@ const (
|
|||
CloudEPMember
|
||||
CloudEPPermission
|
||||
CloudEPNotification
|
||||
CloudEPTweeting
|
||||
CloudEPOrder
|
||||
CloudEPFileStorage
|
||||
CloudEPProduct
|
||||
CloudEPSecKill
|
||||
CloudEPCart
|
||||
CloudEPComment
|
||||
)
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
package errs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.30cm.net/digimon/library-go/errs/code"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ErrorCode uint32
|
||||
|
||||
func (e ErrorCode) ToUint32() uint32 {
|
||||
return uint32(e)
|
||||
}
|
||||
|
||||
func ThirdPartyError(scope uint32, ec ErrorCode, s ...string) *LibError {
|
||||
return NewError(scope, code.ThirdParty, ec.ToUint32(), fmt.Sprintf("thirty error: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
func ThirdPartyErrorL(scope uint32, ec ErrorCode,
|
||||
l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||||
e := ThirdPartyError(scope, ec, s...)
|
||||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func DatabaseErrorWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
|
||||
return NewError(scope, code.DBError, ec.ToUint32(), strings.Join(s, " "))
|
||||
}
|
||||
|
||||
func DatabaseErrorWithScopeL(scope uint32,
|
||||
ec ErrorCode,
|
||||
l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||||
e := DatabaseErrorWithScope(scope, ec, s...)
|
||||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func ResourceNotFoundWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
|
||||
return NewError(scope, code.ResourceNotFound, ec.ToUint32(), fmt.Sprintf("resource not found: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
func ResourceNotFoundWithScopeL(scope uint32, ec ErrorCode,
|
||||
l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||||
e := ResourceNotFoundWithScope(scope, ec, s...)
|
||||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func InvalidRangeWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
|
||||
return NewError(scope, code.CatInput, ec.ToUint32(), fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
func InvalidRangeWithScopeL(scope uint32, ec ErrorCode,
|
||||
l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||||
e := InvalidRangeWithScope(scope, ec, s...)
|
||||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func InvalidFormatWithScope(scope uint32, s ...string) *LibError {
|
||||
return NewError(scope, code.CatInput, code.InvalidFormat, fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
func InvalidFormatWithScopeL(scope uint32,
|
||||
l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||||
e := InvalidFormatWithScope(scope, s...)
|
||||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func ForbiddenWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
|
||||
return NewError(scope, code.Forbidden, ec.ToUint32(), fmt.Sprintf("forbidden: %s", strings.Join(s, " ")))
|
||||
}
|
||||
|
||||
func ForbiddenWithScopeL(scope uint32, ec ErrorCode,
|
||||
l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||||
e := ForbiddenWithScope(scope, ec, s...)
|
||||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||
|
||||
return e
|
||||
}
|
11
go.work
11
go.work
|
@ -1,12 +1,9 @@
|
|||
go 1.23.4
|
||||
go 1.22.3
|
||||
|
||||
use (
|
||||
.
|
||||
./errs
|
||||
./jwt
|
||||
./mongo
|
||||
./utils/bitmap
|
||||
./utils/invited_code
|
||||
./errors
|
||||
./validator
|
||||
./worker_pool
|
||||
./jwt
|
||||
./errs
|
||||
)
|
||||
|
|
390
go.work.sum
390
go.work.sum
|
@ -1,200 +1,71 @@
|
|||
cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
|
||||
cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
|
||||
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
||||
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/IBM/sarama v1.43.1 h1:Z5uz65Px7f4DhI/jQqEm/tV9t8aU+JUdTyW/K/fCXpA=
|
||||
github.com/IBM/sarama v1.43.1/go.mod h1:GG5q1RURtDNPz8xxJs3mgX6Ytak8Z9eLhAkJPObe2xE=
|
||||
github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38=
|
||||
github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE=
|
||||
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA=
|
||||
github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0=
|
||||
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/bufbuild/protocompile v0.10.0 h1:+jW/wnLMLxaCEG8AX9lD0bQ5v9h1RUiMKOBOT5ll9dM=
|
||||
github.com/bufbuild/protocompile v0.10.0/go.mod h1:G9qQIQo0xZ6Uyj6CMNz0saGmx2so+KONo8/KrELABiY=
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4=
|
||||
github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY=
|
||||
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/btrfs/v2 v2.0.0 h1:FN4wsx7KQrYoLXN7uLP0vBV4oVWHOIKDRQ1G2Z0oL5M=
|
||||
github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
|
||||
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
|
||||
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
|
||||
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
|
||||
github.com/containerd/go-cni v1.1.9 h1:ORi7P1dYzCwVM6XPN4n3CbkuOx/NZ2DOqy+SHRdo9rU=
|
||||
github.com/containerd/go-cni v1.1.9/go.mod h1:XYrZJ1d5W6E2VOvjffL3IZq0Dz6bsVlERHbekNK90PM=
|
||||
github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0=
|
||||
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
github.com/containerd/imgcrypt v1.1.8 h1:ZS7TuywcRNLoHpU0g+v4/PsKynl6TYlw5xDVWWoIyFA=
|
||||
github.com/containerd/imgcrypt v1.1.8/go.mod h1:x6QvFIkMyO2qGIY2zXc88ivEzcbgvLdWjoZyGqDap5U=
|
||||
github.com/containerd/nri v0.6.1 h1:xSQ6elnQ4Ynidm9u49ARK9wRKHs80HCUI+bkXOxV4mA=
|
||||
github.com/containerd/nri v0.6.1/go.mod h1:7+sX3wNx+LR7RzhjnJiUkFDhn18P5Bg/0VnJ/uXpRJM=
|
||||
github.com/containerd/ttrpc v1.2.4 h1:eQCQK4h9dxDmpOb9QOOMh2NHTfzroH1IkmHiKZi05Oo=
|
||||
github.com/containerd/ttrpc v1.2.4/go.mod h1:ojvb8SJBSch0XkqNO0L0YX/5NxR3UnVk2LzFKBK0upc=
|
||||
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
|
||||
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
|
||||
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
|
||||
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
|
||||
github.com/containerd/zfs v1.1.0 h1:n7OZ7jZumLIqNJqXrEc/paBM840mORnmGdJDmAmJZHM=
|
||||
github.com/containerd/zfs v1.1.0/go.mod h1:oZF9wBnrnQjpWLaPKEinrx3TQ9a+W/RJO7Zb41d8YLE=
|
||||
github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ=
|
||||
github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
|
||||
github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU=
|
||||
github.com/containernetworking/plugins v1.2.0/go.mod h1:/VjX4uHecW5vVimFa1wkG4s+r/s9qIfPdqlLF4TW8c4=
|
||||
github.com/containers/ocicrypt v1.1.10 h1:r7UR6o8+lyhkEywetubUUgcKFjOWOaWz8cEBrCPX0ic=
|
||||
github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.6.0 h1:CqGDTLtpwuWKn6Nj3uNUdflaq+/kIPsg0gfNzHton30=
|
||||
github.com/eapache/go-resiliency v1.6.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
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/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI=
|
||||
github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fullstorydev/grpcurl v1.9.1 h1:YxX1aCcCc4SDBQfj9uoWcTLe8t4NWrZe1y+mk83BQgo=
|
||||
github.com/fullstorydev/grpcurl v1.9.1/go.mod h1:i8gKLIC6s93WdU3LSmkE5vtsCxyRmihUj5FK1cNW5EM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
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/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
|
||||
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/intel/goresctrl v0.3.0 h1:K2D3GOzihV7xSBedGxONSlaw/un1LZgWsc9IfqipN4c=
|
||||
github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk=
|
||||
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/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
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-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
|
@ -203,108 +74,34 @@ github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
|
|||
github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
|
||||
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/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
|
||||
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jhump/gopoet v0.1.0 h1:gYjOPnzHd2nzB37xYQZxj4EIQNpBrBskRqQQ3q4ZgSg=
|
||||
github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
|
||||
github.com/jhump/goprotoc v0.5.0 h1:Y1UgUX+txUznfqcGdDef8ZOVlyQvnV0pKWZH08RmZuo=
|
||||
github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=
|
||||
github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg=
|
||||
github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46 h1:veS9QfglfvqAw2e+eeNT/SbGySq8ajECXJ9e4fPoLhY=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
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/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lyft/protoc-gen-star/v2 v2.0.3 h1:/3+/2sWyXeMLzKd1bX+ixWKgEMsULrIivpDsuaF441o=
|
||||
github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
||||
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||
github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc=
|
||||
github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/panjf2000/ants/v2 v2.10.0 h1:zhRg1pQUtkyRiOFo2Sbqwjp0GfBNo9cUY2/Grpx1p+8=
|
||||
github.com/panjf2000/ants/v2 v2.10.0/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
||||
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
|
@ -313,56 +110,20 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz
|
|||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo=
|
||||
github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
|
||||
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
|
||||
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/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw=
|
||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
|
||||
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||
github.com/zeromicro/go-zero v1.7.0 h1:B+y7tUVlo3qVQ6F0I0R9bi+Dq4I1QdO9ZB+dz1r0p1s=
|
||||
github.com/zeromicro/go-zero v1.7.0/go.mod h1:ypW4PzQI+jUrMcNJDDQ+7YW+pE+tMua9Xj/pmtmS1Dc=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
||||
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk=
|
||||
go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA=
|
||||
|
@ -371,94 +132,69 @@ go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4
|
|||
go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU=
|
||||
go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4BQ4=
|
||||
go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 h1:RsQi0qJ2imFfCvZabqzM9cNXBG8k6gXMv1A0cXRmH6A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0/go.mod h1:vsh3ySueQCiKPxFLvjWC4Z135gIa34TQ/NSqkDTZYUM=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1msnm4DaBqs/rpXUqY=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
|
||||
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
|
||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.8/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=
|
||||
k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
|
||||
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
||||
k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q=
|
||||
k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o=
|
||||
k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8=
|
||||
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
|
||||
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
|
||||
k8s.io/component-base v0.26.2 h1:IfWgCGUDzrD6wLLgXEstJKYZKAFS2kO+rBRi0p3LqcI=
|
||||
k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs=
|
||||
k8s.io/cri-api v0.27.1 h1:KWO+U8MfI9drXB/P4oU9VchaWYOlwDglJZVHWMpTT3Q=
|
||||
k8s.io/cri-api v0.27.1/go.mod h1:+Ts/AVYbIo04S86XbTD73UPp/DkTiYxtsFeOFEu32L0=
|
||||
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks=
|
||||
k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
tags.cncf.io/container-device-interface v0.7.2 h1:MLqGnWfOr1wB7m08ieI4YJ3IoLKKozEnnNYBtacDPQU=
|
||||
tags.cncf.io/container-device-interface v0.7.2/go.mod h1:Xb1PvXv2BhfNb3tla4r9JL129ck1Lxv9KuU6eVOfKto=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.7.0 h1:w/maMGVeLP6TIQJVYT5pbqTi8SCw/iHZ+n4ignuGHqg=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.7.0/go.mod h1:hMAwAbMZyBLdmYqWgYcKH0F/yctNpV3P35f+/088A80=
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import "time"
|
||||
|
||||
type Conf struct {
|
||||
Schema string
|
||||
User string
|
||||
Password string
|
||||
Host string
|
||||
Database string
|
||||
ReplicaName string
|
||||
MaxStaleness time.Duration
|
||||
MaxPoolSize uint64
|
||||
MinPoolSize uint64
|
||||
MaxConnIdleTime time.Duration
|
||||
Compressors []string
|
||||
EnableStandardReadWriteSplitMode bool
|
||||
ConnectTimeoutMs int64
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/syncx"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
const (
|
||||
authenticationStringTemplate = "%s:%s@"
|
||||
connectionStringTemplate = "%s://%s%s"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotFound is an alias of mongo.ErrNoDocuments.
|
||||
ErrNotFound = mongo.ErrNoDocuments
|
||||
|
||||
// can't use one SingleFlight per conn, because multiple conns may share the same cache key.
|
||||
singleFlight = syncx.NewSingleFlight()
|
||||
stats = cache.NewStat("monc")
|
||||
)
|
|
@ -1,52 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type MgoDecimal struct{}
|
||||
|
||||
var (
|
||||
_ bsoncodec.ValueEncoder = &MgoDecimal{}
|
||||
_ bsoncodec.ValueDecoder = &MgoDecimal{}
|
||||
)
|
||||
|
||||
func (dc *MgoDecimal) EncodeValue(_ bsoncodec.EncodeContext, w bsonrw.ValueWriter, value reflect.Value) error {
|
||||
// TODO 待確認是否有非decimal.Decimal type而導致error的場景
|
||||
dec, ok := value.Interface().(decimal.Decimal)
|
||||
if !ok {
|
||||
return fmt.Errorf("value %v to encode is not of type decimal.Decimal", value)
|
||||
}
|
||||
|
||||
// Convert decimal.Decimal to primitive.Decimal128.
|
||||
primDec, err := primitive.ParseDecimal128(dec.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting decimal.Decimal %v to primitive.Decimal128 error: %w", dec, err)
|
||||
}
|
||||
|
||||
return w.WriteDecimal128(primDec)
|
||||
}
|
||||
|
||||
func (dc *MgoDecimal) DecodeValue(_ bsoncodec.DecodeContext, r bsonrw.ValueReader, value reflect.Value) error {
|
||||
primDec, err := r.ReadDecimal128()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading primitive.Decimal128 from ValueReader error: %w", err)
|
||||
}
|
||||
|
||||
// Convert primitive.Decimal128 to decimal.Decimal.
|
||||
dec, err := decimal.NewFromString(primDec.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting primitive.Decimal128 %v to decimal.Decimal error: %w", primDec, err)
|
||||
}
|
||||
|
||||
// set as decimal.Decimal type
|
||||
value.Set(reflect.ValueOf(dec))
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type DocumentDBWithCache struct {
|
||||
DocumentDBUseCase
|
||||
Cache cache.Cache
|
||||
}
|
||||
|
||||
func MustDocumentDBWithCache(conf *Conf, collection string, cacheConf cache.CacheConf, dbOpts []mon.Option, cacheOpts []cache.Option) (DocumentDBWithCacheUseCase, error) {
|
||||
documentDB, err := NewDocumentDB(conf, collection, dbOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize DocumentDB: %w", err)
|
||||
}
|
||||
|
||||
c := MustModelCache(cacheConf, cacheOpts...)
|
||||
|
||||
return &DocumentDBWithCache{
|
||||
DocumentDBUseCase: documentDB,
|
||||
Cache: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) DelCache(ctx context.Context, keys ...string) error {
|
||||
return dc.Cache.DelCtx(ctx, keys...)
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) GetCache(key string, v any) error {
|
||||
return dc.Cache.Get(key, v)
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) SetCache(key string, v any) error {
|
||||
return dc.Cache.Set(key, v)
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) DeleteOne(ctx context.Context, key string, filter any, opts ...*options.DeleteOptions) (int64, error) {
|
||||
val, err := dc.GetClient().DeleteOne(ctx, filter, opts...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := dc.DelCache(ctx, key); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) FindOne(ctx context.Context, key string, v, filter any, opts ...*options.FindOneOptions) error {
|
||||
return dc.Cache.TakeCtx(ctx, v, key, func(v any) error {
|
||||
return dc.GetClient().FindOne(ctx, v, filter, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) FindOneAndDelete(ctx context.Context, key string, v, filter any, opts ...*options.FindOneAndDeleteOptions) error {
|
||||
if err := dc.GetClient().FindOneAndDelete(ctx, v, filter, opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dc.DelCache(ctx, key)
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) FindOneAndReplace(ctx context.Context, key string, v, filter, replacement any, opts ...*options.FindOneAndReplaceOptions) error {
|
||||
if err := dc.GetClient().FindOneAndReplace(ctx, v, filter, replacement, opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dc.DelCache(ctx, key)
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) InsertOne(ctx context.Context, key string, document any, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
|
||||
res, err := dc.GetClient().InsertOne(ctx, document, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = dc.DelCache(ctx, key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) UpdateByID(ctx context.Context, key string, id, update any, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
res, err := dc.GetClient().UpdateByID(ctx, id, update, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = dc.DelCache(ctx, key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) UpdateMany(ctx context.Context, keys []string, filter, update any, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
res, err := dc.GetClient().UpdateMany(ctx, filter, update, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = dc.DelCache(ctx, keys...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (dc *DocumentDBWithCache) UpdateOne(ctx context.Context, key string, filter, update any, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
res, err := dc.GetClient().UpdateOne(ctx, filter, update, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = dc.DelCache(ctx, key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ========================
|
||||
|
||||
// MustModelCache returns a cache cluster.
|
||||
func MustModelCache(conf cache.CacheConf, opts ...cache.Option) cache.Cache {
|
||||
return cache.New(conf, singleFlight, stats, mongo.ErrNoDocuments, opts...)
|
||||
}
|
137
mongo/doc-db.go
137
mongo/doc-db.go
|
@ -1,137 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||
)
|
||||
|
||||
type DocumentDB struct {
|
||||
Mon *mon.Model
|
||||
}
|
||||
|
||||
func NewDocumentDB(config *Conf, collection string, opts ...mon.Option) (DocumentDBUseCase, error) {
|
||||
authenticationURI := ""
|
||||
if config.User != "" {
|
||||
authenticationURI = fmt.Sprintf(
|
||||
authenticationStringTemplate,
|
||||
config.User,
|
||||
config.Password,
|
||||
)
|
||||
}
|
||||
|
||||
connectionURI := fmt.Sprintf(
|
||||
connectionStringTemplate,
|
||||
config.Schema,
|
||||
authenticationURI,
|
||||
config.Host,
|
||||
)
|
||||
|
||||
connectUri, _ := url.Parse(connectionURI)
|
||||
printConnectUri := connectUri.String()
|
||||
findIndexAt := strings.Index(connectUri.String(), "@")
|
||||
if findIndexAt > -1 && config.User != "" {
|
||||
prefixIndex := len(config.Schema) + 3 + len(config.User)
|
||||
connectUriStr := connectUri.String()
|
||||
printConnectUri = fmt.Sprintf("%s:*****%s", connectUriStr[:prefixIndex], connectUriStr[findIndexAt:])
|
||||
}
|
||||
// 初始化選項
|
||||
intOpt := InitMongoOptions(*config)
|
||||
opts = append(opts, intOpt)
|
||||
|
||||
logx.Infof("[DocumentDB] Try to connect document db `%s`", printConnectUri)
|
||||
client, err := mon.NewModel(connectionURI, config.Database, collection, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(),
|
||||
time.Duration(config.ConnectTimeoutMs)*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
// Force a connection to verify our connection string
|
||||
err = client.Database().Client().Ping(ctx, readpref.SecondaryPreferred())
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Failed to ping cluster: %s", err))
|
||||
}
|
||||
logx.Infof("[DocumentDB] Connected to DocumentDB!")
|
||||
|
||||
return &DocumentDB{
|
||||
Mon: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (document *DocumentDB) PopulateIndex(ctx context.Context, key string, sort int32, unique bool) {
|
||||
c := document.Mon.Collection
|
||||
opts := options.CreateIndexes().SetMaxTime(3 * time.Second)
|
||||
index := document.yieldIndexModel(
|
||||
[]string{key}, []int32{sort}, unique, nil,
|
||||
)
|
||||
_, err := c.Indexes().CreateOne(ctx, index, opts)
|
||||
if err != nil {
|
||||
logx.Errorf("[DocumentDb] Ensure Index Failed, %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (document *DocumentDB) PopulateTTLIndex(ctx context.Context, key string, sort int32, unique bool, ttl int32) {
|
||||
c := document.Mon.Collection
|
||||
opts := options.CreateIndexes().SetMaxTime(3 * time.Second)
|
||||
index := document.yieldIndexModel(
|
||||
[]string{key}, []int32{sort}, unique,
|
||||
options.Index().SetExpireAfterSeconds(ttl),
|
||||
)
|
||||
_, err := c.Indexes().CreateOne(ctx, index, opts)
|
||||
if err != nil {
|
||||
logx.Errorf("[DocumentDb] Ensure TTL Index Failed, %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (document *DocumentDB) PopulateMultiIndex(ctx context.Context, keys []string, sorts []int32, unique bool) {
|
||||
if len(keys) != len(sorts) {
|
||||
logx.Infof("[DocumentDb] Ensure Indexes Failed Please provide some item length of keys/sorts")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c := document.Mon.Collection
|
||||
opts := options.CreateIndexes().SetMaxTime(3 * time.Second)
|
||||
index := document.yieldIndexModel(keys, sorts, unique, nil)
|
||||
|
||||
_, err := c.Indexes().CreateOne(ctx, index, opts)
|
||||
if err != nil {
|
||||
logx.Errorf("[DocumentDb] Ensure TTL Index Failed, %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (document *DocumentDB) GetClient() *mon.Model {
|
||||
return document.Mon
|
||||
}
|
||||
|
||||
func (document *DocumentDB) yieldIndexModel(keys []string, sorts []int32, unique bool, indexOpt *options.IndexOptions) mongo.IndexModel {
|
||||
SetKeysDoc := bson.D{}
|
||||
for index, _ := range keys {
|
||||
key := keys[index]
|
||||
sort := sorts[index]
|
||||
SetKeysDoc = append(SetKeysDoc, bson.E{Key: key, Value: sort})
|
||||
}
|
||||
if indexOpt == nil {
|
||||
indexOpt = options.Index()
|
||||
}
|
||||
indexOpt.SetUnique(unique)
|
||||
index := mongo.IndexModel{
|
||||
Keys: SetKeysDoc,
|
||||
Options: indexOpt,
|
||||
}
|
||||
return index
|
||||
}
|
102
mongo/go.mod
102
mongo/go.mod
|
@ -1,102 +0,0 @@
|
|||
module code.30cm.net/digimon/library-go/mongo
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require (
|
||||
github.com/alicebob/miniredis/v2 v2.33.0
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/testcontainers/testcontainers-go v0.34.0
|
||||
github.com/zeromicro/go-zero v1.7.4
|
||||
go.mongodb.org/mongo-driver v1.17.1
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/containerd v1.7.18 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/docker v27.1.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // 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/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
github.com/yuin/gopher-lua v1.1.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/grpc v1.65.0 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -1,47 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type TypeCodec struct {
|
||||
ValueType reflect.Type
|
||||
Encoder bsoncodec.ValueEncoder
|
||||
Decoder bsoncodec.ValueDecoder
|
||||
}
|
||||
|
||||
// WithTypeCodec registers TypeCodecs to convert custom types.
|
||||
func WithTypeCodec(typeCodecs ...TypeCodec) mon.Option {
|
||||
return func(c *options.ClientOptions) {
|
||||
registry := bson.NewRegistry()
|
||||
for _, v := range typeCodecs {
|
||||
registry.RegisterTypeEncoder(v.ValueType, v.Encoder)
|
||||
registry.RegisterTypeDecoder(v.ValueType, v.Decoder)
|
||||
}
|
||||
c.SetRegistry(registry)
|
||||
}
|
||||
}
|
||||
|
||||
// SetCustomDecimalType force convert primitive.Decimal128 to decimal.Decimal.
|
||||
func SetCustomDecimalType() mon.Option {
|
||||
return WithTypeCodec(TypeCodec{
|
||||
ValueType: reflect.TypeOf(decimal.Decimal{}),
|
||||
Encoder: &MgoDecimal{},
|
||||
Decoder: &MgoDecimal{},
|
||||
})
|
||||
}
|
||||
|
||||
func InitMongoOptions(cfg Conf) mon.Option {
|
||||
return func(opts *options.ClientOptions) {
|
||||
opts.SetMaxPoolSize(cfg.MaxPoolSize)
|
||||
opts.SetMinPoolSize(cfg.MinPoolSize)
|
||||
opts.SetMaxConnIdleTime(cfg.MaxConnIdleTime)
|
||||
opts.SetCompressors([]string{"snappy"})
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
mopt "go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type DocumentDBUseCase interface {
|
||||
PopulateIndex(ctx context.Context, key string, sort int32, unique bool)
|
||||
PopulateTTLIndex(ctx context.Context, key string, sort int32, unique bool, ttl int32)
|
||||
PopulateMultiIndex(ctx context.Context, keys []string, sorts []int32, unique bool)
|
||||
GetClient() *mon.Model
|
||||
}
|
||||
|
||||
type DocumentDBWithCacheUseCase interface {
|
||||
DocumentDBUseCase
|
||||
CacheUseCase
|
||||
DeleteOne(ctx context.Context, key string, filter any, opts ...*mopt.DeleteOptions) (int64, error)
|
||||
FindOne(ctx context.Context, key string, v, filter any, opts ...*mopt.FindOneOptions) error
|
||||
FindOneAndDelete(ctx context.Context, key string, v, filter any, opts ...*mopt.FindOneAndDeleteOptions) error
|
||||
FindOneAndReplace(ctx context.Context, key string, v, filter, replacement any, opts ...*mopt.FindOneAndReplaceOptions) error
|
||||
InsertOne(ctx context.Context, key string, document any, opts ...*mopt.InsertOneOptions) (*mongo.InsertOneResult, error)
|
||||
UpdateByID(ctx context.Context, key string, id, update any, opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error)
|
||||
UpdateMany(ctx context.Context, keys []string, filter, update any, opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error)
|
||||
UpdateOne(ctx context.Context, key string, filter, update any, opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error)
|
||||
}
|
||||
|
||||
type CacheUseCase interface {
|
||||
DelCache(ctx context.Context, keys ...string) error
|
||||
GetCache(key string, v any) error
|
||||
SetCache(key string, v any) error
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
package usecase
|
||||
|
||||
// Bitmap 基礎結構
|
||||
// Bitmap 是一個位圖結構,使用 byte slice 來表示大量的位(bit)。
|
||||
// 每個 byte 由 8 個位組成,因此可以高效地管理大量的開關狀態(true/false)。
|
||||
// Bitmap 的優點在於它能節省空間,尤其是在需要大量布爾值的場合。
|
||||
// 缺點是,如果需要動態擴充 Bitmap 的大小,會導致效率下降,因為需要重新分配和移動內存。
|
||||
// 因此,最好在初始化時就規劃好所需的位數大小,避免在之後頻繁擴充。
|
||||
|
||||
type Bitmap []byte
|
||||
|
||||
// MakeBitmapWithBitSize 通過指定的 bit 數創建一個新的 Bitmap。
|
||||
// 參數 nBits 表示所需的位(bit)數。
|
||||
// 如果指定的位數少於 64,則默認將 Bitmap 初始化為 64 位(這是最低的限制)。
|
||||
// 此外,位數(nBits)會被自動調整為 8 的倍數,以適配 byte 的長度(每 8 位為一個 byte)。
|
||||
// 返回值是一個 Bitmap(byte slice),其大小根據位數確定。
|
||||
func MakeBitmapWithBitSize(nBits int) Bitmap {
|
||||
// 如果指定的位數少於 64,則設置為 64 位(8 個 byte)
|
||||
if nBits < 64 {
|
||||
nBits = 64
|
||||
}
|
||||
// 計算需要的 byte 數,確保每 8 位為一個 byte,並調整 nBits 以達到 8 的倍數
|
||||
return MustBitMap((nBits + 7) / 8)
|
||||
}
|
||||
|
||||
// MustBitMap 根據指定的 byte 數創建一個 Bitmap(byte slice)。
|
||||
// 參數 nBytes 表示所需的 byte 數。
|
||||
// 返回值是一個長度為 nBytes 的 Bitmap。
|
||||
func MustBitMap(nBytes int) Bitmap {
|
||||
// 使用 make 函數創建一個 byte slice,大小為 nBytes。
|
||||
return make([]byte, nBytes)
|
||||
}
|
||||
|
||||
// SetTrue 設置指定位置的 bit 為 true(1)。
|
||||
// 參數 bitPos 是需要設置的位的位置(以 0 為基準的位索引)。
|
||||
// 這個操作會找到該 bit 所在的 byte,然後通過位運算將該位置的 bit 設置為 1。
|
||||
func (b Bitmap) SetTrue(bitPos uint32) {
|
||||
// |= 是一種位運算的複合賦值運算符,表示將左邊的變數與右邊的值進行 位或運算(bitwise OR),並將結果賦值
|
||||
b[bitPos/8] |= 1 << (bitPos % 8)
|
||||
}
|
||||
|
||||
// SetFalse 設置指定位置的 bit 為 false(0)。
|
||||
// 參數 bitPos 是需要設置的位的位置(以 0 為基準的位索引)。
|
||||
// 這個操作會找到該 bit 所在的 byte,然後通過位運算將該位置的 bit 設置為 0。
|
||||
func (b Bitmap) SetFalse(bitPos uint32) {
|
||||
// 取出對應 byte,使用位與和取反運算將對應的 bit 設置為 0
|
||||
// 假設我們有以下情況:
|
||||
|
||||
// • b[1](即 b[bitPos/8])是 10101111(十進制 175)。
|
||||
// • bitPos = 10,也就是我們想清除第 10 位的值。
|
||||
//
|
||||
// 操作步驟:
|
||||
//
|
||||
// 1. bitPos/8 = 1:所以我們要修改 b[1] 這個 byte。
|
||||
// 2. bitPos % 8 = 2:表示我們要清除的位是這個 byte 中的第 3 位(從右數起第 3 位)。
|
||||
// 3. 1 << (bitPos % 8) = 1 << 2 = 00000100:生成位掩碼 00000100。
|
||||
// 4. 取反:^(1 << 2) = ^00000100 = 11111011,這樣的掩碼表示除了第 3 位,其他位都是 1。
|
||||
// 5. 位與運算:10101111 & 11111011 = 10101011,結果將第 3 位清除,其餘位保持不變。即,b[1] 變成了 10101011(十進制 171)。
|
||||
// &= 是一種 位與運算的複合賦值運算符,表示將左邊的變數與右邊的值進行 位與運算(bitwise AND),然後將結果賦值給左邊的變數。
|
||||
b[bitPos/8] &= ^(1 << (bitPos % 8))
|
||||
}
|
||||
|
||||
// IsTrue 檢查指定位置的 bit 是否為 true(1)。
|
||||
// 參數 bitPos 是要檢查的位的位置(以 0 為基準的位索引)。
|
||||
// 如果該 bit 是 1,則返回 true;否則返回 false。
|
||||
func (b Bitmap) IsTrue(bitPos uint32) bool {
|
||||
/*
|
||||
這一行程式碼 b[bitPos/8]&(1<<(bitPos%8)) != 0 是用來檢查 指定位(bit) 是否為 true(1),
|
||||
它的核心是位運算。讓我們逐步拆解並解釋這一行程式碼:
|
||||
|
||||
1. 背景知識:
|
||||
|
||||
• 位運算 是在二進制層面操作數字。每個 byte 有 8 個位(bit),所以位圖結構是以 byte 來表示位的集合。
|
||||
• b 是一個 Bitmap 結構,也就是 []byte,即 byte 的切片。
|
||||
• bitPos 是一個 uint32 類型的變數,表示我們想要檢查的位(bit)在整個位圖中的索引(位置)。
|
||||
3. 完整流程舉例:
|
||||
假設:
|
||||
• b = []byte{0b10101010, 0b01010101} (即二進制表示的兩個 byte,分別是 10101010 和 01010101)。
|
||||
• bitPos = 10(我們要檢查第 10 位是否為 1)。
|
||||
操作順序:
|
||||
|
||||
1. 計算 bitPos/8 = 10/8 = 1,所以我們要檢查的是第二個 byte:0b01010101。
|
||||
2. 計算 bitPos%8 = 10%8 = 2,所以我們要檢查的是該 byte 中的第 3 位(從右數起第 3 位)。
|
||||
3. 位移:1 << 2 = 00000100。
|
||||
4. 位與:0b01010101 & 0b00000100 = 0b00000100(因為該 byte 的第 3 位是 1,結果不等於 0)。
|
||||
5. 判斷結果:結果不等於 0,因此第 10 位是 1(true)。
|
||||
|
||||
4. 總結:
|
||||
|
||||
• b[bitPos/8]&(1<<(bitPos%8)) != 0 是一個經典的位操作,用來檢查位圖中某一個位是否為 1。
|
||||
• bitPos/8 找到對應的 byte,bitPos % 8 找到該位在這個 byte 中的具體位置。
|
||||
• 最後的位與運算和比較用來確定該位的狀態是 true(1)還是 false(0)。
|
||||
*/
|
||||
return b[bitPos/8]&(1<<(bitPos%8)) != 0
|
||||
}
|
||||
|
||||
// Reset 重置 Bitmap,使所有的 bit 都設置為 false(0)。
|
||||
// 這個操作會將整個 Bitmap 的所有 byte 都設置為 0,從而達到重置的效果。
|
||||
func (b Bitmap) Reset() {
|
||||
// 迭代 Bitmap 中的每個 byte,並將其設置為 0
|
||||
for i := range b {
|
||||
b[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// ByteSize 返回 Bitmap 的 byte 長度。
|
||||
// 這個函數返回 Bitmap 目前占用的 byte 數量,該值等於 Bitmap 的長度(slice 的長度)。
|
||||
func (b Bitmap) ByteSize() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
// BitSize 返回 Bitmap 的位(bit)長度。
|
||||
// 這個函數通過將 byte 長度乘以 8 來計算 Bitmap 中的總位數。
|
||||
func (b Bitmap) BitSize() int {
|
||||
// 每個 byte 包含 8 個 bit,因此將 byte 長度乘以 8
|
||||
return len(b) * 8
|
||||
}
|
||||
|
||||
// Resize 重新調整 Bitmap 的大小,將其擴展為指定的 bit 大小。
|
||||
// 原來的數據會被保留,新增加的部分位將初始化為 0。
|
||||
// 參數 newBitSize 是 Bitmap 需要擴展到的位大小。
|
||||
func (b Bitmap) Resize(newBitSize int) Bitmap {
|
||||
newByteSize := (newBitSize + 7) / 8
|
||||
if newByteSize <= len(b) {
|
||||
// 如果新大小比原大小小或相等,不做任何操作,直接返回原 Bitmap
|
||||
return b
|
||||
}
|
||||
|
||||
// 創建新的 Bitmap
|
||||
newBitmap := make([]byte, newByteSize)
|
||||
|
||||
// 將原 Bitmap 複製到新 Bitmap 中
|
||||
copy(newBitmap, b)
|
||||
|
||||
// 返回新的 Bitmap
|
||||
return newBitmap
|
||||
}
|
||||
|
||||
// UpdateFrom 會將傳入的 Bitmap 的值更新到當前 Bitmap 中。
|
||||
// 如果傳入的 Bitmap 大於當前 Bitmap,則當前 Bitmap 會自動擴展並保存新 Bitmap 的數據。
|
||||
// 如果傳入的 Bitmap 小於當前 Bitmap,僅更新前面部分的數據。
|
||||
func (b Bitmap) UpdateFrom(newBitmap Bitmap) Bitmap {
|
||||
// 如果 newBitmap 比當前 Bitmap 長,則擴展當前 Bitmap 的大小
|
||||
if len(newBitmap) > len(b) {
|
||||
// 創建一個擴展過的 Bitmap
|
||||
expandedBitmap := make([]byte, len(newBitmap))
|
||||
copy(expandedBitmap, b) // 將當前 Bitmap 的數據複製到擴展的 Bitmap 中
|
||||
b = expandedBitmap // 更新當前 Bitmap 的引用
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// SetAllTrue 將 Bitmap 中的所有位設置為 true(1)。
|
||||
func (b Bitmap) SetAllTrue() Bitmap {
|
||||
// 將 Bitmap 中的每個 byte 設置為 0xFF,表示所有 bit 都為 1
|
||||
for i := range b {
|
||||
b[i] = 0xFF
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// SetAllFalse 將 Bitmap 中的所有位設置為 false(0)。
|
||||
func (b Bitmap) SetAllFalse() Bitmap {
|
||||
// 將 Bitmap 中的每個 byte 設置為 0,表示所有 bit 都為 0
|
||||
for i := range b {
|
||||
b[i] = 0
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package usecase
|
||||
|
||||
import "testing"
|
||||
|
||||
// 基準測試 SetTrue 函數,測試在不同大小的 Bitmap 上設置位元為 true 的效能
|
||||
func BenchmarkBitmapSetTrue(b *testing.B) {
|
||||
// 以 10^6 位元作為基準測試的 Bitmap 大小
|
||||
bitmap := MakeBitmapWithBitSize(1000000)
|
||||
b.ResetTimer() // 重設計時器,排除初始化的時間
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
bitmap.SetTrue(uint32(i % 1000000)) // 設置位元為 true
|
||||
}
|
||||
}
|
||||
|
||||
// 基準測試 SetFalse 函數,測試在不同大小的 Bitmap 上清除位元為 false 的效能
|
||||
func BenchmarkBitmapSetFalse(b *testing.B) {
|
||||
// 以 10^6 位元作為基準測試的 Bitmap 大小
|
||||
bitmap := MakeBitmapWithBitSize(1000000)
|
||||
b.ResetTimer() // 重設計時器,排除初始化的時間
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
bitmap.SetFalse(uint32(i % 1000000)) // 清除位元為 false
|
||||
}
|
||||
}
|
||||
|
||||
// 基準測試 IsTrue 函數,測試在不同大小的 Bitmap 上檢查位元狀態的效能
|
||||
func BenchmarkBitmapIsTrue(b *testing.B) {
|
||||
// 以 10^6 位元作為基準測試的 Bitmap 大小
|
||||
bitmap := MakeBitmapWithBitSize(1000000)
|
||||
b.ResetTimer() // 重設計時器,排除初始化的時間
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = bitmap.IsTrue(uint32(i % 1000000)) // 檢查位元是否為 true
|
||||
}
|
||||
}
|
||||
|
||||
// 基準測試 Reset 函數,測試重置不同大小的 Bitmap 的效能
|
||||
func BenchmarkBitmapReset(b *testing.B) {
|
||||
// 以 10^6 位元作為基準測試的 Bitmap 大小
|
||||
bitmap := MakeBitmapWithBitSize(1000000)
|
||||
b.ResetTimer() // 重設計時器,排除初始化的時間
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
bitmap.Reset() // 重置 Bitmap
|
||||
}
|
||||
}
|
||||
|
||||
// 基準測試 BitSize 函數,測試返回位圖的 bit 長度的效能
|
||||
func BenchmarkBitmapBitSize(b *testing.B) {
|
||||
// 以 10^6 位元作為基準測試的 Bitmap 大小
|
||||
bitmap := MakeBitmapWithBitSize(1000000)
|
||||
b.ResetTimer() // 重設計時器,排除初始化的時間
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = bitmap.BitSize() // 測試返回位圖的 bit 長度
|
||||
}
|
||||
}
|
||||
|
||||
// 基準測試 ByteSize 函數,測試返回位圖的 byte 長度的效能
|
||||
func BenchmarkBitmapByteSize(b *testing.B) {
|
||||
// 以 10^6 位元作為基準測試的 Bitmap 大小
|
||||
bitmap := MakeBitmapWithBitSize(1000000)
|
||||
b.ResetTimer() // 重設計時器,排除初始化的時間
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = bitmap.ByteSize() // 測試返回位圖的 byte 長度
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBitmap_SetTrueAndIsTrue(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bitPos uint32
|
||||
expected bool
|
||||
}{
|
||||
{"Set bit 0 to true", 0, true},
|
||||
{"Set bit 1 to true", 1, true},
|
||||
{"Set bit 63 to true", 63, true},
|
||||
{"Set bit 64 to true", 64, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
bitmap := MakeBitmapWithBitSize(128) // 初始化一個 128 位的 Bitmap
|
||||
bitmap.SetTrue(tt.bitPos)
|
||||
result := bitmap.IsTrue(tt.bitPos)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmap_SetFalse(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bitPos uint32
|
||||
expected bool
|
||||
}{
|
||||
{"Set bit 0 to false", 0, false},
|
||||
{"Set bit 1 to false", 1, false},
|
||||
{"Set bit 63 to false", 63, false},
|
||||
{"Set bit 64 to false", 64, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
bitmap := MakeBitmapWithBitSize(128) // 初始化一個 128 位的 Bitmap
|
||||
bitmap.SetTrue(tt.bitPos) // 先設置該 bit 為 true
|
||||
bitmap.SetFalse(tt.bitPos) // 然後設置該 bit 為 false
|
||||
result := bitmap.IsTrue(tt.bitPos)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmap_Reset(t *testing.T) {
|
||||
bitmap := MakeBitmapWithBitSize(128) // 初始化一個 128 位的 Bitmap
|
||||
bitmap.SetTrue(0)
|
||||
bitmap.SetTrue(64)
|
||||
|
||||
// 確認 bit 0 和 bit 64 是 true
|
||||
assert.True(t, bitmap.IsTrue(0))
|
||||
assert.True(t, bitmap.IsTrue(64))
|
||||
|
||||
bitmap.Reset() // 重置位圖
|
||||
|
||||
// 確認所有的位都已經重置為 false
|
||||
assert.False(t, bitmap.IsTrue(0))
|
||||
assert.False(t, bitmap.IsTrue(64))
|
||||
}
|
||||
|
||||
func TestBitmap_ByteSize(t *testing.T) {
|
||||
bitmap := MakeBitmapWithBitSize(64) // 初始化一個 64 位的 Bitmap
|
||||
assert.Equal(t, 8, bitmap.ByteSize()) // 64 位應該佔用 8 個 byte
|
||||
}
|
||||
|
||||
func TestBitmap_BitSize(t *testing.T) {
|
||||
bitmap := MakeBitmapWithBitSize(128) // 初始化一個 128 位的 Bitmap
|
||||
assert.Equal(t, 128, bitmap.BitSize()) // 128 位應該有 128 個 bit
|
||||
}
|
||||
|
||||
func TestBitmap_Resize(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
initialSize int
|
||||
newBitSize int
|
||||
expectedLen int
|
||||
}{
|
||||
{"Resize to larger size", 64, 128, 16},
|
||||
{"Resize to smaller size", 128, 64, 16}, // 大小應保持不變
|
||||
{"Resize to equal size", 64, 64, 8}, // 大小應保持不變
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// 初始化一個 Bitmap
|
||||
bitmap := MakeBitmapWithBitSize(tt.initialSize)
|
||||
|
||||
// 調用 Resize
|
||||
resizedBitmap := bitmap.Resize(tt.newBitSize)
|
||||
|
||||
// 檢查結果的 byte 大小
|
||||
assert.Equal(t, tt.expectedLen, len(resizedBitmap))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmap_UpdateFrom(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
initialSize int
|
||||
newBitmapSize int
|
||||
expectedBitPos uint32
|
||||
expectedResult bool
|
||||
}{
|
||||
{"Update to larger bitmap", 64, 128, 50, true},
|
||||
{"Update to smaller bitmap", 128, 64, 50, true}, // 新的 Bitmap 將只更新前面部分
|
||||
{"Update to equal size bitmap", 64, 64, 20, true}, // 將相同大小的 Bitmap 進行合併
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// 初始化一個初始大小的 Bitmap
|
||||
bitmap := MakeBitmapWithBitSize(tt.initialSize)
|
||||
bitmap.SetTrue(tt.expectedBitPos)
|
||||
|
||||
// 初始化一個新的 Bitmap
|
||||
newBitmap := MakeBitmapWithBitSize(tt.newBitmapSize)
|
||||
newBitmap.SetTrue(tt.expectedBitPos)
|
||||
|
||||
// 更新 Bitmap
|
||||
updatedBitmap := bitmap.UpdateFrom(newBitmap)
|
||||
|
||||
// 檢查預期的位是否為 true
|
||||
result := updatedBitmap.IsTrue(tt.expectedBitPos)
|
||||
assert.Equal(t, tt.expectedResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmap_SetAllTrueAndSetAllFalse(t *testing.T) {
|
||||
bitmap := MakeBitmapWithBitSize(128)
|
||||
|
||||
// 測試 SetAllTrue
|
||||
bitmap.SetAllTrue()
|
||||
for i := 0; i < bitmap.BitSize(); i++ {
|
||||
if !bitmap.IsTrue(uint32(i)) {
|
||||
t.Errorf("Expected bit %d to be true, but got false", i)
|
||||
}
|
||||
}
|
||||
|
||||
// 測試 SetAllFalse
|
||||
bitmap.SetAllFalse()
|
||||
for i := 0; i < bitmap.BitSize(); i++ {
|
||||
if bitmap.IsTrue(uint32(i)) {
|
||||
t.Errorf("Expected bit %d to be false, but got true", i)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
module code.30cm.net/digimon/library-go/utils/bitmap
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require github.com/stretchr/testify v1.9.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -1,16 +0,0 @@
|
|||
package usecase
|
||||
|
||||
type BitMapUseCase interface {
|
||||
// SetTrue 設定該 Bit 狀態為 true
|
||||
SetTrue(bitPos uint32)
|
||||
// SetFalse 設定該Bit 狀態為 false
|
||||
SetFalse(bitPos uint32)
|
||||
// IsTrue 確認是否為真
|
||||
IsTrue(bitPos uint32) bool
|
||||
// Reset 重設 BitMap
|
||||
Reset()
|
||||
// ByteSize 最大 Byte 數
|
||||
ByteSize() int
|
||||
// BitSize 最大 Byte * 8
|
||||
BitSize() int
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package invited_code
|
||||
|
||||
const (
|
||||
DefaultCodeLen = 8
|
||||
InitAutoID = 10000000
|
||||
)
|
||||
|
||||
var ConvertTable = []string{
|
||||
"O", "D", "W", "X", "Y",
|
||||
"G", "B", "C", "H", "E",
|
||||
"F", "A", "Q", "I", "J",
|
||||
"L", "M", "N", "Z", "K",
|
||||
"P", "V", "R", "S", "T",
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package invited_code
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Converter struct {
|
||||
Base int
|
||||
Length int
|
||||
ConvertTable []string
|
||||
}
|
||||
|
||||
func (c *Converter) EncodeFromNum(id int64) (string, error) {
|
||||
code, err := generateCode(id, c.Base, c.Length, c.ConvertTable)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return code, nil
|
||||
}
|
||||
|
||||
func (c *Converter) DecodeFromCode(code string) (int64, error) {
|
||||
var result int64 = 0
|
||||
length := len(code)
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
char := string(code[i])
|
||||
index := -1
|
||||
for j, v := range c.ConvertTable {
|
||||
if v == char {
|
||||
index = j
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if index >= 0 {
|
||||
result = result*int64(c.Base) + int64(index)
|
||||
} else {
|
||||
return 0, fmt.Errorf("character not found in convert table")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// generateCode 從 UID 生成 referralCode
|
||||
func generateCode(id int64, base int, length int, convertTable []string) (string, error) {
|
||||
maxReferralUIDBoundary := int64(math.Pow(float64(len(ConvertTable)), float64(DefaultCodeLen)))
|
||||
if id > maxReferralUIDBoundary {
|
||||
return "", fmt.Errorf("encode out of range")
|
||||
}
|
||||
|
||||
encoded := encodeToBase(id, base, length, convertTable)
|
||||
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
func encodeToBase(num int64, base int, length int, convertTable []string) string {
|
||||
result := ""
|
||||
for num > 0 {
|
||||
index := num % int64(base)
|
||||
result = convertTable[index] + result
|
||||
num /= int64(base)
|
||||
}
|
||||
|
||||
if len(result) < length {
|
||||
result = strings.Repeat(convertTable[0], length-len(result)) + result
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func MustConverter(base int, length int, convertTable []string) ConvertUseCase {
|
||||
return &Converter{
|
||||
Base: base,
|
||||
Length: length,
|
||||
ConvertTable: convertTable,
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
package invited_code
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// 測試 ConvertUseCase 的功能
|
||||
func TestConverter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
id int64
|
||||
base int
|
||||
length int
|
||||
wantCode string
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "Test Case 1: Valid ID 1000000",
|
||||
id: 10000000,
|
||||
base: 10,
|
||||
length: 7,
|
||||
wantCode: "DOOOOOOO",
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Test Case 2: Valid ID 12345678",
|
||||
id: 12345678,
|
||||
base: 10,
|
||||
length: 8,
|
||||
wantCode: "DWXYGBCH",
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Test Case 3: Valid ID 98765432",
|
||||
id: 98765432,
|
||||
base: 10,
|
||||
length: 8,
|
||||
wantCode: "EHCBGYXW",
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Test Case 4: ID too large",
|
||||
id: 10000000000000001, // ID 超過界限
|
||||
base: 10,
|
||||
length: 8,
|
||||
wantCode: "",
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
||||
converter := MustConverter(10, 8, ConvertTable)
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
code, err := converter.EncodeFromNum(tt.id)
|
||||
|
||||
if tt.wantError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantCode, code)
|
||||
}
|
||||
|
||||
if !tt.wantError {
|
||||
// 測試解碼
|
||||
decodedID, err := converter.DecodeFromCode(code)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.id, decodedID)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeFromCode(t *testing.T) {
|
||||
converter := MustConverter(10, 8, ConvertTable)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
code string
|
||||
wantID int64
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "Decode valid code 1",
|
||||
code: "DOOOOOOO", // 對應於 id 10000000
|
||||
wantID: 10000000,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Decode valid code 2",
|
||||
code: "DWXYGBCH", // 對應於 id 12345678
|
||||
wantID: 12345678,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Decode valid code 3",
|
||||
code: "EHCBGYXW", // 對應於 id 98765432
|
||||
wantID: 98765432,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Decode invalid code with character not in table",
|
||||
code: "UWOXZZZ", // 包含 ZZZ,不在轉換表中
|
||||
wantID: 0,
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := converter.DecodeFromCode(tt.code)
|
||||
|
||||
if tt.wantError {
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, int64(0), result)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantID, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
module code.30cm.net/digimon/library-go/utils/invited_code
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require github.com/stretchr/testify v1.9.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -1,6 +0,0 @@
|
|||
package invited_code
|
||||
|
||||
type ConvertUseCase interface {
|
||||
EncodeFromNum(id int64) (string, error)
|
||||
DecodeFromCode(code string) (int64, error)
|
||||
}
|
Loading…
Reference in New Issue