Definiendo el Mapping Relaciones

Esta sección cubre la forma de definir un mapping de origen a destino. Estos se definen en HOCON archivos de configuración. (.conf).

==.conf vs.mconf

Estas definiciones también pueden definirse como archivos del formato .mconf.

La estructura del archivo mconf tiene soporte de idioma incorporado a través del IPF Idea Plugin, que proporciona restricciones específicas del dominio y características más allá del soporte proporcionado por terceros Hocon plugins, elegimos un específico extension para no superponerse con lo existente HOCON soporte de idioma.

Las características incluyen:

  • Autocompletado y validación de rutas de campo

  • Validación de clave condicional

  • Verificación de claves duplicadas

Y mucho más.

La estructura de archivos y la sintaxis son actualmente exactamente las mismas entre los dos formatos, aparte de un detalle.

La sintaxis de acceso a arreglos en rutas de campo en hocon es de la forma a.b. 0.c mientras que la sintaxis equivalente en mconf sería a.b[0].c

The code generation la herramienta espera uno o más HOCON archivos de configuración que deben estar presentes en una carpeta definida por el usuario. Aparte de el .conf or .mconf extension, no hay requisitos sobre la nomenclatura. Cada archivo, sin embargo, configurará un mapping or un enriquecimiento.

Detrás de escena, los archivos mconf se traducen a archivos conf antes de ser procesados por el code generation herramienta.

Mapping a Objetos de Destino Mutables

El abajo mapping y las configuraciones de enriquecimiento se aplican a mapping objetos de destino mutables

Mapping Configuración

Cada par de clases que se va a mapear será definido por un archivo de configuración que contiene el mappings clave. Bidirectional mapping también puede ser respaldado añadiendo bidirectional-mapping: true propiedad a mapping conf file.

A básico mapping la configuración se verá así:

AtoB-mapping.conf
source-class:      com.ipf.example.model. TestA  # class to read
destination-class: com.ipf.example.model. TestB  # class to produce
target-package:    com.ipf.example.mapping      # package to generate
target-class-name: TestAToTestBCustomiser       # name of the mapper class to generate
mappings: [
  { source: foo, destination: bar }             # just map this pair
  # { source: moreFoo, destination: moreBar }   #..any other pairs would go here
]

A veces queremos mapear una clase a una versión más nueva de la misma, donde la gran mayoría de los atributos coinciden. Tal vez un arreglo de elementos, del cual solo estamos interesados en el primero, se ha convertido en un escalar, o viceversa. Con mayor frecuencia, un atributo habrá sido eliminado.

En estos casos, podemos ser concisos y utilizar implicit mapping s (implicit-mapping: true), y solo especifique las excepciones, por ejemplo, para excluir un atributo eliminado:

Cto Cv2-mapping.conf
source-class:      com.ipf.example.model.v1. TestC
destination-class: com.ipf.example.model.v2. TestCv2
target-package:    com.ipf.example.mapping
target-class-name: TestCToTestCv2Customiser
implicit-mapping:  true                               # match attributes by name
bidirectional-mapping: true
mappings: [
  { source: foo2, excluded: true }                         # exclude an attribute from mapping
  { source: apples. 0, destination: apple }                 # map first apple in array of apples
  { source: bananas. 0, destination: banana }               # map first banana in array of bananas
  { source: farmer, destination: farmers. 0 }               # it also works the other way around
]

Como se mencionó anteriormente, esta configuración generará TestC → Test Cv2 y Test Cv2 → TestC.mappers porque bidirectional mapping está habilitado. El objeto de manzana en el Test Cv2 se mapearía a un arreglo de un solo elemento con el objeto de manzana mapeado.

Configuración de Enriquecimiento

A menudo, el mensaje que se enviará al sistema objetivo necesita ser enriquecido con valores fijos provenientes de la configuración, del reloj del sistema o simplemente valores codificados.

El marco de trabajo admite esto al leer la configuración de enriquecimiento desde un archivo como el que se muestra a continuación:

TestA-enrichment.conf
enrichment-target: com.ipf.example.model. TestA  # what class to enrich
target-package: com.ipf.example.mapping
enrichments: [
   {destination: version, enrichment-type: value, value: 100L}
   {destination: id, enrichment-type: randomAlphaNumeric}
   {destination: special, enrichment-type: config-value, path: "get.me"}
   {destination: date, enrichment-type: from-instant, format: "dd/MM/yyyy"}
]

El enriquecimiento está respaldado por un contexto de enriquecimiento, proporcionado por el marco, que admite cuatro tipos de fuentes de enriquecimiento:

tipo descripción ejemplo

value

valor constante, en el value propiedad

value: "some literal value"

randomAlphaNumeric

genere un token alfanumérico aleatorio (32 caracteres)

(no specification required)

config-value

leer un valor de un HOCON fuente de configuración

path: "my.config.path"

from-instant

utilice el actual Instant--format

format: "dd/MM/yyyy"

current-instant

utilice la fecha/hora actual devuelta como un Instant

(no specification required)

enrichment-function

Rellene un campo con un valor pasado a mapAndEnrich. Debe ser configurado según la columna "ejemplo"

{destination: [your destination], enrichment-type: enrichment-function, function: "getSource()"}

Luego llame al método de la siguiente manera:

transformationService.mapAndEnrich(source, Destination.class, myValue);

current-local-date

utilice la fecha actual devuelta como un LocalDate

(no specification required)

current-offset-datetime

utilice la fecha/hora actual devuelta como un OffsetDateTime

(no specification required)

current-local-datetime

utilice la fecha/hora actual devuelta como un LocalDateTime

(no specification required)

current-zoned-datetime

utilice la fecha/hora actual devuelta como un ZonedDateTime

(no specification required)

current-iso-datetime

utilice la fecha/hora actual devuelta como un Icon IsoDateTime (para IPF API usage)

(no specification required)

Configuración de Enriquecimiento con Condiciones por Enriquecimiento Individual

Puede incluir un nuevo atributo opcional llamado "enrichment-field-conditions" en cada enriquecimiento. Este atributo proporciona la capacidad de controlar si se aplica un enriquecimiento basado en una expresión de condición específica.

El ejemplo a continuación demuestra dos enriquecimientos separados basados en condiciones específicas. Estos enriquecimientos tienen los siguientes efectos:

  1. Enriqueciendo target.myIntegerProperty a 500 cuando source.myIntegerProperty == 100

  2. Enriqueciendo target.myStringProperty a 'updatedText' cuando source.myStringProperty == 'matchingText'

enrichment-target: com.ipf.payments.common.execution.enrichment.orika.testmodel. TestEnrichmentObject
// target-package is no longer used and does not need to be specified when using `orika-transformation-service-impl`
target-package: com.ipf.payments.common.execution.enrichment.orika.testmodel
enrichments: [
  {
    destination: "myIntegerProperty",
    enrichment-type: value,
    value: 500,
    enrichment-field-conditions:[
      "myIntegerProperty == 100",
    ]
  },
  {
    destination: "myStringProperty",
    enrichment-type: value,
    value: "updatedText",
    enrichment-field-conditions:[
      "myStringProperty == 'matchingText'"
    ]
  }
]