Client WebService – Problema ao Conectar em WSDL com Certificado SSL

Esta é uma dica rápida para aqueles que estão tendo problemas ao consumir um WebService (WSDL) sobre uma camada  com certificado (SSL).  É comum se deparar com erros do tipo:

Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
Caused by: javax.net.ssl.SSLHandshakeException: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Caso você esteja se deparando com este tipo de mensagem , será necessário atribuir o certificado do serviço como confiável na TrustStore do Java. (vide javax.net.ssl.trustStore). No exemplo a seguir vou considerar que você já possui uma keystore do Java com o certificado do serviço já importado (procure por posts no Google ensinando como pegar o certificado do site desejado e incluir dentro de uma KeyStore Java).

Na sua Classe, antes de disparar o consumo do WebService você poderá chamar um método por exemplo “setTrustManager()” para que este realize o byPass de confiar em todos os certificados configurados na sua Keystore. Ps: Atenção as 2 classes necessárias para a implementação do TrustManager.

          public static void setTrustManager() {
           try {
	        final String KEY_STORE = "CAMINHO_PARA_SUA_KEYSTORE"; //Exemplo: C:\certificado.jks";
		final String KEY_STORE_TYPE = "JKS";
		final String KEY_STORE_PASS = "SENHA_DA_SUA_KEYSTORE";
		    
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509","SunJSSE");
            KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE);
            File cert = new File(KEY_STORE);
            InputStream stream = new FileInputStream(cert);
            ks.load(stream, KEY_STORE_PASS.toCharArray());
            stream.close();
            kmf.init(ks,KEY_STORE_PASS.toCharArray());

            SSLContext context = SSLContext.getInstance("TLS");
            TrustEverythingTrustManager trustManager = new TrustEverythingTrustManager();
            context.init(kmf.getKeyManagers(),new TrustManager[] { trustManager }, new SecureRandom());
            SSLContext.setDefault(context);
	    HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
	    HttpsURLConnection.setDefaultHostnameVerifier(new AlwaysTrueHostnameVerifier());			
	   } catch (Exception e) {
	      throw new RuntimeException(e);
	   }
	}

        // Classe Acessória 
	public static class AlwaysTrueHostnameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}

        // Classe Acessória 
        private static class TrustEverythingTrustManager implements X509TrustManager {
		
		@Override
		public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws CertificateException {}
		
		@Override
		public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws CertificateException {}

		@Override
		public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
	}

TISS – Gerar Hash do XML manualmente com Notepad++

Gerar manualmente o hash de um XML de Lote Guias ou qualquer outro XML do padrão da ANS nem sempre é uma tarefa fácil. Uma das possibilidades é gerar o hash manualmente a partir das informações do XML através de um gerador de hash md5 online.

Neste tutorial utilizamos o Notepad++ (https://notepad-plus-plus.org) com o plugin XML Tools que pode ser encontrado em: (https://sourceforge.net/projects/npp-plugins/files/XML%20Tools/.

Após instalado o Notepad++, instale o Plugin XML Tools através do Plugin Manager do Notepad++, siga os passos:

  1. Abra o Notepad++
  2. Acesse o menu Plugins > Plugin Manager > Show Plugin Manager
  3. Procure pelo “XML Tools” na aba Avaiable e clique no botão Install
  4. Após instalado, reinicie o Notepad++. O plugin XML Tools deve aparecer como última opção do menu Plugin conforme Imagem a seguir.

xml-tools

 

Com o Notepad++ e o Plugin XML Tools instalados, abra(ou copie o contéudo) o XML desejado no Notepad++ para geração do hash. Neste exemplo usaremos um XML de Lote de Guias gerado no formato de Client de WebService. (Poderia ser o XML padrão que começa com <ans:mensagemTISS> que é feito Upload para todas as operadoras de plano de saúde ou qualquer outro XML da ANS). Vamos aos passos:

  1. Com o XML aberto no Notepad++ procure a tag referente ao hash para excluir o seu valor. No nosso exemplo é a tag <ans:hash>. (Cada XML da ANS possui uma tag de hash que geralmente possui a palavra hash.)
    limpar-hash
  2. Após removido o conteúdo da tag <ans:hash>, vamos utilizar o plugin XML Tools para transformar o XML em uma única linha via comando Linarize.
    linarizeApós executado esse comando o seu XML deve ficar nesse estilo:
    linarizado
  3. Abra o prompt de Replace do Notepad++ com o atalho CTRL+H ou pelo menu Search -> Replace, pesquise pelo seguinte trecho de expressão regular: <[^>]+>  e clique em REPLACE ALL (atenção: o modo de pesquisa deve ser “Regular Expression”)replace
  4. Após feita a substituição de todas as tags XML, você terá em mãos o conteúdo puro para cálculo do Hash MD5 (padrão utilizado pela ANS até o momento). Acesse um site para cálculo de hash MD5 ou utilize funções PHP ou Java para cálculo de MD5 e cole esse conteúdo e solicite o cálculo do Hash.No nosso exemplo temos o conteúdo
    ENVIO_LOTE_GUIAS82016-07-3012:33:01.0000000-03:0060219370000273.02.0160219377ace4e300c9fa2b00cdaa7a325d1793b80000271513100000661488638100005800NIRACI CARREIRA6021937EDSON FELIX DA SILVA2270927EDSON FELIX DA SILVA70310012403322371092016-07-222221010101230.00que após executar pelo site Md5HashGenerator gerou o HASH 61b1c87318e0759bb150e4cb1625e684Alguns exemplos de site que calculam hash md5 online:
    http://www.md5hashgenerator.com/index.php (usado nesse tutorial)
    http://md5-hash-online.waraxe.us/

    Obs: Cuidado com alguns sites que geram hash online, pois estes utilizam algoritmos MD5 que não condizem com o algoritmo da ANS (em teste deveria ser universal kkk). O que pude perceber é que caracteres especiais alteram a forma como os sites calculam o HASH.

  5. Com o valor de Hash em mãos substitua no arquivo original na tag de hash <ans:hash>
    hash-substitui

Update em 05/07/2017 – gerar hash de SIB da ANS

Para aqueles que estiverem tentando gerar um hash para arquivo do tipo SIB. A ANS em seu manual oficial (arquivo_exemplo exemplo com hash.sbx) exige que no texto do md5 seja concatenado a a string:

http://www.ans.gov.br/padroes/sib/schemas http://www.ans.gov.br/padroes/sib/schemas/sib.xsd

 

SIB_hash_zerado

 

Ficando por exemplo:

http://www.ans.gov.br/padroes/sib/schemas http://www.ans.gov.br/padroes/sib/schemas/sib.xsdSIB02011-05-16T09:00:00.0Z000000035890680001461.1TESTE1ANS0000000000000000000000NOME TESTE 11980-01-01NOME MAE TESTE RUA TESTE000BARRA000000000000000000001000012000-01-01000000000000000000000002000-01-01410000000000002000-01-0100000000000012000-01-01000000000000000000000000000000000000000000000NOME TESTE 11980-01-01NOME MAE TESTE RUA TEST000BARRA000000000000000000001000012000-01-0100000000000

No caso de arquivos do tipo SIB, calcule o hash com base nessa observação!

Fim!


Tomcat – Como consertar o problema do limite de 65535 bytes

Por padrão o Tomcat só aceita JspServelts (aqueles Códigos Java que ficam dentro de um JSP <% %>) em um limite total de 65Kb (65535 byes). Ao tentar acessar uma página JSP que extrapole esse limite você poderá se deparar com a seguinte mensagem.


Unable to compile class for JSP
The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limit

Para resolver isso o recomendável é a refatoração do código que retire o código da camada de apresentação (¬¬ Obvius!) (um simples MVC já resolve!). No entanto, como sabemos que existem alguns projetos legados e bem antigos com pouca possibilidade de alteração, caso seja necessário uma força bruta para resolver a situação utilize o seguinte parâmetro de inicialização no seu Tomcat.

1) Abra o arquivo [Tomcat_Home]/conf/web.xml e procure pelo texto “JspServlet”. Ao encontrar o nó que contem esse texto adicione o seguinte parâmetro de inicialização.

<init-param>
     <param-name>mappedfile</param-name>
     <param-value>false</param-value>
</init-param>

 

A nova tag deve ficar da seguinte maneira:

 <servlet>
         <servlet-name>jsp</servlet-name>
         <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
         <init-param>
             <param-name>fork</param-name>
             <param-value>false</param-value>
         </init-param>
         <init-param>
             <param-name>xpoweredBy</param-name>
             <param-value>false</param-value> 
        </init-param>
 	<init-param> 
            <param-name>mappedfile</param-name>
             <param-value>false</param-value>
     	</init-param>
        <load-on-startup>3</load-on-startup>
     </servlet>

Após estas alterações salve o arquivo e reinicie o Tomcat!


Oracle – Dica Rápida: Pesquisar texto no corpo dos objetos function, trigger, procedure e packages

Dicas simples para pesquisar nos objetos do banco por um texto específico. Esta rotina pesquisa em objetos do tipo FUNCTION, TRIGGER, PROCEDURE E PACKAGES. Para proceder com a pesquisa substitua os campos TEXTO_PROCURADOe SEU_SCHEMA

SELECT OWNER||'.'||NAME,LINE,TEXT
  FROM ALL_SOURCE
 WHERE TYPE IN ('TRIGGER','FUNCTION','PACKAGE BODY','PROCEDURE')
   AND UPPER(TEXT) LIKE UPPER('%TEXTO_PROCURADO%') 
   AND OWNER IN ('SEU_SCHEMA')

Caso deseje, você poderá transformar esta query em uma procedure que imprime os resultados em tela (para chamadas rápidas):

CREATE OR REPLACE PROCEDURE pesquisa_texto(P_TEXTO IN VARCHAR2) is

BEGIN

 FOR R IN (
 SELECT OWNER||'.'||NAME LOCALIZ,LINE,TEXT
  FROM ALL_SOURCE
 WHERE TYPE IN ('TRIGGER','FUNCTION','PACKAGE BODY','PROCEDURE')
   AND UPPER(TEXT) LIKE UPPER('%'||P_TEXTO||'%') -- TEXTO PROCURADO
   AND OWNER IN ('SEU_SCHEMA')
 ) LOOP
        Dbms_Output.Put_Line('LOCAL: '||R.LOCALIZ||' - '||'LINE: '||R.LINE||' - TEXT: '||R.TEXT);
 END LOOP;

END;
/

Como resolver ORA-14450: attempt to access a transactional temp table already in use Tabela temporária Oracle

Um erro que pode incomodar bastante durante a atualização de uma tabela temporária é o :

ORA-14450: attempt to access a transactional temp table already in use

A mensagem apesar de clara pode ser difícil de tratar caso você não consiga identificar e/ou derrubar todas as sessões conectadas. Dessa forma, caso deseje “forçar” a alteração de uma tabela desse tipo, siga os seguintes passos:

  1. Execute o comando
    lock table <SCHEMA>.<TABELA_TEMPORARIA> in exclusive mode;
  2. Desconecte da sessão e conecte novamente no Banco (Ex: utilizando Sql Tools ou PLSQL Developer)
  3. Após conectado execute a seguinte Query:
    SELECT * FROM v$lock WHERE id1 = (SELECT object_id FROM all_objects WHERE owner =<SCHEMA> AND object_name =<TABELA_TEMPORARIA>);
    
  4. Ao identificar uma linha nesse select, vamos proceder “matando” a sessão:
    ALTER SYSTEM KILL SESSION '<sid>,<serial#>';
  5. Depois de executado o comando KILL e confirmado sua execução com sucesso, você poderá executar o comando DDL desejado:
    ALTER TABLE <SCHEMA>.<TABELA_TEMPORARIA> MODIFY(COLUNA NUMBER (20,0));
  6. Por fim, libere o lock realizado no passo1 através do comando:
    rollback;

E só 😉


Páginas:1234567...17