JIRA CLOUD

This article shows how to set a fixed Request type when syncing Jira Cloud Service Desk.

Introduction

When syncing between two Jira Service Desk instances you can sync all tickets form one SD to one specific Request Type on the other side.

Destination side  

Add the code below to the new line in the end of the Incoming sync for new issues(Create processor)

Set the desired request type in the script settings as showed below.

 // SETTINGS: set the relevant request type below
def customerRequestType = "IT Help"
// END: SETTINGS
// CUSTOMER REQUEST TYPE SYNC
def requestType = ({
    final def injector = play.api.Play$.MODULE$.current().injector()
    def issueLevelError = { String msg ->
        new com.exalate.api.exception.IssueTrackerException(msg)
    }
    def issueLevelError2 = { String msg, Throwable e ->
        new com.exalate.api.exception.IssueTrackerException(msg, e)
    }
    def fn = { Closure<?> closure ->
        new scala.runtime.AbstractFunction1<Object, Object>() {
            @Override
            Object apply(Object p) {
                return closure.call(p)
            }
        }
    }
    def fn2 = { Closure<?> closure ->
        new scala.runtime.AbstractFunction2<Object, Object, Object>() {
            @Override
            Object apply(Object p1, Object p2) {
                return closure.call(p1, p2)
            }
        }
    }
    def await = { scala.concurrent.Future<?> f -> scala.concurrent.Await$.MODULE$.result(f, scala.concurrent.duration.Duration$.MODULE$.Inf()) }
    def orNull = { scala.Option<?> opt -> opt.isDefined() ? opt.get() : null }
    def none = { scala.Option$.MODULE$.<?>empty() }
    def pair = { l, r -> scala.Tuple2$.MODULE$.<?, ?>apply(l, r) }
    def seq =  { ... ts ->
        def list = Arrays.asList(ts)
        def scalaBuffer = scala.collection.JavaConversions.asScalaBuffer(list)
        scalaBuffer.toSeq()
    }
    def seqPlus = { scala.collection.Seq<?> tsLeft, ... tsRight ->
        def list = Arrays.asList(tsRight)
        def scalaBuffer = scala.collection.JavaConversions.asScalaBuffer(list)
        scala.collection.Seq$.MODULE$
                .newBuilder()
                .$plus$plus$eq(tsLeft)
                .$plus$plus$eq(scalaBuffer)
                .result()
    }
    def paginateInternal
    paginateInternal = { Integer offset, Integer limit, scala.collection.Seq<?> result, scala.runtime.AbstractFunction2<Integer, Integer, ?> nextPageFn, scala.runtime.AbstractFunction1<?, Integer> getTotalFn ->
        def page = nextPageFn.apply(offset, limit)
        def total = getTotalFn.apply(page)
        def last = total < limit
        def newResult = seqPlus(result, page)
        if (last) {
            newResult
        } else {
            paginateInternal(offset + limit, limit, newResult, nextPageFn, getTotalFn)
        }
    }
    def paginate = { Integer limit, scala.runtime.AbstractFunction2<Integer, Integer, ?> nextPageFn, scala.runtime.AbstractFunction1<?, Integer> getTotalFn ->
        scala.collection.Seq<?> resultSeq = paginateInternal(0, limit, seq(), nextPageFn, getTotalFn)
        scala.collection.JavaConversions.bufferAsJavaList(resultSeq.toBuffer())
    }
    def getGeneralSettings = {
        def gsp = injector.instanceOf(com.exalate.api.persistence.issuetracker.jcloud.IJCloudGeneralSettingsPersistence.class)
        def gsOpt = await(gsp.get())
        def gs = orNull(gsOpt)
        gs
    }
    final def gs = getGeneralSettings()

    def removeTailingSlash = { String str -> str.trim().replace("/+\$","") }
    final def jiraCloudUrl = removeTailingSlash(gs.issueTrackerUrl)

    def getServiceDesks = {
        //noinspection GroovyAssignabilityCheck
        def _serviceDeskPages = paginate(
                50,
                fn2 { Integer offset, Integer limit ->
                    def queryParams = seq(
                            pair("start", offset as String),
                            pair("limit", limit as String)
                    )
                    def qParamsStr = scala.collection.JavaConversions
                            .bufferAsJavaList(
                            queryParams
                                    .tail()
                                    .tail()
                                    .<scala.Tuple2<String, String>>toBuffer()
                    )
                            .inject ("") { resultStr, qp ->
                        resultStr + "&"+ qp._1()+"="+qp._2()
                    }
                    def response
                    try {
                        //noinspection GroovyAssignabilityCheck
                        response = await(await(httpClient.authenticate(
                                none(),
                                httpClient
                                        .ws()
                                        .url(jiraCloudUrl+"/rest/servicedeskapi/servicedesk")
                                        .withQueryString(queryParams)
                                        .withMethod("GET"),
                                gs
                        )).get())
                    } catch (Exception e) {
                        throw issueLevelError2(
                                "Unable to get the service desks, please contact Exalate Support: " +
                                        "\nRequest: GET /rest/servicedeskapi/servicedesk?start="+ offset +"&limit="+limit + qParamsStr +
                                        "\nError: " + e.message
                                , e
                        )
                    }
                    if (response.status() != 200) {
                        throw issueLevelError(
                                "Can not get the service desks (status "+ response.status() +"), please contact Exalate Support: " +
                                        "\nRequest: GET /rest/servicedeskapi/servicedesk?start="+ offset +"&limit="+limit + qParamsStr+
                                        "\nResponse: "+ response.body()
                        )
                    }
                    def resultStr = response.body()
                    groovy.json.JsonSlurper s = new groovy.json.JsonSlurper()
                    def resultJson
                    try {
                        resultJson = s.parseText(resultStr)
                    } catch (Exception e) {
                        throw issueLevelError2("Can not parse the service desk json, please contact Exalate Support: " + resultStr, e)
                    }

                    /*
{
  "_expands": [],
  "size": 3,
  "start": 3,
  "limit": 3,
  "isLastPage": false,
  "_links": {
    ...
  },
  "values": [
    {
      "id": "10001",
      "projectId": "11001",
      "projectName": "IT Help Desk",
      "projectKey": "ITH",
      "_links": {
        "self": "https://your-domain.atlassian.net/rest/servicedeskapi/servicedesk/10001"
      }
    },
    ...
  ]
}
                    */
                    if (!(resultJson instanceof Map)) {
                        throw issueLevelError("Boards json has unrecognized structure, please contact Exalate Support: " + resultStr)
                    }
                    resultJson as Map<String, Object>
                },
                fn { Map<String, Object> page -> (page.values as List<Map<String, Object>>).size() }
        )
        _serviceDeskPages
                .collect { it.get("values") as List<Map<String, Object>> }
                .flatten()
    }

    def getRequestTypesForServiceDesk = { String sdId ->
        //noinspection GroovyAssignabilityCheck
        def _serviceDeskPages = paginate(
                50,
                fn2 { Integer offset, Integer limit ->
                    def queryParams = seq(
                            pair("start", offset as String),
                            pair("limit", limit as String)
                    )
                    def qParamsStr = scala.collection.JavaConversions
                            .bufferAsJavaList(
                            queryParams
                                    .tail()
                                    .tail()
                                    .<scala.Tuple2<String, String>>toBuffer()
                    )
                            .inject ("") { resultStr, qp ->
                        resultStr + "&"+ qp._1()+"="+qp._2()
                    }
                    def response
                    try {
                        //noinspection GroovyAssignabilityCheck
                        response = await(await(httpClient.authenticate(
                                none(),
                                httpClient
                                        .ws()
                                        .url(jiraCloudUrl+"/rest/servicedeskapi/servicedesk/$sdId/requesttype".toString())
                                        .withQueryString(queryParams)
                                        .withMethod("GET"),
                                gs
                        )).get())
                    } catch (Exception e) {
                        throw issueLevelError2(
                                "Unable to get the request types for the service desk $sdId, please contact Exalate Support: ".toString() +
                                        "\nRequest: GET /rest/servicedeskapi/servicedesk/$sdId/requesttype?start="+ offset +"&limit="+limit + qParamsStr +
                                        "\nError: " + e.message
                                , e
                        )
                    }
                    if (response.status() != 200) {
                        throw issueLevelError(
                                "Can not get request types for the service desk $sdId (status ".toString()+ response.status() +"), please contact Exalate Support: " +
                                        "\nRequest: GET /rest/servicedeskapi/servicedesk/$sdId/requesttype?start="+ offset +"&limit="+limit + qParamsStr+
                                        "\nResponse: "+ response.body()
                        )
                    }
                    def resultStr = response.body()
                    groovy.json.JsonSlurper s = new groovy.json.JsonSlurper()
                    def resultJson
                    try {
                        resultJson = s.parseText(resultStr)
                    } catch (Exception e) {
                        throw issueLevelError2("Can not parse the service desk request types json, please contact Exalate Support: " + resultStr, e)
                    }

                    /*
{
  "_expands": [],
  "size": 3,
  "start": 3,
  "limit": 3,
  "isLastPage": false,
  "_links": {
    ...
  },
  "values": [
    {
      "_expands": [],
      "id": "11001",
      "_links": { ... },
      "name": "Get IT Help",
      "description": "Get IT Help",
      "helpText": "Please tell us clearly the problem you have within 100 words.",
      "issueTypeId": "12345",
      "serviceDeskId": "28",
      "groupIds": [
        "12"
      ],
      "icon": {
        ...
      }
    },
    ...
  ]
}
                    */
                    if (!(resultJson instanceof Map)) {
                        throw issueLevelError("Service desk request types json has unrecognized structure, please contact Exalate Support: " + resultStr)
                    }
                    resultJson as Map<String, Object>
                },
                fn { Map<String, Object> page -> (page.values as List<Map<String, Object>>).size() }
        )
        _serviceDeskPages
                .collect { it.get("values") as List<Map<String, Object>> }
                .flatten()
    }

    def _serviceDesks = getServiceDesks()

    // Finding the service desk for local project
    def _sd = _serviceDesks.find { it.projectKey == issue.projectKey }
    if (_sd == null) {
        return null
    }

    def _requestTypes = getRequestTypesForServiceDesk(_sd.id as String)
    def _requestType = _requestTypes.find { it.issueTypeId == nodeHelper.getIssueType(issue.typeName).id && it.name == customerRequestType }
    if (_requestType == null) {
        return null
    }

    serviceDeskHelper.getRequestTypeById(_sd.id as String, _requestType.id as String)
})()
if (requestType != null) {
    issue.customFields."Request Type".value = requestType
}
// END: CUSTOMER REQUEST TYPE SYNC

See also