אפשר לשנות את נתוני CloudEvents באמצעות כתיבת ביטויי שינוי ב-CEL. מידע נוסף זמין במאמר בנושא טרנספורמציה של אירועים שהתקבלו.
ריכזנו כאן כמה תרחישי שימוש נפוצים ודוגמאות שמראים איך לכתוב ביטויי CEL כדי לשנות את נתוני האירועים.
תרחישים סטנדרטיים לדוגמה
ריכזנו כאן כמה תרחישי שימוש סטנדרטיים להמרת נתוני אירועים.
נירמול נתונים
אתם צריכים לשטח מבנה נתונים מקונן בהודעת האירוע כדי לאפשר עיבוד קל יותר על ידי שירות במורד הזרם.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View" } } } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "orderId": "12345", "customerFirstName": "Alex", "customerLastName": "Taylor", "customerStreet": "1800 Amphibious Blvd.", "customerCity": "Mountain View" } }
- פתרון 1:
מעצבים את נתוני הפלט באופן ידני. כך אפשר לראות את שמות השדות ולבחור רק את הרכיבים שרוצים בפלט. זו גישה סבירה כשהקלט צפוי וכשיש מספר קטן של שדות. הפונקציה
setFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. לדוגמה: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, })
- פתרון 2:
משתמשים בפונקציה בביטוי. הפונקציה
setFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. הפונקציהdenormalizeמיישרת מבנים עמוקים לרשימה של צמדי מפתח וערך. שמות השדות מופרדים באמצעות נקודה (.) כדי לפלח את ההיררכיה של המבנה. לדוגמה:message.setField("data", message.data.denormalize())
התוצאה היא הפלט הבא, ששונה מעט ממטען הייעודי (payload) הצפוי. עם זאת, היתרונות כוללים ביטוי CEL קצר יותר שפועל על כל קלט, וכולל באופן אוטומטי כל מספר של שדות נכנסים.
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.address.street": "1800 Amphibious Blvd.", "customer.address.city": "Mountain View" } }
הסתרת נתונים
צריך להסוות נתונים רגישים במטען ייעודי (payload) של אירוע לפני שהוא נשלח לסביבה פחות מאובטחת.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "userId": "user123", "email": "alex@example.com", "creditCardNumber": "1234-5678-9012-3456" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "userId": "user123", "email": "a***@example.com", "creditCardNumber": "xxxx-xxxx-xxxx-3456" } }
- פתרון:
משתמשים בביטוי כדי להסתיר מידע רגיש כמו כתובת האימייל ומספר כרטיס האשראי. הפונקציה
setFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. הפונקציה של הביטוי הרגולריextractפועלת לפי התחביר של RE2. לדוגמה: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"))
השמטת נתונים
אתם צריכים להסיר שדות ספציפיים ממטען ייעודי (payload) של אירוע על סמך תנאים מסוימים.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "orderId": "12345", "customerType": "gold", "discountCode": "VIP" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ { "orderId": "12345", "customerType": "gold" } }
- פתרון:
משתמשים בביטוי שמצנזר את השדה
discountCodeאם הערך שלcustomerTypeהוא gold. הפונקציהremoveFieldsמסירה שדות ספציפיים מאירוע. לדוגמה:message.data.customerType == "gold" ? message.removeFields(["data.discountCode"]) : message
המרת נתונים
אתם צריכים להמיר נתונים מפורמט או מסוג אחד לפורמט או לסוג אחר.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "orderDate": "2024-10-31T12:00:00Z", "totalAmount": "1500" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "orderDate": 1704086400, "totalAmount": 1500.00 } }
- פתרון:
משתמשים בביטוי שממיר את
orderDateלחותמת זמן של UNIX, ואת הסוגtotalAmountמ-stringל-double(מספר נקודה צפה). הפונקציהsetFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. אפשר להשתמש בפונקציות לשינוי מחרוזות כדי להמיר את התוצאות של המחרוזות. לדוגמה:message .setField("data.orderDate", int(timestamp(message.data.orderDate))) .setField("data.totalAmount", double(message.data.totalAmount))
ניתוב מותנה
אתם צריכים להפנות אירועים ליעדים שונים על סמך נתוני האירועים.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "eventType": "order.created", "orderValue": 200 } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "eventType": "order.created", "orderValue": 200, "routingKey": "highValue" } }
- פתרון:
משתמשים בביטוי שמוסיף שדה
routingKeyעם הערך highValue אםorderValueגדול מ-100, אחרת הערך הוא"normal". אפשר להשתמש בשדהroutingKeyכדי לקבוע את נתיב הניתוב. הפונקציהsetFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. לדוגמה:message.data.orderValue > 100 ? message.setField("data.routingKey", "highValue") : message.setField("data.routingKey", "normal")
טיפול בערך ברירת מחדל
צריך לוודא שלשדות מסוימים במטען הייעודי (payload) של האירוע יש ערכי ברירת מחדל אם הם לא קיימים.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "itemName": "Product A" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "itemName": "Product A", "quantity": 1 } }
- פתרון:
משתמשים בביטוי שמוסיף שדה
quantityעם ערך ברירת מחדל של1אם השדה עדיין לא קיים. המאקרוhasבודק אם שדה מסוים זמין. הפונקציהsetFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. לדוגמה:has(message.data.quantity) ? message : message.setField("data.quantity", 1)
מניפולציה של מחרוזות
אתם צריכים לחלץ או לשנות חלקים משדה מחרוזת בנתוני האירוע.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "customerEmail": "alex@example.com" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "customerEmail": "alex@example.com", "emailDomain": "example.com" } }
- פתרון:
משתמשים בביטוי שמחלץ את שם הדומיין ("example.com") מהשדה
customerEmailומאחסן אותו בשדה חדשemailDomain. הפונקציהsetFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. הפונקציה של הביטוי הרגולריextractפועלת לפי התחביר של RE2. לדוגמה:message .setField("data.emailDomain", re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))
פעולות ברשימה ובמפה
אתם צריכים לעבוד עם רשימות או מפות בנתוני האירועים.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "productIds": [ "product123", "product456" ] } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "productIds": [ "product123", "product456" ], "productFound": true } }
- פתרון:
משתמשים בביטוי שבודק אם 'product456' קיים ברשימה
productIdsומאחסן את התוצאה (trueאוfalse) בשדה חדשproductFound. הפונקציהsetFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. המאקרוexistsבודק אם פרדיקט מתקיים עבור כל הרכיבים ברשימה ומשלב את התוצאות עם האופרטור 'או'. לדוגמה:message.setField("data.productFound", message.data.productIds.exists(id, id == "product123"))
טיפול בשגיאות
צריך לטפל בצורה נכונה בשגיאות פוטנציאליות או בנתונים לא צפויים במטען הייעודי (payload) של אירוע.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "quantity": "abc" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "quantity": 0, "error": "Invalid quantity" } }
- פתרון:
משתמשים בביטוי שמנסה להמיר את השדה
quantityלמספר שלם. אם ההמרה נכשלת, צריך להגדיר את השדהquantityלערך0ולהוסיף שדהerrorחדש עם הערך Invalid quantity (כמות לא תקינה).- פקודת המאקרו
hasבודקת אם שדה מסוים זמין. - הפונקציה
typeמחזירה את סוג הערך. - פונקציית הביטוי הרגולרי
matchesפועלת לפי התחביר של RE2. - הפונקציה
setFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון.
לדוגמה:
// 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")
- פקודת המאקרו
תרחישים מורכבים לדוגמה
ריכזנו כאן כמה תרחישי שימוש מורכבים להמרת נתוני אירועים.
התאמת נתונים
צריך לבצע כמה טרנספורמציות על נתוני אירועים מוטמעים.
- תרחיש:
בהינתן נתוני 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 } ] } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.email": "a***@example.com", "customer.address.city": "Mountain View", "customer.address.state": "CA" } }
- פתרון:
משתמשים בביטוי שמחלץ את העיר והמדינה מהכתובת, ומסתיר את כתובת האימייל.
- הפונקציה
setFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. - הפונקציה
toMapממירה רשימה של מפות CEL למפת CEL אחת. - פונקציית הביטוי הרגולרי
extractפועלת לפי התחביר של RE2. - הפונקציה
removeFieldsמסירה שדות ספציפיים מאירוע. - הפונקציה
denormalizeמשטחת מבנים עמוקים לרשימה של צמדי מפתח וערך. שמות השדות מופרדים באמצעות נקודה (.) כדי לפלח את ההיררכיה של המבנה.
לדוגמה:
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() )
- הפונקציה
פורמט הנתונים והניתוב שלהם
צריך לעצב את נתוני האירועים, להוסיף פרטי מוצרים ואז לנתב את הודעת האירוע.
- תרחיש:
בהינתן נתוני CloudEvents הבאים:
{ "data": { "productId": "p123", "productName": "Example Product", "category": "electronics" } }
אתם רוצים לכתוב ביטוי CEL שיוביל לפלט הבא:
{ "data": { "productId": "electronics-p123", "productName": "EXAMPLE PRODUCT", "category": "electronics", "routingKey": "electronics" } }
- פתרון:
משתמשים בביטוי שמגדיר את שם המוצר באותיות רישיות, מוסיף קידומת למזהה המוצר על סמך הקטגוריה שלו וכולל מפתח ניתוב לעיבוד בהמשך. הפונקציה
setFieldמוסיפה או מחליפה שדה של האירוע במפתח נתון. הפונקציהupperAsciiמחזירה מחרוזת שבה כל תווי ה-ASCII מומרים לאותיות רישיות. לדוגמה:message .setField("data.productId", message.data.category + "-" + message.data.productId) .setField("data.productName", message.data.productName.upperAscii()) .setField("data.routingKey", message.data.category)