Em um dos projetos, havia a necessidade de transferir o processo de importação de dados de sistemas de terceiros para uma arquitetura de microsserviço. O Apache NiFi foi escolhido como ferramenta. Como primeira experiência experimental, a importação do registro do Federal Tax Service foi selecionada.
Os dados USRLE são publicados como arquivos XML empacotados em arquivos ZIP. Os arquivos são organizados diariamente em um recurso https://ftp.egrul.nalog.ru/
em um diretório separado para a data correspondente. Para acesso, a chave é # PKCS12.
A tarefa que precisa ser resolvida com o NiFi é fazer o download de arquivos do Serviço Fiscal Federal e preparar os dados baixados para importação em nossos serviços. Este artigo descreve como implementar downloads de arquivos.
Fonte de dados
A obtenção de dados do USRLE é realizada como parte dos bancos de dados do Serviço Federal de Tributação "Integração e Acesso ao Cadastro Estadual Unificado de Pessoas Jurídicas e USRIP". Uma descrição do modelo de interação é apresentada aqui .
Esse é o recurso do Federal Tax Service, do qual você deseja baixar arquivos.

Os diretórios com o sufixo CHEIO são o descarregamento do registro completo no início do ano correspondente. Os catálogos restantes são atualizações diárias no registro. Estamos interessados em baixar atualizações diárias.
Configuração de fluxo no Apache NiFi
A tarefa do fluxo é coletar uma lista de arquivos de catálogo com o upload de ontem, obter esses arquivos e descompactá-los.
NiFi :
- FlowFile,
- HTML
- HTML ,

FlowFile
FlowFile GenerateFlowFile.
24 FlowFile fnsEgrulURL. https://ftp.egrul.nalog.ru/?dir=EGRUL/14.04.2020
. NiFi Expression Language:
${literal('https://ftp.egrul.nalog.ru/?dir=EGRUL/'):append(${now():toNumber():minus(86400000):format('dd.MM.yyyy')})}
Essa. a data atual é obtida e convertida em uma representação numérica da data. 86.400.000 milissegundos são subtraídos dele. O resultado é convertido em uma representação de sequência da data no formato dd.MM.aaaa. A data resultante é adicionada à parte permanente do link.A saída é um FlowFile do seguinte formato:
Recuperando conteúdo do diretório
O processador InvokeHTTP é usado para obter o conteúdo do diretório . Ele executa uma solicitação GET usando o link para o diretório com o upload de ontem. Em resposta, o processador recebe o código HTML do catálogo e adiciona esse código HTML ao FlowFile como conteúdo.
Imagens de tela do processador InvokeHTTP :
HTTPMethod — GET;
Remote URL — , URL . ${fnsEgrulURL}
— FlowFile fnsEgrulURL;
SSL Context Service — SSLContextService , .. HTTPS. #PKCS12 .
FlowFile , , — HTML- .
SSLContextService
SSLContexService #PKCS12 , , .
cacerts JDK. . https://fns.egrul.nalog.ru
, #PKCS12. .

Na cadeia de certificados, você deve selecionar o certificado de Serviço de imposto DPC russo e exportá-lo no formato .CER na codificação DER . Em seguida, você precisa importar o certificado do arquivo recebido para o repositório cacerts usando o utilitário keytool . Por exemplo, assim:
C:\Program Files\Java\jdk1.8.0_121\bin> keytool -importcert -keystore "C:\Program Files\Java\jdk1.8.0_121\jre\lib\security\cacerts" -file { .CER}
A senha padrão para cacerts é changeit .cacerts , NiFi . , Persistent Volume. SSLContextService. PKSC12, cacerts — JKS.
GetHTMLElement, HTML- FlowFile-. ZIP-.
<div id="page-content" class="container">
<div id="directory-list-header">
<div class="row">
<div class="col-md-7 col-sm-6 col-xs-10"></div>
<div class="col-md-2 col-sm-2 col-xs-2 text-right"></div>
<div class="col-md-3 col-sm-4 hidden-xs text-right"> </div>
</div>
</div>
<ul id="directory-listing" class="nav nav-pills nav-stacked">
<li data-name=".." data-href="https://ftp.egrul.nalog.ru/?dir=EGRUL">
<a href="https://ftp.egrul.nalog.ru/?dir=EGRUL" class="clearfix" data-name="..">
<div class="row">
<span class="file-name col-md-7 col-sm-6 col-xs-9">
<i class="fa fa-level-up fa-fw"></i>
.. </span>
<span class="file-size col-md-2 col-sm-2 col-xs-3 text-right">
- </span>
<span class="file-modified col-md-3 col-sm-4 hidden-xs text-right">
2020-04-05 22:00:00 </span>
</div>
</a>
</li>
<li data-name="EGRUL_2020-04-05_1.zip" data-href="EGRUL/05.04.2020/EGRUL_2020-04-05_1.zip">
<a href="EGRUL/05.04.2020/EGRUL_2020-04-05_1.zip" class="clearfix" data-name="EGRUL_2020-04-05_1.zip">
<div class="row">
<span class="file-name col-md-7 col-sm-6 col-xs-9">
<i class="fa fa-file-archive-o fa-fw"></i>
EGRUL_2020-04-05_1.zip </span>
<span class="file-size col-md-2 col-sm-2 col-xs-3 text-right">
528.78KB </span>
<span class="file-modified col-md-3 col-sm-4 hidden-xs text-right">
2020-04-05 22:00:24 </span>
</div>
</a>
<a href="javascript:void(0)" class="file-info-button">
<i class="fa fa-info-circle"></i>
</a>
</li>
</ul>
</div>
:
URL — URL HTML-;
CSS Selector — . li[data-name^=EGRUL]
— li
, data-name
, EGRUL
;
Output Type — Attribute
— HTML-;
Destination — flowfile-attribute
— FlowFile- ( HTMLElement);
Attribute Name — , . abs:${literal('data-href')}
— URL (abs:
) + data-href
, CSS-.
, CSS- FlowFile ZIP- HTMLElement.
InvokeHTTP , HTML- . URL HTMLElement, ZIP-. SSLContextService .
ZIP- FlowFile .
UnpackContent. — ZIP.
Imagens de processador UnpackContent Na saída, o processador cria um FlowFile para cada arquivo XML descompactado do arquivo ZIP.
Mais longe...
Além disso, cada XML precisa ser convertido em JSON e dividido por organização, porque cada XML contém de 1 a 1000 instruções de registro. E a partir do JSON no futuro, será possível carregar dados no armazenamento SQL ou NoSQL.
A conversão de XML para JSON e AVROSchema está no próximo artigo.