mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-04 10:13:53 +08:00
Initial submission of data desensitization strategy backend
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/module/service"
|
||||||
|
"github.com/APIParkLab/APIPark/module/strategy"
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ IStrategyController = (*imlStrategyController)(nil)
|
||||||
|
|
||||||
|
type imlStrategyController struct {
|
||||||
|
strategyModule strategy.IStrategyModule `autowired:""`
|
||||||
|
serviceModule service.IServiceModule `autowired:""`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) GetStrategy(ctx *gin.Context, id string) (*strategy_dto.Strategy, error) {
|
||||||
|
return i.strategyModule.Get(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) search(ctx *gin.Context, keyword string, scope strategy_dto.Scope, target string, driver string, page string, pageSize string, order string, sort string, filters string) ([]*strategy_dto.StrategyItem, int64, error) {
|
||||||
|
p, err := strconv.Atoi(page)
|
||||||
|
if err != nil {
|
||||||
|
if page != "" {
|
||||||
|
return nil, 0, fmt.Errorf("page error: %s", err)
|
||||||
|
}
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
ps, err := strconv.Atoi(pageSize)
|
||||||
|
if err != nil {
|
||||||
|
if pageSize != "" {
|
||||||
|
return nil, 0, fmt.Errorf("page size error: %s", err)
|
||||||
|
}
|
||||||
|
ps = 20
|
||||||
|
}
|
||||||
|
ss := make([]string, 0)
|
||||||
|
json.Unmarshal([]byte(sort), &ss)
|
||||||
|
fs := make([]string, 0)
|
||||||
|
json.Unmarshal([]byte(filters), &fs)
|
||||||
|
list, total, err := i.strategyModule.Search(ctx, keyword, driver, scope, target, p, ps, fs, ss...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return list, total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) GlobalStrategyList(ctx *gin.Context, keyword string, driver string, page string, pageSize string, order string, sort string, filters string) ([]*strategy_dto.StrategyItem, int64, error) {
|
||||||
|
|
||||||
|
return i.search(ctx, keyword, strategy_dto.ToScope(strategy_dto.ScopeSystem), "", driver, page, pageSize, order, sort, filters)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) CreateGlobalStrategy(ctx *gin.Context, driver string, input *strategy_dto.Create) error {
|
||||||
|
input.Driver = driver
|
||||||
|
input.Scope = strategy_dto.ToScope(strategy_dto.ScopeSystem)
|
||||||
|
|
||||||
|
return i.strategyModule.Create(ctx, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) PublishGlobalStrategy(ctx *gin.Context) error {
|
||||||
|
return i.strategyModule.Publish(ctx, strategy_dto.ScopeSystem, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) ServiceStrategyList(ctx *gin.Context, keyword string, serviceId string, driver string, page string, pageSize string, order string, sort string, filters string) ([]*strategy_dto.StrategyItem, int64, error) {
|
||||||
|
|
||||||
|
return i.search(ctx, keyword, strategy_dto.ToScope(strategy_dto.ScopeService), serviceId, driver, page, pageSize, order, sort, filters)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) CreateServiceStrategy(ctx *gin.Context, serviceId string, driver string, input *strategy_dto.Create) error {
|
||||||
|
_, err := i.serviceModule.Get(ctx, serviceId)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("create service strategy error: %s", err)
|
||||||
|
}
|
||||||
|
input.Driver = driver
|
||||||
|
input.Scope = strategy_dto.ToScope(strategy_dto.ScopeService)
|
||||||
|
input.Target = serviceId
|
||||||
|
|
||||||
|
return i.strategyModule.Create(ctx, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) EditStrategy(ctx *gin.Context, id string, input *strategy_dto.Edit) error {
|
||||||
|
return i.EditStrategy(ctx, id, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) EnableStrategy(ctx *gin.Context, id string) error {
|
||||||
|
return i.EnableStrategy(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) DisableStrategy(ctx *gin.Context, id string) error {
|
||||||
|
return i.strategyModule.Disable(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyController) DeleteStrategy(ctx *gin.Context, id string) error {
|
||||||
|
return i.strategyModule.Delete(ctx, id)
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
"github.com/eolinker/go-common/autowire"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IStrategyController interface {
|
||||||
|
GlobalStrategyList(ctx *gin.Context, keyword string, driver string, page string, pageSize string, order string, sort string, filters string) ([]*strategy_dto.StrategyItem, int64, error)
|
||||||
|
CreateGlobalStrategy(ctx *gin.Context, driver string, input *strategy_dto.Create) error
|
||||||
|
PublishGlobalStrategy(ctx *gin.Context) error
|
||||||
|
|
||||||
|
ServiceStrategyList(ctx *gin.Context, keyword string, serviceId string, driver string, page string, pageSize string, order string, sort string, filters string) ([]*strategy_dto.StrategyItem, int64, error)
|
||||||
|
CreateServiceStrategy(ctx *gin.Context, serviceId string, driver string, input *strategy_dto.Create) error
|
||||||
|
|
||||||
|
EditStrategy(ctx *gin.Context, id string, input *strategy_dto.Edit) error
|
||||||
|
GetStrategy(ctx *gin.Context, id string) (*strategy_dto.Strategy, error)
|
||||||
|
EnableStrategy(ctx *gin.Context, id string) error
|
||||||
|
DisableStrategy(ctx *gin.Context, id string) error
|
||||||
|
|
||||||
|
DeleteStrategy(ctx *gin.Context, id string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type IStrategyCommonController interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
autowire.Auto[IStrategyController](func() reflect.Value {
|
||||||
|
return reflect.ValueOf(&imlStrategyController{})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package data_masking
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Rules []*Rule `json:"rules"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Rule struct {
|
||||||
|
Match *BasicItem `json:"match"`
|
||||||
|
Mask *Mask `json:"mask"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BasicItem struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mask struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Begin int `json:"begin"`
|
||||||
|
Length int `json:"length"`
|
||||||
|
Replace *BasicItem `json:"replace"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package data_masking
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
strategy_driver "github.com/APIParkLab/APIPark/module/strategy/driver"
|
||||||
|
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
strategy_driver.Register(&strategyDriver{confName: "data_mask"})
|
||||||
|
}
|
||||||
|
|
||||||
|
type strategyDriver struct {
|
||||||
|
confName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *strategyDriver) Driver() string {
|
||||||
|
return "data-masking"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *strategyDriver) ToApinto(s strategy_dto.Strategy) interface{} {
|
||||||
|
filters := make(map[string][]string)
|
||||||
|
|
||||||
|
for _, f := range s.Filters {
|
||||||
|
filters[f.Name] = f.Values
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]interface{}{
|
||||||
|
"name": s.Filters,
|
||||||
|
"description": s.Desc,
|
||||||
|
"priority": s.Priority,
|
||||||
|
"filters": filters,
|
||||||
|
d.confName: s.Config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *strategyDriver) Check(config interface{}) error {
|
||||||
|
if config == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var cfg Config
|
||||||
|
err = json.Unmarshal(data, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, r := range cfg.Rules {
|
||||||
|
if r.Match == nil {
|
||||||
|
return errors.New("match can't be null. ")
|
||||||
|
}
|
||||||
|
if r.Mask == nil {
|
||||||
|
return errors.New("mask can't be null. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := validMatchTypes[r.Match.Type]; !ok {
|
||||||
|
return fmt.Errorf("match type %s is illegal. ", r.Match.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Match.Type == "inner" {
|
||||||
|
if _, ok := validMatchInnerValues[r.Match.Value]; !ok {
|
||||||
|
return fmt.Errorf("match value %s is illegal. ", r.Match.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, ok := validMaskTypes[r.Mask.Type]; !ok {
|
||||||
|
return fmt.Errorf("mask type %s is illegal. ", r.Mask.Type)
|
||||||
|
}
|
||||||
|
if r.Mask.Replace != nil {
|
||||||
|
if _, ok := validReplaceTypes[r.Mask.Replace.Type]; !ok {
|
||||||
|
return fmt.Errorf("replace type %s is illegal. ", r.Mask.Replace.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package data_masking
|
||||||
|
|
||||||
|
var validMatchInnerValues = map[string]struct{}{
|
||||||
|
"name": {},
|
||||||
|
"phone": {},
|
||||||
|
"email": {},
|
||||||
|
"id-card": {},
|
||||||
|
"bank-card": {},
|
||||||
|
"date": {},
|
||||||
|
"amount": {},
|
||||||
|
}
|
||||||
|
var validMatchTypes = map[string]struct{}{
|
||||||
|
"inner": {},
|
||||||
|
"keyword": {},
|
||||||
|
"regex": {},
|
||||||
|
"json_path": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var validMaskTypes = map[string]struct{}{
|
||||||
|
"partial-display": {},
|
||||||
|
"partial-masking": {},
|
||||||
|
"truncation": {},
|
||||||
|
"replacement": {},
|
||||||
|
"shuffling": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var validReplaceTypes = map[string]struct{}{
|
||||||
|
"random": {},
|
||||||
|
"custom": {},
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package strategy_driver
|
||||||
|
|
||||||
|
import (
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IStrategyDriver interface {
|
||||||
|
Driver() string
|
||||||
|
ToApinto(strategy strategy_dto.Strategy) interface{}
|
||||||
|
Check(config interface{}) error
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package strategy_driver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterOptionsItem struct {
|
||||||
|
Name string
|
||||||
|
Title string
|
||||||
|
Type string
|
||||||
|
Pattern *regexp.Regexp
|
||||||
|
Options []string
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
FilterMethod = "method"
|
||||||
|
FilterPath = "path"
|
||||||
|
FilterIP = "ip"
|
||||||
|
FilterApplication = "application"
|
||||||
|
FilterApi = "api"
|
||||||
|
FilterService = "service"
|
||||||
|
FilterAppKey = "appkey"
|
||||||
|
|
||||||
|
FilterTypeRemote = "remote"
|
||||||
|
FilterTypePattern = "pattern"
|
||||||
|
FilterTypeStatic = "static"
|
||||||
|
|
||||||
|
FilterValuesALL = "ALL"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ApiPathRegexp = `^\*?[\w-/]+\*?$`
|
||||||
|
CIDRIpv4Exp = `^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([1-9]|[1-2]\d|3[0-2]))?$`
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HttpALL = "ALL"
|
||||||
|
HttpGET = "GET"
|
||||||
|
HttpPOST = "POST"
|
||||||
|
HttpPUT = "PUT"
|
||||||
|
HttpDELETE = "DELETE"
|
||||||
|
HttpPATCH = "PATCH"
|
||||||
|
HttpHEADER = "HEADER"
|
||||||
|
HttpOPTIONS = "OPTIONS"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
staticOptions = []*FilterOptionsItem{
|
||||||
|
{
|
||||||
|
Name: FilterMethod,
|
||||||
|
Title: "API请求方式",
|
||||||
|
Type: FilterTypeStatic,
|
||||||
|
Options: []string{HttpALL, HttpGET, HttpPOST, HttpPUT, HttpDELETE, HttpPATCH, HttpHEADER, HttpOPTIONS},
|
||||||
|
}, {
|
||||||
|
Name: FilterPath,
|
||||||
|
Title: "API路径",
|
||||||
|
Type: FilterTypePattern,
|
||||||
|
Pattern: regexp.MustCompile(ApiPathRegexp),
|
||||||
|
}, {
|
||||||
|
Name: FilterIP,
|
||||||
|
Title: "IP",
|
||||||
|
Type: FilterTypePattern,
|
||||||
|
Pattern: regexp.MustCompile(CIDRIpv4Exp),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
globalFilters = map[string]struct{}{}
|
||||||
|
serviceFilters = map[string]struct{}{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
for _, option := range staticOptions {
|
||||||
|
globalFilters[option.Name] = struct{}{}
|
||||||
|
}
|
||||||
|
for _, option := range staticOptions {
|
||||||
|
serviceFilters[option.Name] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckFilters(name string, scope strategy_dto.Scope, filters []*strategy_dto.Filter) error {
|
||||||
|
var fs map[string]struct{}
|
||||||
|
switch scope.String() {
|
||||||
|
case strategy_dto.ScopeSystem:
|
||||||
|
fs = globalFilters
|
||||||
|
case strategy_dto.ScopeService:
|
||||||
|
fs = serviceFilters
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown scope %s", scope)
|
||||||
|
}
|
||||||
|
filterNameSet := make(map[string]struct{})
|
||||||
|
for _, filter := range filters {
|
||||||
|
_, ok := fs[filter.Name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%s filter %s not found", name, filter.Name)
|
||||||
|
}
|
||||||
|
if len(filter.Values) == 0 {
|
||||||
|
return fmt.Errorf("%s.Options can't be null. filter.Name:%s ", name, filter.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, has := filterNameSet[filter.Name]; has {
|
||||||
|
return fmt.Errorf("%s.Name %s is reduplicative. ", name, filter.Name)
|
||||||
|
}
|
||||||
|
filterNameSet[filter.Name] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionTitle struct {
|
||||||
|
Field string `json:"field"`
|
||||||
|
Title string `json:"title" aoi18n:""`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterOptionConfig struct {
|
||||||
|
Title string
|
||||||
|
Titles []OptionTitle
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IFilterOptionHandler interface {
|
||||||
|
Name() string
|
||||||
|
Config() FilterOptionConfig
|
||||||
|
GetOptions(keyword, conditions map[string]interface{}, pageNum, pageSize int) ([]any, int)
|
||||||
|
Labels(values ...string) []string
|
||||||
|
Label(value string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IFilterFactory interface {
|
||||||
|
GetHandler(name string) IFilterOptionHandler
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package strategy_driver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/eolinker/eosc"
|
||||||
|
)
|
||||||
|
|
||||||
|
var manager = newManager()
|
||||||
|
|
||||||
|
func newManager() *Manager {
|
||||||
|
return &Manager{
|
||||||
|
drivers: eosc.BuildUntyped[string, IStrategyDriver](),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Manager struct {
|
||||||
|
drivers eosc.Untyped[string, IStrategyDriver]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) AddDriver(driver IStrategyDriver) {
|
||||||
|
m.drivers.Set(driver.Driver(), driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetDriver(driver string) (IStrategyDriver, bool) {
|
||||||
|
return m.drivers.Get(driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetDrivers() []string {
|
||||||
|
return m.drivers.Keys()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) Delete(name string) {
|
||||||
|
m.drivers.Del(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDriver(name string) (IStrategyDriver, bool) {
|
||||||
|
return manager.GetDriver(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Register(driver IStrategyDriver) {
|
||||||
|
manager.AddDriver(driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckConfig(name string, config interface{}) error {
|
||||||
|
driver, has := manager.GetDriver(name)
|
||||||
|
if !has {
|
||||||
|
return fmt.Errorf("driver %s not found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return driver.Check(config)
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package strategy_dto
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScopeSystem = "system"
|
||||||
|
ScopeTeam = "team"
|
||||||
|
ScopeService = "service"
|
||||||
|
|
||||||
|
PublishStatusOnline = "online"
|
||||||
|
PublishStatusOffline = "offline"
|
||||||
|
PublishStatusUpdate = "update"
|
||||||
|
PublishStatusDelete = "delete"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Scope int
|
||||||
|
|
||||||
|
func (s Scope) String() string {
|
||||||
|
switch s {
|
||||||
|
case 0:
|
||||||
|
return ScopeSystem
|
||||||
|
case 1:
|
||||||
|
return ScopeTeam
|
||||||
|
case 2:
|
||||||
|
return ScopeService
|
||||||
|
default:
|
||||||
|
return ScopeSystem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Scope) Int() int {
|
||||||
|
return int(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToScope(s string) Scope {
|
||||||
|
switch s {
|
||||||
|
case ScopeSystem:
|
||||||
|
return 0
|
||||||
|
case ScopeTeam:
|
||||||
|
return 1
|
||||||
|
case ScopeService:
|
||||||
|
return 2
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package strategy_dto
|
||||||
|
|
||||||
|
type Create struct {
|
||||||
|
Scope Scope `json:"-"`
|
||||||
|
Target string `json:"-"`
|
||||||
|
Driver string `json:"-"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Filters []*Filter `json:"filters"`
|
||||||
|
Config interface{} `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Edit struct {
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Priority *int `json:"priority"`
|
||||||
|
Desc *string `json:"desc"`
|
||||||
|
Filters *[]*Filter `json:"filters"`
|
||||||
|
Config *interface{} `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Filter struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Values []string `json:"values"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package strategy_dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/strategy"
|
||||||
|
"github.com/eolinker/go-common/auto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ToStrategyItem(s *strategy.Strategy, publishVersion string) *StrategyItem {
|
||||||
|
publishStatus := PublishStatusOffline
|
||||||
|
if publishVersion != "" {
|
||||||
|
if s.IsDelete {
|
||||||
|
publishStatus = PublishStatusDelete
|
||||||
|
} else {
|
||||||
|
version := s.UpdateAt.Format("20060102150405")
|
||||||
|
if version != publishVersion {
|
||||||
|
publishStatus = PublishStatusUpdate
|
||||||
|
} else {
|
||||||
|
publishStatus = PublishStatusOnline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &StrategyItem{
|
||||||
|
Id: s.Id,
|
||||||
|
Name: s.Name,
|
||||||
|
Priority: 0,
|
||||||
|
Desc: s.Desc,
|
||||||
|
Filters: "",
|
||||||
|
Updater: auto.UUID(s.Updater),
|
||||||
|
UpdateTime: auto.TimeLabel(s.UpdateAt),
|
||||||
|
ProcessedTotal: 0,
|
||||||
|
PublishStatus: publishStatus,
|
||||||
|
IsStop: s.IsStop,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToStrategy(s *strategy.Strategy) *Strategy {
|
||||||
|
filters := make([]*Filter, 0)
|
||||||
|
json.Unmarshal([]byte(s.Filters), &filters)
|
||||||
|
var cfg interface{}
|
||||||
|
json.Unmarshal([]byte(s.Config), &cfg)
|
||||||
|
return &Strategy{
|
||||||
|
Id: s.Id,
|
||||||
|
Name: s.Name,
|
||||||
|
Priority: s.Priority,
|
||||||
|
Desc: s.Desc,
|
||||||
|
Filters: filters,
|
||||||
|
Config: cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Filters []*Filter `json:"filters"`
|
||||||
|
Config interface{} `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StrategyItem struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Filters string `json:"filters"`
|
||||||
|
Updater auto.Label `json:"updater" aolabel:"user"`
|
||||||
|
UpdateTime auto.TimeLabel `json:"update_time"`
|
||||||
|
ProcessedTotal int `json:"processed_total"`
|
||||||
|
PublishStatus string `json:"publish_status"`
|
||||||
|
IsStop bool `json:"is_stop"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/store"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/universally/commit"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/utils"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
|
strategy_driver "github.com/APIParkLab/APIPark/module/strategy/driver"
|
||||||
|
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/strategy"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ IStrategyModule = (*imlStrategyModule)(nil)
|
||||||
|
|
||||||
|
type imlStrategyModule struct {
|
||||||
|
strategyService strategy.IStrategyService `autowired:""`
|
||||||
|
transaction store.ITransaction `autowired:""`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Search(ctx context.Context, keyword string, driver string, scope strategy_dto.Scope, target string, page int, pageSize int, filters []string, order ...string) ([]*strategy_dto.StrategyItem, int64, error) {
|
||||||
|
list, total, err := i.strategyService.Search(ctx, keyword, driver, scope.Int(), target, page, pageSize, filters, order...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
strategyIds := utils.SliceToSlice(list, func(l *strategy.Strategy) string { return l.Id })
|
||||||
|
commits, err := i.strategyService.ListLatestStrategyCommit(ctx, scope.String(), target, strategyIds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
commitMap := utils.SliceToMapO(commits, func(c *commit.Commit[strategy.StrategyCommit]) (string, string) { return c.Key, c.Data.Version })
|
||||||
|
items := make([]*strategy_dto.StrategyItem, 0, len(list))
|
||||||
|
for _, l := range list {
|
||||||
|
item := strategy_dto.ToStrategyItem(l, commitMap[l.Id])
|
||||||
|
items = append(items, item)
|
||||||
|
}
|
||||||
|
return items, total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Get(ctx context.Context, id string) (*strategy_dto.Strategy, error) {
|
||||||
|
info, err := i.strategyService.Get(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return strategy_dto.ToStrategy(info), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Create(ctx context.Context, input *strategy_dto.Create) error {
|
||||||
|
if input.Name == "" {
|
||||||
|
return fmt.Errorf("name required")
|
||||||
|
}
|
||||||
|
if input.ID == "" {
|
||||||
|
input.ID = uuid.NewString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.Priority < 1 {
|
||||||
|
input.Priority = 1000
|
||||||
|
}
|
||||||
|
err := strategy_driver.CheckFilters(input.Driver, input.Scope, input.Filters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = strategy_driver.CheckConfig(input.Driver, input.Config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
filters, _ := json.Marshal(input.Filters)
|
||||||
|
cfg, _ := json.Marshal(input.Config)
|
||||||
|
return i.strategyService.Create(ctx, &strategy.Create{
|
||||||
|
Id: input.ID,
|
||||||
|
Name: input.Name,
|
||||||
|
Priority: input.Priority,
|
||||||
|
Desc: input.Desc,
|
||||||
|
Filters: string(filters),
|
||||||
|
Config: string(cfg),
|
||||||
|
Scope: input.Scope.Int(),
|
||||||
|
Target: input.Target,
|
||||||
|
Driver: input.Driver,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Edit(ctx context.Context, id string, input *strategy_dto.Edit) error {
|
||||||
|
if input.Name != nil && *input.Name == "" {
|
||||||
|
return fmt.Errorf("name required")
|
||||||
|
}
|
||||||
|
info, err := i.strategyService.Get(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if input.Priority != nil && *input.Priority < 1 {
|
||||||
|
*input.Priority = 1000
|
||||||
|
}
|
||||||
|
filters := info.Filters
|
||||||
|
if input.Filters != nil {
|
||||||
|
err = strategy_driver.CheckFilters(info.Driver, strategy_dto.Scope(info.Scope), *input.Filters)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, _ := json.Marshal(input.Filters)
|
||||||
|
filters = string(data)
|
||||||
|
}
|
||||||
|
cfg := info.Config
|
||||||
|
if input.Config != nil {
|
||||||
|
err = strategy_driver.CheckConfig(info.Driver, input.Config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, _ := json.Marshal(input.Config)
|
||||||
|
cfg = string(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return i.strategyService.Save(ctx, id, &strategy.Edit{
|
||||||
|
Name: input.Name,
|
||||||
|
Priority: input.Priority,
|
||||||
|
Desc: input.Desc,
|
||||||
|
Filters: &filters,
|
||||||
|
Config: &cfg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Enable(ctx context.Context, id string) error {
|
||||||
|
stop := false
|
||||||
|
return i.strategyService.Save(ctx, id, &strategy.Edit{IsStop: &stop})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Disable(ctx context.Context, id string) error {
|
||||||
|
stop := true
|
||||||
|
return i.strategyService.Save(ctx, id, &strategy.Edit{IsStop: &stop})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Publish(ctx context.Context, scope string, target string) error {
|
||||||
|
list, err := i.strategyService.AllByScope(ctx, strategy_dto.ToScope(scope).Int(), target)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return i.transaction.Transaction(ctx, func(txCtx context.Context) error {
|
||||||
|
for _, l := range list {
|
||||||
|
if l.IsDelete {
|
||||||
|
err = i.strategyService.Delete(ctx, l.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:同步到网关
|
||||||
|
err = i.strategyService.CommitStrategy(txCtx, scope, target, l.Id, l)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyModule) Delete(ctx context.Context, id string) error {
|
||||||
|
return i.strategyService.SortDelete(ctx, id)
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/autowire"
|
||||||
|
|
||||||
|
_ "github.com/APIParkLab/APIPark/module/strategy/driver/data-masking"
|
||||||
|
strategy_dto "github.com/APIParkLab/APIPark/module/strategy/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IStrategyModule interface {
|
||||||
|
Search(ctx context.Context, keyword string, driver string, scope strategy_dto.Scope, target string, page int, pageSize int, filters []string, order ...string) ([]*strategy_dto.StrategyItem, int64, error)
|
||||||
|
Get(ctx context.Context, id string) (*strategy_dto.Strategy, error)
|
||||||
|
Create(ctx context.Context, i *strategy_dto.Create) error
|
||||||
|
Edit(ctx context.Context, id string, i *strategy_dto.Edit) error
|
||||||
|
Enable(ctx context.Context, id string) error
|
||||||
|
Disable(ctx context.Context, id string) error
|
||||||
|
Publish(ctx context.Context, scope string, target string) error
|
||||||
|
Delete(ctx context.Context, id string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
strategyModule := new(imlStrategyModule)
|
||||||
|
autowire.Auto[IStrategyModule](func() reflect.Value {
|
||||||
|
return reflect.ValueOf(strategyModule)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/APIParkLab/APIPark/service/universally/commit"
|
"github.com/APIParkLab/APIPark/service/universally/commit"
|
||||||
"github.com/eolinker/go-common/utils"
|
"github.com/eolinker/go-common/utils"
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ type imlUpstreamModule struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *imlUpstreamModule) ExportAll(ctx context.Context) ([]*upstream_dto.ExportUpstream, error) {
|
func (i *imlUpstreamModule) ExportAll(ctx context.Context) ([]*upstream_dto.ExportUpstream, error) {
|
||||||
latestCommits, err := i.upstreamService.ListLatestCommit(ctx)
|
latestCommits, err := i.upstreamService.ListLatestCommit(ctx, cluster.DefaultClusterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ func (p *plugin) aiAPIs() []pm3.Api {
|
|||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.SimpleProviders),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.SimpleProviders),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/config", []string{"context", "query:provider"}, []string{"provider"}, p.aiProviderController.Provider, access.SystemSettingsAiProviderView),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/config", []string{"context", "query:provider"}, []string{"provider"}, p.aiProviderController.Provider, access.SystemSettingsAiProviderView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/llms", []string{"context", "query:provider"}, []string{"llms", "provider"}, p.aiProviderController.LLMs),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/llms", []string{"context", "query:provider"}, []string{"llms", "provider"}, p.aiProviderController.LLMs),
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/enable", []string{"context", "query:provider"}, nil, p.aiProviderController.Enable),
|
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/enable", []string{"context", "query:provider"}, nil, p.aiProviderController.isStop),
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/disable", []string{"context", "query:provider"}, nil, p.aiProviderController.Disable),
|
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/disable", []string{"context", "query:provider"}, nil, p.aiProviderController.Disable),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/config", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderConfig, access.SystemSettingsAiProviderManager),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/config", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderConfig, access.SystemSettingsAiProviderManager),
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/default-llm", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderDefaultLLM),
|
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/default-llm", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderDefaultLLM),
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/controller/strategy"
|
||||||
|
|
||||||
"github.com/APIParkLab/APIPark/controller/ai"
|
"github.com/APIParkLab/APIPark/controller/ai"
|
||||||
ai_api "github.com/APIParkLab/APIPark/controller/ai-api"
|
ai_api "github.com/APIParkLab/APIPark/controller/ai-api"
|
||||||
"github.com/APIParkLab/APIPark/controller/monitor"
|
"github.com/APIParkLab/APIPark/controller/monitor"
|
||||||
@@ -72,6 +74,7 @@ type plugin struct {
|
|||||||
aiAPIController ai_api.IAPIController `autowired:""`
|
aiAPIController ai_api.IAPIController `autowired:""`
|
||||||
apiDocController router.IAPIDocController `autowired:""`
|
apiDocController router.IAPIDocController `autowired:""`
|
||||||
subscribeController subscribe.ISubscribeController `autowired:""`
|
subscribeController subscribe.ISubscribeController `autowired:""`
|
||||||
|
strategyController strategy.IStrategyController `autowired:""`
|
||||||
appAuthorizationController application_authorization.IAuthorizationController `autowired:""`
|
appAuthorizationController application_authorization.IAuthorizationController `autowired:""`
|
||||||
releaseController release.IReleaseController `autowired:""`
|
releaseController release.IReleaseController `autowired:""`
|
||||||
roleController role.IRoleController `autowired:""`
|
roleController role.IRoleController `autowired:""`
|
||||||
@@ -105,6 +108,7 @@ func (p *plugin) OnComplete() {
|
|||||||
p.apis = append(p.apis, p.commonApis()...)
|
p.apis = append(p.apis, p.commonApis()...)
|
||||||
p.apis = append(p.apis, p.systemApis()...)
|
p.apis = append(p.apis, p.systemApis()...)
|
||||||
p.apis = append(p.apis, p.aiAPIs()...)
|
p.apis = append(p.apis, p.aiAPIs()...)
|
||||||
|
p.apis = append(p.apis, p.strategyApis()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *plugin) Name() string {
|
func (p *plugin) Name() string {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/pm3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *plugin) strategyApis() []pm3.Api {
|
||||||
|
return []pm3.Api{
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/strategy/global/:driver/list", []string{"context", "query:keyword", "rest:driver", "query:page", "query:page_size", "query:order", "query:sort", "query:filters"}, []string{"list", "total"}, p.strategyController.GlobalStrategyList),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/strategy/global/:driver", []string{"context", "query:strategy"}, []string{"strategy"}, p.strategyController.GetStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/strategy/global/:driver", []string{"context", "rest:driver", "body"}, nil, p.strategyController.CreateGlobalStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/strategy/global/:driver", []string{"context", "query:strategy", "body"}, nil, p.strategyController.EditStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/strategy/global/:driver", []string{"context", "query:strategy"}, nil, p.strategyController.DeleteStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/strategy/global/:driver/enable", []string{"context", "query:strategy"}, nil, p.strategyController.EnableStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/strategy/global/:driver/disable", []string{"context", "query:strategy"}, nil, p.strategyController.DisableStrategy),
|
||||||
|
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/strategy/service/:driver/list", []string{"context", "query:keyword", "query:service", "rest:driver", "query:page", "query:page_size", "query:order", "query:sort", "query:filters"}, []string{"list", "total"}, p.strategyController.ServiceStrategyList),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/strategy/service/:driver", []string{"context", "query:strategy"}, []string{"strategy"}, p.strategyController.GetStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/strategy/service/:driver", []string{"context", "query:service", "rest:driver", "body"}, nil, p.strategyController.CreateServiceStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/strategy/service/:driver/enable", []string{"context", "query:strategy"}, nil, p.strategyController.EnableStrategy),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/strategy/service/:driver/disable", []string{"context", "query:strategy"}, nil, p.strategyController.DisableStrategy),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/universally/commit"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/utils"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/universally"
|
||||||
|
"github.com/APIParkLab/APIPark/stores/strategy"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ IStrategyService = (*imlStrategyService)(nil)
|
||||||
|
|
||||||
|
type imlStrategyService struct {
|
||||||
|
store strategy.IStrategyStore `autowired:""`
|
||||||
|
commitService commit.ICommitService[StrategyCommit] `autowired:""`
|
||||||
|
universally.IServiceCreate[Create]
|
||||||
|
universally.IServiceEdit[Edit]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) AllByScope(ctx context.Context, scope int, target string) ([]*Strategy, error) {
|
||||||
|
w := make(map[string]interface{})
|
||||||
|
w["scope"] = scope
|
||||||
|
if target != "" {
|
||||||
|
w["target"] = target
|
||||||
|
}
|
||||||
|
list, err := i.store.List(ctx, w)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return utils.SliceToSlice(list, FromEntity), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) CommitStrategy(ctx context.Context, scope string, target string, strategyId string, data *Strategy) error {
|
||||||
|
key := scope
|
||||||
|
if target != "" {
|
||||||
|
key = fmt.Sprintf("%s-%s", scope, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
return i.commitService.Save(ctx, strategyId, key, &StrategyCommit{
|
||||||
|
Id: data.Id,
|
||||||
|
Name: data.Name,
|
||||||
|
Priority: data.Priority,
|
||||||
|
Filters: data.Filters,
|
||||||
|
Config: data.Config,
|
||||||
|
Driver: data.Driver,
|
||||||
|
IsStop: data.IsStop,
|
||||||
|
Version: data.UpdateAt.Format("20060102150405"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) GetStrategyCommit(ctx context.Context, commitId string) (*commit.Commit[StrategyCommit], error) {
|
||||||
|
return i.commitService.Get(ctx, commitId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) LatestStrategyCommit(ctx context.Context, scope string, target string, strategyId string) (*commit.Commit[StrategyCommit], error) {
|
||||||
|
key := scope
|
||||||
|
if target != "" {
|
||||||
|
key = fmt.Sprintf("%s-%s", scope, target)
|
||||||
|
}
|
||||||
|
return i.commitService.Latest(ctx, strategyId, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) ListLatestStrategyCommit(ctx context.Context, scope string, target string, strategyIds ...string) ([]*commit.Commit[StrategyCommit], error) {
|
||||||
|
key := scope
|
||||||
|
if target != "" {
|
||||||
|
key = fmt.Sprintf("%s-%s", scope, target)
|
||||||
|
}
|
||||||
|
return i.commitService.ListLatest(ctx, key, strategyIds...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) ListStrategyCommit(ctx context.Context, commitIds ...string) ([]*commit.Commit[StrategyCommit], error) {
|
||||||
|
if len(commitIds) < 1 {
|
||||||
|
return nil, fmt.Errorf("commit ids is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
return i.commitService.List(ctx, commitIds...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) Search(ctx context.Context, keyword string, driver string, scope int, target string, page int, pageSize int, filters []string, order ...string) ([]*Strategy, int64, error) {
|
||||||
|
w := map[string]interface{}{
|
||||||
|
"scope": scope,
|
||||||
|
"driver": driver,
|
||||||
|
}
|
||||||
|
if target != "" {
|
||||||
|
w["target"] = target
|
||||||
|
}
|
||||||
|
for _, f := range filters {
|
||||||
|
switch f {
|
||||||
|
case "enable":
|
||||||
|
w["enable"] = true
|
||||||
|
case "disable":
|
||||||
|
w["enable"] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(order) < 1 {
|
||||||
|
order = []string{"update_at desc"}
|
||||||
|
}
|
||||||
|
list, total, err := i.store.SearchByPage(ctx, keyword, w, page, pageSize, order...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
return utils.SliceToSlice(list, FromEntity), total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) Get(ctx context.Context, id string) (*Strategy, error) {
|
||||||
|
info, err := i.store.GetByUUID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return FromEntity(info), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) SortDelete(ctx context.Context, id string) error {
|
||||||
|
return i.store.SoftDelete(ctx, map[string]interface{}{"uuid": id})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) Delete(ctx context.Context, id ...string) error {
|
||||||
|
if len(id) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err := i.store.DeleteWhere(ctx, map[string]interface{}{"uuid": id})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *imlStrategyService) OnComplete() {
|
||||||
|
|
||||||
|
i.IServiceCreate = universally.NewCreator[Create, strategy.Strategy](i.store, "strategy", createEntityHandler, uniquestHandler, labelHandler)
|
||||||
|
|
||||||
|
i.IServiceEdit = universally.NewEdit[Edit, strategy.Strategy](i.store, updateHandler, labelHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func labelHandler(e *strategy.Strategy) []string {
|
||||||
|
return []string{e.Name, e.UUID, e.Desc}
|
||||||
|
}
|
||||||
|
func uniquestHandler(i *Create) []map[string]interface{} {
|
||||||
|
return []map[string]interface{}{{"uuid": i.Id}}
|
||||||
|
}
|
||||||
|
func createEntityHandler(i *Create) *strategy.Strategy {
|
||||||
|
now := time.Now()
|
||||||
|
return &strategy.Strategy{
|
||||||
|
UUID: i.Id,
|
||||||
|
Name: i.Name,
|
||||||
|
Priority: i.Priority,
|
||||||
|
Desc: i.Desc,
|
||||||
|
Filters: i.Filters,
|
||||||
|
Config: i.Config,
|
||||||
|
Scope: i.Scope,
|
||||||
|
Target: i.Target,
|
||||||
|
CreateAt: now,
|
||||||
|
UpdateAt: now,
|
||||||
|
IsStop: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func updateHandler(e *strategy.Strategy, i *Edit) {
|
||||||
|
if i.Name != nil {
|
||||||
|
e.Name = *i.Name
|
||||||
|
}
|
||||||
|
if i.Priority != nil {
|
||||||
|
e.Priority = *i.Priority
|
||||||
|
}
|
||||||
|
if i.Desc != nil {
|
||||||
|
e.Desc = *i.Desc
|
||||||
|
}
|
||||||
|
if i.Filters != nil {
|
||||||
|
e.Filters = *i.Filters
|
||||||
|
}
|
||||||
|
if i.Config != nil {
|
||||||
|
e.Config = *i.Config
|
||||||
|
}
|
||||||
|
if i.IsStop != nil {
|
||||||
|
e.IsStop = *i.IsStop
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/stores/strategy"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Strategy struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
Priority int
|
||||||
|
Desc string
|
||||||
|
Filters string
|
||||||
|
Config string
|
||||||
|
Driver string
|
||||||
|
Scope int
|
||||||
|
Target string
|
||||||
|
Creator string
|
||||||
|
Updater string
|
||||||
|
CreateAt time.Time
|
||||||
|
UpdateAt time.Time
|
||||||
|
IsStop bool
|
||||||
|
IsDelete bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromEntity(e *strategy.Strategy) *Strategy {
|
||||||
|
return &Strategy{
|
||||||
|
Id: e.UUID,
|
||||||
|
Name: e.Name,
|
||||||
|
Priority: e.Priority,
|
||||||
|
Driver: e.Driver,
|
||||||
|
Desc: e.Desc,
|
||||||
|
Filters: e.Filters,
|
||||||
|
Config: e.Config,
|
||||||
|
Scope: e.Scope,
|
||||||
|
Target: e.Target,
|
||||||
|
Creator: e.Creator,
|
||||||
|
Updater: e.Updater,
|
||||||
|
CreateAt: e.CreateAt,
|
||||||
|
UpdateAt: e.UpdateAt,
|
||||||
|
IsStop: e.IsStop,
|
||||||
|
IsDelete: e.IsDelete,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Create struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
Priority int
|
||||||
|
Desc string
|
||||||
|
Filters string
|
||||||
|
Config string
|
||||||
|
Scope int
|
||||||
|
Target string
|
||||||
|
Driver string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Edit struct {
|
||||||
|
Name *string
|
||||||
|
Priority *int
|
||||||
|
Desc *string
|
||||||
|
Filters *string
|
||||||
|
Config *string
|
||||||
|
IsStop *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type StrategyCommit struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
Priority int
|
||||||
|
Filters string
|
||||||
|
Config string
|
||||||
|
Driver string
|
||||||
|
IsStop bool
|
||||||
|
Version string
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/universally/commit"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/autowire"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/service/universally"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IStrategyService interface {
|
||||||
|
universally.IServiceCreate[Create]
|
||||||
|
universally.IServiceEdit[Edit]
|
||||||
|
AllByScope(ctx context.Context, scope int, target string) ([]*Strategy, error)
|
||||||
|
Search(ctx context.Context, keyword string, driver string, scope int, target string, page int, pageSize int, filters []string, order ...string) ([]*Strategy, int64, error)
|
||||||
|
Get(ctx context.Context, id string) (*Strategy, error)
|
||||||
|
SortDelete(ctx context.Context, id string) error
|
||||||
|
Delete(ctx context.Context, id ...string) error
|
||||||
|
|
||||||
|
CommitStrategy(ctx context.Context, scope string, target string, strategyId string, data *Strategy) error
|
||||||
|
GetStrategyCommit(ctx context.Context, commitId string) (*commit.Commit[StrategyCommit], error)
|
||||||
|
LatestStrategyCommit(ctx context.Context, scope string, target string, strategyId string) (*commit.Commit[StrategyCommit], error)
|
||||||
|
ListLatestStrategyCommit(ctx context.Context, scope string, target string, strategyIds ...string) ([]*commit.Commit[StrategyCommit], error)
|
||||||
|
ListStrategyCommit(ctx context.Context, commitIds ...string) ([]*commit.Commit[StrategyCommit], error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
autowire.Auto[IStrategyService](func() reflect.Value {
|
||||||
|
return reflect.ValueOf(new(imlStrategyService))
|
||||||
|
})
|
||||||
|
commit.InitCommitService[StrategyCommit]("strategy")
|
||||||
|
}
|
||||||
@@ -2,9 +2,10 @@ package commit
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/eolinker/go-common/utils"
|
"github.com/eolinker/go-common/utils"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/APIParkLab/APIPark/stores/universally/commit"
|
"github.com/APIParkLab/APIPark/stores/universally/commit"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ type imlCommitWithKeyService[T any] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *imlCommitWithKeyService[T]) List(ctx context.Context, uuids ...string) ([]*Commit[T], error) {
|
func (i *imlCommitWithKeyService[T]) List(ctx context.Context, uuids ...string) ([]*Commit[T], error) {
|
||||||
|
|
||||||
list, err := i.store.List(ctx, uuids...)
|
list, err := i.store.List(ctx, uuids...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -31,7 +32,7 @@ func (i *imlCommitWithKeyService[T]) ListLatest(ctx context.Context, target ...s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SliceToSlice(list, newCommit[T]), nil
|
return utils.SliceToSlice(list, newCommit[T]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ func (i *imlCommitWithKeyService[T]) Get(ctx context.Context, uuid string) (*Com
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return newCommit(r), nil
|
return newCommit(r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ func (i *imlCommitWithKeyService[T]) Latest(ctx context.Context, target string)
|
|||||||
if len(list) == 0 {
|
if len(list) == 0 {
|
||||||
return nil, gorm.ErrRecordNotFound
|
return nil, gorm.ErrRecordNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
result := list[0]
|
result := list[0]
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@@ -70,13 +71,13 @@ func (i *imlCommitService[T]) List(ctx context.Context, uuids ...string) ([]*Com
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SliceToSlice(list, newCommit[T]), nil
|
return utils.SliceToSlice(list, newCommit[T]), nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imlCommitService[T]) ListLatest(ctx context.Context, target ...string) ([]*Commit[T], error) {
|
func (i *imlCommitService[T]) ListLatest(ctx context.Context, key string, target ...string) ([]*Commit[T], error) {
|
||||||
list, err := i.store.Latest(ctx, "", target...)
|
list, err := i.store.Latest(ctx, key, target...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -88,7 +89,7 @@ func (i *imlCommitService[T]) Get(ctx context.Context, uuid string) (*Commit[T],
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return newCommit(r), nil
|
return newCommit(r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package commit
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/APIParkLab/APIPark/stores/universally/commit"
|
"github.com/APIParkLab/APIPark/stores/universally/commit"
|
||||||
"github.com/eolinker/go-common/autowire"
|
"github.com/eolinker/go-common/autowire"
|
||||||
)
|
)
|
||||||
@@ -18,7 +18,7 @@ type ICommitWithKeyService[T any] interface {
|
|||||||
|
|
||||||
func InitCommitWithKeyService[T any](name string, key string) {
|
func InitCommitWithKeyService[T any](name string, key string) {
|
||||||
autowire.Auto[commit.ICommitWKStore[T]](func() reflect.Value {
|
autowire.Auto[commit.ICommitWKStore[T]](func() reflect.Value {
|
||||||
|
|
||||||
return reflect.ValueOf(commit.NewCommitWithKey[T](name, key))
|
return reflect.ValueOf(commit.NewCommitWithKey[T](name, key))
|
||||||
})
|
})
|
||||||
autowire.Auto[ICommitWithKeyService[T]](func() reflect.Value {
|
autowire.Auto[ICommitWithKeyService[T]](func() reflect.Value {
|
||||||
@@ -28,7 +28,7 @@ func InitCommitWithKeyService[T any](name string, key string) {
|
|||||||
|
|
||||||
type ICommitService[T any] interface {
|
type ICommitService[T any] interface {
|
||||||
Latest(ctx context.Context, target string, key string) (*Commit[T], error)
|
Latest(ctx context.Context, target string, key string) (*Commit[T], error)
|
||||||
ListLatest(ctx context.Context, target ...string) ([]*Commit[T], error)
|
ListLatest(ctx context.Context, key string, target ...string) ([]*Commit[T], error)
|
||||||
Save(ctx context.Context, target string, key string, data *T) error
|
Save(ctx context.Context, target string, key string, data *T) error
|
||||||
Get(ctx context.Context, uuid string) (*Commit[T], error)
|
Get(ctx context.Context, uuid string) (*Commit[T], error)
|
||||||
List(ctx context.Context, uuids ...string) ([]*Commit[T], error)
|
List(ctx context.Context, uuids ...string) ([]*Commit[T], error)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (i *imlUpstreamService) ListCommit(ctx context.Context, uuid ...string) ([]
|
|||||||
return i.commitService.List(ctx, uuid...)
|
return i.commitService.List(ctx, uuid...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imlUpstreamService) ListLatestCommit(ctx context.Context, serviceIds ...string) ([]*commit.Commit[Config], error) {
|
func (i *imlUpstreamService) ListLatestCommit(ctx context.Context, clusterId string, serviceIds ...string) ([]*commit.Commit[Config], error) {
|
||||||
w := make(map[string]interface{})
|
w := make(map[string]interface{})
|
||||||
if len(serviceIds) > 0 {
|
if len(serviceIds) > 0 {
|
||||||
w["service"] = serviceIds
|
w["service"] = serviceIds
|
||||||
@@ -67,7 +67,7 @@ func (i *imlUpstreamService) ListLatestCommit(ctx context.Context, serviceIds ..
|
|||||||
targetId := utils.SliceToSlice(upstreams, func(u *upstream.Upstream) string {
|
targetId := utils.SliceToSlice(upstreams, func(u *upstream.Upstream) string {
|
||||||
return u.UUID
|
return u.UUID
|
||||||
})
|
})
|
||||||
return i.commitService.ListLatest(ctx, targetId...)
|
return i.commitService.ListLatest(ctx, clusterId, targetId...)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type IUpstreamService interface {
|
|||||||
Delete(ctx context.Context, id string) error
|
Delete(ctx context.Context, id string) error
|
||||||
List(ctx context.Context, serviceIds ...string) ([]*Upstream, error)
|
List(ctx context.Context, serviceIds ...string) ([]*Upstream, error)
|
||||||
LatestCommit(ctx context.Context, uid string, clusterId string) (*commit.Commit[Config], error)
|
LatestCommit(ctx context.Context, uid string, clusterId string) (*commit.Commit[Config], error)
|
||||||
ListLatestCommit(ctx context.Context, serviceIds ...string) ([]*commit.Commit[Config], error)
|
ListLatestCommit(ctx context.Context, clusterId string, serviceIds ...string) ([]*commit.Commit[Config], error)
|
||||||
SaveCommit(ctx context.Context, uid string, partition string, cfg *Config) error
|
SaveCommit(ctx context.Context, uid string, partition string, cfg *Config) error
|
||||||
GetCommit(ctx context.Context, uuid string) (*commit.Commit[Config], error)
|
GetCommit(ctx context.Context, uuid string) (*commit.Commit[Config], error)
|
||||||
ListCommit(ctx context.Context, uuid ...string) ([]*commit.Commit[Config], error)
|
ListCommit(ctx context.Context, uuid ...string) ([]*commit.Commit[Config], error)
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Strategy struct {
|
||||||
|
Id int64 `gorm:"column:id;type:BIGINT(20);AUTO_INCREMENT;NOT NULL;comment:id;primary_key;comment:主键ID;"`
|
||||||
|
UUID string `gorm:"type:varchar(36);not null;column:uuid;uniqueIndex:uuid;comment:UUID;"`
|
||||||
|
Name string `gorm:"type:varchar(100);not null;column:name;comment:name"`
|
||||||
|
Priority int `gorm:"type:tinyint(4);not null;column:priority;comment:优先级"`
|
||||||
|
Desc string `gorm:"type:text;null;column:desc;comment:描述"`
|
||||||
|
Filters string `gorm:"type:mediumtext;null;column:filters;comment:筛选条件"`
|
||||||
|
Config string `gorm:"type:mediumtext;null;column:config;comment:配置"`
|
||||||
|
Driver string `gorm:"type:varchar(100);not null;column:driver;comment:驱动"`
|
||||||
|
Scope int `gorm:"type:tinyint(1);not null;column:scope;comment:范围 0:全局 1:团队 2:服务"`
|
||||||
|
Target string `gorm:"type:varchar(36);null;column:target;comment:目标ID"`
|
||||||
|
Creator string `gorm:"type:varchar(36);not null;column:creator;comment:创建人" aovalue:"creator"`
|
||||||
|
Updater string `gorm:"type:varchar(36);null;column:updater;comment:更新人" aovalue:"updater"`
|
||||||
|
CreateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:create_at;comment:创建时间"`
|
||||||
|
UpdateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:update_at;comment:更新时间"`
|
||||||
|
IsStop bool `gorm:"type:tinyint(1);not null;column:enable;comment:是否禁用 0:否 1:是"`
|
||||||
|
IsDelete bool `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除 0:未删除 1:已删除"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Strategy) TableName() string {
|
||||||
|
return "strategy"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Strategy) IdValue() int64 {
|
||||||
|
return s.Id
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package strategy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/autowire"
|
||||||
|
"github.com/eolinker/go-common/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IStrategyStore store.ISearchStore[Strategy]
|
||||||
|
|
||||||
|
type imlStrategyStore struct {
|
||||||
|
store.SearchStore[Strategy]
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
autowire.Auto[IStrategyStore](func() reflect.Value {
|
||||||
|
return reflect.ValueOf(new(imlStrategyStore))
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user