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
| Componente | Descripción |
|---|---|
| Origen | API REST de Parsable |
| Orquestador | Apache NiFi |
| Formato | CSV |
| Base de datos | Omnicanal |
| Esquema | general_catalogs |
| Tabla destino | alp_cat_parsable |
| Tabla de auditoría | alp_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ámetro | Descripción |
|---|---|
url_base_api | Endpoint principal de Parsable |
team_id | Identificador del equipo de Alpura |
token_acceso | Token Bearer utilizado para autenticación |
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
| Propiedad | Valor |
|---|---|
| Connection Pool | PostgreSQL |
| Tabla | alp_cat_parsable |
| Record Reader | CSVReader |
| Estrategia | REMOVE_UNDERSCORE |
9. Auditoría
Todos los eventos del flujo generan un registro en:
alp_cat_parsable_logs
9.1 Información registrada
| Campo | Descripción |
|---|---|
archivo_uuid | Identificador único (UUID) del FlowFile procesado por Apache NiFi. |
mensaje_error | Descripción del error capturado durante la ejecución. En procesos exitosos puede permanecer vacío o nulo. |
url_ws | URL del servicio web que generó el error o que fue invocado durante el proceso. |
fecha_inicio | Fecha y hora de inicio del rango de extracción utilizado para generar el reporte. |
fecha_fin | Fecha y hora de fin del rango de extracción utilizado para generar el reporte. |
report_id | Identificador del reporte generado por la API de Parsable. |
team_id | Identificador del equipo (Team) configurado en Parsable para la generación del reporte. |
url_base | URL base de la API de Parsable utilizada durante la ejecución del flujo. |
token_usado | Token de autenticación (Bearer Token) utilizado para consumir la API. Por motivos de seguridad se recomienda almacenar únicamente una versión enmascarada o parcial. |
estado | Resultado final de la ejecución del flujo. Valores esperados: EXITO o ERROR. |
paso_flujo | Nombre 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.
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.