Sync multiple remoteissue keys

Originally asked by sapir monza on 28 August 2019 (original question)


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:

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

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:

and the code below to the Outgoing sync(data filter):

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

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:

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:

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

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

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 referring this question. We’ll take it from there

sapir monza commented on 10 September 2019

Hi,

I sent the logs.

Thanks