¿Cómo identificar mensajes duplicados en Servicios construidos en Oracle SOA SUITE 11g?

Un requerimiento normal en implementaciones que tienen que ver con la construcción y despliegue de Servicios, es la identificación de mensajes duplicados.
Por ejemplo:
Un Servicio que represente el ingreso de Contratos. Si el consumidor no tiene forma de evitar que una vez que ya se haya enviado la información al Servicio, no se vuelva a enviar (quizás porque el usuario dio click en el botón de enviar, varias veces, sin querer), se estarán duplicando las llamadas y quizás, lo cual sería lo mas crítico, duplicándolos en el sistema destino.
Estos son escenarios que pueden aplicar para cualquier tipo de escenario en dónde una aplicación está enviando información a una o mas aplicaciones destino, y queremos evitar que las llamadas estén duplicadas, siendo que el consumidor no lo puede controlar.
Bien, una forma de evitar este tipo de situaciones es utilizando las capacidades de Oracle Mediator. En particular, nos referimos a la características de identificar Secuencias en los datos del mensaje.
Hay varias formas en las que Oracle Mediator puede ejercer esta funcionalidad. En la documentación oficial de Oracle, se describe a detalle cuáles son. Esto se puede encontrar aquí.
La que vamos a utilizar en este artículo, es la Standard.
Básicamente, en esta modalidad, lo que se busca es agrupar los mensajes a partir de un identificador, así como tener un elemento que sirva como secuencia para identificar que es un mensaje diferente.
Supongamos que tenemos el siguiente mensaje:
image
Es un mensaje muy simple que identifica un Contrato; se tiene un identificador (idContrato) del mismo, un campo que sirve para establecer la secuencia (idSeq), y después ya los elementos propios del Contrato.
Se tiene un Servicio muy simple, que recibe los datos del Contrato, y los transfiere, a través de un Mediator, hacia un segundo Servicio, que seguramente hará la inserción en algún sistema destino.
image
La configuración que debemos hacer en el Mediator, para poder identificar si un mensaje está siendo duplicado, es la siguiente:
  1. Da dos clicks en Mediator
  2. Ubica la sección dónde se especifica: Resequence Level & Mode.
  3. Ahí escoge: Resequence Level –> component
  4. También Resequence Mode –> Standard
La parte importante, es poder tener elementos en el mensaje que nos permitan agrupar a los mensajes, y poder identificar la secuencia. Esto lo vemos aquí:
image
En la sección: Resequence Options, vemos dos campos: Group y ID.
En Group, vamos a colocar el campo: $in.request/inp1:CONTRATO/inp1:idContrato
pues este campo, nos sirve para identificar un Contrato en particular.
Y en el campo ID: $in.request/inp1:CONTRATO/inp1:idSeq
Pues es la secuencia que vamos a utilizar para identificar que un Contrato en particular está siendo repetido.
También arrancamos la secuencia en 1, y lo incrementamos en 1, igualmente.
Supongamos el siguiente mensaje:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:exam="http://www.example.org">
   <soapenv:Header/>
   <soapenv:Body>
      <exam:CONTRATO>
        <exam:idContrato>contrato1</exam:idContrato>
         <exam:idSeq>1</exam:idSeq>
         <exam:dato1>dato1</exam:dato1>
         <exam:dato2>dato2</exam:dato2>
      </exam:CONTRATO>
   </soapenv:Body>
</soapenv:Envelope>
Este mensaje, representaría que quiero ingresar el contrato1, de manera que si todo se ejecuta de manera adecuada, éste contrato será ingresado en el sistema destino.
Pero si el consumidor, por error, o por alguna otra razón, vuelve a enviar el mismo mensaje, entonces no debe ser procesado.
Si se desplegara el Servicio que estamos usando de ejemplo, y se duplicara un mensaje, el error que se generaría, es el siguiente:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <env:Fault>
         <faultcode>env:Server</faultcode>
         <faultstring>oracle.tip.mediator.infra.exception.MediatorException: ORAMED-04004:[Error persiting resequencer message due to internal Error.]Error persiting resequencer message," oracle.tip.mediator.common.persistence.MediatorResequencerMessage, mediator InstanceId=3E1C6060EA1711E1BFDD8782EC97EFB7, componentDn=default/RACARRASCO_SOA_RESEQ!1.0/Mediator1, operation=execute, groupId=contrato1, sequenceId=1, status=0" , due to internal Error.. Reason : {1}Possible Fix:Check log file for any exceptions and contact Oracle Support Services for further help.</faultstring>
         <faultactor/>
         <detail>
            <exception/>
         </detail>
      </env:Fault>
   </env:Body>
</env:Envelope>
En amarillo, se puede ver cómo los datos que ayudan a identificar al mensaje, aparecen como los causantes de no haberse procesado.
En el Enterprise Manager, veríamos:
image
El mensaje sí llega a la SOA-INFA, pero es detenido en el mediator, que marca a la transacción como fallida.