Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Problems attaching files via REST from Oracle-db

Rolf Knaden January 31, 2013

Hi.

I am using the REST-Api from inside an Oracle-Database to manage Jira-Issues. All works fine, except attaching files to an issue.

I wrote the attached procedure. As response to my request I always get "OK", but the returned data is an empty json-list (see below) and the file is not attached.

============ Request ============
http_req.url = "http://cjvw8041/rest/api/2/issue/TEST-1623/attachments"
http_req.method = "POST"
http_req.http_version = "HTTP/1.1"
=================================
============ Response ===========
http_resp.status_code: "200"
http_resp.reason_phrase: "OK"
http_resp.http_version: "HTTP/1.1"
response data: "[]"
=================================

Can anyone tell me, what I'm doing wrong?
How about base64-encoding? Must I encode it? Must I encode the whole request or only the filedata?

Thanks,

Rolf

(send_file2.prc.txt)

2 answers

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Cameron Ives October 14, 2015

Thank you Rolf.    I started with your code and looked at a curl --trace-ascii of Attlassian's rest attachment example and got it to work.  I only need to handle attaching text files to JIRA issues, so I didn't use write_raw()

procedure attachToIssue  as
l_URL JIRAJSON.URLSTR%TYPE;
l_PARAM JIRAJSON.PARAM%TYPE;
req utl_http.req;
resp utl_http.resp;
paramLength number := 0;
l_stuff CLOB;
l_commentStr varchar2(3000);
msg_base64 CLOB;
msg_multipart CLOB;
l_multipart number;
resp_data CLOB;
rawdata raw(32000) := NULL;
crlf  VARCHAR2(2) := CHR(13) || CHR(10);
boundary  constant varchar2(1000) := '----------------------------a3599ea24c7a';
lDisposition varchar2(10000);
pos number := 1;

BEGIN

l_URL := 'http://jirad.mycompany.com/rest/api/2/issue/CSTPOC-172/attachments';
lDisposition := 'form-data; name="file"; filename="cambam.txt"';
msg_base64 := 'camdata dsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgdsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfgsdfg';
--Creating  the multipart message first so that you can discover its length
	msg_multipart := msg_multipart || '--' || boundary|| crlf;
	msg_multipart := msg_multipart || 'Content-Disposition: ' || lDisposition || crlf;
	msg_multipart := msg_multipart || 'Content-Type: application/text/xml'  || crlf;
	msg_multipart := msg_multipart || crlf || crlf;
	msg_multipart := msg_multipart || msg_base64;
	msg_multipart := msg_multipart || crlf;
	msg_multipart := msg_multipart || '--' || boundary||'--' || crlf;
l_multipart := length(msg_multipart);
-- request that exceptions are raised for error Status Codes */
	Utl_Http.Set_Response_Error_Check(enable => true);
	-- allow testing for exceptions like Utl_Http.Http_Server_Error */
	Utl_Http.Set_Detailed_Excp_Support(enable => true);
	Utl_Http.set_persistent_conn_support(true);
-- open the HTTP request
	req := Utl_Http.Begin_Request(l_URl, 'POST', 'HTTP/1.1');
	utl_http.set_transfer_timeout(req, 15);
-- set header
    UTL_HTTP.SET_AUTHENTICATION(req,'jira_user','mypassword');
	utl_http.set_header(r => req, name => 'X-Atlassian-Token', value => 'nocheck');
	Utl_Http.Set_Header(r => req, name => 'Content-Length', value => TO_CHAR(l_multipart));
   	Utl_Http.Set_Header(r => req, name => 'Expect', value => '100-continue');
	Utl_Http.Set_Header(r => req, name => 'Content-Type', value => 'multipart/form-data; boundary=' || boundary);
   utl_http.write_text(req,msg_multipart);
    
  
    dbms_output.put_line('============ Request ============');
	dbms_output.put_line('http_req.url = "' || req.url || '"');
	dbms_output.put_line('http_req.method = "' || req.method || '"');
	dbms_output.put_line('http_req.http_version = "' || req.http_version || '"');
    dbms_output.put_line('length Multipart = ' || l_multipart);
	dbms_output.put_line('=================================');
    -- receive the response
	resp := Utl_Http.get_response(req);
   --Chunk the response into clob resp_data
   declare
		resp_chunk VARCHAR2(32767);
		chunk_size constant integer := 32767;
	begin
		dbms_lob.createtemporary(resp_data, false);
		LOOP
			begin
				utl_http.read_text(resp, resp_chunk, chunk_size);
				dbms_lob.writeappend(resp_data, length(resp_chunk), resp_chunk);
			exception
				when Utl_Http.End_Of_Body then
					utl_http.end_response(resp);
					exit;
			end;
		END LOOP;
	end;
	dbms_output.put_line('============ Response ===========');
	dbms_output.put_line('http_resp.status_code: "' || resp.status_code || '"');
	dbms_output.put_line('http_resp.reason_phrase: "' || resp.reason_phrase || '"');
	dbms_output.put_line('http_resp.http_version: "' || resp.http_version || '"');
	dbms_output.put_line('response data: "' || substr(resp_data, 1, 4000) || '"');
	dbms_output.put_line('=================================');
END attachToIssue;
0 votes
Renjith Pillai
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 2, 2013

Where is your file being specified in your POST?

And read this http://docs.atlassian.com/jira/REST/latest/#id333578

Rolf Knaden February 2, 2013

The directory and filename are provided as parameters directory_name and file_name.

The file is read into variable msg_base64 in the first loop:

fh := utl_file.fopen(directory_name, file_name, 'R');
LOOP
BEGIN
utl_file.get_raw(fh, rawdata);
msg_base64 := msg_base64 || utl_raw.cast_to_varchar2(rawdata);
--msg_base64 := msg_base64 || utl_raw.cast_to_varchar2(utl_encode.base64_encode(rawdata));
EXCEPTION
WHEN no_data_found THEN
EXIT;
END;
END LOOP;
utl_file.fclose(fh);

TAGS
AUG Leaders

Atlassian Community Events