Skip to main content

Parsable a Omnicanal mediante Apache Niffi

1. Objetivo

Este documento describe el flujo de integración implementado en Apache NiFi para la extracción automática de reportes desde Parsable, su procesamiento y la carga en la base de datos Omnicanal.

El proceso contempla:

  • Extracción programada de reportes CSV.
  • Espera automática hasta que el reporte esté disponible.
  • Descarga segura mediante URL firmada.
  • Carga masiva en Omnicanal.
  • Registro de auditoría y errores.

2. Arquitectura General

ComponenteDescripción
OrigenAPI REST de Parsable
OrquestadorApache NiFi
FormatoCSV
Base de datosOmnicanal
Esquemageneral_catalogs
Tabla destinoalp_cat_parsable
Tabla de auditoríaalp_cat_parsable_logs

3. Flujo del proceso

El flujo completo se divide en cuatro etapas:

3.1. Inicialización

  • Generación automática del flujo a las 08:00 AM
  • Cálculo dinámico del rango de fechas
  • Construcción del JSON de solicitud

3.2. Orquestación del reporte

  • Solicitud del reporte a Parsable
  • Obtención del report_id
  • Consulta periódica del estado
  • Espera hasta que el reporte se encuentre en estado READY

3.3. Descarga e ingestión

  • Obtención de URL firmada
  • Descarga del archivo CSV
  • Conversión mediante CSVReader
  • Inserción mediante PutDatabaseRecord

3.4. Auditoría

  • Registro de éxito
  • Registro de errores
  • Persistencia del log mediante PutSQL

4. Diagrama del flujo


5. Componentes de Apache NiFi

5.1. Contexto de parámetros

El flujo utiliza un Parameter Context denominado:

Parsable_Postgres

5.2 Parámetros

ParámetroDescripción
url_base_apiEndpoint principal de Parsable
team_idIdentificador del equipo de Alpura
token_accesoToken Bearer utilizado para autenticación
info

Las credenciales nunca deben almacenarse directamente en los procesadores de NiFi.

Se recomienda utilizar Parameter Contexts para facilitar la administración entre ambientes.


6. Ventana de extracción

El proceso siempre obtiene información de las últimas 24 horas.

6.1. Fecha inicio

${now():toNumber():minus(86400000):format("yyyy-MM-dd'T'08:00:00.000'Z'", "America/Mexico_City")}

6.2. Fecha fin

${now():format("yyyy-MM-dd'T'07:59:59.000'Z'", "America/Mexico_City")}

7. Procesamiento del CSV

El archivo descargado es interpretado mediante un CSVReader.

Esquema Avro

{
"type": "record",
"name": "ReporteParsable",
"fields": [
{ "name": "job_id", "type": ["null", "string"] },
{ "name": "job_guid", "type": ["null", "string"] },
{ "name": "record_type", "type": ["null", "string"] },
{ "name": "job_title", "type": ["null", "string"] },
{ "name": "job_created_date_utc", "type": ["null", "string"] },
{ "name": "job_started_date_utc", "type": ["null", "string"] },
{ "name": "job_last_updated_date_utc", "type": ["null", "string"] },
{ "name": "job_completed_date_utc", "type": ["null", "string"] },
{ "name": "job_cancelation_date_utc", "type": ["null", "string"] },
{ "name": "job_archived_date_utc", "type": ["null", "string"] },
{ "name": "job_status", "type": ["null", "string"] },
{ "name": "job_total_steps", "type": ["null", "int"] },
{ "name": "job_completed_steps", "type": ["null", "int"] },
{ "name": "job_template_guid", "type": ["null", "string"] },
{ "name": "job_template_title", "type": ["null", "string"] },
{ "name": "job_template_version", "type": ["null", "string"] },
{ "name": "job_template_publisher_name", "type": ["null", "string"] },
{ "name": "job_template_publisher_email", "type": ["null", "string"] },
{ "name": "template_order_number", "type": ["null", "double"] },
{ "name": "step_guid", "type": ["null", "string"] },
{ "name": "step_title", "type": ["null", "string"] },
{ "name": "step_hierarchy_position", "type": ["null", "string"] },
{ "name": "step_type", "type": ["null", "string"] },
{ "name": "step_status", "type": ["null", "string"] },
{ "name": "step_is_na", "type": ["null", "boolean"] },
{ "name": "step_last_updated_date_utc", "type": ["null", "string"] },
{ "name": "step_started_date_utc", "type": ["null", "string"] },
{ "name": "client_step_started_date_utc", "type": ["null", "string"] },
{ "name": "step_completed_date_utc", "type": ["null", "string"] },
{ "name": "client_step_completed_date_utc", "type": ["null", "string"] },
{ "name": "step_duration", "type": ["null", "string"] },
{ "name": "client_step_duration", "type": ["null", "string"] },
{ "name": "parent_step_group_title", "type": ["null", "string"] },
{ "name": "field_guid", "type": ["null", "string"] },
{ "name": "field_label", "type": ["null", "string"] },
{ "name": "field_type", "type": ["null", "string"] },
{ "name": "field_value", "type": ["null", "string"] },
{ "name": "field_is_na", "type": ["null", "boolean"] },
{ "name": "field_measurement_units", "type": ["null", "string"] },
{ "name": "field_seq_id", "type": ["null", "string"] },
{ "name": "field_executor_user_email", "type": ["null", "string"] },
{ "name": "field_executor_user_name", "type": ["null", "string"] },
{ "name": "field_last_updated_date_utc", "type": ["null", "string"] },
{ "name": "field_exec_updated_date_utc", "type": ["null", "string"] },
{ "name": "field_is_required", "type": ["null", "boolean"] },
{ "name": "attr_locations", "type": ["null", "string"] },
{ "name": "attr_bus_func", "type": ["null", "string"] },
{ "name": "attr_bus_units", "type": ["null", "string"] },
{ "name": "template_attr_locations", "type": ["null", "string"] },
{ "name": "template_attr_bus_func", "type": ["null", "string"] },
{ "name": "template_attr_bus_units", "type": ["null", "string"] },
{ "name": "job_parameter_tags", "type": ["null", "string"] }
]
}

8. Inserción en Omnicanal

El procesador encargado de la persistencia es:

PutDatabaseRecord

8.1 Configuración

PropiedadValor
Connection PoolPostgreSQL
Tablaalp_cat_parsable
Record ReaderCSVReader
EstrategiaREMOVE_UNDERSCORE

9. Auditoría

Todos los eventos del flujo generan un registro en:

alp_cat_parsable_logs

9.1 Información registrada

CampoDescripción
archivo_uuidIdentificador único (UUID) del FlowFile procesado por Apache NiFi.
mensaje_errorDescripción del error capturado durante la ejecución. En procesos exitosos puede permanecer vacío o nulo.
url_wsURL del servicio web que generó el error o que fue invocado durante el proceso.
fecha_inicioFecha y hora de inicio del rango de extracción utilizado para generar el reporte.
fecha_finFecha y hora de fin del rango de extracción utilizado para generar el reporte.
report_idIdentificador del reporte generado por la API de Parsable.
team_idIdentificador del equipo (Team) configurado en Parsable para la generación del reporte.
url_baseURL base de la API de Parsable utilizada durante la ejecución del flujo.
token_usadoToken de autenticación (Bearer Token) utilizado para consumir la API. Por motivos de seguridad se recomienda almacenar únicamente una versión enmascarada o parcial.
estadoResultado final de la ejecución del flujo. Valores esperados: EXITO o ERROR.
paso_flujoNombre del procesador o etapa de Apache NiFi donde se registró el evento o se produjo el error.

9.2 Sentencia utilizada

INSERT INTO general_catalogs.alp_cat_parsable_logs
(archivo_uuid, mensaje_error, url_ws, fecha_inicio, fecha_fin, report_id, team_id, url_base, token_usado, estado, paso_flujo)
VALUES
('${uuid}', '${mensaje_error}', '${url_fallida}', '${log_fecha_inicio}', '${log_fecha_fin}', '${log_report_id}', '${log_team_id}', '${log_url_base}', '${log_token}', '${log_estado}', '${log_paso}');

10. Manejo de errores

Los errores pueden ocurrir durante:

  • Invocación del API
  • Consulta del estado
  • Descarga del archivo
  • Inserción en PostgreSQL

Todos los errores son registrados automáticamente en la tabla de auditoría.

info

Si la inserción del log falla, el flujo envía la información al logger interno de Apache NiFi para evitar pérdida de trazabilidad.


11. Resultado esperado

Al finalizar correctamente el proceso se obtiene:

  • Reporte descargado desde Parsable.
  • Información cargada en alp_cat_parsable.
  • Registro de auditoría generado.
  • Evidencia de ejecución disponible para monitoreo.