Consumindo Web Services via UTL_DBWS
Considerações
- Iniciando com a versão 11.2 do banco de dados Oracle, não é mais possível instalar o UTL_DBWS utilitário diretamente no usuário SYS por razões de segurança e devido a incompatibilidades com a JVM. Porém, é possível e recomendado que o utilitário seja instalado e configurado em um schema que não seja o SYS.
- Faça o download do UTL_DBWS diretamente.
Instalação
Note que todos os procedimentos abaixo devem ser executados diretamente no servidor onde se encontra o banco de dados.
Verificando a existência do utilitário UTL_DWS no schema SYS, e status de todas as classes Java e o OJVM pool size.
SQL> desc sys.utl_dbws
ERROR:
ORA-04043: object sys.utl_dbws does not exist
Caso o objeto já existe, prossiga efetuando um drop deste objeto.
Verificando o status dos objetos do tipo JAVA CLASS.
SQL> SELECT owner, status, count(*) FROM DBA_OBJECTS WHERE OBJECT_TYPE='JAVA CLASS' GROUP BY owner, status;
OWNER STATUS COUNT(*)
------------------------------ ------- ----------;
MDSYS VALID 531
SYS VALID 20444
EXFSYS VALID 47
ORDSYS VALID 1898
É importante que não exista objetos do tipo JAVA CLASS inválidos no banco de dados antes de proceder com o resto da instalação. Caso exista objetos inválidos, verifique o MOS article ID Doc ID 1112983.1.
O próximo passo é verificar se o OJVM pool size atende as seguintes configurações mínimas:
SQL> show parameter SHARED_POOL_SIZE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
shared_pool_size big integer 0
SQL> show parameter JAVA_POOL_SIZE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
java_pool_size big integer 0
SQL> alter system set SHARED_POOL_SIZE=132M scope=both;
System altered.
SQL> alter system set JAVA_POOL_SIZE=80M scope=both;
System altered.
SQL> show parameter JAVA_POOL_SIZE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
java_pool_size big integer 80M
Extrair o arquivo dbws-callout-utility-10131.zip que foi baixado anteriormente:
É recomendável que seja feito um backup do diretório $ORACLE_HOME/sqlj antes
mv $ORACLE_HOME/sqlj $ORACLE_HOME/sqlj.org
unzip dbws-callout-utility-10131.zip sqlj* -d $ORACLE_HOME
Criar o database schema que será o owner desta instalação. Para este exemplo, criarei um schema chamado web_service_app:
SQL> show user
USER is "SYS"
SQL> create user web_service_app identified by webservice default tablespace TBSDAT_UTILS temporary tablespace temp;
Pelo menos os seguintes privilégios devem ser concedidos ao schema web_service_app:
SQL> grant connect, resource, create public synonym to web_service_app;
Configurar a variável LD_LIBRARY_PATH de acordo antes de rodar o comando que irá fazer a carga dos objetos JAVA:
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
Carregar os objetos java utilizando o aplicativo loadjava:
cd $ORACLE_HOME/sqlj/lib
loadjava -u web_service_app/webservice -r -v -f -s -grant public -genmissing dbwsclientws.jar dbwsclientdb11.jar >& loadjava.txt
Revise o conteúdo do arquivo de saída loadjava.txt procurando por erros.
Verificando o status dos objetos do tipo JAVA CLASS.após a execução do comand loadjava acima:
SELECT owner, status, count(*) FROM DBA_OBJECTS WHERE OBJECT_TYPE='JAVA CLASS' GROUP BY owner, status;
OWNER STATUS COUNT(*)
------------------------------ ------- ----------
MDSYS VALID 531
SYS VALID 20444
EXFSYS VALID 47
ORDSYS VALID 1898
É de estrema importância que nenhuma JAVA CLASS seja reportada com status INVALID.
Neste ponto, procede-se com a instalação do wrapper, ou seja, uma package que serve de interface para a utilização dos objetos JAVA que foram carregados no passo acima:
$ cd $ORACLE_HOME/sqlj/lib
$
$ sqlplus web_service_app/webservice
SQL> @utl_dbws_decl.sql
Package created.
SQL> @utl_dbws_body.sql
Package body created.
Grant succeeded.
SQL> desc utl_dbws
PROCEDURE ADD_PARAMETER
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
CALL_HANDLE NUMBER IN
XML_NAME VARCHAR2 IN
Q_NAME VARCHAR2(4096) IN
P_MODE VARCHAR2 IN
Conceder os seguintes privilégios ao schema web_service_app:
SQL> conn /as sysdba
Connected.
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'shutdownHooks', '' );
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.util.logging.LoggingPermission', 'control', '' );
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','http.proxySet','write');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','http.proxyHost', 'write');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','http.proxyPort', 'write');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission','getClassLoader','');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.net.SocketPermission','*','connect,resolve');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','*','read,write');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission','setFactory','');
SQL> call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'accessClassInPackage.sun.util.calendar','');
Testando
Neste ponto, iremos fazer uso de um web service disponível na Cloud para testar o funcionamento da package UTL_DBWS que foi carregada no schema web_center_app.
É necessário criar a seguinte função em um schema de sua escolha. Esta função é responsável por criar o envelope que fará uso do UTL_DBWS para a chamada de serviços web service externos.
CREATE OR REPLACE FUNCTION celciusToFahrenheit(temperature NUMBER) RETURN VARCHAR2 AS
service_ web_service_app.utl_dbws.SERVICE;
call_ web_service_app.utl_dbws.CALL;
service_qname web_service_app.utl_dbws.QNAME;
port_qname web_service_app.utl_dbws.QNAME;
response sys.XMLTYPE;
request sys.XMLTYPE;
BEGIN
web_service_app.utl_dbws.set_http_proxy('proxy.domain.com:4040');
service_qname := web_service_app.utl_dbws.to_qname(null, 'CelciusToFahrenheit');
service_ := web_service_app.utl_dbws.create_service(service_qname);
call_ := web_service_app.utl_dbws.create_call(service_);
web_service_app.utl_dbws.set_target_endpoint_address(call_, 'http://webservices.daehosting.com/services/TemperatureConversions.wso');
web_service_app.utl_dbws.set_property( call_, 'OPERATION_STYLE', 'document');
request := sys.XMLTYPE('<CelciusToFahrenheit xmlns="http://webservices.daehosting.com/temperature"><nCelcius>'||temperature||'</nCelcius></ CelciusToFahrenheit>');
response := web_service_app.utl_dbws.invoke(call_, request);
return response.extract('//CelciusToFahrenheitResult/child::text()', 'xmlns="http://webservices.daehosting.com/temperature"').getstringval();
END;
/
Substitua a string ‘proxy.domain.com:4040’ da seguinte maneira:
– Se não existe servidor proxy, remover a linha
– Caso deva-se usar um servidor proxy, informe o nome do servidor e porta. Talvez seja necessário configurar o seu proxy para aceitar requisições feitas a partir deste servidor
A função de teste pode ser chamada da seguinte maneira:
SQL> SELECT celciusToFahrenheit(30) from dual;
CELCIUSTOFAHRENHEIT(30)
--------------------------------------------------------------------------------
86
Até a próxima