Esempi di trasformazione

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 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.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 funzione extract 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 se customerType è "gold". La funzione removeFields 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 tipo totalAmount da string a double (numero in virgola mobile). La funzione setField 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 il orderValue è maggiore di 100; altrimenti, "normal". Il campo routingKey può essere utilizzato per determinare il percorso di routing. La funzione setField 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 di 1 se il campo non esiste già. La macro has verifica se un campo è disponibile. La funzione setField 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 campo emailDomain. La funzione setField aggiunge o sostituisce un campo dell'evento con una determinata chiave. La funzione extract 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 o false) in un nuovo campo productFound. La funzione setField aggiunge o sostituisce un campo dell'evento con una determinata chiave. La macro exists 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 campo quantity su 0 e aggiungi un nuovo campo error 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")

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()
)

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 funzione upperAscii 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)