8.7 KiB
Sistema de Sincronização ServiceNow <> GLPI
Visão Geral
Esta aplicação Node.js é um middleware projetado para realizar a sincronização bidirecional de tickets entre uma instância do ServiceNow (SNOW) e uma do GLPI. O objetivo é manter os tickets, seus status e comentários consistentes entre as duas plataformas, automatizando o fluxo de trabalho para as equipes de suporte.
A aplicação funciona como um job agendado (por exemplo, via cron) que executa um ciclo completo de sincronização.
Fluxo de Execução
A aplicação segue uma ordem de execução estrita para garantir a consistência dos dados. O ponto de entrada é o arquivo src/app.js, que orquestra a chamada dos seguintes controladores:
-
processErrorController- Limpeza de Erros- Objetivo: Aumentar a resiliência do sistema.
- Ação: Busca por tickets que falharam em execuções anteriores (marcados com status de
error). Ele reseta o status desses tickets para um estado anterior válido (ex:pending_checkousynced), permitindo que eles sejam reprocessados no ciclo atual.
-
processTicketsController- Criação de Tickets- Objetivo: Trazer novos tickets do ServiceNow para o GLPI.
- Ação:
- Busca no SNOW: Invoca o
processSyncControllerpara buscar incidentes e requisições novas ou atualizadas no ServiceNow, utilizando uma "marca d'água" (timestamp) para otimização. - Criação no GLPI: Para cada novo ticket coletado, o
glpiTicketServiceé chamado para:- Verificar se o ticket já existe no GLPI para evitar duplicatas.
- Formatar os dados (título, descrição, categoria, etc.).
- Criar o ticket correspondente no banco de dados do GLPI.
- Busca no SNOW: Invoca o
-
processCommentsController- Sincronização de Comentários- Objetivo: Manter as conversas dos tickets sincronizadas.
- Ação: Para cada ticket ativo, realiza uma sincronização bidirecional de comentários (notas/follow-ups):
- SNOW -> GLPI: Busca novos comentários no ServiceNow, os salva no banco intermediário e os insere como follow-ups no GLPI.
- GLPI -> SNOW: Busca novos follow-ups no GLPI, os sanitiza (remove HTML, trata imagens) e os envia como
work_notespara o ServiceNow.
-
processStatusAndClosureController- Sincronização de Status e Fechamento- Objetivo: Manter os status dos tickets alinhados e gerenciar o ciclo de vida (resolução e fechamento).
- Ação: Realiza uma sincronização bidirecional de status, tratando reaberturas, pausas, resoluções e fechamentos em ambas as direções.
Regras de Negócio Principais
A aplicação implementa várias regras de negócio para gerenciar a complexidade da sincronização:
Controle de Fluxo com "Bastão" (source_last)
- Para evitar conflitos de atualização (race conditions), o sistema utiliza um campo
source_lastna tabelaticket_sync. - Este campo funciona como um "bastão da palavra": o sistema que realiza a última atualização (SNOW ou GLPI) "segura o bastão".
- O sistema oposto só pode atualizar o ticket se ele estiver com o bastão. Isso garante que as atualizações de status e comentários ocorram de forma ordenada.
Criação e Enriquecimento de Tickets
- Mapeamento: Tickets do ServiceNow são mapeados para o GLPI com base em regras de categoria, prioridade e SLA definidas no
ticketGlpiModel.js. - Título: O título do ticket no GLPI é padronizado como
[TIPO] - [ENTIDADE] - [TÍTULO ORIGINAL]. - Enriquecimento de Descrição: Se uma requisição do ServiceNow chega com a descrição vazia, o sistema busca automaticamente o conteúdo de variáveis de catálogo (como
justificativaetelefone) e as utiliza para preencher a descrição e os dados do ticket no GLPI.
Sincronização de Comentários
- Lógica de 4 Casos (GLPI -> SNOW): Para evitar duplicatas, a sincronização de comentários do GLPI para o SNOW verifica 4 cenários:
- Já Sincronizado: O comentário existe em ambos os locais. Nenhuma ação.
- Existe no SN, Falta no BD Local: O registro local é criado para corrigir o estado.
- Existe no BD Local, Falta no SN: O comentário é reenviado para o ServiceNow.
- Novo Comentário: O comentário é enviado para o SNOW e registrado localmente.
- Sanitização: Comentários do GLPI passam por um processo de limpeza (
commentSanitizer.js) que remove tags HTML e substitui imagens por um texto placeholder, garantindo que o conteúdo seja legível no ServiceNow.
Sincronização de Status
- Fechamento de Ticket em Espera: Se um ticket é resolvido no GLPI, mas seu correspondente no ServiceNow está com o status "Em Espera" ou "Aguardando Atendimento", o sistema primeiro altera o status no ServiceNow para "Em Atendimento" e só então prossegue com a resolução. Isso automatiza o fluxo e evita falhas.
- Regra "Fora do Escopo": Se um ticket no GLPI é solucionado com o tipo de solução "Fora do Escopo", o sistema não o resolve no ServiceNow. Em vez disso, ele adiciona uma nota de trabalho (
work_note) explicando o motivo e fecha o registro de sincronização, tratando-o como um caso especial. - Reabertura: O sistema permite a reabertura de tickets em ambas as direções, desde que o ticket não esteja permanentemente fechado.
Ambientes (.env)
- A aplicação suporta múltiplos ambientes através de arquivos
.env. - Se a variável de ambiente
NODE_ENVfor definida comoproduction, o arquivo.env.productionserá carregado. - Caso contrário (ou se
NODE_ENVfordevelopment), o arquivo.env.developmentserá utilizado.
Atualização do Mapeamento de Localidades (update_location.py)
- A aplicação conta com um script Python (
src/scripts/python/update_location.py) para manter o mapeamento entre as localidades do ServiceNow e as entidades do GLPI. - Fonte da Verdade: Um arquivo
.csvlocalizado em um servidor de arquivos (LOCATION_MAPPING_CSV_PATHno.env) é a fonte da verdade para este mapeamento. - Processo:
- Um usuário (
sothis) atualiza o arquivo.csvcom as correspondências corretas entre os nomes das localidades (SNOW) e os nomes das entidades (GLPI). - Um
cron jobno servidor executa o scriptupdate_location.pyperiodicamente. - O script lê o
.csv, busca os IDs correspondentes nos bancos de dados de ambos os sistemas e recria a tabelalocation_mappingno banco de dados intermediário (PostgreSQL).
- Um usuário (
- Resultado: Garante que os tickets criados no GLPI sejam sempre associados à entidade correta, com base em um mapeamento centralizado e de fácil manutenção.
Estrutura do Banco de Dados Intermediário (PostgreSQL)
tickets_sn: Armazena uma cópia local dos dados dos tickets do ServiceNow para otimizar consultas.ticket_sync: Tabela central que controla o estado da sincronização de cada ticket, incluindo os IDs de ambos os sistemas e o camposource_last.ticket_updates: Log de todas as atualizações (comentários, etc.), usado para evitar duplicidade e rastrear o histórico.location_mapping: Tabela de mapeamento entre as localizações do ServiceNow e as entidades do GLPI.sync_control: Armazena metadados do processo, como a marca d'água (timestamp) da última sincronização bem-sucedida.
Diagrama de Fluxo (Exemplo)
Sincronização de Resolução: GLPI -> ServiceNow
O diagrama abaixo ilustra como o sistema lida com um ticket que foi marcado como "Solucionado" no GLPI.
sequenceDiagram
participant App as app.js
participant StatusCtrl as processStatusAndClosureController
participant GlpiModel as TicketGlpiModel
participant SyncModel as TicketSyncModel
participant SnowService as servicenowService
participant ServiceNow as ServiceNow API
App->>StatusCtrl: Iniciar ciclo de status
StatusCtrl->>SyncModel: getTicketsToMonitor()
SyncModel-->>StatusCtrl: Lista de tickets ativos
loop Para cada ticket monitorado
StatusCtrl->>GlpiModel: getTicketStatus(glpi_id)
GlpiModel-->>StatusCtrl: Status 'Solucionado' (5)
alt Status mudou para 'Solucionado'
StatusCtrl->>GlpiModel: getTicketSolution(glpi_id)
GlpiModel-->>StatusCtrl: Detalhes da solução
StatusCtrl->>SnowService: closeTicketInServiceNow(sn_id, solucao)
SnowService->>ServiceNow: PATCH /api/now/table/incident/{sys_id} (state: 'Resolved')
ServiceNow-->>SnowService: 200 OK
SnowService-->>StatusCtrl: Sucesso
StatusCtrl->>SyncModel: updateStatus(sn_id, 'solved', 'solved')
SyncModel-->>StatusCtrl: OK
end
end