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?