Showing posts with label PLSQL. Show all posts
Showing posts with label PLSQL. Show all posts

Tuesday, July 5, 2011

How to call BPEL WebService from PLSQL

This article describes how to call BPEL web-service (or any other web-service) from PLSQL UTL_HTTP package.

CREATE OR REPLACE PACKAGE BODY APPS.CALL_BPEL_PROCESS
IS

--Main Procedure to be called from a workflow.
PROCEDURE process_contract(itemtype IN VARCHAR2,
itemkey IN VARCHAR2,
actid IN NUMBER,
funmode IN VARCHAR2,
result OUT VARCHAR2
)
IS
l_date_signed VARCHAR2(100);
l_contract_number VARCHAR2(120);
l_opportunity_id VARCHAR2(450);
l_status VARCHAR2(100);
l_email VARCHAR2(240);
l_message VARCHAR2(4000);
l_debug_loc VARCHAR2(4000);
l_type VARCHAR2(30);
custom_exception EXCEPTION;
BEGIN
BEGIN
SELECT TO_CHAR(NVL(OKHB.date_approved,SYSDATE),'RRRR-MM-DD') DATE_SIGNED
,OKHB.attribute7 --clarified that we may not need to replace ; stored to commas. we would retains as suggested in REKS replace(attribute7,';',',') if reqd
--,REPLACE(OKHB.attribute7,';',',') attribute7
,OKHB.scs_code
,FU.email_address email
INTO l_date_signed
,l_opportunity_id
,l_type
,l_email
FROM okc_k_headers_b OKHB
,fnd_user FU
WHERE OKHB.contract_number = ITEMKEY
AND FU.user_id = OKHB.created_by;

EXCEPTION
WHEN no_data_found THEN
l_debug_loc := 'No details returned for contract passed';
RAISE custom_exception;
END;

IF FUNMODE = 'RUN' THEN
soap_main (
P_Contract_number => ITEMKEY,
p_status => 'Closed Won - Shipment or Service Booking', --'CLOSE',
p_signed_date => l_date_signed,
p_opportunity_id => l_opportunity_id,
p_email => l_email, --'sriramv@xx.com', ---Waiting on clarification, this would be derived based on business decision
x_status => l_status,
x_message => l_message
);

IF l_status ='SUCCESS' OR l_status IS NULL THEN
result :='COMPLETE:SUCCESS';
ELSE
result :='COMPLETE:ERROR';
END IF;

END IF;

EXCEPTION
WHEN custom_exception THEN
WF_CORE.CONTEXT(
pkg_name => 'CALL_BPEL_PROCESS',
proc_name => 'PROCESS_CONTRACT',
arg1 => l_debug_loc,
arg2 => null,
arg3 => null,
arg4 => null,
arg5 => null);
RAISE;
END process_contract;

--main procedure to call BPEL process using UTL_HTTP package.
PROCEDURE soap_main
(
P_Contract_number IN VARCHAR2,
p_status IN VARCHAR2,
p_signed_date IN VARCHAR2,
p_opportunity_id IN VARCHAR2,
p_email IN VARCHAR2,
x_status OUT VARCHAR2,
x_message OUT VARCHAR2
)
IS
ws_endpoint VARCHAR2 (2500);
ws_operation VARCHAR2 (200);
ws_soap_request VARCHAR2 (32767);
ws_soap_response NCLOB;
v_xmldoc DBMS_XMLDOM.domdocument;
buf VARCHAR2 (32767);
l_status VARCHAR2 (20);
l_err_msg VARCHAR2 (2400);
l_ws_process_name VARCHAR2 (240);
BEGIN

BEGIN
SELECT description
INTO ws_endpoint
FROM fnd_lookup_values
WHERE lookup_type = 'XX_OKS_SFDC_WEBSRV_LKP'
AND lookup_code = 'URL_WS_ORASFDC';
EXCEPTION
WHEN OTHERS
THEN
x_status := 'E';
x_message := 'WS End Point Location not added in Lookup';
END;
--Outcome: http://soaprodapp.xx.com:7777/orabpel/sfdcservices/SfdcAutoLinkageSvc/1.0


BEGIN
SELECT description
INTO l_ws_process_name
FROM fnd_lookup_values
WHERE lookup_type = 'XX_OKS_SFDC_WEBSRV_LKP'
AND lookup_code = 'WS_PROCESS_NAME';
EXCEPTION
WHEN OTHERS THEN
x_status := 'E';
x_message := 'WS Process Name not added in Lookup';
END;
--Outcome: SfdcAutoLinkageSvc

ws_operation := 'process';

--Building input XML payload to the BPEL process.
ws_soap_request :=
'



'||p_opportunity_id||'
'||p_status||'
'||p_signed_date||'
'||P_Contract_number||'
'||p_email||'





';

--Invoking BPEL web service
ws_soap_response := invoke_web_service
(ws_endpoint => ws_endpoint,
ws_operation => ws_operation,
ws_soap_request => ws_soap_request
);

--Converting NCLOB response to XML document
v_xmldoc := get_xml_document (ws_soap_response);

DBMS_XMLDOM.writetobuffer (v_xmldoc, buf);

SELECT REPLACE (buf, 'env:')
INTO buf
FROM DUAL;

SELECT REPLACE (buf,
'xmlns:ns1="http://xmlns.oracle.com/'
|| l_ws_process_name
|| '"'
)
INTO buf
FROM DUAL;

SELECT REPLACE (buf,
' xmlns="http://xmlns.oracle.com/'
|| l_ws_process_name
|| '"'
)
INTO buf
FROM DUAL;

SELECT REPLACE (buf, 'ns1:')
INTO buf
FROM DUAL;

SELECT REPLACE (buf, '')
INTO buf
FROM DUAL;

SELECT REPLACE (buf, '')
INTO buf
FROM DUAL;

BEGIN

SELECT XMLTYPE (buf).EXTRACT
( '/Envelope/Body/'
|| l_ws_process_name
|| 'ProcessResponse/statusCode/text()'
).getstringval (),
XMLTYPE (buf).EXTRACT
( '/Envelope/Body/'
|| l_ws_process_name
|| 'ProcessResponse/message/text()'
).getstringval ()
INTO x_status,
x_message
FROM DUAL;


EXCEPTION
WHEN OTHERS
THEN
x_status := NULL;
DBMS_OUTPUT.PUT_LINE
( 'Error While XML Parser for CONTRACT-'|| P_Contract_number|| ' ErrMesg:XML EXTRACT Failed');
END;

EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE
( 'When Others Error '
|| SUBSTR (SQLERRM, 1, 500)
);
END soap_main;

FUNCTION invoke_web_service
(
ws_endpoint IN VARCHAR2 DEFAULT NULL,
ws_operation IN VARCHAR2 DEFAULT 'process',
ws_soap_request IN VARCHAR2 DEFAULT NULL
)
RETURN NCLOB
AS
soap_request VARCHAR2 (30000);
soap_response NCLOB;
--
http_req UTL_HTTP.req;
http_resp UTL_HTTP.resp;
l_excep_err VARCHAR2 (32767);
BEGIN
soap_request := ws_soap_request;
UTL_HTTP.set_response_error_check (TRUE);
UTL_HTTP.set_detailed_excp_support (TRUE);
http_req := UTL_HTTP.begin_request (ws_endpoint, 'POST', 'HTTP/1.1');
UTL_HTTP.set_header (http_req, 'Content-Type', 'text/xml');
UTL_HTTP.set_header (http_req, 'Content-Length', LENGTH (soap_request));
UTL_HTTP.set_header (http_req, 'SOAPAction', ws_operation);
UTL_HTTP.write_text (http_req, soap_request);
--
http_resp := UTL_HTTP.get_response (http_req);
--
UTL_HTTP.read_text (http_resp, soap_response);
UTL_HTTP.end_response (http_resp);
RETURN soap_response;
EXCEPTION
WHEN UTL_HTTP.request_failed THEN
l_excep_err := 'WS Exception : Request failed - '|| UTL_HTTP.get_detailed_sqlerrm;
DBMS_OUTPUT.PUT_LINE ('Error While Invoking WS ' || l_excep_err);
WHEN UTL_HTTP.http_server_error THEN
l_excep_err := 'WS Exception : Server Error - ' || UTL_HTTP.get_detailed_sqlerrm;
DBMS_OUTPUT.PUT_LINE ('Error While Invoking WS ' || l_excep_err);
WHEN UTL_HTTP.http_client_error THEN
l_excep_err := 'WS Exception - Client Error - ' || UTL_HTTP.get_detailed_sqlerrm;
WHEN OTHERS THEN
l_excep_err := 'WS Exception : Others - ' || SQLERRM;
DBMS_OUTPUT.PUT_LINE ('Error While Invoking WS ' || l_excep_err);
END invoke_web_service;

FUNCTION get_xml_document (ws_soap_response IN NCLOB)
RETURN DBMS_XMLDOM.domdocument
AS
xml_doc DBMS_XMLDOM.domdocument;
BEGIN
xml_doc := DBMS_XMLDOM.newdomdocument (SYS.XMLTYPE (ws_soap_response));
RETURN xml_doc;
END get_xml_document;


/*** This procedure used to invoke the SFDC Autholinkage BPEL process thru Concurrent Prog.****/
PROCEDURE submit_bpel_process(err_buf OUT VARCHAR2,
ret_code OUT VARCHAR2,
p_cont_number IN VARCHAR2)
IS
l_date_signed VARCHAR2(100);
l_contract_number VARCHAR2(120);
l_opportunity_id VARCHAR2(450);
l_status VARCHAR2(100);
l_email VARCHAR2(240);
l_message VARCHAR2(4000);
l_type VARCHAR2(30);
custom_exception EXCEPTION;
BEGIN
fnd_file.put_line (fnd_file.OUTPUT,'SFDC AutoLinkage Process Status for Contrat Number :' || p_cont_number);
fnd_file.put_line (fnd_file.OUTPUT,'============================================================================');
BEGIN
SELECT TO_CHAR(NVL(OKHB.date_approved,SYSDATE),'RRRR-MM-DD') DATE_SIGNED
,OKHB.attribute7 --clarified that we may not need to replace ; stored to commas. we would retains as suggested in REKS replace(attribute7,';',',') if reqd
--,REPLACE(OKHB.attribute7,';',',') attribute7
,OKHB.scs_code
,FU.email_address email
INTO l_date_signed
,l_opportunity_id
,l_type
,l_email
FROM okc_k_headers_b OKHB
,fnd_user FU
WHERE OKHB.contract_number = p_cont_number
AND FU.user_id = OKHB.created_by;

EXCEPTION
WHEN no_data_found THEN
RAISE custom_exception;
END;

fnd_file.put_line (fnd_file.OUTPUT,'Invoke SFDC AutoLinkage BPEL Process');
fnd_file.put_line (fnd_file.OUTPUT,' ');
fnd_file.put_line (fnd_file.OUTPUT,' ');
fnd_file.put_line (fnd_file.OUTPUT,'Submit Request - Input Parameter Value');

fnd_file.put_line (fnd_file.OUTPUT,'SVC Signed Date :' || l_date_signed);
fnd_file.put_line (fnd_file.OUTPUT,'Opportunity ID :' || l_opportunity_id);
fnd_file.put_line (fnd_file.OUTPUT,'SVC Category :' || l_type);
fnd_file.put_line (fnd_file.OUTPUT,'Email :' || l_email);

soap_main (
P_Contract_number => p_cont_number,
p_status => 'Closed Won - Shipment or Service Booking', --'CLOSE',
p_signed_date => l_date_signed,
p_opportunity_id => l_opportunity_id,
p_email => l_email, --'sriramv@xx.com', ---Waiting on clarification, this would be derived based on business decision
x_status => l_status,
x_message => l_message
);

fnd_file.put_line (fnd_file.OUTPUT,' ');
fnd_file.put_line (fnd_file.OUTPUT,'SFDC AutoLinkage BPEL Response');

fnd_file.put_line (fnd_file.OUTPUT,' Status : '||l_status);
fnd_file.put_line (fnd_file.OUTPUT,' Message : '||l_message);



EXCEPTION
WHEN custom_exception THEN
err_buf := 'No details returned for contract passed';
ret_code := 0;

END submit_bpel_process;

END CALL_BPEL_PROCESS;
/