2
1
0

Hi Team,

We have a requirement that:

1. Project A( Source project)
2. Project B, C and D ( destination projects)

Project A- Bug1 exalated to project B,C and D with different connections.

Now

Bug1 ----------> Project B(Bug1)
-----------> Project C (Bug1)
-----------> project D(Bug1)

Based on the destination bugs, source bug1 should change the status.

Till now we have done for Bug to Bug mapping but now we need for one bug and multiple destination projects bugs.

Please help us as quickly as possible.

Thanks
Venkatesh.

    CommentAdd your comment...

    1 answer

    1.  
      2
      1
      0

      Based on the destination bugs, source bug1 should change the status.

      What are the business rules


      1. Venkatesh Pokala

        1. Here I have one source project and 3 destinations projects.
        2. I created the 3 different connections with status mapping ( SOURCE_to_DESTProject1, SOURCE_to_DESTProject2 and SOURCE_to_DESTProject3).
        3. From Source BUG1 - Exalated by using connection SOURCE_to_DESTProject1
        4. From the same Source BUG1- Exalated by using connection SOURCE_to_DESTProject2
        5. From the same Source BUG1- Exalated by using connection SOURCE_to_DESTProject3
        6. So, now one Source BUG1 cloned to 3 Bugs to 3 different projects.
        7. My CASE If all 3 BUGS moved to "IN PROGRESS" then SOURCE BUG1 SHOULD MOVE TO "IN PROGRESS"

        Hope this will clear everything.

        Thanks,
        Venkatesh.

      2. Francis Martens (Exalate)

        What you can do is to track the remote status in 3 custom fields on the source bug
        When all 3 turn to 'In progress', you can transition the local also.

        Ie 


        On connection 1 - add in your incoming sync

        issue.customFields."Remote Status Connection 1".value = replica.status.name



        On connection 2 - add in your incoming sync

        issue.customFields."Remote Status Connection 2".value = replica.status.name




        On connection 3 - add in your incoming sync

        issue.customFields."Remote Status Connection 3".value = replica.status.name



        And then in each connection add something like

        if (replica.status.name == "In Progress" && issue.customFields."Remote Status Connection 2".value == "In Progress" && issue.customFields."Remote Status Connection 3".value == "In Progress") {   issue.status = "In Progress
        }
      3. Francis Martens (Exalate)

        Hi Venkatesh Pokala

        I see you raised the same question on the Atlassian community site, which is totally fine
        https://community.atlassian.com/t5/Jira-discussions/One-bug-should-clone-to-many-other-projects-locally/m-p/1490575

        I'm just wondering if my suggestion here is not sufficient for you to continue with your implementation.

      4. Venkatesh Pokala

        Hi Francis Martens (Exalate),


           I tried your suggested way, but not working as expected. See the below logs and other script details. I really need your quick help to proceed further.


         Impact: ISSUELocal entity: F6755-5Remote entity: LAX20-225Connection: F6755_to_LAX20Error type: Incoming sync: update sync errorError Creation Time: 2020-08-05 23:23:37.384Error Detail Message: Script error for issue F6755-5. Details: Cannot get property 'Remote Status RAX20' on null object. 
        Error line: Script109.groovy:39 Error Stack Trace: com.exalate.api.exception.script.ChangeProcessorException: Script error for issue F6755-5. Details: Cannot get property 'Remote Status RAX20' on null object. 
        Error line: Script109.groovy:39
        	at com.exalate.error.services.ScriptExceptionCategoryService$.wrapAsChangeProcessorException(ScriptExceptionCategoryService.scala:58)
        	at com.exalate.processor.jira.JiraChangeIssueProcessor.changeIssue(JiraChangeIssueProcessor.java:163)
        	at com.exalate.replication.request.UpdateIssueSyncRequestState.transition(UpdateIssueSyncRequestState.java:115)
        	at com.exalate.replication.request.UpdateIssueSyncRequestState.transition(UpdateIssueSyncRequestState.java:33)
        	at com.exalate.replication.in.RequestProcessorService.processSyncRequest(RequestProcessorService.java:324)
        	at com.exalate.replication.in.RequestProcessorService.processSyncRequestsForIssue(RequestProcessorService.java:194)
        	at com.exalate.replication.in.RequestProcessorService.processSyncRequests(RequestProcessorService.java:131)
        	at com.exalate.replication.in.RequestWorker$1.run(RequestWorker.java:88)
        	at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService$1.run(ClusteredSensitiveExecutorService.java:32)
        	at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService$1.run(ClusteredSensitiveExecutorService.java:28)
        	at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:48)
        	at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:28)
        	at com.exalate.replication.in.RequestWorker.run(RequestWorker.java:78)
        	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        	at java.lang.Thread.run(Thread.java:748)
        Caused by: com.exalate.api.exception.script.ScriptException: Cannot get property 'Remote Status RAX20' on null object. 
        Error line: Script109.groovy:39
        	at com.exalate.error.services.ScriptExceptionCategoryService.categorizeProcessorAndIssueTrackerExceptionsIntoScriptExceptions(ScriptExceptionCategoryService.scala:36)
        	at com.exalate.processor.ExalateProcessor.executeProcessor(ExalateProcessor.java:48)
        	at com.exalate.processor.jira.JiraChangeIssueProcessor.executeChangeProcessor(JiraChangeIssueProcessor.java:236)
        	at com.exalate.processor.jira.JiraChangeIssueProcessor.changeIssue(JiraChangeIssueProcessor.java:139)
        	... 18 more
        Caused by: javax.script.ScriptException: javax.script.ScriptException: java.lang.NullPointerException: Cannot get property 'Remote Status RAX20' on null object
        	at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:151)
        	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
        	at com.exalate.processor.ExalateProcessor.execute(ExalateProcessor.java:73)
        	at com.exalate.processor.ExalateProcessor.executeProcessor(ExalateProcessor.java:46)
        	... 20 more
        Caused by: javax.script.ScriptException: java.lang.NullPointerException: Cannot get property 'Remote Status RAX20' on null object
        	at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:348)
        	at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:145)
        	... 23 more
        Caused by: java.lang.NullPointerException: Cannot get property 'Remote Status RAX20' on null object
        	at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:57)
        	at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:168)
        	at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
        	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
        	at Script109.run(Script109.groovy:39)
        	at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:345)
        	... 24 more
        Incoming sync data:  Summary:  bug multipleEntity Key:  LAX20-225(id: 344880)Encoded payload:  {"version":{"major":1,"minor":15,"patch":0},"hubIssue":{"components":[],"attachments":[],"voters":[],"customFields":{"ComponentA":{"id":14300.0,"name":"ComponentA","type":"OPTION","value":{"id":19031.0,"sequence":1.0,"value":"circle or SPC","disabled":false,"childOptions":[]}},"ComponentB":{"id":14301.0,"name":"ComponentB","type":"OPTION","value":{"id":19040.0,"sequence":0.0,"value":"APP","disabled":false,"childOptions":[]}},"Priority_HCP":{"id":10555.0,"name":"Priority_HCP","description":"","type":"OPTION","value":{"id":10675.0,"sequence":2.0,"value":"P3 (Low)","disabled":false,"childOptions":[]}},"Issue From":{"id":10560.0,"name":"Issue From","description":"Enter your account name. If issue from Support/Beta users, Kindly fill the ID Number field.","type":"OPTION","value":{"id":10712.0,"sequence":7.0,"value":"Beta","disabled":false,"childOptions":[]}}},"description":"test","project":{"id":17200.0,"key":"LAX20","name":"LAX20","lead":{"key":"fchua","active":true,"email":"Frederick.Chua@netgear.com","displayName":"Frederick Chua","username":"fchua"},"versions":[],"components":[]},"watchers":[],"fixVersions":[],"key":"LAX20-225","summary":"bug multiple","comments":[],"internalMap":{},"reporter":{"key":"pvenkatesh","active":true,"email":"Pokala.Venkatesh@netgear.com","displayName":"Venkatesh Pokala","username":"pvenkatesh"},"priority":{"id":"4","name":"Minor (P4)","description":"Minor loss of function, or other problem where easy workaround is present."},"labels":[],"customKeys":{},"workLogs":[],"issueType":{"id":"1","name":"Bug","description":"A problem which impairs or prevents the functions of the product."},"affectedVersions":[],"entityProperties":{},"status":{"id":"1","name":"OPEN","description":"The issue is open and ready for the assignee to start work on it.","category":{"id":2.0,"key":"new","name":"New"}}},"issueUrl":"https://njsdev.netgear.com/browse/LAX20-225"}
        Script error for issue F6755-5. Details: Cannot get property 'Remote Status RAX20' on null object. Error line: Script109.groovy:39
        
        
        Incoming script
        if(firstSync && replica.project.key == "Dest1"){
        issue.projectKey = "SOURCE"
        issue.typeName = nodeHelper.getIssueType(replica.typeName)?.name ?: "Bug"
        }
        if(firstSync && replica.project.key == "SOURCE"){
        issue.projectKey = "Dest1"
        issue.typeName = nodeHelper.getIssueType(replica.typeName)?.name ?: "Bug"
        }
        if(replica.project.key == "Dest1"){
        //sue.projectKey = "Dest2"
        def statusMapping = ["New":"New", "OPEN":"OPEN", "To Be Fixed":"To Be Fixed", "Fixed":"Fixed", "CTS-Fixed":"CTS-Fixed", "Pending":"Pending", "Re-Open":"Re-Open"]
        def remoteStatusName = replica.status.name
        
        if (issue.project.key == "SOURCE") {
        def remoteStatusDest1 = issue.customField."Remote Status Dest1".value
        def remoteStatusDest2 = issue.customField."Remote Status Dest2".value
        
        if (remoteStatusDest1 == "Rejected" && remoteStatusDest2 == "Rejected") {
        issue.status = "Rejected"
        }
        if (remoteStatusDest1 == "Closed" && remoteStatusDest2 == "Closed") {
        issue.status = "Closed"
        }
        }
        issue.setStatus(statusMapping[remoteStatusName] ?: remoteStatusName)
        
        }
        
        
        
        issue.summary = replica.summary
        issue.description = replica.description
        issue.labels = replica.labels
        issue.comments = commentHelper.mergeComments(issue, replica)
        issue.attachments = attachmentHelper.mergeAttachments(issue, replica)
        issue.customFields."ComponentA".value = replica.customFields."ComponentA"?.value
        issue.customFields."ComponentB".value = replica.customFields."ComponentB"?.value
        issue.customFields."Issue From".value = replica.customFields."Issue From"?.value
        issue.customFields."Priority_HCP".value = replica.customFields."Priority_HCP"?.value
        issue.customFields."16001".value = replica.status.name


        Please help me on this.


        Thanks,

        Venkatesh.

      5. Francis Martens (Exalate)

        The error message is

        > Cannot get property 'Remote Status RAX20' on null object

        The problem is on line 19 of your script.  You should inspect it there.
        Also your incoming script is using 'issue.customField'.  You should be careful as the customField array is named 'issue.customFields' (with an s)

        Please review

      6. Venkatesh Pokala

        Hi Francis Martens (Exalate),


          Seems like i'm closer now. Can you please me how to resolve the below error? 

        Cannot cast object 'OPEN' with class 'java.lang.String' to class 'com.exalate.api.domain.hubobject.v1_2.IHubStatus'. Error line: Script70.groovy:17

        In coming script

        if(firstSync && replica.project.key == "RAX20"){
           issue.projectKey   = "F6755"
           issue.typeName     = nodeHelper.getIssueType(replica.typeName)?.name ?: "Bug"
        }
        if(firstSync && replica.project.key == "F6755"){
           issue.projectKey   = "RAX20"
           issue.typeName     = nodeHelper.getIssueType(replica.typeName)?.name ?: "Bug"
        }
        //if(replica.project.key == "RAX20"){
           //def remoteStatusName = replica.status.name
          // def remoteStatusRAX20 = issue.customFields."Remote Status RAX20".value
           //def remoteStatusLAX20 = issue.customFields."Remote Status LAX20".value
        if (issue.project.key == "F6755") {
           def remoteStatusRAX20 = issue.customFields."Remote Status RAX20".value
           def remoteStatusLAX20 = issue.customFields."Remote Status LAX20".value
          if (replica.status.name == "OPEN" && issue.customFields."Remote Status LAX20".value == "OPEN") {   
            issue.status = "OPEN"  
        
        }
        }
        
           
        issue.summary      = replica.summary
        issue.description  = replica.description
        issue.labels       = replica.labels
        issue.comments     = commentHelper.mergeComments(issue, replica)
        issue.attachments  = attachmentHelper.mergeAttachments(issue, replica)
        issue.customFields."ComponentA".value = replica.customFields."ComponentA"?.value
        issue.customFields."ComponentB".value = replica.customFields."ComponentB"?.value
        issue.customFields."Issue From".value = replica.customFields."Issue From"?.value
        issue.customFields."Priority_HCP".value = replica.customFields."Priority_HCP"?.value
        //issue.customFields."16001".value = replica.status.name
        issue.customFields."Remote Status RAX20".value = replica.status.name
        //issue.customFields."Remote Status LAX20".value = replica.status.name
        
        


        Please help me

      7. Juan Grases

        Hi, the problem is on line:

        issue.status = "OPEN"  

        it should be:

        issue.setStatus("OPEN")

        Take into account that setStatus is case sensitive, so it would probably rather be:


        issue.setStatus("Open")
      8. Venkatesh Pokala

        Hi @Juan,


         Thanks a ton. It is working as expected.  One quick question, if I have multiple bugs with one source bug. Then I need to create a separate customfield for each connection?


        Thanks,

        Venkatesh. 

      CommentAdd your comment...