How to run http web service request from pl/sql package - oracle

I have developed a new procedure to call web service but its showing Oracle adaptor error when I run it. Could you please guide me how can I resolve this error? Is teher something wrong below code?
/* Formatted on 17/07/2014 16:49:02 (QP5 v5.185.11230.41888) */
CREATE OR REPLACE PROCEDURE APPS.xx_web_id
IS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_response_text VARCHAR2 (10000);
BEGIN
-- preparing request
l_http_request :=
UTL_HTTP.begin_request ('https://freegeoip.net/xml/82.39.109.147',
'POST',
'HTTP/1.1');
l_http_response := UTL_HTTP.get_response (l_http_request);
UTL_HTTP.read_text (l_http_response, l_response_text);
DBMS_OUTPUT.put_line (l_response_text);
UTL_HTTP.end_response (l_http_response);
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (l_http_response);
END;

First you should configure ACL ;
BEGIN
dbms_network_acl_admin.create_acl(acl => 'pkg.xml',
description => 'Normal Access',
principal => 'CONNECT',
is_grant => TRUE,
privilege => 'connect',
start_date => NULL,
end_date => NULL);
END;
/
BEGIN
dbms_network_acl_admin.add_privilege(acl => 'utlpkg.xml',
principal => 'XXXX', --- user name
is_grant => TRUE,
privilege => 'connect',
start_date => NULL,
end_date => NULL);
END;
/
BEGIN
dbms_network_acl_admin.assign_acl(acl => 'pkg.xml',
host => 'HOST ADDRESS',-- Web Server URL
lower_port => 7222, -- Web Server PORTs
upper_port => 7222);
END;
/
Then you should create procedure which will be called web service. Sample that i used you may find in below;
CREATE OR REPLACE PROCEDURE web_service_call()
AS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_buffer_size NUMBER (10) := 512;
l_line_size NUMBER (10) := 50;
l_lines_count NUMBER (10) := 20;
l_clob_request CLOB;
l_line VARCHAR2 (32767);
l_substring_msg VARCHAR2 (32767);
l_raw_data RAW (512);
l_clob_response CLOB;
l_host_name VARCHAR2 (128) := 'get.bla.bla';
l_port VARCHAR2 (128) := '7222';
req_length binary_integer;
bufferY varchar(2000);
amount pls_integer:=2000;
offset pls_integer:=1;
BEGIN
l_clob_request := 'xml';
l_http_request :=
UTL_HTTP.begin_request (url => 'http://'
|| l_host_name
|| ':'
|| l_port
|| '/Something/GetSomething',
method => 'POST',
http_version => 'HTTP/1.1'
);
UTL_HTTP.set_header (l_http_request, 'User-Agent', 'Mozilla/4.0');
UTL_HTTP.set_header (l_http_request,
'Host',
l_host_name || ':' || l_port
);
UTL_HTTP.set_header (l_http_request, 'Connection', 'close');
utl_http.set_header(l_http_request, 'Content-Type', 'text/xml;charset=ISO-8859-9');
UTL_HTTP.set_header (l_http_request, 'SOAPAction', '"sayHello"');
UTL_HTTP.set_header (l_http_request,
'Content-Length',
LENGTH (l_clob_request)
);
req_length := DBMS_LOB.getlength (l_clob_request);
offset :=1;
bufferY :=null;
amount:=2000;
WHILE (offset < req_length)
LOOP
DBMS_LOB.read (l_clob_request,
amount,
offset,
bufferY);
UTL_HTTP.write_text (l_http_request, bufferY);
offset := offset + amount;
END LOOP;
l_http_response := UTL_HTTP.get_response (l_http_request);
l_clob_response :=null;
BEGIN
<<response_loop>>
LOOP
UTL_HTTP.read_raw (l_http_response, l_raw_data, l_buffer_size);
l_clob_response :=
l_clob_response || UTL_RAW.cast_to_varchar2 (l_raw_data);
END LOOP response_loop;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (l_http_response);
END;
IF l_http_request.private_hndl IS NOT NULL
THEN
UTL_HTTP.end_request (l_http_request);
END IF;
IF l_http_response.private_hndl IS NOT NULL
THEN
UTL_HTTP.end_response (l_http_response);
END IF;
END;
/

Related

LDAP AD objectSID decode

I'm Using DBMS_LDAP package to get Users and Computers with attribute objectSid, it is a binary. Using DBMS_LDAP.GET_VALUES_BLOB and RAWTOHEX I can get HEX. How I can convert to SID String (SID Structure). There is any function?
For example from 010500000000000515000000e967bb98d6b7d7bf82051e6c28060000 to S-1-5-21-2562418665-3218585558-1813906818-1576.
I've put together this code using the following sources to guide me:
Get objectGUID: https://joelitechlife.ca/2021/04/28/dbms_ldap-example/
ObjectSid WiKi: https://ldapwiki.com/wiki/ObjectSID
Converting SID Binary and String Forms: https://devblogs.microsoft.com/oldnewthing/20040315-00/?p=40253
CREATE OR REPLACE FUNCTION get_objectsid (p_samaccount IN VARCHAR2)
RETURN VARCHAR2 AS
v_objectguid VARCHAR2(100) := NULL;
v_ldap_host VARCHAR2(256) := 'server.domain.base';
v_ldap_port VARCHAR2(256) := '389';
v_ldap_user VARCHAR2(256) := 'CN=Oracle Services,OU=OtherAccounts,OU=Corporate,OU=Locations,DC=domain,DC=base';
v_ldap_passwd VARCHAR2(256) := 'password';
v_ldap_base VARCHAR2(256) := 'DC=domain,DC=base';
v_result PLS_INTEGER;
v_session DBMS_LDAP.session;
v_search_attrs DBMS_LDAP.string_collection;
v_search_results DBMS_LDAP.MESSAGE;
v_entry DBMS_LDAP.MESSAGE;
v_values DBMS_LDAP.BINVAL_COLLECTION;
v_ber_element dbms_ldap.ber_element;
v_attr_name VARCHAR2(256);
l_revision number;
l_num_dashes number;
l_sid_issue_authority number;
l_object_sid varchar2(100);
function endian_value(p_string varchar2, p_endian_type varchar2)
return varchar2
as
l_step number := 2;
l_val varchar2(4000);
begin
if upper(p_endian_type) = 'L' then
for i in 1..length(p_string) / 2
loop
l_val := substr(p_string, i * l_step - 1, 2)||l_val;
dbms_output.put_line('endian of '||l_val);
end loop;
else
l_val := p_string;
end if;
return to_number(l_val, 'xxxxxxxxxxxxxxxx');
end;
function process_left(p_string in out varchar2, p_len int)
return varchar2
as
l_rtn varchar2(100);
begin
l_rtn := substr(p_string, 1, p_len);
p_string := substr(p_string, p_len + 1);
return l_rtn;
end;
BEGIN
-- Choose to raise exceptions.
DBMS_LDAP.use_exception := TRUE;
-- initiating the connection to the LDAP server
v_session := DBMS_LDAP.init(hostname => v_ldap_host, portnum => v_ldap_port);
-- binding the user
v_result := DBMS_LDAP.simple_bind_s(ld => v_session,
dn => v_ldap_user,
passwd => v_ldap_passwd);
-- attribute name to search
v_search_attrs(1) := 'objectSid';
v_result := DBMS_LDAP.search_s( ld => v_session,
base => v_ldap_base,
scope => DBMS_LDAP.SCOPE_SUBTREE,
FILTER => '(&(objectClass=user)(samaccountName='||p_samaccount||'))',
attrs => v_search_attrs,
attronly => 0,
res => v_search_results);
-- expecting there will be only one entry matched , one attribute objectGUID only
IF dbms_ldap.count_entries(ld => v_session, msg => v_search_results) > 0
THEN
v_entry := DBMS_LDAP.first_entry(ld => v_session, msg => v_search_results);
v_attr_name := dbms_ldap.first_attribute(ld => v_session,
ldapentry => v_entry,
ber_elem => v_ber_element);
v_values := dbms_ldap.get_values_len (ld => v_session,
ldapentry => v_entry,
attr => v_attr_name);
IF v_values.COUNT > 0
THEN
FOR i IN v_values.FIRST .. v_values.LAST
LOOP
select rawtohex(v_values(i)) into v_objectguid from dual;
END LOOP;
END IF;
dbms_output.put_line(v_objectguid);
l_revision := to_number(process_left(v_objectguid, 2), '00');
l_num_dashes := to_number(process_left(v_objectguid, 2), '00');
l_sid_issue_authority := endian_value(process_left(v_objectguid, 12), 'b');
l_object_sid := 'S-'||l_revision||'-'||l_sid_issue_authority;
for i in 1..to_number(l_num_dashes)
loop
l_object_sid := l_object_sid||'-'||endian_value(process_left(v_objectguid, 8), 'l');
end loop;
dbms_output.put_line(l_object_sid);
END IF;
IF l_object_sid IS NULL THEN
l_object_sid:='No_objectsid';
END IF;
IF v_entry IS NOT NULL THEN
v_result := DBMS_LDAP.msgfree(v_entry);
END IF;
v_result := DBMS_LDAP.unbind_s(ld => v_session);
RETURN l_object_sid;
EXCEPTION
WHEN NO_DATA_FOUND THEN
l_object_sid:='---NoSid---';
RETURN l_object_sid;
END get_objectsid;

Oracle APEX database blob type to png

Is it possible to convert a blob type image stored in a database table to png? I need to send the image as png to a website using REST, but if I send the database blob item(converted to base64 before sending), the data is getting sent, but the image won't load up when I click on it to show. Could anyone give me a tip on how to do this?
Thanks in advance,
Tamas
Edit1: here's the whole code I'm using
The first request uploads the file to the website, and sends back a token with which I can then attach the file to the second request.
As you can see, both of the request bodys state that the content type is image/png, so I don't exactly understand what can be the problem.
create or replace procedure publish_error_tickets(p_priority_id varchar2, p_description varchar2)
is
req1 utl_http.req;
res1 utl_http.resp;
req2 utl_http.req;
res2 utl_http.resp;
lc_entire_message clob;
l_attachment clob;
url1 varchar2(4000) := 'http://revprox.local/inno-dev.cloudapp.net/redmine/uploads.json';
url2 varchar2(4000) := 'http://revprox.local/inno-dev.cloudapp.net/redmine/projects/support-interface-teszt/issues.json';
name varchar2(4000);
token varchar2(4000);
buffer varchar2(4000);
content varchar2(4000);
p_id number;
p_image blob;
l_request_body clob;
l_request_body_length number;
l_offset number := 1;
l_amount number := 2000;
l_buffer varchar2(4000);
begin
select max(id) into p_id from t_tkt_temp_images;
select image into p_image from t_tkt_temp_images where id = p_id;
l_request_body := apex_web_service.blob2clobbase64(p_image);
l_request_body_length := length(l_request_body);
req1 := utl_http.begin_request(url1, 'POST',' HTTP/1.1');
utl_http.set_header(req1, 'User-Agent', 'mozilla/4.0');
utl_http.set_header(req1, 'Content-Type', 'application/octet-stream');
utl_http.set_header(req1, 'Content-Length', l_request_body_length);
utl_http.set_header(req1, 'Content-Disposition', 'attachment; filename="file.png"');
utl_http.set_header(req1, 'X-Redmine-API-Key', '0asddq3t23w4esdf');
while l_offset < l_request_body_length loop
dbms_lob.read(l_request_body, l_amount, l_offset, l_buffer);
utl_http.write_text(req1, l_buffer);
l_offset := l_offset + l_amount;
end loop;
res1 := utl_http.get_response(req1);
begin
loop
utl_http.read_text(res1, buffer);
lc_entire_message := buffer;
end loop;
utl_http.end_response(res1);
exception
when utl_http.end_of_body
then
utl_http.end_response(res1);
end;
apex_json.parse(lc_entire_message);
token := apex_json.get_varchar2(p_path => 'upload.token');
content :=
'{
"issue": {
"subject": "Hibajegy",
"priority_id": '|| 1 ||',
"description": "asd",
"uploads": [
{"token": "'||token||'", "filename": "file.png", "content_type": "image/png"}
]
}
}';
req2 := utl_http.begin_request(url2, 'POST',' HTTP/1.1');
utl_http.set_header(req2, 'user-agent', 'mozilla/4.0');
utl_http.set_header(req2, 'content-type', 'application/json');
utl_http.set_header(req2, 'Content-Length', length(content));
utl_http.set_header(req2, 'X-Redmine-API-Key', '0asddq3t23w4esdf');
utl_http.write_text(req2, content);
res2 := utl_http.get_response(req2);
begin
loop
utl_http.read_line(res2, buffer);
end loop;
utl_http.end_response(res2);
exception
when utl_http.end_of_body
then
utl_http.end_response(res2);
end;
end publish_error_tickets;

Encryption in Oracle Databases

Recently I am trying to expand my knowledge about communication between databases in Oracle and I would like to get answer for few questions:
Problem
I am sending query through one database to another via LINK, for instance:
insert into testme#linkme values (1, ‘Hello World’);
where testme is destination table in second database and linkme is my link.
Questions
When sending query, are my data vulnerable (are they encrypted somehow during this process)?
If yes, could you briefly tell me more?
If no, is there any way to make this process safe?
Also, do you know any tools that I could use to test what happens with my data during sending process?
create or replace PACKAGE BODY "PKG_LOGI_PWD_REG"
as
FUNCTION decrypt_val( p_val IN RAW ) RETURN VARCHAR2
IS
l_decrypted RAW(32);
l_decrypted_string VARCHAR2(32);
L_USER varchar2(32);
L_CHARACTER_SET varchar2(10);
L_STRING varchar2(32);
L_KEY raw(250);
L_ENCRYPTION_TYPE PLS_INTEGER;
BEGIN
L_KEY := UTL_I18N.STRING_TO_RAW
( data => '98345678901234567890123456789012',
DST_CHARSET => 'AL32UTF8' );
L_ENCRYPTION_TYPE := dbms_crypto.encrypt_aes256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
l_decrypted := dbms_crypto.decrypt
( SRC => P_VAL,
TYP => L_ENCRYPTION_TYPE,
key => L_KEY );
l_decrypted_string := utl_i18n.raw_to_char
( data => l_decrypted ,
src_charset => 'AL32UTF8' );
RETURN l_decrypted_string;
end DECRYPT_VAL;
FUNCTION encrypt_val( p_val IN VARCHAR2 ) RETURN VARCHAR2
is
L_VAL RAW(32);
L_ENCRYPTED raw(32);
L_CHARACTER_SET varchar2(10);
L_STRING varchar2(32);
L_KEY RAW(250);
L_ENCRYPTION_TYPE PLS_INTEGER;
begin
L_KEY := UTL_I18N.STRING_TO_RAW
( data => '98345678901234567890123456789012',
DST_CHARSET => 'AL32UTF8' );
L_ENCRYPTION_TYPE := dbms_crypto.encrypt_aes256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
L_VAL := utl_i18n.string_to_raw
( data => p_val,
dst_charset => 'AL32UTF8' );
L_ENCRYPTED := dbms_crypto.encrypt
( SRC => L_VAL,
TYP => L_ENCRYPTION_TYPE,
key => L_KEY );
return L_ENCRYPTED;
EXCEPTION when OTHERS then
RETURN SQLCODE||'-'||SQLERRM;
end ENCRYPT_VAL;
end PKG_LOGI_PWD_REG;

ORA-29494: invalid state for run task error with DBMS_PARALLEL_EXECUTE

I am running a PL/SQL procedure with DBMS_PARALLEL_EXECUTE. I get stuck with ORA-29494: invalid state for run task error. My code is as below:
Below is the sample output for the DBMS_OUTPUT statement:
PROCESSING
5743
PROCESSING
5744
When I individually run the create task, chunk task and run task with input rowid from the user_parallel_execute_chunks, It works just fine for individual chunks. Also without loop, the task runs for all the chunks and ends with an error saying chunk_not_found. To handle that I used the loop, But I am not able to make it work
CREATE OR REPLACE PROCEDURE code_parse_wrapper AS
l_sql_stmt VARCHAR2(32767);
l_chunk_id NUMBER;
l_start_rowid ROWID;
l_end_rowid ROWID;
l_any_rows BOOLEAN;
l_try NUMBER;
l_status NUMBER;
l_stmt CLOB;
V_CHUNK_ID NUMBER;
V_STATUS VARCHAR2(30);
BEGIN
BEGIN
dbms_parallel_execute.drop_task(task_name => 'parallel_processing');
DBMS_OUTPUT.PUT_LINE('TASK DROPPED');
END;
BEGIN
dbms_parallel_execute.create_task(task_name => 'parallel_processing');
DBMS_OUTPUT.PUT_LINE('TASK CREATED');
END;
-- Create Chunks
BEGIN
dbms_parallel_execute.create_chunks_by_rowid
(
'parallel_processing',
'SchemaName',
'ORDER_DETAIL',
FALSE,
50000
);
END;
BEGIN
LOOP
dbms_parallel_execute.get_rowid_chunk
(
task_name => 'parallel_processing',
chunk_id => l_chunk_id,
start_rowid => l_start_rowid,
end_rowid => l_end_rowid,
any_rows => l_any_rows
);
select STATUS INTO V_STATUS from user_parallel_execute_tasks where task_name = 'parallel_processing';
DBMS_OUTPUT.PUT_LINE(V_STATUS);
l_sql_stmt := ' begin CODE_PARSE6_AK( :start_id, :end_id ); end;';
DBMS_OUTPUT.PUT_LINE(l_chunk_id);
-- DBMS_OUTPUT.PUT_LINE(l_sql_stmt);
IF (l_any_rows = false) THEN
EXIT;
END IF;
BEGIN
-- Get next unassigned chunk.
-- EXECUTE IMMEDIATE 'l_sql_stmt USING l_start_rowid, l_end_rowid';
dbms_parallel_execute.run_task('parallel_processing',
l_sql_stmt,
DBMS_SQL.NATIVE,
parallel_level => 10
);
l_try := 0;
l_status := dbms_parallel_execute.task_status('parallel_processing');
WHILE(l_try < 2 and l_status != dbms_parallel_execute.finished) LOOP
l_try := l_try + 1;
dbms_parallel_execute.resume_task('parallel_processing');
l_status := dbms_parallel_execute.task_status('parallel_processing');
dbms_parallel_execute.set_chunk_status
(
task_name => 'parallel_processing',
chunk_id => l_chunk_id,
status => dbms_parallel_execute.processed
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
-- Record chunk error.
dbms_parallel_execute.set_chunk_status
(
task_name => 'parallel_processing',
chunk_id => l_chunk_id,
status => dbms_parallel_execute.processed_with_error,
err_num => SQLCODE,
err_msg => SQLERRM
);
END;
COMMIT;
END LOOP;
END;
END;
Note sure why are doing get_rowid_chunk, set_chunk_status etc. I would use by_row => TRUE with create_chunks_by_rowid.
I think, you can use a simpler, cleaner piece of code here ... I have been using it for years without any issues. One can reuse this mostly by changing DML in l_sql_stmt.
DECLARE
l_task VARCHAR2(30) := 'parallel_processing';
l_sql_stmt VARCHAR2(32767);
l_try NUMBER;
l_status NUMBER;
BEGIN
DBMS_PARALLEL_EXECUTE.create_task (task_name => l_task);
DBMS_PARALLEL_EXECUTE.create_chunks_by_rowid(task_name => l_task,
table_owner => 'SCHEMANAME',
table_name => 'ORDER_DETAIL',
by_row => TRUE,
chunk_size => 10000);
l_sql_stmt := 'begin CODE_PARSE6_AK( :start_id, :end_id ); end;';
DBMS_PARALLEL_EXECUTE.run_task(task_name => l_task,
sql_stmt => l_sql_stmt,
language_flag => DBMS_SQL.NATIVE,
parallel_level => 10);
-- If there is error, RESUME it for at most 2 times.
l_try := 0;
l_status := DBMS_PARALLEL_EXECUTE.task_status(l_task);
WHILE(l_try < 2 and l_status != DBMS_PARALLEL_EXECUTE.FINISHED)
Loop
l_try := l_try + 1;
DBMS_PARALLEL_EXECUTE.resume_task(l_task);
l_status := DBMS_PARALLEL_EXECUTE.task_status(l_task);
END LOOP;
DBMS_PARALLEL_EXECUTE.drop_task(l_task);
END;
/

ORA-30625: method dispatch on NULL SELF argument is disallowed

Oracle keeps giving me this error:
ORA-30625: method dispatch on NULL SELF argument is disallowed
I trying it with soap_api
The code follows:
FUNCTION add_numbers (p_int_1 IN NUMBER,
p_int_2 IN NUMBER)
RETURN NUMBER
AS
l_request soap_api.t_request;
l_response soap_api.t_response;
l_return VARCHAR2(32767);
l_url VARCHAR2(32767);
l_namespace VARCHAR2(32767);
l_method VARCHAR2(32767);
l_soap_action VARCHAR2(32767);
l_result_name VARCHAR2(32767);
BEGIN
l_url := 'http://192.168.1.23:8080/TestWebservice.asmx';
l_namespace := 'xmlns="http://192.168.1.23:8080/TestWebservice.asmx"';
l_method := 'add';
l_soap_action := 'http://tempuri.org/add';
l_result_name := 'return';
l_request := soap_api.new_request(p_method => l_method,
p_namespace => l_namespace);
soap_api.add_parameter(p_request => l_request,
p_name => 'int1',
p_type => 'xsd:integer',
p_value => p_int_1);
soap_api.add_parameter(p_request => l_request,
p_name => 'int2',
p_type => 'xsd:integer',
p_value => p_int_2);
l_response := soap_api.invoke(p_request => l_request,
p_url => l_url,
p_action => l_soap_action);
l_return := soap_api.get_return_value(p_response => l_response,
p_name => l_result_name,
p_namespace => l_namespace);
RETURN l_return;
END;
Review the return name the next line
l_result_name := 'return';
In my case change this and solved!!
l_result_name := 'Return';

Resources