Transformationsbeispiele

Sie können Ihre CloudEvents-Daten transformieren, indem Sie Transformationsausdrücke mit CEL schreiben. Weitere Informationen finden Sie unter Empfangene Ereignisse transformieren.

Im Folgenden finden Sie einige gängige Anwendungsfälle und Beispiele, die zeigen, wie Sie CEL-Ausdrücke schreiben, um Ihre Ereignisdaten zu transformieren.

Standardanwendungsfälle

Im Folgenden finden Sie einige Standardanwendungsfälle für die Transformation von Ereignisdaten.

Datennormalisierung

Sie müssen eine verschachtelte Datenstruktur in Ihrer Ereignisnachricht vereinfachen, damit sie von einem Downstream-Dienst leichter verarbeitet werden kann.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "orderId": "12345",
    "customer": {
      "firstName": "Alex",
      "lastName": "Taylor",
      "address": {
        "street": "1800 Amphibious Blvd.",
        "city": "Mountain View"
      }
    }
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "orderId": "12345",
    "customerFirstName": "Alex",
    "customerLastName": "Taylor",
    "customerStreet": "1800 Amphibious Blvd.",
    "customerCity": "Mountain View"
  }
}
Lösung 1:

Ausgabedaten manuell formatieren So können Sie die Feldnamen auflisten und nur die Elemente auswählen, die in der Ausgabe benötigt werden. Das ist ein sinnvoller Ansatz, wenn die Eingabe vorhersehbar ist und die Anzahl der Felder gering ist. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Beispiel:

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,
})
Lösung 2:

Verwenden Sie eine Funktion in Ihrem Ausdruck. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Mit der Funktion denormalize werden verschachtelte Strukturen in eine Liste von Schlüssel/Wert-Paaren umgewandelt. Feldnamen werden durch einen Punkt (.) getrennt, um die Strukturhierarchie zu segmentieren. Beispiel:

message.setField("data", message.data.denormalize())

Das führt zu der folgenden Ausgabe, die sich geringfügig von der erwarteten Nutzlast unterscheidet. Zu den Vorteilen gehören jedoch ein kürzerer CEL-Ausdruck, der für jede Eingabe funktioniert und automatisch eine beliebige Anzahl von eingehenden Feldern enthält.

{
  "data": {
    "orderId": "12345",
    "customer.firstName": "Alex",
    "customer.lastName": "Taylor",
    "customer.address.street": "1800 Amphibious Blvd.",
    "customer.address.city": "Mountain View"
  }
}

Datenmaskierung

Sie müssen sensible Daten in einer Ereignisnutzlast maskieren, bevor sie an eine weniger sichere Umgebung gesendet werden.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "userId": "user123",
    "email": "alex@example.com",
    "creditCardNumber": "1234-5678-9012-3456"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "userId": "user123",
    "email": "a***@example.com",
    "creditCardNumber": "xxxx-xxxx-xxxx-3456"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, um vertrauliche Informationen wie die E-Mail-Adresse und die Kreditkartennummer zu maskieren. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Die Funktion für reguläre Ausdrücke extract folgt der RE2-Syntax. Beispiel:

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

Datenentfernung

Sie müssen bestimmte Felder aus einer Ereignisnutzlast entfernen, die auf bestimmten Bedingungen basieren.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "orderId": "12345",
    "customerType": "gold",
    "discountCode": "VIP"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  {
  "orderId": "12345",
  "customerType": "gold"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, mit dem das Feld discountCode unkenntlich gemacht wird, wenn customerType „gold“ ist. Mit der Funktion removeFields werden bestimmte Felder aus einem Ereignis entfernt. Beispiel:

message.data.customerType == "gold" ?
      message.removeFields(["data.discountCode"]) :
      message

Datenkonvertierung

Sie müssen Daten von einem Format oder Typ in ein anderes konvertieren.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "orderDate": "2024-10-31T12:00:00Z",
    "totalAmount": "1500"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "orderDate": 1704086400,
    "totalAmount": 1500.00
  }
}
Lösung:

Verwenden Sie einen Ausdruck, der orderDate in einen UNIX-Zeitstempel und den Typ totalAmount von string in double (Gleitkommazahl) konvertiert. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Sie können Funktionen zur Stringbearbeitung verwenden, um die String-Ergebnisse zu konvertieren. Beispiel:

message
      .setField("data.orderDate", int(timestamp(message.data.orderDate)))
      .setField("data.totalAmount", double(message.data.totalAmount))

Bedingtes Routing

Sie müssen Ereignisse basierend auf den Ereignisdaten an verschiedene Ziele weiterleiten.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "eventType": "order.created",
    "orderValue": 200
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "eventType": "order.created",
    "orderValue": 200,
    "routingKey": "highValue"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, der ein routingKey-Feld mit dem Wert „highValue“ hinzufügt, wenn orderValue größer als 100 ist. Andernfalls wird "normal" verwendet. Mit dem Feld routingKey kann der Routingpfad bestimmt werden. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Beispiel:

message.data.orderValue > 100 ?
      message.setField("data.routingKey", "highValue") :
      message.setField("data.routingKey", "normal")

Umgang mit Standardwerten

Sie müssen dafür sorgen, dass bestimmte Felder in der Ereignisnutzlast Standardwerte haben, wenn sie nicht vorhanden sind.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "itemName": "Product A"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "itemName": "Product A",
    "quantity": 1
  }
}
Lösung:

Verwenden Sie einen Ausdruck, der das Feld quantity mit dem Standardwert 1 hinzufügt, wenn das Feld noch nicht vorhanden ist. Mit dem Makro has wird geprüft, ob ein Feld verfügbar ist. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Beispiel:

has(message.data.quantity)  ?
    message :
    message.setField("data.quantity", 1)

String-Bearbeitung

Sie müssen Teile eines Stringfelds in den Ereignisdaten extrahieren oder ändern.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "customerEmail": "alex@example.com"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "customerEmail": "alex@example.com",
    "emailDomain": "example.com"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, mit dem der Domainname („beispiel.de“) aus dem Feld customerEmail extrahiert und in einem neuen Feld emailDomain gespeichert wird. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Die Funktion für reguläre Ausdrücke extract folgt der RE2-Syntax. Beispiel:

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

Listen- und Kartenvorgänge

Sie müssen mit Listen oder Karten in den Ereignisdaten arbeiten.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "productIds": [
      "product123",
      "product456"
    ]
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "productIds": [
      "product123",
      "product456"
    ],
    "productFound": true
  }
}
Lösung:

Verwenden Sie einen Ausdruck, mit dem geprüft wird, ob „product456“ in der Liste productIds vorhanden ist, und speichern Sie das Ergebnis (true oder false) in einem neuen Feld productFound. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Das Makro exists prüft, ob ein Prädikat für alle Elemente einer Liste gilt, und kombiniert die Ergebnisse mit dem Operator „or“. Beispiel:

message.setField("data.productFound",
        message.data.productIds.exists(id, id == "product123"))

Fehlerbehandlung

Sie müssen potenzielle Fehler oder unerwartete Daten in der Ereignis-Payload abfangen.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "quantity": "abc"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "quantity": 0,
    "error": "Invalid quantity"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, mit dem versucht wird, das Feld quantity in eine Ganzzahl zu konvertieren. Wenn die Conversion fehlschlägt, setzen Sie das Feld quantity auf 0 und fügen Sie ein neues Feld error mit dem Wert „Invalid quantity“ (Ungültige Menge) hinzu.

  • Mit dem Makro has wird geprüft, ob ein Feld verfügbar ist.
  • Die Funktion type gibt den Typ eines Werts zurück.
  • Die Funktion für reguläre Ausdrücke matches folgt der RE2-Syntax.
  • Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt.

Beispiel:

// 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")

Komplexe Anwendungsfälle

Im Folgenden finden Sie einige komplexe Anwendungsfälle für die Transformation von Ereignisdaten.

Datentransformation

Sie müssen mehrere Transformationen für verschachtelte Ereignisdaten ausführen.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "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
      }
    ]
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "orderId": "12345",
    "customer.firstName": "Alex",
    "customer.lastName": "Taylor",
    "customer.email": "a***@example.com",
    "customer.address.city": "Mountain View",
    "customer.address.state": "CA"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, mit dem Stadt und Bundesstaat aus der Adresse extrahiert und die E-Mail-Adresse maskiert werden.

  • Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt.
  • Mit der Funktion toMap wird eine CEL-Liste von CEL-Maps in eine einzelne CEL-Map konvertiert.
  • Die Funktion für reguläre Ausdrücke extract folgt der RE2-Syntax.
  • Mit der Funktion removeFields werden bestimmte Felder aus einem Ereignis entfernt.
  • Die Funktion denormalize fasst verschachtelte Strukturen in einer Liste von Schlüssel/Wert-Paaren zusammen. Feldnamen werden durch einen Punkt (.) getrennt, um die Strukturhierarchie zu segmentieren.

Beispiel:

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

Datenformatierung und ‑routing

Sie müssen Ereignisdaten formatieren, Produktinformationen hinzufügen und dann die Ereignisnachricht weiterleiten.

Szenario:

Angenommen, Sie haben die folgenden CloudEvents-Daten:

{
  "data": {
    "productId": "p123",
    "productName": "Example Product",
    "category": "electronics"
  }
}

Sie möchten einen CEL-Ausdruck schreiben, der die folgende Ausgabe erzeugt:

{
  "data": {
    "productId": "electronics-p123",
    "productName": "EXAMPLE PRODUCT",
    "category": "electronics",
    "routingKey": "electronics"
  }
}
Lösung:

Verwenden Sie einen Ausdruck, der den Produktnamen in Großbuchstaben formatiert, der Produkt-ID basierend auf der Kategorie ein Präfix hinzufügt und einen Routing-Schlüssel für die Downstream-Verarbeitung enthält. Mit der Funktion setField wird einem Ereignis ein Feld mit einem bestimmten Schlüssel hinzugefügt oder ein vorhandenes Feld ersetzt. Die Funktion upperAscii gibt einen String zurück, in dem alle ASCII-Zeichen in die entsprechenden Großbuchstaben umgewandelt wurden. Beispiel:

message
.setField("data.productId",
message.data.category + "-" + message.data.productId)
.setField("data.productName", message.data.productName.upperAscii())
.setField("data.routingKey", message.data.category)