Puoi trasformare i tuoi dati CloudEvents scrivendo espressioni di trasformazione utilizzando CEL. Per saperne di più, consulta la sezione Trasformare gli eventi ricevuti.
Di seguito sono riportati alcuni casi d'uso ed esempi comuni che mostrano come scrivere espressioni CEL per trasformare i dati degli eventi.
Casi d'uso standard
Di seguito sono riportati alcuni casi d'uso standard per la trasformazione dei dati sugli eventi.
Normalizzazione dei dati
Devi appiattire una struttura di dati nidificata nel messaggio evento per consentire un'elaborazione più semplice da parte di un servizio downstream.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View" } } } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "orderId": "12345", "customerFirstName": "Alex", "customerLastName": "Taylor", "customerStreet": "1800 Amphibious Blvd.", "customerCity": "Mountain View" } }
- Soluzione 1:
Formatta manualmente i dati di output. In questo modo puoi elencare i nomi dei campi e scegliere solo gli elementi necessari nell'output. Si tratta di un approccio ragionevole quando l'input è prevedibile e il numero di campi è basso. La funzione
setField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. Ad esempio:message.setField("data", { "orderId": message.data.orderId, "customerFirstName": message.data.customer.firstName, "customerLastName": message.data.customer.lastName, "customerStreet": message.data.customer.address.street, "customerCity": message.data.customer.address.city, })
- Soluzione 2:
Utilizzare una funzione nell'espressione. La funzione
setField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. La funzionedenormalize
appiattisce le strutture profonde in un elenco di coppie chiave-valore. I nomi dei campi sono delimitati da un punto (.
) per segmentare la gerarchia della struttura. Ad esempio:message.setField("data", message.data.denormalize())
Il risultato è il seguente output, che differisce leggermente dal payload previsto. Tuttavia, i vantaggi includono un'espressione CEL più breve che opera su qualsiasi input e che include automaticamente un numero qualsiasi di campi in entrata.
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.address.street": "1800 Amphibious Blvd.", "customer.address.city": "Mountain View" } }
Mascheramento dei dati
Devi mascherare i dati sensibili nel payload di un evento prima che venga inviato a un ambiente meno sicuro.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "userId": "user123", "email": "alex@example.com", "creditCardNumber": "1234-5678-9012-3456" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "userId": "user123", "email": "a***@example.com", "creditCardNumber": "xxxx-xxxx-xxxx-3456" } }
- Soluzione:
Utilizza un'espressione per mascherare le informazioni sensibili, come l'indirizzo email e il numero di carta di credito. La funzione
setField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. La funzioneextract
di espressioni regolari segue la sintassi RE2. Ad esempio:message .setField("data.email", re.extract(message.data.email, "(^.).*@(.*)", "\\1***@\\2")) .setField("data.creditCardNumber", re.extract(message.data.creditCardNumber, "(\\d{4})\\D*$", "xxxx-xxxx-xxxx-\\1"))
Oscuramento dei dati
Devi rimuovere campi specifici dal payload di un evento in base a determinate condizioni.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "orderId": "12345", "customerType": "gold", "discountCode": "VIP" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ { "orderId": "12345", "customerType": "gold" } }
- Soluzione:
Utilizza un'espressione che oscuri il campo
discountCode
secustomerType
è "gold". La funzioneremoveFields
rimuove campi specifici da un evento. Ad esempio:message.data.customerType == "gold" ? message.removeFields(["data.discountCode"]) : message
Conversione dei dati
Devi convertire i dati da un formato o tipo a un altro.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "orderDate": "2024-10-31T12:00:00Z", "totalAmount": "1500" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "orderDate": 1704086400, "totalAmount": 1500.00 } }
- Soluzione:
Utilizza un'espressione che converte
orderDate
in un timestamp UNIX e il tipototalAmount
dastring
adouble
(numero in virgola mobile). La funzionesetField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. Puoi utilizzare le funzioni di manipolazione delle stringhe per convertire i risultati delle stringhe. Ad esempio:message .setField("data.orderDate", int(timestamp(message.data.orderDate))) .setField("data.totalAmount", double(message.data.totalAmount))
Routing condizionale
Devi indirizzare gli eventi a destinazioni diverse in base ai dati degli eventi.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "eventType": "order.created", "orderValue": 200 } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "eventType": "order.created", "orderValue": 200, "routingKey": "highValue" } }
- Soluzione:
Utilizza un'espressione che aggiunge un campo
routingKey
con un valore "highValue" se ilorderValue
è maggiore di 100; altrimenti,"normal"
. Il camporoutingKey
può essere utilizzato per determinare il percorso di routing. La funzionesetField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. Ad esempio:message.data.orderValue > 100 ? message.setField("data.routingKey", "highValue") : message.setField("data.routingKey", "normal")
Gestione dei valori predefiniti
Devi assicurarti che determinati campi nel payload dell'evento abbiano valori predefiniti se non sono presenti.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "itemName": "Product A" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "itemName": "Product A", "quantity": 1 } }
- Soluzione:
Utilizza un'espressione che aggiunge un campo
quantity
con un valore predefinito di1
se il campo non esiste già. La macrohas
verifica se un campo è disponibile. La funzionesetField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. Ad esempio:has(message.data.quantity) ? message : message.setField("data.quantity", 1)
Manipolazione delle stringhe
Devi estrarre o modificare parti di un campo stringa nei dati evento.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "customerEmail": "alex@example.com" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "customerEmail": "alex@example.com", "emailDomain": "example.com" } }
- Soluzione:
Utilizza un'espressione che estrae il nome di dominio ("example.com") dal campo
customerEmail
e lo memorizza in un nuovo campoemailDomain
. La funzionesetField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. La funzioneextract
di espressioni regolari segue la sintassi RE2. Ad esempio:message .setField("data.emailDomain", re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))
Operazioni su elenchi e mappe
Devi lavorare con elenchi o mappe nei dati evento.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "productIds": [ "product123", "product456" ] } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "productIds": [ "product123", "product456" ], "productFound": true } }
- Soluzione:
Utilizza un'espressione che controlla se "product456" esiste nell'elenco
productIds
e memorizza il risultato (true
ofalse
) in un nuovo campoproductFound
. La funzionesetField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. La macroexists
verifica se un predicato è valido per tutti gli elementi di un elenco e combina i risultati con l'operatore "or". Ad esempio:message.setField("data.productFound", message.data.productIds.exists(id, id == "product123"))
Gestione degli errori
Devi gestire correttamente potenziali errori o dati imprevisti nel payload dell'evento.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "quantity": "abc" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "quantity": 0, "error": "Invalid quantity" } }
- Soluzione:
Utilizza un'espressione che tenta di convertire il campo
quantity
in un numero intero. Se la conversione non va a buon fine, imposta il campoquantity
su0
e aggiungi un nuovo campoerror
con il valore "Quantità non valida".- La macro
has
verifica se un campo è disponibile. - La funzione
type
restituisce il tipo di un valore. - La funzione di espressione regolare
matches
segue la sintassi RE2. - La funzione
setField
aggiunge o sostituisce un campo dell'evento con una determinata chiave.
Ad esempio:
// Check if data.quantity exists has(message.data.quantity) && // Check if data.quantity is a string type(message.data.quantity) == string && // Check if string consists of digits message.data.quantity.matches(r'^-?[0-9]+$') ? // If data.quantity is valid, use message message : // If data.quantity is invalid, set to 0 and generate error message .setField("data.quantity", 0) .setField("data.error", "Invalid quantity")
- La macro
Casi d'uso complessi
Di seguito sono riportati alcuni casi d'uso complessi durante la trasformazione dei dati sugli eventi.
Trasformazione dei dati
Devi eseguire più trasformazioni sui dati degli eventi nidificati.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "email": "alex@example.com", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View", "state": "CA" } }, "items": [ { "itemId": "item1", "price": 10.00, "quantity": 2 }, { "itemId": "item2", "price": 5.00, "quantity": 1 } ] } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.email": "a***@example.com", "customer.address.city": "Mountain View", "customer.address.state": "CA" } }
- Soluzione:
Utilizza un'espressione che estrae la città e lo stato dall'indirizzo e che maschera l'indirizzo email.
- La funzione
setField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. - La funzione
toMap
converte un elenco CEL di mappe CEL in una singola mappa CEL. - La funzione di espressione regolare
extract
segue la sintassi RE2. - La funzione
removeFields
rimuove campi specifici da un evento. - La funzione
denormalize
appiattisce le strutture profonde in un elenco di coppie chiave-valore. I nomi dei campi sono delimitati da un punto (.
) per segmentare la gerarchia della struttura.
Ad esempio:
message .setField("data", message.data.setField("customer.address", message.data.customer.address.map(key, key == "city" || key == "state", { key: message.data.customer.address[key] }).toMap()) .setField("customer.email", re.extract(message.data.customer.email, "(^..?).*@(.*)", "\\1***@\\2")) .removeFields(["items"]) .denormalize() )
- La funzione
Formattazione e routing dei dati
Devi formattare i dati degli eventi, aggiungere le informazioni sul prodotto e poi indirizzare il messaggio dell'evento.
- Scenario:
Considerando i seguenti dati CloudEvents:
{ "data": { "productId": "p123", "productName": "Example Product", "category": "electronics" } }
Vuoi scrivere un'espressione CEL che generi il seguente output:
{ "data": { "productId": "electronics-p123", "productName": "EXAMPLE PRODUCT", "category": "electronics", "routingKey": "electronics" } }
- Soluzione:
Utilizza un'espressione che formatti il nome del prodotto in maiuscolo, aggiunga un prefisso all'ID prodotto in base alla categoria e includa una chiave di routing per l'elaborazione downstream. La funzione
setField
aggiunge o sostituisce un campo dell'evento con una determinata chiave. La funzioneupperAscii
restituisce una stringa con tutti i caratteri ASCII convertiti nei corrispondenti caratteri maiuscoli. Ad esempio:message .setField("data.productId", message.data.category + "-" + message.data.productId) .setField("data.productName", message.data.productName.upperAscii()) .setField("data.routingKey", message.data.category)