Documentation for a newer release is available. View Latest

DSL 5 - Uso de una decisión

Comenzando

Este paso del tutorial utiliza como punto de partida la solución add_external_domain del proyecto.

Si en cualquier momento quieres ver la solución de este paso, la encontrarás en la solución add_decision.

¿Qué es una decisión?

Hasta ahora hemos añadido una función de dominio (llamada interna) y un dominio externo (llamada externa). Ahora es momento de considerar algunas de las opciones de procesamiento disponibles para determinar cómo procesar nuestros pagos.

En esta sección del tutorial, necesitamos decidir cuándo realizar la comprobación de fraude que deberías haber implementado como parte del ejercicio del tutorial anterior (si no completaste ese ejercicio, trae aquí la implementación de la comprobación de fraude desde add_external_domain). Los criterios que determinan si realizamos la comprobación de fraude son los siguientes:

  • Si el valor del pago es ⇐ 10, entonces omitimos la comprobación de fraude.

  • Si el valor del pago es > 10, entonces ejecutamos la comprobación de fraude.

Podemos utilizar "decisiones" para modelar este comportamiento.

Una "decisión" en el DSL es muy simple: es una función que recibe algunos datos y devuelve un tipo especial de resultado llamado "resultado" (outcome). A diferencia de una función de dominio, donde el resultado puede ser un dato de negocio complejo, un resultado solo puede ser una cadena simple, por ejemplo SKIP o CHECK. Esta simplicidad de una decisión nos aporta varios beneficios:

  • Una decisión no requiere definición de respuestas.

  • Una decisión no requiere definición de comportamientos de entrada.

  • Una decisión no requiere definir eventos.

Configuración del DSL

Añadir una decisión

Empecemos añadiendo una nueva biblioteca de decisiones a nuestro modelo. Como antes, haz clic derecho en el modelo y selecciona New  v2Flo  Decision Library.

Esto debería mostrar la nueva página de biblioteca de decisiones:

decision 1

En esta ocasión dejaremos nuestra biblioteca con el nombre por defecto "Decision Library". Podríamos proporcionar un nombre diferente y tener tantas bibliotecas como necesitemos.

Sigamos adelante y añadamos nuestra lógica de decisión. Primero añadiremos los campos como hemos hecho muchas veces en pasos anteriores:

  • Para el nombre, usaremos "Run Fraud Check".

  • Para la descripción, usaremos "Checks payment value requires a fraud check".

  • Para los datos de negocio, usaremos "Customer Credit Transfer".

El siguiente campo es "Outcomes" (resultados), que es un concepto nuevo.

Un "Outcome" es simplemente un posible resultado de la decisión. Una decisión puede tener tantos resultados diferentes como quieras; son muy similares a los "Response Codes" que usamos anteriormente.

El campo de outcomes es texto libre que nos permite introducir un nombre, así que especifiquemos dos resultados:

  • FRAUD_REQUIRED

  • SKIP_FRAUD

Para introducir nuevos outcomes, simplemente pulsa la tecla Return tras completar el anterior.

Una vez completado, nuestra decisión debería verse así:

decision 2

Con esto nuestra decisión está definida y lista para usarse, así que el siguiente paso es integrarla en el flujo.

Usar una decisión

Una decisión se maneja de forma ligeramente diferente a las llamadas de función de dominio o dominio externo que hemos usado hasta ahora. En esos ejemplos, utilizamos pasos concretos específicos para representar el hecho de que el sistema estaba realizando esas funciones. En el caso de una decisión, sin embargo, es solo una posición de enrutamiento en el flujo y, como tal, presentamos ahora el concepto de un estado pseudo. Se utilizarán en diferentes casos más adelante en el tutorial, pero por ahora usaremos el que necesitamos para decisiones, al que nos referiremos como estado de decisión.

Como se mencionó en la introducción, la decisión es muy ligera, por lo que no hay necesidad de añadir eventos ni comportamientos de entrada aquí. Podemos saltar directamente al procesamiento de Event Behaviour.

Básicamente, ahora queremos decir: "Una vez que hayamos recibido el evento Account Validation Passed, deberíamos ejecutar la decisión de fraude. Si requiere una comprobación de fraude, ejecutaremos la comprobación de fraude como antes; en caso contrario, simplemente completaremos nuestro pago".

Así que empecemos editando nuestro manejo del evento "Account Validation Passed"; antes teníamos:

decision 3

Ahora, en lugar de movernos al estado "Checking Fraud", nos moveremos al estado de decisión "Run Fraud Check" y ejecutaremos nuestra decisión. Para esto, en lugar de seleccionar un estado concreto como "Checking Fraud" en la sección "Move To State", elegimos "Create Decision State".

decision 4

Aquí podemos introducir el nombre del estado como "Run Fraud Check" (ten en cuenta que no tiene por qué ser el mismo nombre que la decisión que pensamos usar. Es una buena regla general hacerlo, pero al permitir cualquier nombre aquí podemos reutilizar la misma decisión en múltiples casos de uso en todo nuestro flujo).

Luego, en perform action, elegimos "Routing Decision" y, a continuación, elegimos la decisión "Run Fraud Check" (que creamos en nuestra "Decision Library").

Una vez terminado, debería verse así:

decision 5

Ahora manejemos el resultado de nuestra comprobación de fraude. Para ello añadiremos comportamientos de evento para completar el flujo (si se omite la comprobación) o ejecutar la comprobación de fraude (si se requiere la comprobación).

Comencemos añadiendo el caso de omisión. Añadirás un nuevo comportamiento de evento y especificarás:

  • "With Current State" como nuestro estado de decisión "Run Fraud Check".

  • "When" como "On".

Para el evento, usamos un tipo especial de evento, el "Decision Outcome Event"; así que seleccionamos "Decision Outcome" y luego elegimos nuestro outcome "SKIP_FRAUD". Para completar nuestro comportamiento simplemente nos movemos a "Complete". Una vez finalizado debería verse así:

decision 6

A continuación, necesitamos el comportamiento cuando la decisión dice que debemos ejecutar la comprobación de fraude. En ese caso simplemente queremos movernos al estado "Checking Fraud" y ejecutar la petición "Fraud Check". Intenta añadir esto o, si lo prefieres, la solución está abajo:

decision 7

Eso es todo; ya hemos integrado nuestra decisión en el flujo. Abrámoslo en el Flow Viewer (Tools > "Open Flo Viewer") y veamos cómo queda:

decision 8
Top Tip

En los comportamientos de evento con estados de decisión, puedes añadir múltiples outcomes y redirigirlos a diferentes estados o acciones según sea necesario. Usa nombres de outcomes claros y consistentes para facilitar el mantenimiento.

Implementación en Java

Cambiemos ahora a IntelliJ y veamos cómo conectamos esto con nuestro código de implementación. Como de costumbre, empezaremos ejecutando una build desde una ventana de terminal:

mvn clean install

Una vez construido, podemos revisar el puerto generado de la biblioteca de decisiones y añadir una implementación adaptadora que devuelva FRAUD_REQUIRED si el valor del pago es > 10, o SKIP_FRAUD en caso contrario. Un ejemplo ilustrativo (resumido) podría ser:

.withDecisionLibraryAdapter(input ->
    input.getCustomerCreditTransfer().getCdtTrfTxInf().get(0).getIntrBkSttlmAmt().getValue().compareTo(BigDecimal.TEN) > 0 ?
        RunFraudCheckDecisionOutcomes.FRAUDREQUIRED : RunFraudCheckDecisionOutcomes.SKIPFRAUD)

Comprobación de nuestra solución

Inicia la aplicación como anteriormente (si necesitas recordatorio, consulta Revisión de la aplicación inicial).

Envía un pago con un valor ⇐ 10 y comprueba que el flujo se completa sin ejecutar la comprobación de fraude.

A continuación, envía un pago con un valor > 10 y comprueba que el flujo ejecuta la comprobación de fraude y continúa según lo definido.

Conclusiones

En esta sección:

  • Definimos una biblioteca de decisiones con outcomes claros.

  • Integramos la decisión en el flujo usando un estado de decisión y comportamientos de evento.

  • Implementamos la lógica en Java y comprobamos su funcionamiento de extremo a extremo.