You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by ab...@apache.org on 2024/02/04 02:11:02 UTC
(incubator-devlake) branch main updated: refactor: 5519 bitbucket adopts new dshelpers (#6867)
This is an automated email from the ASF dual-hosted git repository.
abeizn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new a80db0024 refactor: 5519 bitbucket adopts new dshelpers (#6867)
a80db0024 is described below
commit a80db00249ac22ef416af9b9a7dbbc00edbba996
Author: Klesh Wong <zh...@merico.dev>
AuthorDate: Sun Feb 4 10:10:55 2024 +0800
refactor: 5519 bitbucket adopts new dshelpers (#6867)
* refactor: 5519 bitbucket wip
* refactor: bitbucket adopts new dshelper
---
.../pluginhelper/api/ds_connection_api_helper.go | 5 +-
.../plugins/bitbucket/api/blueprint_V200_test.go | 196 ------------------
backend/plugins/bitbucket/api/blueprint_v200.go | 119 ++++++-----
.../api/{connection.go => connection_api.go} | 46 +----
backend/plugins/bitbucket/api/init.go | 43 +---
backend/plugins/bitbucket/api/remote.go | 159 ---------------
backend/plugins/bitbucket/api/remote_api.go | 219 +++++++++++++++++++++
.../bitbucket/api/{scope.go => scope_api.go} | 34 ++--
.../api/{scope_config.go => scope_config_api.go} | 20 +-
backend/plugins/bitbucket/e2e/repo_test.go | 2 +-
backend/plugins/bitbucket/impl/impl.go | 12 +-
backend/plugins/bitbucket/models/repo.go | 3 +-
12 files changed, 327 insertions(+), 531 deletions(-)
diff --git a/backend/helpers/pluginhelper/api/ds_connection_api_helper.go b/backend/helpers/pluginhelper/api/ds_connection_api_helper.go
index b404fce6b..27eeb4383 100644
--- a/backend/helpers/pluginhelper/api/ds_connection_api_helper.go
+++ b/backend/helpers/pluginhelper/api/ds_connection_api_helper.go
@@ -18,9 +18,10 @@ limitations under the License.
package api
import (
- "github.com/apache/incubator-devlake/server/api/shared"
"strconv"
+ "github.com/apache/incubator-devlake/server/api/shared"
+
"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
@@ -47,7 +48,7 @@ func NewDsConnectionApiHelper[
}
}
-func (connApi *DsConnectionApiHelper[C, S, SC]) GetMergedConnection(input *plugin.ApiResourceInput) (*C, error) {
+func (connApi *DsConnectionApiHelper[C, S, SC]) GetMergedConnection(input *plugin.ApiResourceInput) (*C, errors.Error) {
connection, err := connApi.FindByPk(input)
if err != nil {
return nil, errors.BadInput.Wrap(err, "find connection from db")
diff --git a/backend/plugins/bitbucket/api/blueprint_V200_test.go b/backend/plugins/bitbucket/api/blueprint_V200_test.go
deleted file mode 100644
index 25fa0d379..000000000
--- a/backend/plugins/bitbucket/api/blueprint_V200_test.go
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package api
-
-import (
- "database/sql"
- "testing"
-
- "github.com/apache/incubator-devlake/core/dal"
- "gorm.io/gorm/migrator"
-
- coreModels "github.com/apache/incubator-devlake/core/models"
- "github.com/apache/incubator-devlake/core/models/common"
- "github.com/apache/incubator-devlake/core/models/domainlayer"
- "github.com/apache/incubator-devlake/core/models/domainlayer/code"
- "github.com/apache/incubator-devlake/core/models/domainlayer/ticket"
- "github.com/apache/incubator-devlake/core/plugin"
- helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
- "github.com/apache/incubator-devlake/helpers/unithelper"
- mockdal "github.com/apache/incubator-devlake/mocks/core/dal"
- mockplugin "github.com/apache/incubator-devlake/mocks/core/plugin"
- "github.com/apache/incubator-devlake/plugins/bitbucket/models"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/mock"
-)
-
-func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
- connection := &models.BitbucketConnection{
- BaseConnection: helper.BaseConnection{
- Name: "bitbucket-test",
- Model: common.Model{
- ID: 1,
- },
- },
- BitbucketConn: models.BitbucketConn{
- RestConnection: helper.RestConnection{
- Endpoint: "https://api.bitbucket.org/2.0/",
- Proxy: "",
- RateLimitPerHour: 0,
- },
- BasicAuth: helper.BasicAuth{
- Username: "Username",
- Password: "Password",
- },
- },
- }
- mockMeta := mockplugin.NewPluginMeta(t)
- mockMeta.On("RootPkgPath").Return("github.com/apache/incubator-devlake/plugins/bitbucket")
- mockMeta.On("Name").Return("bitbucket").Maybe()
- err := plugin.RegisterPlugin("bitbucket", mockMeta)
- assert.Nil(t, err)
- // Refresh Global Variables and set the sql mock
- mockBasicRes(t)
-
- bs := &coreModels.BlueprintScope{
- ScopeId: "1",
- }
- bpScopes := make([]*coreModels.BlueprintScope, 0)
- bpScopes = append(bpScopes, bs)
-
- plan := make(coreModels.PipelinePlan, len(bpScopes))
- plan, err = makeDataSourcePipelinePlanV200(nil, plan, bpScopes, connection)
- assert.Nil(t, err)
- scopes, err := makeScopesV200(bpScopes, connection)
- assert.Nil(t, err)
-
- expectPlan := coreModels.PipelinePlan{
- coreModels.PipelineStage{
- {
- Plugin: "bitbucket",
- Subtasks: []string{},
- Options: map[string]interface{}{
- "fullName": "likyh/likyhphp",
- "connectionId": uint64(1),
- },
- },
- {
- Plugin: "gitextractor",
- Options: map[string]interface{}{
- "proxy": "",
- "repoId": "bitbucket:BitbucketRepo:1:likyh/likyhphp",
- "name": "likyh/likyhphp",
- "url": "https://Username:Password@this_is_cloneUrl",
- },
- },
- },
- coreModels.PipelineStage{
- {
- Plugin: "refdiff",
- Options: map[string]interface{}{
- "repoId": "bitbucket:BitbucketRepo:1:likyh/likyhphp",
- "tagsLimit": 10,
- "tagsOrder": "reverse semver",
- "tagsPattern": "pattern",
- },
- },
- },
- }
- assert.Equal(t, expectPlan, plan)
- expectScopes := make([]plugin.Scope, 0)
- scopeRepo := &code.Repo{
- DomainEntity: domainlayer.DomainEntity{
- Id: "bitbucket:BitbucketRepo:1:likyh/likyhphp",
- },
- Name: "likyh/likyhphp",
- }
-
- scopeTicket := &ticket.Board{
- DomainEntity: domainlayer.DomainEntity{
- Id: "bitbucket:BitbucketRepo:1:likyh/likyhphp",
- },
- Name: "likyh/likyhphp",
- Description: "",
- Url: "",
- CreatedDate: nil,
- Type: "",
- }
-
- expectScopes = append(expectScopes, scopeRepo, scopeTicket)
- assert.Equal(t, expectScopes, scopes)
-}
-
-func mockBasicRes(t *testing.T) {
- testBitbucketRepo := &models.BitbucketRepo{
- Scope: common.Scope{
- ConnectionId: 1,
- ScopeConfigId: 1,
- },
- BitbucketId: "likyh/likyhphp",
- Name: "test/testRepo",
- CloneUrl: "https://this_is_cloneUrl",
- }
-
- testScopeConfig := &models.BitbucketScopeConfig{
- ScopeConfig: common.ScopeConfig{
- Entities: []string{"CODE", "TICKET"},
- Model: common.Model{
- ID: 1,
- },
- Name: "Bitbucket scope config",
- },
- IssueStatusTodo: "new,open,wantfix",
- Refdiff: map[string]interface{}{
- "tagsPattern": "pattern",
- "tagsLimit": 10,
- "tagsOrder": "reverse semver",
- },
- }
- var testColumTypes = []dal.ColumnMeta{
- migrator.ColumnType{
- NameValue: sql.NullString{
- String: "abc",
- Valid: true,
- },
- },
- }
-
- // Refresh Global Variables and set the sql mock
- mockRes := unithelper.DummyBasicRes(func(mockDal *mockdal.Dal) {
- mockDal.On("First", mock.AnythingOfType("*models.BitbucketRepo"), mock.Anything).Run(func(args mock.Arguments) {
- dst := args.Get(0).(*models.BitbucketRepo)
- *dst = *testBitbucketRepo
- }).Return(nil)
-
- mockDal.On("First", mock.AnythingOfType("*models.BitbucketScopeConfig"), mock.Anything).Run(func(args mock.Arguments) {
- dst := args.Get(0).(*models.BitbucketScopeConfig)
- *dst = *testScopeConfig
- }).Return(nil)
- mockDal.On("GetPrimarykeyColumns", mock.AnythingOfType("*models.BitbucketConnection"), mock.Anything).Run(nil).Return(
- testColumTypes, nil)
- mockDal.On("GetColumns", mock.AnythingOfType("models.BitbucketConnection"), mock.Anything).Run(nil).Return(
- testColumTypes, nil)
- mockDal.On("GetColumns", mock.AnythingOfType("models.BitbucketRepo"), mock.Anything).Run(nil).Return(
- testColumTypes, nil)
- mockDal.On("GetColumns", mock.AnythingOfType("models.BitbucketScopeConfig"), mock.Anything).Run(nil).Return(
- testColumTypes, nil)
- })
- p := mockplugin.NewPluginMeta(t)
- p.On("Name").Return("dummy").Maybe()
- Init(mockRes, p)
-}
diff --git a/backend/plugins/bitbucket/api/blueprint_v200.go b/backend/plugins/bitbucket/api/blueprint_v200.go
index d1b562103..f1547df5c 100644
--- a/backend/plugins/bitbucket/api/blueprint_v200.go
+++ b/backend/plugins/bitbucket/api/blueprint_v200.go
@@ -18,6 +18,7 @@ limitations under the License.
package api
import (
+ "context"
"net/url"
"github.com/apache/incubator-devlake/core/errors"
@@ -30,6 +31,7 @@ import (
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/core/utils"
helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ "github.com/apache/incubator-devlake/helpers/srvhelper"
"github.com/apache/incubator-devlake/plugins/bitbucket/models"
"github.com/apache/incubator-devlake/plugins/bitbucket/tasks"
)
@@ -39,19 +41,28 @@ func MakeDataSourcePipelinePlanV200(
connectionId uint64,
bpScopes []*coreModels.BlueprintScope,
) (coreModels.PipelinePlan, []plugin.Scope, errors.Error) {
- // get the connection info for url
- connection := &models.BitbucketConnection{}
- err := connectionHelper.FirstById(connection, connectionId)
+ // load connection, scope and scopeConfig from the db
+ connection, err := dsHelper.ConnSrv.FindByPk(connectionId)
+ if err != nil {
+ return nil, nil, err
+ }
+ scopeDetails, err := dsHelper.ScopeSrv.MapScopeDetails(connectionId, bpScopes)
if err != nil {
return nil, nil, err
}
- plan := make(coreModels.PipelinePlan, len(bpScopes))
- plan, err = makeDataSourcePipelinePlanV200(subtaskMetas, plan, bpScopes, connection)
+ // needed for the connection to populate its access tokens
+ // if AppKey authentication method is selected
+ _, err = helper.NewApiClientFromConnection(context.TODO(), basicRes, connection)
if err != nil {
return nil, nil, err
}
- scopes, err := makeScopesV200(bpScopes, connection)
+
+ plan, err := makeDataSourcePipelinePlanV200(subtaskMetas, scopeDetails, connection)
+ if err != nil {
+ return nil, nil, err
+ }
+ scopes, err := makeScopesV200(scopeDetails, connection)
if err != nil {
return nil, nil, err
}
@@ -61,20 +72,32 @@ func MakeDataSourcePipelinePlanV200(
func makeDataSourcePipelinePlanV200(
subtaskMetas []plugin.SubTaskMeta,
- plan coreModels.PipelinePlan,
- bpScopes []*coreModels.BlueprintScope,
+ scopeDetails []*srvhelper.ScopeDetail[models.BitbucketRepo, models.BitbucketScopeConfig],
connection *models.BitbucketConnection,
) (coreModels.PipelinePlan, errors.Error) {
- for i, bpScope := range bpScopes {
+ plan := make(coreModels.PipelinePlan, len(scopeDetails))
+ for i, scopeDetail := range scopeDetails {
+ bitbucketRepo, scopeConfig := scopeDetail.Scope, scopeDetail.ScopeConfig
stage := plan[i]
if stage == nil {
stage = coreModels.PipelineStage{}
}
- // get repo and scope config from db
- repo, scopeConfig, err := scopeHelper.DbHelper().GetScopeAndConfig(connection.ID, bpScope.ScopeId)
+ // construct task options for Jira
+ task, err := helper.MakePipelinePlanTask(
+ "bamboo",
+ subtaskMetas,
+ scopeConfig.Entities,
+ tasks.BitbucketOptions{
+ ConnectionId: bitbucketRepo.ConnectionId,
+ FullName: bitbucketRepo.BitbucketId,
+ },
+ )
if err != nil {
return nil, err
}
+
+ stage = append(stage, task)
+
// refdiff
if scopeConfig != nil && scopeConfig.Refdiff != nil {
// add a new task to next stage
@@ -83,7 +106,7 @@ func makeDataSourcePipelinePlanV200(
plan = append(plan, nil)
}
refdiffOp := scopeConfig.Refdiff
- refdiffOp["repoId"] = didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, repo.BitbucketId)
+ refdiffOp["repoId"] = didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, bitbucketRepo.BitbucketId)
plan[j] = coreModels.PipelineStage{
{
Plugin: "refdiff",
@@ -92,33 +115,9 @@ func makeDataSourcePipelinePlanV200(
}
scopeConfig.Refdiff = nil
}
-
- // construct task options for bitbucket
- op := &tasks.BitbucketOptions{
- ConnectionId: repo.ConnectionId,
- FullName: repo.BitbucketId,
- }
- options, err := tasks.EncodeTaskOptions(op)
- if err != nil {
- return nil, err
- }
-
- subtasks, err := helper.MakePipelinePlanSubtasks(subtaskMetas, scopeConfig.Entities)
- if err != nil {
- return nil, err
- }
- stage = append(stage, &coreModels.PipelineTask{
- Plugin: "bitbucket",
- Subtasks: subtasks,
- Options: options,
- })
- if err != nil {
- return nil, err
- }
-
// add gitex stage
if utils.StringsContains(scopeConfig.Entities, plugin.DOMAIN_TYPE_CODE) {
- cloneUrl, err := errors.Convert01(url.Parse(repo.CloneUrl))
+ cloneUrl, err := errors.Convert01(url.Parse(bitbucketRepo.CloneUrl))
if err != nil {
return nil, err
}
@@ -127,8 +126,8 @@ func makeDataSourcePipelinePlanV200(
Plugin: "gitextractor",
Options: map[string]interface{}{
"url": cloneUrl.String(),
- "name": repo.BitbucketId,
- "repoId": didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, repo.BitbucketId),
+ "name": bitbucketRepo.BitbucketId,
+ "repoId": didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, bitbucketRepo.BitbucketId),
"proxy": connection.Proxy,
},
})
@@ -139,44 +138,44 @@ func makeDataSourcePipelinePlanV200(
return plan, nil
}
-func makeScopesV200(bpScopes []*coreModels.BlueprintScope, connection *models.BitbucketConnection) ([]plugin.Scope, errors.Error) {
+func makeScopesV200(
+ scopeDetails []*srvhelper.ScopeDetail[models.BitbucketRepo, models.BitbucketScopeConfig],
+ connection *models.BitbucketConnection,
+) ([]plugin.Scope, errors.Error) {
scopes := make([]plugin.Scope, 0)
- for _, bpScope := range bpScopes {
- repo, scopeConfig, err := scopeHelper.DbHelper().GetScopeAndConfig(connection.ID, bpScope.ScopeId)
- if err != nil {
- return nil, err
- }
+ idgen := didgen.NewDomainIdGenerator(&models.BitbucketRepo{})
+ for _, scopeDetail := range scopeDetails {
+ scope, scopeConfig := scopeDetail.Scope, scopeDetail.ScopeConfig
+ id := idgen.Generate(connection.ID, scope.BitbucketId)
+
if utils.StringsContains(scopeConfig.Entities, plugin.DOMAIN_TYPE_CODE_REVIEW) ||
utils.StringsContains(scopeConfig.Entities, plugin.DOMAIN_TYPE_CODE) ||
utils.StringsContains(scopeConfig.Entities, plugin.DOMAIN_TYPE_CROSS) {
// if we don't need to collect gitex, we need to add repo to scopes here
- scopeRepo := &code.Repo{
+ scopes = append(scopes, &code.Repo{
DomainEntity: domainlayer.DomainEntity{
- Id: didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, repo.BitbucketId),
+ Id: id,
},
- Name: repo.BitbucketId,
- }
- scopes = append(scopes, scopeRepo)
+ Name: scope.BitbucketId,
+ })
}
// add cicd_scope to scopes
if utils.StringsContains(scopeConfig.Entities, plugin.DOMAIN_TYPE_CICD) {
- scopeCICD := &devops.CicdScope{
+ scopes = append(scopes, &devops.CicdScope{
DomainEntity: domainlayer.DomainEntity{
- Id: didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, repo.BitbucketId),
+ Id: id,
},
- Name: repo.BitbucketId,
- }
- scopes = append(scopes, scopeCICD)
+ Name: scope.BitbucketId,
+ })
}
// add board to scopes
if utils.StringsContains(scopeConfig.Entities, plugin.DOMAIN_TYPE_TICKET) {
- scopeTicket := &ticket.Board{
+ scopes = append(scopes, &ticket.Board{
DomainEntity: domainlayer.DomainEntity{
- Id: didgen.NewDomainIdGenerator(&models.BitbucketRepo{}).Generate(connection.ID, repo.BitbucketId),
+ Id: id,
},
- Name: repo.BitbucketId,
- }
- scopes = append(scopes, scopeTicket)
+ Name: scope.BitbucketId,
+ })
}
}
return scopes, nil
diff --git a/backend/plugins/bitbucket/api/connection.go b/backend/plugins/bitbucket/api/connection_api.go
similarity index 81%
rename from backend/plugins/bitbucket/api/connection.go
rename to backend/plugins/bitbucket/api/connection_api.go
index ad1b9a9a7..f9f185389 100644
--- a/backend/plugins/bitbucket/api/connection.go
+++ b/backend/plugins/bitbucket/api/connection_api.go
@@ -100,8 +100,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// @Failure 500 {string} errcode.Error "Internal Error"
// @Router /plugins/bitbucket/{connectionId}/test [POST]
func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connection := &models.BitbucketConnection{}
- err := connectionHelper.First(connection, input.Params)
+ connection, err := dsHelper.ConnApi.GetMergedConnection(input)
if err != nil {
return nil, errors.BadInput.Wrap(err, "find connection from db")
}
@@ -125,13 +124,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// @Failure 500 {string} errcode.Error "Internal Error"
// @Router /plugins/bitbucket/connections [POST]
func PostConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- // update from request and save to database
- connection := &models.BitbucketConnection{}
- err := connectionHelper.Create(connection, input)
- if err != nil {
- return nil, err
- }
- return &plugin.ApiResourceOutput{Body: connection.Sanitize(), Status: http.StatusOK}, nil
+ return dsHelper.ConnApi.Post(input)
}
// @Summary patch bitbucket connection
@@ -143,17 +136,7 @@ func PostConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// @Failure 500 {string} errcode.Error "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId} [PATCH]
func PatchConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connection := &models.BitbucketConnection{}
- if err := connectionHelper.First(&connection, input.Params); err != nil {
- return nil, err
- }
- if err := (&models.BitbucketConnection{}).MergeFromRequest(connection, input.Body); err != nil {
- return nil, errors.Convert(err)
- }
- if err := connectionHelper.SaveWithCreateOrUpdate(connection); err != nil {
- return nil, err
- }
- return &plugin.ApiResourceOutput{Body: connection.Sanitize()}, nil
+ return dsHelper.ConnApi.Patch(input)
}
// @Summary delete a bitbucket connection
@@ -165,14 +148,7 @@ func PatchConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// @Failure 500 {string} errcode.Error "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId} [DELETE]
func DeleteConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- conn := &models.BitbucketConnection{}
- output, err := connectionHelper.Delete(conn, input)
- if err != nil {
- return output, err
- }
- output.Body = conn.Sanitize()
- return output, nil
-
+ return dsHelper.ConnApi.Delete(input)
}
// @Summary get all bitbucket connections
@@ -183,15 +159,7 @@ func DeleteConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput
// @Failure 500 {string} errcode.Error "Internal Error"
// @Router /plugins/bitbucket/connections [GET]
func ListConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- var connections []models.BitbucketConnection
- err := connectionHelper.List(&connections)
- if err != nil {
- return nil, err
- }
- for idx, c := range connections {
- connections[idx] = c.Sanitize()
- }
- return &plugin.ApiResourceOutput{Body: connections, Status: http.StatusOK}, nil
+ return dsHelper.ConnApi.GetAll(input)
}
// @Summary get bitbucket connection detail
@@ -202,7 +170,5 @@ func ListConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// @Failure 500 {string} errcode.Error "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId} [GET]
func GetConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- connection := &models.BitbucketConnection{}
- err := connectionHelper.First(connection, input.Params)
- return &plugin.ApiResourceOutput{Body: connection.Sanitize()}, err
+ return dsHelper.ConnApi.GetDetail(input)
}
diff --git a/backend/plugins/bitbucket/api/init.go b/backend/plugins/bitbucket/api/init.go
index 4676dacfd..5e0dcb98c 100644
--- a/backend/plugins/bitbucket/api/init.go
+++ b/backend/plugins/bitbucket/api/init.go
@@ -25,48 +25,16 @@ import (
"github.com/go-playground/validator/v10"
)
+var basicRes context.BasicRes
var vld *validator.Validate
-var connectionHelper *api.ConnectionApiHelper
-var scopeHelper *api.ScopeApiHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketScopeConfig]
-var remoteHelper *api.RemoteApiHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketApiRepo, models.GroupResponse]
-var scHelper *api.ScopeConfigHelper[models.BitbucketScopeConfig, *models.BitbucketScopeConfig]
var dsHelper *api.DsHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketScopeConfig]
-var basicRes context.BasicRes
+var raProxy *api.DsRemoteApiProxyHelper[models.BitbucketConnection]
+var raScopeList *api.DsRemoteApiScopeListHelper[models.BitbucketConnection, models.BitbucketRepo, BitbucketRemotePagination]
+var raScopeSearch *api.DsRemoteApiScopeSearchHelper[models.BitbucketConnection, models.BitbucketRepo]
func Init(br context.BasicRes, p plugin.PluginMeta) {
basicRes = br
- vld = validator.New()
- connectionHelper = api.NewConnectionHelper(
- basicRes,
- vld,
- p.Name(),
- )
- params := &api.ReflectionParameters{
- ScopeIdFieldName: "BitbucketId",
- ScopeIdColumnName: "bitbucket_id",
- RawScopeParamName: "FullName",
- SearchScopeParamName: "name",
- }
- scopeHelper = api.NewScopeHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketScopeConfig](
- basicRes,
- vld,
- connectionHelper,
- api.NewScopeDatabaseHelperImpl[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketScopeConfig](
- basicRes, connectionHelper, params),
- params,
- nil,
- )
- remoteHelper = api.NewRemoteHelper[models.BitbucketConnection, models.BitbucketRepo, models.BitbucketApiRepo, models.GroupResponse](
- basicRes,
- vld,
- connectionHelper,
- )
- scHelper = api.NewScopeConfigHelper[models.BitbucketScopeConfig, *models.BitbucketScopeConfig](
- basicRes,
- vld,
- p.Name(),
- )
dsHelper = api.NewDataSourceHelper[
models.BitbucketConnection, models.BitbucketRepo, models.BitbucketScopeConfig,
@@ -80,5 +48,8 @@ func Init(br context.BasicRes, p plugin.PluginMeta) {
nil,
nil,
)
+ raProxy = api.NewDsRemoteApiProxyHelper[models.BitbucketConnection](dsHelper.ConnApi.ModelApiHelper)
+ raScopeList = api.NewDsRemoteApiScopeListHelper[models.BitbucketConnection, models.BitbucketRepo, BitbucketRemotePagination](raProxy, listBitbucketRemoteScopes)
+ raScopeSearch = api.NewDsRemoteApiScopeSearchHelper[models.BitbucketConnection, models.BitbucketRepo](raProxy, searchBitbucketRepos)
}
diff --git a/backend/plugins/bitbucket/api/remote.go b/backend/plugins/bitbucket/api/remote.go
deleted file mode 100644
index 820c1ece7..000000000
--- a/backend/plugins/bitbucket/api/remote.go
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package api
-
-import (
- gocontext "context"
- "fmt"
- "net/http"
- "net/url"
- "strings"
-
- "github.com/apache/incubator-devlake/core/context"
- "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/bitbucket/models"
-)
-
-// RemoteScopes list all available scope for users
-// @Summary list all available scope for users
-// @Description list all available scope for users
-// @Tags plugins/bitbucket
-// @Accept application/json
-// @Param connectionId path int false "connection ID"
-// @Param groupId query string false "group ID"
-// @Param pageToken query string false "page Token"
-// @Success 200 {object} api.RemoteScopesOutput
-// @Failure 400 {object} shared.ApiBody "Bad Request"
-// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/bitbucket/connections/{connectionId}/remote-scopes [GET]
-func RemoteScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return remoteHelper.GetScopesFromRemote(input,
- func(basicRes context.BasicRes, gid string, queryData *api.RemoteQueryData, connection models.BitbucketConnection) ([]models.GroupResponse, errors.Error) {
- if gid != "" {
- return nil, nil
- }
- query := initialQuery(queryData)
-
- apiClient, err := api.NewApiClientFromConnection(gocontext.TODO(), basicRes, &connection)
- if err != nil {
- return nil, errors.BadInput.Wrap(err, "failed to get create apiClient")
- }
- var res *http.Response
- query.Set("sort", "workspace.slug")
- query.Set("fields", "values.workspace.slug,values.workspace.name,pagelen,page,size")
- res, err = apiClient.Get("/user/permissions/workspaces", query, nil)
- if err != nil {
- return nil, err
- }
-
- resBody := &models.WorkspaceResponse{}
- err = api.UnmarshalResponse(res, resBody)
- if err != nil {
- return nil, err
- }
-
- return resBody.Values, err
- },
- func(basicRes context.BasicRes, gid string, queryData *api.RemoteQueryData, connection models.BitbucketConnection) ([]models.BitbucketApiRepo, errors.Error) {
- if gid == "" {
- return nil, nil
- }
- query := initialQuery(queryData)
-
- apiClient, err := api.NewApiClientFromConnection(gocontext.TODO(), basicRes, &connection)
- if err != nil {
- return nil, errors.BadInput.Wrap(err, "failed to get create apiClient")
- }
- var res *http.Response
- query.Set("fields", "values.name,values.full_name,values.language,values.description,values.owner.display_name,values.created_on,values.updated_on,values.links.clone,values.links.html,pagelen,page,size")
- // list projects part
- res, err = apiClient.Get(fmt.Sprintf("/repositories/%s", gid), query, nil)
- if err != nil {
- return nil, err
- }
- var resBody models.ReposResponse
- err = api.UnmarshalResponse(res, &resBody)
- if err != nil {
- return nil, err
- }
- return resBody.Values, err
- },
- )
-}
-
-// SearchRemoteScopes use the Search API and only return project
-// @Summary use the Search API and only return project
-// @Description use the Search API and only return project
-// @Tags plugins/bitbucket
-// @Accept application/json
-// @Param connectionId path int false "connection ID"
-// @Param search query string false "search"
-// @Param page query int false "page number"
-// @Param pageSize query int false "page size per page"
-// @Success 200 {object} api.SearchRemoteScopesOutput
-// @Failure 400 {object} shared.ApiBody "Bad Request"
-// @Failure 500 {object} shared.ApiBody "Internal Error"
-// @Router /plugins/bitbucket/connections/{connectionId}/search-remote-scopes [GET]
-func SearchRemoteScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return remoteHelper.SearchRemoteScopes(input,
- func(basicRes context.BasicRes, queryData *api.RemoteQueryData, connection models.BitbucketConnection) ([]models.BitbucketApiRepo, errors.Error) {
- // create api client
- apiClient, err := api.NewApiClientFromConnection(gocontext.TODO(), basicRes, &connection)
- if err != nil {
- return nil, errors.BadInput.Wrap(err, "failed to get create apiClient")
- }
-
- // request search
- query := initialQuery(queryData)
- if len(queryData.Search) == 0 {
- return nil, errors.BadInput.New("empty search query")
- }
- s := queryData.Search[0]
- if strings.Contains(s, `"`) {
- return nil, errors.BadInput.New("search query contains invalid character")
- }
- query.Set("sort", "name")
- query.Set("fields", "values.name,values.full_name,values.language,values.description,values.owner.display_name,values.created_on,values.updated_on,values.links.clone,values.links.html,pagelen,page,size")
- query.Set("role", "member")
- query.Set("q", fmt.Sprintf(`full_name~"%s"`, s))
-
- // list repos part
- res, err := apiClient.Get("/repositories", query, nil)
- if err != nil {
- return nil, err
- }
-
- var resBody models.ReposResponse
- err = api.UnmarshalResponse(res, &resBody)
- if err != nil {
- return nil, err
- }
-
- return resBody.Values, err
- },
- )
-}
-
-func initialQuery(queryData *api.RemoteQueryData) url.Values {
- query := url.Values{}
- query.Set("page", fmt.Sprintf("%v", queryData.Page))
- query.Set("pagelen", fmt.Sprintf("%v", queryData.PerPage))
- return query
-}
diff --git a/backend/plugins/bitbucket/api/remote_api.go b/backend/plugins/bitbucket/api/remote_api.go
new file mode 100644
index 000000000..d81c0d027
--- /dev/null
+++ b/backend/plugins/bitbucket/api/remote_api.go
@@ -0,0 +1,219 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package api
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+ dsmodels "github.com/apache/incubator-devlake/helpers/pluginhelper/api/models"
+ "github.com/apache/incubator-devlake/plugins/bitbucket/models"
+)
+
+type BitbucketRemotePagination struct {
+ Page int `json:"page" validate:"required"`
+ PageLen int `json:"pagelen" validate:"required"`
+}
+
+func listBitbucketRemoteScopes(
+ connection *models.BitbucketConnection,
+ apiClient plugin.ApiClient,
+ groupId string,
+ page BitbucketRemotePagination,
+) (
+ children []dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo],
+ nextPage *BitbucketRemotePagination,
+ err errors.Error,
+) {
+ if page.Page == 0 {
+ page.Page = 1
+ }
+ if page.PageLen == 0 {
+ page.PageLen = 100
+ }
+
+ if groupId == "" {
+ return listBitbucketWorkspaces(apiClient, page)
+ }
+ return listBitbucketRepos(apiClient, groupId, page)
+}
+
+func listBitbucketWorkspaces(
+ apiClient plugin.ApiClient,
+ page BitbucketRemotePagination,
+) (
+ children []dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo],
+ nextPage *BitbucketRemotePagination,
+ err errors.Error,
+) {
+ var res *http.Response
+ res, err = apiClient.Get(
+ "/user/permissions/workspaces",
+ url.Values{
+ "sort": {"workspace.slug"},
+ "fields": {"values.workspace.slug,values.workspace.name,pagelen,page,size"},
+ "page": {fmt.Sprintf("%v", page.Page)},
+ "pagelen": {fmt.Sprintf("%v", page.PageLen)},
+ },
+ nil,
+ )
+ if err != nil {
+ return
+ }
+
+ resBody := &models.WorkspaceResponse{}
+ err = api.UnmarshalResponse(res, resBody)
+ if err != nil {
+ return
+ }
+ for _, r := range resBody.Values {
+ children = append(children, dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo]{
+ Type: api.RAS_ENTRY_TYPE_GROUP,
+ Id: r.Workspace.Slug,
+ Name: r.Workspace.Name,
+ FullName: r.Workspace.Name,
+ })
+ }
+ return
+}
+
+func listBitbucketRepos(
+ apiClient plugin.ApiClient,
+ workspace string,
+ page BitbucketRemotePagination,
+) (
+ children []dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo],
+ nextPage *BitbucketRemotePagination,
+ err errors.Error,
+) {
+
+ var res *http.Response
+ // list projects part
+ res, err = apiClient.Get(fmt.Sprintf("/repositories/%s", workspace), url.Values{
+ "fields": {"values.name,values.full_name,values.language,values.description,values.owner.display_name,values.created_on,values.updated_on,values.links.clone,values.links.html,pagelen,page,size"},
+ "page": {fmt.Sprintf("%v", page.Page)},
+ "pagelen": {fmt.Sprintf("%v", page.PageLen)},
+ }, nil)
+ if err != nil {
+ return
+ }
+ var resBody models.ReposResponse
+ err = api.UnmarshalResponse(res, &resBody)
+ if err != nil {
+ return
+ }
+
+ for _, r := range resBody.Values {
+ children = append(children, dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo]{
+ Type: api.RAS_ENTRY_TYPE_SCOPE,
+ Id: r.FullName,
+ ParentId: &workspace,
+ Name: r.Name,
+ FullName: r.FullName,
+ Data: r.ConvertApiScope(),
+ })
+ }
+ return
+}
+
+func searchBitbucketRepos(
+ apiClient plugin.ApiClient,
+ params *dsmodels.DsRemoteApiScopeSearchParams,
+) (
+ children []dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo],
+ err errors.Error,
+) {
+ var res *http.Response
+ res, err = apiClient.Get(
+ "/repositories",
+ url.Values{
+ "sort": {"name"},
+ "fields": {"values.name,values.full_name,values.language,values.description,values.owner.display_name,values.created_on,values.updated_on,values.links.clone,values.links.html,pagelen,page,size"},
+ "role": {"member"},
+ "q": {fmt.Sprintf(`full_name~"%s"`, params.Search)},
+ "page": {fmt.Sprintf("%v", params.Page)},
+ "pagelen": {fmt.Sprintf("%v", params.PageSize)},
+ },
+ nil,
+ )
+ if err != nil {
+ return nil, err
+ }
+ var resBody models.ReposResponse
+ err = api.UnmarshalResponse(res, &resBody)
+ if err != nil {
+ return
+ }
+ for _, r := range resBody.Values {
+ children = append(children, dsmodels.DsRemoteApiScopeListEntry[models.BitbucketRepo]{
+ Type: api.RAS_ENTRY_TYPE_SCOPE,
+ Id: r.FullName,
+ Name: r.Name,
+ FullName: r.FullName,
+ Data: r.ConvertApiScope(),
+ })
+ }
+ return
+}
+
+// RemoteScopes list all available scopes on the remote server
+// @Summary list all available scopes on the remote server
+// @Description list all available scopes on the remote server
+// @Accept application/json
+// @Param connectionId path int false "connection ID"
+// @Param groupId query string false "group ID"
+// @Param pageToken query string false "page Token"
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Success 200 {object} dsmodels.DsRemoteApiScopeList[models.BitbucketRepo]
+// @Tags plugins/bitbucket
+// @Router /plugins/bitbucket/connections/{connectionId}/remote-scopes [GET]
+func RemoteScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return raScopeList.Get(input)
+}
+
+// SearchRemoteScopes searches scopes on the remote server
+// @Summary searches scopes on the remote server
+// @Description searches scopes on the remote server
+// @Accept application/json
+// @Param connectionId path int false "connection ID"
+// @Param search query string false "search"
+// @Param page query int false "page number"
+// @Param pageSize query int false "page size per page"
+// @Failure 400 {object} shared.ApiBody "Bad Request"
+// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Success 200 {object} dsmodels.DsRemoteApiScopeList[models.BitbucketRepo] "the parentIds are always null"
+// @Tags plugins/bitbucket
+// @Router /plugins/bitbucket/connections/{connectionId}/search-remote-scopes [GET]
+func SearchRemoteScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return raScopeSearch.Get(input)
+}
+
+// @Summary Remote server API proxy
+// @Description Forward API requests to the specified remote server
+// @Param connectionId path int true "connection ID"
+// @Param path path string true "path to a API endpoint"
+// @Tags plugins/bitbucket
+// @Router /plugins/bitbucket/connections/{connectionId}/proxy/{path} [GET]
+func Proxy(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return raProxy.Proxy(input)
+}
diff --git a/backend/plugins/bitbucket/api/scope.go b/backend/plugins/bitbucket/api/scope_api.go
similarity index 84%
rename from backend/plugins/bitbucket/api/scope.go
rename to backend/plugins/bitbucket/api/scope_api.go
index c64e400f2..13fddfe2e 100644
--- a/backend/plugins/bitbucket/api/scope.go
+++ b/backend/plugins/bitbucket/api/scope_api.go
@@ -26,29 +26,25 @@ import (
"github.com/apache/incubator-devlake/plugins/bitbucket/models"
)
-type ScopeRes struct {
- models.BitbucketRepo
- api.ScopeResDoc[models.BitbucketScopeConfig]
-}
-
-type ScopeReq api.ScopeReq[models.BitbucketRepo]
+type PutScopesReqBody api.PutScopesReqBody[models.BitbucketRepo]
+type ScopeDetail api.ScopeDetail[models.BitbucketRepo, models.BitbucketScopeConfig]
-// PutScope create or update repo
+// PutScopes create or update repo
// @Summary create or update repo
// @Description Create or update repo
// @Tags plugins/bitbucket
// @Accept application/json
// @Param connectionId path int true "connection ID"
-// @Param scope body ScopeReq true "json"
+// @Param scope body PutScopesReqBody true "json"
// @Success 200 {object} []models.BitbucketRepo
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scopes [PUT]
-func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scopeHelper.Put(input)
+func PutScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return dsHelper.ScopeApi.PutMultiple(input)
}
-// UpdateScope patch to repo
+// PatchScope patch to repo
// @Summary patch to repo
// @Description patch to repo
// @Tags plugins/bitbucket
@@ -60,12 +56,12 @@ func PutScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{scopeId} [PATCH]
-func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+func PatchScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
input.Params["scopeId"] = strings.TrimLeft(input.Params["scopeId"], "/")
- return scopeHelper.Update(input)
+ return dsHelper.ScopeApi.Patch(input)
}
-// GetScopeList get repos
+// GetScopes get repos
// @Summary get repos
// @Description get repos
// @Tags plugins/bitbucket
@@ -74,12 +70,12 @@ func UpdateScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, err
// @Param pageSize query int false "page size, default 50"
// @Param page query int false "page size, default 1"
// @Param blueprints query bool false "also return blueprints using these scopes as part of the payload"
-// @Success 200 {object} []ScopeRes
+// @Success 200 {object} []ScopeDetail
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scopes/ [GET]
-func GetScopeList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scopeHelper.GetScopeList(input)
+func GetScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return dsHelper.ScopeApi.GetPage(input)
}
func GetScopeDispatcher(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
@@ -103,7 +99,7 @@ func GetScopeDispatcher(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutp
// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{scopeId} [GET]
func GetScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
input.Params["scopeId"] = strings.TrimLeft(input.Params["scopeId"], "/")
- return scopeHelper.GetScope(input)
+ return dsHelper.ScopeApi.GetScopeDetail(input)
}
// DeleteScope delete plugin data associated with the scope and optionally the scope itself
@@ -120,5 +116,5 @@ func GetScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors
// @Router /plugins/bitbucket/connections/{connectionId}/scopes/{scopeId} [DELETE]
func DeleteScope(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
input.Params["scopeId"] = strings.TrimLeft(input.Params["scopeId"], "/")
- return scopeHelper.Delete(input)
+ return dsHelper.ScopeApi.Delete(input)
}
diff --git a/backend/plugins/bitbucket/api/scope_config.go b/backend/plugins/bitbucket/api/scope_config_api.go
similarity index 87%
rename from backend/plugins/bitbucket/api/scope_config.go
rename to backend/plugins/bitbucket/api/scope_config_api.go
index fc0defde0..1e894165c 100644
--- a/backend/plugins/bitbucket/api/scope_config.go
+++ b/backend/plugins/bitbucket/api/scope_config_api.go
@@ -22,22 +22,22 @@ import (
"github.com/apache/incubator-devlake/core/plugin"
)
-// CreateScopeConfig create scope config for Bitbucket
+// PostScopeConfig create scope config for Bitbucket
// @Summary create scope config for Bitbucket
// @Description create scope config for Bitbucket
-// @Tags plugins/bitbucket
// @Accept application/json
// @Param connectionId path int true "connectionId"
// @Param scopeConfig body models.BitbucketScopeConfig true "scope config"
// @Success 200 {object} models.BitbucketScopeConfig
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
+// @Tags plugins/bitbucket
// @Router /plugins/bitbucket/connections/{connectionId}/scope-configs [POST]
-func CreateScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scHelper.Create(input)
+func PostScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return dsHelper.ScopeConfigApi.Post(input)
}
-// UpdateScopeConfig update scope config for Bitbucket
+// PatchScopeConfig update scope config for Bitbucket
// @Summary update scope config for Bitbucket
// @Description update scope config for Bitbucket
// @Tags plugins/bitbucket
@@ -49,8 +49,8 @@ func CreateScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutpu
// @Failure 400 {object} shared.ApiBody "Bad Request"
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scope-configs/{id} [PATCH]
-func UpdateScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scHelper.Update(input)
+func PatchScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
+ return dsHelper.ScopeConfigApi.Patch(input)
}
// GetScopeConfig return one scope config
@@ -64,7 +64,7 @@ func UpdateScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutpu
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scope-configs/{id} [GET]
func GetScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scHelper.Get(input)
+ return dsHelper.ScopeConfigApi.GetDetail(input)
}
// GetScopeConfigList return all scope configs
@@ -79,7 +79,7 @@ func GetScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scope-configs [GET]
func GetScopeConfigList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scHelper.List(input)
+ return dsHelper.ScopeConfigApi.GetAll(input)
}
// DeleteScopeConfig delete a scope config
@@ -93,5 +93,5 @@ func GetScopeConfigList(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutp
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/bitbucket/connections/{connectionId}/scope-configs/{id} [DELETE]
func DeleteScopeConfig(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
- return scHelper.Delete(input)
+ return dsHelper.ScopeConfigApi.Delete(input)
}
diff --git a/backend/plugins/bitbucket/e2e/repo_test.go b/backend/plugins/bitbucket/e2e/repo_test.go
index 239bf6c88..abc764650 100644
--- a/backend/plugins/bitbucket/e2e/repo_test.go
+++ b/backend/plugins/bitbucket/e2e/repo_test.go
@@ -59,7 +59,7 @@ func TestRepoDataFlow(t *testing.T) {
// verify extraction
dataflowTester.FlushTabler(&models.BitbucketRepo{})
- scope := apiRepo.ConvertApiScope().(*models.BitbucketRepo)
+ scope := apiRepo.ConvertApiScope()
scope.ConnectionId = 1
err := dataflowTester.Dal.CreateIfNotExist(scope)
assert.Nil(t, err)
diff --git a/backend/plugins/bitbucket/impl/impl.go b/backend/plugins/bitbucket/impl/impl.go
index 868288618..9e29984ba 100644
--- a/backend/plugins/bitbucket/impl/impl.go
+++ b/backend/plugins/bitbucket/impl/impl.go
@@ -216,7 +216,7 @@ func (p Bitbucket) ApiResources() map[string]map[string]plugin.ApiResourceHandle
// GetScope "connections/:connectionId/scopes/:scopeId"
// Because there may be slash in scopeId, so we handle it manually.
"GET": api.GetScopeDispatcher,
- "PATCH": api.UpdateScope,
+ "PATCH": api.PatchScope,
"DELETE": api.DeleteScope,
},
"connections/:connectionId/remote-scopes": {
@@ -226,15 +226,15 @@ func (p Bitbucket) ApiResources() map[string]map[string]plugin.ApiResourceHandle
"GET": api.SearchRemoteScopes,
},
"connections/:connectionId/scopes": {
- "GET": api.GetScopeList,
- "PUT": api.PutScope,
+ "GET": api.GetScopes,
+ "PUT": api.PutScopes,
},
"connections/:connectionId/scope-configs": {
- "POST": api.CreateScopeConfig,
+ "POST": api.PostScopeConfig,
"GET": api.GetScopeConfigList,
},
"connections/:connectionId/scope-configs/:id": {
- "PATCH": api.UpdateScopeConfig,
+ "PATCH": api.PatchScopeConfig,
"GET": api.GetScopeConfig,
"DELETE": api.DeleteScopeConfig,
},
@@ -275,7 +275,7 @@ func EnrichOptions(taskCtx plugin.TaskContext,
return err
}
logger.Debug(fmt.Sprintf("Current repo: %s", repo.FullName))
- scope := repo.ConvertApiScope().(*models.BitbucketRepo)
+ scope := repo.ConvertApiScope()
scope.ConnectionId = op.ConnectionId
err = taskCtx.GetDal().CreateIfNotExist(scope)
if err != nil {
diff --git a/backend/plugins/bitbucket/models/repo.go b/backend/plugins/bitbucket/models/repo.go
index be68dee91..799b549b9 100644
--- a/backend/plugins/bitbucket/models/repo.go
+++ b/backend/plugins/bitbucket/models/repo.go
@@ -26,7 +26,6 @@ import (
var _ plugin.ToolLayerScope = (*BitbucketRepo)(nil)
var _ plugin.ApiGroup = (*GroupResponse)(nil)
-var _ plugin.ApiScope = (*BitbucketApiRepo)(nil)
type BitbucketRepo struct {
common.Scope `mapstructure:",squash"`
@@ -91,7 +90,7 @@ type BitbucketApiRepo struct {
} `json:"links"`
}
-func (b BitbucketApiRepo) ConvertApiScope() plugin.ToolLayerScope {
+func (b BitbucketApiRepo) ConvertApiScope() *BitbucketRepo {
scope := &BitbucketRepo{}
scope.BitbucketId = b.FullName
scope.CreatedDate = b.CreatedAt