1
0
-1

Hi Team,

We have a custom script which simulates Exalate “Connect” operation as below during first sync.

Scenario Flow (Customer Jira to Our Jira):

  1. User creates a Feature manually in our Jira.

  2. Customer user creates feature manually in their Jira providing a label with our Feature key created in Step-1.

  3. With the help of our feature key mentioned in Customer Jira, while establishing first sync, we are using below small custom script:


Script snippet

if (firstSync) {

  if(replica.typeName == "Feature"){
       connectFeatureToFeature()
  }

}


void connectFeatureToFeature() {
     String projectKey = issue.getProjectKey()
     final String INTERNAL_KEY_REGEX = "^${projectKey}-\\d+"

  Issue jiraSyncedIssue = ComponentAccessor.getIssueManager().getIssueObject(issue.getKey())

   IHubLabel label = getLabelOfIssueKeyPerRegex(jiraSyncedIssue, INTERNAL_KEY_REGEX)

   if (label) {

       String issueKey = label.getLabel()

       Issue jiraIssue = ComponentAccessor.getIssueManager().getIssueObject(issueKey)         if(jiraIssue){

          issue.id = jiraIssue.getId() as Long

       }

   }

}



The major problem we are facing in this situation is:

We are able to successfully connect Customer Feature to our exiting Feature by script, but whatever Attachments and Comments were previously added by our user during Feature creation are getting deleted/removed during first sync only.


Incoming script line used for syncing comments as below:

issue.comments = commentHelper.mergeComments(issue, replica)


and we do not have any incoming script for syncing attachments so we were expecting that our side attachments should remain as it is.


Note: All other system fields and customfield values remain as it is and it is working as expected.

So, could you please suggest on how to resolve issue only for attachments and comments?

    CommentAdd your comment...

    4 answers

    1.  
      2
      1
      0

      Thankyou Syed. It is working fine now after updating scripts as suggested below.

      1. Syed Majid Hassan

        Glad to hear that!


        Thanks

        Majid


      CommentAdd your comment...
    2.  
      1
      0
      -1

      Hello Syed Majid Hassan 

      After adding above script we are facing below issue.

      we have found a bug that due to this script, None of the customField values are getting updated during first sync in our Production. Once we trigger another update, then only customfield values are updated.

      Thanks,
      Kiran Barhanpure


        CommentAdd your comment...
      1.  
        1
        0
        -1

        Hello Majid,


        we have found a bug in above script.. all the process works well related to attachment and comments but during first sync activity none of the customFields values get updated. Only system fields get updated due to this provided script.


        Could you please provide a fix for this issue?


        Thanks,

        Sahil Yadav

        1. Syed Majid Hassan

          Hi Sahil, 

          If you review my script, it does not deal with any custom fields at all, as you would not expect it to. I have no idea about the configuration on your end regarding custom fields. But you can extend the script to include the custom fields, Or vice versa i.e. include my firstSync block in your existing code. 

          Hope it helps. 

          Thanks

          Majid

        2. Kiran Kalyani Barhanpure

          Hello Syed Majid Hassan 


          On the Amdocs side, we already have your provided scipt in firstSync, so the problem is that none of the customField values are getting updated during the first sync in our production. Once we trigger another update, then only custom field values are updated. If we remove your script, it works as expected. 

          So which part of your script is blocking sync changes in the first sync?

        3. Syed Majid Hassan

          If you review the firstSync block, it has no mention of any custom fields. 

          You need to add your custom fields within the firstSync block for them to be updated on the first event please. 


        4. Sahil Yadav

          Hello Majid,


          we have not added customfields in firstSync block for more than 2 years and still it worked before and Even today, if we remove your new script it works where we only simply mention script line as :


          issue.id = jiraIssue.id


          The only issue with above single line is it removes existing attachments and comments and thats why we are trying to add your script to avoid it. But it does not mean that we had to add all customFields in firstSync block.


          As soon as we add new lines provided here, it stops working. So there must be something that is creating problem by adding your scripts. Do let us know if you would like to setup a call with screen sharing to resolve this issue?

        CommentAdd your comment...
      2.  
        1
        0
        -1

        Hi Sahil Yadav,


        I was able to reproduce your scenario and resolve it. The video attachment has the details, but here is the script that I used in the Incoming (you will need to modify it to use the logic of your labels etc.):

        import com.atlassian.jira.component.ComponentAccessor
        
        if(firstSync){
           issue.projectKey   = "SYEDB" 
           issue.typeName     = nodeHelper.getIssueType(replica.type?.name, issue.projectKey)?.name ?: "Task"
           
           def issueManager = ComponentAccessor.issueManager
           def mainIssue = issueManager.getIssueByCurrentKey(replica.customFields."Majids Field"?.value)
         
            if (mainIssue){     
                // Connect through Exalate
                def issueKey = new com.exalate.basic.domain.BasicIssueKey(mainIssue.id, mainIssue.key)
                def hubObjVersion = new com.exalate.basic.domain.BasicSemanticVersion(1, 0, 0);
                def hubObjectHelperFactory = com.atlassian.jira.component.ComponentAccessor
                  .getOSGiComponentInstanceOfType(com.exalate.api.hubobject.IHubObjectHelperFactory.class)
                def hubObjectHelper = hubObjectHelperFactory.get(hubObjVersion)
                def hubIssue = hubObjectHelper.getHubIssueOnOutgoingProcessor(issueKey)
                hubIssue.getProperties().each { k, v ->
                    issueBeforeScript[k] = v
                    if (v instanceof Map) {
                        def newV = [:]
                        newV.putAll(v)
                        issue[k] = newV
                    } else {
                        issue[k] = v
                    }
                }
                hubIssue.entrySet().each { entry ->
                   def k = entry.key
                   def v = entry.value
                   issueBeforeScript.putAll([k:v])
                   issue.putAll([k:v])
                }
                issueBeforeScript.id = null
                issue.id = mainIssue.id
                issue.key = mainIssue.key
                issue.customKeys.somethingIsChanged = true
        
                // take care of comments, attahchments and workLogs:
                replica.comments.each { replicaComment ->
                    // Check if the comment already exists in the local issue based on author email, creation date, and content
                    def existingComment = issue.comments.find { 
                        it.body == replicaComment.body
                    }
                    if (existingComment) {
                        def trace = new com.exalate.basic.domain.BasicNonPersistentTrace()
                         .setType(com.exalate.api.domain.twintrace.TraceType.COMMENT)
                         .setToSynchronize(true)
                         .setLocalId(existingComment.id as String) 
                         .setRemoteId(replicaComment.remoteId as String)
                         .setAction(com.exalate.api.domain.twintrace.TraceAction.NONE)
                        traces.add(trace)
                    }
                }
                replica.attachments.each { replicaAttachment ->
        
                    def existingAttachment = issue.attachments.find {
                        it.filename == replicaAttachment.filename &&
                        it.filesize == replicaAttachment.filesize
                    }
                
                    if (existingAttachment) {
                        def trace = new com.exalate.basic.domain.BasicNonPersistentTrace()
                            .setType(com.exalate.api.domain.twintrace.TraceType.ATTACHMENT)
                            .setToSynchronize(true)
                            .setLocalId(existingAttachment.id as String) 
                            .setRemoteId(replicaAttachment.remoteId as String)
                            .setAction(com.exalate.api.domain.twintrace.TraceAction.NONE)
                        traces.add(trace)
                    }
                    return issueKey
                }
            }
        }
        issue.summary      = replica.summary
        issue.description  = replica.description
        issue.comments     = commentHelper.mergeComments(issue, replica)
        issue.attachments  = attachmentHelper.mergeAttachments(issue, replica)
        issue.labels       = replica.labels


        Video explanation:


        Hope it helps. 


        Thanks

        Majid


          CommentAdd your comment...