Puedes transformar los datos de eventos escribiendo expresiones de transformación con CEL. Por ejemplo, puede modificar las cargas útiles de eventos para cumplir el contrato de API específico de un destino.
Ten en cuenta que los eventos siempre se envían en formato CloudEvents mediante una solicitud HTTP en modo de contenido binario, a menos que especifiques un enlace de mensaje.
Definir los formatos de datos de entrada y salida
Además de escribir una expresión de transformación en CEL, también puede especificar el formato de los datos de eventos entrantes. De esta forma, Eventarc Advanced sabe cómo analizar la carga útil del evento. También puedes convertir los datos de un formato a otro.
Se admiten los siguientes formatos: Avro, JSON y Protobuf. Para obtener más información, consulta Formatear eventos recibidos.
Expresiones de transformación
Al transformar eventos, se puede acceder a todos los atributos de eventos en una expresión CEL como variables a través de un objeto message
predefinido. Estas variables se rellenan con valores basados en los datos de evento en el tiempo de ejecución. Por ejemplo:
message.id
devuelve el atributoid
del evento.message.data
devuelve una representación de valor de CEL de la carga útil del evento.message.data.some-key
devuelve el contenido de un campo llamadosome-key
de la carga útil del evento.
Los campos de message.data
siempre se representan como tipos String
y los valores se asignan del evento original mediante el esquema especificado al definir el formato de los datos de entrada.
La expresión de transformación debe expresar un evento completo que incluya los atributos de contexto del evento y la carga útil de datos del evento. Las expresiones se escriben en JSON, pero se admiten funciones, macros y operadores de CEL predefinidos, así como expresiones regulares que usan RE2. Eventarc Advanced también admite determinadas funciones de extensión que se pueden usar para transformar los datos de eventos.
A continuación, se muestran dos ejemplos de cómo usar expresiones CEL para transformar los datos de eventos. Para ver más casos prácticos y ejemplos, consulta Ejemplos de transformación.
Ejemplo: Formatear valores de atributo
En el siguiente ejemplo se da formato a los valores del atributo phone_number
mediante funciones de expresiones regulares. (Se han omitido otros atributos).
// Input: // { // "data": // { // "email_address": "charlie@altostrat.com", // "phone_number": "8005550100", // } // } // Output: // { // "data": // { // "email_domain": "altostrat.com", // "phone_number": "(800) 555-0100", // "area_code": "800", // "local_number": "5550100", // } // } { "data": { "email_domain": re.capture( message.data.email_address, "\\S+@(\\S+)"), "phone_number": re.extract( message.data.phone_number, "^(\\d{3})(\\d{3})(\\d{4})", "(\\1) \\2-\\3" ), }.merge ( re.captureN(message.data.phone_number, "^(?P\d{3})[\w\-)(]*(?P ) ) }\d{7})"
Estas son las funciones de expresión regular que se han usado en el ejemplo anterior:
re.capture
: captura el valor del primer grupo con nombre o sin nombre. Los argumentos son los siguientes:target
: cadena que se debe analizar.regex
: expresión regular usada para capturar valores.
Devuelve una cadena con el valor del primer grupo capturado.
re.captureN
: hace una coincidencia completa en la cadena y la expresión regular dadas. Los argumentos son los siguientes:target
: cadena que se debe analizarregex
: expresión regular usada para capturar valores
Devuelve un mapa con pares de clave y valor de un grupo con nombre (nombre del grupo, cadena capturada) o de un grupo sin nombre (índice del grupo, cadena capturada).
re.extract
: coincide con los valores de grupo de la cadena de destino proporcionada y reescribe la cadena. Los argumentos son los siguientes:target
: cadena que se debe analizarregex
: expresión regular que se usa para extraer valores.rewrite
: expresión regular para cómo se debe formatear el resultado
Devuelve una cadena de los valores extraídos que tiene un formato basado en el argumento
rewrite
.
Ejemplo: asignar una matriz a una matriz de objetos
En el siguiente ejemplo se asigna una matriz de números enteros a una matriz de objetos. (Se han omitido otros atributos).
// Input: // { // "data": // { // "product_ids": [1, 2, 3] // } // } // Output: // { // "data": // { // "products": [ // { // "name": "apple", // "price": 70 // }, // { // "name": "orange", // "price": 80 // }, // { // "name": "Product(3)", // "price": 0 // }, // { // "name": "apple", // "price": 70 // } // ] // } // } { "data": { "products": message.data.product_ids.map(product_id, product_id == 1? { "name": "apple", "price": 70 } : product_id == 2? { "name": "orange", "price": 80 } : // Default: { "name": "Product(" + string(product_id) + ")", "price": 0 } ) } }
Configurar una canalización para transformar eventos
Puedes configurar una canalización para transformar datos de eventos en la consola Google Cloud o con la CLI de gcloud.
Solo se admite una mediación por canalización.
Consola
En la Google Cloud consola, ve a la página Eventarc > Pipelines.
Puedes crear una canalización o, si vas a actualizar una, hacer clic en su nombre.
En la página Detalles de la canalización, haz clic en
Editar.En el panel Mediación de eventos, haga lo siguiente:
- Seleccione la casilla Aplicar una transformación.
En la lista Formato de entrada, seleccione el formato aplicable.
Para obtener más información, consulta Formatear eventos recibidos.
En el campo Expresión CEL, escribe una expresión de transformación en JSON. Se admiten funciones, macros y operadores CEL predefinidos, así como expresiones regulares. Por ejemplo:
{ "id": message.id, "datacontenttype": "application/json", "data": "{ \"scrubbed\": \"true\" }" }
En el ejemplo anterior se hace lo siguiente:
- Elimina todos los atributos del evento original, excepto su
id
. - Asigna el valor
application/json
al atributodatacontenttype
. - Sustituye la carga útil del evento por una cadena JSON estática.
- Elimina todos los atributos del evento original, excepto su
Haz clic en Continuar.
En el panel Destino, haga lo siguiente:
Si procede, en la lista Formato de salida, seleccione un formato.
Para obtener más información, consulta Formatear eventos recibidos.
También puedes aplicar un enlace de mensaje. Para obtener más información, consulta la sección Definir una vinculación de mensajes de este documento.
Haz clic en Guardar.
Una canalización puede tardar un par de minutos en actualizarse.
gcloud
Abre la terminal.
Puedes crear una canalización o actualizarla con el comando
gcloud eventarc pipelines update
:gcloud eventarc pipelines update PIPELINE_NAME \ --location=REGION \ --mediations=transformation_template= \ { TRANSFORMATION_EXPRESSION }
Haz los cambios siguientes:
PIPELINE_NAME
: el ID de la canalización o un nombre completoREGION
: una ubicación de Eventarc Advanced compatibleTambién puedes definir la propiedad de ubicación de gcloud CLI:
gcloud config set eventarc/location REGION
TRANSFORMATION_EXPRESSION
: una expresión escrita en JSON. Se admiten funciones, macros y operadores CEL predefinidos, así como expresiones regulares. Se usa una marcamediations
para aplicar una clavetransformation_template
.
Una canalización puede tardar un par de minutos en actualizarse.
Ejemplo:
gcloud eventarc pipelines update my-pipeline \ --location=us-central1 \ --mediations=transformation_template= \ { "id": message.id, "datacontenttype": "application/json", "data": "{ \"scrubbed\": \"true\" }" }
En el ejemplo anterior se hace lo siguiente:
- Elimina todos los atributos del evento original, excepto su
id
. - Asigna el valor
application/json
al atributodatacontenttype
. - Sustituye la carga útil del evento por una cadena JSON estática.
Funciones de extensión
Eventarc Advanced admite las siguientes funciones de extensión, que se pueden usar para transformar los datos de eventos recibidos a través de un bus.
Función | Descripción |
---|---|
denormalize |
Desnormaliza un mapa o una lista añadiendo datos redundantes para mejorar el rendimiento de lectura. Los nombres de los campos del mapa resultante se delimitan con un punto ( Ten en cuenta que, como no puedes usar un punto ( Por ejemplo: |
merge |
Une dos campos y devuelve el campo combinado. Los campos con nombres duplicados se combinan. Por ejemplo:
|
removeFields |
Elimina campos específicos de un evento. Los nombres de los campos se resuelven como rutas. El carácter de punto ( Ten en cuenta que se espera un JSON sin procesar. Si serializas el JSON, es posible que la transformación se aplique a una cadena JSON y se produzca un error. Por ejemplo: |
setField |
Añade o sustituye un campo del evento con una clave determinada. El campo
name se resuelve como una ruta. El carácter de punto ( Por ejemplo: |
Ejemplo: Añadir un atributo a la carga útil de un evento sin modificar otros datos
// Input: // { // "data": // { // "credit_card_number": "XXXX-XXXX-XXXX-XXXX" // } // } // Output: // { // "data": // { // "credit_card_number": "XXXX-XXXX-XXXX-XXXX", // "card_type": "credit" // } // } { "data": message.data.merge( { "card_type": "credit" } ) }
Ejemplo: Desnormalizar una lista de elementos de la carga útil de un evento
// Input: //{ //"data": // { // "products": [ // { // "number": 021774, // "type": "perishable", // "price": 2.00 // }, // { // "number": 95602, // "type": "diy", // "price": 120.00 // }, // { // "number": 568302, // "type": "toys", // "price": 12.00 // } // ] // } //} // // Output: //{ //"data": // { // "products": { // "0.number": 021774, // "0.type": "perishable", // "0.price": 2.00, // "1.number": 95602, // "1.type": "diy", // "1.price": 120.00, // "2.number": 568302, // "2.type": "toys", // "2.price": 12.00 // } // } //} // // message.setField("data.products", message.data.products.denormalize())
Ejemplo: quitar un campo de la carga útil de un evento
// Input: // { // "data": // { // "payment": { // "card_number": "XXXX-XXXX-XXXX-XXXX", // "card_type": "credit", // } // } // } // Output: // { // "data": // { // "payment": { // "card_type": "credit" // } // } // } message.removeFields(["data.payment.card_number"])
Definir una vinculación de mensajes
De forma predeterminada, los eventos siempre se envían a un destino en formato CloudEvents mediante una solicitud HTTP en modo de contenido binario. También puedes anular este comportamiento definiendo un enlace de mensajes y construyendo una nueva solicitud HTTP.
Las cabeceras HTTP que introduzcan otras políticas o controles (por ejemplo, tokens de OAuth u OIDC) se conservan y se combinan con las cabeceras resultantes de la expresión de enlace.
Puedes definir un enlace de mensajes al configurar una canalización en la consola deGoogle Cloud o mediante la CLI de gcloud.
Consola
En la Google Cloud consola, ve a la página Eventarc > Pipelines.
Puedes crear una canalización o, si vas a actualizar una, hacer clic en su nombre.
Ten en cuenta que actualizar una canalización puede tardar más de 10 minutos.
En la página Detalles de la canalización, haz clic en
Editar.En el panel Destino, aplica un enlace de mensaje, que es una expresión CEL escrita en JSON. De este modo, se crea una solicitud HTTP que se envía al destino de la canalización.
Para obtener más información, consulta las secciones Acceder a mensajes entrantes y Crear solicitudes HTTP de este documento.
Haz clic en Guardar.
gcloud
Abre la terminal.
Puedes crear una canalización o actualizarla con el comando
gcloud eventarc pipelines update
:gcloud eventarc pipelines update PIPELINE_NAME \ --location=REGION \ --destinations=http_endpoint_message_binding_template='MESSAGE_BINDING'
Haz los cambios siguientes:
PIPELINE_NAME
: el ID de la canalización o un nombre completoREGION
: una ubicación de Eventarc Advanced compatibleTambién puedes definir la propiedad de ubicación de gcloud CLI:
gcloud config set eventarc/location REGION
MESSAGE_BINDING
: una expresión CEL escrita en JSON que da como resultado una solicitud HTTP recién creada que se envía al destino de la canalización.Para obtener más información, consulta las secciones Acceder a mensajes entrantes y Crear solicitudes HTTP de este documento.
Ejemplo:
gcloud eventarc pipelines create my-pipeline \ --location=us-central1 \ --destinations=http_endpoint_uri='https://example-endpoint.com', \ http_endpoint_message_binding_template='{"headers":{"new-header-key": "new-header-value"}}'
Ten en cuenta que, si usas una clave
http_endpoint_message_binding_template
, también debes definir la clavehttp_endpoint_uri
.
Acceder a los mensajes entrantes
Puedes usar una expresión CEL para acceder a un mensaje de CloudEvents entrante de la siguiente manera:
- Usa el valor
message.data
para acceder al campodata
del mensaje entrante. - Use los valores de
message.key
(dondekey
es el nombre del atributo) para acceder a los atributos del mensaje entrante. Usa una variable
headers
para acceder a los encabezados que se hayan añadido a la solicitud HTTP por mediaciones anteriores en la cadena de procesamiento. Esta variable define un mapa de pares clave-valor que corresponden a los encabezados HTTP adicionales y no a los encabezados originales de la solicitud entrante inicial.Por ejemplo, la siguiente expresión CEL se puede usar para crear una solicitud HTTP que solo contenga encabezados. Para ello, se añade un encabezado adicional a los que se han añadido en mediaciones de la canalización anteriores:
{"headers": headers.merge({"new-header-key": "new-header-value"})}
Construir solicitudes HTTP
El resultado de la expresión CEL debe ser un mapa de pares clave-valor cuyos campos headers
y body
se usen para crear la solicitud HTTP de la siguiente manera.
En los campos headers
:
- Si existe un mapa
headers
como resultado de la expresión CEL, sus pares clave-valor se asignan directamente a los encabezados de la solicitud HTTP y sus valores se construyen mediante la codificación de cadena canónica del tipo de datos correspondiente. - Si no existe el campo
headers
, la solicitud HTTP resultante no contendrá ningún encabezado.
En los campos body
:
- Si existe un campo
body
como resultado de la expresión CEL, su valor se asigna directamente al cuerpo de la solicitud HTTP. - Si el valor del campo
body
es de tipobytes
ostring
, se usa tal cual como cuerpo de la solicitud HTTP. De lo contrario, se convierte en una cadena JSON. - Si el campo
body
no existe, el cuerpo de la solicitud HTTP resultante es el cuerpo del enlace de mensajes HTTP de CloudEvents final en modo de contenido binario.
Se ignoran los demás campos que resulten de la expresión CEL.
Funciones de extensión
Eventarc Advanced admite las siguientes funciones de extensión, que se pueden usar para transformar los datos de eventos al especificar un enlace de mensajes.
Función | Descripción |
---|---|
merge |
Combina un mapa de CEL transmitido con el mapa de CEL al que se aplica la función. Si la misma clave existe en ambos mapas o si el valor de la clave es de tipo
Ejemplo: |
toBase64 |
Convierte un valor de CEL en una cadena codificada en URL en base64. Ejemplo: |
toCloudEventJsonWithPayloadFormat |
Convierte un mensaje en un mapa de CEL que corresponde a una representación JSON de un mensaje de CloudEvents y aplica Ejemplo: |
toDestinationPayloadFormat |
Convierte Ejemplo: |
toJsonString |
Convierte un valor de CEL en una cadena JSON. Por ejemplo:
|
toMap |
Convierte una lista de mapas de CEL en un solo mapa de CEL. Ejemplo: |
Ejemplo: Conservar encabezados, añadir un encabezado nuevo y definir el cuerpo con el formato de destino
gcloud eventarc pipelines create my-pipeline \ --location=us-central1 \ --input-payload-format-json='{}' \ --destinations=http_endpoint_uri='https://example-endpoint.com',http_endpoint_message_binding_template='{"headers": headers.merge({"content-type":"application/avro"}), "body": message.data.toDestinationPayloadFormat()"}',output_payload_format_avro_schema_definition='{"schema_definition": "{"type":"record","name":"myrecord","fields":[{"name":"name","type":"string"},{"name":"account_late","type":"boolean"}]}"}'