Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

We need scriptrunner script to retrieve "Time to first response"

Deleted user September 28, 2022

We need to figure out "Time to first response" and below are the details about jira details and custom field value that we are getting. Can you please suggest the logic that we need to write from this custom field value to retrieve the same:-

1) JIRA# SPSDT-68 (https://dev-jira.lamresearch.com/browse/SPSDT-68\)
2) On UI it shows #
-8mon
3) Custom field value that we are getting is below:-
SLAValue{completeSLAData=[], timeline=Timeline{events=[TimelineEvent

{date=2022-02-09T08:44:36.389Z, types=[START]}

]}, ongoingSLAData=OngoingSLAData{goalId=60, startTime=2022-02-09T08:44:36.389Z, paused=false, thresholdData=some(ThresholdData

{calculatedAt=2022-02-13T08:44:36.440Z, remainingTime=some(-338400051), thresholdsConfigChangeDate=2021-03-19T13:58:30.300Z, thresholdsConfigChangeMsEpoch=1616162310301}

)}, metricId=24, definitionChangeDate=1970-01-01T00:00:00.000Z, definitionChangeMsEpoch=0, goalsChangeDate=2021-04-30T18:23:16.240Z, goalsChangeMsEpoch=1619806996239, goalTimeUpdatedDate=2021-04-30T18:23:16.200Z, goalTimeUpdatedMsEpoch=1619806996199, metricCreatedDate=1616162310301, updatedDate=some(1644741876456)}

For the other jira the custom field value we are getting is different as explained below:-
1) JIRA# SPSDT-69(https://dev-jira.lamresearch.com/browse/SPSDT-69\)
2) On UI it shows #
-1mon
3) Custom field value that we are getting is below:-
SLAValue{completeSLAData=[CompleteSLAData{calendarName=Default 24/7 calendar, succeeded=false, goalTime=7200000, goalTimeUnits=some(SLAGoalRemainingTimeUnits

{weeks=0, remainingDaysWithinWeek=0, remainingMillisWithinDay=7200000, breached=false}

), elapsedTime=4930727580, remainingTime=some(-4923527580), remainingTimeUnits=some(SLAGoalRemainingTimeUnits

{weeks=7, remainingDaysWithinWeek=6, remainingMillisWithinDay=171527580, breached=true}

), startTime=2022-02-14T16:56:35.453Z, stopTime=2022-04-12T18:35:23.033Z}], timeline=Timeline{events=[TimelineEvent

{date=2022-02-14T16:56:35.453Z, types=[START]}

, TimelineEvent

{date=2022-04-12T18:35:23.033Z, types=[STOP]}

]}, ongoingSLAData=null, metricId=24, definitionChangeDate=1970-01-01T00:00:00.000Z, definitionChangeMsEpoch=0, goalsChangeDate=null, goalsChangeMsEpoch=null, goalTimeUpdatedDate=null, goalTimeUpdatedMsEpoch=null, metricCreatedDate=1616162310301, updatedDate=some(1649788524423)}

Can you suggest a logic for retrieving "Time to first response".

1 answer

0 votes
Ram Kumar Aravindakshan _Adaptavist_
Community Champion
September 29, 2022

Hi @[deleted]

For your requirement, you will need to use the REST Endpoint to invoke the SLA from the Service Desk's REST Service and need to filter the result with something like:-

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.RESTClient
import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate
getTimeToFirstResponse { MultivaluedMap queryParams, body, HttpServletRequest request ->
def issueKey = queryParams.getFirst('issueKey')

def applicationProperties = ComponentAccessor.applicationProperties

final def baseUrl = applicationProperties.getString('jira.baseurl')
final def username = 'admin'
final def password = 'q'
final def headers = ['Authorization': "Basic ${"${username}:${password}".bytes.encodeBase64()}",
'X-ExperimentalApi': 'opt-in', 'Accept': 'application/json'] as Map

def http = new RESTClient(baseUrl)
http.setHeaders(headers)

def resp = http.get(path: "/rest/servicedeskapi/request/${issueKey}/sla") as HttpResponseDecorator

if (resp.status != 200) {
log.warn 'Commander did not respond with 200 for retrieving project list'
}

def issueJson = resp.data as Map

def totalValues = issueJson['values'] as List<Map>

def result = totalValues.findAll {it['name'] == 'Time to first response'}

def time = result['ongoingCycle']['startTime']['jira']

Response.ok(new JsonBuilder(time).toPrettyString()).build()
}

Please note that the sample code provided is not 100% exact to your environment. Hence, you will need to make the required modifications. 

Below is a screenshot filtered result that is returned:-

first_response_time.png

Below is a screenshot of the REST Endpoint configuration:-

rest_endpoing_config.png

Once you have obtained the result, you can pass the value to a Behaviour or Listener or whatever you want to use to invoke it.

I hope this helps to solve your question. :-)

Thank you and Kind regards,

Ram

Deleted user September 29, 2022

For Issue# SPSDT68 i got the below response 

2022-09-29 09:42:49,250 WARN [runner.ScriptBindingsManager]: Time:[ "2022-02-09T08:44:36.389+0000" ]

  • But in jira UI  it is showing -8months as shown in the attachment. Can you suggest why jira UI is not matching the result here?
  • Also i want the data in minutes can you suggest how we can ge it in minutes.

For Issue# SPSDT69 i got the below response '

2022-09-29 09:47:24,054 WARN [runner.ScriptBindingsManager]: Time:[ ]

  • There is no onGoingcycle in the payload only completedCycles. Below is the payload i get from api for this issue.

{
"id": "24",
"name": "Time to first response",
"_links": {"self": "https://dev-jira.lamresearch.com/rest/servicedeskapi/request/SPSDT-69/sla/24"},
"completedCycles": [ {
"startTime": {
"iso8601": "2022-02-14T08:56:35-0800",
"jira": "2022-02-14T16:56:35.453+0000",
"friendly": "14/Feb/22 8:56 AM",
"epochMillis": 1644857795453
},
"stopTime": {
"iso8601": "2022-04-12T11:35:23-0700",
"jira": "2022-04-12T18:35:23.033+0000",
"friendly": "12/Apr/22 11:35 AM",
"epochMillis": 1649788523033
},
"breached": true,
"goalDuration": {
"millis": 7200000,
"friendly": "2h"
},
"elapsedTime": {
"millis": 4930727580,
"friendly": "1,369h 38m"
},
"remainingTime": {
"millis": -4923527580,
"friendly": "-1,367h 38m"
}
}

  •  But in jira UI  it is showing -1months as shown in the attachment. Can you suggest why jira UI is not matching the result here?
Ram Kumar Aravindakshan _Adaptavist_
Community Champion
September 29, 2022

Hi @[deleted]

Can you please share the exact code that you have used?

If you have used the sample code template I provided in my previous comment; this will not be the result returned.

Instead, it will filter all these values and only return the start time, i.e. the start time, using the jira format.

Thank you and Kind regards,

Ram

Deleted user September 29, 2022

I am running the below code from Script console:-

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.RESTClient
import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

//@BaseScript CustomEndpointDelegate delegate
//getTimeToFirstResponse { MultivaluedMap queryParams, body, HttpServletRequest request ->
    def issueKey = 'SPSDT-69'

    def applicationProperties = ComponentAccessor.applicationProperties

    final def baseUrl = applicationProperties.getString('jira.baseurl')
    //final def username = 'tiwarab'
    //final def password = 'q'
    final def headers = ['Authorization': "Bearer MDI5NjAxODc5ODE5Olvt0d7GCC2o790uYGHZ3AuHp4eo",
                         'X-ExperimentalApi': 'opt-in', 'Accept': 'application/json'] as Map

    def http = new RESTClient(baseUrl)
    http.setHeaders(headers)

    def resp = http.get(path: "/rest/servicedeskapi/request/${issueKey}/sla") as HttpResponseDecorator

    if (resp.status != 200) {
        log.warn 'Commander did not respond with 200 for retrieving project list'
    }

    def issueJson = resp.data as Map

    def totalValues = issueJson['values'] as List<Map>

    def result = totalValues.findAll {it['name'] == 'Time to first response'}

    def time =  result['ongoingCycle']['startTime']['jira']
    log.warn("Time:" + new JsonBuilder(time).toPrettyString())
Ram Kumar Aravindakshan _Adaptavist_
Community Champion
September 29, 2022

Hi @[deleted]

It appears you have commented out the lines below:-

@BaseScript CustomEndpointDelegate delegate
getTimeToFirstResponse { MultivaluedMap queryParams, body, HttpServletRequest request -

 You need these lines for the REST Endpoint to work correctly.

Also, you seem to be missing the last line, i.e.:-

 Response.ok(new JsonBuilder(time).toPrettyString()).build()

If the last line is not included, you won't be able to get the correct value that you want. Instead, you will get the entire JSON Response.

Please correct your code and ensure it is added to the REST Endpoint. The code should be:-

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import groovyx.net.http.HttpResponseDecorator
import groovyx.net.http.RESTClient
import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate
getTimeToFirstResponse { MultivaluedMap queryParams, body, HttpServletRequest request ->
def issueKey = queryParams.getFirst('issueKey')

def applicationProperties = ComponentAccessor.applicationProperties

final def baseUrl = applicationProperties.getString('jira.baseurl')
final def username = 'tiwarab'
final def password = 'q'
final def headers = ['Authorization': "Bearer MDI5NjAxODc5ODE5Olvt0d7GCC2o790uYGHZ3AuHp4eo",
'X-ExperimentalApi': 'opt-in', 'Accept': 'application/json'] as Map

def http = new RESTClient(baseUrl)
http.setHeaders(headers)

def resp = http.get(path: "/rest/servicedeskapi/request/${issueKey}/sla") as HttpResponseDecorator

if (resp.status != 200) {
log.warn 'Commander did not respond with 200 for retrieving project list'
}

def issueJson = resp.data as Map

def totalValues = issueJson['values'] as List<Map>

def result = totalValues.findAll {it['name'] == 'Time to first response'}

def time = result['ongoingCycle']['startTime']['jira']

Response.ok(new JsonBuilder(time).toPrettyString()).build()
}

For this code to work, you need to configure the REST Endpoint and not just invoke it from the console.

Once you have configured the REST Endpoint, you can now invoke the REST Endpoint from the ScriptRunner console doing something like:-

 

import com.atlassian.jira.component.ComponentAccessor

import groovy.json.JsonSlurper

def applicationProperties = ComponentAccessor.applicationProperties

final def host = applicationProperties.getString('jira.baseurl')

def issueKey = 'ST-1'

def baseUrl = "${host}/rest/scriptrunner/latest/custom/getTimeToFirstResponse?issueKey=${issueKey}" as String

def output = new URL(baseUrl).text

def json = new JsonSlurper().parseText(output) as List

log.warn "=====>>> ${json.first()}"

This should return your date value. Using the code above in the Console should return something like:-

test1.png

 

Thank you and Kind regards,

Ram

Deleted user September 29, 2022

Hi Ram,

I am able to execute it successfully. Please check my above questions, i would need your help answering them.

Ram Kumar Aravindakshan _Adaptavist_
Community Champion
September 29, 2022

Hi @[deleted]

What exactly is your question? You have only asked how to retrieve the Time to First Response.

I've had to update my response because of the page timeout on my side. 

I have included the ScriptRunner console code to invoke the REST Endpoint and get the value from the Time to First Response field.

Thank you and Kind regards,

Ram

Deleted user September 29, 2022

My questions are:-

1) For "Time to first response" we are getting a date "2022-02-09T08:44:36.389+0000" from rest api but in jira UI it shows -8mon. Why is there a difference?(Issue-SPSDT-68)

2) There is one more Jira for which it shows -1mon in jira UI. But the rest api is giving no date because it has no ongoingCycle how to handle this case.Rest endpoint payload for this issue i have posted in my previous comments, please refer?(Issue-SPSDT-69)

3) Also, is there noway we can get "Time to first response" from customfield value object rather than calling rest apis?

Ram Kumar Aravindakshan _Adaptavist_
Community Champion
September 30, 2022

Hi @[deleted]

In your last comment, you asked:-

1) For "Time to first response" we are getting a date "2022-02-09T08:44:36.389+0000" from rest api but in jira UI it shows -8mon. Why is there a difference?(Issue-SPSDT-68)

Basically, Jira is doing a calculation between the number of days or months from the Time to First Response and the current system date. In other words, something like:-

 

def dateFrom = Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "2022-02-09T08:44:36.389+0000")

def dateTo = new Date(System.currentTimeMillis())

def diffMonths = { Date start, Date end ->

int diffYears = (start[Calendar.YEAR] - end[Calendar.YEAR]) * 12

int diffMonths = start[Calendar.MONTH] - end[Calendar.MONTH]

return diffYears + diffMonths

}

log.warn diffMonths(dateFrom, dateTo)

So the output will display the total number of months, i.e.

image1.png

You also asked:-

2) There is one more Jira for which it shows -1mon in jira UI. But the rest api is giving no date because it has no ongoingCycle how to handle this case.Rest endpoint payload for this issue i have posted in my previous comments, please refer?(Issue-SPSDT-69)

That doesn't make sense. Even if the issue's SLA is paused, the ongoing cycle will remain.

And for your third question, i.e.:-

3) Also, is there noway we can get "Time to first response" from customfield value object rather than calling rest apis?

Basically, once you have obtained the value from the REST Endpoint, you can use the console, for example, to update a Text Field with that value.

 

I hope this helps to answer your questions. :-)

Thank you and Kind regards,

Ram

 

Deleted user October 14, 2022

Thank you for your valuable response. I have a query on Elasped Time. We need to get the elapsed time. Could you please confirm how the Pause is incorporated into the Elapsed time? 

 For Example,

Ticket Creation Date = 08/01/22

Blocked Status (Pause from SLA) from 08/05/22 to 10/10/22 In-Progress and Resolved on 10/14/22

 Is the pause excluded from the Elapsed time or would the elapsed time be calculated from the Creation date? 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events