# Integração de metadados CRM - SGDP via Totvs Link
## Passos necessários para a integração
### 1. Registrar a aplicação no Totvs RAC
Neste passo o Roger solicitou a criação do produto "TOTVS CRM" no RAC para os ambientes
Em breve teremos a possibiliadde de registrar novos tenants dinamicamente para que possamos automitizar completamnete o processo, ou seja, ao cadastrarmos um novo cliente e criar um tenant para o mesmo no cloud manager, receberemos por mensageira a lista dos tenants disponíveis, iremos comparar com os que existem previamente no serviço data protection e atualizar os mesmos, é importante registrar cada novo tenant no RAC
para que possamos receber as mensagens para este tenant.
### 2. Criar o tenant do CRM no SGDP
Foi criado o tenant para o desenvolvimento chamado "totvscrm" e cadastrado os usuários com o perfil de acesso DPO.
Para o acesso às telas usamos o endereço https://totvscrm.sgdp.dev.totvs.app/
Para acessar o RAC desse tenant, pode ser utilizado o endereço: https://totvscrm.rac.dev.totvs.app/
### 3. Associar o tenant ao produto no SGDP
Foi associado o tenant "totvscrm" ao produto "TOTVS CRM" no SGDP na instância admin;
### 4. Importar a lib do Totvs Client no data-protection
Utilizar as informações do Totvs Link para configuração do Totvs Client no serviço: https://arquitetura.totvs.io/solution-books/TOTVSApps/services/support-elements/LINK/
### 5. Realizar a configuração do arquivo yaml de propriedades
Segue um exemplo do arquivo de configuração usado pelo TOTVS CRM:
```
# TOTVS LINK Config
totvs:
link:
auth:
url: https://admin.rac.dev.totvs.io/totvs.rac/connect/token
client: totvscrm
secret: b517f1b7-2203-441f-a69a-8f613e691738
tenants:
- tenant:
client: 59f1e4a6ed4c475394e2fd6438254c2d
secret: 5f0e57e2bbb446c890de3e2dc9cf61f5
client:
subscriptions:
- SGDPDataCommand
- SGDPMaskCommand
server:
host: link.dev.totvs.app
port: 443
secure: true
```
Nota: Existe a possibilidade de adicionar todos os tenants no arquivo de configuração, mas não vamos optar por essa abordagem, pois seria necessário reiniciar os serviços todas as vezes que tivesse um novo tenant.
Está é toda a configuração necessária do lado do client, que será a aplicação Java que consumirá
as mensagens e enviará para o Link Service.
Deve ser informado no arquivo de configuração yaml os atributos abaixo
#### Autenticação do `Link client` do CRM no `Link service`
Para a autenticação, deve ser enviado os dados dentro da tag *auth*:
- url: endereço de autenticação com o Totvs RAC
- Exemplo: https://admin.rac.dev.totvs.io/totvs.rac/connect/token (*RAC de dev*)
- client: descrição da chave de acesso
- Exemplo: totvscrm
- secret: senha da chave de acesso
- Exemplo: b517f1b7-2203-441f-a69a-8f613e691738;
Sendo essa chave (client e secret) gerada no Totvs RAC, pelos seguintes passos:
- acessar o menu "Clientes OAuth" e encontrar o serviço/produto do `LINK service`, conforme imagem abaixo:

- editar o `LINK service` criando uma nova chave de acesso para ser utilizada no `Link client do CRM`, conforme imagem abaixo:

> Acredito que não vamos ter acesso a fazer essa criação da chave de acesso no Totvs RAC, ficando como responsabilidade do time do SGDP, já que esse processo deve ser executado uma única vez. Sendo nossa responsabilidade somente cadastrar corretamente no arquivo .yaml
#### Relação de tenants
> Informar o client e secret de todos os tenants??
> - client: tenant_id ??
> - secret: senha para o tenant ??
**Manualmente** essa chave (client e secret) do tenant é gerada no RAC do tenant, somente para usuários *admin*, que é diferente do Totvs RAC, ou seja, cada tenant tem o seu RAC próprio, onde também deve ser gerada a chave de acesso para ser utilizada pelo `Link client` do CRM, seguindo os passos:
- acessar o menu "Cadastro de Clientes OAuth", conforme imagem abaixo:

- incluir um novo registro para o produto "TOTVS CRM", conforme imagem abaixo:

- clicar em `Gerar` para gerar a senha secreta (**secret**), que deve ser copiada, pois depois não ficará mais visivél em tela;
- já o **client** (chamado de ClientId) e o tenant_id (identificado como Id do Tenant), só ficam visíveis com a edição do registro, conforme imagem abaixo:

> Lembrando que o tenant_id será necessário para o envio e consumo das mensagens, já que ele faz parte do *header* da mensagem
>*Ponto ANA*: Não tenho certeza aonde o tenant é criado, mas acredito que seja no Totvs RAC, conforme percepção no exemplo do Roger abaixo, onde tem um menu: Cadastro de Tenants

Se realmente for, para fazermos uma inseção automática do tenant, estou achando que vamos ter dois processos: um para criar o tenant no Totvs RAC e outro para criar a chave de acesso no RAC do tenant... só se eles tiverem um endpoint lá que já faça tudo isso kkk
#### Subscrição mensageria
Informar qual fila da mensageria deverá estar subscrito, dentro da tag *subscriptions*:
- SGDPDataCommand: Fila para consulta de dados anonimizados?
- SGDPMaskCommand: Fila para mensagens de anonimização?
> **Existem filas de retorno?**
> - SGDPDataResponse?
> - SGDPMaskResponse?
#### Acesso Totvs Link
Deve ser informado os dados de acesso ao servidor do Totvs Link, especificado dentro da tag *server*:
- host: URL do servidor do Totvs Link
- Exemplo: link.dev.totvs.app
- port: Porta do servidor do Totvs Link
- Exemplo: 443
- secure: Indica se a comunicação será feita de forma segura
- Exemplo: true
### 6. Criação do modelo para o tenant?
Existem duas possibilidades de informar para o servidor os tenants que queremos consumir.
Atualmente para cadastrar um novo tenant é necessário solicitar para a equipe do Link Service,
após isso feito, podemos definir os tenants que iremos filtrar de duas formas:
1. A primeira opção é utilizando no arquivo de configuração, citado mais acima:
```
auth:
url: https://admin.rac.dev.totvs.io/totvs.rac/connect/token
client: totvscrm
secret: b517f1b7-2203-441f-a69a-8f613e691738
tenants:
- tenant:
client: 59f1e4a6ed4c475394e2fd6438254c2d
secret: 5f0e57e2bbb446c890de3e2dc9cf61f5
```
2. A segunda opção está em desenvolvimento, Foi solicitado para que possamos cadastrar tenants dinamicamente.
Onde precisamos cadastrar nossos tenants por meio de REST ou mensageria, recebemos um client e uma secret para o mesmo. Sempre que temos um novo cliente, recebemos essa informação no data protection por mensageria e cadastramos esse novo tenant. Para tenants que não estão sendo mais utilizados, por exclusão por exemplo, fazemos uma verificação no serviço para que possamos excluir estes tenants do Link Service.
Como não teremos nada preenchido no tenants, iremos consumir todas as mensagens, além de cadastrar e excluir tenants dinamicamente.
### 7. Qual a diferença entre SGDP...Tenant... e SGDP...Model...?
Quando é utilizado o Model no meio do tópico significa que é algo padrão que servirá para todos os tenants, entretanto, quanto o Tenant é utilizado é algo personalizado para cada tenant. Aparentemente utilizaremos
apenas os tópicos que contém o Tenant no meio, já que não mesmo as entidades padrões podem ser personalizadas e adicionadas novos campos pelos clientes.
É importante lembrar que um modelo padrão, ou seja, os models application, não são alterados por metadados específicos. Ou seja, um modelo application, não será deletado por um DeleteTenant por exemplo.
### 8. Como cadastrar um novo produto e aplicação?
Basta enviar uma mensagem para o seguinte tópico: SGDPUpdateApplicationMetadata. Importante lembrar que o applicationId e também o productId são apenas agrupadores. Quando estamos utilizamos o application e o product default, não conseguimos realizar todas as operações.
```
{
"header": {
"type": "SGDPUpdateApplicationMetadata"
},
"content": {
"applicationId": "sgdp-sample-aggregate-dev",
"productId": "sgdp-sample",
}
}
```
Nota: o dado só será mostrado na tela do Totvs Link se o mesmo estiver configurado para ser mostrado, no seguinte link: https://totvscrm.sgdp.dev.totvs.app/config

O produto récem cadastrado deve ser selecionado no campo de multi select produtos.
### 9. Envio do metadado?
```
**Metadados** são os objetos e as informações do mesmo, contendo se o campo pode ser anonimizado e seus tipos.
```
Nota: É importante frisar que esse tópico vai atualizar todos os metadados já adicionados, isso significa que é necessário enviar uma lista com todos os metadados pertinentes aquele tenant, caso contrário, os metadados que estavam previamente gravados, serão excluidos e restará ou serão adicionados apenas os que estão sendo enviados nessa mensagem.
Entidade para salvar ou atualizar todos os metadados de uma vez:
```
{
"header": {
"type": "SGDPUpdateApplicationMetadata"
},
"content": {
"applicationId": "sgdp-sample-aggregate-dev",
"productId": "sgdp-sample",
"models": {
"br.com.sgdp.sample.model.Customer": {
"sgdpSupport": true,
"description": "Cadastro de Clientes",
"attributes": {
"gender": {
"type": "String",
"description": "Gender",
"sgdpData": {
"sensitive": true,
"type": "EMPTY",
"allowsAnonymization": false,
"identification": false
}
}
}
}
}
}
}
```
### 10. Como atualizar um metadado em especifico?
SGDPUpdateApplicationModel. O tópico SGDPUpdateApplicationMetadata se alterado, irá sobreescrever, os registros anteriores, ou seja, caso foi enviado apenas dois registros e haviam quatro, apenas dois restarão, os outros são serão excluidos automaticamente.
Para atualizar um modelo em especifico, basta enviar uma mensagem para o seguitne tópico:
Com o seguinte payload:
```
{
"header": {
"type": "SGDPUpdateApplicationModel"
},
"content": {
"applicationId": "sgdp-sample-aggregate-dev",
"modelId": "br.com.sgdp.sample.model.Customer",
"model": {
"sgdpSupport": true,
"description": "Cadastro de Clientes",
"attributes": {
"gender": {
"type": "Boolean",
"description": "Gender",
"sgdpData": {
"sensitive": true,
"type": "EMPTY",
"allowsAnonymization": false,
"identification": false
}
},
"name": {
"type": "String",
"description": "Name",
"sgdpData": {
"sensitive": true,
"type": "EMPTY",
"allowsAnonymization": false,
"identification": false
}
}
}
}
}
}
```
### 11. Como excluir uma aplicação?
Ao excluir uma aplicação, é importante lembrar que todas as politicas de privacidade e também os metadados previamentes associados a esse aplicação serão perdidos, serão todos excluidos automaticamente.
Para excluir uma aplicação basta enviar para o seguinte tópico: SGDPDeleteApplication.
Com o seguinte payload:
```
{
"header": {
"type": "SGDPDeleteApplication"
},
"content": {
"applicationId": "sgdp-sample-app"
}
}
```
### 12. Como excluir um modelo especifico?
Para excluir um modelo especifico basta enviar para o seguinte tópico: SGDPDeleteApplicationModel.
Com o seguinte payload:
```
{
"header": {
"type": "SGDPDeleteApplicationModel"
},
"content": {
"applicationId": "sgdp-sample-app",
"modelId": "Jedi"
}
}
```
### 13. Como consumir mensagens utilizando o TOTVS LINK?
Tudo que se faz necessário é a implementação de apenas uma interface, após de configurado o arquivo yaml propriamente.
Segue o exemplo de uma implementação abaixo:
```
@Component
public class TotvsLinkMessageHandler implements MessageHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TotvsLinkMessageHandler.class);
@Autowired
private LinkService service;
@Override
public void handle(final LinkMessage message) throws Exception {
LOGGER.info("Message: " + message.getDeliveryTag() + message.getMessageContent());
service.ackMessage(message.getDeliveryTag(), true);
service.sendMessage("SGDPDataResponse", message.getMessageContent(), "SGDP");
}
}
```
### 14. Como atualizar (Inserir ou modificar) um Metadata de um Tenant em especifico?
Este funciona de maneira muito parecida com o tópico SGDPUpdateApplicationMetadata. Entretanto, a diferença é que esse é para um tenant em especifico, porém as regras são as mesmas.
Para atualizar basta enviar uma mensagem para o seguinte tópico: SGDPUpdateTenantMetadata.
Com o seguinte tópico:
```
{
"header": {
"type": "SGDPUpdateTenantMetadata",
"tenantId": "5d097ae0-1720-40f8-9e44-546245d34e6c"
},
"content": {
"applicationId": "totvs-crm",
"productId": "totvscrm",
"models": {
"br.com.sgdp.sample.model.Test": {
"sgdpSupport": true,
"description": "Cadastro de Clientes",
"attributes": {
"test": {
"type": "Boolean",
"description": "Gender",
"sgdpData": {
"sensitive": false,
"type": "EMPTY",
"allowsAnonymization": false,
"identification": false
}
}
}
}
}
}
}
```
### 15. Como atualizar (Inserir ou modificar) um modelo de um Tenant em especifico?
Este tópico é bem parecido com o tópico: SGDPUpdateApplicationModel
A diferença é que ao usar o mesmo, atualizará apenas o modelo no tenant, ou seja, não é algo padronizado. Para fazer isso, basta enviar para o seguinte tópico: SGDPUpdateTenantModel
Nota: Pelo que eu entendi, o modelo e a aplicação que serão enviados no payload já devem previamente existir.
Com o seguinte payload:
```
{
"header": {
"type": "SGDPUpdateTenantModel",
"tenantId": "5d097ae0-1720-40f8-9e44-546245d34e6c"
},
"content": {
"applicationId": "totvs-crm",
"modelId": "br.com.sgdp.sample.model.Test2",
"model": {
"sgdpSupport": true,
"description": "Cadastro de Clientes",
"attributes": {
"working": {
"type": "Boolean",
"description": "Gender",
"sgdpData": {
"sensitive": false,
"type": "EMPTY",
"allowsAnonymization": false,
"identification": false
}
}
}
}
}
}
```
### 16. Como atualizar a politica de dados pessoais padrão da aplicação?
É importante lembrar que só existe uma politica de dados por aplicação.
A política pode ser vista abaixo:

Para atualizar a política da aplicação basta enviar uma mensagem com o seguinte tópico: SGDPUpdateApplicationPrivacy
E com o seguinte payload:
```
{
"header": {
"type": "SGDPUpdateApplicationPrivacy"
},
"content": {
"applicationId": "totvs-crm",
"privacyText": "Política de privacidade da aplicação..."
}
}
```
### 17. Como excluir um modelo criado a partir de um tenant?
Para excluir um modelo específico criado a partir de um tenant e não de um modelo da aplicação, basta apenas
enviar uma mensagem para o seguinte tópico: SGDPDeleteTenantModel
Com o seguinte payload:
```
{
"header": {
"type": "SGDPDeleteTenantModel",
"tenantId": "5d097ae0-1720-40f8-9e44-546245d34e6c"
},
"content": {
"applicationId": "totvs-crm",
"modelId": "br.com.sgdp.sample.model.Test2"
}
}
```
### 18. Como excluir um metadado de um tenant em específico?
Nota: É importante frisar que apesar do nome do tópico, não será excluido os modelos, além disso, os modelos que forem padrão da aplicação, também não serão excluídos.
Mas para excluir os modelos por tenant de uma vez, por tenant, basta enviar uma mensagme para o seguinte tópico: SGDPDeleteTenantMetadata.
Com o seguinte payload:
```
{
"header": {
"type": "SGDPDeleteTenantMetadata",
"tenantId": "5d097ae0-1720-40f8-9e44-546245d34e6c"
},
"content": {
"applicationId": "teste"
}
}
```
### 19. Fluxo de cadastro de metadados no warmup
```mermaid
sequenceDiagram
WARMUP->>+Cadastro dos metadados no SGDP: Cadastra todos os tenants no RAC e salva os ids gerados no banco
WARMUP->>+Cadastro dos metadados no SGDP: Traz do banco todas os tenants, junto com os ids gerados pelo RAC e todos os seus respectivos metadados
WARMUP->>+Cadastro dos metadados no SGDP: Envia os metadados formatados para o seguinte tópico: SGDPUpdateApplicationMetadata
Note right of WARMUP: É importante enviar no header o tenantId, para a aplicação saber para onde enviar o metadado
Note right of WARMUP: A aplicação e o produto são criados ao envio do SGDPUpdateApplicationMetadata
```
### 20. Informações importantes
Por enquanto, ao ser enviado um payload inválido, não temos nenhum tipo de validação, ou seja, ainda que o serviço não consiga processar, não receberemos erro algum.
## Documentação de referência
- Portal oficial da documentação SGDP
- https://arquitetura.totvs.io/solution-books/TOTVSApps/services/support-elements/SGDP/
- Documentação swagger do ambiente DEV:
- https://link.dev.totvs.app/swagger/swagger-ui/index.html?configUrl=/swagger/swagger-config#/
- Exemplo de metadado:
- https://sgdp.dev.totvs.app/sgdp-jedi-order/sgdp/metadata