How to update Tempo work log attribute via HTTP/Rest call via Scriptrunner

Paddy Byrne April 12, 2016

Hi - would anyone have any examples or advice to give on how to update the value of a tempo work log attribute with a specific text string using the Tempo Rest API?

I am using the Script Runner plugin, and have had success posting any kind of GET request I need (by importing "groovyx.net.http.RESTClient"). I can retrieve and parse all work-logs for any given JIRA issue. My code that determines the actual string I want to post is also working fine. I am struggling with setting up a successful PUT query to accomplish my ultimate goal of updating the relevant work-log. 

The Tempo API for my version of time-sheets is here:

http://tempo.io/doc/timesheets/api/rest/latest/#json_48

I'm struggling with the syntax to use when building the PUT json body in my groovy script. I've enclosed all key/pair values in double quotes, and also tried with no quotes etc. Also confused about how to handle some of the key/pairs that the API instructions say are ignored by post/put requests. Nothing I try seems to succeed so far.

I'd really appreciate any code snippets of something similar to what i'm trying to do.

2 answers

1 accepted

1 vote
Answer accepted
Paddy Byrne April 14, 2016

Thanks!!! That works for me. If anyone else uses the below example from Ashraful Hasan, the uri path should be

uri.path = '/rest/api/2/issue/JRA-2

and obviously admin:admin needs to be changed to a real username and password combo of a valid JIRA user.

Now I just need to work on the tempo specific formatting of the JSON payload. I will continue with that, and mark this answered, the remainder of my problem is not script-runner specific.

Thanks again smile

0 votes
Ashraful Hasan [Adaptavist] April 13, 2016

Hi - If your problem is only related to sending JSON body in PUT request then you can use the below syntax. In the example I am sending JSON  to update couple of fields of an issue [JRA-2]. 

def fieldProperty = [
        fields: [
                description: "The description has been updated by REST",
                summary    : "Summary has been edited"
        ]
]
 
HttpResponse response
def statusCode
try {
    response = http.request(PUT, JSON) {
        uri.path = '/jira/rest/api/latest/issue/JRA-2'
        send JSON, fieldProperty
    }
    statusCode = response.getStatusLine().statusCode
    log.debug "status code is : ${statusCode}"
} catch (HttpResponseException ex) 
{
    log.error "error:  ${ex.message}"
}

 

I think variable "fieldProperty" is what you are looking for. I have run this code in ScriptRunner to update issues and it works fine.   

Paddy Byrne April 13, 2016

Hi, i'm having two problems basically. A) sending any kind of valid PUT http JSON call, and B) once I get first one working I need to figure out correct syntax for my JSON, specially in a format the tempo API will accept.

This is very helpful for my first problem, thanks for helping. Could you share a more complete example? I have tried yours (in script console) but get the error

groovy.lang.MissingPropertyException: No such property: PUT for class: Script1040 at Script1040.run(Script1040.groovy:22)

22 is the line in my particular script that has the 'response = http.request(PUT, JSON) {' line.

I think you are maybe using different imports to me. I have tried these:

 

import groovyx.net.http.RESTClient
import org.apache.http.HttpRequest
import org.apache.http.HttpResponse
import org.apache.http.client.HttpResponseException
def baseUrl = "http://localhost:8080"
def RESTClient http
http = new RESTClient(baseUrl)
http.headers['Authorization'] = 'Basic '+ '***removed***'
<then your code here, adapted to an issue in my JIRA>

I think the error is telling me my imported RESTClient does not support a PUT call?

 

Ashraful Hasan [Adaptavist] April 13, 2016

Hi - Select "Script Console" in ScriptRunner and run the following code for testing. I have changed the "fieldProperty" [now it is more like TEMPO doc and should be fine, I cannot provide you exact TEMPO example as I do not have TEMPO]. In script console you may see some red dot but the script should run fine and you should be able to see status code 204 in log.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.properties.APKeys
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import groovyx.net.http.RESTClient
import org.apache.http.HttpRequest
import org.apache.http.HttpRequestInterceptor
import groovyx.net.http.HttpResponseException
import org.apache.http.HttpResponse
import org.apache.http.protocol.HttpContext
import static groovyx.net.http.ContentType.JSON
import static groovyx.net.http.Method.GET
import static groovyx.net.http.Method.PUT
def baseUrl = ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL)
def RESTClient http = new RESTClient(baseUrl)
http.client.addRequestInterceptor(new HttpRequestInterceptor() {
    void process(HttpRequest httpRequest, HttpContext httpContext) {
        httpRequest.addHeader('Authorization', 'Basic ' + 'admin:admin'.bytes.encodeBase64().toString())
        httpRequest.addHeader('X-Atlassian-Token', "no-check")
    }
})
def fieldProperty = """{
   "fields": {
       "description":"!updated by rest",
       "summary":"Edited by rest, different format"
       }
   }
}"""
HttpResponse response
def statusCode
try {
    response = http.request(PUT, JSON) {
        uri.path = '/jira/rest/api/latest/issue/JRA-2'
        send JSON, fieldProperty
    }
    statusCode = response.getStatusLine().statusCode
    log.debug "status code is : ${statusCode}"
} catch (HttpResponseException ex) {
    log.error "error:  ${ex.message}"
}
log.debug "complete"

 

 

Paddy Byrne April 14, 2016

The code above works great - just edit uri and user/password to suit

Paddy Byrne April 14, 2016

I figured out the last part of my problem also. The snippet of code below will work.

def String locs = "Paris"
def String loce = "Rome"
def String logid = "10436"
def String payload = """{
"worklogAttributes":[{"key":"_EndLocation_","value":"${loce}"},{"key":"_StartLocation_","value":"${locs}"}],  
"issue":{"key":"GEO-9"}
}"""
HttpResponse response
def statusCode
try {
    response = http.request(PUT, JSON) {
        uri.path = "/rest/tempo-timesheets/3/worklogs/${logid}"
        send JSON, payload
    }
    statusCode = response.getStatusLine().statusCode
    log.debug "status code is : ${statusCode}"
} catch (HttpResponseException ex) {
    log.error "error:  ${ex.message}"
}
log.debug "complete"

If anyone else ever needs to look at different rest calls to Tempo, the google chrome extension Advanced Rest Client is very handy. You can run GET requests and look the returned data. Look at the results in RAW format. The syntax/format of the returned GET request will help you construct a POST or PUT request. When using PUT, I found anything stated in the tempo API as "//Ignored in POST and PUT operations" should be omitted from your call as it will most likely fail to parse it. I also found I had to post at least one piece of json data in the "issue" element. The above worked for me, and hopefully this may help someone else someday.

CST JIRA Confluence Admin July 17, 2016

Hi all,

Why it doesn't work on JIRA 7.0.4. I tried to put it into ScriptRunner Console and change http request type from put to get but it was unsucessful. It show the error: Canot find matching method org.apache.http.client.HttpClient#addRequestInterceptor(Script383$1). Please check if the declared type is right and if the method exist.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events