Esempi di trasformazione

Puoi trasformare i dati CloudEvents scrivendo espressioni di trasformazione utilizzando CEL. Per ulteriori informazioni, consulta Trasformare gli eventi ricevuti.

Di seguito sono riportati alcuni casi d'uso comuni ed esempi che mostrano come scrivere espressioni CEL per trasformare i dati sugli 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ù facile da parte di un servizio a valle.

Scenario:

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 i dati di output manualmente. 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 è ridotto. 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:

Utilizza una funzione nell'espressione. La funzione setField aggiunge o sostituisce un campo dell'evento con una determinata chiave. La funzione denormalize appiattisce le strutture complesse in un elenco di coppie chiave e 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 in un payload dell'evento prima che vengano inviati a un ambiente meno sicuro.

Scenario:

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, ad esempio 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 di espressione regolare extract è conforme alla 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:

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 oscura 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 all'altro.

Scenario:

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 converta 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 sugli eventi.

Scenario:

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 "valoreAlto" se orderValue è maggiore di 100; in caso contrario, "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 del valore predefinito

Devi assicurarti che determinati campi nel payload dell'evento abbiano valori predefiniti se non sono presenti.

Scenario:

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 di stringhe

Devi estrarre o modificare parti di un campo di stringa nei dati sugli eventi.

Scenario:

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 di espressione regolare extract è conforme alla sintassi RE2. Ad esempio:

message
  .setField("data.emailDomain",
re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))

Elenca operazioni e mappa

Devi lavorare con elenchi o mappe nei dati sugli eventi.

Scenario:

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 verifichi se "product456" esiste nell'elenco productIds e memorizzi 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 in modo corretto potenziali errori o dati imprevisti nel payload dell'evento.

Scenario:

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 per la trasformazione dei dati sugli eventi.

Trasformazione dei dati

Devi eseguire più trasformazioni sui dati sugli eventi nidificati.

Scenario:

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 nasconde 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 complesse 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 sugli eventi, aggiungere le informazioni sul prodotto e instradare il messaggio dell'evento.

Scenario:

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 formatta il nome del prodotto in lettere maiuscole, aggiunge un prefisso all'ID prodotto in base alla sua categoria e include una chiave di instradamento per l'elaborazione a valle. 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 rispettivi caratteri in maiuscolo. 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)