DSL 6 - Mapping Funciones

Iniciando

El paso del tutorial utiliza el add_decision solución del proyecto como su punto de partida.

Si en algún momento desea ver la solución a este paso, puede encontrarla en el add_mapping_function¡solución!

¿Qué es un Mapping¿Función?

A mapping la función es simplemente una función que realiza una traducción de muchos a muchos de business data elementos. Hay tres lugares dentro del DSL donde es posible utilizar mapping funciones. Estas se describen a continuación:

Enriqueciendo el agregado -'Aggregate Functions'

Un agregado es el almacén de datos en vivo para un pago particular, es una especie de resumen de todos los events recibido hasta la fecha en un solo lugar para que pueda ser utilizado rápidamente y transmitido donde sea necesario. Sin embargo, ¿qué sucede si desea realizar una acción contra ese agregado, por ejemplo, transformar algunos datos, rastrear actualizaciones o realizar un cálculo? Nos referimos a este tipo de mapping como un 'Aggregate Function', es la capacidad que tenemos para ejecutar una función contra los datos agregados cuando un nuevo event viene.

An 'aggregate function por lo tanto, es relativamente simple de definir:

  • An aggregate function ocurre al recibir un dado event

  • An aggregate function tiene acceso a la events datos y cualquier dato previamente en el agregado

  • An aggregate function define qué datos proporciona a cambio-esto podría ser una actualización de datos anteriores o la generación de nuevos datos.

Datos generados por un aggregate function no se persiste en el diario maestro, pero se volverá a ejecutar durante la recuperación del nodo. Por lo tanto, se debe tener cuidado al calcular valores dinámicos como las fechas.

Enriqueciendo el event -'Enriquecimiento de Entrada'

El segundo uso de mapping Las funciones son cuando queremos enriquecer un event con los datos que recibimos de la entrada junto con los datos actualmente mantenidos en el agregado. Llamamos a este tipo de mapping un 'enriquecimiento de entrada'.

Un 'enriquecimiento de entrada' puede definirse de manera similar como:

  • Se produce un enriquecimiento de entrada antes de un event está guardado.

  • Una función de enriquecimiento de entrada tiene acceso a la events datos y cualquier dato previamente en el agregado

  • Una función de enriquecimiento de entrada define qué datos proporciona a cambio.- esto podría ser una actualización de datos anteriores o la generación de nuevos datos.

  • Los puntos de datos actualizados se añaden a la event.

Los datos generados por un enriquecimiento de entrada se persisten en el event y, por lo tanto, es de larga duración y se enviará aguas abajo a través de processing data características.

Suministrando datos para una llamada de acción

El uso final de un mapping la función está en una llamada de acción. Si al llamar a una acción necesita un punto de datos que no se proporciona en otro lugar del flujo, entonces es posible crear esos datos utilizando el mapping. Nos referiremos a esto como un " Action Mapping.

An 'action mapping' puede, por lo tanto, definirse simplemente como:

  • An action mapping se ejecuta cuando el dominio llama a una acción.

  • Una función de acción tiene acceso a todos los datos agregados.

  • Una función de acción define qué datos proporciona a cambio.

  • La función de acción generada no retiene los datos, por lo que es solo un punto en el tiempo.

Mapping Tabla de Tipos de Función

Tipo Llamado cuando.. Datos Disponibles Efecto Secundario Persistido Caso de uso

Aggregate Function

Event recibido

event, agregar

Nuevos datos o actualizar existentes

No

realice cálculos sobre datos de conteo transitorios

Enriquecimiento de Entrada

Antes de guardar event

event, agregar

Nuevos datos o actualizar existentes

realice cálculos que deben ser persistidos en el diario

Action Mapping

Acción llamada

agregar

none

No

generación de datos donde esos datos no son relevantes en otra parte del flujo

Usando un mapping función

Vamos a utilizar un aggregate function como un método para ser más precisos en lo que enviamos a nuestro sistema contable cuando realizamos nuestra Validate Account solicitud. En ese caso, enviamos el pacs008 completo al sistema contable, ahora queremos enviar solo la parte del pacs008 que contiene la información de la cuenta. Así que utilicemos un aggregate function como una forma de dividir el pacs. 008 y simplemente poniendo la información relevante a disposición.

Configuración de DSL

Configuración de un nuevo Business Data Punto

Hasta ahora no hemos considerado realmente business data, solo utilizando el suministrado customer credit transfer. Ahora que queremos utilizar un tipo de dato diferente, necesitaremos definirlo para hacerlo disponible en nuestro flujo. Aquí es donde business data viene.

Comencemos creando un nuevo business data biblioteca haciendo clic derecho en nuestro ipftutorialmodel y seleccionando (Nuevo > v2Flo >Business Data Biblioteca).

Se le presentará con el business data pantalla de la biblioteca donde estableceremos:

  • Una descripción de "Una muestra data library "

  • A business data elemento (haciendo clic en "Agregar" Business Data ") que contiene:

    • Un nombre de "Cuenta del Acreedor"

    • Una descripción de "los detalles del acreedor"

    • Para el data type seleccionaremos "Cash Account38" (nota-hay tipos para cada ISO message type, necesitará la versión pacs008)

Una vez completado, deberíamos ver:

mapping function 1
Consejo Principal

Cualquier java el objeto puede ser utilizado como un business data tipo. Estos java los tipos pueden ser importados al proyecto (cubriremos esto en Using custom business data. Si el tipo está en el alcance pero no aparece en la búsqueda anticipada, intente presionar Ctrl+R, ya que esto buscará entre los objetos que no están actualmente importados y que el modelo también puede ver.

Actualizando la Solicitud

Ahora que tenemos nuestro data type, el primer trabajo es simplemente reemplazar el " Business Data "en la llamada a la "Solicitud de Validación de Cuenta" para que en lugar de tomar el " Customer Credit Transfer " como entrada business data Ahora tomamos la "Cuenta del Acreedor". Una vez hecho esto, la nueva definición de solicitud debería verse así:

mapping function 2

Eso es todo el soporte configurado, ahora es el momento de crear nuestro aggregate function. Si recordamos, la función debía extraer los detalles del acreedor de la customer credit transfer. En nuestro caso, el customer credit transfer los detalles llegan en la "Iniciación del Flujo" event, así que utilicemos eso para configurar nuestro aggregate function.

Creando un Mapping Función para Actualizar Nuestros Datos Agregados

Comenzamos haciendo clic en el botón "Agregar Función" en nuestro flujo y luego ingresando los siguientes parámetros:

  • Un nombre de "Extraer Cuenta de Acreedor"

  • Una descripción para "Extrae la cuenta del acreedor del pacs008"

  • los datos de entrada como " Customer Credit Transfer "

  • los datos de salida como "Cuenta del Acreedor"

Así que aquí simplemente estamos proporcionando una función sencilla que puede extraer los detalles del acreedor de la customer credit transfer para que pueda ser utilizado más adelante en el flujo. Nuestra nueva función debería verse así:

mapping function 3

A continuación, necesitamos definir dónde queremos que se ejecute nuestra función. En nuestro caso, deseamos que esto se ejecute al inicio del flujo cuando recibamos el inicial.customer credit transfer. Para hacer esto, simplemente actualizamos el initiation behaviour con el aggregate function hemos definido:

mapping function 4

Eso es todo el trabajo de flujo que hemos realizado, el flujo ahora extraerá los detalles de la cuenta del acreedor del pacs008 y utilizará eso para enviarlo al sistema contable.

Ahora examinemos el lado de la implementación de este requisito.

Java Implementación

Ahora volvamos a Intellij y veamos cómo integrar esto en nuestro código de implementación. Como es habitual, comenzaremos ejecutando una compilación desde una ventana de terminal:

mvn clean install

Una vez construido, podemos nuevamente observar el código generado en /domain-root/domain/target, y ahora deberíamos encontrar el puerto para llamar a nuestra función de la siguiente manera (/domain-root/domain/target/classes/com/iconsolutions/ipf/tutorial/ipftutorialmodel/mapping):

public interface IpftutorialflowMappingPort {

  ExtractCreditorAccountForFlowIpftutorialflowMappingOutput performExtractCreditorAccount(ExtractCreditorAccountForFlowIpftutorialflowMappingParameters parameters);

}

Aquí podemos ver la definición de nuestra función puerto, es bastante directa. Ahora necesitamos una implementación de adaptador para ello. Hacemos esto de manera habitual añadiéndolo a la declaración de dominio en la configuración del Tutorial IPF. Intente hacerlo ahora y una implementación se encuentra a continuación:

@Bean
public IpftutorialmodelDomain init(ActorSystem actorSystem) {
       // 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 SampleFraudSystemActionAdapter())
                .withDecisionLibraryAdapter(input ->
                        input.getCustomerCreditTransfer().getCdtTrfTxInf().get(0).getIntrBkSttlmAmt().getValue().compareTo(BigDecimal. TEN)>0?
                                RunFraudCheckDecisionOutcomes. FRAUDREQUIRED: RunFraudCheckDecisionOutcomes. SKIPFRAUD)
                .withIpftutorialflowMappingAdapter(input -> new ExtractCreditorAccountForFlowIpftutorialflowMappingOutput(input.getCustomerCreditTransfer().getCdtTrfTxInf().get(0).getCdtrAcct()))
                .build();
}

Verificando nuestra Solución

Aquí podemos ver que hemos añadido nuestro aggregate function a nuestra configuración y todo está ahora completo y listo para probar, así que como es habitual, ahora verifiquemos que la solución funciona. Inicie la aplicación como se indicó anteriormente (instructions están disponibles en Revisando la solicitud inicial si necesita un repaso!)

Entonces podemos enviar un pago:

curl -X POST localhost:8080/submit -H 'Content-Type: application/json' -d '{"value": "5"}' | jq

Nota - La elección del valor de pago es bastante arbitraria aquí, ya que solo estamos interesados en ver el cambio en los datos contables. Para verificar que nuestro cambio está funcionando, necesitaremos observar el agregado en sí. Así que esta vez consultaremos el agregado completo:

Hablemos del pago en el Developer GUI y presente la vista agregada (buscar por unit of work id → haga clic en "ver" → "haga clic para ver los datos agregados") y luego, hacia el final de los detalles agregados, deberíamos ver los nuevos detalles de la cuenta del acreedor:

mapping function 5

Así que ahí lo tenemos, hemos extraído con éxito los detalles del acreedor de nuestro agregado y ahora podemos utilizarlos en otra parte del flujo.

Alternativas

Como se mencionó anteriormente, hay múltiples formas de utilizar mapping funciones. Podemos intentar esto aquí para proporcionar diferentes formas de obtener los datos necesarios para la llamada contable.

Mapping en el momento de la llamada

El primer enfoque es establecer el mapping función en el punto en que se llama a la función. Para hacer esto, hacemos clic derecho en la llamada de validación de la cuenta:

mapping function 6

y seleccione " Inspector " desde el menú desplegable (o presione Ctrl+Alt+I) y esto muestra las opciones para la llamada. Aquí podríamos entonces simplemente aplicar nuestro mapping función:

mapping function 7

No necesitaríamos entonces nuestro mapping función en el initiation behaviour pero desde el punto de vista de la implementación, nada cambiaría.

La única diferencia importante aquí es que si usted mirara el agregado (por ejemplo, cargando la transacción en la aplicación de desarrollo y haciendo clic en el botón de ver agregado), entonces los datos no se mostrarían aquí.

Mapping como un enriquecimiento de iniciación

La siguiente opción es cambiarlo de un aggregate function a un enriquecimiento de entrada. Podemos hacer esto simplemente trasladando la función del comportamiento de entrada a un enriquecimiento de entrada.

mapping function 8

Nuevamente, aquí no se necesitarían cambios en la implementación. Podríamos ver la diferencia aquí al observar el 'FLow Initiated'.domain event en la aplicación para desarrolladores, ahora la cuenta del acreedor se persistirá como un elemento de datos aquí.

Mapping como un aggregate function en otros pasos

También podemos ejecutar aggregate functions en pasos distintos a la enriquecimiento. Para ello, añadimos un aggregate function aquí:

mapping function 9

Cuando hacemos clic en 'Agregar Aggregate Function' botón podemos suministrar el event y mapping función que queremos aplicar después de eso event siendo recibido. Esto funcionará de la misma manera que el de iniciación, excepto por el event se invoca después. Nuevamente, no se requieren cambios en la implementación, pero recuerde que estos datos tampoco se persistirán y se recrearán en la reactivación del flujo.

Mapping como enriquecimiento de entrada en otros pasos

El enfoque final es agregarlo como parte de la recepción de una entrada, al igual que lo anterior con el enriquecimiento de la entrada en el initiation behaviour. Para hacer esto, simplemente seleccionamos el mapping función que queremos aplicar como parte del bloque de enriquecedores de entrada:

mapping function 10

Conclusiones

En esta sección hemos:

  • aprendió a usar aggregate functions para convertir data type s.

Now having configured our application to use an aggregate function, let’s look another capability in: DSL 7 - Handling Timeouts