Ir para o conteúdo principal

Integração entre os sistemas Consignação e Governa para troca de informações

Data de elaboração 17/16/2023
Responsável pelo estudo
  • Alef Carvalho da Silva (Analista)
Equipe do estudo
  • André Honório de Andrade Silva (Tecnico)
  • Gezinéia Paula da Costa (Product Owner)
  • Emanuel Rufino Alcantara de Lima (Analista)
  • Alef Carvalho (Analista)
  • Gustavo Felix (Analista)
Alvo Alpha Serviços
Origem

VING-1388:  Eu, Vingadores, preciso realizar um estudo sobre a integração da consignação com o governa

Objetivo

O presente estudo visa analisar a viabilidade técnica e propor soluções para a integração entre os sistemas Consignação e Governa.


1 - OBJETIVO

O Presente estudo objetiva levantar as formas de integração para consumo das informações sensíveis entre os sistemas Governa e Consignação.

1.1 JUSTIFICATIVA

Atualmente a troca de informações entre os dois sistemas de dá por meio da exportação e importação de arquivos de texto plano. O processo de transporte destes arquivos entre os sistemas é feito de maneira manual, desta forma não há qualquer garantia de integridade das informações transmitidas.

Além disso um grande volume de informação desnecessária é transmitido por meio destes arquivos visto que todos os registros do banco de dados são empacotados no arquivo. Durante o processo de leitura é feito a verificação de duplicidade das informações e nesse caso o registro do arquivo é ignorado, fazendo com que o processo de leitura do arquivo atualmente leve em torno de 4 (quatro) dias.

1.2 RESULTADOS ESPERADOS

Espera-se que, após este estudo, seja possível identificar se há viabilidade para construção da integração entre os sistemas, além dos meios e recursos técnicos necessários para tal.

2 - INTRODUÇÃO

O sistema Consignação realiza o gerenciamento de pedidos de empréstimo na modalidade consignado para os servidores do quadro efetivo do Governo do Estado de Rondônia.

2.1 - GARANTIA DE INTEGRIDADE

Com a integração entre os dois sistemas há a possibilidade de se implantar técnicas de verificação da integridade dos arquivos visando garantir que os mesmos não foram alterados ou corrompidos durante a transmissão.

2.2 - MENOR TEMPO DE IMPORTAÇÃO 

A transmissão automática dos arquivos entre os sistemas tornará possível o envio somente das informações do fechamento atual, eliminando dados que já foram importados anteriormente e otimizando o tempo de leitura e importação dos arquivos.

3 - DESENVOLVIMENTO

3.1 CENÁRIO ATUAL 

Como já mencionado os dois sistemas são interdependentes, desta forma um usuário com permissões de administrador no sistema de consignação pode exportar ou importar os tipos de arquivo a seguir: 

Exportação:

        • Registro de averbações
        • Desconto de cartão de crédito

Importação:

        • Lotação
        • Cargo
        • Verba
        • Servidor
        • Pensionista
        • Margem
        • Averbação
        • Classificação
        • Retorno
        • Fixa e variável
        • Variável cartão
        • Retorno com CODAVB
        • Retorno data de crédito
        • Averbação de exclusão

3.2 POSSÍVEIS SOLUÇÕES

3.2.1 INTEGRAÇÃO VIA SERVIÇO DE MESSAGERIA

Nesta abordagem a transmissão e recepção manual dos arquivos é substituída por uma comunicação direta entre os dois sistemas por meio de um serviço de messageria RabbitMQ. 

Para tal deveremos adicionar as entradas abaixo no arquivo application.properties e em seguida adicionar as entradas correspondentes em cada arquivo de configuração de variáveis de ambiente.

sprint.rabbitmq.host=${RABBITMQ_HOST}
sprint.rabbitmq.port=${RABBITMQ_PORT}
sprint.rabbitmq.username=${RABBITMQ_USERNAME}
sprint.rabbitmq.password=${RABBITMQ_PASSWORD}
RABBITMQ_HOST={host do servidor rmq}
RABBITMQ_PORT=5672
RABBITMQ_USERNAME={usuário do servidor rmq}
RABBITMQ_PASSWORD={senha do servidor rmq}

Em seguida deveremos declarar a dependência necessária para conexão entre o Spring Boot e o servidor RabbitMQ no arquivo pom.xml

<dependency>
  <groupId>org.springframework.amqp</groupId>
  <artifactId>spring-rabbit</artifactId>
</dependency>

As filas de comunicação entre os sistemas serão declaradas numa classe com propriedades estáticas no package de constantes.

package br.com.gov.consignacao.constante;

public final class RMQ {
  public static String QUEUE_EXPORTACAO = "consignacao.exportacao";
  public static String QUEUE_IMPORTACAO = "consignacao.importacao";
}

Deverá também ser criada uma classe de inicialização da conexão que será automaticamente inicializada pelo Sprint durante a inicialização da aplicação.

package br.com.gov.consignacao.connections;

import br.com.gov.consignacao.constante;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class RMQConnection {
  
  private static final String AMQP_EXCHANGE_NAME = "amq.direct";

  private AmqpAdmin amqpAdmin;

  public RMQConnection(AmqpAdmin amqpAdmin){
    this.amqpAdmin = amqpAdmin;
  }

  private Queue getQueue(String nomeFila){
    return new Queue(nomeFila, true, false, false);
  }

  private DirectExchange getExchange() {
    return new DirectExchange(AMQP_EXCHANGE_NAME);
  }

  private Binding getBinding(Queue queue, DirectExchange exchange) {
    return new Binding(queue.getName(), Binding.DestinationType.QUEUE, exchange.getName(), queue.getName(), null);
  }

  //está função é executada assim que nossa classe é instanciada pelo Spring, devido a anotação @Component
  @PostConstruct
  private void setup() {
    
    DirectExchange directExchange = this.getExchange();
    
    Queue exportacaoQueue = this.getQueue(RMQ.QUEUE_EXPORTACAO);
    Queue importacaoQueue = this.getQueue(RMQ.QUEUE_IMPORTACAO);
    
    Binding exportacaoBinding = this.getBinding(exportacaoQueue, directExchange);
    Binding importacoBinding   = this.getBinding(importacaoQueue, directExchange);

    // registra as filas no RMQ
    this.amqpAdmin.declareQueue(exportacaoQueue);
    this.amqpAdmin.declareQueue(importacaoQueue);

    // registra a exchange no RMQ
    this.amqpAdmin.declareExchange(directExchange);

    // registra os bindings no RMQ
    this.amqpAdmin.declareBinding(exportacaoBinding);
    this.amqpAdmin.declareBinding(importacoBinding);
    
  }

Também criaremos uma classe de serviço para abstrair as funcionalidades de envio de mensagens para as filas no servidor do RabbitMQ.

package br.com.gov.consignacao.servico

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RMQService {

  @Autowired
  private RabbitTemplate rmqTemplate;

  @Autowired
  private ObjectMapper objectMapper;

  public void send(String queueName, Object message){
    try {
      String payload = this.objectMapper.writeValueAsString(message);
      this.rmqTemplate.convertAndSend(queueName, payload);
    } catch (Exception e){
      e.printStackTrace();
    }
  }
}

O recebimento de mensagens da fila será feito por meio de classes "consumidoras":

package com.microsservico.consumidorestoque.consumer;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class ImportacaoConsumer {

  @Autowired
  private ImportacaoServico importacaoServico;
  
  @RabbitListener(queues = RMQ.QUEUE_IMPORTACAO)
  private void consumer(String message) throws JsonProcessingException, InterruptedException {
    
    ImportacaoDto importacaoDto = new ObjectMapper().readValue(message, ImportacaoDto.class);

    System.out.println(importacaoDto.tipo);
    System.out.println(importacaoDto.conteudo);

    // abaixo, passamos o arquivo recebido para que o mesmo possa ser tratado pelo serviço de importação existente
    this.importacaoServico.salvar(importacao.conteudo, importacaoDto.tipo);
  
  }

}

Para as funcionalidades de exportação utilizaremos a classe RMQService para realizar o envio dos arquivos exportados pelo sistema de consignação para a fila e posterior consumo pelo Governa.

// ARQUIVO: PublicoControlador.java

@GetMapping("/exportacao/download/arquivo")
public ResponseEntity<Resource> exportarArquivos(@RequestParam(name = "tipoArquivo", required = true) String tipoArquivo,
			@RequestParam(name = "mesReferencia", required = true) Integer mesReferencia,
			@RequestParam(name = "anoReferencia", required = true) Integer anoReferencia,
			@RequestParam(name = "lotacoes", required = true) List<Long> lotacoes) {

  // Abaixo devemos alterar a lógica para enviar o arquivo para a fila RMQ
  if ("D".equals(tipoArquivo)) {
			Resource resource = averbacaoServico.exportarCartao(mesReferencia, anoReferencia, lotacoes);
			return ResponseEntity.ok().contentType(MediaType.parseMediaType("text/csv"))
					.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + "Reltorio_Cartao.csv" + "\"").body(resource);
  }

  if ("A".equals(tipoArquivo)) {
			Resource resource = averbacaoServico.exportarAverbacao(mesReferencia, anoReferencia, lotacoes);
			return ResponseEntity.ok().contentType(MediaType.parseMediaType("text/csv"))
					.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + "Reltorio_Averbacao.csv" + "\"").body(resource);
  }
  
  return null;

}

3.3 POSSÍVEIS IMPEDIMENTOS

Atualmente a manutenção do sistema de consignação é de responsabilidade do time Vingadores. A equipe ainda não havia trabalhado com as tecnologias implementadas no projeto como a linguagem de programação Java e a biblioteca de front-end VueJS. 

Também há pouca ou mesmo nenhuma documentação das regras de negócio do sistema, desta forma vislumbra-se possíveis impedimentos futuros em relação ao processo de adequação a novas atualizações, indisponibilidades ou outros problemas na integração entre os dois sistemas.

3.4 HISTÓRIAS DE USUÁRIO

Para a correta aplicação da solução proposta acima, foram mapeadas as seguintes histórias de usuário:

 
O que? Pontos Regras Produto
Realizar a configuração do projeto para consumir e enviar dados via serviço de messageria 13
  • Realizar configuração das variáveis de ambiente e do arquivo de configuração do Spring;
  • Realizar a instalação da biblioteca de dependência Spring-RabbitMQ;
  • Criar classe de conexão com o serviço de messageria;
  • Criar classe de serviço para envio de mensagens;
  • Criar classe para assinatura e validação de dados utilizando algoritimo RSA;
Consignação
Realizar a exportação do arquivo de Registro de averbações pelo serviço de messageria;messageria 85
  • Utilizar a mesma formatação atual dos arquivos de texto;
  • Assinar o payload de dados do arquivo com o algoritmo RSA;
  • Remover função atual de download do arquivo;
  • Gravar log;
Consignação
Realizar a exportação do arquivo de Desconto de cartão de crédito pelo serviço de messageria;messageria 85
  • Utilizar a mesma formatação atual dos arquivos de texto;
  • Assinar o payload de dados do arquivo com o algoritmo RSA;
  • Remover função atual de download do arquivo;
  • Gravar log;
Consignação

Realizar o recebimento e processamento dos arquivos do tipo: Lotação via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Cargo via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Verba via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Servidor via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Pensionista via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Margem via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Averbação via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Classificação via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Retorno via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Fixa e variável via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Variável cartão via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Retorno com CODAVB via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Retorno data de crédito via serviço de messageria

8

Realizar o recebimento e processamento dos arquivos do tipo: Averbação de exclusão via serviço de messageria

8

4 - CONCLUSÃO

Conclui-se pela viabilidade técnica da integração entre os dois sistemas utilizando solução de comunicação baseada em messageria.

Esta integração trará dentre outras, mais segurança e agilidade para o processo de comunicação e integração de informações entre os dois sistemas.

5 - REFERÊNCIAS