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 sind einige Standardanwendungsfälle für die Transformation von Ereignisdaten aufgeführt.
Datennormalisierung
Sie müssen eine verschachtelte Datenstruktur in Ihrer Ereignisnachricht flachstellen, 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 zu der folgenden Ausgabe führt:
{ "data": { "orderId": "12345", "customerFirstName": "Alex", "customerLastName": "Taylor", "customerStreet": "1800 Amphibious Blvd.", "customerCity": "Mountain View" } }
- Lösung 1:
Formatieren Sie die Ausgabedaten manuell. 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 ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder 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 ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Die Funktiondenormalize
bricht tiefe Strukturen in eine Liste von Schlüssel/Wert-Paaren auf. Feldnamen werden durch einen Punkt (.
) voneinander getrennt, um die Strukturhierarchie zu segmentieren. Beispiel:message.setField("data", message.data.denormalize())
Das führt zur folgenden Ausgabe, die sich geringfügig von der erwarteten Nutzlast unterscheidet. Zu den Vorteilen gehören jedoch ein kürzerer CEL-Ausdruck, der auf jede Eingabe angewendet werden kann und automatisch eine beliebige Anzahl eingehender Felder 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 zu der folgenden Ausgabe führt:
{ "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 ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Die reguläre Ausdrucksfunktionextract
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, wenn bestimmte Bedingungen erfüllt sind.
- Szenario:
Angenommen, Sie haben die folgenden CloudEvents-Daten:
{ "data": { "orderId": "12345", "customerType": "gold", "discountCode": "VIP" } }
Sie möchten einen CEL-Ausdruck schreiben, der zu der folgenden Ausgabe führt:
{ { "orderId": "12345", "customerType": "gold" } }
- Lösung:
Verwenden Sie einen Ausdruck, der das Feld
discountCode
entfernt, wenncustomerType
„gold“ ist. Mit der FunktionremoveFields
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 einen anderen 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 zu der folgenden Ausgabe führt:
{ "data": { "orderDate": 1704086400, "totalAmount": 1500.00 } }
- Lösung:
Verwenden Sie einen Ausdruck, der
orderDate
in einen UNIX-Zeitstempel und dentotalAmount
-Typ vonstring
indouble
(Gleitkommazahl) konvertiert. Mit der FunktionsetField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Sie können Funktionen zur Stringmanipulation verwenden, um die Stringergebnisse 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 zu der folgenden Ausgabe führt:
{ "data": { "eventType": "order.created", "orderValue": 200, "routingKey": "highValue" } }
- Lösung:
Verwenden Sie einen Ausdruck, der ein
routingKey
-Feld mit dem Wert „highValue“ hinzufügt, wennorderValue
größer als 100 ist, andernfalls"normal"
. Mit dem FeldroutingKey
kann der Routingpfad ermittelt werden. Mit der FunktionsetField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Beispiel:message.data.orderValue > 100 ? message.setField("data.routingKey", "highValue") : message.setField("data.routingKey", "normal")
Umgang mit Standardwerten
Bestimmte Felder in der Ereignisnutzlast müssen Standardwerte haben, falls sie nicht vorhanden sind.
- Szenario:
Angenommen, Sie haben die folgenden CloudEvents-Daten:
{ "data": { "itemName": "Product A" } }
Sie möchten einen CEL-Ausdruck schreiben, der zu der folgenden Ausgabe führt:
{ "data": { "itemName": "Product A", "quantity": 1 } }
- Lösung:
Verwenden Sie einen Ausdruck, der ein
quantity
-Feld mit dem Standardwert1
hinzufügt, wenn das Feld noch nicht vorhanden ist. Mit dem Makrohas
wird geprüft, ob ein Feld verfügbar ist. Mit der FunktionsetField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Beispiel:has(message.data.quantity) ? message : message.setField("data.quantity", 1)
String-Manipulation
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 zu der folgenden Ausgabe führt:
{ "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 FeldemailDomain
gespeichert wird. Mit der FunktionsetField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Die reguläre Ausdrucksfunktionextract
folgt der RE2-Syntax. Beispiel:message .setField("data.emailDomain", re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))
Listen- und Zuordnungsvorgänge
Sie müssen in den Ereignisdaten mit Listen oder Karten arbeiten.
- Szenario:
Angenommen, Sie haben die folgenden CloudEvents-Daten:
{ "data": { "productIds": [ "product123", "product456" ] } }
Sie möchten einen CEL-Ausdruck schreiben, der zu der folgenden Ausgabe führt:
{ "data": { "productIds": [ "product123", "product456" ], "productFound": true } }
- Lösung:
Verwenden Sie einen Ausdruck, der prüft, ob „Produkt456“ in der Liste
productIds
vorhanden ist, und das Ergebnis (true
oderfalse
) in einem neuenproductFound
-Feld speichert. Mit der FunktionsetField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Mit dem Makroexists
wird geprüft, ob ein Prädikat für alle Elemente einer Liste gilt, und die Ergebnisse mit dem Operator „or“ kombiniert. Beispiel:message.setField("data.productFound", message.data.productIds.exists(id, id == "product123"))
Fehlerbehandlung
Sie müssen mit potenziellen Fehlern oder unerwarteten Daten in der Ereignisnutzlast angemessen umgehen.
- Szenario:
Angenommen, Sie haben die folgenden CloudEvents-Daten:
{ "data": { "quantity": "abc" } }
Sie möchten einen CEL-Ausdruck schreiben, der zu der folgenden Ausgabe führt:
{ "data": { "quantity": 0, "error": "Invalid quantity" } }
- Lösung:
Verwenden Sie einen Ausdruck, mit dem versucht wird, das Feld
quantity
in eine Ganzzahl umzuwandeln. Wenn die Conversion fehlschlägt, setzen Sie das Feldquantity
auf0
und fügen Sie ein neues Felderror
mit dem Wert „Ungültige Stückzahl“ 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 reguläre Ausdrucksfunktion
matches
folgt der RE2-Syntax. - Mit der Funktion
setField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder 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")
- Mit dem Makro
Komplexe Anwendungsfälle
Im Folgenden finden Sie einige komplexe Anwendungsfälle für die Transformation von Ereignisdaten.
Datenumwandlung
Sie müssen mehrere Transformationen auf 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 zu der folgenden Ausgabe führt:
{ "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 die Stadt und der Bundesstaat aus der Adresse extrahiert und die E-Mail-Adresse maskiert werden.
- Mit der Funktion
setField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. - Die Funktion
toMap
wandelt eine CEL-Liste mit CEL-Maps in eine einzelne CEL-Map um. - Die reguläre Ausdrucksfunktion
extract
folgt der RE2-Syntax. - Mit der Funktion
removeFields
werden bestimmte Felder aus einem Ereignis entfernt. - Die Funktion
denormalize
wandelt tiefe Strukturen in eine Liste von Schlüssel/Wert-Paaren um. Feldnamen werden durch einen Punkt (.
) voneinander 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() )
- Mit der Funktion
Datenformatierung und -weiterleitung
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 zu der folgenden Ausgabe führt:
{ "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 ihrer Kategorie ein Präfix hinzufügt und einen Routingschlüssel für die nachfolgende Verarbeitung enthält. Mit der Funktion
setField
wird ein Feld des Ereignisses mit einem bestimmten Schlüssel hinzugefügt oder ersetzt. Die FunktionupperAscii
gibt einen String zurück, in dem alle ASCII-Zeichen in die entsprechenden Großbuchstaben umgewandelt sind. Beispiel:message .setField("data.productId", message.data.category + "-" + message.data.productId) .setField("data.productName", message.data.productName.upperAscii()) .setField("data.routingKey", message.data.category)