Motor de Calidad de Datos

Motor de Calidad de Datos o MQD es la herramienta de código abierto que evalúa la calidad de los datos que se comparten entre los participantes de Open Finance, asegurando así la integridad de la información.

Sensedia proporciona herramientas para facilitar la integración entre la Sensedia API Platform, Events Hub y MQD, permitiendo que los datos sean procesados de manera eficiente.

El diagrama ilustra esta integración:

Flujo de integración entre MQD

El diagrama presenta un flujo de integración de Open Finance, en el cual la Sensedia API Platform actúa como publicadora de APIs elegibles para el MQD — como cuentas, tarjetas y préstamos.

Los eventos generados por estas APIs se publican de forma asíncrona en el Sensedia Events Hub, que los consume, aplica políticas, los clasifica y los envía, a través de la MQD Subscriber API, al proxy de la Institución Financiera.

Este proceso garantiza la entrega eficiente, segura y controlada de los datos.

A continuación, se detalla el paso a paso para realizar la integración:

Etapa 1: Configuración del Events Hub

Contexto

  1. Cree un contexto, como muestra la imagen a continuación:

Pantalla de creación del contexto del MQD

Consulte más información sobre la configuración de contextos en Events Hub.

Handler

  1. Cree un handler, por ejemplo: MQD Handler.

  2. En la etapa Topics:

    1. Agregue los tópicos del cliente: accounts, consents, creditCardAccounts, etc. Debe configurar un tópico para cada API de datos elegible para el MQD.

      Configuración del tópico del MQD

    2. Habilite el contexto en cada tópico haciendo clic en la lupa.

      Cada tópico crea una URL de publicación, que deberá estar configurada en el interceptor Custom JS de las APIs de datos.

      Vea el ejemplo de una URL creada por Events Hub:

      Ejemplo de URL del tópico del MQD

  3. En la etapa Policy:

    1. Cree una política de IP Filtering Validation, que es específica para las IPs de salida de la Sensedia API Platform.

      Para consultar las IPs de la Sensedia API Platform, acceda al Gestor de Infraestructura:

    2. Complete los campos de las configuraciones de entrega (delivery settings):

      • Cantidad de reintentos,

      • Códigos para reintentos automáticos: 500, 502, 503, 504,408 y

      • Request timeout.

Después de registradas, las informaciones deben aparecer así:

Política de IP Filtering Validation

Consulte más información sobre la configuración de handlers en Events Hub.

Subscriber

  1. Cree un subscriber para el MQD, que será la API MQD subscriber.

    MQD Subscriber registrado

  2. En la etapa Security:

    1. Valide la clave y cree un token estático para el subscriber (opcional).

  3. En la etapa Topics:

    1. Seleccione el MQD Handler y luego seleccione los tópicos del cliente. Habilite la opción Publish.

    2. Complete el campo Subscriber URL con el endpoint de la API MQD subscriber.

    3. Agregue el código de estado 200 en el campo correspondiente.

Configuración del subscriber del MQD

Si la API está inactiva en el momento del registro, el status del subscriber aparecerá en color gris, pero esto no significa que estará inactiva.
Consulte más información sobre la configuración de subscribers en Events Hub.

Etapa 2: Configuración de la API MQD subscriber

Configure una API MQD subscriber que hará el proxy con el entorno de la institución financiera. Esta API será responsable de recibir los datos del Events Hub y enviarlos al MQD.

Al configurar esta API:

  1. En la etapa Resources:

    1. Agregue un recurso, por ejemplo: v1/report-data.

  2. En la etapa Flows:

    1. Inserte la URL que será el destino de la API, que varía según la API que se quiera exponer.

      Configuración del destino de la API

    2. Agregue los siguientes interceptores:

      • IP Filtering: con las IPs de salida del Events Hub (consulte las IPs con el equipo de soporte).

      • Access Token Validation: el mismo insertado en Events Hub.

      • Custom JS: manipulará el header para el formato del MQD. Puede personalizarlo para el cliente eliminando algunos headers que no serán necesarios.

        Consulte el interceptor Custom JS en el flujo de la API:

        Interceptor JS en la API MQD Subscriber

        Puede configurar el interceptor JS de la siguiente manera:

        const scriptName = String("MQD - Event Subscriber Interceptor ");
        const scriptVersion = String("1.0.0");
        try {
            $call.tracer.trace(">Sensedia debug => Custom javascript: Name [ "+scriptName+" ] version [ "+scriptVersion+" ]." );
            var json = JSON.parse( $call.request.getBody().getString( "utf-8" ) );
            $request.setHeader("endpointName", json.mqd.endpointName);
            $request.setHeader("serverOrgId", json.mqd.serverOrgId);
            $request.setHeader("x-fapi-interaction-id", json.mqd.fapiInteractionId);
        
            delete json['mqd'];
            $call.request.getBody().setString( $json.stringify(json), "utf-8" );
        
            $call.request.getAllHeaders().remove("x-clientname-webhooks-signature");
            $call.request.getAllHeaders().remove("access-token");
        
        
        } catch (exception) {
            $call.tracer.trace("Exception message => " + exception.message + " <= in line => " + exception.stack);
            $console.debug(">sensedia => Exception", exception);
        }
        Consulte más información sobre la creación de APIs en la Sensedia API Platform.

Etapa 3: Configuración del interceptor Custom JS en el flujo de las APIs de datos

En la Sensedia API Platform, seleccione las APIs de datos elegibles para el MQD:

  1. Agregue el interceptor Custom JS en la etapa de Flows. Si hay más de una API, coloque el interceptor una vez en cada API existente.

  2. En el campo Resources mantenga la opción "All".

Adición del Interceptor JS en el Flow

Puede configurar el interceptor Custom JS de la siguiente manera:

const scriptName = String("MQD - Event Producer Interceptor");
const scriptVersion = String("1.1.0");

try {

    $call.tracer.trace(">Sensedia debug => Custom javascript: Name [ "+scriptName+" ] version [ "+scriptVersion+" ]." );
    $console.debug("responseStatusCode", $call.response.getStatus());

    if ($call.response.getStatus() == 200 && $call.request.getMethod() == "GET") {

        const url = String($call.request.getRequestedUrl().getPath());

        const apiName = extractApiNameByUrl(url);

        $console.debug("apiName", apiName);

        const mqdTopicUrl = String($call.environmentVariables.get('mqd-'+ apiName +'-topic-handler-url'));

        $console.debug("mqdTopicUrl", mqdTopicUrl);

        if(mqdTopicUrl) {

            let jsonResponse = JSON.parse( $call.response.getBody().getString("UTF-8") );

            jsonResponse.mqd = {};
            jsonResponse.mqd.endpointName = substituirPathPorPathId(url);
            jsonResponse.mqd.serverOrgId = $call.request.getHeader("x-organisation-id");
            jsonResponse.mqd.fapiInteractionId = $response.getHeader("x-fapi-interaction-id");

            const response =  $http.post(mqdTopicUrl, $call.response.getHeaders(), $json.stringify(jsonResponse));

            $console.debug("response", response.responseText);
            $console.debug("response status", response.getStatus());

            $call.tracer.trace("Custom javascript: Name [ "+scriptName+" ] version [ "+scriptVersion+" ].Envio para MQD Finalizado." );

        } else {
            $call.tracer.trace("Custom javascript: Name [ "+scriptName+" ] version [ "+scriptVersion+" ]. ATENCIÓN!  environmentVariable >'mqd-"+ apiName +"-topic-handler-url'< no configurada! Ignorando envío al tópico MQD." );
        }
    }
} catch (exception) {
    $call.tracer.trace("Exception message => " + exception.message + " <= in line => " + exception.stack);
    $console.debug(">sensedia => Exception", exception);
}


function substituirPathPorPathId(urlSearch) {

  function substituir(match, pathAnterior) {
      // Remover el último carácter "s" del path anterior
      const pathId = pathAnterior.slice(0, -1) + 'Id';
      // Retornar el pathId entre llaves
      return '/' + pathAnterior + '/{'+pathId+'}';
  }
  //regex uuid estándar para los recursos api de datos
  let regex = /\/([^\/]+)\/([a-f0-9-]+)(?=\/|$)/g;

  //si es api consents el regex será diferente
  if(apiName === "consents"){
    regex = /\/([^\/]+)\/(urn:[a-zA-Z0-9-]+:[a-f0-9-]+)(?=\/|$)/g;
  }

  // Sustituir el nombre del path anterior más "Id" por el string dentro de las llaves
  const nuevaUrl = urlSearch.replace(regex, substituir);

  return nuevaUrl.match(/open-banking(.+)/)[1];
}

function extractApiNameByUrl(url) {
  const start = "open-banking/";
  const startIndex = url.indexOf(start);

  if (startIndex === -1) {
    return "";
  }

  const endIndex = url.indexOf("/", startIndex + start.length);
  if (endIndex === -1) {
    return url.substring(startIndex + start.length);
  }

  return url.substring(startIndex + start.length, endIndex);
}

En el interceptor Custom JS:

  • El método utilizado será siempre el GET, y la respuesta será 200, ya que el interceptor JS se activará cuando la API de datos reciba una respuesta exitosa.

  • Configure variables de entorno con la URL del tópico del Events Hub. Los tópicos crean URLs de publicación para cada uno de ellos (la cantidad de URLs varía según la cantidad de APIs).

Con esta configuración, los interceptores toman las respuestas elegibles para el MQD y las publican en un tópico del Events Hub.

Consulte más información sobre la configuración de interceptores y sobre el interceptor JS en la Sensedia API Platform.
Thanks for your feedback!
EDIT

Share your suggestions with us!
Click here and then [+ Submit idea]