JIRA SERVER

This article shows how to create a JIRA link between the source and a destination issue and keep the link even if the issue has been Unexalated.

By default, the Exalate app displays remote issue link on the Sync panel, but once you 'Unexalate' an issue, the sync panel will be removed from the issue view. 

In some cases, it would be handy to keep the remote issue link on the source issue, even if the synchronization is finished.

It could be achieved with the help of Jira Server API

Source side

Add the code to the Data Filter to send the

 // ADD AN ISSUE LINK WHEN THE ISSUE IS CREATED
replica.id            = issue.id
// END: ADD AN ISSUE LINK WHEN THE ISSUE IS CREATED



Destination side

Add the following script to the Create Processor 

 // ADD AN ISSUE LINK WHEN THE ISSUE IS CREATED
final def connectionName = relation.name as String
final def replicaId = replica.id as Long
final def remoteIssueKey = replica.key as String
final def remoteIssueUrl = remoteReplica.payload.issueUrl
Thread.start {
    def count = 0
    while (nodeHelper.getLocalIssueFromRemoteId(replicaId) == null && count < Integer.MAX_VALUE) {
        sleep(100L);
        count++
    }
    def createdIssueId = nodeHelper.getLocalIssueFromRemoteId(replicaId).id as Long
    def issueManager = com.atlassian.jira.component.ComponentAccessor.getIssueManager()
    def remoteIssueLinkService = com.atlassian.jira.component.ComponentAccessor.getComponent(com.atlassian.jira.bc.issue.link.RemoteIssueLinkService.class)
    final def nservInternal = com.atlassian.jira.component.ComponentAccessor.getOSGiComponentInstanceOfType(com.exalate.api.node.INodeService.class)
    def proxyAppUserInternal = nservInternal.getProxyUser()
    def createdIssue = issueManager.getIssueObject(createdIssueId)
    if (createdIssue != null) {
        def message = { com.atlassian.jira.util.ErrorCollection c ->
            """Field errors: `${c.errors.entrySet().collect { e -> "${e.key} - ${e.value}".toString() }.join(",")}`, Messages: `${c.errorMessages.join(",")}`, Reasons: `${c.reasons.collect{ r -> r.name() }.join(",")}`""".toString()
        }
        com.atlassian.jira.issue.link.RemoteIssueLinkBuilder builder = new com.atlassian.jira.issue.link.RemoteIssueLinkBuilder();

        builder.issueId(createdIssue.id)
        builder.title(remoteIssueKey);

        builder.applicationName(connectionName);
        builder.applicationType("com.exalate.jiranode.script");
        builder.relationship("Escalated from");
        builder.url(remoteIssueUrl);

        com.atlassian.jira.bc.issue.link.RemoteIssueLinkService.CreateValidationResult validation = ({try {
                return remoteIssueLinkService.validateCreate(proxyAppUserInternal, builder.build())
            } catch (Exception ignore) {
                return remoteIssueLinkService.validateCreate(proxyAppUserInternal.getDirectoryUser(), builder.build())
            }})()
        if (!validation.isValid()) {
            throw new com.exalate.api.exception.IssueTrackerException("Couldn't create a link on " +
                    createdIssue.key + " " +
                    "using proxy user '" + proxyAppUserInternal.getDisplayName() + "' " +
                    "via the JIRA API: " + message(validation.getErrorCollection()));
        }


        com.atlassian.jira.bc.issue.link.RemoteIssueLinkService.RemoteIssueLinkResult remoteIssueLinkResult =
                ({try {
                    return remoteIssueLinkService.create(proxyAppUserInternal, validation)
                } catch (Exception ignore) {
                    return remoteIssueLinkService.create(proxyAppUserInternal.getDirectoryUser(), validation)
                }})()
        if (!remoteIssueLinkResult.isValid()) {
            throw new com.exalate.api.exception.IssueTrackerException("Couldn't create a link on " +
                    createdIssue.key + " " +
                    " using proxy user '" + proxyAppUserInternal.getDisplayName() + "'" +
                    " via the JIRA API: " + message(remoteIssueLinkResult.getErrorCollection()));
        }
    }
}
// END: ADD AN ISSUE LINK WHEN THE ISSUE IS CREATED
Check the example below

The remote issue link display on the Sync panel and in the Issue Links section

The remote issue link remains in the Issue Links section (the issue is not under sync anymore)