Llamada a WebService Desde Una Función Oracle

download Llamada a WebService Desde Una Función Oracle

of 9

Transcript of Llamada a WebService Desde Una Función Oracle

Introduccin

Para acceder a servicios de Internet, Oracle cuenta de modo nativo con el Package UTL_HTTP.

Con el Package UTL_HTTP, se pueden escribir programas PL / SQL que se comunican con los servidores web (HTTP).El paquete tambin soporta HTTP en el protocolo Secured Socket Layer (SSL), tambin conocido como HTTPS, directamente o a travs de un proxy HTTP.Otros protocolos de acceso a datos relacionados con Internet (como el protocolo de transferencia de archivos (FTP) o el protocolo Gopher) tambin estn soportados mediante un servidor proxy HTTP que soporta los protocolos.

Acceso a Servicios de Red en Oracle 11g.Oracle permite el acceso a servicios de red externos usando APIs PL/SQL(UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP and UTL_INADDR), las cuales son implementadas usando el protocolo TCP.En versiones previas de la base de datos, este acceso slo dependa del GRANT sobre un package especfico a un usuario.Oracle 11g introduce un acceso de grano fino a servicios de red usando el Access Control List (ACL) en el repositorio XML DB, permitiendo control sobre qu usuarios accesan qu recursos de red, independiente de los grants a los packages.Las Access Control Lists se pueden crear, modificar y eliminar en el repositorio XML DB usando FTP o WebDav.Adems, Oracle proporciona los packages DBMS_NETWORK_ACL_ADMIN y DBMS_NETWORK_ACL_UTILITY que permiten administrar la ACL desdePL/SQL.

Crear una Access Control List (ACL)(pondremos en rojo , lo que debemos ejecutar)Entrar a la base de datos con usuario SYS o administrador.Las ACLs son manipuladas usando el package DBMS_NETWORK_ACL_ADMIN package. El procedimiento CREATE_ACL usa los siguientes parmetros para crear un nuevo ACL:

ParmetroDescripcin

aclEl nombre del archivo XML de la ACL, generado relativo al directorio "/sys/acls" en el repositorio XML DB.

descriptionUna descripcin del ACL.

principalLa primera cuenta de usuario o rol al que se otorga (grant) o deniega permisos. El texto es case sensitive.

is_grantTRUE para grant, FALSE para quitar el privilegio.

privilegeUsar 'connect' para accesos del tipo UTL_TCP, UTL_SMTP, UTL_MAIL y UTL_HTTP. El texto es case sensitive.

start_dateValor por defecto NULL. Cuando se especifica, el ACL estar activo a partir de la fecha.

end_dateUna fecha opcional para el fin del ACL.

En nuestro caso, primero daremos permiso al usuario para que acceda al package:Otorgar permiso al Package GRANT EXECUTE ON UTL_HTTP TO ADMORA;

A continuacin, crearemos el ACL.Crear el ACL BEGINDBMS_NETWORK_ACL_ADMIN.CREATE_ACL (acl=>'acceso_utl_http.xml',description=>'Permiso para acceder a utl_http',principal => 'ADMORA',is_grant => TRUE,privilege => 'connect');COMMIT;END;/

Una vez creado,el ACL es visible en el directorio "http://host:port/sys/acls/".

Se puede agregar nuevos usuarios o roles al ACL, usando el procedimiento ADD_PRIVILEGE.

Su lista de parmetros es similar al procedimiento CREATE_ACL, con la omisin del parmetro DESCRIPTION y la adicin del parmetro POSITION, el cual setea el orden de precedencia.

BEGIN DBMS_NETWORK_ACL_ADMIN.add_privilege ( acl => 'acceso_utl_http.xml', principal => 'TEST1', is_grant => FALSE, privilege => 'connect', position => NULL, start_date => NULL, end_date => NULL); COMMIT;END;/

Los privilegios se remueven usando el procedimiento DELETE_PRIVILEGE.Si los parmetros IS_GRANT o PRIVILEGE van NULL, todos los grants o privilegios para el ACL son eliminados.

BEGIN DBMS_NETWORK_ACL_ADMIN.delete_privilege ( acl => 'acceso_utl_http.xml', principal => 'TEST1', is_grant => FALSE, privilege => 'connect');

COMMIT;END;/

Los ACLs son eliminados usando el procedimiento DROP_ACL.

BEGIN DBMS_NETWORK_ACL_ADMIN.drop_acl ( acl => 'acceso_utl_http.xml'); COMMIT;END;/

Asignando un ACL a una REDLas ACLs se asignan a redes usando el procedimiento ASSIGN_ACL, cuyos parmetros se listan a continuacin:

ParmetroDescripcin

aclEl nombre del archivo XML del ACL.

HostEl hostaname, dominio, IP o subred a asignar. Los Hostnames son case sensitive, y se permiten wildcards en las IP y dominios.

lower_portDefault a NULL. Especifica el rango bajo de puerto para el privilegio 'connect'.

upper_portDefault a NULL. Si se especifica lower_port, y el upper_port es NULL, se asumen iguales.

El cdigo siguiente muestra como se asigna el ACL creado previamente a una IP especfica.

BEGIN DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL ( acl => 'acceso_utl_http.xml', host => '10.200.91.125', lower_port => 8888, upper_port => NULL); COMMIT;END;/

El procedimiento UNASSIGN_ACL permite eliminar manualmente las asignaciones.

BEGIN DBMS_NETWORK_ACL_ADMIN.unassign_acl ( acl => 'acceso_utl_http.xml', host => '10.200.91.125', lower_port => 8888, upper_port => NULL);

COMMIT;END;

Funcin que llama a un Web Service Oracle

CREATE OR REPLACE FUNCTION get_test( p_destino IN NUMBER )Return VARCHAR2IS

/*Objetivo : Llamar a WS y retornar resultadoCreado por : Waldo Gomez AlvarezFecha de Creacion : 15/05/2013*/

v_req UTL_HTTP.req := NULL;v_resp UTL_HTTP.resp := NULL;v_retorno NUMBER;

v_respVal VARCHAR2(32767);v_reqXML VARCHAR2(32767);v_webservice VARCHAR2(100);

BEGIN /* Setea estados de error de excepciones */ Utl_Http.Set_Response_Error_Check( ENABLE => TRUE ); Utl_Http.Set_Detailed_Excp_Support( ENABLE => TRUE );

-- Web Service v_webservice := 'http://10.200.91.188:8888/integracion.pb.webservice/endpoints/TransferenciaService.wsdl';

BEGIN -- Generamos un Request a la URL destino, el mtodo debe ser POST v_req := UTL_HTTP.begin_request(v_webservice, 'POST');

-- Creamos un mensaje SOAP tal cual se define en el WSDL v_reqXML := ' 100 ' || TO_CHAR(p_destino) || ' 1.5E2 100 ';

-- El contenido que enviamos es XML: UTL_HTTP.set_header(v_req, 'Content-Type', 'text/xml');

-- Establecemos el SOAPAction (mtodo) a invocar: UTL_HTTP.set_header(v_req,'SOAPAction','"'||'transferencia'||'"');

-- Indicamos en el header el tamano del mensaje enviado: UTL_HTTP.set_header(v_req, 'Content-Length', Length(v_reqXML));

-- Escribimos el body del request UTL_HTTP.write_text(v_req,v_reqXML);

-- Obtenemos la respuesta v_resp := UTL_HTTP.get_response(v_req);

IF (v_resp.status_code > 300) THEN UTL_HTTP.end_response(v_resp); raise_application_error(20000, 'Peticion HTTP rechazada'); END IF;

-- Cargamos en la variable respVal la devolucin del servidor UTL_HTTP.read_text(v_resp, v_respVal );

-- Finalizamos la conexin HTTP UTL_HTTP.end_response(v_resp);

-- Para facilitar el ExtractValue, se deja la eqtiqueta 'limpia'. v_respVal := Replace(v_respVal, 'env:', ''); v_respVal := Replace(v_respVal, 'ns2:', '');

EXCEPTION WHEN Utl_Http.Request_Failed THEN Dbms_Output.Put_Line ( 'Peticion HTTP rechazada: ' || Utl_Http.Get_Detailed_Sqlerrm ); WHEN Utl_Http.Http_Server_Error THEN Dbms_Output.Put_Line ( 'Error en Servidor HTTP: ' || Utl_Http.Get_Detailed_Sqlerrm ); WHEN Utl_Http.Http_Client_Error THEN Dbms_Output.Put_Line ( 'Error en Cliente HTTP: ' || Utl_Http.Get_Detailed_Sqlerrm ); WHEN OTHERS THEN Dbms_Output.Put_Line (SQLERRM);

END; -- Buscamos contenido del nodo con el resultado SELECT TO_NUMBER( EXTRACTVALUE(xmltype(v_respVal), 'Envelope/Body/transferenciaResponse/resultado'), '9999' )INTO v_retorno FROM dual;

Return v_retorno; END;

Referencias:

Oracle-Basehttp://www.oracle-base.com/articles/11g/fine-grained-access-to-network-services-11gr1.php