# BRAGI ## O que é? O BRAGI é um serviço que disponibiliza o padrão arquitetural **CQRS**, unindo dados de varios serviços em uma única base de dados, permitindo realizar consultas na mesma, sendo possível consultar dados de: * Vários serviços ao mesmo tempo; * Um ou mais serviços filtrando por dados de outro(s) serviço(s); * Campos customizados com o BTB e aplicar filtros nos mesmos; O BRAGI utiliza como base de dados única de leitura o **ELASTICSEARCH**, a qual é alimentada por dados dos Serviços de Negócio. E para consultar estes dados no **ELASTICSEARCH** é usado o **Prestp SQL (agora chamado de Trino)**, um mecanismo de consulta SQL distribuído e de alto desempenho para big data. ## Quais os objetivos do BRAGI? Possibilitar aplicar filtros na pesquisa avançada das listagens (preference): * Campos do App Builder (BTB) * Campos de outra entidade vínculada (joins) Criação de relatórios (Report Transactional) * Unir dados de diferentes serviços * Utilizar objetos e campos criados no BTB ## Arquitetura - CQRS CQRS significa Command Query Responsibility Segregation, em português, segregar a responsabilidade de consulta de leitura de dados da parte de escrita. Ele é um padrão arquitetural assim como [Event Sourcing](https://medium.com/@marcelomg21/event-sourcing-es-em-uma-arquitetura-de-microsservi%C3%A7os-852f6ce04595#:~:text=Event%2Dsourcing%20trata%2Dse%20uma,o%20estado%20atual%20das%20entidades.). Arquiteturamente o CQRS é muito complexo, mas o seu conceito é relativamente simples, é como utilizar-mos dois bancos de dados separados, um fica responsável pela escrita de dados, e outro é único e exclusivo para a leitura de dados (obviamente que há uma escrita de dados neste banco para ter alguma coisa para estar disponível para consulta) ![](https://i.imgur.com/stu87nX.png) Usando a imagem acima como exemplo: * Temos a parte de **UI** que é como se fosse o nosso frontend (midgard) * No **COMPONENTE** temos os serviços de negócio (Vou utilizar o BTB como exemplo) * Temos o **DB** que é o banco de dados (Postgres) * No **CACHE** seria o banco que estamos separando (CQRS/BRAGI em si)(**ELASTICSEARCH**) Resumindo como funciona hoje, o front quer gravar um campo customizado que para tabela customization-lake, portanto ele manda para o BTB (Componete) que grava no banco de dados (DB (Postgres)). Quando queremos fazer a leitura do dado, também vai para o BTB (Componente) que busca no banco de dados (DB (Postgres)). O CQRS cria um banco de dados separado, e quando mandamos persistir, criar este dado no BTB, o BTB vai mandar este dado para o banco de dados (DB) igual já é hoje, mas também vai mandar uma réplica deste dado lá para o CQRS/BRAGI (Cache). Basicamente este bando do CQRS/BRAGI é uma cópia, um espelho, dos bancos de dados dos outros serviços. Dito isto o que que acontece agora, o front ao invés de fazer a consulta no BTB (Componente), ele pode ir conforme a imagem acima, fazer a consulta (Query) direto no banco do BRAGI/CQRS, não utilizando o serviço (componente) para a consulta. Concluindo o front faz a consulta no BRAGI/CQRS e faz a escrita de dados no serviço (BTB por exemplo). ## Arquitetura - BRAGI Utilizando o padrão arquitetural CQRS foi criado o micro serviço BRAGI, que utiliza as mesmas tecnologias da nossa stack (Commons, Kotlin, etc). Um dos fatores que o difere dos seiviços existentes é que ele utiliza **ELASTICSEARCH** como base dados. #### Elasticsearch O Elasticsearch é um mecanismo para análise e consulta de dados RESTful, sendo muito parecido com as nossas APIs a forma de utilizar ele, a diferença é que ele é um mecanismo poderoso e rápido, faz uma consulta de dados muito rápida tendo a capacidade de aguentar grandes capacidades de dados, fazer filtros de diferentes maneiras possíveis assim. Possui uma documentação bem completa, acesse [aqui](https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-intro.html). O Elasticsearch tem um conceito de indice,campos e documentos. O indice fazendo uma analogia com o nosso banco relacional é como se fosse uma tabela, o campo são os campos da tabela, e o documento e como se fosse os registros. O Elaticsearch é populado pelos dados dos serviços de negócio. O Elasticsearch tem seus tipos de dados especificos, contudo temos uma conversão de tipos de dados que tem no BTB e nos tipos do Elasticsearch. ![](https://i.imgur.com/5ezJTnX.png) Para realizar consultas no elasticsearch usamos o Presto SQL ([Trino](https://trino.io/docs/current/sql.html)), então ao invés de fazermos consulta no padrão do elasticSearch com RESTfull, utilizamos o [Trino](https://trino.io/docs/current/sql.html) para realizar as consultas semelhante as utilizadas de costume ao consultar direto na base do serviço e o Trino se vira em converter. #### Contrato - BRAGI Dentro do BRAGI também é utilizado banco Postgres, tendo assim o Postgres e o Elasticsearch. O Postgres é utilizado para salvar o contrato que vai ser criado dentro do Elasticsearch, então quando vamos criar os indices que são as nossas tabelas e os campos no Elasticsearch temos que saber quais são os indices (tabelas), quais são os campos que tem, quais são os tipos que são estes campos, e estás informações vem do BTB, dos meta-objects e dos meta-attributes do BTB. Basicamente um meta-object vira um indice (tabela) dentro do Elasticsearch, um meta-attribute vira um campo de um indice (tabela) dentro do Elasticsearch, eles (meta-object, meta-attribute) são replicados dentro BRAGI, porém esta replicação deste contrato são salvos dentro de uma base de dados Postgres. Depois disso pegamos estes dados, estes meta-objects, meta-attribute e ai sim criamos a estrutura dentro do Elasticsearch. > OBS: Os documentos (registros) eles não ficam salvos dentro do banco Postgres do BRAGI, somente dentro do Elasticsearch. Todo o cenário descrito acima, exemplo, o BTB manda o meta-object pro BRAGI, manda o meta-attribute, pegamos os registros do sistema e salvamos no Elasticsearch, tudo isto é feito através da **MENSAGERIA**. #### A arquitetura do BRAGI em diagrama ![](https://i.imgur.com/DsOGQvb.png) Conforme o diagrama acima, tudo começa no BTB (business-template-builder), o BTB publica os eventos de meta-objects e meta-attributes que vai para a parte de MENSAGERIA (message-broker) basicamente é o SNS e SQS, depois estes eventos chegam no BRAGI, o BRAGI pega estes objetos e atributos e salva no PostesSQL e em sequencia ele pega estes objetos e com os eventos de meta-objects ele cria todos os indices (tabelas) do Elasticsearch, pega os eventos de meta-attributes e cria os campos dentro desses indices (tabelas) no Elastisearch, e ai ele pega todos os dados de registros de Cliente (customer), Oportunidades (opportunity), Produtos (product), Vendas (sales)... e salva estes dados direto dentro do Elasticsearch, dentro dos indices (tabelas). > Esta parte de salvar um registro no Elasticsearch é chamada de indexação, então você indexa um dado dentro de um index dentro do Elasticsearch e ele se torna um documento que é como o Elasticsearch chama o registro. #### Warm-up Quando vamos subir o BRAGI/CQRS pela primeira vez, a nossa base dados no Elasticsearch está vazia, precisa-se popular esta base com o estado atual da aplicação, preciso popular o Elasticsearch com todas as tabelas que já existam no sistema e com todos os registros, para isto foi criado este mecanismo **Warm-up**. O Warm-up é um mecanismo que utiliza mensageria que é para gente poder integrar os dados dos serviços que desejamos, quando iniciarmos o nosso CQRS pela primeira vez por exemplo em PRD, vamos fazer um Warm-up dos dados existentes hoje, ele vai pedir para o BTB mandar todos os objetos que existe hoje, ele vai pegar estes objetos e criar as tabelas e os indices no Postgres, banco do BRAGI e no Elasticsearch, o mesmo vale para todos os atributos, os registros da customization-lake e também os dados dos serviços que a gente entraria dados, customer, todos os registos da base de customer por exemplo para replicar no Elasticsearch. > OBS: Não são todas as tabelas que são replicadas para o Elasticsearch, por hora somente as entidades que os BTB possui suporte são replicadas.