Modelo de notificação em integrações orientadas a eventos

Aprenda a projetar uma estratégia de notificação para arquiteturas orientadas a eventos.

Este documento descreve uma sugestão de implementação de um mecanismo de notificação centralizado para integrações orientadas a eventos na Digibee Integration Platform. O objetivo é garantir que eventos importantes, especialmente erros, sejam comunicados de forma confiável e escalável, permitindo que sistemas e usuários respondam de maneira adequada.

Para mais detalhes sobre integrações orientadas a eventos na Digibee Integration Platform, leia os seguintes artigos:

Cenário

Em um ambiente de integração assíncrona, eventos podem ser disparados por diversos sistemas, exigindo um mecanismo robusto para notificar sistemas consumidores ou usuários finais. O modelo de notificação proposto neste documento aborda esses desafios considerando:

  • Baixa latência na entrega da notificação.

  • Garantia de entrega com tentativas de reenvio.

  • Flexibilidade para envio via diferentes canais (email, webhook, fila, e assim por diante).

  • Observabilidade para rastreamento de eventos.

  • Tratamento de erros com repositório centralizado e regras predefinidas.

Arquitetura

A implementação do modelo de notificação segue uma arquitetura baseada em eventos, onde:

  1. Disparo do evento: Qualquer pipeline de negócio pode acionar o pipeline save-notification-event via evento Digibee chamado notification-event.

  2. Armazenamento da notificação: O pipeline save-notification-event insere ou atualiza o registro no Object Store notification-store, garantindo que mensagens duplicadas não sejam armazenadas dentro do intervalo de tempo definido.

  3. Processamento e envio da notificação: Um segundo pipeline, send-notification-timer, consulta periodicamente os registros armazenados no notification-store e realiza o envio das notificações com base nas regras estabelecidas.

  4. Entrega ao destino: As notificações são enviadas para os sistemas de sua preferência, como sistemas de alerta (Dynatrace, Datadog, Grafana, e-mail) ou sistemas de abertura de tickets (ServiceNow, Zendesk, Jira).

Diagrama de fluxo

Implementação na Digibee

Configuração dos pipelines

  1. Pipeline save-notification-event:

    • Recebe um evento notification-event.

    • Verifica se a mensagem já existe no notification-store.

    • Insere um novo registro ou atualiza um existente, incrementando o contador de ocorrências.

    • Define o tempo de espera antes do envio do alerta.

  2. Pipeline send-notification-timer:

    • Recupera registros do notification-store paginando a busca a cada 500 registros.

    • Aplica regras de criticidade para definir o destino da notificação.

    • Calcula o horário de envio com base no tempoEsperaAlerta.

    • Envia a notificação ao sistema adequado.

Exemplo de payloads

Entrada do evento notification-event (Exemplo para ServiceNow e Dynatrace)
{
  "tituloErro": "Exemplo: Falha de integração de produtos",
  "mensagem":"código de erro + mensagem",
  "pipelineName":"nome do pipeline",
  "lastPipelineKey": "pipeline key",
  "etapaIntegracao": "Qual etapa do fluxo ocorreu o erro",
  "dataHora": "timestamp",
  "criticidade": 1,
  "tempoEsperaAlerta": "1",
  "servicenow":{
    "variables":{
      "assignment_group": "",
      "u_type_closure": "",
      "urgency": "",
      "cmdb_ci": "",
      "business_service": "",
      "subcategory": ""
    }
  },
  "dynatrace":{
    "startTime": "",
    "properties":{
      "step": ""
    }
  }
}
Armazenamento no notification-store
{
  "mensagem":"código de erro + mensagem",
  "pipelineName":"nome do pipeline",
  "etapaIntegracao": "Qual etapa do fluxo ocorreu o erro",
  "tituloErro": "Exemplo: Falha de integração de produtos",
  "lastPipelineKey": "pipeline key",
  "dataHora": "timestamp",
  "criticidade": 1,
  "qtdeOcorrencias": 1,
  "limiteAlert": "calculado",
  "servicenow":{
    "variables":{
      "assignment_group": "",
      "u_type_closure": "",
      "urgency": "",
      "cmdb_ci": "",
      "business_service": "",
      "subcategory": ""
    }
  },
  "dynatrace": {
    "startTime": "",
    "properties": {
      "step": ""
    }
  }
}

Exemplos de pipeline specs

Trigger: Scheduler | Nome do pipeline: send-notification-timer
{
  "meta": {
    "e8e9e28e-c047-4591-9ad9-324dd4f7e425": {
      "position": {
        "x": 195,
        "y": 75
      }
    },
    "755c8909-8a1f-4b98-88c2-ae693fbb3ef5": {
      "position": {
        "x": 405,
        "y": 75
      }
    },
    "dcc24676-159c-4a93-aa9e-931d13ce1b3c": {
      "position": {
        "x": 600,
        "y": 75
      }
    },
    "0718a765-dcf7-42df-b959-a04b024f834d": {
      "position": {
        "x": 795,
        "y": 75
      }
    },
    "b185a262-9813-4bde-8287-b8cf500f3a62": {
      "position": {
        "x": 1245,
        "y": 0
      }
    },
    "9d2331d2-7842-494b-9be1-c6a4f2ce52e7": {
      "position": {
        "x": 1455,
        "y": 0
      }
    },
    "d7be81fd-d35f-4ee9-a56d-2c1e10989bbc": {
      "position": {
        "x": 1650,
        "y": 0
      }
    },
    "95792095-5b05-4d54-b65c-6b329884d159": {
      "position": {
        "x": 1845,
        "y": 0
      }
    },
    "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6": {
      "position": {
        "x": 2055,
        "y": 0
      }
    },
    "158d4027-f8c9-4274-a5bc-45064f6a81ed": {
      "position": {
        "x": 1245,
        "y": 150
      }
    },
    "eaf2e26f-a933-4f92-9f95-2caec4c69f04": {
      "position": {
        "x": 1455,
        "y": 150
      }
    },
    "6265f91e-daaf-4424-ad9e-f7af9aa8c63d": {
      "position": {
        "x": 0,
        "y": 225
      }
    }
  },
  "flowSpec": {
    "disconnected-root:2bc39e21-f496-451b-9649-76f2ff6074e7": [
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Delete notification-store +7 days",
        "params": {
          "operation": "DELETE_BY_QUERY",
          "objectStore": "notification-store",
          "query": "{\n    \"dataHora\": { $lt: {{ SUMDATE(NOW(), \"DAY\", -7) }} }\n}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "e8e9e28e-c047-4591-9ad9-324dd4f7e425"
      },
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Delete notification-store +7 days",
        "params": {
          "logLevel": "INFO",
          "message": "Delete notification-store +7 days: {{ message.$ }}"
        },
        "id": "755c8909-8a1f-4b98-88c2-ae693fbb3ef5"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Find notification-store",
        "params": {
          "operation": "FIND_BY_QUERY",
          "objectStore": "notification-store",
          "query": "{\n    \"limitAlert\": { $lt: {{ NOW() }} }\n}",
          "limit": "500",
          "skip": "0",
          "sort": "{}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "dcc24676-159c-4a93-aa9e-931d13ce1b3c"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success notification-store (1)",
            "jsonPath": "$.[?(@.rowCount > 0)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Find notificarion-store (1)",
        "id": "0718a765-dcf7-42df-b959-a04b024f834d"
      }
    ],
    "Success notification-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Find notification-store",
        "params": {
          "logLevel": "INFO",
          "message": "Success Find notification-store"
        },
        "id": "b185a262-9813-4bde-8287-b8cf500f3a62"
      },
      {
        "type": "transformer",
        "stepName": "Transformer (JOLT)",
        "transformSpec": [
          {
            "operation": "shift",
            "spec": {
              "data": [
                "&",
                "temp"
              ]
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": {
                "*": {
                  "criticidade": {
                    "1|2": {
                      "@2": "data[]"
                    }
                  }
                }
              },
              "temp": {
                "*": {
                  "criticidade": {
                    "3": {
                      "@2": [
                        "temp[]",
                        "temp[]"
                      ]
                    }
                  }
                }
              }
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": "&",
              "temp": {
                "*": "data[]"
              }
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": [
                "data",
                "data2"
              ]
            }
          },
          {
            "operation": "shift",
            "spec": {
              "data": {
                "*": {
                  "$": "data[#2].seq",
                  "tituloErro": "data[#2].&",
                  "mensagem": "data[#2].&",
                  "pipelineName": "data[#2].&",
                  "lastPipelineKey": "data[#2].&",
                  "etapaIntegracao": "data[#2].&",
                  "dataHora": "data[#2].&",
                  "criticidade": "data[#2].&",
                  "tempoEsperaAlerta": "data[#2].&",
                  "servicenow": "data[#2].&",
                  "dynatrace": "data[#2].&",
                  "limitAlert": "data[#2].&",
                  "qtdeOcorrencias": "data[#2].&",
                  "_oId": "data[#2].&"
                }
              }
            }
          },
          {
            "operation": "modify-overwrite-beta",
            "spec": {
              "data": {
                "*": {
                  "seq": "=toInteger"
                }
              }
            }
          }
        ],
        "id": "9d2331d2-7842-494b-9be1-c6a4f2ce52e7"
      },
      {
        "type": "connector",
        "name": "json-transformer-connector",
        "stepName": "JSON Transformer",
        "params": {
          "actions": "[{\"desc\":\"Description\",\"type\":\"edit\",\"props\":[{\"root\":false,\"path\":\"data\",\"keyValueStringEdit\":\"{\\\"criticidade\\\":\\\"{{ IF(EQUALTO(item.criticidade,3),IF(EQUALTO(MOD(item.seq,2),0.0),2,1),item.criticidade) }}\\\"}\",\"keyRemove\":\"\",\"keyValueToRemovePropWithCondition\":\"\"}]},{\"desc\":\"Description\",\"type\":\"remove\",\"props\":[{\"root\":false,\"path\":\"data\",\"keyRemove\":[\"seq\"],\"keyValueToRemovePropWithCondition\":\"\"}]}]",
          "failOnError": false
        },
        "id": "d7be81fd-d35f-4ee9-a56d-2c1e10989bbc"
      },
      {
        "type": "session-management",
        "stepName": "Put data",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "data"
        ],
        "id": "95792095-5b05-4d54-b65c-6b329884d159"
      },
      {
        "type": "connector",
        "name": "for-each-connector",
        "stepName": "For Each data",
        "params": {
          "jsonPath": "$.data",
          "itemIdentifier": "",
          "parallel": false,
          "failOnError": false,
          "onProcess": "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onProcessTrack",
          "onException": "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onExceptionTrack"
        },
        "id": "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6"
      }
    ],
    "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onProcessTrack": [
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "request",
        "params": {
          "json": "{\n    \"request\": {{ message.$ }},\n    \"_oId\": {{ message._oId }}\n}",
          "failOnError": false
        },
        "id": "c8877f16-e81e-4a9f-8cdf-dfc9d361503b"
      },
      {
        "type": "session-management",
        "stepName": "Put _oId",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "_oId"
        ],
        "id": "f1cb864a-e929-40f9-8db9-53769bec0e5c"
      },
      {
        "type": "connector",
        "name": "block-execution-connector",
        "stepName": "Send Customer Sistem",
        "params": {
          "onProcess": "290da7bf-fbab-4c42-8c1e-d5739b0c154a-onProcessTrack",
          "onException": "290da7bf-fbab-4c42-8c1e-d5739b0c154a-onExceptionTrack"
        },
        "id": "290da7bf-fbab-4c42-8c1e-d5739b0c154a",
        "description": "Block for to send the request for ServiceNow or Dynatrace"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success Send",
            "jsonPath": "$.[?(@.success == true)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Send ServiceNow|Dynatrace (1)",
        "id": "dc02a67b-ae79-4f35-8f5a-3972d542ce1a"
      }
    ],
    "290da7bf-fbab-4c42-8c1e-d5739b0c154a-onProcessTrack": [
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Criticidade 1",
            "jsonPath": "$.[?(@.request.criticidade == 1)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Criticidade 2",
        "id": "0458512a-0acf-4ed6-b057-b57ba665a845"
      }
    ],
    "Criticidade 1": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Sistem 1",
        "params": {
          "logLevel": "INFO",
          "message": "Sistem 1|Criticidade: {{ message.request.criticidade }}"
        },
        "id": "0c0bc38a-27de-4a33-8f42-9159ea86a3cb"
      }
    ],
    "Criticidade 2": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Sistem 2",
        "params": {
          "logLevel": "INFO",
          "message": "Sistem 2|Criticidade: {{ message.request.criticidade }}"
        },
        "id": "199422c1-e293-412d-aaa0-0a7fbd69e81c"
      }
    ],
    "Success Send": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Sent Sistem",
        "params": {
          "logLevel": "INFO",
          "message": "Success Sent Sistem"
        },
        "id": "a652992f-690a-4c17-a5e9-be2d93c3b87e"
      },
      {
        "type": "session-management",
        "stepName": "Get _oId",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "_oId"
        ],
        "id": "1176936e-5a03-4bcb-a0ce-1832b6392159"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Delete notification-store",
        "params": {
          "operation": "DELETE",
          "objectStore": "notification-store",
          "objectId": "{{ message._oId }}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "a1ade107-bb49-45c4-b945-7a014b7278c9"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success Delete ObjStore (1)",
            "jsonPath": "$.[?(@.updateCount > 0)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Delete ObjStore (1)",
        "id": "a3a527cc-2b8c-4fca-b7e1-827818b7e803"
      }
    ],
    "Success Delete ObjStore (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Delete ObjStore",
        "params": {
          "logLevel": "INFO",
          "message": "Success Delete ObjStore"
        },
        "id": "ca9d769c-25a0-4c17-b82f-d53a29f0d332"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "success true",
        "params": {
          "json": "{\n    \"success\": true\n}",
          "failOnError": false
        },
        "id": "b797fdb1-9a57-4840-821c-a24a623fbfe8"
      }
    ],
    "Fail Delete ObjStore (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Fail Delete ObjStore",
        "params": {
          "logLevel": "ERROR",
          "message": "Fail  Delete ObjStore {{ message.$ }}"
        },
        "id": "ac4b8a02-51d9-41d4-97ab-4d04728bfafb"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "success true",
        "params": {
          "json": "{\n    \"success\": true\n}",
          "failOnError": false
        },
        "id": "af7d02b7-1e08-4ee6-823a-94146c0f6945"
      }
    ],
    "Fail Send ServiceNow|Dynatrace (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Fail Sent ServiceNow/Dynatrace",
        "params": {
          "logLevel": "ERROR",
          "message": "Fail Sent ServiceNow/Dynatrace"
        },
        "id": "f6171366-3394-4628-a349-bb1ffe373814"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "success false",
        "params": {
          "json": "{\n    \"success\": false\n}",
          "failOnError": false
        },
        "id": "719e5f44-744d-4263-af9f-ad4422be6a83"
      }
    ],
    "8a90a7be-7ae7-4baa-87a3-ef91b395c8d6-onExceptionTrack": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Error For Each",
        "params": {
          "logLevel": "ERROR",
          "message": "Error For Each {{ message.$ }}"
        },
        "id": "6d5ac53a-58f4-4369-a6b5-0b67188f39c3"
      }
    ],
    "Fail Find notificarion-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Not Found notification-store",
        "params": {
          "logLevel": "WARN",
          "message": "Not Found notification-store"
        },
        "id": "158d4027-f8c9-4274-a5bc-45064f6a81ed"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "JSON Generator",
        "params": {
          "json": "{\n    \"message\": \"Registers not found in notification-store.\",\n    \"dateTime\": {{ FORMATDATE(NOW(),\"timestamp\",\"dd/MM/yyyy HH:mm:ss\",\"pt-BR\",\"GMT-3\") }}\n}",
          "failOnError": false
        },
        "id": "eaf2e26f-a933-4f92-9f95-2caec4c69f04"
      }
    ],
    "disconnected-root:3f84c991-d096-4afd-9283-8a87a2e1cddb": [
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "Find notification-store",
        "params": {
          "json": "{\n  \"data\": [\n    {\n      \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n      \"mensagem\": \"código de erro + mensagem\",\n      \"pipelineName\": \"nome do pipeline\",\n      \"lastPipelineKey\": \"pipeline key\",\n      \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n      \"dataHora\": 1692020829906,\n      \"criticidade\": 1,\n      \"tempoEsperaAlerta\": 1,\n      \"servicenow\": {\n        \"variables\": {\n          \"assignment_group\": \"\",\n          \"u_type_closure\": \"\",\n          \"urgency\": \"\",\n          \"cmdb_ci\": \"\",\n          \"business_service\": \"\",\n          \"subcategory\": \"\"\n        }\n      },\n      \"dynatrace\": {\n        \"timeout\": \"\",\n        \"properties\": {\n          \"step\": \"\"\n        }\n      },\n      \"limitAlert\": 1692024429906,\n      \"qtdeOcorrencias\": 16,\n      \"_oId\": \"7d874ba1-7dd4-4880-8afb-de041b8ef649\"\n    },\n    {\n      \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n      \"mensagem\": \"código de erro + mensagem\",\n      \"pipelineName\": \"nome do pipeline\",\n      \"lastPipelineKey\": \"pipeline key\",\n      \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n      \"dataHora\": 1692020829906,\n      \"criticidade\": 3,\n      \"tempoEsperaAlerta\": 1,\n      \"servicenow\": {\n        \"variables\": {\n          \"assignment_group\": \"\",\n          \"u_type_closure\": \"\",\n          \"urgency\": \"\",\n          \"cmdb_ci\": \"\",\n          \"business_service\": \"\",\n          \"subcategory\": \"\"\n        }\n      },\n      \"dynatrace\": {\n        \"timeout\": \"\",\n        \"properties\": {\n          \"step\": \"\"\n        }\n      },\n      \"limitAlert\": 1692024429906,\n      \"qtdeOcorrencias\": 16,\n      \"_oId\": \"7d874ba1-7dd4-4880-8afb-de041b8ef649\"\n    },\n    {\n      \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n      \"mensagem\": \"código de erro + mensagem\",\n      \"pipelineName\": \"nome do pipeline\",\n      \"lastPipelineKey\": \"pipeline key\",\n      \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n      \"dataHora\": 1692020829906,\n      \"criticidade\": 3,\n      \"tempoEsperaAlerta\": 1,\n      \"servicenow\": {\n        \"variables\": {\n          \"assignment_group\": \"\",\n          \"u_type_closure\": \"\",\n          \"urgency\": \"\",\n          \"cmdb_ci\": \"\",\n          \"business_service\": \"\",\n          \"subcategory\": \"\"\n        }\n      },\n      \"dynatrace\": {\n        \"timeout\": \"\",\n        \"properties\": {\n          \"step\": \"\"\n        }\n      },\n      \"limitAlert\": 1692024429906,\n      \"qtdeOcorrencias\": 16,\n      \"_oId\": \"7d874ba1-7dd4-4880-8afb-de041b8ef649\"\n    }\n  ],\n  \"rowCount\": 3\n}",
          "failOnError": false
        },
        "id": "6265f91e-daaf-4424-ad9e-f7af9aa8c63d",
        "__documentation__": ""
      }
    ]
  }
}
Trigger: Event | Nome do evento: save-notification-event
{
  "meta": {
    "634e4658-0bf8-4d51-a2f0-9f49b1773d21": {
      "position": {
        "x": 195,
        "y": 75
      }
    },
    "0923c0da-1662-4ed8-a90d-62b1c64bf45a": {
      "position": {
        "x": 400,
        "y": 75
      }
    },
    "a0fba1b5-66a7-4d85-b19b-673063d528db": {
      "position": {
        "x": 600,
        "y": 75
      }
    },
    "419107c2-aa79-4c11-80a1-b6d032824659": {
      "position": {
        "x": 800,
        "y": 75
      }
    },
    "1a914487-be66-4c4f-8268-d20476c33d37": {
      "position": {
        "x": 1000,
        "y": 75
      }
    },
    "6cd53565-b6c5-4fe7-945d-5eaf21287072": {
      "position": {
        "x": 1450,
        "y": 0
      }
    },
    "93a0465b-a939-40a2-af3e-e5b32bda3061": {
      "position": {
        "x": 1650,
        "y": 0
      }
    },
    "b5f6d727-72ea-4272-9c2c-6cc0cde483b9": {
      "position": {
        "x": 1850,
        "y": 0
      }
    },
    "4015ccfe-df27-4554-8cdc-4fc5311f8bd3": {
      "position": {
        "x": 2050,
        "y": 0
      }
    },
    "4f6fc79d-72f9-41e9-bfa5-1f8a81d4850b": {
      "position": {
        "x": 2250,
        "y": 0
      }
    },
    "65ecf8db-6aaa-4409-b032-57a1450c69a8": {
      "position": {
        "x": 2450,
        "y": 0
      }
    },
    "a948890b-e52a-4bee-854f-294a9f14528d": {
      "position": {
        "x": 1450,
        "y": 150
      }
    },
    "0d4065ac-2801-4c50-94f9-c6224d4fc272": {
      "position": {
        "x": 1650,
        "y": 150
      }
    },
    "9ddf92c8-b8c4-4599-8238-8aea39d8ae9a": {
      "position": {
        "x": 1850,
        "y": 150
      }
    },
    "15714b58-3223-47bc-b0a2-acdbe7f9f00c": {
      "position": {
        "x": 2050,
        "y": 150
      }
    },
    "5415eeb8-1242-49d9-b95c-e192f7ea2e9b": {
      "position": {
        "x": 2250,
        "y": 150
      }
    },
    "614f85c5-4137-4a93-926e-89b8c0238cc3": {
      "position": {
        "x": 2450,
        "y": 150
      }
    },
    "78a22097-4485-4810-aa04-fc488568751c": {
      "position": {
        "x": 0,
        "y": 225
      }
    }
  },
  "flowSpec": {
    "disconnected-root:d43c4651-80c1-4594-9f64-91ff52edc963": [
      {
        "type": "transformer",
        "stepName": "Transformer (JOLT)",
        "transformSpec": [
          {
            "operation": "shift",
            "spec": {
              "*": "payload.&"
            }
          },
          {
            "operation": "modify-overwrite-beta",
            "spec": {
              "payload": {
                "limitAlert": 0,
                "qtdeOcorrencias": 1
              }
            }
          }
        ],
        "id": "634e4658-0bf8-4d51-a2f0-9f49b1773d21"
      },
      {
        "type": "validator",
        "stepName": "Validator (JSON Schema)",
        "validationSpec": {
          "schema": "http://json-schema.org/draft-04/schema#",
          "additionalProperties": false,
          "definitions": {},
          "id": "validate-schema-form",
          "properties": {
            "payload": {
              "type": "object",
              "properties": {
                "tituloErro": {
                  "type": "string"
                },
                "mensagem": {
                  "type": "string"
                },
                "pipelineName": {
                  "type": "string"
                },
                "etapaIntegracao": {
                  "type": "string"
                },
                "dataHora": {
                  "type": "number"
                },
                "criticidade": {
                  "type": "number"
                },
                "tempoEsperaAlerta": {
                  "type": "number"
                }
              },
              "required": [
                "tituloErro",
                "mensagem",
                "pipelineName",
                "lastPipelineKey",
                "etapaIntegracao",
                "dataHora",
                "criticidade",
                "tempoEsperaAlerta"
              ]
            }
          },
          "required": [
            "payload"
          ],
          "type": "object"
        },
        "id": "0923c0da-1662-4ed8-a90d-62b1c64bf45a"
      },
      {
        "type": "session-management",
        "stepName": "Put payload",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "payload"
        ],
        "id": "a0fba1b5-66a7-4d85-b19b-673063d528db"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Find notification-store",
        "params": {
          "operation": "FIND_BY_QUERY",
          "objectStore": "notification-store",
          "expireAfterSeconds": 0,
          "query": "{\n    \"pipelineName\": {{ message.payload.pipelineName }},\n    \"mensagem\": {{ message.payload.mensagem }},\n    \"etapaIntegracao\": {{ message.payload.etapaIntegracao }}\n}",
          "limit": "0",
          "skip": "0",
          "sort": "{}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "419107c2-aa79-4c11-80a1-b6d032824659"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "target": "Success Find notificarion-store (1)",
            "jsonPath": "$.[?(@.rowCount > 0)]",
            "__documentation__": ""
          }
        ],
        "otherwise": "Fail Find notificarion-store (1)",
        "id": "1a914487-be66-4c4f-8268-d20476c33d37"
      }
    ],
    "Success Find notificarion-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Success Find notification-store",
        "params": {
          "logLevel": "INFO",
          "message": "Success Find notification-store"
        },
        "id": "6cd53565-b6c5-4fe7-945d-5eaf21287072"
      },
      {
        "type": "transformer",
        "stepName": "Increment qtdeOcorrencias",
        "transformSpec": [
          {
            "operation": "shift",
            "spec": {
              "data": {
                "0": {
                  "_oId": "_oId",
                  "qtdeOcorrencias": "qtdeOcorrencias"
                }
              }
            }
          }
        ],
        "id": "93a0465b-a939-40a2-af3e-e5b32bda3061"
      },
      {
        "type": "session-management",
        "stepName": "Get payload",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "payload"
        ],
        "id": "b5f6d727-72ea-4272-9c2c-6cc0cde483b9"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Instert notification-store",
        "params": {
          "operation": "UPDATE",
          "objectStore": "notification-store",
          "objectId": "{{ message._oId }}",
          "query": "",
          "document": "{\n    $set:{\n        \"lastPipelineKey\": {{ message.payload.lastPipelineKey }},\n        \"dataHora\": {{ message.payload.dataHora }},\n        \"qtdeOcorrencias\": {{ TOINT(SUM(message.qtdeOcorrencias,1)) }}\n    }\n}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "4015ccfe-df27-4554-8cdc-4fc5311f8bd3"
      },
      {
        "type": "connector",
        "name": "assert-connector-v2",
        "stepName": "Assert V2",
        "params": {
          "condition": "{{ GREATERTHAN( message.updateCount, 0) }}",
          "errorMessage": "Error to Update Object Store: notification-store",
          "internalErrorMessage": "Internal Error",
          "errorCode": 500,
          "failOnError": true
        },
        "id": "4f6fc79d-72f9-41e9-bfa5-1f8a81d4850b"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "JSON Generator",
        "params": {
          "json": "{\n    \"message\": \"Success to Update notification-store.\"\n}",
          "failOnError": false
        },
        "id": "65ecf8db-6aaa-4409-b032-57a1450c69a8"
      }
    ],
    "Fail Find notificarion-store (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Fail Find notification-store",
        "params": {
          "logLevel": "INFO",
          "message": "Failed Find notification-store"
        },
        "id": "a948890b-e52a-4bee-854f-294a9f14528d"
      },
      {
        "type": "session-management",
        "stepName": "Get payload",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "payload"
        ],
        "id": "0d4065ac-2801-4c50-94f9-c6224d4fc272"
      },
      {
        "type": "connector",
        "name": "json-transformer-connector",
        "stepName": "Calcule limitAlert (in Minutes)",
        "params": {
          "actions": "[{\"type\":\"edit\",\"desc\":\"Calculate limitAlert\",\"props\":[{\"path\":\"payload\",\"keyValueStringEdit\":\"{\\\"limitAlert\\\":\\\"{{ SUMDATE(message.payload.dataHora, \\\\\\\"MINUTE\\\\\\\", message.payload.tempoEsperaAlerta, \\\\\\\"UTC\\\\\\\") }}\\\"}\"}]}]",
          "failOnError": false
        },
        "id": "9ddf92c8-b8c4-4599-8238-8aea39d8ae9a"
      },
      {
        "type": "connector",
        "name": "object-store-connector",
        "accountLabel": "dgb-internal-object-store-account",
        "stepName": "Instert notification-store",
        "params": {
          "operation": "INSERT",
          "objectStore": "notification-store",
          "objectId": "{{ UUID() }}",
          "document": "{{ message.payload }}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "15714b58-3223-47bc-b0a2-acdbe7f9f00c"
      },
      {
        "type": "connector",
        "name": "assert-connector-v2",
        "stepName": "Assert V2",
        "params": {
          "condition": "{{ GREATERTHAN( message.updateCount, 0) }}",
          "errorMessage": "Error to Update Object Store: notification-store",
          "internalErrorMessage": "Internal Error",
          "errorCode": 500,
          "failOnError": true
        },
        "id": "5415eeb8-1242-49d9-b95c-e192f7ea2e9b"
      },
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "JSON Generator",
        "params": {
          "json": "{\n    \"message\": \"Success to Insert notification-store.\"\n}",
          "failOnError": false
        },
        "id": "614f85c5-4137-4a93-926e-89b8c0238cc3"
      }
    ],
    "disconnected-root:a5dc82f0-714d-46f8-82ae-d5305557775b": [
      {
        "name": "json-generator-connector",
        "type": "connector",
        "stepName": "Payload",
        "params": {
          "json": "{\n  \"tituloErro\": \"Exemplo: Falha de integração de produtos\",\n  \"mensagem\": \"código de erro + mensagem\",\n  \"pipelineName\": \"nome do pipeline2\",\n  \"lastPipelineKey\": \"pipeline key\",\n  \"etapaIntegracao\": \"Qual etapa do fluxo ocorreu o erro\",\n  \"dataHora\": {{ NOW() }},\n  \"criticidade\": 3,\n  \"tempoEsperaAlerta\": 60,\n  \"servicenow\": {\n    \"variables\": {\n      \"assignment_group\": \"\",\n      \"u_type_closure\": \"\",\n      \"urgency\": \"\",\n      \"cmdb_ci\": \"\",\n      \"business_service\": \"\",\n      \"subcategory\": \"\"\n    }\n  },\n  \"dynatrace\": {\n    \"timeout\": \"\",\n    \"properties\": {\n      \"step\": \"\"\n    }\n  }\n}",
          "failOnError": false
        },
        "id": "78a22097-4485-4810-aa04-fc488568751c"
      }
    ]
  }
}

Estratégia de reprocessamento e regras de notificação

  • Evitar duplicidade: Não pode haver mensagens repetidas no mesmo pipeline dentro do intervalo definido.

  • Atualização de registros existentes: Se a chave já existir, o contador de ocorrências é incrementado.

  • Tempo para envio: O publicador define o tempo de espera.

  • Criticidade define o destino:

    • Nível 1: Apenas chamado (ex: ServiceNow)

    • Nível 2: Apenas alerta (ex: Dynatrace)

    • Nível 3: Alerta + chamado (ex: Dynatrace e ServiceNow)

Observabilidade e monitoramento

Para garantir a confiabilidade das notificações, recomenda-se:

  • Logging estruturado para rastrear eventos e erros.

  • Métricas como taxa de sucesso e tempo de resposta.

  • Alertas para falhas recorrentes.

Conclusão

Este modelo de notificação garante a entrega confiável e escalável de mensagens de erro em arquiteturas orientadas a eventos. Com a Digibee, é possível implementar esse modelo de forma flexível e integrada aos sistemas existentes, permitindo automação e rastreabilidade completa das notificações críticas.

Atualizado

Isto foi útil?