Histórico da Página
Introdução
O objetivo desta API é auxiliar o desenvolvedor na construção de novos acessos, auxiliado por um framework, o Intellector-Api. O entendimento do seu mecanismo também será abordado nesse manual.
Executando Políticas e suas Particularidades
Como entry-point para execução de políticas, o TOTVS Intellector aceita chamadas via Servlets ou Web Service.
Executando via Servlets
Para executar uma política, basta submeter um post para o servlet runpolicy do TOTVS Intellector, passando o XML de entrada como conteúdo do request; veja abaixo um snippet em código Java.
Bloco de código | ||||
---|---|---|---|---|
| ||||
// Pega a URL destino String strURL = "[http://localhost:8080/intellector/runpolicy";] // Pega o arquivo para ser postado String strXMLFilename = args[1]; File input = new File(strXMLFilename); // Prepara o post HTTP PostMethod post = new PostMethod(strURL); // O conteudo do Request serah retirado diretamento do stream de entrada RequestEntity entity = new FileRequestEntity(input, "text/xml; charset=ISO-8859-1"); post.setRequestEntity(entity); // Pega o HTTP client HttpClient httpclient = new HttpClient(); // Executa o request try { int result = httpclient.executeMethod(post); // Mostra o status code System.out.println("Response status code: " + result); // Mostra o response System.out.println("Response body: "); System.out.println(post.getResponseBodyAsString()); } finally { // Release da conexao atual para o connection pool de conexoes, uma vez que jah foi feito post.releaseConnection(); } |
Dados de Entrada
O XML de entrada é composto pelas variáveis de entrada descritas em um layout de política e pelas seguintes informações: Nome da política a ser executada, Layout utilizado na execução da política, Nome e senha do usuário e Tipo de política; alguns dados, como: Nome da Política, Nome do Layout, Nome e Senha do Usuário, Tipo, bem como as Variáveis necessárias ao acesso, são obrigatórias.
Bloco de código | ||||
---|---|---|---|---|
| ||||
<programa cod_programa="politica_dummy"> <usuario>admin</usuario> <tipo>credito</tipo> <layout>Layout_politica_dummy</layout> <publishDate>2008-11-26 17:59:56.619 BRST</publishDate> <entrada> <campo> <nom_campo>CodCpf</nom_campo> <cod_formato></cod_formato> <tipo_dado>String</tipo_dado> <val_default></val_default> <listaDexPara> <dexPara valorDefault="true"> <para>00000001910</para> </dexPara> </listaDexPara> </campo> <campo> <nom_campo>DataNascimento</nom_campo> <cod_formato>1</cod_formato> <tipo_dado>Date</tipo_dado> <val_default></val_default> </campo> ... </entrada> <saida> <campo> <nom_campo>LPT__sAcao</nom_campo> <cod_formato></cod_formato> <tipo_dado>String</tipo_dado> <val_default></val_default> </campo> <campo> <nom_campo>LPT__sMsgErro</nom_campo> <cod_formato></cod_formato> <tipo_dado>String</tipo_dado> <val_default></val_default> </campo> <campo> <nom_campo>LPT__iRetorno</nom_campo> <cod_formato></cod_formato> <tipo_dado>Integer</tipo_dado> <val_default></val_default> </campo> <campo> <nom_campo>D100_NOMEdummy</nom_campo> <cod_formato></cod_formato> <tipo_dado>String</tipo_dado> <val_default></val_default> </campo> <campo> <nom_campo>DtSistema</nom_campo> <cod_formato>1</cod_formato> <tipo_dado>Date</tipo_dado> <val_default></val_default> </campo> ... </saida> </programa> |
Um XML de entrada de execução de política montado a para o layout acima:
Bloco de código | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="ISO-8859-1"?> <raiz> <!-- nome da politica --> <programa>politica_dummy</programa> <!-- nome do usuário com permissão pra execucao --> <usuario>admin</usuario> <!-- senha do usuario --> <senha>senha_admin</senha> <!-- tipo de politica --> <tipo>credito</tipo> <!-- layout para ser usado --> <layout>Layout_politica_dummy</layout> <!-- dados de entrada para a execução da politica --> <CodCpf>21769796304</CodCpf> <DataNascimento>30011966</DataNascimento> ... </raiz> |
Dados de Saída
Bloco de código | ||||
---|---|---|---|---|
| ||||
O XML de saída é composto pelas variáveis de saída descritas no layout de política utilizado na execução e, pelas seguintes variáveis de controle: <!-- UUID - identificador unico --> <LPT__CodExecucao>3176837B-00D1-4B50-8419-126650B0E114</LPT__CodExecucao> <LPT__iRetorno>0</LPT__iRetorno> <LPT__sAcao>NEGA CREDITO</LPT__sAcao> <LPT__sMsgErro></LPT__sMsgErro> |
Vamos explicitar cada uma das variáveis de retorno acima, exceto o código de execução.
- LPT__iRetorno
1 = ConfigException - exceção de erro na configuração do acesso
2 = LayoutException - exceção de erro na configuração do layout
3 = InfraException - exceção de erro de infraestrutura, como unknown host, certificados errados, autorização, timeout, etc.
4 = InstantiationException - exceção ao instanciar o acesso; erro na reflection
5 = IllegalAccessException - exceção ao instanciar o acesso; erro na reflection por acesso ilegal
6 = ClassNotFoundException - classe do acesso para reflection não encontrada
7 = Erro na política - exceto retorno do acesso.
8 = Erros inesperados, ocorridos durante a execução/tratamento do retorno dos acessos.
9 = Exceção - durante preenchimento das variáveis de retorno da política
10 = Exceção durante a execução da politica e não referente a acessos.
- T__sAcao - contém a ação que a política retornou; pode ser:
NEGA CREDITO
APROVA CREDITO
ANALISE
MY_ACTION, YOUR_ACTION,... - uma ação qualquer definida pelo usuário.
- LPT__sMsgErro - contém uma mensagem de erro explicitada numa string
Controle do post:
Response status code: 200 Response body:
Um XML de retorno de uma execução:
Bloco de código | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="ISO-8859-1"?> <raiz> <D200_DATA_1dummy>02/12/2008</D200_DATA_1dummy> <INTEGER_VALUEdummy>69</INTEGER_VALUEdummy> <D100_MYDIRdummy>/home/jboss/intellector/acessos/dummy//resources/dummyaccess.xml</D100_MYDIRdummy> <D100_OUTROdummy>Pode me ver agora</D100_OUTROdummy> <D200_TIPO_1dummy>CORRUPTO</D200_TIPO_1dummy> <MensagemRetorno>CodCpf = 00000001910;;idade = 30;tem seguro;salario > 1000;variavel double > 5.2;</MensagemRetorno> <D200_VALOR_1dummy>171.69</D200_VALOR_1dummy> <BOOLEAN_VALUEdummy>true</BOOLEAN_VALUEdummy> <STRING_VALUEdummy>DUMMY</STRING_VALUEdummy> <DOUBLE_VALUEdummy>9999,99</DOUBLE_VALUEdummy> <DATE_VALUEdummy>02/12/2008</DATE_VALUEdummy> <D200_HORA_1dummy>23:59:59</D200_HORA_1dummy> <D100_NOMEdummy>Claudio dos Anzoes Pereira</D100_NOMEdummy> <D200_MOEDA_1dummy>real</D200_MOEDA_1dummy> <D100_DTNASCIMENTOdummy>02/12/2008</D100_DTNASCIMENTOdummy> <DtSistema>02/12/2008</DtSistema> <LPT__sMsgErrodummy></LPT__sMsgErrodummy> <LPT__CodExecucao>3176837B-00D1-4B50-8419-126650B0E114</LPT__CodExecucao> <LPT__iRetorno>0</LPT__iRetorno> <LPT__iRetornodummy>0</LPT__iRetornodummy> <LPT__sAcao>NEGA CREDITO</LPT__sAcao> <LPT__sMsgErro></LPT__sMsgErro> </raiz> |
Para cada política executada pelo TOTVS Intellector, será gerado um Código de Execução, retornado pela variável:
- LPTCodExecucao - UUID (identificador único).
Bloco de código | ||||
---|---|---|---|---|
| ||||
<!-- UUID - identificador unico --> <LPT__CodExecucao>3176837B-00D1-4B50-8419-126650B0E114</LPT__CodExecucao> |
Linha de Comando - Executando uma Política no TOTVS Intellector
Abaixo, listamos alguns exemplos usando várias linguagens, para executar uma política no TOTVS Intellector. Lembramos que os exemplos necessitam de ajustes, mas a ideia central está disponibilizada.
Usando Java com API Apache commons-httpclient
Bloco de código | ||||
---|---|---|---|---|
| ||||
/** * $Revision: 1.2 $ * $Date: 2008-11-13 20:26:51 $ */ package br.com.tools.intellector.util; import java.io.File; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.FileRequestEntity; import org.apache.commons.httpclient.methods.RequestEntity; /** * Uma classe generica, via linha de comando para enviar arquivos, * e, a intencao eh enviar arquivos XML para testar os servlets * <p> * @author claudio cardozo * */ public class PostXML { /** * * Use: java PostXML [http://www.intellector.com.br:8080/intellector/runpolicy] c:\dummy_pol.xml * * @param args comando na linha de argumentos * Argumento 0 eh uma URL para um web server, servlet (wsdl?) * Argumento 1 eh arquivo local formato XML (pode ser qq arquivo!) * */ public static void main(String[] args) throws Exception { // passagem de argumentos if (args.length != 2) { System.out.println("Use: java -classpath <classpath> [-Dorg.apache.commons.logging.simplelog.defaultlog=<loglevel>] PostXML <url> <arquivo>]"); System.out.println("<classpath> - deve conter commons-httpclient.jar e commons-logging.jar"); System.out.println("<loglevel> - nivel de erro, warn, info, debug, trace"); System.out.println("<url> - a URL para postar o arquivo"); System.out.println("<arquivo> - arquivo para postar para a URL"); System.out.println(); System.exit(1); } // Pega a URL destino String strURL = args[0]; // Pega o arquivo para ser postado String strXMLFilename = args[1]; File input = new File(strXMLFilename); // Prepara o post HTTP PostMethod post = new PostMethod(strURL); // O conteudo do Request serah retirado diretamento do stream de entrada RequestEntity entity = new FileRequestEntity(input, "text/xml; charset=ISO-8859-1"); post.setRequestEntity(entity); // Pega o HTTP client HttpClient httpclient = new HttpClient(); // Executa o request try { int result = httpclient.executeMethod(post); // Mostra o status code System.out.println("Response status code: " + result); // Mostra o response System.out.println("Response body: "); System.out.println(post.getResponseBodyAsString()); } finally { // Release da conexao atual para o connection pool de conexoes, uma vez que jah foi feito post.releaseConnection(); } } } |
Usando PL/SQL
Aqui um pequeno exemplo de chamada usando os utilities do PLSQL do Oracle.
Bloco de código | ||||
---|---|---|---|---|
| ||||
create or replace FUNCTION sp_solicitahttp ( szXmlEntrada IN VARCHAR2, lenXmlEntrada IN BINARY_INTEGER, szXmlSaida IN OUT VARCHAR2, lenXmlSaida IN OUT BINARY_INTEGER ) RETURN BINARY_INTEGER IS /*------------------------------------------------------------------------------------------------ DATA : 02/12/2008 AUTOR : LUIZ LIMA PRODUTO : SCE MODULO : BATCH SGBD : ORACLE -------------------------------------------------------------------------------------------------*/ o_return_code INTEGER; i_urltext VARCHAR2(32767); i_timeout INTEGER DEFAULT 60; sslreq UTL_HTTP.req; rsp UTL_HTTP.resp; replymessage VARCHAR2(32767); replyline VARCHAR2(32767); BEGIN -- Maquina de Teste i_urltext := 'http://192.168.0.172:8080/intellector/runpolicy'; i_timeout := 50; -- Iniciando o Banco sslreq := UTL_HTTP.BEGIN_REQUEST(i_urltext,'POST','HTTP/1.0'); UTL_HTTP.SET_HEADER(sslreq,'Content-Type','text/xml;charset=ISO-8859-1'); UTL_HTTP.SET_HEADER(sslreq,'Content-Length',lenXmlEntrada); UTL_HTTP.SET_TRANSFER_TIMEOUT(i_timeout); /* Write information over secure connection */ /*MyXML := '<?xml version="1.0" encoding="UTF-8"?>' || '<raiz>' || '<programa>politica_dummy</programa>' || '<usuario>admin</usuario>' || '<senha>tools</senha>' || '<tipo>credito</tipo>' || '<layout>Layout_politica_dummy</layout>' || '<CodCpf>21769796304</CodCpf>' || '<DataNascimento>30011966</DataNascimento>' || '</raiz>'; */ UTL_HTTP.WRITE_TEXT(sslreq, szXmlEntrada); --UTL_HTTP.WRITE_TEXT( sslreq, MyXML); /* Initialize Response */ rsp:=UTL_HTTP.GET_RESPONSE(sslreq); replymessage := ''; /* Retrieve response */ BEGIN LOOP UTL_HTTP.READ_LINE(rsp, replyline, TRUE); replymessage := replymessage || replyline; END LOOP; UTL_HTTP.END_RESPONSE(rsp); EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN UTL_HTTP.END_RESPONSE(rsp); END; /* Set output information */ szXmlSaida := replymessage; lenXmlSaida := length(szXmlSaida); o_return_code := 1; RETURN o_return_code; EXCEPTION WHEN OTHERS THEN o_return_code := -1; szXmlSaida := replymessage || ' erro ' || SQLERRM; lenXmlSaida := length(szXmlSaida); return o_return_code; END; |
Usando Active X (VB/ASP)
Aqui um pequeno trecho de código para uma chamada simples ao TOTVS Intellector usando VB/ASP.
Bloco de código | ||||
---|---|---|---|---|
| ||||
'----------------------------------------------------------------- '-- Função que executa o Intellector via HTTP '----------------------------------------------------------------- Function SolicitaHTTP( byval asXmlEntrada ) Dim Url Dim objXMLReceive Dim objXMLSend Dim objSrvHTTP 'Pego o Host e o path do servelet do intellector para formar a url Url = "[http://www.intellector.com.br:8080/intellector/runpolicy"] Set objSrvHTTP = CreateObject("Msxml2.ServerXMLHTTP.3.0") Set objXMLSend = CreateObject("Msxml2.DOMDocument.3.0") Set objXMLReceive = CreateObject("Msxml2.DOMDocument.3.0") objXMLSend.async = false if not( asXmlEntrada = "" or isnull( asXmlEntrada ) or isempty( asXmlEntrada ) ) then 'Carrego XML de entrada objXMLSend.loadXML asXmlEntrada 'Seto os Timeouts 'objXMLSend.setTimeouts(resolveTimeout, connectTimeout, sendTimeout, receiveTimeout) 'Valores No timeout , 90 seg , 2 min , 5 min objSrvHTTP.setTimeouts 0 , 90000 , 120000, 3000000 'Configuro o endereço objSrvHTTP.open "POST", Url, false 'Envio o xml para o servidor objSrvHTTP.send objXMLSend Response.ContentType = "text/html;charset=ISO-8859-1" 'Busco o XML de retorno objXMLReceive = objSrvHTTP.responseText SolicitaHTTP = objXMLReceive end if End Function |
Usando RESTful
Uma vez que os exemplos acima, via browser, esclareceram envelope/contrato, segue abaixo um exemplo de chamada via httpClient. REST é apenas um estilo de arquitetura, baseado em estados de transferência.
Bloco de código | ||||
---|---|---|---|---|
| ||||
package br.com.tools.intellector.util; import java.io.IOException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; /** * Uma classe generica, via linha de comando para enviar arquivos, * e, a intencao eh enviar arquivos XML para testar o wsdl/rest * <p> * @author claudio cardozo * */ public class PostWSDL { // configura a url?wsdl private static String url = "[http://192.168.0.185:8080/intellector/services/PolicyExecution/executePolicy";] /** * Chamada RESTful via httpClient * @param args */ public static void main(String[] args) { // instancia um HttpClient HttpClient client = new HttpClient(); // instancia um GET HTTP method HttpMethod method = new GetMethod(url); // configura name-value pairs da string para o metodo // definindo um xml com os dados a serem para um uma politica NameValuePair nvp1= new NameValuePair("xmlInputString", "<raiz>" + "<programa>politica_dummy</programa><usuario>admin</usuario>" + "<senha>tools01</senha>"+ "<tipo>credito</tipo>"+ "<layout>Layout_politica_dummy_credito</layout>"+ "<CodCpf>21769796304</CodCpf>"+ "<DataNascimento>30011966</DataNascimento>"+ "<ValBem>101.34</ValBem>"+ "<DataAberturaConta>23102008</DataAberturaConta>"+ "</raiz>"); // configura as partes de envio method.setQueryString(new NameValuePair[]{nvp1}); try{ int statusCode = client.executeMethod(method); System.out.println("QueryString>> " + method.getQueryString()); System.out.println("Status Text>> " + HttpStatus.getStatusText(statusCode)); // pega a resposta como String System.out.println("Response>> " + method.getResponseBodyAsString()); //release da conexao method.releaseConnection(); } catch(IOException e) { e.printStackTrace(); } } } |
Nota: Saiba mais sobre REST
Consultando Políticas via Web Service (WSDL)
A Consulta de Políticas é um serviço de obtenção de nome, layout e tipo de todas as politicas cadastradas na base, via um XML. Deverão ser passados ao serviço 2 parâmetros:
- Nome de Usuário cadastrado no TOTVS Intellector
- Senha do Usuário criptografada usando algoritmo de criptografia AES.
Este XML pode ser convertido para um arraylist de hashmap( ) com o uso de da API XStream. O XML de retorno terá na primeira posição do arraylist um hashpmap com as seguintes chaves: retorno e msgerro.
- retorno pode ser 0 (sucesso) ou -1 (erro)
- msgerro contém uma mensagem determinada pela operação.
Bloco de código | ||||
---|---|---|---|---|
| ||||
<list> <map> <entry> <string>retorno</string> <string>0</string> </entry> <entry> <string>msgerro</string> <string></string> </entry> </map> <map> <entry> <string>layout</string> <string>Layout_politica_dummy</string> </entry> <entry> <string>cod_programa</string> <string>politica_dummy</string> </entry> <entry> <string>policyType</string> <string>defaulttype</string> </entry> </map> <map> <entry> <string>layout</string> <string>Layout_politica_dummy1</string> </entry> <entry> <string>cod_programa</string> <string>politica_dummy1</string> </entry> <entry> <string>policyType</string> <string>defaulttype</string> </entry> </map> <map> <entry> <string>layout</string> <string>Layout_politica_dummy2</string> </entry> <entry> <string>cod_programa</string> <string>politica_dummy2</string> </entry> <entry> <string>policyType</string> <string>defaulttype</string> </entry> </map> </list> |
Exemplo de código cliente WSDL usando Java para chamada do Web Service
Bloco de código | ||||
---|---|---|---|---|
| ||||
package br.com.tools.executaWebService; import java.net.URL; import javax.xml.namespace.QName; import br.com.tools.acessos.cipher.CipherVO; import br.com.tools.acessos.cipher.Ciphering; public class testeWebService { // definicao do serviço private static final QName SERVICE = new QName("[http://intellector.tools.com.br/services/WSPolicyExecution/",] "PolicyExecutionService"); public static void main(String args[]) { try { // definindo a url do web service URL wsdlURL = new URL("[http://192.168.0.59:8080/intellector/services/PolicyExecution?wsdl");] // definindo um xml com os dados a serem para um uma politica String sUsuario = "admin"; String sSenha = "tools01"; System.out.println("wsdl url: " + wsdlURL); // instanciando o servico PolicyExecutionService ss = new PolicyExecutionService( wsdlURL, SERVICE); // pegando o port type ListLayoutsPortType port = ss.getListPolicyLayouts(); // definindo uma string para receber o retorno do soap/wsdl String resp = null; //criptografo a senha Ciphering cipher = new Ciphering(); CipherVO passciphered = cipher.encript(sSenha); System.out.println("Invoking executePolicy()..."); resp = port.listPolicyLayouts(sUsuario, passciphered.getPassword()); System.out.println("TOTVS Intellector respondeu:\n" + resp); System.out.println(); System.exit(0); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
Desenvolvendo um Acesso Externo
Para obter exemplos de como construir usando a Intellector API, favor contactar a equipe TOTVS Financial.
Nem preciso explicar que esse framework nasceu da necessidade de padronizar o desenvolvimento dos primeiros plugins de acessos e execuções de políticas, embora essa característica fosse evidente desde o princípio. Na realidade, queríamos "forçar" qualquer desenvolvedor de plugins de acesso para o TOTVS Intellector a seguir o pattern que fosse operacional na chamada da política ao acesso desenvolvido, como exceções lançadas, etc., e tivesse uma luz no fim do túnel, com algumas artifícios que ajudassem, pois quanto problemas e dúvidas melhor. Ele é um framework de abstração para operações como chamadas HTTPS com certificados, as vezes bem complexas, e, acreditem, não é tão trivial lidar com sopa de letrinhas esquisitas. Mas nada de ficar assustado, abaixo veremos cada característica desse framework.
- Interface Acesso - Interface de acessos externos. Arremessa as exceções 'InfraException' para problemas de infraestrutura, como unknown host (conexões e suas configurações, erros de autenticação, logins e passwords, jks, etc);'LayoutException' para problemas relacionados aos layouts, registros e tipos do acesso e, 'ConfigException' se for detectado qualquer anomalia na configuração do acesso. Atualmente um único método precisa ser implementado, oexecute(). É interessante observar as HashMap de entrada/saída:
Bloco de código | ||||
---|---|---|---|---|
| ||||
public interface Acesso { /** * Executa um acesso externo; interface * <p> * @param hashIn * @throws InfraException * @throws LayoutException * @throws ConfigException */ public HashMap<String, Object> execute( HashMap<String, Object> hashIn) throws InfraException, LayoutException, ConfigException; } |
Exceptions throwable - O intellector-api disponibiliza algumas exceções para serem utilizadas pelos plugins de acessos, interpretados e tratados por qualquer política compilada pelo TOTVS Intellector Server, são elas:
- CipheringException - Classe Exception para tratamento das exceptions de ciphering (criptografia);
- ConfigException - Exceção gerada sempre que há um erro na configuração do acesso externo, como por exemplo, arquivos de configuração não localizados, certificados não localizados, etc.;
- InfraException - Exceção gerada sempre que há um erro na execução do acesso externo, como por exemplo, host não localizado, erros na conexão, autenticação, etc.;
- LayoutException - Exceção gerada sempre que há um erro na configuração dos layouts, como por exemplo, arquivos de configuração não localizados, layouts configurados de forma errada, etc.;
- PolicyException - Exceção gerada sempre que há um erro na política de controle de acessos de usuários na publicação de políticas, layouts de políticas, autenticação no site e execução de políticas.
Todas as exceções tem overload como no exemplo abaixo, permitindo lançar o throwable da causa junto.
Bloco de código | ||||
---|---|---|---|---|
| ||||
public class CipheringException extends Exception { /** * Excecao relativa a problemas de criptografia * <p> * @param msg mensagem para ser mostrada pela excecao */ public CipheringException(String msg) { super(msg); } /** * Constrói uma nova exceção especificando a mensagem detalhada e a causa. * Note que a mensagem detalhada associada a causa não são incorporadas * automaticamente na mensagem desta exceção. * <p> * @param message * Mensagem detalhada (que é armazenada para posterior obtenção * pelo método {@link #getMessage()}) * @param cause * Causa (que é guardada para posterior recuperação pelo método * {@link #getCause()}) (Um valor nulo é permitida, e indica que * a causa é inexistente ou desconhecida.) */ public CipheringException(String message, Throwable cause) { super(message, cause); } } |
Considerações sobre o arquivo XML para ser importado pelo Compilador
Criar manualmente o arquivo com o layout do acesso externo. Um template para a criação desse arquivo se encontra no dummyaccess para facilitar a vida do desenvolvedor e, tenha em mente, ele será validado pelo Compilador (Intellector Cliente). Esse XML deverá conter o nome do acesso externo e a sua classe de implementação em Java, lista das variáveis de entrada e outra de saída com o nome, tipo Java de cada uma, formato e descrição, e.g. abaixo para o nosso accessdummy:
Bloco de código | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- $Revision: 1.1.2.7 $ --> <!-- $Date: 2008-11-05 21:02:55 $ --> <!-- @Author claudio cardozo --> <dummy> <!-- metodo de acesso para ser carregado no acesso --> <code name="br.com.tools.acessos.DummyAccess"/> <!-- esse deverah ser sufixo para ser acrescentado ao nome --> <!-- vindo da politica, entao irei buscar na hash da politica --> <!-- hash.getKey(cpf_dummy); um de/para para os elementos --> <nome_acesso>dummy</nome_acesso> <!-- contem os dados necessarios para entrada no Dummy --> <entrada> <!-- posso testar pelo valor obrigatorio dentro de cada --> <!-- acesso, ele dever ser "CPF" --> <field description="cpf requerente" type="String" format="">CPF</field> <field description="Data de Nascimento" type="Date" format="ddmmyyyy">DT_NASC</field> <field description="Tem seguro" type="Boolean" format="">TEM_SEGURO</field> <field description="Valor do salario" type="Double" format="">VAL_SALARIO</field> <field description="Idade do requerente" type="Integer" format="">IDADE</field> </entrada> <!-- contem todas as saidas disponiveis pelo Dummy --> <!-- Obs.: quando counter=alguma_coisa, entao todo o bloco --> <!-- abaixo sofrerah um looping baseado nesse counter --> <saida id="DUMMY" counter="" > <register description="Teste de boolean" type="Boolean" format="">BOOLEAN_VALUE</register> <register description="Teste pra tipo Data" type="Date" format="">DATE_VALUE</register> <register description="Teste pra tipo Double" type="Double" format="">DOUBLE_VALUE</register> <register description="Teste pra tipo Integer" type="Integer" format="">INTEGER_VALUE</register> <register description="Teste pra tipo String" type="String" format="">STRING_VALUE</register> </saida> <saida id="D100" counter="" > <register description="Um Nome qualquer" type="String" format="">D100_NOME</register> <register description="Uma data de Nascimento" type="Date" format="ddmmyyyy">D100_DTNASCIMENTO</register> <register description="Mostra o diretorio" type="String" format="">D100_MYDIR</register> <register description="Qualquer string" type="String" format="">D100_OUTRO</register> </saida> <saida id="D200" counter="D200_NUMCONSULTAS" > <register description="Simula String com contador" type="String" format="">D200_TIPO_</register> <register description="Simula Date com contador" type="Date" format="yyyyddmm">D200_DATA_</register> <register description="Simula String com contador" type="String" format="">D200_HORA_</register> <register description="Simula String com contador" type="String" format="">D200_MOEDA_</register> <register description="Simula Double com contador" type="Double" format="">D200_VALOR_</register> </saida> </dummy> |
E o dummyaccess não é tão dummy assim...
O acesso dummy estará sempre sendo submetido a melhorias, por isso, procure sempre por uma versão atualizada, pois ele terá várias versões, que ao longo do nosso desenvolvimento são taggeds. Talvez exista uma que seja mais adequado a sua necessidade.
Desenvolvendo...
Importar o acesso dummy (dummyaccess) como um template para desenvolvimento de um acesso externo. A ideia é que ele oriente o desenvolvimento de toda a estruturanecessária para a criação de um plugin de acesso, mantendo uma padronização na construção destes, evitando que o fonte de cada acesso externo tenha uma forma de implementação completamente diferente dos outros. O objetivo é facilitar desenvolvimento de novos acessos de forma fácil e rápida. Os artefatos que comporão o projeto vazio de um plugin serão:
- Arquivo de propriedades com os dados de configuração do acesso externo, caso existam. Como não se sabe inicialmente quais são esses dados, criar um arquivo de exemplo com as propriedades mais comuns: protocolo (HTTP, HTTPS, TCP, etc), host, porta e objeto no servidor; atualmente só http/servlet é suportado;
- Artefatos necessários para a criação de uma funcionalidade no site do Intellector Server que permitirá a configuração do arquivo de propriedades pelo administrador do sistema;
- As estruturas das classes Java que deverão ser programadas para cada acesso externo:
- As classes, se for o caso, de implementação do acesso externo, para que o desenvolvedor possa programar o acesso externo propriamente dito;
- Um XML com os dados de entrada para chamada do acesso de acordo com o layout pré estabelecido pelo órgão e, que receberá o layout montado pela classe anterior e fará o acesso e retornará a classe com o layout de saída;
- Uma classe que fará o parser do retorno do órgão externo e montará o VO com as variáveis de resposta, que será chamada pela classe que efetuou o acesso;
- Colocar todos os arquivos de propriedades e layouts dentro de uma pasta, para que seja retirado do JAR depois. Essa lista deve ficar no arquivo de manifesto, i.e. META-INF/MANIFEST.MF com uma tag específica (Implementation-FileList - veja exemplo); os arquivos importados ficarão no diretório apontado pela variável de ambiente descrita pela tag 'Implementation-Datadir' no MANIFEST.MF e, esse local deve ter permissão de escrita para o owner do application server;
- Para configuração do plugin de acesso no "Intellector Data Dir", deverá ser informado no arquivo de manifesto, i.e. META-INF/MANIFEST.MF, o nome do acesso, na tag 'Implementation-Plugin'. Na Instalação do plugin, no Intellector, será criada um diretório com esse nome no "Intellector Data Dir".
- Para consultar o plugin de acesso é necessário determinar as chaves primárias para que futuramente o plugin de acesos seja armazenado em uma base de dados, portanto as variáveis primarykey e pkdescription deverão ser informados no arquivo de manifesto, i.e. META-INF/MANIFEST.MF, sendo o campo primarykey as chaves no HashMap de entrada do acesso mais importantes da consulta separados por ',' para que sejam consultados na funcionalidade Consultar Resultados de Plugin de Acesso e o campo pkdescription um nome mais amigável para que seja listado na funcionalidade também separado por ',' na mesma sequência descrita no campo primarykey;
- Criar um novo projeto no Eclipse, tendo como base/exemplo o acessodummy no diretório base de onde os artefatos foram gerados.
Exemplo do MANIFEST.MF (nesse caso, um do SERASA):
Bloco de código | ||||
---|---|---|---|---|
| ||||
Manifest-Version: 1.0 Main-Class: br.com.tools.acessos.serasa.SerasaPF Class-Path: . Version-Info: teste-10 Implementation-Vendor: Tools Servicos Implementation-Plugin: serasapf Implementation-Layout: serasapf Implementation-Datadir: serasapf.datadir Implementation-FileList: resources/https.properties, resources/layout_p002.xml, resources/layout_p006.xml, resources/layoutPF_b49c.xml, resources/layoutPJ_b49c.xml, resources/serasa.properties, resources/serasapf.xml, resources/serasapj.xml primarykey: CPF, DTNASCIMENTO, pkdescription: CPF, Data de Nascimento, |
Downloads
Baixe aqui o template do accessdummy;