Rotina de sincronismo de chamados entre ServiceNow e GLPI
Go to file
2025-11-19 16:30:50 -03:00
config REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
src REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
.env.development REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
.env.example REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
.gitignore CHORE: Direório de Logs adicionado ao .gitignore 2025-11-19 16:30:50 -03:00
cron.js REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
ecosystem.config.js REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
package-lock.json REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
package.json REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00
README.md REFACTOR/BUG: Correção de bugs e alteção de run 2025-11-19 16:01:37 -03:00

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.


Como Executar a Aplicação

Esta seção contém as instruções essenciais para configurar e rodar a aplicação em diferentes ambientes.

1. Pré-requisitos

  • Node.js: Certifique-se de ter o Node.js (versão 18 ou superior) instalado.
  • Dependências: Na raiz do projeto, execute o comando abaixo para instalar todas as dependências necessárias:
    npm install
    
  • Arquivos de Ambiente: Crie os arquivos .env.development e .env.production na raiz do projeto, baseando-se no exemplo .env.example (se houver) e preenchendo com as credenciais e URLs corretas para cada ambiente.

2. Executando com Scripts NPM

2. Configuração do Ambiente Python

A aplicação utiliza um script Python para sincronizar o mapeamento de localidades.

a) Dependências Python

Navegue até a pasta do script e instale as dependências listadas no requirements.txt:

cd src/scripts/python
pip install -r requirements.txt

b) Montagem do Compartilhamento de Arquivos (CIFS/Samba)

O script Python lê um arquivo .csv de um compartilhamento de rede. No servidor de produção, é necessário montar este compartilhamento para que o caminho definido em LOCATION_MAPPING_CSV_PATH seja acessível.

Adicione a seguinte linha ao seu arquivo /etc/fstab para montar o compartilhamento automaticamente durante o boot do sistema. Ajuste o IP, credenciais e caminhos conforme necessário.

//10.0.121.40/Tecnica/Controle\040CAOA/ENTIDADE\040SERVICE\040NOW /mnt/csv_share cifs username=<seu_usuario>,password=<sua_senha>,uid=1000,gid=1000,iocharset=utf8 0 0

Após editar o /etc/fstab, execute sudo mount -a para montar o compartilhamento imediatamente.

Os comandos abaixo utilizam a variável NODE_ENV para carregar o arquivo de ambiente (.env) correto.

Ambiente de Desenvolvimento

Para rodar em modo de desenvolvimento com reinício automático a cada alteração de arquivo (usando nodemon):

npm run dev

Ambiente de Produção

Para rodar a aplicação em modo de produção (usando node):

npm start

ou o comando explícito:

npm run start:prod

3. Executando com PM2

O PM2 é o gerenciador de processos recomendado para ambientes de produção. Ele garante que a aplicação reinicie automaticamente em caso de falhas e facilita o gerenciamento.

  • Para iniciar em modo de produção:
    pm2 start ecosystem.config.js --env production
    
  • Para iniciar em modo de desenvolvimento:
    pm2 start ecosystem.config.js --env development
    
  • Comandos úteis do PM2:
    pm2 list                  # Lista todos os processos
    pm2 logs sn-glpi-sync-cron  # Exibe os logs em tempo real
    pm2 restart sn-glpi-sync-cron # Reinicia a aplicação
    pm2 stop sn-glpi-sync-cron    # Para a aplicaçã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:

  1. 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_check ou synced), permitindo que eles sejam reprocessados no ciclo atual.
  2. processTicketsController - Criação de Tickets

    • Objetivo: Trazer novos tickets do ServiceNow para o GLPI.
    • Ação:
      • Busca no SNOW: Invoca o processSyncController para 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.
  3. 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_notes para o ServiceNow.
  4. 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_last na tabela ticket_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 justificativa e telefone) 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:
    1. Já Sincronizado: O comentário existe em ambos os locais. Nenhuma ação.
    2. Existe no SN, Falta no BD Local: O registro local é criado para corrigir o estado.
    3. Existe no BD Local, Falta no SN: O comentário é reenviado para o ServiceNow.
    4. 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_ENV for definida como production, o arquivo .env.production será carregado.
  • Caso contrário (ou se NODE_ENV for development), o arquivo .env.development será 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 .csv localizado em um servidor de arquivos (LOCATION_MAPPING_CSV_PATH no .env) é a fonte da verdade para este mapeamento.
  • Processo:
    1. Um usuário (sothis) atualiza o arquivo .csv com as correspondências corretas entre os nomes das localidades (SNOW) e os nomes das entidades (GLPI).
    2. Um cron job no servidor executa o script update_location.py periodicamente.
    3. O script lê o .csv, busca os IDs correspondentes nos bancos de dados de ambos os sistemas e recria a tabela location_mapping no banco de dados intermediário (PostgreSQL).
  • 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 campo source_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