This is an automated email from the ASF dual-hosted git repository. klesh pushed a commit to branch kw-5519-remoteapi-dshelper in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
commit b2b13ca90d97cef873374b73013c0acf3c9f5cee Merge: df4a07510 f7f808742 Author: Klesh Wong <[email protected]> AuthorDate: Tue May 14 16:49:49 2024 +0800 Merge remote-tracking branch 'origin/main' into kw-5519-remoteapi-dshelper README.md | 43 +++- backend/Makefile | 2 +- backend/core/config/config_viper.go | 1 + backend/core/models/common/string_int64.go | 78 ++++++ .../20240424_add_subtask_states.go | 59 +++++ backend/core/models/migrationscripts/register.go | 1 + backend/core/models/project.go | 15 ++ backend/core/models/subtask_state.go | 40 +++ backend/core/utils/json.go | 9 + backend/helpers/e2ehelper/data_flow_tester.go | 5 +- backend/helpers/pluginhelper/api/api_client.go | 66 ++++- .../helpers/pluginhelper/api/api_client_test.go | 65 +++++ backend/helpers/pluginhelper/api/api_extractor.go | 2 +- ...{api_extractor.go => api_extractor_stateful.go} | 94 ++++--- .../helpers/pluginhelper/api/batch_save_divider.go | 42 +-- .../pluginhelper/api/data_convertor_stateful.go | 129 ++++++++++ backend/helpers/pluginhelper/api/ds_helper.go | 2 +- .../pluginhelper/api/ds_scope_config_api_helper.go | 11 + .../helpers/pluginhelper/api/graphql_collector.go | 2 +- backend/helpers/pluginhelper/api/pipeline_plan.go | 24 ++ .../pluginhelper/api/subtask_state_manager.go | 155 +++++++++++ .../pluginhelper/api/subtask_state_manager_test.go | 189 ++++++++++++++ .../helpers/srvhelper/any_model_service_helper.go | 2 +- .../srvhelper/any_scope_config_service_helper.go | 72 ++++++ backend/impls/context/default_subtask_context.go | 6 +- backend/impls/dalgorm/dalgorm.go | 14 + .../azuredevops_go/api/azuredevops/client.go | 282 +++++++++++++++++++++ .../client_test.go} | 6 +- .../azuredevops_go/api/azuredevops/models.go | 132 ++++++++++ .../api/{ => azuredevops}/testdata/test.txt | 0 .../plugins/azuredevops_go/api/blueprint_v200.go | 62 ++++- .../azuredevops_go/api/blueprint_v200_test.go | 75 +++++- .../plugins/azuredevops_go/api/connection_api.go | 9 +- backend/plugins/azuredevops_go/api/remote_data.go | 65 ----- .../plugins/azuredevops_go/api/remote_helper.go | 223 +++++++++++----- .../plugins/azuredevops_go/api/scope_config_api.go | 14 + backend/plugins/azuredevops_go/api/vs_client.go | 137 ---------- backend/plugins/azuredevops_go/e2e/build_test.go | 1 + .../raw_tables/_raw_azuredevops_go_api_builds.csv | 5 +- .../_raw_azuredevops_go_api_timeline_records.csv | 6 +- .../_tool_azuredevops_go_builds.csv | 5 +- .../_tool_azuredevops_go_timeline_records.csv | 4 + .../e2e/snapshot_tables/cicd_pipeline_commits.csv | 5 +- .../e2e/snapshot_tables/cicd_pipelines.csv | 5 +- .../e2e/snapshot_tables/cicd_tasks.csv | 4 + backend/plugins/azuredevops_go/impl/impl.go | 6 +- backend/plugins/azuredevops_go/models/base.go | 5 + backend/plugins/azuredevops_go/models/build.go | 16 +- .../20240413_add_remote_repo_support.go | 68 +++++ .../models/migrationscripts/register.go | 1 + backend/plugins/azuredevops_go/models/repo.go | 13 +- .../azuredevops_go/tasks/ci_cd_build_collector.go | 12 +- .../azuredevops_go/tasks/ci_cd_build_converter.go | 7 +- .../azuredevops_go/tasks/ci_cd_build_extractor.go | 6 +- backend/plugins/azuredevops_go/tasks/task_data.go | 4 +- backend/plugins/bamboo/api/scope_config_api.go | 14 + backend/plugins/bamboo/impl/impl.go | 3 + backend/plugins/bitbucket/api/scope_config_api.go | 14 + backend/plugins/bitbucket/impl/impl.go | 3 + backend/plugins/bitbucket_server/api/remote_api.go | 29 +-- .../bitbucket_server/api/scope_config_api.go | 14 + backend/plugins/bitbucket_server/impl/impl.go | 3 + backend/plugins/circleci/api/connection_api.go | 6 +- backend/plugins/circleci/api/scope_config_api.go | 14 + backend/plugins/circleci/impl/impl.go | 5 +- .../dora/e2e/change_lead_time/commits_diffs.csv | 13 +- .../e2e/change_lead_time/project_pr_metrics.csv | 1 + .../e2e/change_lead_time/pull_request_comments.csv | 27 +- .../e2e/change_lead_time/pull_request_commits.csv | 27 +- .../dora/e2e/change_lead_time/pull_requests.csv | 15 +- .../dora/tasks/change_lead_time_calculator.go | 1 + backend/plugins/gitextractor/gitextractor.go | 2 +- backend/plugins/gitextractor/impl/impl.go | 2 +- .../plugins/gitextractor/parser/clone_gitcli.go | 62 +++-- backend/plugins/gitextractor/parser/taskdata.go | 29 ++- backend/plugins/gitextractor/tasks/repo_cloner.go | 3 + backend/plugins/github/api/scope_config_api.go | 14 + backend/plugins/github/impl/impl.go | 3 + backend/plugins/gitlab/api/scope_config_api.go | 14 + backend/plugins/gitlab/impl/impl.go | 3 + backend/plugins/jenkins/api/remote_api.go | 13 +- backend/plugins/jenkins/api/scope_config_api.go | 14 + backend/plugins/jenkins/impl/impl.go | 3 + .../plugins/jenkins/tasks/build_cicd_convertor.go | 4 + backend/plugins/jenkins/tasks/stage_convertor.go | 4 + backend/plugins/jira/api/scope_config_api.go | 14 + backend/plugins/jira/impl/impl.go | 3 + .../jira/tasks/board_filter_begin_collector.go | 3 + .../jira/tasks/board_filter_end_collector.go | 3 +- .../jira/tasks/issue_changelog_collector.go | 2 +- .../jira/tasks/issue_changelog_convertor.go | 76 +++--- .../jira/tasks/issue_changelog_extractor.go | 15 +- backend/plugins/jira/tasks/issue_convertor.go | 61 ++--- backend/plugins/jira/tasks/issue_extractor.go | 24 +- .../20240508_modify_commit_character_type.go | 54 ++++ .../sonarqube/models/migrationscripts/register.go | 1 + backend/plugins/tapd/api/scope_config_api.go | 14 + backend/plugins/tapd/impl/impl.go | 3 + .../plugins/tapd/tasks/bug_changelog_collector.go | 2 +- .../plugins/tapd/tasks/bug_changelog_converter.go | 2 +- .../plugins/tapd/tasks/bug_changelog_extractor.go | 3 +- backend/plugins/trello/api/scope_config_api.go | 14 + backend/plugins/trello/impl/impl.go | 3 + backend/plugins/zentao/api/scope_api.go | 8 +- backend/plugins/zentao/api/scope_config_api.go | 14 + backend/plugins/zentao/impl/impl.go | 3 + backend/plugins/zentao/models/task.go | 2 +- .../zentao/tasks/bug_repo_commits_collector.go | 2 +- .../zentao/tasks/bug_repo_commits_convertor.go | 2 +- .../zentao/tasks/bug_repo_commits_extractor.go | 2 +- .../zentao/tasks/story_repo_commits_collector.go | 2 +- .../zentao/tasks/story_repo_commits_convertor.go | 5 +- .../zentao/tasks/story_repo_commits_extractor.go | 3 +- .../zentao/tasks/task_repo_commits_collector.go | 2 +- .../zentao/tasks/task_repo_commits_convertor.go | 5 +- .../zentao/tasks/task_repo_commits_extractor.go | 3 +- .../python/plugins/azuredevops/azuredevops/main.py | 2 +- .../plugins/azuredevops/azuredevops/models.py | 4 +- .../python/pydevlake/pydevlake/pipeline_tasks.py | 5 +- backend/server/api/api.go | 37 +-- backend/server/api/project/project.go | 4 +- backend/server/api/router.go | 4 +- backend/server/services/project.go | 32 +++ .../server/services/remote/plugin/default_api.go | 3 + .../services/remote/plugin/scope_config_api.go | 4 + backend/server/services/task.go | 9 +- backend/test/e2e/manual/azuredevops/models.go | 1 + backend/test/e2e/remote/helper.go | 7 +- backend/test/helper/api.go | 37 ++- backend/test/helper/models.go | 1 + config-ui/env.example | 1 + config-ui/index.html | 2 +- config-ui/nginx.conf | 6 +- config-ui/package.json | 4 +- config-ui/src/api/blueprint/index.ts | 9 +- config-ui/src/api/project/index.ts | 5 +- config-ui/src/api/scope-config/index.ts | 5 + .../tips/index.ts => api/scope-config/types.ts} | 7 +- config-ui/src/app/store.ts | 3 +- .../action/icon-button/index.tsx} | 29 +-- config-ui/src/components/action/index.ts | 1 + config-ui/src/features/index.ts | 1 - config-ui/src/features/tips/slice.ts | 58 ----- config-ui/src/plugins/components/index.ts | 2 + .../components/plugin-name/index.tsx} | 45 +++- .../plugins/components/scope-config-form/index.tsx | 16 +- .../components/scope-config-select/index.tsx | 31 +-- .../src/plugins/components/scope-config/index.tsx | 204 +++++++++++++++ config-ui/src/plugins/register/github/config.tsx | 1 - .../routes/blueprint/connection-detail/index.tsx | 138 +++++----- .../routes/blueprint/connection-detail/table.tsx | 102 ++++++++ .../blueprint/detail/blueprint-detail-page.tsx | 8 + .../components/add-connection-dialog/index.tsx | 50 ++-- config-ui/src/routes/blueprint/home/index.tsx | 15 +- config-ui/src/routes/connection/connection.tsx | 153 +++++++---- config-ui/src/routes/layout/layout.tsx | 88 ++----- config-ui/src/routes/onboard/components/card.tsx | 6 +- config-ui/src/routes/onboard/index.tsx | 8 +- config-ui/src/routes/onboard/step-0.tsx | 40 ++- config-ui/src/routes/onboard/step-3.tsx | 20 +- config-ui/src/routes/pipeline/components/table.tsx | 10 +- config-ui/src/routes/pipeline/components/task.tsx | 3 + config-ui/src/routes/project/detail/index.tsx | 8 + config-ui/src/routes/project/home/index.tsx | 29 +-- config-ui/src/vite-env.d.ts | 1 + config-ui/yarn.lock | 73 +++--- env.example | 12 +- grafana/dashboards/DORA.json | 27 +- grafana/dashboards/EngineeringOverview.json | 2 +- 169 files changed, 3300 insertions(+), 1088 deletions(-) diff --cc backend/helpers/pluginhelper/api/ds_helper.go index 0a0718bc0,0b14356e3..74f065b6b --- a/backend/helpers/pluginhelper/api/ds_helper.go +++ b/backend/helpers/pluginhelper/api/ds_helper.go @@@ -25,55 -25,8 +25,55 @@@ import "github.com/apache/incubator-devlake/helpers/srvhelper" ) +// DsAnyHelper is a helper struct for implementing APIs for data source plugin like github/gitlab, etc. +// Normally, the plugin will have a connection model, a scope model, and a scope config model. +// - connection: holds the data source url and credential etc +// - scope: a scope is a collection of data source objects, like a github repo, a gitlab project, etc +// - scope config: configuration of what to collect, how to transform, etc +// +// The helper provides APIs for CRUD operations on connection, scope, and scope config without type information +type DsAnyHelper struct { + ConnSrv *srvhelper.AnyConnectionSrvHelper + ConnApi *DsAnyConnectionApiHelper + ScopeSrv *srvhelper.AnyScopeSrvHelper + ScopeApi *DsAnyScopeApiHelper + ScopeConfigSrv *srvhelper.AnyScopeConfigSrvHelper + ScopeConfigApi *DsAnyScopeConfigApiHelper +} + +// NewDataSourceAnyHelper creates a new DsAnyHelper +func NewDataSourceAnyHelper( + basicRes context.BasicRes, + pluginName string, + scopeSearchColumns []string, + connectionSterilizer func(c any) any, + connModelInfo srvhelper.ConnectionModelInfo, + scopeModelInfo srvhelper.ScopeModelInfo, + scopeConfigModelInfo srvhelper.ScopeConfigModelInfo, +) *DsAnyHelper { + connSrv := srvhelper.NewAnyConnectionSrvHelper(basicRes, connModelInfo, scopeModelInfo, scopeConfigModelInfo, pluginName) + connApi := NewDsAnyConnectionApiHelper(basicRes, connSrv, connectionSterilizer) + scopeSrv := srvhelper.NewAnyScopeSrvHelper(basicRes, scopeModelInfo, scopeConfigModelInfo, pluginName, scopeSearchColumns) + scopeApi := NewDsAnyScopeApiHelper(basicRes, scopeSrv) + var scopeConfigSrv *srvhelper.AnyScopeConfigSrvHelper + var scopeConfigApi *DsAnyScopeConfigApiHelper + if scopeConfigModelInfo != nil { - scopeConfigSrv = srvhelper.NewAnyScopeConfigSrvHelper(basicRes, scopeConfigModelInfo, scopeModelInfo) ++ scopeConfigSrv = srvhelper.NewAnyScopeConfigSrvHelper(basicRes, scopeConfigModelInfo, scopeModelInfo, pluginName) + scopeConfigApi = NewDsAnyScopeConfigApiHelper(basicRes, scopeConfigSrv) + } + return &DsAnyHelper{ + ConnSrv: connSrv, + ConnApi: connApi, + ScopeSrv: scopeSrv, + ScopeApi: scopeApi, + ScopeConfigSrv: scopeConfigSrv, + ScopeConfigApi: scopeConfigApi, + } +} + var noScopeConfig = reflect.TypeOf(new(srvhelper.NoScopeConfig)) +// DsHelper is the Typed version of DsAnyHelper type DsHelper[ C plugin.ToolLayerConnection, S plugin.ToolLayerScope, diff --cc backend/helpers/pluginhelper/api/ds_scope_config_api_helper.go index af6616391,c93144e45..a58105a7e --- a/backend/helpers/pluginhelper/api/ds_scope_config_api_helper.go +++ b/backend/helpers/pluginhelper/api/ds_scope_config_api_helper.go @@@ -53,7 -57,19 +53,18 @@@ func (scopeConfigApi *DsAnyScopeConfigA }, nil } -func (connApi *DsScopeConfigApiHelper[C, S, SC]) GetProjectsByScopeConfig(input *plugin.ApiResourceInput) (out *plugin.ApiResourceOutput, err errors.Error) { - var scopeConfig *SC - scopeConfig, err = connApi.FindByPk(input) ++func (scopeConfigApi *DsAnyScopeConfigApiHelper) GetProjectsByScopeConfig(input *plugin.ApiResourceInput) (out *plugin.ApiResourceOutput, err errors.Error) { ++ scopeConfig, err := scopeConfigApi.FindByPkAny(input) + if err != nil { + return nil, err + } - projectDetails := errors.Must1(connApi.ScopeConfigSrvHelper.GetProjectsByScopeConfig(input.Params["plugin"], scopeConfig)) ++ projectDetails := errors.Must1(scopeConfigApi.AnyScopeConfigSrvHelper.GetProjectsByScopeConfig(scopeConfig)) + return &plugin.ApiResourceOutput{ + Body: projectDetails, + }, nil + } + -func (connApi *DsScopeConfigApiHelper[C, S, SC]) Post(input *plugin.ApiResourceInput) (out *plugin.ApiResourceOutput, err errors.Error) { +func (scopeConfigApi *DsAnyScopeConfigApiHelper) Post(input *plugin.ApiResourceInput) (out *plugin.ApiResourceOutput, err errors.Error) { // fix connectionId connectionId, err := extractConnectionId(input) if err != nil { diff --cc backend/helpers/srvhelper/any_scope_config_service_helper.go index bcc2e5e79,c06354d25..bc075acfc --- a/backend/helpers/srvhelper/any_scope_config_service_helper.go +++ b/backend/helpers/srvhelper/any_scope_config_service_helper.go @@@ -32,28 -32,18 +34,31 @@@ func (NoScopeConfig) TableName() strin func (NoScopeConfig) ScopeConfigId() uint64 { return 0 } func (NoScopeConfig) ScopeConfigConnectionId() uint64 { return 0 } +type ScopeConfigModelInfo interface { + ModelInfo + GetConnectionId(any) uint64 + GetScopeConfigId(any) uint64 +} + // ScopeConfigSrvHelper -type ScopeConfigSrvHelper[C plugin.ToolLayerConnection, S plugin.ToolLayerScope, SC plugin.ToolLayerScopeConfig] struct { - *ModelSrvHelper[SC] +type AnyScopeConfigSrvHelper struct { + ScopeConfigModelInfo + ScopeModelInfo + *AnyModelSrvHelper ++ pluginName string } -func NewScopeConfigSrvHelper[ - C plugin.ToolLayerConnection, - S plugin.ToolLayerScope, - SC plugin.ToolLayerScopeConfig, -](basicRes context.BasicRes, searchColumns []string) *ScopeConfigSrvHelper[C, S, SC] { - return &ScopeConfigSrvHelper[C, S, SC]{ - ModelSrvHelper: NewModelSrvHelper[SC](basicRes, searchColumns), +func NewAnyScopeConfigSrvHelper( + basicRes context.BasicRes, + scopeConfigModelInfo ScopeConfigModelInfo, + scopeModelInfo ScopeModelInfo, ++ pluginName string, +) *AnyScopeConfigSrvHelper { + return &AnyScopeConfigSrvHelper{ + ScopeConfigModelInfo: scopeConfigModelInfo, + ScopeModelInfo: scopeModelInfo, + AnyModelSrvHelper: NewAnyModelSrvHelper(basicRes, scopeConfigModelInfo, nil), ++ pluginName: pluginName, } } @@@ -66,17 -56,79 +71,84 @@@ func (scopeConfigSrv *AnyScopeConfigSrv return scopeConfigs, err } -func (scopeConfigSrv *ScopeConfigSrvHelper[C, S, SC]) GetProjectsByScopeConfig(pluginName string, scopeConfig *SC) (*models.ProjectScopeOutput, errors.Error) { ++func (scopeConfigSrv *AnyScopeConfigSrvHelper) GetProjectsByScopeConfig(scopeConfig any) (*models.ProjectScopeOutput, errors.Error) { + ps := &models.ProjectScopeOutput{} + projectMap := make(map[string]*models.ProjectScope) + // 1. get all scopes that are using the scopeConfigId - var scope []*S - err := scopeConfigSrv.db.All(&scope, - dal.Where("scope_config_id = ?", (*scopeConfig).ScopeConfigId()), ++ scopes := scopeConfigSrv.ScopeModelInfo.NewSlice() ++ sc := scopeConfig.(plugin.ToolLayerScopeConfig) ++ err := scopeConfigSrv.db.All(&scopes, ++ dal.Where("scope_config_id = ?", sc.ScopeConfigId()), + ) + if err != nil { + return nil, err + } - for _, s := range scope { ++ slice := reflect.ValueOf(scopes) ++ for i := 0; i < slice.Len(); i++ { + // 2. get blueprint id by connection id and scope id + bpScope := []*models.BlueprintScope{} ++ s := slice.Index(i).Interface().(plugin.ToolLayerScope) + err = scopeConfigSrv.db.All(&bpScope, - dal.Where("plugin_name = ? and connection_id = ? and scope_id = ?", pluginName, (*s).ScopeConnectionId(), (*s).ScopeId()), ++ dal.Where("plugin_name = ? and connection_id = ? and scope_id = ?", scopeConfigSrv.pluginName, s.ScopeConnectionId(), s.ScopeId()), + ) + if err != nil { + return nil, err + } + + for _, bs := range bpScope { + // 3. get project details by blueprint id + bp := models.Blueprint{} + err = scopeConfigSrv.db.All(&bp, + dal.Where("id = ?", bs.BlueprintId), + ) + if err != nil { + return nil, err + } + if project, exists := projectMap[bp.ProjectName]; exists { + project.Scopes = append(project.Scopes, struct { + ScopeID string `json:"scopeId"` + ScopeName string `json:"scopeName"` + }{ + ScopeID: bs.ScopeId, - ScopeName: (*s).ScopeName(), ++ ScopeName: s.ScopeName(), + }) + } else { + projectMap[bp.ProjectName] = &models.ProjectScope{ + Name: bp.ProjectName, + BlueprintId: bp.ID, + Scopes: []struct { + ScopeID string `json:"scopeId"` + ScopeName string `json:"scopeName"` + }{ + { + ScopeID: bs.ScopeId, - ScopeName: (*s).ScopeName(), ++ ScopeName: s.ScopeName(), + }, + }, + } + } + } + } + // 4. combine all projects + for _, project := range projectMap { + ps.Projects = append(ps.Projects, *project) + } + ps.Count = len(ps.Projects) + + return ps, err + } + -func (scopeConfigSrv *ScopeConfigSrvHelper[C, S, SC]) DeleteScopeConfig(scopeConfig *SC) (refs []*S, err errors.Error) { - err = scopeConfigSrv.ModelSrvHelper.NoRunningPipeline(func(tx dal.Transaction) errors.Error { +func (scopeConfigSrv *AnyScopeConfigSrvHelper) DeleteScopeConfigAny(scopeConfig any) (refs any, err errors.Error) { + err = scopeConfigSrv.NoRunningPipeline(func(tx dal.Transaction) errors.Error { // make sure no scope is using the scopeConfig - sc := *scopeConfig + connectionId := scopeConfigSrv.ScopeConfigModelInfo.GetConnectionId(scopeConfig) + scopeConfigId := scopeConfigSrv.ScopeConfigModelInfo.GetScopeConfigId(scopeConfig) + refs = scopeConfigSrv.ScopeModelInfo.NewSlice() errors.Must(tx.All( &refs, - dal.Where("connection_id = ? AND scope_config_id = ?", sc.ScopeConfigConnectionId(), sc.ScopeConfigId()), + dal.Where("connection_id = ? AND scope_config_id = ?", connectionId, scopeConfigId), )) - if len(refs) > 0 { + if reflect.ValueOf(refs).Len() > 0 { return errors.Conflict.New("Please delete all data scope(s) before you delete this ScopeConfig.") } errors.Must(tx.Delete(scopeConfig)) diff --cc backend/plugins/azuredevops_go/api/connection_api.go index 45e6be6e8,d29cac85b..9386519ec --- a/backend/plugins/azuredevops_go/api/connection_api.go +++ b/backend/plugins/azuredevops_go/api/connection_api.go @@@ -23,8 -21,10 +23,9 @@@ import "github.com/apache/incubator-devlake/core/errors" "github.com/apache/incubator-devlake/core/plugin" "github.com/apache/incubator-devlake/helpers/pluginhelper/api" + "github.com/apache/incubator-devlake/plugins/azuredevops_go/api/azuredevops" "github.com/apache/incubator-devlake/plugins/azuredevops_go/models" "github.com/apache/incubator-devlake/server/api/shared" - "net/http" ) type AzuredevopsTestConnResponse struct { diff --cc backend/server/services/remote/plugin/default_api.go index 09246ec32,83ead1327..826ae99ef --- a/backend/server/services/remote/plugin/default_api.go +++ b/backend/server/services/remote/plugin/default_api.go @@@ -81,6 -93,28 +81,9 @@@ func GetDefaultAPI "connections/:connectionId/search-remote-scopes": { "GET": papi.SearchRemoteScopes, }, + "scope-config/:id/projects": { + "GET": papi.GetProjectsByScopeConfig, + }, } - papi.createScopeHelper() return resources } - -func (pa *pluginAPI) createScopeHelper() { - params := &api.ReflectionParameters{ - ScopeIdFieldName: "Id", - ScopeIdColumnName: "id", - RawScopeParamName: "ScopeId", - } - pa.scopeHelper = api.NewGenericScopeHelper[remoteModel.RemoteConnection, remoteModel.DynamicScopeModel, remoteModel.RemoteScopeConfig]( - basicRes, - vld, - pa.connhelper, - NewScopeDatabaseHelperImpl(pa, basicRes, params), - params, - &api.ScopeHelperOptions{ - IsRemote: true, - }, - ) -} diff --cc backend/server/services/remote/plugin/scope_config_api.go index 300ba2493,f3a54fd01..aff52938a --- a/backend/server/services/remote/plugin/scope_config_api.go +++ b/backend/server/services/remote/plugin/scope_config_api.go @@@ -31,11 -76,103 +31,15 @@@ func (pa *pluginAPI) PatchScopeConfig(i } func (pa *pluginAPI) GetScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) { - scopeConfig := pa.scopeConfigType.New() - db := basicRes.GetDal() - connectionId, configId, err := extractConfigParam(input.Params) - if err != nil { - return nil, err - } - err = api.CallDB(db.First, scopeConfig, dal.Where("connection_id = ? AND id = ?", connectionId, configId)) - if err != nil { - return nil, errors.Default.Wrap(err, "no scope config with given id") - } - - return &plugin.ApiResourceOutput{Body: scopeConfig.Unwrap()}, nil + return pa.dsHelper.ConnApi.GetDetail(input) } + func (pa *pluginAPI) GetProjectsByScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) { - db := basicRes.GetDal() - configId, err := strconv.ParseUint(input.Params["id"], 10, 64) - if err != nil { - return nil, errors.BadInput.New("invalid configId") - } - - ps := &coreModels.ProjectScopeOutput{} - projectMap := make(map[string]*coreModels.ProjectScope) - // 1. get all scopes that are using the scopeConfigId - scopes := models.NewDynamicScopeModel(pa.scopeType.NewSlice()) - err = api.CallDB(db.All, scopes, dal.Where("scope_config_id = ?", configId)) - if err != nil { - return nil, errors.Default.Wrap(err, "no scope config with given id") - } - for _, s := range scopes.UnwrapSlice() { - // 2. get blueprint id by connection id and scope id - scope := models.NewDynamicScopeModel(pa.scopeType) - _ = scope.From(s) - // result = append(result, scope) - bpScope := []*coreModels.BlueprintScope{} - err = db.All(&bpScope, - dal.Where("plugin_name = ? and connection_id = ? and scope_id = ?", input.Params["plugin"], scope.ConnectionId(), scope.ScopeId()), - ) - if err != nil { - return nil, errors.Default.Wrap(err, "no blueprint scope with given id") - } - for _, bs := range bpScope { - // 3. get project details by blueprint id - bp := coreModels.Blueprint{} - err = db.All(&bp, - dal.Where("id = ?", bs.BlueprintId), - ) - if err != nil { - return nil, errors.Default.Wrap(err, "no blueprint with given id") - } - if project, exists := projectMap[bp.ProjectName]; exists { - project.Scopes = append(project.Scopes, struct { - ScopeID string `json:"scopeId"` - ScopeName string `json:"scopeName"` - }{ - ScopeID: bs.ScopeId, - ScopeName: scope.ScopeName(), - }) - } else { - projectMap[bp.ProjectName] = &coreModels.ProjectScope{ - Name: bp.ProjectName, - BlueprintId: bp.ID, - Scopes: []struct { - ScopeID string `json:"scopeId"` - ScopeName string `json:"scopeName"` - }{ - { - ScopeID: bs.ScopeId, - ScopeName: scope.ScopeName(), - }, - }, - } - } - } - } - // 4. combine all projects - for _, project := range projectMap { - ps.Projects = append(ps.Projects, *project) - } - ps.Count = len(ps.Projects) - - return &plugin.ApiResourceOutput{Body: ps}, nil ++ return pa.dsHelper.ScopeConfigApi.GetProjectsByScopeConfig(input) + } + func (pa *pluginAPI) ListScopeConfigs(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) { - scopeConfigs := pa.scopeConfigType.NewSlice() - limit, offset := api.GetLimitOffset(input.Query, "pageSize", "page") - if limit > 100 { - return nil, errors.BadInput.New("pageSize cannot exceed 100") - } - - db := basicRes.GetDal() - err := api.CallDB(db.All, scopeConfigs, dal.Limit(limit), dal.Offset(offset)) - if err != nil { - return nil, err - } - return &plugin.ApiResourceOutput{Body: scopeConfigs.Unwrap()}, nil + return pa.dsHelper.ScopeConfigApi.GetAll(input) } func (pa *pluginAPI) DeleteScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
