- feito ajuste de direção de status para respeitar source_last e evitar reabertura indevida - feito tratamento de reabertura SN->GLPI após resolução, mantendo bloqueio para fechamento permanente - feito ajuste de finalização GLPI->SN para propagar resolução/fechamento corretamente - feito correção de runtime no processStatusController (uso de variável antes da inicialização) - feito correção para não prender ticket em status transitório de comentários - feito preservação de ordem cronológica e datas reais de comments/work_notes SN no GLPI - feito normalização de autor (ex.: email/login para nome amigável) - feito destaque visual para mensagens automáticas e encerramento no GLPI - feito sanitização de justificativa na regra de fora de escopo - feito padronização de variáveis de ambiente e remoção de inconsistências de config - feito separação de SQL destrutivo para arquivo de manutenção dedicado
9.1 KiB
9.1 KiB
Sistema de Sincronizacao ServiceNow <> GLPI
Middleware em Node.js para sincronizacao bidirecional de tickets, comentarios e status entre ServiceNow e GLPI, com banco intermediario PostgreSQL e acesso direto ao banco MySQL/MariaDB do GLPI.
O que o projeto faz hoje
- Busca incidentes e requisicoes no ServiceNow por watermark (
sync_control). - Salva/atualiza tickets no banco intermediario (
tickets_sn). - Cria tickets no GLPI para registros pendentes (
ticket_sync.glpi_sync_status = 'pending_check'). - Sincroniza comentarios em duas direcoes:
- ServiceNow -> GLPI
- GLPI -> ServiceNow
- No fluxo ServiceNow -> GLPI:
commentsviram comentarios (followups) no GLPI.work_notesviram tarefas no GLPI.
- Sincroniza status em duas direcoes com controle de origem (
source_last:SNOW/GLPI). - Trata regras de negocio especificas de fechamento/reabertura.
- Reprocessa tickets em estado de erro no inicio de cada ciclo.
- Executa em job agendado (
node-cron) com protecao contra concorrencia local (isCronRunning).
Arquitetura
Componentes
cron.js: agenda e dispara o ciclo de sincronizacao.src/app.js: orquestra o ciclo principal.src/controllers/*: fluxo de tickets, comentarios, status e recuperacao de erro.src/services/*: integracoes com ServiceNow e GLPI.src/models/*: acesso a dados (PostgreSQL e GLPI MySQL).src/data/*: pools de conexao (pgemysql2).src/scripts/python/update_location_mapping.py: atualiza tabelalocation_mappinga partir de CSV.
Bancos envolvidos
- PostgreSQL (
snglpi): estado da integracao. - MySQL/MariaDB (GLPI): criacao/consulta/atualizacao de tickets e followups.
Fluxo do ciclo
Executado em ordem pelo main():
processErrorControllerprocessTicketsControllerprocessCommentsControllerprocessStatusAndClosureController
Regras de negocio importantes
- Controle de precedencia por
source_lastpara reduzir conflito de atualizacao. - Ao detectar divergencia de status, o bastao nao e invertido para
GLPIquando a ultima origem valida ja eSNOW. - Encerramento/Resolucao vindo do ServiceNow:
- Nao fecha ticket no GLPI automaticamente.
- Insere nota formatada no GLPI.
- Marca sync como
closed/closedpara remover do monitoramento.
- Ticket resolvido no GLPI com
solutiontypes_id = GLPI_OOS_SOLUTION_TYPE_ID(fora do escopo):- Nao resolve no SN.
- Adiciona
work_noteno SN. - Marca sincronizacao como encerrada/ignorada.
- Se GLPI resolver e SN estiver em
Em EsperaouAguardando Atendimento, integracao forcaEm Atendimentoantes de resolver no SN. - Comentarios GLPI sao sanitizados (HTML/imagens/metadados) antes de envio ao SN.
- Watermark de coleta no ServiceNow usa margem de seguranca de 6 horas para tras (
newWatermark - 6h).- Motivo: reduzir risco de perda de eventos em casos de atraso de replicacao, diferenca de timezone e clock skew entre sistemas.
- Efeito colateral esperado: releitura de uma janela recente e maior chance de reprocessamento controlado (idempotencia pelo banco local).
Regras de negocio detalhadas
- Controle de origem (
source_last)
SNOWouGLPIdefine quem teve a ultima escrita valida para o ticket.- Evita corrida de atualizacao de status/comentario entre os dois sistemas.
- Status GLPI -> ServiceNow
- Solucao no GLPI dispara tentativa de resolucao no SN.
- Se SN estiver em status bloqueante (
Em EsperaouAguardando Atendimento), a integracao setaEm Atendimentoantes da resolucao. - Regra fora do escopo (
solutiontypes_id = GLPI_OOS_SOLUTION_TYPE_ID) fecha fluxo local sem resolver no SN e registrawork_note.
- Status ServiceNow -> GLPI
- Mudancas de estado no SN sao refletidas no GLPI para tickets ativos.
- Para
Resolvido,EncerradoeEncerrado - Omitidono SN:- GLPI recebe nota de encerramento/resolucao.
- Integracao remove ticket do monitoramento (
closed/closed), sem fechar ticket no GLPI.
- Fechamento permanente no GLPI bloqueia reabertura automatica por sincronizacao.
- Comentarios GLPI -> SN
- Fluxo com verificacao de existencia local/remota para evitar duplicatas.
- Conteudo passa por sanitizacao para remover HTML, normalizar texto e tratar imagens.
- Comentarios SN -> GLPI
- Comentarios novos detectados no SN sao persistidos no banco intermediario e enviados ao GLPI.
work_notesdo SN sao persistidas comoupdate_type = taske enviadas como tarefa no GLPI.- Campo
authorno banco intermediario usasys_created_bydo SN. - Conteudo enviado ao GLPI e formatado com card visual e autor no cabecalho.
- IDs de origem/destino ficam registrados em
ticket_updatespara rastreabilidade.
- Reprocessamento de erro
- Inicio de cada ciclo tenta resetar estados de erro para recolocar tickets no fluxo automatico.
Pre-requisitos
- Node.js 18+
- NPM
- PostgreSQL
- MySQL/MariaDB com base do GLPI acessivel
- Python 3.10+ (para o mapeador de localidades)
Instalacao
npm install
Dependencias Python
cd src/scripts/python
pip install -r requirements.txt
Configuracao de ambiente
Crie .env.development e .env.production com base em .env.example e inclua tambem as variaveis usadas no codigo:
ServiceNow
SERVICENOW_USERNAMESERVICENOW_PASSWORDSERVICENOW_ASSIGNMENT_GROUPSERVICENOW_TABLE_INCIDENT_URLSERVICENOW_TABLE_REQUEST_URLSERVICENOW_TABLE_JOURNAL_URLSERVICENOW_SC_ITEM_OPTION_URLSERVICENOW_DEFAULT_USERSERVICENOW_RESOLVED_BY_SYSIDSERVICENOW_IGNORE_DEFAULT_USER_JOURNAL(truepor padrao; usefalsepara testes locais)
GLPI (MySQL/MariaDB)
GLPI_DB_HOSTGLPI_DB_PORTGLPI_DB_USERGLPI_DB_PASSWORDGLPI_DB_NAMEGLPI_DB_CHARSETGLPI_DEFAULT_USER_IDGLPI_DEFAULT_GROUP_ID(padrao30)GLPI_DEFAULT_ENTITY_ID(padrao127)GLPI_OOS_SOLUTION_TYPE_ID(padrao27)
Banco intermediario (PostgreSQL)
SNGLPI_DB_HOSTSNGLPI_DB_PORTSNGLPI_DB_NAMESNGLPI_DB_USERSNGLPI_DB_PASSWORD
Agendamento e mapeamento
CRON_SCHEDULE(ex.:*/5 * * * *)LOCATION_MAPPING_CSV_PATH(arquivo CSV para mapeamento SN -> GLPI)
Execucao
Desenvolvimento
npm run dev
Producao
npm run start:prod
Execucao com PM2
Subir os dois processos (sync + mapeador):
pm2 start ecosystem.config.js --env production
Comandos uteis:
pm2 list
pm2 logs sn-glpi-sync-cron
pm2 logs sn-glpi-location-mapper
pm2 restart sn-glpi-sync-cron
Script de mapeamento de localidades
Arquivo: src/scripts/python/update_location_mapping.py
- Carrega
NODE_ENVe respectivo.env.*. - Monitora alteracoes recentes no CSV (
LOCATION_MAPPING_CSV_PATH). - Recria os dados da tabela
location_mappingcom base no CSV e IDs validos em ambos os bancos. - Roda em loop continuo (ideal via PM2 como processo separado).
Como os dados chegam do ServiceNow
- Incidentes: consulta na tabela definida por
SERVICENOW_TABLE_INCIDENT_URL, filtrando porassignment_groupesys_updated_on >= watermark. - Requisicoes: consulta na tabela definida por
SERVICENOW_TABLE_REQUEST_URLcom o mesmo filtro. - Comentarios: consulta na tabela definida por
SERVICENOW_TABLE_JOURNAL_URLporelement_ideelement IN (comments, work_notes), com paginacao (limit/offset). - Enriquecimento de requisicoes: consulta em
SERVICENOW_SC_ITEM_OPTION_URLpara capturar variaveis como justificativa e telefone. - Campos principais persistidos localmente:
- Ticket:
number,sys_id,short_description,state,description,caller/opened_by,location,opened_at,sys_updated_on. - Atualizacoes:
sys_id,element,value,sys_created_on,sys_created_by.
- Ticket:
Estrutura do banco intermediario
Definicao base em src/scripts/database/scriptBD.sql:
tickets_snticket_syncticket_updateslocation_mappingsync_control
Arquivo auxiliar de manutencao/reset (com comandos destrutivos):
src/scripts/database/maintenance_reset.sql
Limitacoes conhecidas (estado atual)
- Nao ha suite de testes automatizados (
npm teste placeholder). - Parte do fluxo depende de acesso direto ao banco do GLPI (acoplamento operacional alto). (Utilizar API em nova versão)
- Existe logica sensivel de timezone/watermark que merece revisao para evitar reprocesso/perda de evento.
Proximas melhorias recomendadas
- Cobertura de testes (unitario e integracao com mocks de API/DB).
- Externalizar IDs e regras hardcoded para variaveis de ambiente.
- Revisar estrategia de watermark/timezone e idempotencia.
- Criar healthcheck/observabilidade (metricas de ciclo, falhas por etapa, tickets processados).
- Adicionar validacoes de configuracao na inicializacao (falha rapida quando faltar env obrigatoria).
- Alterar uso de banco do GLPI para a API do GLPI.
Arquivos principais
cron.jssrc/app.jssrc/controllers/processTicketsController.jssrc/controllers/processCommentsController.jssrc/controllers/processStatusController.jssrc/controllers/processErrorController.jssrc/services/servicenowService.jssrc/services/glpiTicketService.jssrc/services/glpiCommentService.jssrc/scripts/python/update_location_mapping.py