# Sync multiple remoteissue keys

**URL:** <https://community.exalate.com/t/sync-multiple-remoteissue-keys/4053>\
**Category:** General Questions\
**Tags:** onpremise-jira, migrated\_question\
**Created:** [November 4, 2024, 6:25am UTC](https://community.exalate.com/t/sync-multiple-remoteissue-keys/4053 "2024-11-04T06:25:27Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![xl8bot](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/xl8bot/32/324_2.png) [@xl8bot](https://community.exalate.com/u/xl8bot)\
**Post date:** [November 4, 2024, 6:25am UTC](https://community.exalate.com/t/sync-multiple-remoteissue-keys/4053/1 "2024-11-04T06:25:27Z")

</div>

_Originally asked by sapir monza on 28 August 2019 [(original question)](https://oldcommunity.exalate.com/questions/2592689)_

* * *

Hi,

I’m using Exalate to sync between projects on the same Jira server instance.

Currently, the remote issue key is synced to a custom filed in the original ticket with the following code:

```auto
ExalateEventListener.hangListener(
connection,

{ String localIssueKey, String remoteIssueKey, localIssue, remoteIssue -> // operation when remote issue has been Exalated localIssue.customFields."Escalated ticket".value = remoteIssueKey }

,

{ String localIssueKey, String remoteIssueKey, localIssue, remoteIssue -> // operation when remote issue has been UnExalated }

,

{ String localIssueKey, String remoteIssueKey, localIssue, remoteIssue -> // operation when remote issue has been Deleted }

)

```

However, when the original ticket needs to be sync with 2 projects, only one of the remoteissue key is synced to that field - “Escalated ticket”.

How can make sure that those 2 cases will display in this field separated with a comma?  
For example, the triggered fired and now the synchronization of the original ticket under project ‘z’ started with two different projects (project ‘x’ and project ‘y’), in “Escalated ticket” field under the original ticket in project ‘z’ I expected the two cases will be displayed on from project ‘x’ and the second on from project ‘y’.

Thanks,  
Sapir

* * *

#### Comments:

> **Francis Martens (Exalate) commented on 28 August 2019**
>
> > Hi Sapir,
> 
> I’m a bit lost on the structure of the code and the use case you want to implement
> 
> Can we take it step by step and confirm that the sequence below is correct - or rectify where possible
> 
> - Issue A1 gets exalated to create a twin B1
> - Issue A1 gets exalated to create a twin C1
> - With the ExalateEventListener.hangListener you are trying to update a customField “Escalated Ticket” such that it contains a link to B1 and C1
> - Something fails
> 
> Could you add the complete script here or in a code-sharing service such as [https://codepile.io](https://codepile.io)

> **sapir monza commented on 29 August 2019**
>
> > Hi Francis,
> 
> Correct, actually the process didn’t fail, both issues B1 and C1 linked to A1, but only one of them displayed under the “Escalated Ticket” field.
> 
> I got the script from Roman Melnychenko in case number EASE-2816, I have added all the following scripts to our Jira server under scripts folder:
> 
> - [ExalateEventListener.groovy](https://stash.idalko.com/projects/JISES/repos/jira-server/raw/src/main/scripts/ExalateEventListener.groovy?at=refs%2Fheads%2Ffeature%2Fexalate-event-listener "Follow link")
> - [IsSource.groovy](https://stash.idalko.com/projects/JISES/repos/jira-server/raw/src/main/scripts/IsSource.groovy?at=refs%2Fheads%2Ffeature%2FEASE-1544-move-use-case "Follow link")
> - [StopSync.groovy](https://stash.idalko.com/projects/JISES/repos/jira-server/raw/src/main/scripts/StopSync.groovy?at=refs%2Fheads%2Ffeature%2FEASE-1544-move-use-case "Follow link")
> - [StatusSync.groovy](https://stash.idalko.com/projects/JISES/repos/jira-server/raw/src/main/scripts/StatusSync.groovy?at=refs%2Fheads%2Fstatus-sync "Follow link")
> - [IssueLinkSync.groovy](https://stash.idalko.com/projects/JISES/repos/jira-server/raw/src/main/scripts/IssueLinkSync.groovy?at=refs%2Fheads%2Ffeature%2FEASE-1544-move-use-case "Follow link")
> 
> and the code below to the Outgoing sync(data filter):
> 
> ```auto
> ExalateEventListener.hangListener(
> connection,
> { String localIssueKey, String remoteIssueKey, localIssue, remoteIssue ->
> // operation when remote issue has been Exalated
> localIssue.customFields."Remote Issue Key".value = remoteIssueKey
> },
> { String localIssueKey, String remoteIssueKey, localIssue, remoteIssue ->
> // operation when remote issue has been UnExalated
> },
> { String localIssueKey, String remoteIssueKey, localIssue, remoteIssue ->
> // operation when remote issue has been Deleted
> }
> )  
>   
> Please let me know if any clearification is needed.  
> Thanks!
> 
> ```

> **Jorge Jerez Ibáñez commented on 22 February 2021**
>
> > Hi
> 
> Are this files hiden now? I’ve a similar problem and can’t solve it

---

<div class="post-metadata">

**Author:** ![xl8bot](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/xl8bot/32/324_2.png) [@xl8bot](https://community.exalate.com/u/xl8bot)\
**Post date:** [November 4, 2024, 6:25am UTC](https://community.exalate.com/t/sync-multiple-remoteissue-keys/4053/2 "2024-11-04T06:25:28Z")

</div>

_Answer by Serhiy Onyshchenko on 03 September 2019_

Hello, Sapir.

I believe the problem is that the entire custom field value is overridden with the issue key from the last sync.

So I’d suggest the following:

```auto
ExalateEventListener.hangListener(
 connection,
 { String localIssueKey, String remoteIssueKey, localIssue, remoteIssue ->
    // operation when remote issue has been Exalated
    localIssue.customFields."Remote Issue Key".value = ExalateApi
      .getRemoteIssueKeys(localIssue)
      .collect{it.URN}
      .join(",")
 },
 { String localIssueKey, String remoteIssueKey, localIssue, remoteIssue ->
    // operation when remote issue has been UnExalated
 },
 { String localIssueKey, String remoteIssueKey, localIssue, remoteIssue ->
    // operation when remote issue has been Deleted
 }
)

```

And make sure that your ExalateApi.groovy has the “getRemoteIssueKeys” method:

```auto
import com.exalate.api.domain.IIssueKey
import com.exalate.api.domain.connection.IConnection
import com.exalate.basic.domain.BasicIssueKey
import com.exalate.basic.domain.hubobject.v1.BasicHubIssue

/**
 * This class is used to track breaking changes in Exalate API
 * necessary to ensure that:
 * 1) they are documented for proper escalation
 * 2) they are handled for the versions where they've been introduced
 * */
class ExalateApi {
    static IConnection getConnection(int id) {
        getConnectionInt(id)
    }
    static IConnection getConnection(Integer id) {
        if (id == null) {
            return null
        }
        getConnectionInt(id.intValue())
    }
    private static IConnection getConnectionInt(int id) {
        try {
            // Exalate 4.2.X
            def relrepo = com.atlassian.jira.component.ComponentAccessor.getOSGiComponentInstanceOfType(com.exalate.api.persistence.relation.IRelationRepository.class)
            relrepo.getRelation(id)
        } catch (MissingMethodException ignore) {
            // Exalate 4.3.X
            def relrepo = com.atlassian.jira.component.ComponentAccessor.getOSGiComponentInstanceOfType(com.exalate.api.persistence.relation.IRelationRepository.class)
            relrepo.getConnectionById(id)
        }
    }

    static com.atlassian.jira.user.ApplicationUser getProxyUser() {
        def nserv = com.atlassian.jira.component.ComponentAccessor.getOSGiComponentInstanceOfType(com.exalate.api.node.INodeService.class)
        nserv.proxyUser
    }

    static List<IIssueKey> getRemoteIssueKeys(BasicHubIssue issue) {
        def ttRepo = com.atlassian.jira.component.ComponentAccessor.getOSGiComponentInstanceOfType(com.exalate.api.persistence.twintrace.ITwinTraceRepository.class)
        ttRepo
                .findByLocalIssueKey(new BasicIssueKey(issue.id as Long, issue.key))
                .collect { it.remoteReplica?.issueKey }
                .findAll()
    }
}

```

Please, let me know if this helps.

Regards, Serhiy.

* * *

#### Comments:

> **sapir monza commented on 04 September 2019**
>
> > Hi Serhiy,
> 
> Where ExalateApi.groovy located?
> 
> Thanks

> **sapir monza commented on 05 September 2019**
>
> > Hi Serhiy,
> 
> So I created the ExalateApi.groovy file with the code you have provided and save it in the scripts folder and replaced the
> 
> ```auto
> ExalateEventListener.hangListener
> 
> ```
> 
> with the provided code, and when I tested it none of the remote issue displayed in “Remote Issue Key” field.
> 
> Do you have any ideas?
> 
> Thanks,
> 
> Sapir

> **Francis Martens (Exalate) commented on 10 September 2019**
>
> > Sapir - did you try to debug the flow.
> 
> Check for some examples how following document - [https://docs.idalko.com/exalate/x/J4crAQ](https://docs.idalko.com/exalate/x/J4crAQ)

> **sapir monza commented on 10 September 2019**
>
> > Hi Francis,
> 
> So, it seems that the value that returns from ExalateApi function is null, I can see the following log:
> 
> `Cannot set property ‘value’ on null object`
> 
> How can I debug the code in that function?
> 
> Thanks,
> 
> Sapir

> **Francis Martens (Exalate) commented on 10 September 2019**
>
> > Can you send an exalate support zip to [support@exalate.com](mailto:support@exalate.com) referring this question. We’ll take it from there

> **sapir monza commented on 10 September 2019**
>
> > Hi,
> 
> I sent the logs.
> 
> Thanks
