The Exalate team will be on holiday for the coming days - returning Jan 4
Enjoy & stay safe

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The main requirement for this use case is to maintain the issue hierarchy while Exalating issues between ServiceNow and Azure DevOps (bi-directionally).


The Incident → Incident Task relationship in ServiceNow must be reflected as Task → Issue relationship on Azure DevOps, and vice versa. The following depicts what we are trying to achieve here:

Image Modified

Let us first consider the ServiceNow to Azure DevOps side:


  • ServiceNow outgoing scripts need to ensure that the both the Incident and Incident_task tables are catered for:


    Code Block
    languagegroovy
    themeEmacs
    collapsetrue
    if(entity.tableName == "incident") {
        replica.key            = entity.key
        replica.summary        = entity.short_description
        replica.description    = entity.description
        replica.attachments    = entity.attachments
        replica.comments       = entity.comments
        replica.state          = entity.state
        replica.entityType = "incident"
    }
    if(entity.tableName == "incident_task") {
        replica.key            = entity.key
        replica.summary        = entity.short_description
        replica.description    = entity.description
        replica.attachments    = entity.attachments
        replica.comments       = entity.comments
        replica.state          = entity.state
    
        if (entity?.incident)    
            replica.parentid = nodeHelper.getTableByLink(entity.incident.link).sys_id
        replica.entityType = "incident_task"   
    }
  • On the Azure DevOps side, we need to firstly map the issue types. This can be easily done using the following code segment on the Incoming Script on the Azure DevOps side:

    Code Block
    languagegroovy
    themeEmacs
    collapsetrue
       if (replica.entityType == "incident")
            workItem.typeName = "Task";
       else if (replica.entityType == "incident_task")
            workItem.typeName = "Issue";
  • The next step on the Azure DevOps side would be populate the parent link in order to ensure that the hierarchy is maintained. This can be done via the following code snippet, that uses the getLocalIssueKeyFromRemoteId method, added in the Azure DevOps incoming scripts:

    Code Block
    languagegroovy
    themeEmacs
    collapsetrue
    if(replica.parentid){
        def localParent = syncHelper.getLocalIssueKeyFromRemoteId(replica.parentid, 'incident').id
        if(localParent)
            issue.parentId = localParent
        else 
           throw new com.exalate.api.exception.IssueTrackerException("Cant field parent with id " + replica.parentId)
    }

Let us now consider the Azure DevOps to ServiceNow direction:

  • The key to maintaining the hierarchy here is passing the parentid field in the outgoing script on the Azure DevOps side:

    Code Block
    languagegroovy
    themeEmacs
    replica.parentId = workItem.parentId



  • Next we need to ensure that the correct mappings are present on the ServiceNow Incoming scripts:

    Code Block
    languagegroovy
    themeEmacs
    collapsetrue
        if (replica.type.name == "Task")
            entity.tableName = "incident"
        else if (replica.type.name == "Issue")
            entity.tableName = "incident_task"
  • And to close this off, we will employ getLocalIssueKeyFromRemoteId to fetch the local parent and maintain the hierarchy:

    Code Block
    languagegroovy
    themeEmacs
    entity.incident  = syncHelper.getLocalIssueKeyFromRemoteId(replica.parentId)?.idStr


The entire code from the ServiceNow side is here, and for Azure DevOps is here


Please review the following video to see the use case in action:

View file
nameSNOW_ADO_Bi-directional Hierarchy.mp4
height250



Questions

Questions List
filterrecent
asktrue
include-topicsany
spaceexacom

...