Error when attaching a file via Jira Cloud REST API in ScriptRunner Rest Endpoints

Michael Smith August 20, 2020

I'm new in HTTP Requests so when I'm trying to attach a file to Jira Cloud REST API in ScriptRunner Rest Endpoints my script failed with error:

<code>

2020-08-20 15:12:44,422 ERROR [common.UserCustomScriptEndpoint]: Script endpoint failed on method: POST attach
org.apache.http.client.ClientProtocolException
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at org.apache.http.client.HttpClient$execute.call(Unknown Source)
	at Script561$_run_closure1.doCall(Script561.groovy:66)
	at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy:225)
	at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy)
	at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy:345)
	at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy)
	at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder.withRecording(ScriptExecutionRecorder.groovy:13)
	at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder$withRecording.call(Unknown Source)
	at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl.execute(DiagnosticsManagerImpl.groovy:343)
	at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.doEndpoint(UserCustomScriptEndpoint.groovy:215)
	at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.postUserEndpoint(UserCustomScriptEndpoint.groovy:123)
Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:108)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	... 14 more
Caused by: org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 8,308; received: 0)
	at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178)
	at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
	at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:148)
	at org.apache.http.entity.mime.content.InputStreamBody.writeTo(InputStreamBody.java:92)
	at org.apache.http.entity.mime.AbstractMultipartForm.doWriteTo(AbstractMultipartForm.java:134)
	at org.apache.http.entity.mime.AbstractMultipartForm.writeTo(AbstractMultipartForm.java:157)
	at org.apache.http.entity.mime.MultipartFormEntity.writeTo(MultipartFormEntity.java:113)
	at org.apache.http.impl.execchain.RequestEntityProxy.writeTo(RequestEntityProxy.java:121)
	at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
	at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:152)
	at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	... 16 more 

My code:

<code>

import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import com.atlassian.jira.util.json.JSONObject
import com.atlassian.jira.util.json.JSONTokener
import com.atlassian.jira.util.json.JSONArray
import org.apache.commons.lang3.StringUtils
import org.apache.http.HttpEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.mime.MultipartEntityBuilder
import org.apache.http.entity.mime.content.FileBody
import org.apache.http.entity.mime.content.InputStreamBody
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils
import java.io.*

@BaseScript CustomEndpointDelegate delegate
attach ( httpMethod: "POST") {
MultivaluedMap queryParams, String body ->
//parsing json
JSONObject json = new JSONObject(new JSONTokener(body))
JSONObject issue = json.getJSONObject("issue")
JSONObject fields = issue.getJSONObject("fields")
JSONArray attachments = fields.getJSONArray("attachment")
JSONObject attachment = attachments.getJSONObject(attachments.length() - 1)
String vendorRequest = fields.getString("customfield_11616")
String linkToFile = attachment.getString("content")
String fileName = StringUtils.substringAfterLast(linkToFile, "/")

//download attachment to entity
CloseableHttpClient httpclient = HttpClients.createDefault()
HttpGet getAttach = new HttpGet(linkToFile)
getAttach.setHeader("X-Atlassian-Token", "no-check")
getAttach.setHeader("Authorization", "Basic xxxxxxxxxxxxxxxxxxxx")
CloseableHttpResponse responseFromServer = httpclient.execute(getAttach)

//responseFromServer.getStatusLine().getStatusCode() code 200 here
HttpEntity entity = responseFromServer.getEntity()
responseFromServer.close()

HttpPost post = new HttpPost("https://cloud-djira.atlassian.net/rest/api/2/issue/" + vendorRequest + "/attachments")
post.setHeader("X-Atlassian-Token", "no-check")
post.setHeader("Authorization", "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==")


//i geuss problem here
InputStreamBody fileBody = new InputStreamBody(entity.getContent(), fileName)
HttpEntity entityToAttach = MultipartEntityBuilder.create().addPart("file", fileBody).build()
post.setEntity(entityToAttach)

//script failed here
CloseableHttpResponse responseFromCloud = httpclient.execute(post)

responseFromCloud.close()
httpclient.close()
}

This code works in IDE if it uses like java so maybe it'd better use only groovy in ScriptRunner Rest Endpoints.

Could anyone help?

2 answers

1 accepted

0 votes
Answer accepted
Michael Smith August 21, 2020

I fixed that. Just moved line 

responseFromServer.close()

to end of the script

0 votes
Kristian Walker _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 20, 2020

Hi Michael.

I notice you have marked your question as Jira Cloud but this code is for Jira Server and will not be compatible in Jira Cloud as Atlassian does not provide the same Java API in cloud and only provides a Rest API.

I would advise re categorising this ticket as Jira Server if it is related to Server so that users who use the sever version can assist yourself with this question.

Regards,

Kristian

Michael Smith August 20, 2020

Suggest an answer

Log in or Sign up to answer