Pular para o conteúdo principal

Mensageria

Conforme mencionado na visão geral da PDPJ-Br, o serviço de mensageria permite a comunicação interna entre os sistemas, módulos e serviços hospedados na PDPJ. É utilizado um Message Broker, a solução open source RabbitMQ.

Esse mecanismo de comunicação agrega uma maior robustez à arquitetura, uma vez que as mensagens são enfileiradas em filas (queues) definidas por cada aplicação, as quais podem consumir as mensagens a seu tempo e modo, ou seja, de forma assíncrona e conforme sua capacidade de processamento.

Serviço Mensageria-Proxy

É possível a utilização do serviço de Mensageria por meio de fachada REST criada especificamente para tal função. O serviço funciona como um proxy para o RabbitMQ. Assim, não é necessário profundo conhecimento da solução por parte do usuário que deseja lançar eventos no serviço.

Hands On

Um exemplo de mensagem encaminhada ao servidor RabbitMQ da PDPJ (em homologação, https://mq.stg.cnj.cloud/), é o seguinte:

Exemplo de JSON encaminhado ao RabbitMQ, no padrão esperado na PDPJ

 {
"uuid": "417fe9e0-7b8f-40c4-bb4c-b099cf5e4283",
"appName": "PJEMIDIAS",
"appVersion": "1.0.0",
"routingKey": "804.1.PJEMIDIAS.AudienciaSincronizada",
"timestamp": 1628275714,
"eventName": "AudienciaSincronizada",
"sigiloDoEvento": 0,
"payloadType": "Audiencia",
"payload": {
"idVideo": "7222",
"nrProcesso": "00012318023123123123",
"idOrgaoCorporativo": "10",
"dsVara": "CNJ",
"descricao": "Teste",
"dsTipoVideo": "Inicial",
"dtJuntada": "31/12/2010",
"link": "http://wwwh.cnj.jus.br/midias/web/audiencia/visualizar?id=9ZDdmMDIxMTBiZTBmMDJjMzdhYzkwZTRlMzhifZGUzOWFOekl5TWc9PQ%2C%2C",
"sigilo": false,
"grauEntrega": 1
},
"payloadHash": "31dfb1ea737c9364716b1fea55f21589",
"numeroUnicoProcesso": "0001234-95.2010.2.00.0000",
"autor": {
"uuid": "dbd869cd-ba5a-4be0-8acf-6dc9ba08a6cc",
"nome": "FULANO DE TAL",
"documentoIdentificacaoPrincipalValor": "73466684560",
"documentoIdentificacaoPrincipalTipo": "CPF",
"justificativaAusenciaDocumentoIdentificacao": null
},
"instanciaTribunalAcao": {
"siglaTribunal": "Tribunal de Justiça do Estado do Amazonas",
"codigoSegmentoJustica": "JCE",
"identificadorGrauJurisdicao": 1,
"outrosIdentificadores": null,
"jtr": "804"
},
"hashAlgorithm": "MD5",
"payloadHashSigned": "Qm856lYMNM8DA",
"signatureAlgorithm": "DES",
"signaturePublicKey": null,
"links": null
}

Além disso, como será explicado mais adiante, as mensagens produzidas pelas aplicações hospedas na PDPJ poderão ser registradas no serviço de notificações da plataforma para eventual consumo dos sistemas de processo judicial eletrônico dos Tribunais, de terceiros atores essenciais à Administração da Justiça, ou mesmo de pessoas.

Routings Keys

Toda mensagem possui uma Routing Key, e esta deve seguir, na PDPJ, o seguinte formato: JTR.GRAU.SIGLA-SISTEMA.NOME-EVENTO, onde o JTR é o número de três posições associados a cada Tribunal pela Resolução nº 65/2008 do CNJ (ex: 804, no caso do TJ do Amazonas); GRAU é um número de 0 a 4, indicando o grau/instância de origem (zero, se não se aplica); SIGLA-SISTEMA é o nome do serviço para fins de filtragens posteriores pelo serviço de notificações, outras aplicações, etc; e, finalmente, NOME-EVENTO, que deve ser uma descrição breve de um fato ocorrido no passado o qual aquela mensagem representa (ex: AudienciaSincronizada).

Enviando uma mensagem usando PHP

No exemplo abaixo, utilizamos a biblioteca php-amqplib/php-amqplib:

 try{
$messageBody = "{\"uuid\": \"417fe9e0-7b8f-40c4-bb4c-b099cf5e4283\", \"appName\": \"PJEMIDIAS\", .....";
$routingKey = "804.1.PJEMIDIAS.AudienciaSincronizada"
$exchange = "pdpj.exchange";
$connection = new AMQPStreamConnection(
$rabbitmq_host,
$rabbitmq_port,
$rabbitmq_user,
$rabbitmq_password,
$rabbitmq_vhost);
$channel = $connection->channel();
$channel->exchange_declare($exchange, AMQPExchangeType::TOPIC, false, true, false);
$message = new AMQPMessage($messageBody, array('content_type' => 'application/json', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
$channel->basic_publish($message, $exchange, $routingKey);
$channel->close();
$connection->close();
}
catch (\Exception $e){
throw $e;
}

Enviando uma mensagem usando Java

Caso você esteja utilizando Spring Boot como framework de sua aplicação Java, e maven como gerenciador de dependências, no arquivo POM.XML da aplicação, adicione a seguinte dependência:

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

E na classe responsável por enviar mensagens da sua aplicação:

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(String json) {
this.rabbitTemplate.convertAndSend(this.getRoutingKey(), json);
}

Lembrando que o Routing Key segue o formato explicado mais acima em routing-key.

Para facilitar a montagem do objeto json a ser encaminhado ao servidor Rabbit nas aplicações Java, é possível também fazer uso de métodos utilitários fornecidos na biblioteca pdpj-commons, escrita pelo CNJ.

Para tanto, no arquivo POM.XML, adicione as seguintes linhas:

<dependency>
<groupId>br.jus.pdpj</groupId>
<artifactId>pdpj-commons</artifactId>
<version>2.3.0</version>
</dependency>

E no código java de envio da mensagem, modifique o método sendMessage da seguinte maneira:

import br.jus.pdpj.commons.builders.DomainEventMessageBuilder;
import com.fasterxml.jackson.databind.ObjectMapper;

@Autowired
private ObjectMapper mapper;

@Autowired
private RabbitTemplate rabbitTemplate;

public void sendMessage(DTO dto, String json) {
String json = this.mapper.writeValueAsString(
DomainEventMessageBuilder
.instance("Chave para assinar a mensagem") 1
.withAppName("AppDeTeste") 2
.withAppVersion("0.0.1") 3
.withInstanciaTribunalAcao( 4
TribunalEnum.NA,
InstanciaJusticaEnum.NAO_SE_APLICA,
null)
.withAutor(new PessoaSimples( 5
UUID.randomUUID(),
"Fulano de Tal",
"Sem documento"))
.withPayload(dto) 6
.withEventName("EventoOcorrido") 7
.build());
this.rabbitTemplate.convertAndSend(this.getRoutingKey(), json);
}
  1. Uma string qualquer, para servir de chave simétrica para assinatura da mensagem. Pode ser utilizada pelo sistema que irá consumir a mensagem para desencripta-la, garantindo, assim, que a mensagem só está sendo lida por quem conhece a chave. Obs: a biblioteca pdpj-commons gera um hash SHA256 da representação json do objeto DomainEventMessage gerado por DomainEventMessageBuilder, e assina, com a chave informada, esse hash, usando o algoritmo DES.
  2. Nome da aplicação/serviço. Será utilizado na montagem do routing key, portanto, não deve possuir espaços em branco.
  3. Versão da aplicação/serviço que gerou a mensagem. Meramente informativo.
  4. Objeto do tipo InstanciaTribunal, que contém informações que serão acrescidas à mensagem. Caso seja informado um Tribunal específico, o seu JTR será colocado no routing key da mensagem. Caso contrário, será informado o valor zero no campo respectivo. Obs: um mesmo serviço pode lançar valores diferentes para InstanciaTribunal, a depender da operação. Por exemplo, um serviço nacional poderá lançar a mensagem indicando o tribunal e grau que originou a operação (ex: TJMA, primeirou grau, ou o TJRN, segundo grau, etc).
  5. Objeto do tipo Pessoa Simples, para indicar o usuário operador que realizou a ação que desencadeou a mensagem. Meramente informativo.
  6. O payload propriamente dito que será encaminhado na mensagem. Geralmente, um POJO ou DTO que contém um objeto com os dados negociais relevantes.
  7. O nome do evento que será incluído no routing key. Não deve possuir espaços em branco e deve indicar um ação ocorrida no passado.