DSL 9 - Usando Subflows

Iniciando

El paso del tutorial utiliza la solución "add_version" del proyecto como su punto de partida.

Si en algún momento desea ver la solución a este paso, ¡esta se puede encontrar en la solución "add_subflow"!

¿Qué es un Subflujo?

Un "Subflujo" es una sección reutilizable de un flujo. Efectivamente, tiene todas las mismas características que un flujo, pero no se espera que sea independiente, sino que se incluye dentro de otro flujo.

Un subflujo puede, por lo tanto, ser:

  • Utilizado en muchos flujos diferentes.

  • Utilizado múltiples veces dentro del mismo flujo.

Un ejemplo frecuentemente observado de un subflujo es una verificación de sanciones. Puede ser que muchos flujos diferentes utilicen una verificación de sanciones o, de hecho, que se necesite una verificación de sanciones en diferentes partes del flujo (por ejemplo, tras una reanudación tras un retraso).

Para esta sección, utilizaremos el ejemplo de sanciones para integrar un subflujo en nuestro flujo.

Nuestro subflujo de sanciones deberá realizar las siguientes acciones:

Cuando comienza el subflujo, hacemos una solicitud a un sistema de sanciones.

Entonces, el sistema de sanciones puede devolver:

  • Aprobado-todo está bien, el flujo puede continuar.

  • Espere

Entonces, en la condición de espera, debemos esperar hasta que los sistemas de sanciones nos envíen uno de los tres mensajes adicionales:

  • Aprobado

  • Bloqueado

  • Fallido

Configuración de DSL

Añadiendo el Sanctions Domain

Antes de comenzar a examinar el subflujo en sí, primero necesitamos agregar un dominio externo que sea capaz de soportar nuestro flujo. Así que procedamos a hacerlo.

Primero, crearemos un nuevo dominio externo para nuestro sistema de sanciones. Esto es similar a lo que hicimos en (Nuevo  v2Flo  Dominio Externo), excepto que la respuesta necesita utilizar una capacidad adicional que no hemos discutido completamente antes. Así que comencemos añadiendo lo básico:

  • Un nombre de " Sanctions Domain "

  • Una descripción de "Un sistema de sanciones de muestra"

  • Agregue una solicitud con detalles:

    • Un nombre de "Verificar Sanciones"

    • Una descripción de "Llamada de sanciones de muestra"

    • Agregue el customer credit transfer to business data

Ahora consideramos las respuestas. Hay varias maneras diferentes en las que podríamos modelar las respuestas requeridas utilizando combinaciones de response codes y reason codes como lo hicimos en el sistema de fraude. Aquí, sin embargo, lo haremos modelando múltiples respuestas a nuestra única solicitud de sanciones.

La primera respuesta es el escenario "aprobado", lo llamaremos un escenario de "no coincidencia". Para esto, simplemente añadimos una respuesta sencilla como la que hemos tenido antes:

  • Un nombre de "Sanctions No Hit"

  • Una descripción de "La verificación de sanciones ha sido superada"

  • Dejaremos todos los demás campos como los predeterminados.

La segunda respuesta es aquella en la que la verificación inicial no pasa de inmediato y se nos solicita esperar. Usted llamará a esto un escenario de "hit".

La principal diferencia entre los escenarios de "acierto" y "sin acierto" es que:

  • en el escenario sin resultados, completa la solicitud-es decir, no estamos esperando ninguna información adicional del sistema de sanciones.

  • en el escenario de éxito no se completa la solicitud, todavía estamos esperando un resultado final de nuestra llamada de sanciones.

Así que esta vez, para nuestro escenario de éxito necesitamos establecer nuestro "Completar" flag to false para informar al sistema que esperamos mensajes subsiguientes del sistema de sanciones en respuesta a la solicitud inicial.

Establezcamos esta respuesta:

  • Un nombre de "Sanctions Hit"

  • Una descripción de "El sistema de sanciones está verificando el resultado".

  • La finalización flag sin verificar

  • Dejaremos todos los demás campos como los predeterminados.

Finalmente, también necesitamos la respuesta del resultado cuando las sanciones system event Normalmente nos envía una respuesta. Usted llamará a esto la "Respuesta Final de Sanciones". Así que añadamos esto:

  • Un nombre de "Respuesta Final a Sanciones"

  • Una descripción de "El resultado final del sistema de sanciones"

  • Para el response codes Necesitaremos crear una nueva biblioteca de códigos de respuesta para nuestras "Sanciones Finales". Response Codes ". Esto es igual que en DSL 4 Usando un Dominio Externo. En nuestro caso, tendremos tres" response codes: Falso positivo, Bloquear, Rechazar.

  • Todos los demás campos los dejaremos como predeterminados.

Una vez que hayamos reunido todo esto, la definición de nuestro sistema de sanciones debería verse así:

subflow 1

Y para referencia, nuestro nuevo "Sanctions Final Response Codes " se verá como:

subflow 2

Tenga en cuenta que podemos simplemente agregar nuestro response codes a la biblioteca existente que utilizamos para nuestros códigos de validación de cuentas.

Ese es nuestro sistema de sanciones, completamente configurado y listo para usar.

Añadiendo el Subflujo

Ahora que tenemos nuestro sanctions domain configure, proceda a crear nuestro subflujo. Hacemos esto haciendo clic derecho en nuestro modelo y seleccionando Nuevo  v2Flo  Subflujo.

Esto debería crear una nueva página de subflujo:

subflow 3

Lo primero que debe tener en cuenta es cuán similar es esto a la página de flujo. ¡Eso se debe a que es efectivamente un tipo especializado de flujo! Por lo tanto, utilizar esta página debería resultar muy familiar.

Establezcamos nuestro nuevo subflujo, comenzaremos dándole a nuestro flujo de sanciones un nombre de "Subflujo de Sanciones" y una descripción de "Un subflujo de ejemplo para sanciones".

Lo siguiente a considerar son los estados que vamos a necesitar. A partir de los requisitos, podemos ver que hay tres estados que necesitaremos:

  • Una "Verificación de Sanciones" state para cuando hacemos la solicitud inicial a las sanciones y estamos a la espera de una respuesta.

  • Un "Resultado Final Pendiente" state para cuando hayamos recibido una notificación de espera de sanciones y estemos a la espera de la respuesta final.

  • Un "Completo" state para cuando hayamos completado con éxito una verificación de sanciones.

  • Un "Rechazado" state para cuando se haya realizado la verificación de sanciones failed.

  • A "Bloqueado" state para cuando la verificación de sanciones ha resultado en una notificación bloqueada.

Proceda a configurar estos ahora. Considere qué valores necesitará para el terminal.flag y global state sobre cada uno de estos estados y cuando esté completo, la solución se encuentra a continuación:

subflow 4

Es realmente importante dentro de un subflujo obtener correctamente los estados terminales. Esto se debe a que esos son los estados que el subflujo podrá informar de vuelta al flujo principal. Así que aquí tenemos "Completo", "Rechazado" y "Bloqueado" como estados terminales. Esto se debe a que los estados "Verificando Sanciones" y "Esperando Resultado Final" son estados intermedios durante el procesamiento del subflujo. Podemos enfatizar aún más esto mediante la configuración de la variable global "PENDIENTE".state.

Ahora continuemos con nuestro subflujo y lo siguiente a considerar es el events. Volviendo nuevamente a los requisitos, podemos ver que necesitaremos 4 events:

  • "Sancciones Aprobadas" para una verificación de sanciones exitosa

  • "Sancciones Rechazadas" para un failed verificación de sanciones

  • "Sancciones Bloqueadas" para una verificación de sanciones bloqueada

  • "Las sanciones afectan" para una notificación de espera.

Nota aquí que hay muchas diferentes event nombres que podríamos utilizar. Hemos decidido utilizar el mismo event "Sancciones Aprobadas" tanto para el paso directo como indirecto (a través de espera) de la verificación de sanciones. Podríamos haber creado dos events para identificar cada uno de manera única.

Añadamos estos Event Definiciones ahora y deberíamos ver:

subflow 5

Continuando con nuestro subflujo, nuestra próxima sección a considerar es el Comportamiento de Entrada. Aquí debemos considerar cada una de nuestras tres respuestas diferentes del sistema de sanciones y cómo deseamos manejarlas. Intente hacerlo usted mismo y la solución se encuentra a continuación:

subflow 6

A continuación, al iniciar, necesitamos llamar al sistema de sanciones. Por lo tanto, necesitaremos un nuevo state "Verificación de Sanciones" y un initiation behaviour que nos lleva a la "Verificación de Sanciones" state y llama a nuestro sistema de sanciones. Intente eso ahora y la solución está abajo:

subflow 7

Finalmente, necesitamos manejar nuestro event comportamiento. Vea si puede resolverlo, y luego la solución se encuentra a continuación:

subflow 8

El único punto interesante a señalar aquí es cómo hemos manejado la línea 4 en el event comportamiento. Hubiera sido igualmente correcto tener dos líneas aquí, una para el "Verificando Sanciones" actual state y uno para el "Resultado Final en Espera" actual state. Pero hemos elegido aquí utilizar la capacidad de tener múltiples estados definidos en el actual state. Esta es simplemente una forma abreviada de evitar repetir la misma lógica múltiples veces si el resultado no es diferente.

Hemos completado todas nuestras secciones del flujo, pero si miramos, todavía hay un error que se muestra en el "Realizar Acción" del initiation behaviour. Investiguemos esto validando el flujo (ALT + ENTER y luego valide el flujo). Nos indica:

subflow 20

Nos está indicando que el subflujo no tiene acceso a un customer credit transfer y por lo tanto no puede realizar la llamada al sistema de sanciones. En nuestro caso, nuestro customer credit transfer pertenece al flujo principal. Por lo tanto, para proporcionarlo al subflujo, debemos añadirlo a los datos de iniciación, hagámoslo y ahora deberíamos ver:

subflow 9

Y nuestro error ha sido resuelto. Como es habitual, antes de completar, consultemos nuestro gráfico (Herramientas > Abrir Visor de Flujo) para encontrar:

subflow 10

Ese es nuestro subflujo completamente configurado y listo para usar, así que la siguiente pregunta es cómo aplicamos esto a nuestro flujo principal. Regresemos a él, actualizaremos solo en nuestra última versión V2:

Vamos a añadir nuestro subflujo como un nuevo paso después de la validación de nuestra cuenta. Actualmente, tenemos:

subflow 11

Para incluir el paso adicional, queremos que la cuenta de validación llame a nuestro subflujo (no ejecute la verificación de fraude).decision) y luego ejecute la verificación de fraude en lugar de pasar las sanciones con éxito.

Si recuerda de vuelta a DSL 5 - Utilizando una decisión, introdujimos el concepto de un pseudo state y en ese caso el tipo específico de un " Decision State ". Aquí queremos utilizar un tipo diferente de state-a "Subflujo State ". Comencemos añadiéndolo después de recibir el resultado de "Validación de Cuenta Aprobada".

Así que en lugar de pasar a "Ejecutar Verificación de Fraude" decision, creemos nuestro "Subflujo State.

  • Para hacer esto, primero necesitamos eliminar el existente decision state y luego seleccione "Crear Subflujo" State.

  • Ingresará el nombre como "In Sanctions".

  • Luego, en el cuadro "Realizar Acción", eliminaremos la llamada existente a Fraude y luego seleccionaremos "Llamar Subflujo" y elegiremos el "Subflujo de Sanciones". Una vez hecho esto, deberíamos ver lo siguiente:

subflow 12

Si usted inspecciona el error ahora, veremos:

subflow 13

Aquí podemos ver que el flujo necesita que definamos cómo manejar el hecho de que el subflujo ha alcanzado esos estados de Completo, Rechazado o Bloqueado. ¿Por qué solo esos 3? Porque esos son los que especificamos como terminales con el subflujo de sanciones.

Establezcamos nuestro manejo del subflujo que termina como " Event "Comportamiento" en el flujo principal V2. Para hacer esto, comenzamos añadiendo un nuevo Event Comportamiento con corriente state de "En Sanciones". Luego en el "Para Event "seleccionamos "Finalización de Subflujo", y luego comenzaremos seleccionando "Completar"."

En nuestro caso, al recibir la información completa del flujo de sanciones, necesitaremos crear nuestro "Ejecutar Verificación de Fraude".decision y active la verificación de fraude decision como habíamos mencionado anteriormente (nota-hasta que esto esté hecho "Ejecutar Verificación de Fraude" aparece como una 'Referencia No Resuelta'):

subflow 14

Ahora hagamos lo mismo para manejar el resultado de Rechazado y Bloqueado, por ahora simplemente enviaremos ambos a rechazado.

subflow 15

Nuevamente, observe aquí cómo hemos utilizado la capacidad de "Cualquiera de" para minimizar la entrada.

Finalmente, analicemos cómo esto ha impactado nuestro diagrama de flujo (Herramientas > Abrir FlowViewer):

subflow 16

Aquí podemos ver que nuestra llamada de subflujo ha sido representada por un cuadro. El cuadro contiene toda la lógica del subflujo para minimizar la complejidad del gráfico. Sin embargo, si usted observa la parte superior del gráfico, hay una nueva opción "Expandir Subflujo". Haga clic en esto y aplique para ver:

subflow 17

Y en esta vista podemos ver el subflujo siendo expandido para que podamos observar el funcionamiento interno del flujo.

Eso es todo lo relacionado con nuestra configuración de DSL. Ahora pasemos a la parte de implementación.

Java Implementación

Definiendo el Adaptador

Cambiemos a Intellij para trabajar con el java lado.

Primero, reconstruya nuestro proyecto para que podamos generar nuestro nuevo flujo. Para hacer esto, abra una nueva terminal y ejecute:

mvn clean install

No hay nada especial acerca del subflujo en sí desde el punto de vista de generación, los cambios que debemos considerar son simplemente que hemos definido un nuevo Dominio Externo (Sanctions Domain) que ahora debemos implementar. Nuevamente, aquí elegirá utilizar la implementación de la aplicación de muestra como lo hicimos en DSL 4 - Uso de un dominio externo, así que intente agregar eso ahora y la solución está abajo cuando esté listo:

@Bean
public IpftutorialmodelDomain init(ActorSystem actorSystem, SchedulerPort schedulerAdapter) {
    // All adapters should be added to the domain model
    return new IpftutorialmodelDomain. Builder(actorSystem)
             .withTutorialDomainFunctionLibraryAdapter(input -> CompletableFuture.completedStage(new DuplicateCheckResponseInput. Builder(input.getId(), AcceptOrRejectCodes. Accepted).build()))
             .withAccountingSystemActionAdapter(new SampleAccountingSystemActionAdapter())
             .withFraudSystemActionAdapter(new FraudSystemActionAdapter())
             .withDecisionLibraryAdapter(input ->
                    input.getCustomerCreditTransfer().getCdtTrfTxInf().get(0).getIntrBkSttlmAmt().getValue().compareTo(BigDecimal. TEN)>0?
                            RunFraudCheckDecisionOutcomes. FRAUDREQUIRED: RunFraudCheckDecisionOutcomes. SKIPFRAUD)
             .withIpftutorialflowV1AggregateFunctionAdapter(input -> new ExtractCreditorAccountForFlowIpftutorialflowV1AggregateFunctionOutput(input.getCustomerCreditTransfer().getCdtTrfTxInf().get(0).getCdtrAcct()))
             .withIpftutorialflowV2AggregateFunctionAdapter(input -> new ExtractCreditorAccountForFlowIpftutorialflowV2AggregateFunctionOutput(input.getCustomerCreditTransfer().getCdtTrfTxInf().get(0).getCdtrAcct()))
             .withSchedulerAdapter(schedulerAdapter)
             .withCSMServiceActionAdapter(new SampleCSMServiceActionAdapter())
             .withSanctionsDomainActionAdapter(new SampleSanctionsDomainActionAdapter())
             .build();
}

Aquí hemos añadido a nuestra configuración la especificación del sistema de sanciones.

Verificando nuestra Solución

Como es habitual, ahora verifiquemos cómo funciona la solución. Inicie la aplicación como se indicó anteriormente (instructions están disponibles en Revisando la solicitud inicial si necesita un repaso!)

Para los pagos, simplemente utilizaremos uno estándar:

curl -X POST localhost:8080/submit | jq

Entonces, como es habitual, si ahora mencionamos el pago en el Developer GUI y muestre el gráfico de flujo (search by unit of work id, haga clic en ver, haga clic en ver gráfico) y deberíamos ver:

subflow 18

Y podemos ver que nuestro subflujo se ha expandido para ser parte del flujo principal en ejecución, el cual se ha completado con éxito. Si observamos el events en lugar de (haga clic domain events):

subflow 19

Debemos señalar que el event el nombre es la combinación de ambos el prefijo que proporcionamos en nuestro pseudo state junto con el nombre real del event en el subflujo. Esto es importante de entender, ya que es esta capacidad la que nos permite utilizar nuestro subflujo en múltiples lugares a lo largo de nuestro flujo. Puede intentar esto usted mismo si lo desea, añadiendo una segunda llamada al subflujo de sanciones en el flujo.

Conclusiones

En esta sección hemos aprendido cómo crear un subflujo e invocarlo desde dentro de nuestro flujo.

Habiendo considerado subflows y cómo utilizarlos, ahora dirijamos nuestra atención a otros flujos y cómo llamar a un flujo desde otro en:xref:calling_other1.adoc[DSL 10 - Llamando a otros flujos]