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 322db65b2 refactor: zentao plugin (#5653)
322db65b2 is described below
commit 322db65b2538f42fa8c62f1ebdf7fd7a30ebfb08
Author: Liang Zhang <[email protected]>
AuthorDate: Tue Jul 11 10:54:47 2023 +0800
refactor: zentao plugin (#5653)
* refactor: zentao plugin
* fix: table info check
* fix: unit test and lint error
---
backend/plugins/zentao/api/blueprint_V200_test.go | 1 -
backend/plugins/zentao/api/init.go | 11 +-
backend/plugins/zentao/api/remote.go | 30 +---
backend/plugins/zentao/impl/impl.go | 23 +++-
.../plugins/zentao/models/archived/changelog.go | 8 +-
.../register.go => archived/execution_stories.go} | 24 ++--
.../register.go => archived/execution_summary.go} | 26 ++--
.../register.go => archived/product_summary.go} | 24 ++--
.../register.go => archived/project_stories.go} | 23 ++--
backend/plugins/zentao/models/bug.go | 42 +++++-
backend/plugins/zentao/models/bug_test.go | 121 ++++++++++++++++
backend/plugins/zentao/models/changelog.go | 8 +-
.../register.go => execution_stories.go} | 24 ++--
.../register.go => execution_summary.go} | 26 ++--
.../20230705_add_execution_stories.go | 45 ++++++
.../zentao/models/migrationscripts/register.go | 1 +
backend/plugins/zentao/models/product.go | 61 ---------
.../register.go => product_summary.go} | 26 ++--
backend/plugins/zentao/models/project.go | 4 +-
.../register.go => project_stories.go} | 23 ++--
backend/plugins/zentao/models/remote_db.go | 89 ++++++++----
backend/plugins/zentao/tasks/account_collector.go | 10 +-
backend/plugins/zentao/tasks/account_convertor.go | 10 +-
backend/plugins/zentao/tasks/account_extractor.go | 14 +-
backend/plugins/zentao/tasks/bug_collector.go | 26 ++--
.../plugins/zentao/tasks/bug_commits_collector.go | 37 ++---
.../plugins/zentao/tasks/bug_commits_extractor.go | 26 ++--
backend/plugins/zentao/tasks/bug_convertor.go | 34 ++---
backend/plugins/zentao/tasks/bug_extractor.go | 46 ++-----
.../zentao/tasks/bug_repo_commits_collector.go | 28 ++--
.../zentao/tasks/bug_repo_commits_convertor.go | 16 +--
.../zentao/tasks/bug_repo_commits_extractor.go | 26 ++--
.../plugins/zentao/tasks/changelog_convertor.go | 61 +++++++--
backend/plugins/zentao/tasks/changelog_dbget.go | 152 ++++++++++++---------
.../plugins/zentao/tasks/department_collector.go | 20 +--
.../plugins/zentao/tasks/department_convertor.go | 10 +-
.../plugins/zentao/tasks/department_extractor.go | 14 +-
.../plugins/zentao/tasks/execution_collector.go | 35 ++---
.../plugins/zentao/tasks/execution_convertor.go | 10 +-
.../plugins/zentao/tasks/execution_extractor.go | 28 ++--
...t_collector.go => execution_story_collector.go} | 44 +++---
...t_convertor.go => execution_story_convertor.go} | 56 +++-----
...collector.go => execution_summary_collector.go} | 32 ++---
...extractor.go => execution_summary_extractor.go} | 33 ++---
backend/plugins/zentao/tasks/iterator.go | 105 ++++++++++++++
backend/plugins/zentao/tasks/project_convertor.go | 10 +-
backend/plugins/zentao/tasks/shared.go | 68 +++++----
backend/plugins/zentao/tasks/story_collector.go | 45 ++++--
.../zentao/tasks/story_commits_collector.go | 41 ++----
.../zentao/tasks/story_commits_extractor.go | 20 +--
backend/plugins/zentao/tasks/story_convertor.go | 33 ++---
backend/plugins/zentao/tasks/story_extractor.go | 49 +++----
.../zentao/tasks/story_repo_commits_collector.go | 18 +--
.../zentao/tasks/story_repo_commits_convertor.go | 16 +--
.../zentao/tasks/story_repo_commits_extractor.go | 20 +--
backend/plugins/zentao/tasks/task_collector.go | 21 +--
.../plugins/zentao/tasks/task_commits_collector.go | 32 +----
.../plugins/zentao/tasks/task_commits_extractor.go | 16 +--
backend/plugins/zentao/tasks/task_convertor.go | 28 +---
backend/plugins/zentao/tasks/task_data.go | 15 +-
backend/plugins/zentao/tasks/task_extractor.go | 20 +--
.../zentao/tasks/task_repo_commits_collector.go | 10 +-
.../zentao/tasks/task_repo_commits_convertor.go | 10 +-
.../zentao/tasks/task_repo_commits_extractor.go | 11 +-
64 files changed, 1013 insertions(+), 983 deletions(-)
diff --git a/backend/plugins/zentao/api/blueprint_V200_test.go
b/backend/plugins/zentao/api/blueprint_V200_test.go
index 5d8cddf95..ecd98139f 100644
--- a/backend/plugins/zentao/api/blueprint_V200_test.go
+++ b/backend/plugins/zentao/api/blueprint_V200_test.go
@@ -82,7 +82,6 @@ func TestMakeDataSourcePipelinePlanV200(t *testing.T) {
Subtasks: []string{},
Options: map[string]interface{}{
"ConnectionId": uint64(1),
- "productId": int64(0),
"projectId": int64(1),
},
},
diff --git a/backend/plugins/zentao/api/init.go
b/backend/plugins/zentao/api/init.go
index 5d2b6715a..2e7abfd49 100644
--- a/backend/plugins/zentao/api/init.go
+++ b/backend/plugins/zentao/api/init.go
@@ -34,8 +34,7 @@ var vld *validator.Validate
var connectionHelper *api.ConnectionApiHelper
var projectScopeHelper *api.ScopeApiHelper[models.ZentaoConnection,
models.ZentaoProject, models.ZentaoScopeConfig]
-var productRemoteHelper *api.RemoteApiHelper[models.ZentaoConnection,
models.ZentaoProduct, models.ZentaoProductRes, api.BaseRemoteGroupResponse]
-var projectRemoteHelper *api.RemoteApiHelper[models.ZentaoConnection,
models.ZentaoProject, models.ZentaoProject, api.NoRemoteGroupResponse]
+var projectRemoteHelper *api.RemoteApiHelper[models.ZentaoConnection,
models.ZentaoProject, models.ZentaoProject, api.BaseRemoteGroupResponse]
var basicRes context.BasicRes
var scHelper *api.ScopeConfigHelper[models.ZentaoScopeConfig]
@@ -63,12 +62,8 @@ func Init(br context.BasicRes, p plugin.PluginMeta) {
projectParams,
nil,
)
- productRemoteHelper = api.NewRemoteHelper[models.ZentaoConnection,
models.ZentaoProduct, models.ZentaoProductRes, api.BaseRemoteGroupResponse](
- basicRes,
- vld,
- connectionHelper,
- )
- projectRemoteHelper = api.NewRemoteHelper[models.ZentaoConnection,
models.ZentaoProject, models.ZentaoProject, api.NoRemoteGroupResponse](
+
+ projectRemoteHelper = api.NewRemoteHelper[models.ZentaoConnection,
models.ZentaoProject, models.ZentaoProject, api.BaseRemoteGroupResponse](
basicRes,
vld,
connectionHelper,
diff --git a/backend/plugins/zentao/api/remote.go
b/backend/plugins/zentao/api/remote.go
index 91bd3e77a..e724e42d3 100644
--- a/backend/plugins/zentao/api/remote.go
+++ b/backend/plugins/zentao/api/remote.go
@@ -74,35 +74,7 @@ func RemoteScopes(input *plugin.ApiResourceInput)
(*plugin.ApiResourceOutput, er
}
gid := groupId[0]
if gid == "" {
- return productRemoteHelper.GetScopesFromRemote(input, getGroup,
nil)
- } else if gid == `products` {
- /*
- return productRemoteHelper.GetScopesFromRemote(input,
- nil,
- func(basicRes context2.BasicRes, gid string,
queryData *api.RemoteQueryData, connection models.ZentaoConnection)
([]models.ZentaoProductRes, errors.Error) {
- query := initialQuery(queryData)
- // create api client
- apiClient, err :=
api.NewApiClientFromConnection(context.TODO(), basicRes, &connection)
- if err != nil {
- return nil, err
- }
-
- query.Set("sort", "name")
- // list projects part
- res, err := apiClient.Get("/products",
query, nil)
- if err != nil {
- return nil, err
- }
-
- resBody := &ProductResponse{}
- err = api.UnmarshalResponse(res,
resBody)
- if err != nil {
- return nil, err
- }
- return resBody.Values, nil
- })
- */
- return nil, errors.BadInput.New("products are currently
unsupported")
+ return projectRemoteHelper.GetScopesFromRemote(input, getGroup,
nil)
} else if gid == `projects` {
return projectRemoteHelper.GetScopesFromRemote(input,
nil,
diff --git a/backend/plugins/zentao/impl/impl.go
b/backend/plugins/zentao/impl/impl.go
index 1c655aae4..2da39bec2 100644
--- a/backend/plugins/zentao/impl/impl.go
+++ b/backend/plugins/zentao/impl/impl.go
@@ -86,6 +86,10 @@ func (p Zentao) GetTablesInfo() []dal.Tabler {
&models.ZentaoBugRepoCommit{},
&models.ZentaoConnection{},
&models.ZentaoScopeConfig{},
+ &models.ZentaoExecutionStory{},
+ &models.ZentaoExecutionSummary{},
+ &models.ZentaoProductSummary{},
+ &models.ZentaoProjectStory{},
}
}
@@ -103,22 +107,20 @@ func (p Zentao) ScopeConfig() dal.Tabler {
func (p Zentao) SubTaskMetas() []plugin.SubTaskMeta {
return []plugin.SubTaskMeta{
- //tasks.ConvertProductMeta,
tasks.ConvertProjectMeta,
- tasks.DBGetChangelogMeta,
- tasks.ConvertChangelogMeta,
-
// both
tasks.CollectAccountMeta,
tasks.ExtractAccountMeta,
tasks.ConvertAccountMeta,
- tasks.CollectDepartmentMeta,
- tasks.ExtractDepartmentMeta,
- tasks.ConvertDepartmentMeta,
+ //tasks.CollectDepartmentMeta,
+ //tasks.ExtractDepartmentMeta,
+ //tasks.ConvertDepartmentMeta,
// project
+ tasks.CollectExecutionSummaryMeta,
+ tasks.ExtractExecutionSummaryMeta,
tasks.CollectExecutionMeta,
tasks.ExtractExecutionMeta,
tasks.ConvertExecutionMeta,
@@ -137,6 +139,7 @@ func (p Zentao) SubTaskMetas() []plugin.SubTaskMeta {
tasks.CollectStoryMeta,
tasks.ExtractStoryMeta,
tasks.ConvertStoryMeta,
+ tasks.ConvertExecutionStoryMeta,
tasks.CollectBugMeta,
tasks.ExtractBugMeta,
@@ -153,6 +156,9 @@ func (p Zentao) SubTaskMetas() []plugin.SubTaskMeta {
tasks.CollectBugRepoCommitsMeta,
tasks.ExtractBugRepoCommitsMeta,
tasks.ConvertBugRepoCommitsMeta,
+
+ tasks.DBGetChangelogMeta,
+ tasks.ConvertChangelogMeta,
}
}
@@ -195,6 +201,9 @@ func (p Zentao) PrepareTaskData(taskCtx plugin.TaskContext,
options map[string]i
ProductList: map[int64]string{},
StoryList: map[int64]int64{},
FromBugList: map[int]bool{},
+ Stories: map[int64]struct{}{},
+ Tasks: map[int64]struct{}{},
+ Bugs: map[int64]struct{}{},
}
if connection.DbUrl != "" {
diff --git a/backend/plugins/zentao/models/archived/changelog.go
b/backend/plugins/zentao/models/archived/changelog.go
index 0e7f196b0..baaa95d08 100644
--- a/backend/plugins/zentao/models/archived/changelog.go
+++ b/backend/plugins/zentao/models/archived/changelog.go
@@ -27,14 +27,14 @@ type ZentaoChangelog struct {
archived.NoPKModel `json:"-"`
ConnectionId uint64 `json:"connectionId"
mapstructure:"connectionId" gorm:"primaryKey;type:BIGINT NOT NULL"`
Id int64 `json:"id" mapstructure:"id"
gorm:"primaryKey;type:BIGINT NOT NULL;autoIncrement:false"`
- ObjectId int `json:"objectId" mapstructure:"objectId"
gorm:"index; NOT NULL"`
- Execution int `json:"execution" mapstructure:"execution"
`
+ ObjectId int64 `json:"objectId" mapstructure:"objectId"
gorm:"index; NOT NULL"`
+ Execution int64 `json:"execution" mapstructure:"execution"
`
Actor string `json:"actor" mapstructure:"actor" `
Action string `json:"action" mapstructure:"action"`
Extra string `json:"extra" mapstructure:"extra"`
ObjectType string `json:"objectType"
mapstructure:"objectType"`
- Project int `json:"project" mapstructure:"project"`
- Product int `json:"product" mapstructure:"product"`
+ Project int64 `json:"project" mapstructure:"project"`
+ Product int64 `json:"product" mapstructure:"product"`
Vision string `json:"vision" mapstructure:"vision"`
Comment string `json:"comment" mapstructure:"comment"`
Efforted string `json:"efforted" mapstructure:"efforted"`
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/archived/execution_stories.go
similarity index 65%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/archived/execution_stories.go
index 4d3e3dc40..8b818f0b7 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/archived/execution_stories.go
@@ -15,20 +15,20 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package archived
import (
- "github.com/apache/incubator-devlake/core/plugin"
+
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoExecutionStory struct {
+ archived.NoPKModel
+ ConnectionId uint64 `gorm:"primaryKey"`
+ ProjectId int64 `gorm:"primaryKey"`
+ ExecutionId int64 `gorm:"primaryKey"`
+ StoryId int64 `gorm:"primaryKey"`
+}
+
+func (ZentaoExecutionStory) TableName() string {
+ return "_tool_zentao_execution_stories"
}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/archived/execution_summary.go
similarity index 58%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/archived/execution_summary.go
index 4d3e3dc40..308085ddd 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/archived/execution_summary.go
@@ -15,20 +15,22 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package archived
import (
- "github.com/apache/incubator-devlake/core/plugin"
+
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoExecutionSummary struct {
+ ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"`
+ Id int64 `gorm:"primaryKey;type:BIGINT NOT
NULL;autoIncrement:false"`
+ Name string `gorm:"type:varchar(255)"`
+ Project int64
+ Code string `gorm:"type:varchar(255)"`
+ Type string `gorm:"type:varchar(255)"`
+ archived.NoPKModel
+}
+
+func (ZentaoExecutionSummary) TableName() string {
+ return "_tool_zentao_execution_summary"
}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/archived/product_summary.go
similarity index 64%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/archived/product_summary.go
index 4d3e3dc40..6b603e947 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/archived/product_summary.go
@@ -15,20 +15,20 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package archived
import (
- "github.com/apache/incubator-devlake/core/plugin"
+
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoProductSummary struct {
+ archived.NoPKModel
+ ConnectionId uint64 `gorm:"primaryKey"`
+ ProjectId int64 `gorm:"primaryKey"`
+ Id int64 `gorm:"primaryKey;autoIncrement:false"`
+ Name string `gorm:"type:VARCHAR(255)"`
+}
+
+func (ZentaoProductSummary) TableName() string {
+ return "_tool_zentao_product_summary"
}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/archived/project_stories.go
similarity index 67%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/archived/project_stories.go
index 4d3e3dc40..dbeb77e24 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/archived/project_stories.go
@@ -15,20 +15,19 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package archived
import (
- "github.com/apache/incubator-devlake/core/plugin"
+
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoProjectStory struct {
+ archived.NoPKModel
+ ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"`
+ ProjectId int64 `gorm:"primaryKey"`
+ StoryId int64 `gorm:"primaryKey"`
+}
+
+func (ZentaoProjectStory) TableName() string {
+ return "_tool_zentao_project_stories"
}
diff --git a/backend/plugins/zentao/models/bug.go
b/backend/plugins/zentao/models/bug.go
index 1a16bfa96..dd0112af5 100644
--- a/backend/plugins/zentao/models/bug.go
+++ b/backend/plugins/zentao/models/bug.go
@@ -18,10 +18,42 @@ limitations under the License.
package models
import (
+ "bytes"
+ "encoding/json"
"github.com/apache/incubator-devlake/core/models/common"
helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
)
+type ApiAccount struct {
+ ID int64 `json:"id"`
+ Account string `json:"account"`
+ Avatar string `json:"avatar"`
+ Realname string `json:"realname"`
+}
+
+func (a *ApiAccount) UnmarshalJSON(data []byte) error {
+ var dst struct {
+ ID int64 `json:"id"`
+ Account string `json:"account"`
+ Avatar string `json:"avatar"`
+ Realname string `json:"realname"`
+ }
+ data = bytes.TrimSpace(data)
+ if string(data) == "null" {
+ a = nil
+ }
+ if len(data) > 1 && data[0] == '"' && data[len(data)-1] == '"' {
+ dst.Account = string(data[1 : len(data)-1])
+ } else {
+ err := json.Unmarshal(data, &dst)
+ if err != nil {
+ return err
+ }
+ }
+ *a = dst
+ return nil
+}
+
type ZentaoBugRes struct {
ID int64 `json:"id"`
Project int64 `json:"project"`
@@ -55,17 +87,17 @@ type ZentaoBugRes struct {
ActivatedDate *helper.Iso8601Time `json:"activatedDate"`
FeedbackBy string `json:"feedbackBy"`
NotifyEmail string `json:"notifyEmail"`
- OpenedBy *ZentaoAccount `json:"openedBy"`
+ OpenedBy *ApiAccount `json:"openedBy"`
OpenedDate *helper.Iso8601Time `json:"openedDate"`
OpenedBuild string `json:"openedBuild"`
- AssignedTo *ZentaoAccount `json:"assignedTo"`
+ AssignedTo *ApiAccount `json:"assignedTo"`
AssignedDate *helper.Iso8601Time `json:"assignedDate"`
Deadline string `json:"deadline"`
- ResolvedBy *ZentaoAccount `json:"resolvedBy"`
+ ResolvedBy *ApiAccount `json:"resolvedBy"`
Resolution string `json:"resolution"`
ResolvedBuild string `json:"resolvedBuild"`
ResolvedDate *helper.Iso8601Time `json:"resolvedDate"`
- ClosedBy *ZentaoAccount `json:"closedBy"`
+ ClosedBy *ApiAccount `json:"closedBy"`
ClosedDate *helper.Iso8601Time `json:"closedDate"`
DuplicateBug int `json:"duplicateBug"`
LinkBug string `json:"linkBug"`
@@ -80,7 +112,7 @@ type ZentaoBugRes struct {
RepoType string `json:"repoType"`
IssueKey string `json:"issueKey"`
Testtask int `json:"testtask"`
- LastEditedBy *ZentaoAccount `json:"lastEditedBy"`
+ LastEditedBy *ApiAccount `json:"lastEditedBy"`
LastEditedDate *helper.Iso8601Time `json:"lastEditedDate"`
Deleted bool `json:"deleted"`
PriOrder string `json:"priOrder"`
diff --git a/backend/plugins/zentao/models/bug_test.go
b/backend/plugins/zentao/models/bug_test.go
new file mode 100644
index 000000000..ff501cef3
--- /dev/null
+++ b/backend/plugins/zentao/models/bug_test.go
@@ -0,0 +1,121 @@
+/*
+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 models
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+)
+
+func TestApiAccount_UnmarshalJSON(t *testing.T) {
+ type bug struct {
+ NotifyEmail string `json:"notifyEmail"`
+ OpenedBy *ApiAccount
+ }
+
+ type args struct {
+ data []byte
+ }
+ tests := []struct {
+ name string
+ args args
+ want bug
+ wantErr bool
+ }{
+ {
+ "string",
+ args{
+ data: []byte(`{
+
"notifyEmail": "[email protected]",
+ "openedBy":
"admin"
+ }`),
+ },
+ bug{
+ NotifyEmail: "[email protected]",
+ OpenedBy: &ApiAccount{Account: "admin"},
+ },
+ false,
+ },
+ {
+ "empty string",
+ args{
+ data: []byte(`{
+
"notifyEmail": "[email protected]",
+ "openedBy": ""
+ }`),
+ },
+ bug{
+ NotifyEmail: "[email protected]",
+ OpenedBy: &ApiAccount{},
+ },
+ false,
+ },
+ {
+ "struct",
+ args{
+ data: []byte(`{
+
"notifyEmail": "[email protected]",
+ "openedBy": {
+ "id": 1,
+
"account": "admin",
+
"avatar": "https://example.com/avatar.png",
+
"realname": "root"
+ }
+ }`),
+ },
+ bug{
+ NotifyEmail: "[email protected]",
+ OpenedBy: &ApiAccount{
+ ID: 1,
+ Account: "admin",
+ Avatar:
"https://example.com/avatar.png",
+ Realname: "root",
+ },
+ },
+ false,
+ },
+ {
+ "null",
+ args{
+ data: []byte(`{
+
"notifyEmail": "[email protected]",
+ "openedBy":
null
+ }`),
+ },
+ bug{
+ NotifyEmail: "[email protected]",
+ OpenedBy: nil,
+ },
+ false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ var dst bug
+ if err := json.Unmarshal(tt.args.data, &dst); (err !=
nil) != tt.wantErr {
+ t.Errorf("UnmarshalJSON() error = %v, wantErr
%v", err, tt.wantErr)
+ }
+ if !reflect.DeepEqual(dst, tt.want) {
+ t.Errorf("UnmarshalJSON() got = %v, want %v",
dst, tt.want)
+ }
+ t.Logf("%+v\n", dst.OpenedBy)
+ })
+ }
+}
diff --git a/backend/plugins/zentao/models/changelog.go
b/backend/plugins/zentao/models/changelog.go
index ef7693847..91ea87a81 100644
--- a/backend/plugins/zentao/models/changelog.go
+++ b/backend/plugins/zentao/models/changelog.go
@@ -27,14 +27,14 @@ type ZentaoChangelog struct {
common.NoPKModel `json:"-"`
ConnectionId uint64 `json:"connectionId"
mapstructure:"connectionId" gorm:"primaryKey;type:BIGINT NOT NULL"`
Id int64 `json:"id" mapstructure:"id"
gorm:"primaryKey;type:BIGINT NOT NULL;autoIncrement:false"`
- ObjectId int `json:"objectId" mapstructure:"objectId"
gorm:"index; NOT NULL"`
- Execution int `json:"execution" mapstructure:"execution" `
+ ObjectId int64 `json:"objectId" mapstructure:"objectId"
gorm:"index; NOT NULL"`
+ Execution int64 `json:"execution" mapstructure:"execution" `
Actor string `json:"actor" mapstructure:"actor" `
Action string `json:"action" mapstructure:"action"`
Extra string `json:"extra" mapstructure:"extra"`
ObjectType string `json:"objectType" mapstructure:"objectType"`
- Project int `json:"project" mapstructure:"project"`
- Product int `json:"product" mapstructure:"product"`
+ Project int64 `json:"project" mapstructure:"project"`
+ Product int64 `json:"product" mapstructure:"product"`
Vision string `json:"vision" mapstructure:"vision"`
Comment string `json:"comment" mapstructure:"comment"`
Efforted string `json:"efforted" mapstructure:"efforted"`
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/execution_stories.go
similarity index 65%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/execution_stories.go
index 4d3e3dc40..82b919c80 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/execution_stories.go
@@ -15,20 +15,20 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package models
import (
- "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/core/models/common"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoExecutionStory struct {
+ common.NoPKModel
+ ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"`
+ ProjectId int64 `gorm:"primaryKey"`
+ ExecutionId int64 `gorm:"primaryKey"`
+ StoryId int64 `gorm:"primaryKey"`
+}
+
+func (ZentaoExecutionStory) TableName() string {
+ return "_tool_zentao_execution_stories"
}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/execution_summary.go
similarity index 59%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/execution_summary.go
index 4d3e3dc40..2609697aa 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/execution_summary.go
@@ -15,20 +15,22 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package models
import (
- "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/core/models/common"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoExecutionSummary struct {
+ ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"`
+ Id int64 `gorm:"primaryKey;type:BIGINT NOT
NULL;autoIncrement:false"`
+ Name string `gorm:"type:varchar(255)"`
+ Project int64
+ Code string `gorm:"type:varchar(255)"`
+ Type string `gorm:"type:varchar(255)"`
+ common.NoPKModel
+}
+
+func (ZentaoExecutionSummary) TableName() string {
+ return "_tool_zentao_execution_summary"
}
diff --git
a/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
b/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
new file mode 100644
index 000000000..234451cf3
--- /dev/null
+++
b/backend/plugins/zentao/models/migrationscripts/20230705_add_execution_stories.go
@@ -0,0 +1,45 @@
+/*
+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 migrationscripts
+
+import (
+ "github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/helpers/migrationhelper"
+ "github.com/apache/incubator-devlake/plugins/zentao/models/archived"
+)
+
+type addExecutionStoryAndExecutionSummary struct{}
+
+func (*addExecutionStoryAndExecutionSummary) Up(basicRes context.BasicRes)
errors.Error {
+ return migrationhelper.AutoMigrateTables(
+ basicRes,
+ &archived.ZentaoExecutionStory{},
+ &archived.ZentaoExecutionSummary{},
+ &archived.ZentaoProductSummary{},
+ &archived.ZentaoProjectStory{},
+ )
+}
+
+func (*addExecutionStoryAndExecutionSummary) Version() uint64 {
+ return 20230705135809
+}
+
+func (*addExecutionStoryAndExecutionSummary) Name() string {
+ return "add table _tool_zentao_execution_stories,
_tool_zentao_execution_summary and _tool_zentao_product_summary"
+}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/migrationscripts/register.go
index 4d3e3dc40..4fdfac508 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/migrationscripts/register.go
@@ -29,6 +29,7 @@ func All() []plugin.MigrationScript {
new(addIssueRepoCommitsTables),
new(addInitChangelogTables),
new(addTaskLeft),
+ new(addExecutionStoryAndExecutionSummary),
new(addRawParamTableForScope),
}
}
diff --git a/backend/plugins/zentao/models/product.go
b/backend/plugins/zentao/models/product.go
index 7790a6990..a4ec727ea 100644
--- a/backend/plugins/zentao/models/product.go
+++ b/backend/plugins/zentao/models/product.go
@@ -18,10 +18,7 @@ limitations under the License.
package models
import (
- "fmt"
-
"github.com/apache/incubator-devlake/core/models/common"
- "github.com/apache/incubator-devlake/core/plugin"
helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
)
@@ -69,49 +66,6 @@ type ZentaoProductRes struct {
CaseReview bool `json:"caseReview" mapstructure:"caseReview"`
}
-func getAccountId(account *ZentaoAccount) int64 {
- if account != nil {
- return account.ID
- }
- return 0
-}
-
-func (res ZentaoProductRes) ConvertApiScope() plugin.ToolLayerScope {
- return &ZentaoProduct{
- Id: res.ID,
- Program: res.Program,
- Name: res.Name,
- Code: res.Code,
- Bind: res.Bind,
- Line: res.Line,
- Type: `product`,
- ProductType: res.Type,
- Status: res.Status,
- SubStatus: res.SubStatus,
- Description: res.Description,
- POId: getAccountId(res.PO),
- QDId: getAccountId(res.QD),
- RDId: getAccountId(res.RD),
- Acl: res.Acl,
- Reviewer: res.Reviewer,
- CreatedById: getAccountId(res.CreatedBy),
- CreatedDate: res.CreatedDate,
- CreatedVersion: res.CreatedVersion,
- OrderIn: res.OrderIn,
- Deleted: res.Deleted,
- Plans: res.Plans,
- Releases: res.Releases,
- Builds: res.Builds,
- Cases: res.Cases,
- Projects: res.Projects,
- Executions: res.Executions,
- Bugs: res.Bugs,
- Docs: res.Docs,
- Progress: res.Progress,
- CaseReview: res.CaseReview,
- }
-}
-
type ZentaoProduct struct {
common.NoPKModel `json:"-"`
ConnectionId uint64 `json:"connectionId"
mapstructure:"connectionId" gorm:"primaryKey;type:BIGINT NOT NULL"`
@@ -152,18 +106,3 @@ type ZentaoProduct struct {
func (ZentaoProduct) TableName() string {
return "_tool_zentao_products"
}
-
-func (p ZentaoProduct) ScopeId() string {
- return fmt.Sprintf(`products/%d`, p.Id)
-}
-
-func (p ZentaoProduct) ScopeParams() interface{} {
- return &ZentaoApiParams{
- ConnectionId: p.ConnectionId,
- ZentaoId: fmt.Sprintf("products/%d", p.Id),
- }
-}
-
-func (p ZentaoProduct) ScopeName() string {
- return p.Name
-}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/product_summary.go
similarity index 64%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/product_summary.go
index 4d3e3dc40..f448af77b 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/product_summary.go
@@ -15,20 +15,18 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package models
-import (
- "github.com/apache/incubator-devlake/core/plugin"
-)
+import "github.com/apache/incubator-devlake/core/models/common"
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoProductSummary struct {
+ common.NoPKModel
+ ConnectionId uint64 `gorm:"primaryKey"`
+ ProjectId int64 `gorm:"primaryKey"`
+ Id int64 `gorm:"primaryKey;autoIncrement:false"`
+ Name string `gorm:"type:VARCHAR(255)"`
+}
+
+func (ZentaoProductSummary) TableName() string {
+ return "_tool_zentao_product_summary"
}
diff --git a/backend/plugins/zentao/models/project.go
b/backend/plugins/zentao/models/project.go
index 42390d4f9..26402b0cc 100644
--- a/backend/plugins/zentao/models/project.go
+++ b/backend/plugins/zentao/models/project.go
@@ -157,7 +157,7 @@ func (p ZentaoProject) ScopeName() string {
func (p ZentaoProject) ScopeParams() interface{} {
return &ZentaoApiParams{
ConnectionId: p.ConnectionId,
- ZentaoId: fmt.Sprintf("projects/%d", p.Id),
+ ProjectId: p.Id,
}
}
@@ -171,5 +171,5 @@ func (p ZentaoProject) ConvertApiScope()
plugin.ToolLayerScope {
type ZentaoApiParams struct {
ConnectionId uint64
- ZentaoId string
+ ProjectId int64
}
diff --git a/backend/plugins/zentao/models/migrationscripts/register.go
b/backend/plugins/zentao/models/project_stories.go
similarity index 68%
copy from backend/plugins/zentao/models/migrationscripts/register.go
copy to backend/plugins/zentao/models/project_stories.go
index 4d3e3dc40..79a02f319 100644
--- a/backend/plugins/zentao/models/migrationscripts/register.go
+++ b/backend/plugins/zentao/models/project_stories.go
@@ -15,20 +15,19 @@ See the License for the specific language governing
permissions and
limitations under the License.
*/
-package migrationscripts
+package models
import (
- "github.com/apache/incubator-devlake/core/plugin"
+ "github.com/apache/incubator-devlake/core/models/common"
)
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
- return []plugin.MigrationScript{
- new(addInitTables),
- new(addScopeConfigTables),
- new(addIssueRepoCommitsTables),
- new(addInitChangelogTables),
- new(addTaskLeft),
- new(addRawParamTableForScope),
- }
+type ZentaoProjectStory struct {
+ common.NoPKModel
+ ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"`
+ ProjectId int64 `gorm:"primaryKey"`
+ StoryId int64 `gorm:"primaryKey"`
+}
+
+func (ZentaoProjectStory) TableName() string {
+ return "_tool_zentao_project_stories"
}
diff --git a/backend/plugins/zentao/models/remote_db.go
b/backend/plugins/zentao/models/remote_db.go
index a1b1f09fd..99233afa2 100644
--- a/backend/plugins/zentao/models/remote_db.go
+++ b/backend/plugins/zentao/models/remote_db.go
@@ -29,22 +29,34 @@ type ZentaoRemoteDbHistoryBase struct {
}
type ZentaoRemoteDbHistory struct {
- Id int `gorm:"column:id"`
- Action int `gorm:"column:action"`
+ Id int64 `gorm:"column:id"`
+ Action int64 `gorm:"column:action"`
ZentaoRemoteDbHistoryBase
}
+func (h ZentaoRemoteDbHistory) ToChangelogDetail(connectionId uint64)
*ZentaoChangelogDetail {
+ return &ZentaoChangelogDetail{
+ ConnectionId: connectionId,
+ Id: h.Id,
+ ChangelogId: h.Action,
+ Field: h.Field,
+ Old: h.Old,
+ New: h.New,
+ Diff: h.Diff,
+ }
+}
+
func (ZentaoRemoteDbHistory) TableName() string {
return "zt_history"
}
type ZentaoRemoteDbAction struct {
- Id int `gorm:"column:id"`
+ Id int64 `gorm:"column:id"`
ObjectType string `gorm:"column:objectType"`
- ObjectId int `gorm:"column:objectID"`
+ ObjectId int64 `gorm:"column:objectID"`
Product string `gorm:"column:product"`
- Project int `gorm:"column:project"`
- Execution int `gorm:"column:execution"`
+ Project int64 `gorm:"column:project"`
+ Execution int64 `gorm:"column:execution"`
Actor string `gorm:"column:actor"`
Action string `gorm:"column:action"`
Date time.Time `gorm:"column:date"`
@@ -55,6 +67,25 @@ type ZentaoRemoteDbAction struct {
Efforted string `gorm:"column:efforted"`
}
+func (a ZentaoRemoteDbAction) ToChangelog(connectionId uint64)
*ZentaoChangelog {
+ return &ZentaoChangelog{
+ ConnectionId: connectionId,
+ Id: a.Id,
+ ObjectId: a.ObjectId,
+ Execution: a.Execution,
+ Actor: a.Actor,
+ Action: a.Action,
+ Extra: a.Extra,
+ ObjectType: a.ObjectType,
+ Project: a.Project,
+ Vision: a.Vision,
+ Comment: a.Comment,
+ Efforted: a.Efforted,
+ Date: a.Date,
+ Read: a.Read,
+ }
+}
+
func (ZentaoRemoteDbAction) TableName() string {
return "zt_action"
}
@@ -63,34 +94,36 @@ type ZentaoRemoteDbActionHistory struct {
ZentaoRemoteDbAction
ZentaoRemoteDbHistoryBase
- ActionId int `gorm:"column:aid"`
- HistoryId int `gorm:"column:hid"`
+ ActionId int64 `gorm:"column:aid"`
+ HistoryId int64 `gorm:"column:hid"`
}
-func (ah *ZentaoRemoteDbActionHistory) Convert() *ZentaoChangelogCom {
+func (ah *ZentaoRemoteDbActionHistory) Convert(connectId uint64)
*ZentaoChangelogCom {
return &ZentaoChangelogCom{
&ZentaoChangelog{
- Id: int64(ah.ActionId),
- ObjectId: ah.ObjectId,
- Execution: ah.Execution,
- Actor: ah.Actor,
- Action: ah.Action,
- Extra: ah.Extra,
- ObjectType: ah.ObjectType,
- Project: ah.Project,
- Vision: ah.Vision,
- Comment: ah.Comment,
- Efforted: ah.Efforted,
- Date: ah.Date,
- Read: ah.Read,
+ ConnectionId: connectId,
+ Id: ah.ActionId,
+ ObjectId: ah.ObjectId,
+ Execution: ah.Execution,
+ Actor: ah.Actor,
+ Action: ah.Action,
+ Extra: ah.Extra,
+ ObjectType: ah.ObjectType,
+ Project: ah.Project,
+ Vision: ah.Vision,
+ Comment: ah.Comment,
+ Efforted: ah.Efforted,
+ Date: ah.Date,
+ Read: ah.Read,
},
&ZentaoChangelogDetail{
- Id: int64(ah.HistoryId),
- ChangelogId: int64(ah.ActionId),
- Field: ah.Field,
- Old: ah.Old,
- New: ah.New,
- Diff: ah.Diff,
+ ConnectionId: connectId,
+ Id: ah.HistoryId,
+ ChangelogId: ah.ActionId,
+ Field: ah.Field,
+ Old: ah.Old,
+ New: ah.New,
+ Diff: ah.Diff,
},
}
}
diff --git a/backend/plugins/zentao/tasks/account_collector.go
b/backend/plugins/zentao/tasks/account_collector.go
index 9ecd35665..dd849e638 100644
--- a/backend/plugins/zentao/tasks/account_collector.go
+++ b/backend/plugins/zentao/tasks/account_collector.go
@@ -36,13 +36,9 @@ func CollectAccount(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_ACCOUNT_TABLE,
+ Ctx: taskCtx,
+ Table: RAW_ACCOUNT_TABLE,
+ Options: data.Options,
},
ApiClient: data.ApiClient,
PageSize: 100,
diff --git a/backend/plugins/zentao/tasks/account_convertor.go
b/backend/plugins/zentao/tasks/account_convertor.go
index 50a4aaa2b..1a07a12dd 100644
--- a/backend/plugins/zentao/tasks/account_convertor.go
+++ b/backend/plugins/zentao/tasks/account_convertor.go
@@ -57,13 +57,9 @@ func ConvertAccount(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoAccount{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_ACCOUNT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_ACCOUNT_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoAccount)
diff --git a/backend/plugins/zentao/tasks/account_extractor.go
b/backend/plugins/zentao/tasks/account_extractor.go
index 9ad1b720d..eba07bea7 100644
--- a/backend/plugins/zentao/tasks/account_extractor.go
+++ b/backend/plugins/zentao/tasks/account_extractor.go
@@ -40,13 +40,9 @@ func ExtractAccount(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_ACCOUNT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_ACCOUNT_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
account := &models.ZentaoAccount{}
@@ -55,9 +51,7 @@ func ExtractAccount(taskCtx plugin.SubTaskContext)
errors.Error {
return nil, errors.Default.WrapRaw(err)
}
account.ConnectionId = data.Options.ConnectionId
- results := make([]interface{}, 0)
- results = append(results, account)
- return results, nil
+ return []interface{}{account}, nil
},
})
diff --git a/backend/plugins/zentao/tasks/bug_collector.go
b/backend/plugins/zentao/tasks/bug_collector.go
index 700012430..2aebd07fe 100644
--- a/backend/plugins/zentao/tasks/bug_collector.go
+++ b/backend/plugins/zentao/tasks/bug_collector.go
@@ -33,30 +33,22 @@ const RAW_BUG_TABLE = "zentao_api_bugs"
var _ plugin.SubTaskEntryPoint = CollectBug
func CollectBug(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, CollectBugForOneProduct)
-}
-
-func CollectBugForOneProduct(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
-
- // this collect only work for product
- if data.Options.ProductId == 0 {
- return nil
+ cursor, iterator, err := getProductIterator(taskCtx)
+ if err != nil {
+ return err
}
-
+ defer cursor.Close()
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_TABLE,
},
+ Input: iterator,
ApiClient: data.ApiClient,
PageSize: 100,
- UrlTemplate: "/{{ .Params.ZentaoId }}/bugs",
+ UrlTemplate: "/products/{{ .Input.Id }}/bugs",
Query: func(reqData *api.RequestData) (url.Values,
errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
diff --git a/backend/plugins/zentao/tasks/bug_commits_collector.go
b/backend/plugins/zentao/tasks/bug_commits_collector.go
index 7c2b61420..70970058f 100644
--- a/backend/plugins/zentao/tasks/bug_commits_collector.go
+++ b/backend/plugins/zentao/tasks/bug_commits_collector.go
@@ -41,23 +41,20 @@ var CollectBugCommitsMeta = plugin.SubTaskMeta{
DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
}
-func CollectBugCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, CollectBugCommitsForOneProduct)
+type bugInput struct {
+ BugId int64
+ ProductId int64
}
-func CollectBugCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
+func CollectBugCommits(taskCtx plugin.SubTaskContext) errors.Error {
db := taskCtx.GetDal()
data := taskCtx.GetData().(*ZentaoTaskData)
// state manager
collectorWithState, err :=
api.NewStatefulApiCollector(api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_COMMITS_TABLE,
}, data.TimeAfter)
if err != nil {
return err
@@ -65,11 +62,11 @@ func CollectBugCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error
// load bugs id from db
clauses := []dal.Clause{
- dal.Select("id, last_edited_date"),
+ dal.Select("id As bug_id, product As product_id"),
dal.From(&models.ZentaoBug{}),
dal.Where(
- "product = ? AND connection_id = ?",
- data.Options.ProductId, data.Options.ConnectionId,
+ "project = ? AND connection_id = ?",
+ data.Options.ProjectId, data.Options.ConnectionId,
),
}
// incremental collection
@@ -84,25 +81,21 @@ func CollectBugCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error
if err != nil {
return err
}
- iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(SimpleZentaoBug{}))
+ iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(bugInput{}))
if err != nil {
return err
}
// collect bug commits
err = collectorWithState.InitCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_COMMITS_TABLE,
},
ApiClient: data.ApiClient,
Input: iterator,
Incremental: incremental,
- UrlTemplate: "bugs/{{ .Input.ID }}",
+ UrlTemplate: "bugs/{{ .Input.BugId }}",
ResponseParser: func(res *http.Response) ([]json.RawMessage,
errors.Error) {
var data struct {
Actions []json.RawMessage `json:"actions"`
diff --git a/backend/plugins/zentao/tasks/bug_commits_extractor.go
b/backend/plugins/zentao/tasks/bug_commits_extractor.go
index 23454341f..498e9bb89 100644
--- a/backend/plugins/zentao/tasks/bug_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/bug_commits_extractor.go
@@ -39,27 +39,14 @@ var ExtractBugCommitsMeta = plugin.SubTaskMeta{
}
func ExtractBugCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ExtractBugCommitsForOneProduct)
-}
-
-func ExtractBugCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for product
- if data.Options.ProductId == 0 {
- return nil
- }
-
re := regexp.MustCompile(`href='(.*?)'`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_COMMITS_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoBugCommitsRes{}
@@ -67,6 +54,11 @@ func ExtractBugCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error
if err != nil {
return nil, errors.Default.WrapRaw(err)
}
+ var input bugInput
+ err = json.Unmarshal(row.Input, &input)
+ if err != nil {
+ return nil, errors.Default.WrapRaw(err)
+ }
// only linked2revision action is valid
if res.Action != "linked2revision" {
return nil, nil
@@ -77,7 +69,7 @@ func ExtractBugCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error
ID: res.ID,
ObjectType: res.ObjectType,
ObjectID: res.ObjectID,
- Product: data.Options.ProductId,
+ Product: input.ProductId,
Project: data.Options.ProjectId,
Execution: res.Execution,
Actor: res.Actor,
diff --git a/backend/plugins/zentao/tasks/bug_convertor.go
b/backend/plugins/zentao/tasks/bug_convertor.go
index 945e27351..f9731cd10 100644
--- a/backend/plugins/zentao/tasks/bug_convertor.go
+++ b/backend/plugins/zentao/tasks/bug_convertor.go
@@ -42,15 +42,11 @@ var ConvertBugMeta = plugin.SubTaskMeta{
}
func ConvertBug(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ConvertBugForOneProduct)
-}
-
-func ConvertBugForOneProduct(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
bugIdGen := didgen.NewDomainIdGenerator(&models.ZentaoBug{})
accountIdGen := didgen.NewDomainIdGenerator(&models.ZentaoAccount{})
-
+ executionIdGen := didgen.NewDomainIdGenerator(&models.ZentaoExecution{})
boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProduct{})
if data.Options.ProjectId != 0 {
boardIdGen =
didgen.NewDomainIdGenerator(&models.ZentaoProject{})
@@ -59,8 +55,8 @@ func ConvertBugForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
storyIdGen := didgen.NewDomainIdGenerator(&models.ZentaoStory{})
cursor, err := db.Cursor(
dal.From(&models.ZentaoBug{}),
- dal.Where(`_tool_zentao_bugs.product = ? and
- _tool_zentao_bugs.connection_id = ?`,
data.Options.ProductId, data.Options.ConnectionId),
+ dal.Where(`project = ? and
+ connection_id = ?`, data.Options.ProjectId,
data.Options.ConnectionId),
)
if err != nil {
return err
@@ -70,13 +66,9 @@ func ConvertBugForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoBug{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoBug)
@@ -122,15 +114,17 @@ func ConvertBugForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error {
results = append(results, issueAssignee)
}
- boardId :=
boardIdGen.Generate(data.Options.ConnectionId, data.Options.ProductId)
- if data.Options.ProjectId != 0 {
- boardId =
boardIdGen.Generate(data.Options.ConnectionId, data.Options.ProjectId)
- }
-
domainBoardIssue := &ticket.BoardIssue{
- BoardId: boardId,
+ BoardId:
boardIdGen.Generate(data.Options.ConnectionId, data.Options.ProjectId),
IssueId: domainEntity.Id,
}
+ if toolEntity.Execution != 0 {
+ sprintIssue := &ticket.SprintIssue{
+ SprintId:
executionIdGen.Generate(data.Options.ConnectionId, toolEntity.Execution),
+ IssueId: domainEntity.Id,
+ }
+ results = append(results, sprintIssue)
+ }
results = append(results, domainEntity,
domainBoardIssue)
return results, nil
},
diff --git a/backend/plugins/zentao/tasks/bug_extractor.go
b/backend/plugins/zentao/tasks/bug_extractor.go
index 9226e8847..6be9ddfbd 100644
--- a/backend/plugins/zentao/tasks/bug_extractor.go
+++ b/backend/plugins/zentao/tasks/bug_extractor.go
@@ -38,29 +38,16 @@ var ExtractBugMeta = plugin.SubTaskMeta{
}
func ExtractBug(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ExtractBugForOneProduct)
-}
-
-func ExtractBugForOneProduct(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for product
- if data.Options.ProductId == 0 {
- return nil
- }
-
statusMappings := getBugStatusMapping(data)
stdTypeMappings := getStdTypeMappings(data)
-
+ cache := newAccountCache(taskCtx.GetDal(), data.Options.ConnectionId)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoBugRes{}
@@ -68,18 +55,11 @@ func ExtractBugForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
if err != nil {
return nil, errors.Default.WrapRaw(err)
}
-
- // project scope need filter
- if data.Options.ProjectId != 0 {
- if init, ok := data.FromBugList[int(res.ID)];
!ok || !init {
- return nil, nil
- }
- }
-
+ data.Bugs[res.ID] = struct{}{}
bug := &models.ZentaoBug{
ConnectionId: data.Options.ConnectionId,
ID: res.ID,
- Project: res.Project,
+ Project: data.Options.ProjectId,
Product: res.Product,
Injection: res.Injection,
Identify: res.Identify,
@@ -110,19 +90,19 @@ func ExtractBugForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error {
ActivatedDate: res.ActivatedDate,
FeedbackBy: res.FeedbackBy,
NotifyEmail: res.NotifyEmail,
- OpenedById: getAccountId(res.OpenedBy),
- OpenedByName: getAccountName(res.OpenedBy),
+ OpenedById:
cache.getAccountIDFromApiAccount(res.OpenedBy),
+ OpenedByName:
cache.getAccountNameFromApiAccount(res.OpenedBy),
OpenedDate: res.OpenedDate,
OpenedBuild: res.OpenedBuild,
- AssignedToId: getAccountId(res.AssignedTo),
- AssignedToName: getAccountName(res.AssignedTo),
+ AssignedToId:
cache.getAccountIDFromApiAccount(res.AssignedTo),
+ AssignedToName:
cache.getAccountNameFromApiAccount(res.AssignedTo),
AssignedDate: res.AssignedDate,
Deadline: res.Deadline,
- ResolvedById: getAccountId(res.ResolvedBy),
+ ResolvedById:
cache.getAccountIDFromApiAccount(res.ResolvedBy),
Resolution: res.Resolution,
ResolvedBuild: res.ResolvedBuild,
ResolvedDate: res.ResolvedDate,
- ClosedById: getAccountId(res.ClosedBy),
+ ClosedById:
cache.getAccountIDFromApiAccount(res.ClosedBy),
ClosedDate: res.ClosedDate,
DuplicateBug: res.DuplicateBug,
LinkBug: res.LinkBug,
@@ -137,7 +117,7 @@ func ExtractBugForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
RepoType: res.RepoType,
IssueKey: res.IssueKey,
Testtask: res.Testtask,
- LastEditedById: getAccountId(res.LastEditedBy),
+ LastEditedById:
cache.getAccountIDFromApiAccount(res.LastEditedBy),
LastEditedDate: res.LastEditedDate,
Deleted: res.Deleted,
PriOrder: res.PriOrder,
diff --git a/backend/plugins/zentao/tasks/bug_repo_commits_collector.go
b/backend/plugins/zentao/tasks/bug_repo_commits_collector.go
index 4428c042a..7d499e106 100644
--- a/backend/plugins/zentao/tasks/bug_repo_commits_collector.go
+++ b/backend/plugins/zentao/tasks/bug_repo_commits_collector.go
@@ -42,20 +42,16 @@ var CollectBugRepoCommitsMeta = plugin.SubTaskMeta{
}
func CollectBugRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, CollectBugRepoCommitsForOneProduct)
-}
-
-func CollectBugRepoCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
db := taskCtx.GetDal()
data := taskCtx.GetData().(*ZentaoTaskData)
// load bugs id from db
clauses := []dal.Clause{
- dal.Select("object_id, repo_revision"),
+ dal.Select("product, repo_revision"),
dal.From(&models.ZentaoBugCommit{}),
dal.Where(
- "product = ? AND connection_id = ?",
- data.Options.ProductId, data.Options.ConnectionId,
+ "project = ? AND connection_id = ?",
+ data.Options.ProjectId, data.Options.ConnectionId,
),
}
@@ -64,7 +60,7 @@ func CollectBugRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Er
return err
}
- iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(SimpleZentaoBugCommit{}))
+ iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(bugCommitInput{}))
if err != nil {
return err
}
@@ -72,13 +68,9 @@ func CollectBugRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Er
// collect bug repo commits
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_REPO_COMMITS_TABLE,
},
ApiClient: data.ApiClient,
Input: iterator,
@@ -102,11 +94,9 @@ func CollectBugRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Er
return collector.Execute()
}
-type SimpleZentaoBugCommit struct {
- ObjectID int `json:"objectID"`
- Host string `json:"host"` //the host part of extra
+type bugCommitInput struct {
+ Product int64
RepoRevision string `json:"repoRevision"` // the repoRevisionJson part
of extra
-
}
type RepoRevisionResponse struct {
diff --git a/backend/plugins/zentao/tasks/bug_repo_commits_convertor.go
b/backend/plugins/zentao/tasks/bug_repo_commits_convertor.go
index 41e946bc9..cdd538ec9 100644
--- a/backend/plugins/zentao/tasks/bug_repo_commits_convertor.go
+++ b/backend/plugins/zentao/tasks/bug_repo_commits_convertor.go
@@ -40,16 +40,12 @@ var ConvertBugRepoCommitsMeta = plugin.SubTaskMeta{
}
func ConvertBugRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ConvertBugRepoCommitsForOneProduct)
-}
-
-func ConvertBugRepoCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
cursor, err := db.Cursor(
dal.From(&models.ZentaoBugRepoCommit{}),
- dal.Where(`product = ? and connection_id = ?`,
data.Options.ProductId, data.Options.ConnectionId),
+ dal.Where(`project = ? and connection_id = ?`,
data.Options.ProjectId, data.Options.ConnectionId),
)
if err != nil {
return err
@@ -61,13 +57,9 @@ func ConvertBugRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Er
InputRowType: reflect.TypeOf(models.ZentaoBugRepoCommit{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_REPO_COMMITS_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoBugRepoCommit)
diff --git a/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
b/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
index 8b49d0626..53b9215ce 100644
--- a/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/bug_repo_commits_extractor.go
@@ -38,27 +38,15 @@ var ExtractBugRepoCommitsMeta = plugin.SubTaskMeta{
}
func ExtractBugRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ExtractBugRepoCommitsForOneProduct)
-}
-
-func ExtractBugRepoCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for product
- if data.Options.ProductId == 0 {
- return nil
- }
re := regexp.MustCompile(`(\d+)(?:,\s*(\d+))*`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_BUG_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_BUG_REPO_COMMITS_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoBugRepoCommitsRes{}
@@ -66,14 +54,18 @@ func ExtractBugRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Er
if err != nil {
return nil, errors.Default.WrapRaw(err)
}
-
+ var input bugCommitInput
+ err = json.Unmarshal(row.Input, &input)
+ if err != nil {
+ return nil, errors.Default.WrapRaw(err)
+ }
results := make([]interface{}, 0)
match := re.FindStringSubmatch(res.Log.Comment)
for i := 1; i < len(match); i++ {
if match[i] != "" {
bugRepoCommits :=
&models.ZentaoBugRepoCommit{
ConnectionId:
data.Options.ConnectionId,
- Product:
data.Options.ProductId,
+ Product: input.Product,
Project:
data.Options.ProjectId,
RepoUrl: res.Repo.CodePath,
CommitSha: res.Revision,
diff --git a/backend/plugins/zentao/tasks/changelog_convertor.go
b/backend/plugins/zentao/tasks/changelog_convertor.go
index 6cd43730a..2ee973655 100644
--- a/backend/plugins/zentao/tasks/changelog_convertor.go
+++ b/backend/plugins/zentao/tasks/changelog_convertor.go
@@ -79,9 +79,8 @@ func ConvertChangelog(taskCtx plugin.SubTaskContext)
errors.Error {
dal.From(&models.ZentaoChangelog{}),
dal.Join(fmt.Sprintf("LEFT JOIN %s on %s.changelog_id = %s.id",
cdn, cdn, cn)),
dal.Join(fmt.Sprintf("LEFT JOIN %s on %s.realname = %s.actor",
an, an, cn)),
- dal.Where(fmt.Sprintf(`%s.product = ? and %s.project = ? and
%s.connection_id = ?`,
- cn, cn, cn),
- data.Options.ProductId,
+ dal.Where(fmt.Sprintf(`%s.project = ? and %s.connection_id = ?`,
+ cn, cn),
data.Options.ProjectId,
data.Options.ConnectionId),
)
@@ -94,13 +93,9 @@ func ConvertChangelog(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(ZentaoChangelogSelect{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_ACCOUNT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_ACCOUNT_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
cl := inputRow.(*ZentaoChangelogSelect)
@@ -168,18 +163,18 @@ func ConvertChangelog(taskCtx plugin.SubTaskContext)
errors.Error {
// accountCache is a cache for account id
type accountCache struct {
- accounts map[string]int64
+ accounts map[string]models.ZentaoAccount
db dal.Dal
connectionId uint64
}
func newAccountCache(db dal.Dal, connectionId uint64) *accountCache {
- return &accountCache{db: db, connectionId: connectionId, accounts:
make(map[string]int64)}
+ return &accountCache{db: db, connectionId: connectionId, accounts:
make(map[string]models.ZentaoAccount)}
}
func (a *accountCache) getAccountID(account string) int64 {
- if id, ok := a.accounts[account]; ok {
- return id
+ if data, ok := a.accounts[account]; ok {
+ return data.ID
}
var zentaoAccount models.ZentaoAccount
err := a.db.First(
@@ -189,6 +184,42 @@ func (a *accountCache) getAccountID(account string) int64 {
if err != nil {
return 0
}
- a.accounts[account] = zentaoAccount.ID
+ a.accounts[account] = zentaoAccount
return zentaoAccount.ID
}
+
+func (a *accountCache) getAccountIDFromApiAccount(account *models.ApiAccount)
int64 {
+ if account == nil {
+ return 0
+ }
+ if account.ID != 0 {
+ return account.ID
+ }
+ return a.getAccountID(account.Account)
+}
+
+func (a *accountCache) getAccountName(account string) string {
+ if data, ok := a.accounts[account]; ok {
+ return data.Realname
+ }
+ var zentaoAccount models.ZentaoAccount
+ err := a.db.First(
+ &zentaoAccount,
+ dal.Where("connection_id = ? AND account = ?", a.connectionId,
account),
+ )
+ if err != nil {
+ return ""
+ }
+ a.accounts[account] = zentaoAccount
+ return zentaoAccount.Realname
+}
+
+func (a *accountCache) getAccountNameFromApiAccount(account
*models.ApiAccount) string {
+ if account == nil {
+ return ""
+ }
+ if account.Realname != "" {
+ return account.Realname
+ }
+ return a.getAccountName(account.Account)
+}
diff --git a/backend/plugins/zentao/tasks/changelog_dbget.go
b/backend/plugins/zentao/tasks/changelog_dbget.go
index 64d15630f..f192d5910 100644
--- a/backend/plugins/zentao/tasks/changelog_dbget.go
+++ b/backend/plugins/zentao/tasks/changelog_dbget.go
@@ -18,7 +18,6 @@ limitations under the License.
package tasks
import (
- "fmt"
"reflect"
"github.com/apache/incubator-devlake/core/dal"
@@ -30,93 +29,114 @@ import (
var _ plugin.SubTaskEntryPoint = DBGetActionHistory
-func DBGetActionHistory(taskCtx plugin.SubTaskContext) errors.Error {
- data := taskCtx.GetData().(*ZentaoTaskData)
+type actionHistoryHandler struct {
+ changelogBachSave *api.BatchSave
+ changelogDetailBachSave *api.BatchSave
+ stories map[int64]struct{}
+ tasks map[int64]struct{}
+ bugs map[int64]struct{}
+}
- // skip if no RemoteDb
- if data.RemoteDb == nil {
- return nil
+func newActionHistoryHandler(taskCtx plugin.SubTaskContext, divider
*api.BatchSaveDivider) (*actionHistoryHandler, errors.Error) {
+ data := taskCtx.GetData().(*ZentaoTaskData)
+ changelogBachSave, err :=
divider.ForType(reflect.TypeOf(&models.ZentaoChangelog{}))
+ if err != nil {
+ return nil, err
}
+ changelogDetailBachSave, err :=
divider.ForType(reflect.TypeOf(&models.ZentaoChangelogDetail{}))
+ if err != nil {
+ return nil, err
+ }
+ return &actionHistoryHandler{
+ changelogBachSave: changelogBachSave,
+ changelogDetailBachSave: changelogDetailBachSave,
+ stories: data.Stories,
+ tasks: data.Tasks,
+ bugs: data.Bugs,
+ }, nil
+}
- divider := api.NewBatchSaveDivider(taskCtx, 500, "", "")
- defer func() {
- err1 := divider.Close()
- if err1 != nil {
- panic(err1)
- }
- }()
+func (h actionHistoryHandler) collectActionHistory(rdb dal.Dal, connectionId
uint64) errors.Error {
+ clause := []dal.Clause{
+ dal.Select("*,zt_action.id aid,zt_history.id hid "),
+ dal.From("zt_action"),
+ dal.Join("LEFT JOIN zt_history on zt_history.action =
zt_action.id"),
+ dal.Where("zt_action.objectType IN ?", []string{"story",
"task", "bug"}),
+ }
+ cursor, err := rdb.Cursor(clause...)
+ if err != nil {
+ return err
+ }
+ defer cursor.Close()
- return dBGetActionHistory(data, func(zcc *models.ZentaoChangelogCom)
errors.Error {
- batch, err := divider.ForType(reflect.TypeOf(zcc.Changelog))
+ for cursor.Next() {
+ var ah models.ZentaoRemoteDbActionHistory
+ err = rdb.Fetch(cursor, &ah)
if err != nil {
return err
}
- zcc.Changelog.ConnectionId = data.Options.ConnectionId
- zcc.Changelog.Product = int(data.Options.ProductId)
- err = batch.Add(zcc.Changelog)
+ switch ah.ObjectType {
+ case "story":
+ if _, ok := h.stories[ah.ObjectId]; !ok {
+ continue
+ }
+ case "task":
+ if _, ok := h.tasks[ah.ObjectId]; !ok {
+ continue
+ }
+ case "bug":
+ if _, ok := h.bugs[ah.ObjectId]; !ok {
+ continue
+ }
+ default:
+ continue
+ }
+
+ zcc := ah.Convert(connectionId)
+ err = h.changelogBachSave.Add(zcc.Changelog)
if err != nil {
return err
}
if zcc.ChangelogDetail.Id != 0 {
- batch, err =
divider.ForType(reflect.TypeOf(zcc.ChangelogDetail))
- if err != nil {
- return err
- }
- zcc.ChangelogDetail.ConnectionId =
data.Options.ConnectionId
- err = batch.Add(zcc.ChangelogDetail)
+ err = h.changelogDetailBachSave.Add(zcc.ChangelogDetail)
if err != nil {
return err
}
}
- return nil
- })
-}
-
-var DBGetChangelogMeta = plugin.SubTaskMeta{
- Name: "DBGetChangelog",
- EntryPoint: DBGetActionHistory,
- EnabledByDefault: true,
- Description: "get action and history data to be changelog from
Zentao databases",
- DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
-}
-
-// it is work for zentao version 18.3
-func dBGetActionHistory(data *ZentaoTaskData, callback
func(*models.ZentaoChangelogCom) errors.Error) errors.Error {
- rdb := data.RemoteDb
- atn := (models.ZentaoRemoteDbAction{}).TableName()
- htn := (models.ZentaoRemoteDbHistory{}).TableName()
-
- clause := []dal.Clause{
- dal.Select(fmt.Sprintf("*,%s.id aid,%s.id hid ", atn, htn)),
- dal.From(atn),
}
-
- if data.Options.ProductId != 0 {
- clause = append(clause, dal.Where(fmt.Sprintf("%s.product = ?",
atn), fmt.Sprintf(",%d,", data.Options.ProductId)))
- }
- if data.Options.ProjectId != 0 {
- clause = append(clause, dal.Where(fmt.Sprintf("%s.project = ?",
atn), data.Options.ProjectId))
- }
- clause = append(clause, dal.Join(fmt.Sprintf("LEFT JOIN %s on %s.action
= %s.id", htn, htn, atn)))
-
- cursor, err := rdb.Cursor(clause...)
+ err = h.changelogBachSave.Flush()
if err != nil {
return err
}
- defer cursor.Close()
+ return h.changelogDetailBachSave.Flush()
+}
- for cursor.Next() {
- actionHistory := &models.ZentaoRemoteDbActionHistory{}
- err = rdb.Fetch(cursor, actionHistory)
- if err != nil {
- return err
- }
+func DBGetActionHistory(taskCtx plugin.SubTaskContext) errors.Error {
+ data := taskCtx.GetData().(*ZentaoTaskData)
- err = callback(actionHistory.Convert())
- if err != nil {
- return err
+ // skip if no RemoteDb
+ if data.RemoteDb == nil {
+ return nil
+ }
+
+ divider := api.NewBatchSaveDivider(taskCtx, 500, "", "")
+ defer func() {
+ err1 := divider.Close()
+ if err1 != nil {
+ panic(err1)
}
+ }()
+ handler, err := newActionHistoryHandler(taskCtx, divider)
+ if err != nil {
+ return err
}
+ return handler.collectActionHistory(data.RemoteDb,
data.Options.ConnectionId)
+}
- return nil
+var DBGetChangelogMeta = plugin.SubTaskMeta{
+ Name: "DBGetChangelog",
+ EntryPoint: DBGetActionHistory,
+ EnabledByDefault: true,
+ Description: "get action and history data to be changelog from
Zentao databases",
+ DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
}
diff --git a/backend/plugins/zentao/tasks/department_collector.go
b/backend/plugins/zentao/tasks/department_collector.go
index bdcad7ffd..8da824846 100644
--- a/backend/plugins/zentao/tasks/department_collector.go
+++ b/backend/plugins/zentao/tasks/department_collector.go
@@ -36,17 +36,13 @@ func CollectDepartment(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_DEPARTMENT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_DEPARTMENT_TABLE,
},
ApiClient: data.ApiClient,
PageSize: 100,
- UrlTemplate: "/users",
+ UrlTemplate: "/departments",
Query: func(reqData *api.RequestData) (url.Values,
errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
@@ -55,14 +51,12 @@ func CollectDepartment(taskCtx plugin.SubTaskContext)
errors.Error {
},
GetTotalPages: GetTotalPagesFromResponse,
ResponseParser: func(res *http.Response) ([]json.RawMessage,
errors.Error) {
- var data struct {
- Users []json.RawMessage `json:"users"`
- }
+ var data []json.RawMessage
err := api.UnmarshalResponse(res, &data)
if err != nil {
- return nil, errors.Default.Wrap(err, "error
reading endpoint response by Zentao bug collector")
+ return nil, errors.Default.Wrap(err, "error
reading endpoint response by Zentao departments collector")
}
- return data.Users, nil
+ return data, nil
},
})
if err != nil {
diff --git a/backend/plugins/zentao/tasks/department_convertor.go
b/backend/plugins/zentao/tasks/department_convertor.go
index e5b88b917..b2c4a7020 100644
--- a/backend/plugins/zentao/tasks/department_convertor.go
+++ b/backend/plugins/zentao/tasks/department_convertor.go
@@ -56,13 +56,9 @@ func ConvertDepartment(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoDepartment{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_DEPARTMENT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_DEPARTMENT_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoDepartment)
diff --git a/backend/plugins/zentao/tasks/department_extractor.go
b/backend/plugins/zentao/tasks/department_extractor.go
index 691906ac8..d6cd5ada9 100644
--- a/backend/plugins/zentao/tasks/department_extractor.go
+++ b/backend/plugins/zentao/tasks/department_extractor.go
@@ -40,13 +40,9 @@ func ExtractDepartment(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_DEPARTMENT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_DEPARTMENT_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
department := &models.ZentaoDepartment{}
@@ -55,9 +51,7 @@ func ExtractDepartment(taskCtx plugin.SubTaskContext)
errors.Error {
return nil, errors.Default.WrapRaw(err)
}
department.ConnectionId = data.Options.ConnectionId
- results := make([]interface{}, 0)
- results = append(results, department)
- return results, nil
+ return []interface{}{department}, nil
},
})
diff --git a/backend/plugins/zentao/tasks/execution_collector.go
b/backend/plugins/zentao/tasks/execution_collector.go
index 2dcc54441..ee04a3dcd 100644
--- a/backend/plugins/zentao/tasks/execution_collector.go
+++ b/backend/plugins/zentao/tasks/execution_collector.go
@@ -20,12 +20,11 @@ package tasks
import (
"encoding/json"
"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"
+ "net/http"
+ "net/url"
)
const RAW_EXECUTION_TABLE = "zentao_api_executions"
@@ -34,24 +33,20 @@ var _ plugin.SubTaskEntryPoint = CollectExecutions
func CollectExecutions(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
-
- // this collect only work for project
- if data.Options.ProjectId == 0 {
- return nil
+ cursor, iterator, err := getExecutionIterator(taskCtx)
+ if err != nil {
+ return err
}
-
+ defer cursor.Close()
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_EXECUTION_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_EXECUTION_TABLE,
},
+ Input: iterator,
ApiClient: data.ApiClient,
- UrlTemplate: "/{{ .Params.ZentaoId }}/executions",
+ UrlTemplate: "/executions/{{ .Input.Id }}",
Query: func(reqData *api.RequestData) (url.Values,
errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
@@ -59,14 +54,12 @@ func CollectExecutions(taskCtx plugin.SubTaskContext)
errors.Error {
return query, nil
},
ResponseParser: func(res *http.Response) ([]json.RawMessage,
errors.Error) {
- var data struct {
- Executions []json.RawMessage `json:"executions"`
- }
+ var data json.RawMessage
err := api.UnmarshalResponse(res, &data)
if err != nil {
- return nil, errors.Default.Wrap(err, "error
reading endpoint response by Zentao bug collector")
+ return nil, err
}
- return data.Executions, nil
+ return []json.RawMessage{data}, nil
},
})
if err != nil {
diff --git a/backend/plugins/zentao/tasks/execution_convertor.go
b/backend/plugins/zentao/tasks/execution_convertor.go
index 470609ca5..46804813f 100644
--- a/backend/plugins/zentao/tasks/execution_convertor.go
+++ b/backend/plugins/zentao/tasks/execution_convertor.go
@@ -57,13 +57,9 @@ func ConvertExecutions(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoExecution{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_EXECUTION_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_EXECUTION_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolExecution := inputRow.(*models.ZentaoExecution)
diff --git a/backend/plugins/zentao/tasks/execution_extractor.go
b/backend/plugins/zentao/tasks/execution_extractor.go
index 27b3b4316..1b94772d9 100644
--- a/backend/plugins/zentao/tasks/execution_extractor.go
+++ b/backend/plugins/zentao/tasks/execution_extractor.go
@@ -19,7 +19,6 @@ package tasks
import (
"encoding/json"
-
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
@@ -39,20 +38,11 @@ var ExtractExecutionMeta = plugin.SubTaskMeta{
func ExtractExecutions(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for project
- if data.Options.ProjectId == 0 {
- return nil
- }
-
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_EXECUTION_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_EXECUTION_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoExecutionRes{}
@@ -60,10 +50,15 @@ func ExtractExecutions(taskCtx plugin.SubTaskContext)
errors.Error {
if err != nil {
return nil, errors.Default.WrapRaw(err)
}
-
- // append product to taskdata
+ var results []interface{}
for _, product := range res.Products {
- data.ProductList[product.ID] = product.Name
+ p := &models.ZentaoProductSummary{
+ ConnectionId: data.Options.ConnectionId,
+ ProjectId: data.Options.ProjectId,
+ Id: product.ID,
+ Name: product.Name,
+ }
+ results = append(results, p)
}
execution := &models.ZentaoExecution{
@@ -126,7 +121,6 @@ func ExtractExecutions(taskCtx plugin.SubTaskContext)
errors.Error {
Progress: res.Progress,
CaseReview: res.CaseReview,
}
- results := make([]interface{}, 0)
results = append(results, execution)
return results, nil
},
diff --git a/backend/plugins/zentao/tasks/account_collector.go
b/backend/plugins/zentao/tasks/execution_story_collector.go
similarity index 69%
copy from backend/plugins/zentao/tasks/account_collector.go
copy to backend/plugins/zentao/tasks/execution_story_collector.go
index 9ecd35665..b1fd01c5c 100644
--- a/backend/plugins/zentao/tasks/account_collector.go
+++ b/backend/plugins/zentao/tasks/execution_story_collector.go
@@ -20,49 +20,49 @@ package tasks
import (
"encoding/json"
"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"
+ "net/http"
+ "net/url"
)
-const RAW_ACCOUNT_TABLE = "zentao_api_accounts"
-
-var _ plugin.SubTaskEntryPoint = CollectAccount
+var _ plugin.SubTaskEntryPoint = CollectExecutionStory
-func CollectAccount(taskCtx plugin.SubTaskContext) errors.Error {
+func CollectExecutionStory(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
+ cursor, iterator, err := getExecutionIterator(taskCtx)
+ if err != nil {
+ return err
+ }
+ defer cursor.Close()
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_ACCOUNT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_TABLE,
},
ApiClient: data.ApiClient,
+ Input: iterator,
PageSize: 100,
- UrlTemplate: "/users",
+ UrlTemplate: "/executions/{{ .Input.Id }}/stories",
Query: func(reqData *api.RequestData) (url.Values,
errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
query.Set("limit", fmt.Sprintf("%v",
reqData.Pager.Size))
+ query.Set("status", "allstory")
return query, nil
},
GetTotalPages: GetTotalPagesFromResponse,
ResponseParser: func(res *http.Response) ([]json.RawMessage,
errors.Error) {
var data struct {
- Users []json.RawMessage `json:"users"`
+ Story []json.RawMessage `json:"stories"`
}
err := api.UnmarshalResponse(res, &data)
if err != nil {
- return nil, errors.Default.Wrap(err, "error
reading endpoint response by Zentao bug collector")
+ return nil, err
}
- return data.Users, nil
+ return data.Story, nil
},
})
if err != nil {
@@ -71,11 +71,3 @@ func CollectAccount(taskCtx plugin.SubTaskContext)
errors.Error {
return collector.Execute()
}
-
-var CollectAccountMeta = plugin.SubTaskMeta{
- Name: "collectAccount",
- EntryPoint: CollectAccount,
- EnabledByDefault: true,
- Description: "Collect Account data from Zentao api",
- DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
-}
diff --git a/backend/plugins/zentao/tasks/product_convertor.go
b/backend/plugins/zentao/tasks/execution_story_convertor.go
similarity index 54%
rename from backend/plugins/zentao/tasks/product_convertor.go
rename to backend/plugins/zentao/tasks/execution_story_convertor.go
index 0030f12ed..01536807a 100644
--- a/backend/plugins/zentao/tasks/product_convertor.go
+++ b/backend/plugins/zentao/tasks/execution_story_convertor.go
@@ -18,12 +18,10 @@ limitations under the License.
package tasks
import (
- "fmt"
"reflect"
"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
- "github.com/apache/incubator-devlake/core/models/domainlayer"
"github.com/apache/incubator-devlake/core/models/domainlayer/didgen"
"github.com/apache/incubator-devlake/core/models/domainlayer/ticket"
"github.com/apache/incubator-devlake/core/plugin"
@@ -31,60 +29,44 @@ import (
"github.com/apache/incubator-devlake/plugins/zentao/models"
)
-const RAW_PRODUCT_TABLE = "zentao_api_products"
+var _ plugin.SubTaskEntryPoint = ConvertExecutionStory
-var _ plugin.SubTaskEntryPoint = ConvertProducts
-
-var ConvertProductMeta = plugin.SubTaskMeta{
- Name: "convertProducts",
- EntryPoint: ConvertProducts,
+var ConvertExecutionStoryMeta = plugin.SubTaskMeta{
+ Name: "convertExecutionStory",
+ EntryPoint: ConvertExecutionStory,
EnabledByDefault: true,
- Description: "convert Zentao products",
+ Description: "convert Zentao execution_stories",
DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
}
-func ConvertProducts(taskCtx plugin.SubTaskContext) errors.Error {
+func ConvertExecutionStory(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
- boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProduct{})
+ executionIdGen := didgen.NewDomainIdGenerator(&models.ZentaoExecution{})
+ storyIdGen := didgen.NewDomainIdGenerator(&models.ZentaoStory{})
cursor, err := db.Cursor(
- dal.From(&models.ZentaoProduct{}),
- dal.Where(`id = ? and connection_id = ?`,
data.Options.ProductId, data.Options.ConnectionId),
+ dal.From(&models.ZentaoExecutionStory{}),
+ dal.Where(`project_id = ? and connection_id = ?`,
data.Options.ProjectId, data.Options.ConnectionId),
)
if err != nil {
return err
}
defer cursor.Close()
convertor, err := api.NewDataConverter(api.DataConverterArgs{
- InputRowType: reflect.TypeOf(models.ZentaoProduct{}),
+ InputRowType: reflect.TypeOf(models.ZentaoExecutionStory{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_PRODUCT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_EXECUTION_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
- toolProduct := inputRow.(*models.ZentaoProduct)
-
- data.ProductList[toolProduct.Id] = toolProduct.Name
-
- domainBoard := &ticket.Board{
- DomainEntity: domainlayer.DomainEntity{
- Id:
boardIdGen.Generate(toolProduct.ConnectionId, toolProduct.Id),
- },
- Name: toolProduct.Name,
- Description: toolProduct.Description,
- CreatedDate:
toolProduct.CreatedDate.ToNullableTime(),
- Type: toolProduct.Type + "/" +
toolProduct.ProductType,
- Url:
fmt.Sprintf("/product-index-%d.html", data.Options.ProductId),
+ executionStory :=
inputRow.(*models.ZentaoExecutionStory)
+ sprintIssue := &ticket.SprintIssue{
+ SprintId:
executionIdGen.Generate(data.Options.ConnectionId, executionStory.ExecutionId),
+ IssueId:
storyIdGen.Generate(data.Options.ConnectionId, executionStory.StoryId),
}
- results := make([]interface{}, 0)
- results = append(results, domainBoard)
- return results, nil
+ return []interface{}{sprintIssue}, nil
},
})
diff --git a/backend/plugins/zentao/tasks/execution_collector.go
b/backend/plugins/zentao/tasks/execution_summary_collector.go
similarity index 74%
copy from backend/plugins/zentao/tasks/execution_collector.go
copy to backend/plugins/zentao/tasks/execution_summary_collector.go
index 2dcc54441..3688b3826 100644
--- a/backend/plugins/zentao/tasks/execution_collector.go
+++ b/backend/plugins/zentao/tasks/execution_summary_collector.go
@@ -28,30 +28,20 @@ import (
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
)
-const RAW_EXECUTION_TABLE = "zentao_api_executions"
+const RAW_EXECUTION_SUMMARY_TABLE = "zentao_api_execution_summary"
-var _ plugin.SubTaskEntryPoint = CollectExecutions
+var _ plugin.SubTaskEntryPoint = CollectExecutionSummary
-func CollectExecutions(taskCtx plugin.SubTaskContext) errors.Error {
+func CollectExecutionSummary(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
-
- // this collect only work for project
- if data.Options.ProjectId == 0 {
- return nil
- }
-
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_EXECUTION_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_EXECUTION_SUMMARY_TABLE,
},
ApiClient: data.ApiClient,
- UrlTemplate: "/{{ .Params.ZentaoId }}/executions",
+ UrlTemplate: fmt.Sprintf("/projects/%d/executions",
data.Options.ProjectId),
Query: func(reqData *api.RequestData) (url.Values,
errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
@@ -76,10 +66,10 @@ func CollectExecutions(taskCtx plugin.SubTaskContext)
errors.Error {
return collector.Execute()
}
-var CollectExecutionMeta = plugin.SubTaskMeta{
- Name: "collectExecutions",
- EntryPoint: CollectExecutions,
+var CollectExecutionSummaryMeta = plugin.SubTaskMeta{
+ Name: "collectExecutionSummary",
+ EntryPoint: CollectExecutionSummary,
EnabledByDefault: true,
- Description: "Collect Execution data from Zentao api",
+ Description: "Collect Execution summary data from Zentao api",
DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
}
diff --git a/backend/plugins/zentao/tasks/account_extractor.go
b/backend/plugins/zentao/tasks/execution_summary_extractor.go
similarity index 68%
copy from backend/plugins/zentao/tasks/account_extractor.go
copy to backend/plugins/zentao/tasks/execution_summary_extractor.go
index 9ad1b720d..3aecf9cfa 100644
--- a/backend/plugins/zentao/tasks/account_extractor.go
+++ b/backend/plugins/zentao/tasks/execution_summary_extractor.go
@@ -26,38 +26,33 @@ import (
"github.com/apache/incubator-devlake/plugins/zentao/models"
)
-var _ plugin.SubTaskEntryPoint = ExtractAccount
+var _ plugin.SubTaskEntryPoint = ExtractExecutionSummary
-var ExtractAccountMeta = plugin.SubTaskMeta{
- Name: "extractAccount",
- EntryPoint: ExtractAccount,
+var ExtractExecutionSummaryMeta = plugin.SubTaskMeta{
+ Name: "extractExecutionSummary",
+ EntryPoint: ExtractExecutionSummary,
EnabledByDefault: true,
- Description: "extract Zentao account",
+ Description: "extract Zentao execution summary",
DomainTypes: []string{plugin.DOMAIN_TYPE_TICKET},
}
-func ExtractAccount(taskCtx plugin.SubTaskContext) errors.Error {
+func ExtractExecutionSummary(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
+
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_ACCOUNT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_EXECUTION_SUMMARY_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
- account := &models.ZentaoAccount{}
- err := json.Unmarshal(row.Data, account)
+ executionSummary := &models.ZentaoExecutionSummary{}
+ err := json.Unmarshal(row.Data, executionSummary)
if err != nil {
return nil, errors.Default.WrapRaw(err)
}
- account.ConnectionId = data.Options.ConnectionId
- results := make([]interface{}, 0)
- results = append(results, account)
- return results, nil
+ executionSummary.ConnectionId =
data.Options.ConnectionId
+ return []interface{}{executionSummary}, nil
},
})
diff --git a/backend/plugins/zentao/tasks/iterator.go
b/backend/plugins/zentao/tasks/iterator.go
new file mode 100644
index 000000000..0c3400a72
--- /dev/null
+++ b/backend/plugins/zentao/tasks/iterator.go
@@ -0,0 +1,105 @@
+/*
+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 tasks
+
+import (
+ "github.com/apache/incubator-devlake/core/errors"
+ "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type iteratorConcator struct {
+ index int
+ iterators []api.Iterator
+}
+
+func newIteratorConcator(iterators ...api.Iterator) *iteratorConcator {
+ return &iteratorConcator{iterators: iterators}
+}
+
+func (w *iteratorConcator) HasNext() bool {
+ for w.index < len(w.iterators) {
+ if w.iterators[w.index].HasNext() {
+ return true
+ }
+ w.index++
+ }
+ return false
+}
+
+func (w *iteratorConcator) Fetch() (interface{}, errors.Error) {
+ if w.index >= len(w.iterators) {
+ return nil, errors.Default.New("index out of range")
+ }
+ return w.iterators[w.index].Fetch()
+}
+
+func (w *iteratorConcator) Close() errors.Error {
+ for _, iterator := range w.iterators {
+ iterator.Close()
+ }
+ return nil
+}
+
+type iteratorWrapper struct {
+ original api.Iterator
+ wrapperFunc func(interface{}) interface{}
+}
+
+func newIteratorWrapper(original api.Iterator, wrapperFunc func(interface{})
interface{}) *iteratorWrapper {
+ return &iteratorWrapper{original: original, wrapperFunc: wrapperFunc}
+}
+
+func (w *iteratorWrapper) HasNext() bool {
+ return w.original.HasNext()
+}
+
+func (w *iteratorWrapper) Fetch() (interface{}, errors.Error) {
+ data, err := w.original.Fetch()
+ if err != nil {
+ return nil, err
+ }
+ return w.wrapperFunc(data), nil
+}
+
+func (w *iteratorWrapper) Close() errors.Error {
+ return w.original.Close()
+}
+
+type iteratorFromSlice struct {
+ index int
+ data []interface{}
+}
+
+func newIteratorFromSlice(data []interface{}) *iteratorFromSlice {
+ return &iteratorFromSlice{data: data}
+}
+
+func (i *iteratorFromSlice) HasNext() bool {
+ return i.index < len(i.data)
+}
+
+func (i *iteratorFromSlice) Fetch() (interface{}, errors.Error) {
+ data := i.data[i.index]
+ i.index++
+ return data, nil
+}
+
+func (i *iteratorFromSlice) Close() errors.Error {
+ i.index = len(i.data) - 1
+ return nil
+}
diff --git a/backend/plugins/zentao/tasks/project_convertor.go
b/backend/plugins/zentao/tasks/project_convertor.go
index 60d458c63..7beb16d5e 100644
--- a/backend/plugins/zentao/tasks/project_convertor.go
+++ b/backend/plugins/zentao/tasks/project_convertor.go
@@ -59,13 +59,9 @@ func ConvertProjects(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoProject{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_PROJECT_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_PROJECT_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolProject := inputRow.(*models.ZentaoProject)
diff --git a/backend/plugins/zentao/tasks/shared.go
b/backend/plugins/zentao/tasks/shared.go
index 6f029ed09..93d749f2b 100644
--- a/backend/plugins/zentao/tasks/shared.go
+++ b/backend/plugins/zentao/tasks/shared.go
@@ -19,16 +19,22 @@ package tasks
import (
"fmt"
+ "github.com/apache/incubator-devlake/core/dal"
+ "github.com/apache/incubator-devlake/core/plugin"
"net/http"
"net/url"
+ "reflect"
"strings"
"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/zentao/models"
)
+type input struct {
+ Id int64
+}
+
func GetTotalPagesFromResponse(res *http.Response, args *api.ApiCollectorArgs)
(int, errors.Error) {
body := &ZentaoPagination{}
err := api.UnmarshalResponse(res, body)
@@ -83,9 +89,6 @@ func getOriginalProject(data *ZentaoTaskData) string {
if data.Options.ProjectId != 0 {
return data.ProjectName
}
- if data.Options.ProductId != 0 {
- return data.ProductName
- }
return ""
}
@@ -182,30 +185,49 @@ func ignoreHTTPStatus404(res *http.Response) errors.Error
{
return nil
}
-func RangeProductOneByOne(taskCtx plugin.SubTaskContext, callback func(taskCtx
plugin.SubTaskContext) errors.Error) errors.Error {
+func getProductIterator(taskCtx plugin.SubTaskContext) (dal.Rows,
*api.DalCursorIterator, errors.Error) {
data := taskCtx.GetData().(*ZentaoTaskData)
- for id, name := range data.ProductList {
- data.Options.ProductId = id
- data.ProductName = name
-
- err := callback(taskCtx)
- if err != nil {
- return err
- }
+ db := taskCtx.GetDal()
+ clauses := []dal.Clause{
+ dal.Select("id"),
+ dal.From(&models.ZentaoProductSummary{}),
+ dal.Where(
+ "project_id = ? AND connection_id = ?",
+ data.Options.ProjectId, data.Options.ConnectionId,
+ ),
}
- return nil
+ cursor, err := db.Cursor(clauses...)
+ if err != nil {
+ return nil, nil, err
+ }
+ iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(input{}))
+ if err != nil {
+ cursor.Close()
+ return nil, nil, err
+ }
+ return cursor, iterator, nil
}
-func ScopeParams(cid uint64, projectId int64, productId int64) ZentaoApiParams
{
- param := ZentaoApiParams{
- ConnectionId: cid,
+func getExecutionIterator(taskCtx plugin.SubTaskContext) (dal.Rows,
*api.DalCursorIterator, errors.Error) {
+ data := taskCtx.GetData().(*ZentaoTaskData)
+ db := taskCtx.GetDal()
+ clauses := []dal.Clause{
+ dal.Select("id"),
+ dal.From(&models.ZentaoExecutionSummary{}),
+ dal.Where(
+ "project = ? AND connection_id = ?",
+ data.Options.ProjectId, data.Options.ConnectionId,
+ ),
+ }
+ cursor, err := db.Cursor(clauses...)
+ if err != nil {
+ return nil, nil, err
}
- if projectId != 0 {
- param.ZentaoId = fmt.Sprintf("projects/%d", projectId)
- } else {
- param.ZentaoId = fmt.Sprintf("products/%d", productId)
+ iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(input{}))
+ if err != nil {
+ cursor.Close()
+ return nil, nil, err
}
-
- return param
+ return cursor, iterator, nil
}
diff --git a/backend/plugins/zentao/tasks/story_collector.go
b/backend/plugins/zentao/tasks/story_collector.go
index 02dd21af2..342840f98 100644
--- a/backend/plugins/zentao/tasks/story_collector.go
+++ b/backend/plugins/zentao/tasks/story_collector.go
@@ -32,31 +32,48 @@ const RAW_STORY_TABLE = "zentao_api_stories"
var _ plugin.SubTaskEntryPoint = CollectStory
-func CollectStory(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, CollectStoryForOneProduct)
+type storyInput struct {
+ Path string
+ ProjectId int64
+ ProductId int64
+ ExecutionId int64
}
-func CollectStoryForOneProduct(taskCtx plugin.SubTaskContext) errors.Error {
+func CollectStory(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
+ // project iterator
+ iter0 := newIteratorFromSlice([]interface{}{&storyInput{ProjectId:
data.Options.ProjectId, Path: fmt.Sprintf("/projects/%d",
data.Options.ProjectId)}})
+
+ // product iterator
+ productCursor, productIterator, err := getProductIterator(taskCtx)
+ if err != nil {
+ return err
+ }
+ defer productCursor.Close()
+ iter1 := newIteratorWrapper(productIterator, func(arg interface{})
interface{} {
+ return &storyInput{ProductId: arg.(*input).Id, Path:
fmt.Sprintf("/products/%d", arg.(*input).Id)}
+ })
- // this collect only work for product
- if data.Options.ProductId == 0 {
- return nil
+ // execution iterator
+ executionCursor, executionIterator, err := getExecutionIterator(taskCtx)
+ if err != nil {
+ return err
}
+ defer executionCursor.Close()
+ iter2 := newIteratorWrapper(executionIterator, func(arg interface{})
interface{} {
+ return &storyInput{ExecutionId: arg.(*input).Id, Path:
fmt.Sprintf("/executions/%d", arg.(*input).Id)}
+ })
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_TABLE,
},
+ Input: newIteratorConcator(iter0, iter1, iter2),
ApiClient: data.ApiClient,
PageSize: 100,
- UrlTemplate: "/{{ .Params.ZentaoId }}/stories",
+ UrlTemplate: "{{ .Input.Path }}/stories",
Query: func(reqData *api.RequestData) (url.Values,
errors.Error) {
query := url.Values{}
query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
diff --git a/backend/plugins/zentao/tasks/story_commits_collector.go
b/backend/plugins/zentao/tasks/story_commits_collector.go
index ec780c76f..07fea3cfe 100644
--- a/backend/plugins/zentao/tasks/story_commits_collector.go
+++ b/backend/plugins/zentao/tasks/story_commits_collector.go
@@ -42,22 +42,14 @@ var CollectStoryCommitsMeta = plugin.SubTaskMeta{
}
func CollectStoryCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, CollectStoryCommitsForOneProduct)
-}
-
-func CollectStoryCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
db := taskCtx.GetDal()
data := taskCtx.GetData().(*ZentaoTaskData)
// state manager
collectorWithState, err :=
api.NewStatefulApiCollector(api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_COMMITS_TABLE,
}, data.TimeAfter)
if err != nil {
return err
@@ -65,12 +57,13 @@ func CollectStoryCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Erro
// load stories id from db
clauses := []dal.Clause{
- dal.Select("id, last_edited_date"),
- dal.From(&models.ZentaoStory{}),
- dal.Where(
- "product = ? AND connection_id = ?",
- data.Options.ProductId, data.Options.ConnectionId,
- ),
+ dal.Select("_tool_zentao_project_stories.story_id AS id,
last_edited_date"),
+ dal.From(&models.ZentaoProjectStory{}),
+ dal.Join(`LEFT JOIN _tool_zentao_stories ON
+
_tool_zentao_project_stories.story_id = _tool_zentao_stories.id
+ AND
_tool_zentao_project_stories.connection_id =
_tool_zentao_stories.connection_id`),
+ dal.Where(`_tool_zentao_project_stories.project_id = ? and
+ _tool_zentao_project_stories.connection_id = ?`,
data.Options.ProjectId, data.Options.ConnectionId),
}
// incremental collection
incremental := collectorWithState.IsIncremental()
@@ -85,7 +78,7 @@ func CollectStoryCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Erro
return err
}
- iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(SimpleZentaoStory{}))
+ iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(inputWithLastEditedDate{}))
if err != nil {
return err
}
@@ -93,13 +86,9 @@ func CollectStoryCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Erro
// collect story commits
err = collectorWithState.InitCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_COMMITS_TABLE,
},
ApiClient: data.ApiClient,
Input: iterator,
@@ -125,7 +114,7 @@ func CollectStoryCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Erro
return collectorWithState.Execute()
}
-type SimpleZentaoStory struct {
+type inputWithLastEditedDate struct {
ID int64 `json:"id"`
LastEditedDate *api.Iso8601Time `json:"lastEditedDate"`
}
diff --git a/backend/plugins/zentao/tasks/story_commits_extractor.go
b/backend/plugins/zentao/tasks/story_commits_extractor.go
index c883e3beb..97243db25 100644
--- a/backend/plugins/zentao/tasks/story_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/story_commits_extractor.go
@@ -39,27 +39,14 @@ var ExtractStoryCommitsMeta = plugin.SubTaskMeta{
}
func ExtractStoryCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ExtractStoryCommitsForOneProduct)
-}
-
-func ExtractStoryCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for product
- if data.Options.ProductId == 0 {
- return nil
- }
-
re := regexp.MustCompile(`href='(.*?)'`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_COMMITS_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoStoryCommitsRes{}
@@ -78,7 +65,6 @@ func ExtractStoryCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.Erro
ID: res.ID,
ObjectType: res.ObjectType,
ObjectID: res.ObjectID,
- Product: data.Options.ProductId,
Project: data.Options.ProjectId,
Execution: res.Execution,
Actor: res.Actor,
diff --git a/backend/plugins/zentao/tasks/story_convertor.go
b/backend/plugins/zentao/tasks/story_convertor.go
index bd7eca35e..66b73dd2b 100644
--- a/backend/plugins/zentao/tasks/story_convertor.go
+++ b/backend/plugins/zentao/tasks/story_convertor.go
@@ -42,23 +42,19 @@ var ConvertStoryMeta = plugin.SubTaskMeta{
}
func ConvertStory(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ConvertStoryForOneProduct)
-}
-
-func ConvertStoryForOneProduct(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
storyIdGen := didgen.NewDomainIdGenerator(&models.ZentaoStory{})
- boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProduct{})
+ boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProject{})
accountIdGen := didgen.NewDomainIdGenerator(&models.ZentaoAccount{})
- if data.Options.ProjectId != 0 {
- boardIdGen =
didgen.NewDomainIdGenerator(&models.ZentaoProject{})
- }
cursor, err := db.Cursor(
dal.From(&models.ZentaoStory{}),
- dal.Where(`_tool_zentao_stories.product = ? and
- _tool_zentao_stories.connection_id = ?`,
data.Options.ProductId, data.Options.ConnectionId),
+ dal.Join(`LEFT JOIN _tool_zentao_project_stories ON
+
_tool_zentao_project_stories.story_id = _tool_zentao_stories.id
+ AND
_tool_zentao_project_stories.connection_id =
_tool_zentao_stories.connection_id`),
+ dal.Where(`_tool_zentao_project_stories.project_id = ? and
+ _tool_zentao_project_stories.connection_id = ?`,
data.Options.ProjectId, data.Options.ConnectionId),
)
if err != nil {
return err
@@ -68,13 +64,9 @@ func ConvertStoryForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoStory{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoStory)
@@ -124,13 +116,8 @@ func ConvertStoryForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error {
domainEntity.LeadTimeMinutes =
int64(toolEntity.ClosedDate.ToNullableTime().Sub(toolEntity.OpenedDate.ToTime()).Minutes())
}
- boardId :=
boardIdGen.Generate(data.Options.ConnectionId, data.Options.ProductId)
- if data.Options.ProjectId != 0 {
- boardId =
boardIdGen.Generate(data.Options.ConnectionId, data.Options.ProjectId)
- }
-
domainBoardIssue := &ticket.BoardIssue{
- BoardId: boardId,
+ BoardId:
boardIdGen.Generate(data.Options.ConnectionId, data.Options.ProjectId),
IssueId: domainEntity.Id,
}
results = append(results, domainEntity,
domainBoardIssue)
diff --git a/backend/plugins/zentao/tasks/story_extractor.go
b/backend/plugins/zentao/tasks/story_extractor.go
index 6495e7bf6..88c1ba324 100644
--- a/backend/plugins/zentao/tasks/story_extractor.go
+++ b/backend/plugins/zentao/tasks/story_extractor.go
@@ -38,44 +38,37 @@ var ExtractStoryMeta = plugin.SubTaskMeta{
}
func ExtractStory(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx, ExtractStoryForOneProduct)
-}
-
-func ExtractStoryForOneProduct(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this collect only work for product
- if data.Options.ProductId == 0 {
- return nil
- }
-
statusMappings := getStoryStatusMapping(data)
stdTypeMappings := getStdTypeMappings(data)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
+ var inputParams storyInput
+ err := json.Unmarshal(row.Input, &inputParams)
+ if err != nil {
+ return nil, errors.Default.WrapRaw(err)
+ }
res := &models.ZentaoStoryRes{}
- err := json.Unmarshal(row.Data, res)
+ err = json.Unmarshal(row.Data, res)
if err != nil {
return nil, errors.Default.WrapRaw(err)
}
- // project scope need filter
- if data.Options.ProjectId != 0 {
- if _, ok := data.StoryList[res.ID]; !ok {
- return nil, nil
- }
+ data.Stories[res.ID] = struct{}{}
+ var results []interface{}
+ projectStory := &models.ZentaoProjectStory{
+ ConnectionId: data.Options.ConnectionId,
+ ProjectId: data.Options.ProjectId,
+ StoryId: res.ID,
}
-
+ results = append(results, projectStory)
story := &models.ZentaoStory{
ConnectionId: data.Options.ConnectionId,
ID: res.ID,
@@ -150,8 +143,16 @@ func ExtractStoryForOneProduct(taskCtx
plugin.SubTaskContext) errors.Error {
}, story.Stage)
}
- results := make([]interface{}, 0)
results = append(results, story)
+ if inputParams.ExecutionId != 0 {
+ executionStory := &models.ZentaoExecutionStory{
+ ConnectionId: data.Options.ConnectionId,
+ ProjectId: data.Options.ProjectId,
+ ExecutionId: inputParams.ExecutionId,
+ StoryId: story.ID,
+ }
+ results = append(results, executionStory)
+ }
return results, nil
},
})
diff --git a/backend/plugins/zentao/tasks/story_repo_commits_collector.go
b/backend/plugins/zentao/tasks/story_repo_commits_collector.go
index 371e39d50..49af17b0f 100644
--- a/backend/plugins/zentao/tasks/story_repo_commits_collector.go
+++ b/backend/plugins/zentao/tasks/story_repo_commits_collector.go
@@ -42,10 +42,6 @@ var CollectStoryRepoCommitsMeta = plugin.SubTaskMeta{
}
func CollectStoryRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx,
CollectStoryRepoCommitsForOneProduct)
-}
-
-func CollectStoryRepoCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
db := taskCtx.GetDal()
data := taskCtx.GetData().(*ZentaoTaskData)
@@ -54,8 +50,8 @@ func CollectStoryRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.
dal.Select("object_id, repo_revision"),
dal.From(&models.ZentaoStoryCommit{}),
dal.Where(
- "product = ? AND connection_id = ?",
- data.Options.ProductId, data.Options.ConnectionId,
+ "project = ? AND connection_id = ?",
+ data.Options.ProjectId, data.Options.ConnectionId,
),
}
@@ -72,13 +68,9 @@ func CollectStoryRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.
// collect story repo commits
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_REPO_COMMITS_TABLE,
},
ApiClient: data.ApiClient,
Input: iterator,
diff --git a/backend/plugins/zentao/tasks/story_repo_commits_convertor.go
b/backend/plugins/zentao/tasks/story_repo_commits_convertor.go
index 8c5126396..2fb5654a0 100644
--- a/backend/plugins/zentao/tasks/story_repo_commits_convertor.go
+++ b/backend/plugins/zentao/tasks/story_repo_commits_convertor.go
@@ -40,16 +40,12 @@ var ConvertStoryRepoCommitsMeta = plugin.SubTaskMeta{
}
func ConvertStoryRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx,
ConvertStoryRepoCommitsForOneProduct)
-}
-
-func ConvertStoryRepoCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
cursor, err := db.Cursor(
dal.From(&models.ZentaoStoryRepoCommit{}),
- dal.Where(`product = ? and connection_id = ?`,
data.Options.ProductId, data.Options.ConnectionId),
+ dal.Where(`project = ? and connection_id = ?`,
data.Options.ProjectId, data.Options.ConnectionId),
)
if err != nil {
return err
@@ -61,13 +57,9 @@ func ConvertStoryRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.
InputRowType: reflect.TypeOf(models.ZentaoStoryRepoCommit{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_REPO_COMMITS_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoStoryRepoCommit)
diff --git a/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
b/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
index 6bcea26ac..3176d8ea3 100644
--- a/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/story_repo_commits_extractor.go
@@ -38,27 +38,14 @@ var ExtractStoryRepoCommitsMeta = plugin.SubTaskMeta{
}
func ExtractStoryRepoCommits(taskCtx plugin.SubTaskContext) errors.Error {
- return RangeProductOneByOne(taskCtx,
ExtractStoryRepoCommitsForOneProduct)
-}
-
-func ExtractStoryRepoCommitsForOneProduct(taskCtx plugin.SubTaskContext)
errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for product
- if data.Options.ProductId == 0 {
- return nil
- }
-
re := regexp.MustCompile(`(\d+)(?:,\s*(\d+))*`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_STORY_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_STORY_REPO_COMMITS_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoStoryRepoCommitsRes{}
@@ -73,7 +60,6 @@ func ExtractStoryRepoCommitsForOneProduct(taskCtx
plugin.SubTaskContext) errors.
if match[i] != "" {
storyRepoCommits :=
&models.ZentaoStoryRepoCommit{
ConnectionId:
data.Options.ConnectionId,
- Product:
data.Options.ProductId,
Project:
data.Options.ProjectId,
RepoUrl: res.Repo.CodePath,
CommitSha: res.Revision,
diff --git a/backend/plugins/zentao/tasks/task_collector.go
b/backend/plugins/zentao/tasks/task_collector.go
index 854cc970b..0ac2332a7 100644
--- a/backend/plugins/zentao/tasks/task_collector.go
+++ b/backend/plugins/zentao/tasks/task_collector.go
@@ -33,20 +33,11 @@ import (
const RAW_TASK_TABLE = "zentao_api_tasks"
-type ExecuteInput struct {
- Id int64
-}
-
var _ plugin.SubTaskEntryPoint = CollectTask
func CollectTask(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this collect only work for project
- if data.Options.ProjectId == 0 {
- return nil
- }
-
cursor, err := taskCtx.GetDal().Cursor(
dal.Select(`id`),
dal.From(&models.ZentaoExecution{}),
@@ -57,20 +48,16 @@ func CollectTask(taskCtx plugin.SubTaskContext)
errors.Error {
}
defer cursor.Close()
- iterator, err := api.NewDalCursorIterator(taskCtx.GetDal(), cursor,
reflect.TypeOf(ExecuteInput{}))
+ iterator, err := api.NewDalCursorIterator(taskCtx.GetDal(), cursor,
reflect.TypeOf(input{}))
if err != nil {
return err
}
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_TABLE,
},
Input: iterator,
ApiClient: data.ApiClient,
diff --git a/backend/plugins/zentao/tasks/task_commits_collector.go
b/backend/plugins/zentao/tasks/task_commits_collector.go
index f4ee06783..bfb91099d 100644
--- a/backend/plugins/zentao/tasks/task_commits_collector.go
+++ b/backend/plugins/zentao/tasks/task_commits_collector.go
@@ -45,20 +45,11 @@ func CollectTaskCommits(taskCtx plugin.SubTaskContext)
errors.Error {
db := taskCtx.GetDal()
data := taskCtx.GetData().(*ZentaoTaskData)
- // this collect only work for project
- if data.Options.ProjectId == 0 {
- return nil
- }
-
// state manager
collectorWithState, err :=
api.NewStatefulApiCollector(api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_COMMITS_TABLE,
}, data.TimeAfter)
if err != nil {
return err
@@ -86,7 +77,7 @@ func CollectTaskCommits(taskCtx plugin.SubTaskContext)
errors.Error {
return err
}
- iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(SimpleZentaoTask{}))
+ iterator, err := api.NewDalCursorIterator(db, cursor,
reflect.TypeOf(inputWithLastEditedDate{}))
if err != nil {
return err
}
@@ -94,13 +85,9 @@ func CollectTaskCommits(taskCtx plugin.SubTaskContext)
errors.Error {
// collect task commits
err = collectorWithState.InitCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_COMMITS_TABLE,
},
ApiClient: data.ApiClient,
Input: iterator,
@@ -125,8 +112,3 @@ func CollectTaskCommits(taskCtx plugin.SubTaskContext)
errors.Error {
return collectorWithState.Execute()
}
-
-type SimpleZentaoTask struct {
- ID int64 `json:"id"`
- LastEditedDate *api.Iso8601Time `json:"lastEditedDate"`
-}
diff --git a/backend/plugins/zentao/tasks/task_commits_extractor.go
b/backend/plugins/zentao/tasks/task_commits_extractor.go
index 09113504c..533df08e7 100644
--- a/backend/plugins/zentao/tasks/task_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/task_commits_extractor.go
@@ -41,21 +41,12 @@ var ExtractTaskCommitsMeta = plugin.SubTaskMeta{
func ExtractTaskCommits(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this Extract only work for project
- if data.Options.ProjectId == 0 {
- return nil
- }
-
re := regexp.MustCompile(`href='(.*?)'`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_COMMITS_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoTaskCommitsRes{}
@@ -74,7 +65,6 @@ func ExtractTaskCommits(taskCtx plugin.SubTaskContext)
errors.Error {
ID: res.ID,
ObjectType: res.ObjectType,
ObjectID: res.ObjectID,
- Product: data.Options.ProductId,
Project: data.Options.ProjectId,
Execution: res.Execution,
Actor: res.Actor,
diff --git a/backend/plugins/zentao/tasks/task_convertor.go
b/backend/plugins/zentao/tasks/task_convertor.go
index 7d39b7d2b..916a9c609 100644
--- a/backend/plugins/zentao/tasks/task_convertor.go
+++ b/backend/plugins/zentao/tasks/task_convertor.go
@@ -45,7 +45,7 @@ func ConvertTask(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
db := taskCtx.GetDal()
storyIdGen := didgen.NewDomainIdGenerator(&models.ZentaoStory{})
- bugIdGen := didgen.NewDomainIdGenerator(&models.ZentaoBug{})
+ //bugIdGen := didgen.NewDomainIdGenerator(&models.ZentaoBug{})
boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProject{})
executionIdGen := didgen.NewDomainIdGenerator(&models.ZentaoExecution{})
taskIdGen := didgen.NewDomainIdGenerator(&models.ZentaoTask{})
@@ -62,13 +62,9 @@ func ConvertTask(taskCtx plugin.SubTaskContext) errors.Error
{
InputRowType: reflect.TypeOf(models.ZentaoTask{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoTask)
@@ -127,22 +123,6 @@ func ConvertTask(taskCtx plugin.SubTaskContext)
errors.Error {
results = append(results, domainEntity,
domainBoardIssue, sprintIssueTask)
- if toolEntity.StoryID != 0 {
- sprintIssueStory := &ticket.SprintIssue{
- SprintId: sprintId,
- IssueId:
storyIdGen.Generate(data.Options.ConnectionId, toolEntity.StoryID),
- }
- results = append(results, sprintIssueStory)
- }
-
- if toolEntity.FromBug != 0 {
- sprintIssueBug := &ticket.SprintIssue{
- SprintId: sprintId,
- IssueId:
bugIdGen.Generate(data.Options.ConnectionId, int64(toolEntity.FromBug)),
- }
- results = append(results, sprintIssueBug)
- }
-
return results, nil
},
})
diff --git a/backend/plugins/zentao/tasks/task_data.go
b/backend/plugins/zentao/tasks/task_data.go
index 7bf510976..c453ea1d7 100644
--- a/backend/plugins/zentao/tasks/task_data.go
+++ b/backend/plugins/zentao/tasks/task_data.go
@@ -36,7 +36,6 @@ type ZentaoOptions struct {
// Such As How many rows do your want
// You can use it in subtasks, and you need to pass it to main.go and
pipelines.
ConnectionId uint64 `json:"connectionId"`
- ProductId int64 `json:"productId" mapstructure:"productId"`
ProjectId int64 `json:"projectId" mapstructure:"projectId"`
// TODO not support now
TimeAfter string `json:"timeAfter"
mapstructure:"timeAfter,omitempty"`
@@ -44,6 +43,13 @@ type ZentaoOptions struct {
ScopeConfigs *ZentaoScopeConfigs `json:"scopeConfigs"
mapstructure:"scopeConfigs,omitempty"`
}
+func (o *ZentaoOptions) GetParams() any {
+ return models.ZentaoApiParams{
+ ConnectionId: o.ConnectionId,
+ ProjectId: o.ProjectId,
+ }
+}
+
type TypeMappings map[string]string
type StatusMappings map[string]string
@@ -104,6 +110,9 @@ type ZentaoTaskData struct {
ProductList map[int64]string // set if it is setting project id, it is
map[id]name
StoryList map[int64]int64 // set if it is run the task_extractor
FromBugList map[int]bool // set if it is run the task_extracor
+ Stories map[int64]struct{}
+ Tasks map[int64]struct{}
+ Bugs map[int64]struct{}
ApiClient *helper.ApiAsyncClient
}
@@ -117,8 +126,8 @@ func DecodeAndValidateTaskOptions(options
map[string]interface{}) (*ZentaoOption
if op.ConnectionId == 0 {
return nil, fmt.Errorf("connectionId is invalid")
}
- if op.ProductId == 0 && op.ProjectId == 0 {
- return nil, fmt.Errorf("please set productId")
+ if op.ProjectId == 0 {
+ return nil, fmt.Errorf("please set projectId")
}
return &op, nil
}
diff --git a/backend/plugins/zentao/tasks/task_extractor.go
b/backend/plugins/zentao/tasks/task_extractor.go
index ba52d0dc1..cb1d1248e 100644
--- a/backend/plugins/zentao/tasks/task_extractor.go
+++ b/backend/plugins/zentao/tasks/task_extractor.go
@@ -40,23 +40,14 @@ var ExtractTaskMeta = plugin.SubTaskMeta{
func ExtractTask(taskCtx plugin.SubTaskContext) errors.Error {
data := taskCtx.GetData().(*ZentaoTaskData)
- // this collect only work for project
- if data.Options.ProjectId == 0 {
- return nil
- }
-
statusMappings := getTaskStatusMapping(data)
stdTypeMappings := getStdTypeMappings(data)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoTaskRes{}
@@ -65,10 +56,7 @@ func ExtractTask(taskCtx plugin.SubTaskContext) errors.Error
{
return nil, errors.Default.WrapRaw(err)
}
- // set storyList and FromBugList
- data.StoryList[res.StoryID] = res.Story
- data.FromBugList[res.FromBug] = true
-
+ data.Tasks[res.Id] = struct{}{}
task := &models.ZentaoTask{
ConnectionId: data.Options.ConnectionId,
ID: res.Id,
diff --git a/backend/plugins/zentao/tasks/task_repo_commits_collector.go
b/backend/plugins/zentao/tasks/task_repo_commits_collector.go
index bcfaabf4c..03b09055d 100644
--- a/backend/plugins/zentao/tasks/task_repo_commits_collector.go
+++ b/backend/plugins/zentao/tasks/task_repo_commits_collector.go
@@ -68,13 +68,9 @@ func CollectTaskRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
// collect task repo commits
collector, err := api.NewApiCollector(api.ApiCollectorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_REPO_COMMITS_TABLE,
},
ApiClient: data.ApiClient,
Input: iterator,
diff --git a/backend/plugins/zentao/tasks/task_repo_commits_convertor.go
b/backend/plugins/zentao/tasks/task_repo_commits_convertor.go
index 24f446e09..c52326fa3 100644
--- a/backend/plugins/zentao/tasks/task_repo_commits_convertor.go
+++ b/backend/plugins/zentao/tasks/task_repo_commits_convertor.go
@@ -57,13 +57,9 @@ func ConvertTaskRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
InputRowType: reflect.TypeOf(models.ZentaoTaskRepoCommit{}),
Input: cursor,
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_REPO_COMMITS_TABLE,
},
Convert: func(inputRow interface{}) ([]interface{},
errors.Error) {
toolEntity := inputRow.(*models.ZentaoTaskRepoCommit)
diff --git a/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
b/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
index 2ff135b54..da670f2b0 100644
--- a/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
+++ b/backend/plugins/zentao/tasks/task_repo_commits_extractor.go
@@ -48,13 +48,9 @@ func ExtractTaskRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
re := regexp.MustCompile(`(\d+)(?:,\s*(\d+))*`)
extractor, err := api.NewApiExtractor(api.ApiExtractorArgs{
RawDataSubTaskArgs: api.RawDataSubTaskArgs{
- Ctx: taskCtx,
- Params: ScopeParams(
- data.Options.ConnectionId,
- data.Options.ProjectId,
- data.Options.ProductId,
- ),
- Table: RAW_TASK_REPO_COMMITS_TABLE,
+ Ctx: taskCtx,
+ Options: data.Options,
+ Table: RAW_TASK_REPO_COMMITS_TABLE,
},
Extract: func(row *api.RawData) ([]interface{}, errors.Error) {
res := &models.ZentaoTaskRepoCommitsRes{}
@@ -69,7 +65,6 @@ func ExtractTaskRepoCommits(taskCtx plugin.SubTaskContext)
errors.Error {
if match[i] != "" {
taskRepoCommits :=
&models.ZentaoTaskRepoCommit{
ConnectionId:
data.Options.ConnectionId,
- Product:
data.Options.ProductId,
Project:
data.Options.ProjectId,
RepoUrl: res.Repo.CodePath,
CommitSha: res.Revision,