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

zhangliang2022 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 9ba4f85ac feat: add jira tool layer issue relationship (#5762)
9ba4f85ac is described below

commit 9ba4f85acacd437210e820d45638c7cdb5fcc8f8
Author: abeizn <[email protected]>
AuthorDate: Mon Jul 31 10:59:12 2023 +0800

    feat: add jira tool layer issue relationship (#5762)
    
    * feat: add jira tool layer issue relationship
    
    * feat: add domain issue relationships and e2e test
---
 .../models/domainlayer/domaininfo/domaininfo.go    |   1 +
 .../domainlayer/ticket/issue_relationship.go}      |  38 +++-----
 .../20230728_add_issue_relationship_table.go}      |  43 ++++-----
 .../archived/issue_relationship.go}                |  36 ++-----
 backend/core/models/migrationscripts/register.go   |   1 +
 .../plugins/jira/e2e/issue_relationship_test.go    |  63 +++++++++++++
 .../_raw_jira_api_issue_relationships.csv          |  23 +++++
 .../snapshot_tables/_tool_jira_board_issues.csv    |  24 +++++
 .../_tool_jira_issue_relationships.csv             |  13 +++
 .../e2e/snapshot_tables/issue_relationships.csv    |  13 +++
 backend/plugins/jira/impl/impl.go                  |   2 +
 backend/plugins/jira/models/issue_relationship.go  |  41 ++++++++
 ...go => 20230726_add_issue_relationship_table.go} |  42 ++++-----
 .../archived/issue_relationship.go                 |  41 ++++++++
 .../jira/models/migrationscripts/register.go       |   1 +
 backend/plugins/jira/tasks/apiv2models/issue.go    |  56 ++++++++++-
 backend/plugins/jira/tasks/issue_extractor.go      |  17 ++++
 .../jira/tasks/issue_relationship_convertor.go     | 105 +++++++++++++++++++++
 18 files changed, 461 insertions(+), 99 deletions(-)

diff --git a/backend/core/models/domainlayer/domaininfo/domaininfo.go 
b/backend/core/models/domainlayer/domaininfo/domaininfo.go
index b811d492a..de139e173 100644
--- a/backend/core/models/domainlayer/domaininfo/domaininfo.go
+++ b/backend/core/models/domainlayer/domaininfo/domaininfo.go
@@ -85,5 +85,6 @@ func GetDomainTablesInfo() []dal.Tabler {
                &ticket.Sprint{},
                &ticket.SprintIssue{},
                &ticket.IssueAssignee{},
+               &ticket.IssueRelationship{},
        }
 }
diff --git a/backend/plugins/jira/models/migrationscripts/register.go 
b/backend/core/models/domainlayer/ticket/issue_relationship.go
similarity index 50%
copy from backend/plugins/jira/models/migrationscripts/register.go
copy to backend/core/models/domainlayer/ticket/issue_relationship.go
index c0c9ed9a2..136dcf9f0 100644
--- a/backend/plugins/jira/models/migrationscripts/register.go
+++ b/backend/core/models/domainlayer/ticket/issue_relationship.go
@@ -15,32 +15,18 @@ See the License for the specific language governing 
permissions and
 limitations under the License.
 */
 
-package migrationscripts
+package ticket
 
-import (
-       "github.com/apache/incubator-devlake/core/plugin"
-)
+import "github.com/apache/incubator-devlake/core/models/domainlayer"
 
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
-       return []plugin.MigrationScript{
-               new(addSourceTable20220407),
-               new(renameSourceTable20220505),
-               new(addInitTables20220716),
-               new(addTransformationRule20221116),
-               new(addProjectName20221215),
-               new(addJiraMultiAuth20230129),
-               new(removeIssueStdStoryPoint),
-               new(addCommitRepoPattern),
-               new(expandRemotelinkUrl),
-               new(addConnectionIdToTransformationRule),
-               new(addChangeTotal20230412),
-               new(expandRemotelinkSelfUrl),
-               new(addDescAndComments),
-               new(renameTr2ScopeConfig),
-               new(addRepoUrl),
-               new(addApplicationType),
-               new(clearRepoPattern),
-               new(addRawParamTableForScope),
-       }
+type IssueRelationship struct {
+       domainlayer.DomainEntity
+
+       SourceIssueId uint64 `gorm:"index"`
+       TargetIssueId uint64
+       OriginalType  string `gorm:"type:varchar(255)"`
+}
+
+func (IssueRelationship) TableName() string {
+       return "issue_relationships"
 }
diff --git a/backend/plugins/jira/models/migrationscripts/register.go 
b/backend/core/models/migrationscripts/20230728_add_issue_relationship_table.go
similarity index 52%
copy from backend/plugins/jira/models/migrationscripts/register.go
copy to 
backend/core/models/migrationscripts/20230728_add_issue_relationship_table.go
index c0c9ed9a2..9cf262b96 100644
--- a/backend/plugins/jira/models/migrationscripts/register.go
+++ 
b/backend/core/models/migrationscripts/20230728_add_issue_relationship_table.go
@@ -18,29 +18,26 @@ limitations under the License.
 package migrationscripts
 
 import (
-       "github.com/apache/incubator-devlake/core/plugin"
+       "github.com/apache/incubator-devlake/core/context"
+       "github.com/apache/incubator-devlake/core/errors"
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+       "github.com/apache/incubator-devlake/helpers/migrationhelper"
 )
 
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
-       return []plugin.MigrationScript{
-               new(addSourceTable20220407),
-               new(renameSourceTable20220505),
-               new(addInitTables20220716),
-               new(addTransformationRule20221116),
-               new(addProjectName20221215),
-               new(addJiraMultiAuth20230129),
-               new(removeIssueStdStoryPoint),
-               new(addCommitRepoPattern),
-               new(expandRemotelinkUrl),
-               new(addConnectionIdToTransformationRule),
-               new(addChangeTotal20230412),
-               new(expandRemotelinkSelfUrl),
-               new(addDescAndComments),
-               new(renameTr2ScopeConfig),
-               new(addRepoUrl),
-               new(addApplicationType),
-               new(clearRepoPattern),
-               new(addRawParamTableForScope),
-       }
+type addIssueRelationship struct{}
+
+func (u *addIssueRelationship) Up(basicRes context.BasicRes) errors.Error {
+       return migrationhelper.AutoMigrateTables(
+               basicRes,
+               &archived.IssueRelationship{},
+       )
+
+}
+
+func (*addIssueRelationship) Version() uint64 {
+       return 20230728000001
+}
+
+func (*addIssueRelationship) Name() string {
+       return "add issue_relationships table"
 }
diff --git a/backend/plugins/jira/models/migrationscripts/register.go 
b/backend/core/models/migrationscripts/archived/issue_relationship.go
similarity index 50%
copy from backend/plugins/jira/models/migrationscripts/register.go
copy to backend/core/models/migrationscripts/archived/issue_relationship.go
index c0c9ed9a2..4779b534f 100644
--- a/backend/plugins/jira/models/migrationscripts/register.go
+++ b/backend/core/models/migrationscripts/archived/issue_relationship.go
@@ -15,32 +15,16 @@ 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"
-)
+type IssueRelationship struct {
+       DomainEntity
 
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
-       return []plugin.MigrationScript{
-               new(addSourceTable20220407),
-               new(renameSourceTable20220505),
-               new(addInitTables20220716),
-               new(addTransformationRule20221116),
-               new(addProjectName20221215),
-               new(addJiraMultiAuth20230129),
-               new(removeIssueStdStoryPoint),
-               new(addCommitRepoPattern),
-               new(expandRemotelinkUrl),
-               new(addConnectionIdToTransformationRule),
-               new(addChangeTotal20230412),
-               new(expandRemotelinkSelfUrl),
-               new(addDescAndComments),
-               new(renameTr2ScopeConfig),
-               new(addRepoUrl),
-               new(addApplicationType),
-               new(clearRepoPattern),
-               new(addRawParamTableForScope),
-       }
+       SourceIssueId uint64 `gorm:"index"`
+       TargetIssueId uint64
+       OriginalType  string `gorm:"type:varchar(255)"`
+}
+
+func (IssueRelationship) TableName() string {
+       return "issue_relationships"
 }
diff --git a/backend/core/models/migrationscripts/register.go 
b/backend/core/models/migrationscripts/register.go
index 585855835..3aad7517b 100644
--- a/backend/core/models/migrationscripts/register.go
+++ b/backend/core/models/migrationscripts/register.go
@@ -86,5 +86,6 @@ func All() []plugin.MigrationScript {
                new(modifyPrLabelsAndComments),
                new(renameFinishedCommitsDiffs),
                new(addUpdatedDateToIssueComments),
+               new(addIssueRelationship),
        }
 }
diff --git a/backend/plugins/jira/e2e/issue_relationship_test.go 
b/backend/plugins/jira/e2e/issue_relationship_test.go
new file mode 100644
index 000000000..f75df3d8a
--- /dev/null
+++ b/backend/plugins/jira/e2e/issue_relationship_test.go
@@ -0,0 +1,63 @@
+/*
+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 e2e
+
+import (
+       "testing"
+
+       "github.com/apache/incubator-devlake/core/models/common"
+       "github.com/apache/incubator-devlake/core/models/domainlayer/ticket"
+       "github.com/apache/incubator-devlake/helpers/e2ehelper"
+       "github.com/apache/incubator-devlake/plugins/jira/impl"
+       "github.com/apache/incubator-devlake/plugins/jira/models"
+       "github.com/apache/incubator-devlake/plugins/jira/tasks"
+)
+
+func TestIssueRelationshipDataFlow(t *testing.T) {
+       var plugin impl.Jira
+       dataflowTester := e2ehelper.NewDataFlowTester(t, "jira", plugin)
+
+       taskData := &tasks.JiraTaskData{
+               Options: &tasks.JiraOptions{
+                       ConnectionId: 2,
+                       BoardId:      8,
+               },
+       }
+
+       // import raw data table
+       
dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_jira_api_issue_relationships.csv",
 "_raw_jira_api_issue_relationships")
+
+       // verify issue extraction
+       dataflowTester.FlushTabler(&models.JiraIssueRelationship{})
+       dataflowTester.Subtask(tasks.ExtractIssuesMeta, taskData)
+
+       dataflowTester.VerifyTableWithOptions(&models.JiraIssueRelationship{}, 
e2ehelper.TableOptions{
+               CSVRelPath:  
"./snapshot_tables/_tool_jira_issue_relationships.csv",
+               IgnoreTypes: []interface{}{common.NoPKModel{}},
+       })
+
+       
dataflowTester.ImportCsvIntoTabler("./snapshot_tables/_tool_jira_board_issues.csv",
 &models.JiraBoardIssue{})
+
+       // verify issue conversion
+       dataflowTester.FlushTabler(&ticket.IssueRelationship{})
+       dataflowTester.Subtask(tasks.ConvertIssueRelationshipsMeta, taskData)
+       dataflowTester.VerifyTableWithOptions(&ticket.IssueRelationship{}, 
e2ehelper.TableOptions{
+               CSVRelPath:  "./snapshot_tables/issue_relationships.csv",
+               IgnoreTypes: []interface{}{common.NoPKModel{}},
+       })
+}
diff --git 
a/backend/plugins/jira/e2e/raw_tables/_raw_jira_api_issue_relationships.csv 
b/backend/plugins/jira/e2e/raw_tables/_raw_jira_api_issue_relationships.csv
new file mode 100644
index 000000000..8fb2c53dd
--- /dev/null
+++ b/backend/plugins/jira/e2e/raw_tables/_raw_jira_api_issue_relationships.csv
@@ -0,0 +1,23 @@
+"id","params","data","url","input","created_at"
+1,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10802"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10802"",""key"":""DZFNK0168-1"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+2,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10803"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10803"",""key"":""DZFNK0168-2"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+3,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10804"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10804"",""key"":""DZFNK0168-3"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+4,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10805"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10805"",""key"":""DZFNK0168-4"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+5,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10806"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10806"",""key"":""DZFNK0168-5"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+6,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10807"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10807"",""key"":""DZFNK0168-6"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+7,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10808"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10808"",""key"":""DZFNK0168-7"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+8,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10809"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10809"",""key"":""DZFNK0168-8"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+9,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10810"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10810"",""key"":""DZFNK0168-9"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsmall 
[...]
+10,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10811"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10811"",""key"":""DZFNK0168-10"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+11,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10812"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10812"",""key"":""DZFNK0168-11"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+12,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10813"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10813"",""key"":""DZFNK0168-12"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+13,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10814"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10814"",""key"":""DZFNK0168-13"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+14,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10815"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10815"",""key"":""DZFNK0168-14"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+15,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10816"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10816"",""key"":""DZFNK0168-15"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+16,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10817"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10817"",""key"":""DZFNK0168-16"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+17,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10818"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10818"",""key"":""DZFNK0168-17"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+18,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10819"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10819"",""key"":""DZFNK0168-18"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+19,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10820"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10820"",""key"":""DZFNK0168-19"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+20,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10821"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10821"",""key"":""DZFNK0168-20"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+21,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10822"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10822"",""key"":""DZFNK0168-21"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
+22,"{""ConnectionId"":2,""BoardId"":8}","{""expand"":""operations,versionedRepresentations,editmeta,changelog,renderedFields"",""id"":""10823"",""self"":""http://3.81.151.94:8080/rest/agile/1.0/issue/10823"",""key"":""DZFNK0168-22"",""fields"":{""issuetype"":{""self"":""http://3.81.151.94:8080/rest/api/2/issuetype/10004"",""id"":""10004"",""description"":""A
 problem which impairs or prevents the functions of the 
product."",""iconUrl"":""http://3.81.151.94:8080/secure/viewavatar?size=xsma 
[...]
diff --git 
a/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues.csv 
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues.csv
index 2c4f0cfe1..b1a34effe 100644
--- a/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues.csv
+++ b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_board_issues.csv
@@ -29,3 +29,27 @@ 
connection_id,board_id,issue_id,_raw_data_params,_raw_data_table,_raw_data_id,_r
 2,8,10097,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12468,
 2,8,10098,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12469,
 2,8,10099,"{""ConnectionId"":2,""BoardId"":8}",_raw_jira_api_issues,12470,
+2,8,10802,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",1,""
+2,8,10803,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",2,""
+2,8,10804,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",3,""
+2,8,10805,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",4,""
+2,8,10806,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",5,""
+2,8,10807,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",6,""
+2,8,10808,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",7,""
+2,8,10809,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",8,""
+2,8,10810,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",9,""
+2,8,10811,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",10,""
+2,8,10812,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",11,""
+2,8,10813,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",12,""
+2,8,10814,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",13,""
+2,8,10815,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",14,""
+2,8,10816,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",15,""
+2,8,10817,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",16,""
+2,8,10818,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",17,""
+2,8,10819,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",18,""
+2,8,10820,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",19,""
+2,8,10821,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",20,""
+2,8,10822,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",21,""
+2,8,10823,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",22,""
+2,8,116800,"{""ConnectionId"":2,""BoardId"":8}","_raw_jira_api_issues",23,""
+
diff --git 
a/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_issue_relationships.csv 
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_issue_relationships.csv
new file mode 100644
index 000000000..9277294ed
--- /dev/null
+++ 
b/backend/plugins/jira/e2e/snapshot_tables/_tool_jira_issue_relationships.csv
@@ -0,0 +1,13 @@
+connection_id,issue_id,issue_key,type_id,type_name,inward,outward,inward_issue_id,inward_issue_key,outward_issue_id,outward_issue_key
+2,10802,DZFNK0168-1,10000,Blocks,is blocked by,blocks,10806,DZFNK0168-5,0,
+2,10803,DZFNK0168-2,10000,Blocks,is blocked by,blocks,0,,10823,DZFNK0168-22
+2,10805,DZFNK0168-4,10001,Cloners,is cloned by,clones,0,,10812,DZFNK0168-11
+2,10806,DZFNK0168-5,10002,Duplicate,is duplicated 
by,duplicates,10812,DZFNK0168-11,0,
+2,10812,DZFNK0168-11,10002,Duplicate,is duplicated 
by,duplicates,116583,IP8CUD168-35305,0,
+2,10815,DZFNK0168-14,10002,Duplicate,is duplicated 
by,duplicates,0,,116566,IP8CUD168-35288
+2,10817,DZFNK0168-16,10001,Cloners,is cloned 
by,clones,111957,M2VRIQ168-12985,0,
+2,10818,DZFNK0168-17,10001,Cloners,is cloned 
by,clones,0,,111900,M2VRIQ168-12954
+2,10820,DZFNK0168-19,10003,Relates,relates to,relates to,0,,10822,DZFNK0168-21
+2,10821,DZFNK0168-20,10000,Blocks,is blocked 
by,blocks,116684,IP8CUD168-35406,0,
+2,10822,DZFNK0168-21,10003,Relates,relates to,relates to,10820,DZFNK0168-19,0,
+2,10823,DZFNK0168-22,10000,Blocks,is blocked by,blocks,10803,DZFNK0168-2,0,
diff --git a/backend/plugins/jira/e2e/snapshot_tables/issue_relationships.csv 
b/backend/plugins/jira/e2e/snapshot_tables/issue_relationships.csv
new file mode 100644
index 000000000..515fc9089
--- /dev/null
+++ b/backend/plugins/jira/e2e/snapshot_tables/issue_relationships.csv
@@ -0,0 +1,13 @@
+id,source_issue_id,target_issue_id,original_type
+jira:JiraIssueRelationship:2:10802-isblockedby-10806,10802,10806,is blocked by
+jira:JiraIssueRelationship:2:10803-blocks-10823,10803,10823,blocks
+jira:JiraIssueRelationship:2:10805-clones-10812,10805,10812,clones
+jira:JiraIssueRelationship:2:10806-isduplicatedby-10812,10806,10812,is 
duplicated by
+jira:JiraIssueRelationship:2:10812-isduplicatedby-116583,10812,116583,is 
duplicated by
+jira:JiraIssueRelationship:2:10815-duplicates-116566,10815,116566,duplicates
+jira:JiraIssueRelationship:2:10817-isclonedby-111957,10817,111957,is cloned by
+jira:JiraIssueRelationship:2:10818-clones-111900,10818,111900,clones
+jira:JiraIssueRelationship:2:10820-relatesto-10822,10820,10822,relates to
+jira:JiraIssueRelationship:2:10821-isblockedby-116684,10821,116684,is blocked 
by
+jira:JiraIssueRelationship:2:10822-relatesto-10820,10822,10820,relates to
+jira:JiraIssueRelationship:2:10823-isblockedby-10803,10823,10803,is blocked by
diff --git a/backend/plugins/jira/impl/impl.go 
b/backend/plugins/jira/impl/impl.go
index 96928aa7e..b2a39bbd9 100644
--- a/backend/plugins/jira/impl/impl.go
+++ b/backend/plugins/jira/impl/impl.go
@@ -88,6 +88,7 @@ func (p Jira) GetTablesInfo() []dal.Tabler {
                &models.JiraStatus{},
                &models.JiraWorklog{},
                &models.JiraIssueComment{},
+               &models.JiraIssueRelationship{},
                &models.JiraScopeConfig{},
        }
 }
@@ -139,6 +140,7 @@ func (p Jira) SubTaskMetas() []plugin.SubTaskMeta {
                tasks.ConvertIssueCommentsMeta,
                tasks.ConvertWorklogsMeta,
                tasks.ConvertIssueChangelogsMeta,
+               tasks.ConvertIssueRelationshipsMeta,
 
                tasks.ConvertSprintsMeta,
                tasks.ConvertSprintIssuesMeta,
diff --git a/backend/plugins/jira/models/issue_relationship.go 
b/backend/plugins/jira/models/issue_relationship.go
new file mode 100644
index 000000000..f96e02a9e
--- /dev/null
+++ b/backend/plugins/jira/models/issue_relationship.go
@@ -0,0 +1,41 @@
+/*
+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 (
+       "github.com/apache/incubator-devlake/core/models/common"
+)
+
+type JiraIssueRelationship struct {
+       common.NoPKModel
+       ConnectionId    uint64 `gorm:"primaryKey"`
+       IssueId         uint64 `gorm:"primarykey"`
+       IssueKey        string `gorm:"type:varchar(255)"` // e.g. DEV-1
+       TypeId          uint64 // e.g. 10001
+       TypeName        string `gorm:"type:varchar(255)"` // e.g. Blocks
+       Inward          string `gorm:"type:varchar(255)"` // e.g. blocks
+       Outward         string `gorm:"type:varchar(255)"` // e.g. is blocked by
+       InwardIssueId   uint64 // e.g. 116566
+       InwardIssueKey  string `gorm:"type:varchar(255)"` // e.g. DEV-2
+       OutwardIssueId  uint64 // e.g. 116567
+       OutwardIssueKey string `gorm:"type:varchar(255)"` // e.g. DEV-3
+}
+
+func (JiraIssueRelationship) TableName() string {
+       return "_tool_jira_issue_relationships"
+}
diff --git a/backend/plugins/jira/models/migrationscripts/register.go 
b/backend/plugins/jira/models/migrationscripts/20230726_add_issue_relationship_table.go
similarity index 52%
copy from backend/plugins/jira/models/migrationscripts/register.go
copy to 
backend/plugins/jira/models/migrationscripts/20230726_add_issue_relationship_table.go
index c0c9ed9a2..e04482f76 100644
--- a/backend/plugins/jira/models/migrationscripts/register.go
+++ 
b/backend/plugins/jira/models/migrationscripts/20230726_add_issue_relationship_table.go
@@ -18,29 +18,25 @@ limitations under the License.
 package migrationscripts
 
 import (
-       "github.com/apache/incubator-devlake/core/plugin"
+       "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/jira/models/migrationscripts/archived"
 )
 
-// All return all the migration scripts
-func All() []plugin.MigrationScript {
-       return []plugin.MigrationScript{
-               new(addSourceTable20220407),
-               new(renameSourceTable20220505),
-               new(addInitTables20220716),
-               new(addTransformationRule20221116),
-               new(addProjectName20221215),
-               new(addJiraMultiAuth20230129),
-               new(removeIssueStdStoryPoint),
-               new(addCommitRepoPattern),
-               new(expandRemotelinkUrl),
-               new(addConnectionIdToTransformationRule),
-               new(addChangeTotal20230412),
-               new(expandRemotelinkSelfUrl),
-               new(addDescAndComments),
-               new(renameTr2ScopeConfig),
-               new(addRepoUrl),
-               new(addApplicationType),
-               new(clearRepoPattern),
-               new(addRawParamTableForScope),
-       }
+type addIssueRelationship struct{}
+
+func (script *addIssueRelationship) Up(basicRes context.BasicRes) errors.Error 
{
+       return migrationhelper.AutoMigrateTables(
+               basicRes,
+               &archived.JiraIssueRelationship{},
+       )
+}
+
+func (*addIssueRelationship) Version() uint64 {
+       return 20230727122534
+}
+
+func (*addIssueRelationship) Name() string {
+       return "add table _tool_jira_issue_relationships table"
 }
diff --git 
a/backend/plugins/jira/models/migrationscripts/archived/issue_relationship.go 
b/backend/plugins/jira/models/migrationscripts/archived/issue_relationship.go
new file mode 100644
index 000000000..29f8b1a13
--- /dev/null
+++ 
b/backend/plugins/jira/models/migrationscripts/archived/issue_relationship.go
@@ -0,0 +1,41 @@
+/*
+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 archived
+
+import (
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
+)
+
+type JiraIssueRelationship struct {
+       archived.NoPKModel
+       ConnectionId    uint64 `gorm:"primaryKey"`
+       IssueId         uint64 `gorm:"primarykey"`
+       IssueKey        string `gorm:"type:varchar(255)"` // e.g. DEV-1
+       TypeId          uint64 // e.g. 10001
+       TypeName        string `gorm:"type:varchar(255)"` // e.g. Blocks
+       Inward          string `gorm:"type:varchar(255)"` // e.g. blocks
+       Outward         string `gorm:"type:varchar(255)"` // e.g. is blocked by
+       InwardIssueId   uint64 // e.g. 116566
+       InwardIssueKey  string `gorm:"type:varchar(255)"` // e.g. DEV-2
+       OutwardIssueId  uint64 // e.g. 116567
+       OutwardIssueKey string `gorm:"type:varchar(255)"` // e.g. DEV-3
+}
+
+func (JiraIssueRelationship) TableName() string {
+       return "_tool_jira_issue_relationships"
+}
diff --git a/backend/plugins/jira/models/migrationscripts/register.go 
b/backend/plugins/jira/models/migrationscripts/register.go
index c0c9ed9a2..37a65394b 100644
--- a/backend/plugins/jira/models/migrationscripts/register.go
+++ b/backend/plugins/jira/models/migrationscripts/register.go
@@ -42,5 +42,6 @@ func All() []plugin.MigrationScript {
                new(addApplicationType),
                new(clearRepoPattern),
                new(addRawParamTableForScope),
+               new(addIssueRelationship),
        }
 }
diff --git a/backend/plugins/jira/tasks/apiv2models/issue.go 
b/backend/plugins/jira/tasks/apiv2models/issue.go
index 8a0651acd..bfef2f171 100644
--- a/backend/plugins/jira/tasks/apiv2models/issue.go
+++ b/backend/plugins/jira/tasks/apiv2models/issue.go
@@ -97,7 +97,7 @@ type Issue struct {
                Timeestimate                  interface{}        
`json:"timeestimate"`
                Aggregatetimeoriginalestimate interface{}        
`json:"aggregatetimeoriginalestimate"`
                Versions                      []interface{}      
`json:"versions"`
-               Issuelinks                    []interface{}      
`json:"issuelinks"`
+               Issuelinks                    []IssueLink        
`json:"issuelinks"`
                Assignee                      *Account           
`json:"assignee"`
                Updated                       helper.Iso8601Time 
`json:"updated"`
                Status                        struct {
@@ -160,6 +160,60 @@ type Issue struct {
        } `json:"changelog"`
 }
 
+type IssueLinkType struct {
+       ID      uint64 `json:"id,string"`
+       Name    string `json:"name"`
+       Inward  string `json:"inward"`
+       Outward string `json:"outward"`
+       Self    string `json:"self"`
+}
+
+type InOutwardIssue struct {
+       ID     uint64 `json:"id,string"`
+       Key    string `json:"key"`
+       Self   string `json:"self"`
+       Fields struct {
+               Summary string `json:"summary"`
+               Status  struct {
+                       Self           string `json:"self"`
+                       Description    string `json:"description"`
+                       IconURL        string `json:"iconUrl"`
+                       Name           string `json:"name"`
+                       ID             uint64 `json:"id,string"`
+                       StatusCategory struct {
+                               Self      string `json:"self"`
+                               ID        int    `json:"id"`
+                               Key       string `json:"key"`
+                               ColorName string `json:"colorName"`
+                               Name      string `json:"name"`
+                       } `json:"statusCategory"`
+               } `json:"status"`
+               Priority struct {
+                       Self    string `json:"self"`
+                       IconURL string `json:"iconUrl"`
+                       Name    string `json:"name"`
+                       ID      uint64 `json:"id,string"`
+               } `json:"priority"`
+               Issuetype struct {
+                       Self        string `json:"self"`
+                       ID          uint64 `json:"id,string"`
+                       Description string `json:"description"`
+                       IconURL     string `json:"iconUrl"`
+                       Name        string `json:"name"`
+                       Subtask     bool   `json:"subtask"`
+                       AvatarID    int    `json:"avatarId"`
+               } `json:"issuetype"`
+       } `json:"fields"`
+}
+
+type IssueLink struct {
+       ID           uint64         `json:"id,string"`
+       Self         string         `json:"self"`
+       Type         IssueLinkType  `json:"type"`
+       InwardIssue  InOutwardIssue `json:"inwardIssue"`
+       OutwardIssue InOutwardIssue `json:"outwardIssue"`
+}
+
 func (i Issue) toToolLayer(connectionId uint64) *models.JiraIssue {
        var workload float64
        result := &models.JiraIssue{
diff --git a/backend/plugins/jira/tasks/issue_extractor.go 
b/backend/plugins/jira/tasks/issue_extractor.go
index 7b98a842d..11e730f35 100644
--- a/backend/plugins/jira/tasks/issue_extractor.go
+++ b/backend/plugins/jira/tasks/issue_extractor.go
@@ -177,6 +177,23 @@ func extractIssues(data *JiraTaskData, mappings 
*typeMappings, row *api.RawData)
                }
                results = append(results, issueLabel)
        }
+       issuelinks := apiIssue.Fields.Issuelinks
+       for _, v := range issuelinks {
+               issueLink := &models.JiraIssueRelationship{
+                       ConnectionId:    data.Options.ConnectionId,
+                       IssueId:         issue.IssueId,
+                       IssueKey:        issue.IssueKey,
+                       TypeId:          v.Type.ID,          // Extracting the 
TypeId from the issuelink
+                       TypeName:        v.Type.Name,        // Extracting the 
TypeName from the issuelink
+                       Inward:          v.Type.Inward,      // Extracting the 
Inward from the issuelink
+                       Outward:         v.Type.Outward,     // Extracting the 
Outward from the issuelink
+                       InwardIssueId:   v.InwardIssue.ID,   // Extracting the 
InwardIssueId from the issuelink
+                       InwardIssueKey:  v.InwardIssue.Key,  // Extracting the 
InwardIssueKey from the issuelink
+                       OutwardIssueId:  v.OutwardIssue.ID,  // Extracting the 
OutwardIssueId from the issuelink
+                       OutwardIssueKey: v.OutwardIssue.Key, // Extracting the 
OutwardIssueKey from the issuelink
+               }
+               results = append(results, issueLink)
+       }
        return results, nil
 }
 
diff --git a/backend/plugins/jira/tasks/issue_relationship_convertor.go 
b/backend/plugins/jira/tasks/issue_relationship_convertor.go
new file mode 100644
index 000000000..64fbb640b
--- /dev/null
+++ b/backend/plugins/jira/tasks/issue_relationship_convertor.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 (
+       "fmt"
+       "reflect"
+       "strings"
+
+       "github.com/apache/incubator-devlake/core/dal"
+       "github.com/apache/incubator-devlake/core/errors"
+       "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"
+       helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+
+       "github.com/apache/incubator-devlake/plugins/jira/models"
+)
+
+var ConvertIssueRelationshipsMeta = plugin.SubTaskMeta{
+       Name:             "convertIssueRelationships",
+       EntryPoint:       ConvertIssueRelationships,
+       EnabledByDefault: true,
+       Description:      "Convert tool layer table jira_issue_relationships 
into  domain layer table issue_relationships",
+       DomainTypes:      []string{plugin.DOMAIN_TYPE_TICKET},
+}
+
+func ConvertIssueRelationships(taskCtx plugin.SubTaskContext) errors.Error {
+       db := taskCtx.GetDal()
+       data := taskCtx.GetData().(*JiraTaskData)
+
+       cursor, err := db.Cursor(
+               dal.Select("jir.*"),
+               dal.From("_tool_jira_issue_relationships jir"),
+               dal.Join(`LEFT JOIN _tool_jira_board_issues jbi
+              ON jir.connection_id = jbi.connection_id AND jir.issue_id = 
jbi.issue_id`),
+               dal.Where("jir.connection_id = ? AND jbi.board_id = ?", 
data.Options.ConnectionId, data.Options.BoardId),
+               dal.Orderby("issue_id ASC"),
+       )
+       if err != nil {
+               return err
+       }
+       defer cursor.Close()
+       issueIdGen := didgen.NewDomainIdGenerator(&JiraIssueRelationship{})
+
+       converter, err := helper.NewDataConverter(helper.DataConverterArgs{
+               RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
+                       Ctx: taskCtx,
+                       Params: JiraApiParams{
+                               ConnectionId: data.Options.ConnectionId,
+                               BoardId:      data.Options.BoardId,
+                       },
+                       Table: RAW_ISSUE_TABLE,
+               },
+               InputRowType: reflect.TypeOf(models.JiraIssueRelationship{}),
+               Input:        cursor,
+               Convert: func(inputRow interface{}) ([]interface{}, 
errors.Error) {
+                       issueRelationship := 
inputRow.(*models.JiraIssueRelationship)
+                       domainIssueRelationship := &ticket.IssueRelationship{
+                               SourceIssueId: issueRelationship.IssueId,
+                       }
+                       if issueRelationship.InwardIssueId != 0 {
+                               domainIssueRelationship.TargetIssueId = 
issueRelationship.InwardIssueId
+                               domainIssueRelationship.OriginalType = 
issueRelationship.Inward
+                       } else {
+                               domainIssueRelationship.TargetIssueId = 
issueRelationship.OutwardIssueId
+                               domainIssueRelationship.OriginalType = 
issueRelationship.Outward
+                       }
+
+                       originalType := 
strings.Replace(domainIssueRelationship.OriginalType, " ", "", -1)
+                       relationshipKey := fmt.Sprintf("%d-%s-%d", 
domainIssueRelationship.SourceIssueId, originalType, 
domainIssueRelationship.TargetIssueId)
+
+                       domainIssueRelationship.DomainEntity.Id = 
issueIdGen.Generate(data.Options.ConnectionId, relationshipKey)
+
+                       return []interface{}{
+                               domainIssueRelationship,
+                       }, nil
+               },
+       })
+       if err != nil {
+               return err
+       }
+
+       return converter.Execute()
+}
+
+type JiraIssueRelationship struct {
+       ConnectionId    uint64 `gorm:"primaryKey"`
+       RelationshipKey string `gorm:"primarykey"`
+}


Reply via email to