2
1
0

Dear community,

We´re trying to sync issues between two server instances (Jira core to JSM), where the Jira Core is the master system sending data to JSM.
Within Jira core we have a dedicated custom field where we declare which issue type (and corresponding customer request type) should be created on the JSM side.

However, no matter what we try to do, we end up having issues and the sync doesn´t work.

The logic:


If customfield value = A, create an incident and set the customer request type = A
If customfield value = B, create an change request and set the customer request type = B

If customfield value = C, create an problem and set the customer request type = C

If customfield value = D, create an task and set the customer request type = D

Currently we´re trying to send values from the sender side and have the decision in the incoming script of the recipient Jira instance.


if(replica.customFields."type of issue" == "Problem") {
  issue.projectKey   = "SYNC"
  issue.typeName     = "Fault"
  issue.customFields."Customer Request Type" = "Problem"
}
else if (replica.customFields."type of issue" == "Request") {
  issue.projectKey   = "SYNC"
  issue.typeName     = "Request"
  issue.customFields."Customer Request Type" = "Request"
}
else if (replica.customFields."type of issue" == "Change") {
  issue.projectKey   = "SYNC"
  issue.typeName     = "Change"
  issue.customFields."Customer Request Type" = "Change request"
}
else (replica.customFields."type of issue" == "Task") {
  issue.projectKey   = "SYNC"
  issue.typeName     = "Project issue"
  issue.customFields."Customer Request Type" = "Ordinary task"
}


Can anyone tell me how the incoming script of the recipient side should look like?

Thank you in advance,
Kind regards,
Peter

    CommentAdd your comment...

    2 answers

    1.  
      2
      1
      0

      Another variation on the question



      The problem is, if we have an issue with issue type corrective and customer request type corrective, and we move, on Jira Software, the sync issue to a unplaned support issue type, we need exalate to update the customer request type to unplaned support.

      Actually, this doesn't update that field, if we do a JQL we can find an Unplaned Support with Corrective customer request type. Which is impossible due to the configuration.

      Actually, the only solution we found is creating an automation which detects issue type field had changed, and changes the customer request type.

      1. Francis Martens (Exalate)


        Regarding the customer request type - it can always be set as part of the logic which changes the issue.type


        issue.type = replica.type
        
        def requestName = [
               // typename is mapped to request type
        
               "Bug" : "IT Help",
               "Improvement" : "Change request",
        
               
        ]
        // custom field 'request type' can have another name
        issue."Request Type".value = requestName[replica.type.name] ?: "Default Request"
        
        
      CommentAdd your comment...
    2.  
      1
      0
      -1

      Hello, Peter Pesta 
      Thanks for raising this on community!
      Have you tried either using the .value after customfield name in the full notation:

      if(replica.customFields."type of issue".value == "Problem") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Fault"
        issue.customFields."Customer Request Type".value = "Problem"
      }
      else if (replica.customFields."type of issue".value == "Request") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Request"
        issue.customFields."Customer Request Type".value = "Request"
      }
      else if (replica.customFields."type of issue".value == "Change") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Change"
        issue.customFields."Customer Request Type".value = "Change request"
      }
      else (replica.customFields."type of issue".value == "Task") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Project issue"
        issue.customFields."Customer Request Type".value = "Ordinary task"
      }

      Or using the shorthand customfield notation:

      if(replica."type of issue" == "Problem") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Fault"
        issue."Customer Request Type" = "Problem"
      }
      else if (replica."type of issue" == "Request") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Request"
        issue."Customer Request Type" = "Request"
      }
      else if (replica."type of issue" == "Change") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Change"
        issue."Customer Request Type" = "Change request"
      }
      else (replica."type of issue" == "Task") {
        issue.projectKey   = "SYNC"
        issue.typeName     = "Project issue"
        issue."Customer Request Type" = "Ordinary task"
      }

      Regards, Serhiy.

      1. Peter Pesta

        Hi Serhiy Onyshchenko ,

        Yes, we tried this but didn´t manage to get it working.
        Even tried .value.value as advised by Andrii.

        Regards,
        Peter

      2. Serhiy Onyshchenko

        Hello, Peter Pesta , did you get any errors?
        Have you tried placing a debug.error("special message") into either of the if blocks to check if the "if" blocks were working?

      3. Peter Pesta

        Hi Serhiy Onyshchenko,

        I do apologize for the delay, here´s the output:

        • Impact: ISSUE
        • Local entity: TESMOSD-562
        • Remote entity: SD-11636
        • Connection: mssr_to_icz2
        • Error type: Issue Tracker Error
        • Error Creation Time: 2021-10-14 14:20:41.0
        • Error Detail Message: Cannot set the Customer request type. You can assign only string value to a custom field. The assigned value was com.exalate.basic.domain.hubobject.v1.BasicHubOption
        • Error Stack Trace: com.exalate.api.exception.IssueTrackerException: Cannot set the Customer request type. You can assign only string value to a custom field. The assigned value was com.exalate.basic.domain.hubobject.v1.BasicHubOption at com.exalate.node.hubobject.v1_3.NodeHubObjectConversionService.getNodeVpOrigin(NodeHubObjectConversionService.java:1928) at com.exalate.node.hubobject.v1_3.NodeHubObjectConversionService.getNodeCustomFieldValue(NodeHubObjectConversionService.java:1434) at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateCustomFieldWith(NodeHubIssueHelper.java:1407) at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateCustomFieldsWith(NodeHubIssueHelper.java:1386) at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.applyFields(NodeHubIssueHelper.java:1240) at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateIssueWith(NodeHubIssueHelper.java:883) at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateIssueWith(NodeHubIssueHelper.java:780) at com.exalate.compatibility.HubObjectHelperAdapter.updateNodeIssueWith(HubObjectHelperAdapter.java:61) at com.exalate.hubobject.v1_2.HubObjectHelper.updateNodeIssueWith(HubObjectHelper.java:352) at com.exalate.processor.jira.JiraChangeIssueProcessor.applyProcessorResult(JiraChangeIssueProcessor.java:311) at com.exalate.processor.jira.JiraChangeIssueProcessor.changeIssue(JiraChangeIssueProcessor.java:201) at com.exalate.replication.request.UpdateIssueSyncRequestState.transition(UpdateIssueSyncRequestState.java:118) at com.exalate.replication.request.UpdateIssueSyncRequestState.transition(UpdateIssueSyncRequestState.java:36) at com.exalate.replication.in.RequestProcessorService.processSyncRequest(RequestProcessorService.java:320) at com.exalate.replication.in.RequestProcessorService.processSyncRequestsForIssue(RequestProcessorService.java:190) at com.exalate.replication.in.RequestProcessorService.processSyncRequests(RequestProcessorService.java:127) at com.exalate.replication.in.RequestWorker$1.run(RequestWorker.java:83) at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.lambda$executeHandlingLocks$0(ClusteredSensitiveExecutorService.java:31) at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:52) at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:29) at com.exalate.replication.in.RequestWorker.run(RequestWorker.java:72) 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)
        • Incoming sync data:

        Summary: customer request type test v4Entity Key: SD-11636(id: 25605)Encoded payload: {"version":{"major":1,"minor":15,"patch":0},"hubIssue":{"components":[],"attachments":[],"voters":[],"customFields":{"Typ požiadavky":{"id":11901.0,"name":"Typ požiadavky","uid":"11901","type":"OPTION","value":{"id":"11607","sequence":1.0,"value":"Žiadosť o školenie a metodiku","disabled":false,"childOptions":[]}},"E-mail":{"id":11200.0,"name":"E-mail","uid":"11200","description":"","type":"STRING"},"Úroveň problému":{"id":11806.0,"name":"Úroveň problému","uid":"11806","type":"OPTION","value":{"id":"11515","sequence":2.0,"value":"Nekritický problém","disabled":false,"childOptions":[]}},"Prostredie":{"id":11805.0,"name":"Prostredie","uid":"11805","type":"OPTION","value":{"id":"11516","sequence":2.0,"value":"Integračné","disabled":false,"childOptions":[]}}},"project":{"idStr":"10200","key":"SD","name":"Service Desk","lead":{"key":"helpdesk","active":true,"email":"domena@xxxxx.sk","displayName":"Systém JIRA","username":"system.jira"},"versions":[],"components":[]},"watchers":[],"fixVersions":[],"key":"SD-11636","summary":"customer request type test v4","comments":[],"internalMap":{},"priority":{"id":"10100","name":"Nie je určená","description":""},"labels":[],"customKeys":{},"workLogs":[],"affectedVersions":[],"entityProperties":{}},"issueUrl":"https://jirat.xxxxxx.sk/browse/SD-11636"}

      4. Peter Pesta

        Hi Serhiy Onyshchenko,

        Here´s the incoming script on the receivers side:

        if(firstSync){

           issue.projectKey   = "TESMOSD"

           // Set type name from source issue, if not found set a default

           //issue.typeName     = nodeHelper.getIssueType(replica.typeName)?.name ?: "Fault"

           issue.typeName     = nodeHelper.getIssueType(replica.type?.name, issue.projectKey)?.name ?: "Fault"

        }

        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."Úroveň problému".value = "Závažný problém"

        issue.customFields."Zadávateľ".value = "Zakaznik"

        //issue.customFields."e-mail"?.value = replica.customFields."E-mail"?.value

        issue.customFields."Úroveň problému".value = replica.customFields."Úroveň problému".value

        issue.customFields."Prostredie".value = replica.customFields."Prostredie".value

        //issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value ?: "Problém"


        if(replica.customFields."Typ požiadavky".value == "Problém") {

          issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value

          issue.projectKey   = "TESMOSD"

          issue.typeName     = "Fault"

        }

        else if (replica.customFields."Typ požiadavky".value == "Žiadosť o školenie a metodiku") {

         issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value

          issue.projectKey   = "TESMOD"

          issue.typeName     = "Task"

        }

        else if (replica.customFields."Typ požiadavky".value == "Žiadosť o zmenu (RFC)") {

          issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value

          issue.projectKey   = "TESMOD"

          issue.typeName     = "Change"

        }

        else if (replica.customFields."Typ požiadavky".value == "Úloha z pracovného stretnutia") {

          issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value

          issue.projectKey   = "TESMOD"

          issue.typeName     = "Project issue"

        }


        //issue.customFields."Telefonický kontakt (new)"?.value = replica.customFields."Telefónne číslo".value

        //issue.customFields."e-mail"?.value = replica.customFields."E-mail".value


        /*

        User Synchronization (Assignee/Reporter)


        Set a Reporter/Assignee from the source side, if the user can't be found set a default user

        You can use this approach for custom fields of type User

        def defaultUser = nodeHelper.getUserByEmail("default@idalko.com")

        issue.reporter = nodeHelper.getUserByEmail(replica.reporter?.email) ?: defaultUser

        issue.assignee = nodeHelper.getUserByEmail(replica.assignee?.email) ?: defaultUser

        */


        /*

        Comment Synchronization


        Sync comments with the original author if the user exists in the local instance

        Remove original Comments sync line if you are using this approach

        issue.comments = commentHelper.mergeComments(issue, replica){ it.executor = nodeHelper.getUserByEmail(it.author?.email) }

        */


        /*

        Status Synchronization


        Sync status according to the mapping [remote issue status: local issue status]

        If statuses are the same on both sides don't include them in the mapping

        def statusMapping = ["Open":"New", "To Do":"Backlog"]

        def remoteStatusName = replica.status.name

        issue.setStatus(statusMapping[remoteStatusName] ?: remoteStatusName)

        */


        /*

        Custom Fields


        This line will sync Text, Option(s), Number, Date, Organization, and Labels CFs

        For other types of CF check documentation

        issue.customFields."CF Name".value = replica.customFields."CF Name".value

        */

      5. Serhiy Onyshchenko

        Hello, Peter Pesta , please try:

        if(replica.customFields."Typ požiadavky".value.value == "Problém") {
        
          issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value.value
        
          issue.projectKey   = "TESMOSD"
        
          issue.typeName     = "Fault"
        
        }
        
        else if (replica.customFields."Typ požiadavky".value.value == "Žiadosť o školenie a metodiku") {
        
         issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value.value
        
          issue.projectKey   = "TESMOD"
        
          issue.typeName     = "Task"
        
        }
        
        else if (replica.customFields."Typ požiadavky".value.value == "Žiadosť o zmenu (RFC)") {
        
          issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value.value
        
          issue.projectKey   = "TESMOD"
        
          issue.typeName     = "Change"
        
        }
        
        else if (replica.customFields."Typ požiadavky".value.value == "Úloha z pracovného stretnutia") {
        
          issue.customFields."Customer Request Type".value = replica.customFields."Typ požiadavky"?.value.value
        
          issue.projectKey   = "TESMOD"
        
          issue.typeName     = "Project issue"
        
        }

        The problem is that Typ požiadavky is a select list, which has both option id and option text (value).
        Regards, Serhiy.

      6. Peter Pesta

        Hi Serhiy Onyshchenko ,

        Thank you very much, this helped a lot and it´s working fine on the testing environment. However, once I´ve staged the settings to the production env, it´s malfunctioning and the behaviour is strange.

        If I enter the value A into the custom field "Typ poziadavky" then the sync works fine, if I enter value B into the same custom field, the data are not being sent (checked the payload, the values are not within the sent file).
        Have to admit that the custom field "typ poziadavky" was created shortly before I´ve set up the synchronization, but it´s working fine for one value, not for the other. Also, I´ve performed an background re-index with no success.

        Guess an deeper analysis would be necessary, I also have the support.zip files ready.

        Regards,
        Peter

      CommentAdd your comment...