Login Registre-se
Comportamento estranho - Rejeicao: CNPJ do transmissor do lote difere do CNPJ do transmissor da cons  XML
Índice dos Fóruns » NF-e / NFS-e / CT-e / CF-e / Certificados Digitais
Autor Mensagem
DTH

JavaC Membro

Membro desde: 03/11/2017 19:57:22
Mensagens: 36
Offline

Bom dia Pessoal,

Gostaria de compartilhar algo estranho que ocorreu esse final de semana no emissor de notas que desenvolvi.

Fiz um webservice para emissão de nota aqui na empresa, temos atualmente 53 empresas cadastradas e emitindo NFCe.
Na semana passada foram mais de 10 mil notas emitidas sem nenhum erro.

Porém, o transtorno começou na sexta-feira quando o certificado de uma empresa expirou.
Para a empresa com o certificado expirado, a autorização ocorria normalmente, mas na consulta via recibo e consulta via chave de acesso retornavam a mensagem abaixo:

Rejeicao: CNPJ do transmissor do lote difere do CNPJ do transmissor da consulta


Mas o que mais achei estranho foi que a consulta de NFCe das outras empresas começaram a dar o mesmo erro, mesmo o certificado delas estarem validos.
E para deixar mais estranho, na segunda tentativa a consulta era efetuada com sucesso.

É como se, de alguma forma, o certificado expirado tivesse interferindo na autenticação SSL das outras empresas com a SEFAZ.
Quando vimos que a empresa estava com o certificado expirado e paramos suas emissões/consultas, esse erro parou de ocorrer nas consultas das outras empresas.


Dando uma pesquisada encontrei algo interessante que alguns sites dizem a respeito do erro mencionado:


Essa divergência pode ocorrer quando temos algum certificado inválido ou vencido na máquina, juntamente com o que estamos usando para assinar as notas, pode ser que haja um conflito entre esses certificados ocasionando uma diferença entre os processos de autenticação e assinatura.



Quando temos algum certificado inválido ou vencido na máquina, juntamente com o que estamos usando para assinar as notas, pode ser que haja um conflito entre esses certificados ocasionando uma diferença entre os processos de autenticação e assinatura. Recomendamos a remoção dos certificados inválidos ou vencidos, mantendo somente os certificados corretos.

Recomendamos a remoção dos certificados inválidos ou vencidos, mantendo somente os certificados corretos.


Alguém já teve esse problema ao utilizar vários certificados ao mesmo tempo e uma delas expirar?


Obs.: Poderia ser um problema de código, onde o certificado de outra empresa estaria sendo usado para autenticar a conexão e utilizando outro certificado para assinar. Porém revisei o código e não encontrei nada que poderia ocasionar esse comportamento.
GGarcia

JavaC Membro
[Avatar]

Membro desde: 28/05/2013 17:12:21
Mensagens: 297
Offline

Você precisa rodar uma instância do seu aplicativo para cada empresa e jamais utilizar o System para alocar dados de certificado (utiliza a classe de Certificado Dinâmico disponibilizada aqui).

Esse tipo de erro ocorre porque já existe um certificado alocado em memória (do CNPJ A), usado para fazer uma transação do CNPJ B.

Se você tem apenas uma classe principal que executa suas funções com os webservices e ela é uma Singleton, façaa dela uma classe "normal" e instancie uma versão dela para cada empresa que requisita o serviço e dessa forma você isola os certificados/envios e os erros para de ocorrer.

Um factory por CNPJ seria a forma mais simples de fazer isso.

Esta mensagem foi editada 1 vez. Última atualização foi em 11/02/2019 13:18:40


If you're here, who's running hell?
marceel08

JavaC Membro

Membro desde: 03/10/2017 20:03:52
Mensagens: 27
Offline

Ola,

tivemos o mesmo problema aqui.

o problema do webservice nosso é que como nao tínhamos nenhuma fila de processamento, simplesmente chovia solicitações e elas em algum momento acabam invertendo alguns dados,

criamos uma especie de fila de processamento como protocolo

aqui, nossa api em java parece que ao processar as coisas, parecia que criava coisas na memoria, e com varias solicitacoes ao mesmo tempo, ele acabava se perdendo...



GGarcia

JavaC Membro
[Avatar]

Membro desde: 28/05/2013 17:12:21
Mensagens: 297
Offline

marceel08 wrote:Ola,

tivemos o mesmo problema aqui.

o problema do webservice nosso é que como nao tínhamos nenhuma fila de processamento, simplesmente chovia solicitações e elas em algum momento acabam invertendo alguns dados,

criamos uma especie de fila de processamento como protocolo

aqui, nossa api em java parece que ao processar as coisas, parecia que criava coisas na memoria, e com varias solicitacoes ao mesmo tempo, ele acabava se perdendo...





Suas requisições são multithreaded? Se forem, a melhor maneira de resolver isso seria usar synchronized entre model <-> webservice e para "empilhar" as requisições utilizar um ArrayBlockingQueue que é thread safe. É simples mas muito funcional.

Abraço

If you're here, who's running hell?
DTH

JavaC Membro

Membro desde: 03/11/2017 19:57:22
Mensagens: 36
Offline

Boa tarde GGarcia e marceel08!

Trouxe esse relato justamente por isso, não aloco o certificado na VM.
Cada empresa tem sua instancia do certificado e as classes envolvidas não são singleton.

Como havia mencionado emitimos semana passada mais de 10 mil notas de diferentes empresas, muitas delas paralelamente e o problema não ocorreu.
O problema só ocorreu quando um dos certificado expirou, a partir do momento que barramos emissões e consultas dessa empresa, tudo se normalizou.

Sábado e domingo as emissões e consultas ocorreram normalmente, já foram até o momento quase 2 mil notas sem nenhum erro.

É muita coincidência o problema começar para todas as empresas no momento que o certificado de uma unica empresa expirar
e parar de dar erro depois que paramos de emitir/consultar notas com esse certificado expirado.

DTH

JavaC Membro

Membro desde: 03/11/2017 19:57:22
Mensagens: 36
Offline

GGarcia wrote:
marceel08 wrote:Ola,

tivemos o mesmo problema aqui.

o problema do webservice nosso é que como nao tínhamos nenhuma fila de processamento, simplesmente chovia solicitações e elas em algum momento acabam invertendo alguns dados,

criamos uma especie de fila de processamento como protocolo

aqui, nossa api em java parece que ao processar as coisas, parecia que criava coisas na memoria, e com varias solicitacoes ao mesmo tempo, ele acabava se perdendo...





Suas requisições são multithreaded? Se forem, a melhor maneira de resolver isso seria usar synchronized entre model <-> webservice e para "empilhar" as requisições utilizar um ArrayBlockingQueue que é thread safe. É simples mas muito funcional.

Abraço


As emissões ou consultas não ocorrer paralelamente, a unica coisa perto de paralelismo que pode ocorrer é que dividi em etapas o processo todo utilizando o scheduled do spring.

Está divido em 4 crons (Rodando de 1 em 1 minuto):
- Autorização
- Consulta lote (via recibo)
- Consulta nota (via chave)
- Inutilização.

Então naquele minuto se houver 10 autorizações para serem realizadas, será feito um a um.

Já estou tomando algumas precauções.
- Tenho uma rotina que valida toda noite a expiração do certificado e ele notificava o cliente 30 dias antes da expiração. Irei notificar mais vezes durantes essa janela de tempo.
GGarcia

JavaC Membro
[Avatar]

Membro desde: 28/05/2013 17:12:21
Mensagens: 297
Offline

Se cada instância é separada e não compartilham informações, então alguma coisa ficou em aberto para isso ocorrer.

Bloquear a emissão com certificado vencido é obrigatório, senão depois dá muita confusão.

Não sei te informar onde você poderia olhar porque você usa Spring e eu tenho pavor de framework de terceiros. Gosto de ter todo o controle na minha mão, por isso nosso framewrok é "feito em casa".

Se as emissões de cada instância ocorrem em regime de fila (FIFO, creio eu), então no momento em que uma instância termina para iniciar a outra, podem ocorrer os seguintes problemas:

- Você apenas "zera" a classe de envio mas alguma variável, provavelmente static, mantem seu valor e gera erro nas outras classes
- A classe da instancia está correta ao ser inicializada, mas ela usa dados de outras classes/model do sistema e alguma variável/flag static manteve a informação de que o certificado estava vencido e isso replicou para todas as instâncias seguintes
- As duas coisas juntas

Não é fácil de detectar o erro, mas relativamente simples de corrigir. Verifique todos os construtores das classes envolvidas e como suas passagens de parâmetro ocorrem. Se você inicializa com construtor default, todas as variáveis estão sendo inicializadas para valores default conhecidos?

Depois disso, confira os métodos de criação/destruição das instâncias e quais dados são repassados nas suas inicializações.

As vezes um detalhe minúsculo passa despercebido e isso tira o sono por semanas.

Abraço

Esta mensagem foi editada 1 vez. Última atualização foi em 11/02/2019 18:16:43


If you're here, who's running hell?
DTH

JavaC Membro

Membro desde: 03/11/2017 19:57:22
Mensagens: 36
Offline

Bom dia GGarcia,

Valeu pelas dicas.

Fiz uma rotina para bloquear as emissões em caso de certificado vencido.

Essa semana as emissões ocorreram normalmente, sem o bendito erro.
Atualizamos o certificado dessa empresa e as emissões continuaram OK.

Continuarei analisando, mas acredito que não irá mais ocorrer o problema, pois não existe mais a possibilidade de emissões com certificado vencido no sistema.
Quando eu descobrir a causa, eu volto a reportar neste post

Obrigado!
GGarcia

JavaC Membro
[Avatar]

Membro desde: 28/05/2013 17:12:21
Mensagens: 297
Offline

DTH wrote:Bom dia GGarcia,

Valeu pelas dicas.

Fiz uma rotina para bloquear as emissões em caso de certificado vencido.

Essa semana as emissões ocorreram normalmente, sem o bendito erro.
Atualizamos o certificado dessa empresa e as emissões continuaram OK.

Continuarei analisando, mas acredito que não irá mais ocorrer o problema, pois não existe mais a possibilidade de emissões com certificado vencido no sistema.
Quando eu descobrir a causa, eu volto a reportar neste post

Obrigado!


Bom dia.

Legal que conseguiu resolver, mas seria interessante descobrir porque um certificado vencido de uma empresa fez com que todas as outras não emitissem também. Pode, no futuro, ocorrer algum outro tipo de situação adversa e tudo parar novamente.

Correções emergenciais de bugs, quando são urgentíssimas, corremos atrás e damos um fim no problema. Depois é que vem a parte chata: procurar a causa que, dependendo da complexidade do código e o operacional da parte afetada, pode demorar

Abraço

If you're here, who's running hell?
 
Índice dos Fóruns » NF-e / NFS-e / CT-e / CF-e / Certificados Digitais
Ir para:   
Powered by JForum 2.1.9 © JForum Team