¿Cómo puedo protegerme contra respuestas duplicadas procesadas por mi dominio?
De forma predeterminada, el puerto de dominio externo que proporciona el dominio viene con soporte de reintentos configurable. Para garantizar que los reintentos no se interpreten como respuestas independientes del dominio externo, el puerto aprovechará la tupla inputId y physicalMessageId para:
-
hacer cumplir la idempotencia
-
diferenciar entre reprocesamiento de mensajes (es decir, el mismo mensaje se consume dos veces) y envíos duplicados (es decir, se consumen dos mensajes diferentes que ambos tienen el mismo
inputId).
El inputId representa un identificador de negocio único (desde la perspectiva del flujo) para la respuesta de un dominio externo, y funciona como la referencia principal para las comprobaciones de idempotencia. Si no se especifica, el puerto lo establece como un UUID aleatorio.
El physicalMessageId representa un identificador de transporte único de la respuesta de un dominio externo y permite al sistema distinguir entre reprocesamiento de mensajes y envíos duplicados. Si no se especifica, el puerto lo establece como un UUID aleatorio.
Cuando se utiliza el marco de conectores de IPF, los mensajes de todos los transportes de conectores de recepción basados en broker compatibles contendrán un physicalMessageId adecuado dentro de su objeto ReceivingContext, que luego puede usarse para rellenar la entrada.
Si el flujo recibe dos entradas con el mismo inputId, la segunda entrada siempre omitirá la ejecución y dará como resultado un Done.Result.EXECUTED o un Done.Result.DUPLICATE, dependiendo del physicalMessageId. Si el physicalMessageId también es el mismo en ambas entradas, la segunda entrada se trata como un mensaje reprocesado y se devuelve un Done.Result.EXECUTED. De lo contrario, la entrada se trata como un envío duplicado y se devuelve un Done.Result.DUPLICATE.
Aunque los valores predeterminados asignados por el puerto para inputId y physicalMessageId proporcionan una protección de idempotencia adecuada para la mayoría de los escenarios, hay algunos casos límite, como cuando tu flujo maneja el mismo tipo de entrada desde múltiples estados no exclusivos, que requerirán que especifiques al menos un inputId para evitar que el reprocesamiento de mensajes o los envíos duplicados disparen incorrectamente una transición de flujo. A continuación se proporciona un ejemplo de cómo hacerlo:
XYZDomain.externalDomainPort().handle(new ExternalDomainResponseInput
.Builder(id, ExternalDomainResponseCodes.OK)
.withInputId(someInputIdFromResponseMessage)
.build());