diff --git a/controller/cluster/iml.go b/controller/cluster/iml.go index d67de3d0..509d4af3 100644 --- a/controller/cluster/iml.go +++ b/controller/cluster/iml.go @@ -45,8 +45,8 @@ func (p *imlCluster) Check(ctx *gin.Context, input *cluster_dto.CheckCluster) ([ // return id, nil //} // -//func (p *imlCluster) Search(ctx *gin.Context, keyword string) ([]*parition_dto.Item, error) { -// return p.module.Search(ctx, keyword) +//func (p *imlCluster) SearchByDriver(ctx *gin.Context, keyword string) ([]*parition_dto.Item, error) { +// return p.module.SearchByDriver(ctx, keyword) //} // //func (p *imlCluster) Simple(ctx *gin.Context) ([]*parition_dto.Simple, error) { diff --git a/controller/service/iml.go b/controller/service/iml.go index c8e58239..e95a8238 100644 --- a/controller/service/iml.go +++ b/controller/service/iml.go @@ -62,6 +62,62 @@ var ( loader = openapi3.NewLoader() ) +func (i *imlServiceController) swagger(ctx *gin.Context, id string) (*openapi3.T, error) { + doc, err := i.apiDocModule.GetDoc(ctx, id) + if err != nil { + return nil, err + } + tmp, err := loader.LoadFromData([]byte(doc.Content)) + if err != nil { + return nil, err + } + cfg := i.settingModule.Get(ctx) + + tmp.AddServer(&openapi3.Server{ + URL: cfg.InvokeAddress, + }) + return tmp, nil +} + +func (i *imlServiceController) ExportSwagger(ctx *gin.Context) { + id, has := ctx.Params.Get("id") + if !has { + ctx.JSON(200, &pm3.Response{ + Code: -1, + Success: "fail", + Message: fmt.Sprintf("id is required"), + }) + return + } + s, err := i.module.Get(ctx, id) + if err != nil { + ctx.JSON(200, &pm3.Response{ + Code: -1, + Success: "fail", + Message: err.Error(), + }) + return + } + tmp, err := i.swagger(ctx, id) + if err != nil { + ctx.JSON(200, &pm3.Response{ + Code: -1, + Success: "fail", + Message: err.Error(), + }) + return + } + + data, _ := tmp.MarshalJSON() + ctx.Status(200) + // 设置响应头 + ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s.json", strings.Replace(s.Name, " ", "_", -1))) + ctx.Header("Content-Type", "application/octet-stream") + ctx.Header("Content-Transfer-Encoding", "binary") + ctx.Writer.Write(data) + return +} + func (i *imlServiceController) Swagger(ctx *gin.Context) { id, has := ctx.Params.Get("id") if !has { @@ -71,9 +127,8 @@ func (i *imlServiceController) Swagger(ctx *gin.Context) { Message: fmt.Sprintf("id is required"), }) return - } - doc, err := i.apiDocModule.GetDoc(ctx, id) + tmp, err := i.swagger(ctx, id) if err != nil { ctx.JSON(200, &pm3.Response{ Code: -1, @@ -82,30 +137,7 @@ func (i *imlServiceController) Swagger(ctx *gin.Context) { }) return } - tmp, err := loader.LoadFromData([]byte(doc.Content)) - if err != nil { - ctx.JSON(200, &pm3.Response{ - Code: -1, - Success: "fail", - Message: err.Error(), - }) - return - } - cfg := i.settingModule.Get(ctx) - - tmp.AddServer(&openapi3.Server{ - URL: cfg.InvokeAddress, - }) - data, err := tmp.MarshalJSON() - if err != nil { - ctx.JSON(200, &pm3.Response{ - Code: -1, - Success: "fail", - Message: err.Error(), - }) - return - } - ctx.JSON(200, string(data)) + ctx.JSON(200, tmp) return } diff --git a/controller/service/service.go b/controller/service/service.go index ddf657f5..4e2a553e 100644 --- a/controller/service/service.go +++ b/controller/service/service.go @@ -28,6 +28,7 @@ type IServiceController interface { MySimple(ctx *gin.Context) ([]*service_dto.SimpleServiceItem, error) Swagger(ctx *gin.Context) + ExportSwagger(ctx *gin.Context) } type IAppController interface { diff --git a/module/cluster/impl.go b/module/cluster/impl.go index db37f50e..4fc11ee3 100644 --- a/module/cluster/impl.go +++ b/module/cluster/impl.go @@ -145,8 +145,8 @@ func (m *imlClusterModule) ClusterNodes(ctx context.Context, clusterId string) ( // return m.Get(ctx, create.Id) //} // -//func (m *imlClusterModule) Search(ctx context.Context, keyword string) ([]*paritiondto.Item, error) { -// partitions, err := m.partitionService.Search(ctx, keyword, nil) +//func (m *imlClusterModule) SearchByDriver(ctx context.Context, keyword string) ([]*paritiondto.Item, error) { +// partitions, err := m.partitionService.SearchByDriver(ctx, keyword, nil) // if err != nil { // return nil, err // } @@ -185,7 +185,7 @@ func (m *imlClusterModule) ClusterNodes(ctx context.Context, clusterId string) ( // if err != nil { // return nil, err // } -// //oDetails, err := m.organizationService.Search(ctx, "") +// //oDetails, err := m.organizationService.SearchByDriver(ctx, "") // //if err != nil { // // return nil, err // //} @@ -248,7 +248,7 @@ func (m *imlClusterModule) ClusterNodes(ctx context.Context, clusterId string) ( //} // //func (m *imlClusterModule) Simple(ctx context.Context) ([]*paritiondto.Simple, error) { -// pm, err := m.partitionService.Search(ctx, "", nil) +// pm, err := m.partitionService.SearchByDriver(ctx, "", nil) // if err != nil { // return nil, err // } @@ -262,7 +262,7 @@ func (m *imlClusterModule) ClusterNodes(ctx context.Context, clusterId string) ( //} // //func (m *imlClusterModule) SimpleByIds(ctx context.Context, ids []string) ([]*paritiondto.Simple, error) { -// pm, err := m.partitionService.Search(ctx, "", map[string]interface{}{ +// pm, err := m.partitionService.SearchByDriver(ctx, "", map[string]interface{}{ // "uuid": ids, // }) // if err != nil { @@ -278,7 +278,7 @@ func (m *imlClusterModule) ClusterNodes(ctx context.Context, clusterId string) ( // //} //func (m *imlClusterModule) SimpleWithCluster(ctx context.Context) ([]*paritiondto.SimpleWithCluster, error) { -// pm, err := m.partitionService.Search(ctx, "", nil) +// pm, err := m.partitionService.SearchByDriver(ctx, "", nil) // if err != nil { // return nil, err // } diff --git a/module/service-diff/iml.go b/module/service-diff/iml.go index b1a91283..8972ed46 100644 --- a/module/service-diff/iml.go +++ b/module/service-diff/iml.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" + "github.com/APIParkLab/APIPark/service/strategy" + "github.com/APIParkLab/APIPark/service/service" "github.com/APIParkLab/APIPark/service/api" @@ -23,6 +25,7 @@ type imlServiceDiff struct { apiDocService api_doc.IAPIDocService `autowired:""` upstreamService upstream.IUpstreamService `autowired:""` releaseService release.IReleaseService `autowired:""` + strategyService strategy.IStrategyService `autowired:""` clusterService cluster.IClusterService `autowired:""` } @@ -79,6 +82,34 @@ func (m *imlServiceDiff) getBaseInfo(ctx context.Context, serviceId, baseRelease return base, nil } + +func (m *imlServiceDiff) latestStrategyCommits(ctx context.Context, serviceId string) ([]*commit.Commit[strategy.StrategyCommit], error) { + list, err := m.strategyService.All(ctx, 2, serviceId) + if err != nil { + return nil, fmt.Errorf("get latest strategy failed:%w", err) + } + + return utils.SliceToSlice(list, func(s *strategy.Strategy) *commit.Commit[strategy.StrategyCommit] { + key := fmt.Sprintf("service-%s", s.Id) + return &commit.Commit[strategy.StrategyCommit]{ + Target: s.Id, + Key: key, + Data: &strategy.StrategyCommit{ + Id: s.Id, + Name: s.Name, + Priority: s.Priority, + Filters: s.Filters, + Config: s.Config, + Driver: s.Driver, + IsStop: s.IsStop, + Version: s.UpdateAt.Format("20060102150405"), + }, + } + }, func(s *strategy.Strategy) bool { + return !s.IsDelete + }), nil +} + func (m *imlServiceDiff) DiffForLatest(ctx context.Context, serviceId string, baseRelease string) (*service_diff.Diff, bool, error) { serviceInfo, err := m.serviceService.Get(ctx, serviceId) if err != nil { @@ -130,6 +161,11 @@ func (m *imlServiceDiff) DiffForLatest(ctx context.Context, serviceId string, ba return nil, false, fmt.Errorf("upstream not found") } + strategyCommits, err := m.latestStrategyCommits(ctx, serviceId) + if err != nil { + return nil, false, err + } + base, err := m.getBaseInfo(ctx, serviceId, baseRelease) if err != nil { return nil, false, err @@ -140,6 +176,7 @@ func (m *imlServiceDiff) DiffForLatest(ctx context.Context, serviceId string, ba apiProxyCommits: proxy, apiDocCommits: apiDocCommits, upstreamCommits: upstreamCommits, + strategyCommits: strategyCommits, } clusters, err := m.clusterService.List(ctx) if err != nil { @@ -211,6 +248,46 @@ func (m *imlServiceDiff) getReleaseInfo(ctx context.Context, releaseId string) ( upstreamCommits: upstreamCommits, }, nil } + +func (m *imlServiceDiff) diffStrategies(base, target []*commit.Commit[strategy.StrategyCommit]) []*service_diff.StrategyDiff { + baseStrategy := utils.SliceToMap(base, func(i *commit.Commit[strategy.StrategyCommit]) string { + return i.Target + }) + targetStrategy := utils.SliceToMap(target, func(i *commit.Commit[strategy.StrategyCommit]) string { + return i.Target + }) + out := make([]*service_diff.StrategyDiff, 0, len(target)) + for _, tc := range targetStrategy { + key := tc.Target + t := tc.Data + o := &service_diff.StrategyDiff{ + Strategy: key, + Name: t.Name, + Priority: t.Priority, + Change: service_diff.ChangeTypeNone, + Status: 0, + } + b, hasB := baseStrategy[key] + if !hasB { + o.Change = service_diff.ChangeTypeNew + } else if b.UUID != tc.UUID { + o.Change = service_diff.ChangeTypeUpdate + } + delete(baseStrategy, key) + out = append(out, o) + } + for _, b := range baseStrategy { + o := &service_diff.StrategyDiff{ + Strategy: b.Target, + Name: b.Data.Name, + Priority: b.Data.Priority, + Change: service_diff.ChangeTypeDelete, + Status: 0, + } + out = append(out, o) + } + return out +} func (m *imlServiceDiff) diff(partitions []string, base, target *projectInfo) *service_diff.Diff { out := &service_diff.Diff{ Apis: nil, @@ -328,6 +405,7 @@ func (m *imlServiceDiff) diff(partitions []string, base, target *projectInfo) *s } } } + out.Strategies = m.diffStrategies(base.strategyCommits, target.strategyCommits) return out } @@ -373,5 +451,13 @@ func (m *imlServiceDiff) Out(ctx context.Context, diff *service_diff.Diff) (*Dif }), }) } + out.Strategies = utils.SliceToSlice(diff.Strategies, func(i *service_diff.StrategyDiff) *StrategyDiffOut { + return &StrategyDiffOut{ + Name: i.Name, + Priority: i.Priority, + Change: i.Change, + Status: i.Status, + } + }) return out, nil } diff --git a/module/service-diff/out.go b/module/service-diff/out.go index a6b98cf3..b4b3dbfb 100644 --- a/module/service-diff/out.go +++ b/module/service-diff/out.go @@ -4,13 +4,15 @@ import ( "github.com/APIParkLab/APIPark/service/api" api_doc "github.com/APIParkLab/APIPark/service/api-doc" "github.com/APIParkLab/APIPark/service/service_diff" + "github.com/APIParkLab/APIPark/service/strategy" "github.com/APIParkLab/APIPark/service/universally/commit" "github.com/APIParkLab/APIPark/service/upstream" ) type DiffOut struct { - Routers []*RouterDiffOut `json:"routers"` - Upstreams []*UpstreamDiffOut `json:"upstreams"` + Routers []*RouterDiffOut `json:"routers"` + Upstreams []*UpstreamDiffOut `json:"upstreams"` + Strategies []*StrategyDiffOut `json:"strategies"` } type RouterDiffOut struct { @@ -30,6 +32,13 @@ type UpstreamDiffOut struct { Addr []string `json:"addr,omitempty"` } +type StrategyDiffOut struct { + Name string `json:"name"` + Priority int `json:"priority"` + Change service_diff.ChangeType `json:"change,omitempty"` + Status service_diff.StatusType `json:"status,omitempty"` +} + type projectInfo struct { id string //apis []*api.Info @@ -37,4 +46,5 @@ type projectInfo struct { apiProxyCommits []*commit.Commit[api.Proxy] apiDocCommits []*commit.Commit[api_doc.DocCommit] upstreamCommits []*commit.Commit[upstream.Config] + strategyCommits []*commit.Commit[strategy.StrategyCommit] } diff --git a/module/service/iml.go b/module/service/iml.go index 652c1a97..377990bd 100644 --- a/module/service/iml.go +++ b/module/service/iml.go @@ -174,7 +174,7 @@ func (i *imlServiceModule) SearchMyServices(ctx context.Context, teamId string, //func (i *imlServiceModule) SimpleAPPS(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { // w := make(map[string]interface{}) // w["as_app"] = true -// services, err := i.serviceService.Search(ctx, keyword, w) +// services, err := i.serviceService.SearchByDriver(ctx, keyword, w) // if err != nil { // return nil, err // } diff --git a/module/strategy/iml.go b/module/strategy/iml.go index 1c3032b4..a8bcbad2 100644 --- a/module/strategy/iml.go +++ b/module/strategy/iml.go @@ -53,7 +53,7 @@ func (i *imlStrategyModule) DeleteServiceStrategy(ctx context.Context, serviceId func (i *imlStrategyModule) ToPublish(ctx context.Context, driver string) ([]*strategy_dto.ToPublishItem, error) { scope := strategy_dto.ToScope(strategy_dto.ScopeGlobal) - list, err := i.strategyService.SearchAll(ctx, "", driver, scope.Int(), "") + list, err := i.strategyService.SearchAllByDriver(ctx, "", driver, scope.Int(), "") if err != nil { return nil, err } @@ -80,7 +80,7 @@ func (i *imlStrategyModule) ToPublish(ctx context.Context, driver string) ([]*st } 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...) + list, total, err := i.strategyService.SearchByDriver(ctx, keyword, driver, scope.Int(), target, page, pageSize, filters, order...) if err != nil { return nil, 0, err } @@ -213,7 +213,7 @@ func (i *imlStrategyModule) Disable(ctx context.Context, id string) error { } func (i *imlStrategyModule) Publish(ctx context.Context, driver string, scope string, target string) error { - list, err := i.strategyService.AllByScope(ctx, driver, strategy_dto.ToScope(scope).Int(), target) + list, err := i.strategyService.AllByDriver(ctx, driver, strategy_dto.ToScope(scope).Int(), target) if err != nil { return err } diff --git a/plugins/core/service.go b/plugins/core/service.go index 11a8ee5d..8fd6dc63 100644 --- a/plugins/core/service.go +++ b/plugins/core/service.go @@ -29,6 +29,7 @@ func (p *plugin) ServiceApis() []pm3.Api { pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/doc", []string{"context", "query:service"}, []string{"doc"}, p.serviceController.ServiceDoc, access.SystemWorkspaceServiceViewAll, access.TeamServiceServiceIntroView), pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/doc", []string{"context", "query:service", "body"}, nil, p.serviceController.SaveServiceDoc, access.SystemWorkspaceServiceManagerAll, access.TeamServiceServiceIntroManager), - pm3.CreateApiSimple(http.MethodGet, "/swagger/:id", p.serviceController.Swagger), + pm3.CreateApiSimple(http.MethodGet, "/api/v1/service/swagger/:id", p.serviceController.Swagger), + pm3.CreateApiSimple(http.MethodGet, "/api/v1/export/openapi/:id", p.serviceController.ExportSwagger), } } diff --git a/service/service_diff/diff.go b/service/service_diff/diff.go index 2c27ead5..3b6feb03 100644 --- a/service/service_diff/diff.go +++ b/service/service_diff/diff.go @@ -39,8 +39,17 @@ type UpstreamDiff struct { Status StatusType `json:"status,omitempty"` } -type Diff struct { - Clusters []string `json:"clusters,omitempty"` - Apis []*ApiDiff `json:"apis"` - Upstreams []*UpstreamDiff `json:"upstreams"` +type StrategyDiff struct { + Strategy string `json:"strategy,omitempty"` + Name string `json:"name"` + Priority int `json:"priority"` + Change ChangeType `json:"change,omitempty"` + Status StatusType `json:"status,omitempty"` +} + +type Diff struct { + Clusters []string `json:"clusters,omitempty"` + Apis []*ApiDiff `json:"apis"` + Upstreams []*UpstreamDiff `json:"upstreams"` + Strategies []*StrategyDiff `json:"strategies"` } diff --git a/service/strategy/iml.go b/service/strategy/iml.go index ca72ac61..5d435157 100644 --- a/service/strategy/iml.go +++ b/service/strategy/iml.go @@ -22,12 +22,25 @@ type imlStrategyService struct { universally.IServiceEdit[Edit] } +func (i *imlStrategyService) All(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) Restore(ctx context.Context, id string) error { _, err := i.store.UpdateWhere(ctx, map[string]interface{}{"uuid": id}, map[string]interface{}{"is_delete": false}) return err } -func (i *imlStrategyService) SearchAll(ctx context.Context, keyword string, driver string, scope int, target string) ([]*Strategy, error) { +func (i *imlStrategyService) SearchAllByDriver(ctx context.Context, keyword string, driver string, scope int, target string) ([]*Strategy, error) { w := make(map[string]interface{}) w["scope"] = scope if target != "" { @@ -40,7 +53,7 @@ func (i *imlStrategyService) SearchAll(ctx context.Context, keyword string, driv return utils.SliceToSlice(list, FromEntity), nil } -func (i *imlStrategyService) AllByScope(ctx context.Context, driver string, scope int, target string) ([]*Strategy, error) { +func (i *imlStrategyService) AllByDriver(ctx context.Context, driver string, scope int, target string) ([]*Strategy, error) { w := make(map[string]interface{}) w["scope"] = scope if target != "" { @@ -100,7 +113,7 @@ func (i *imlStrategyService) ListStrategyCommit(ctx context.Context, commitIds . 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) { +func (i *imlStrategyService) SearchByDriver(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, diff --git a/service/strategy/service.go b/service/strategy/service.go index 817b2732..24501de9 100644 --- a/service/strategy/service.go +++ b/service/strategy/service.go @@ -14,9 +14,10 @@ import ( type IStrategyService interface { universally.IServiceCreate[Create] universally.IServiceEdit[Edit] - AllByScope(ctx context.Context, driver string, 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) - SearchAll(ctx context.Context, keyword string, driver string, scope int, target string) ([]*Strategy, error) + All(ctx context.Context, scope int, target string) ([]*Strategy, error) + AllByDriver(ctx context.Context, driver string, scope int, target string) ([]*Strategy, error) + SearchByDriver(ctx context.Context, keyword string, driver string, scope int, target string, page int, pageSize int, filters []string, order ...string) ([]*Strategy, int64, error) + SearchAllByDriver(ctx context.Context, keyword string, driver string, scope int, target string) ([]*Strategy, error) Get(ctx context.Context, id string) (*Strategy, error) SortDelete(ctx context.Context, id string) error Delete(ctx context.Context, id ...string) error