You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by kl...@apache.org on 2022/12/12 08:14:14 UTC

[incubator-devlake] branch main updated: feat(jira): refactor jira bp v200 (#3909)

This is an automated email from the ASF dual-hosted git repository.

klesh 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 4d67ff160 feat(jira): refactor jira bp v200 (#3909)
4d67ff160 is described below

commit 4d67ff16000f621075f5af2d4a8476eca68f8b91
Author: Warren Chen <yi...@merico.dev>
AuthorDate: Mon Dec 12 16:14:10 2022 +0800

    feat(jira): refactor jira bp v200 (#3909)
---
 plugins/github/api/blueprint_V200_test.go |  1 -
 plugins/github/api/blueprint_v200.go      | 12 ++---
 plugins/jira/api/blueprint_v200.go        | 73 ++++++-------------------------
 plugins/jira/api/blueprint_v200_test.go   | 62 ++++----------------------
 plugins/jira/impl/impl.go                 | 31 ++++++++-----
 5 files changed, 45 insertions(+), 134 deletions(-)

diff --git a/plugins/github/api/blueprint_V200_test.go b/plugins/github/api/blueprint_V200_test.go
index 19db95b22..9bc756e7a 100644
--- a/plugins/github/api/blueprint_V200_test.go
+++ b/plugins/github/api/blueprint_V200_test.go
@@ -74,7 +74,6 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
 	bs := &core.BlueprintScopeV200{
 		Entities: []string{"CODE", "TICKET"},
 		Id:       "1",
-		Name:     "",
 	}
 	bpScopes := make([]*core.BlueprintScopeV200, 0)
 	bpScopes = append(bpScopes, bs)
diff --git a/plugins/github/api/blueprint_v200.go b/plugins/github/api/blueprint_v200.go
index 14e47369a..d2c7fd1bf 100644
--- a/plugins/github/api/blueprint_v200.go
+++ b/plugins/github/api/blueprint_v200.go
@@ -94,8 +94,8 @@ func makeDataSourcePipelinePlanV200(
 		githubRepo := &models.GithubRepo{}
 		// get repo from db
 		err = basicRes.GetDal().First(githubRepo, dal.Where(`connection_id = ? AND github_id = ?`, connection.ID, bpScope.Id))
-		if err != nil && goerror.Is(err, gorm.ErrRecordNotFound) {
-			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find repo%s", bpScope.Id))
+		if err != nil {
+			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find repo %s", bpScope.Id))
 		}
 		transformationRule := &models.GithubTransformationRule{}
 		// get transformation rules from db
@@ -164,15 +164,9 @@ func makeScopesV200(bpScopes []*core.BlueprintScopeV200, connection *models.Gith
 		githubRepo := &models.GithubRepo{}
 		// get repo from db
 		err := basicRes.GetDal().First(githubRepo, dal.Where(`connection_id = ? AND github_id = ?`, connection.ID, bpScope.Id))
-		if err != nil && goerror.Is(err, gorm.ErrRecordNotFound) {
+		if err != nil {
 			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find repo%s", bpScope.Id))
 		}
-		transformationRule := &models.GithubTransformationRule{}
-		// get transformation rules from db
-		err = basicRes.GetDal().First(transformationRule, dal.Where(`id = ?`, githubRepo.TransformationRuleId))
-		if err != nil && !goerror.Is(err, gorm.ErrRecordNotFound) {
-			return nil, err
-		}
 		if utils.StringsContains(bpScope.Entities, core.DOMAIN_TYPE_CODE_REVIEW) ||
 			utils.StringsContains(bpScope.Entities, core.DOMAIN_TYPE_CODE) ||
 			utils.StringsContains(bpScope.Entities, core.DOMAIN_TYPE_CROSS) {
diff --git a/plugins/jira/api/blueprint_v200.go b/plugins/jira/api/blueprint_v200.go
index 5bad7d93c..fb5e26067 100644
--- a/plugins/jira/api/blueprint_v200.go
+++ b/plugins/jira/api/blueprint_v200.go
@@ -18,37 +18,25 @@ limitations under the License.
 package api
 
 import (
-	goerror "errors"
 	"fmt"
-	"github.com/apache/incubator-devlake/models/domainlayer/ticket"
-	"github.com/apache/incubator-devlake/plugins/helper"
-	"gorm.io/gorm"
-
 	"github.com/apache/incubator-devlake/errors"
 	"github.com/apache/incubator-devlake/models/domainlayer"
 	"github.com/apache/incubator-devlake/models/domainlayer/didgen"
+	"github.com/apache/incubator-devlake/models/domainlayer/ticket"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/core/dal"
+	"github.com/apache/incubator-devlake/plugins/helper"
 	"github.com/apache/incubator-devlake/plugins/jira/models"
-	"github.com/apache/incubator-devlake/plugins/jira/tasks"
 	"github.com/apache/incubator-devlake/utils"
-	"github.com/mitchellh/mapstructure"
 )
 
 func MakeDataSourcePipelinePlanV200(subtaskMetas []core.SubTaskMeta, connectionId uint64, bpScopes []*core.BlueprintScopeV200) (core.PipelinePlan, []core.Scope, errors.Error) {
-	// get the connection info for url
-	connection := &models.JiraConnection{}
-	err := connectionHelper.FirstById(connection, connectionId)
-	if err != nil {
-		return nil, nil, err
-	}
-
 	plan := make(core.PipelinePlan, len(bpScopes))
-	plan, err = makeDataSourcePipelinePlanV200(subtaskMetas, plan, bpScopes, connection)
+	plan, err := makeDataSourcePipelinePlanV200(subtaskMetas, plan, bpScopes, connectionId)
 	if err != nil {
 		return nil, nil, err
 	}
-	scopes, err := makeScopesV200(bpScopes, connection)
+	scopes, err := makeScopesV200(bpScopes, connectionId)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -60,45 +48,18 @@ func makeDataSourcePipelinePlanV200(
 	subtaskMetas []core.SubTaskMeta,
 	plan core.PipelinePlan,
 	bpScopes []*core.BlueprintScopeV200,
-	connection *models.JiraConnection,
+	connectionId uint64,
 ) (core.PipelinePlan, errors.Error) {
-	db := basicRes.GetDal()
-	var err errors.Error
 	for i, bpScope := range bpScopes {
 		stage := plan[i]
 		if stage == nil {
 			stage = core.PipelineStage{}
 		}
-		jiraBoard := &models.JiraBoard{}
-		// get repo from db
-		err = db.First(jiraBoard, dal.Where(`connection_id = ? and board_id = ?`, connection.ID, bpScope.Id))
-		if err != nil && goerror.Is(err, gorm.ErrRecordNotFound) {
-			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find board%s", bpScope.Id))
-		}
-		transformationRule := &models.JiraTransformationRule{}
-		// get transformation rules from db
-		err = db.First(transformationRule, dal.Where(`id = ?`, jiraBoard.TransformationRuleId))
-		if err != nil && !goerror.Is(err, gorm.ErrRecordNotFound) {
-			return nil, err
-		}
 		// construct task options for Jira
-		var options map[string]interface{}
-		err = errors.Convert(mapstructure.Decode(jiraBoard, &options))
-		if err != nil {
-			return nil, err
-		}
-		// make sure task options is valid
-		_, err = tasks.DecodeAndValidateTaskOptions(options)
-		if err != nil {
-			return nil, err
-		}
+		options := make(map[string]interface{})
+		options["scopeId"] = bpScope.Id
+		options["connectionId"] = connectionId
 
-		var transformationRuleMap map[string]interface{}
-		err = errors.Convert(mapstructure.Decode(transformationRule, &transformationRuleMap))
-		if err != nil {
-			return nil, err
-		}
-		options["transformationRules"] = transformationRuleMap
 		subtasks, err := helper.MakePipelinePlanSubtasks(subtaskMetas, bpScope.Entities)
 		if err != nil {
 			return nil, err
@@ -114,32 +75,26 @@ func makeDataSourcePipelinePlanV200(
 	return plan, nil
 }
 
-func makeScopesV200(bpScopes []*core.BlueprintScopeV200, connection *models.JiraConnection) ([]core.Scope, errors.Error) {
+func makeScopesV200(bpScopes []*core.BlueprintScopeV200, connectionId uint64) ([]core.Scope, errors.Error) {
 	scopes := make([]core.Scope, 0)
 	for _, bpScope := range bpScopes {
 		jiraBoard := &models.JiraBoard{}
 		// get repo from db
 		err := basicRes.GetDal().First(jiraBoard,
 			dal.Where(`connection_id = ? and board_id = ?`,
-				connection.ID, bpScope.Id))
-		if err != nil && goerror.Is(err, gorm.ErrRecordNotFound) {
-			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find board%d", jiraBoard.BoardId))
-		}
-		transformationRule := &models.JiraTransformationRule{}
-		// get transformation rules from db
-		err = basicRes.GetDal().First(transformationRule, dal.Where(`id = ?`, jiraBoard.TransformationRuleId))
-		if err != nil && !goerror.Is(err, gorm.ErrRecordNotFound) {
-			return nil, err
+				connectionId, bpScope.Id))
+		if err != nil {
+			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find board %s", bpScope.Id))
 		}
 		// add board to scopes
 		if utils.StringsContains(bpScope.Entities, core.DOMAIN_TYPE_TICKET) {
-			jiraBoard := &ticket.Board{
+			domainBoard := &ticket.Board{
 				DomainEntity: domainlayer.DomainEntity{
 					Id: didgen.NewDomainIdGenerator(&models.JiraBoard{}).Generate(jiraBoard.ConnectionId, jiraBoard.BoardId),
 				},
 				Name: jiraBoard.Name,
 			}
-			scopes = append(scopes, jiraBoard)
+			scopes = append(scopes, domainBoard)
 		}
 	}
 	return scopes, nil
diff --git a/plugins/jira/api/blueprint_v200_test.go b/plugins/jira/api/blueprint_v200_test.go
index 0e5648fe8..5f9a9e209 100644
--- a/plugins/jira/api/blueprint_v200_test.go
+++ b/plugins/jira/api/blueprint_v200_test.go
@@ -19,11 +19,9 @@ package api
 
 import (
 	"github.com/apache/incubator-devlake/mocks"
-	"github.com/apache/incubator-devlake/models/common"
 	"github.com/apache/incubator-devlake/models/domainlayer"
 	"github.com/apache/incubator-devlake/models/domainlayer/ticket"
 	"github.com/apache/incubator-devlake/plugins/core"
-	"github.com/apache/incubator-devlake/plugins/helper"
 	"github.com/apache/incubator-devlake/plugins/jira/models"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
@@ -37,29 +35,15 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
 	assert.Nil(t, err)
 	bs := &core.BlueprintScopeV200{
 		Entities: []string{"TICKET"},
-		Id:       "",
-		Name:     "",
+		Id:       "10",
 	}
 	bpScopes := make([]*core.BlueprintScopeV200, 0)
 	bpScopes = append(bpScopes, bs)
-
-	connection := &models.JiraConnection{
-		RestConnection: helper.RestConnection{
-			BaseConnection: helper.BaseConnection{
-				Name: "Jira",
-				Model: common.Model{
-					ID: 1,
-				},
-			},
-		},
-	}
-
-	basicRes = NewMockBasicRes()
 	plan := make(core.PipelinePlan, len(bpScopes))
-	plan, err = makeDataSourcePipelinePlanV200(nil, plan, bpScopes, connection)
+	plan, err = makeDataSourcePipelinePlanV200(nil, plan, bpScopes, uint64(1))
 	assert.Nil(t, err)
 	basicRes = NewMockBasicRes()
-	scopes, err := makeScopesV200(bpScopes, connection)
+	scopes, err := makeScopesV200(bpScopes, uint64(1))
 	assert.Nil(t, err)
 
 	expectPlan := core.PipelinePlan{
@@ -69,17 +53,8 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
 				Subtasks:   []string{},
 				SkipOnFail: false,
 				Options: map[string]interface{}{
-					"connectionId":         uint64(1),
-					"boardId":              uint64(10),
-					"projectId":            uint(20),
-					"name":                 "a",
-					"self":                 "self",
-					"transformationRuleId": uint64(1),
-					"transformationRules": map[string]interface{}{
-						"name":         "jira transformation rule",
-						"epicKeyField": "hey,man,wasup",
-					},
-					"type": "type",
+					"connectionId": uint64(1),
+					"scopeId":      "10",
 				},
 			},
 		},
@@ -91,10 +66,7 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
 		DomainEntity: domainlayer.DomainEntity{
 			Id: "jira:JiraBoard:1:10",
 		},
-		Name:        "a",
-		Description: "",
-		Url:         "",
-		CreatedDate: nil,
+		Name: "a",
 	}
 
 	expectScopes = append(expectScopes, jiraBoard)
@@ -104,22 +76,11 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
 // NewMockBasicRes FIXME ...
 func NewMockBasicRes() *mocks.BasicRes {
 	jiraBoard := &models.JiraBoard{
-		ConnectionId:         1,
-		BoardId:              10,
-		Name:                 "a",
-		ProjectId:            20,
-		Self:                 "self",
-		Type:                 "type",
-		TransformationRuleId: 1,
+		ConnectionId: 1,
+		BoardId:      10,
+		Name:         "a",
 	}
 
-	transformationRule := &models.JiraTransformationRule{
-		Model: common.Model{
-			ID: 1,
-		},
-		Name:         "jira transformation rule",
-		EpicKeyField: "hey,man,wasup",
-	}
 	mockRes := new(mocks.BasicRes)
 	mockDal := new(mocks.Dal)
 
@@ -128,11 +89,6 @@ func NewMockBasicRes() *mocks.BasicRes {
 		*dst = *jiraBoard
 	}).Return(nil).Once()
 
-	mockDal.On("First", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
-		dst := args.Get(0).(*models.JiraTransformationRule)
-		*dst = *transformationRule
-	}).Return(nil).Once()
-
 	mockRes.On("GetDal").Return(mockDal)
 	mockRes.On("GetConfig", mock.Anything).Return("")
 
diff --git a/plugins/jira/impl/impl.go b/plugins/jira/impl/impl.go
index e6302078a..89cc4012c 100644
--- a/plugins/jira/impl/impl.go
+++ b/plugins/jira/impl/impl.go
@@ -18,9 +18,9 @@ limitations under the License.
 package impl
 
 import (
+	goerror "errors"
 	"fmt"
 	"net/http"
-	"strconv"
 	"time"
 
 	"github.com/apache/incubator-devlake/errors"
@@ -148,7 +148,8 @@ func (plugin Jira) SubTaskMetas() []core.SubTaskMeta {
 
 func (plugin Jira) PrepareTaskData(taskCtx core.TaskContext, options map[string]interface{}) (interface{}, errors.Error) {
 	var op tasks.JiraOptions
-	var err error
+	var err errors.Error
+	db := taskCtx.GetDal()
 	logger := taskCtx.GetLogger()
 	logger.Debug("%v", options)
 	err = helper.Decode(options, &op, nil)
@@ -171,23 +172,20 @@ func (plugin Jira) PrepareTaskData(taskCtx core.TaskContext, options map[string]
 		return nil, errors.Default.Wrap(err, "unable to get Jira connection")
 	}
 
-	var createdDateAfter time.Time
-	if op.CreatedDateAfter != "" {
-		createdDateAfter, err = time.Parse("2006-01-02T15:04:05Z", op.CreatedDateAfter)
-		if err != nil {
-			return nil, errors.BadInput.Wrap(err, "invalid value for `createdDateAfter`")
-		}
-	}
 	if op.BoardId == 0 && op.ScopeId != "" {
-		op.BoardId, err = strconv.ParseUint(op.ScopeId, 10, 64)
+		var jiraBoard models.JiraBoard
+		// get repo from db
+		err = db.First(&jiraBoard, dal.Where(`connection_id = ? and board_id = ?`, connection.ID, op.ScopeId))
 		if err != nil {
-			return nil, errors.BadInput.Wrap(err, "invalid value for scopeId")
+			return nil, errors.Default.Wrap(err, fmt.Sprintf("fail to find board%s", op.ScopeId))
 		}
+		op.BoardId = jiraBoard.BoardId
+		op.TransformationRuleId = jiraBoard.TransformationRuleId
 	}
 	if op.TransformationRules == nil && op.TransformationRuleId != 0 {
 		var transformationRule models.JiraTransformationRule
 		err = taskCtx.GetDal().First(&transformationRule, dal.Where("id = ?", op.TransformationRuleId))
-		if err != nil {
+		if err != nil && !goerror.Is(err, gorm.ErrRecordNotFound) {
 			return nil, errors.BadInput.Wrap(err, "fail to get transformationRule")
 		}
 		op.TransformationRules, err = tasks.MakeTransformationRules(transformationRule)
@@ -195,6 +193,15 @@ func (plugin Jira) PrepareTaskData(taskCtx core.TaskContext, options map[string]
 			return nil, errors.BadInput.Wrap(err, "fail to make transformationRule")
 		}
 	}
+
+	var createdDateAfter time.Time
+	if op.CreatedDateAfter != "" {
+		createdDateAfter, err = errors.Convert01(time.Parse("2006-01-02T15:04:05Z", op.CreatedDateAfter))
+		if err != nil {
+			return nil, errors.BadInput.Wrap(err, "invalid value for `createdDateAfter`")
+		}
+	}
+
 	jiraApiClient, err := tasks.NewJiraApiClient(taskCtx, connection)
 	if err != nil {
 		return nil, errors.Default.Wrap(err, "failed to create jira api client")