סקירה כללית של פונקציות בהגדרת המשתמש (UDF)

פונקציה בהגדרת המשתמש (UDF) ב-JavaScript היא סוג של Single Message Transform (SMT). פונקציות UDF מספקות דרך גמישה להטמעת לוגיקה מותאמת אישית של טרנספורמציה ב-Pub/Sub, בדומה לפונקציות UDF של JavaScript ב-BigQuery.

פונקציות UDF מקבלות הודעה אחת כקלט, מבצעות את הפעולות המוגדרות בקלט ומחזירות את תוצאת התהליך.

ל-UDF יש את המאפיינים העיקריים הבאים:

  • קוד: קוד JavaScript שמגדיר את לוגיקת הטרנספורמציה.

  • שם הפונקציה: השם של פונקציית JavaScript בקוד שסופק, ש-Pub/Sub מחיל על ההודעות.

יצירת פונקציית JavaScript

קוד ה-UDF חייב להכיל פונקציה עם החתימה הבאה:

  /**
  * Transforms a Pub/Sub message.
  * @return {(Object<string, (string | Object<string, string>)>|* null)} - To
  * filter a message, return `null`. To transform a message, return a map with
  * the following keys:
  *   - (required) 'data' : {string}
  *   - (optional) 'attributes' : {Object<string, string>}
  * Returning empty `attributes` will remove all attributes from the message.
  *
  * @param  {(Object<string, (string | Object<string, string>)>} - Pub/Sub
  * message. Keys:
  *   - (required) 'data' : {string}
  *   - (required) 'attributes' : {Object<string, string>}
  *
  * @param  {Object<string, any>} metadata - Pub/Sub message metadata.
  * Keys:
  *   - (optional) 'message_id'  : {string}
  *   - (optional) 'publish_time': {string} YYYY-MM-DDTHH:MM:SSZ format
  *   - (optional) 'ordering_key': {string}
  */
  function <function_name>(message, metadata) {
    // Perform custom transformation logic
    return message; // to filter a message instead, return `null`
  }

קלט

הפונקציה מקבלת את הקלט הבא:

  • הארגומנט message: אובייקט JavaScript שמייצג את ההודעה ב-Pub/Sub. הוא מכיל את המאפיינים הבאים:

    • data: (String, חובה) המטען הייעודי (payload) של ההודעה.

    • attributes: (Object<String, String>, אופציונלי) מיפוי של זוגות של מפתח-ערך שמייצגים מאפיינים של הודעה.

  • הארגומנט metadata: אובייקט JavaScript שמכיל מטא-נתונים שלא ניתן לשנות לגבי הודעת Pub/Sub:

    • message_id: (String, אופציונלי) המזהה הייחודי של ההודעה.

    • publish_time: (String, אופציונלי) זמן הפרסום של ההודעה בפורמט RFC 3339 (YYYY-MM-DDTHH:mm:ssZ).

    • ordering_key: (String, אופציונלי) מפתח הסידור של ההודעה, אם רלוונטי.

פלט

הפונקציה צריכה להחזיר אחת מהאפשרויות הבאות:

  • כדי לשנות הודעה, עורכים את התוכן של message.data ושל message.attributes ומחזירים את האובייקט message ששונה.

  • כדי לסנן הודעה, מחזירים null.

דרישות קלט / פלט

  • אם ה-UDF משנה את מטען הנתונים של ההודעה, מטען הנתונים של הקלט והפלט חייב להיות מחרוזות בקידוד UTF-8.
  • אם ה-UDF לא מבצע טרנספורמציה של מטען הייעודי (payload) של ההודעה, יכול להיות שהמטען הייעודי ישתמש בכל קידוד.
  • צמדי מפתח-ערך של מאפיינים חייבים להיות מחרוזות בקידוד UTF-8.

איך פונקציות UDF משנות הודעה

התוצאה של הפעלת UDF בהודעה יכולה להיות אחת מהאפשרויות הבאות:

  • ה-UDF משנה את ההודעה.

  • הפונקציה UDF מחזירה null.

    • נושאים של SMT: מערכת Pub/Sub מחזירה הצלחה לבעל התוכן הדיגיטלי וכוללת מזהה הודעה בתגובה להודעות המסוננות. ‫Pub/Sub לא שומר את ההודעה ולא שולח אותה למנויים.

    • הודעות SMT של מינוי: מערכת Pub/Sub מאשרת את מסירת ההודעה בלי לשלוח אותה למנוי.

  • ה-UDF מחזירה שגיאה.

    • נושאים של SMT: מערכת Pub/Sub מחזירה את השגיאה למוציא לאור ולא מפרסמת אף אחת מההודעות.

    • הודעות SMT של מינוי: המערכת ב-Pub/Sub שולחת אישור שלילי להודעה.

יצירת פונקציית SMT מוגדרת על ידי המשתמש

אפשר להגדיר SMT בנושאים או במינויים ב-Pub/Sub.

  • ה-SMT של הנושא מופעל לפני שההודעה מאוחסנת ב-Pub/Sub, והתוצאות זמינות לכל המנויים.
  • הפעולות של כללי התנועה של המינוי מבוצעות לפני שההודעה נמסרת, והתוצאות זמינות רק למינוי הזה.

המסוף

  1. נכנסים לדף Topics של Pub/Sub במסוף Cloud de Confiance .

    לדף Topics

  2. יוצרים נושא או מינוי.

    • כדי ליצור נושא, לוחצים על יצירת נושא. ייפתח הדף Create topic.

    • כדי ליצור מינוי:

      1. לוחצים על שם הנושא שרוצים להירשם אליו.

      2. לוחצים על יצירת מינוי. נפתח הדף הוספת מינוי לנושא.

  3. בקטע טרנספורמציות, לוחצים על הוספת טרנספורמציה.

  4. בקטע סוג הטרנספורמציה, בוחרים באפשרות פונקציית UDF של JavaScript.

  5. בשדה שם הפונקציה, מזינים את השם של פונקציית JavaScript שה-SMT קורא לה. דוגמה: redactSSN.

  6. באזור הטקסט, מזינים את הקוד של ה-UDF. דוגמה:

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
    

    הקוד צריך להכיל פונקציה שהשם שלה זהה לערך בשדה שם הפונקציה.

  7. אם לא רוצים שה-SMT יהיה פעיל באופן מיידי, בוחרים באפשרות השבתת השינוי. כשבוחרים באפשרות הזו, ה-SMT נוצר עם הנושא, אבל הוא לא מופעל על הודעות נכנסות. אחרי שיוצרים את הנושא, אפשר לערוך אותו כדי להפעיל את ה-SMT.

  8. כדי ליצור את הנושא או המינוי, לוחצים על Create.

gcloud

יצירת קובץ הגדרה

יוצרים קובץ YAML או JSON שמגדיר את פונקציית ה-UDF SMT.

YAML

- javascriptUdf:
    code: { FUNCTION_CODE }
    functionName: FUNCTION_NAME

JSON

{
  "javascriptUdf": {
    "code": {
      FUNCTION_CODE
    }
    "functionName": FUNCTION_NAME
  }
}

מחליפים את מה שכתוב בשדות הבאים:

  • FUNCTION_CODE: קוד ה-JavaScript של ה-UDF. הקוד חייב להכיל פונקציה שהשם שלה זהה לערך בשדה functionName. דוגמה:

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
    
  • FUNCTION_NAME: השם של פונקציית JavaScript שה-SMT קורא לה. דוגמה: redactSSN.

יצירת נושא או מינוי

כדי ליצור נושא, מריצים את הפקודה gcloud pubsub topics create.

gcloud pubsub topics create TOPIC_ID \
  --message-transforms-file=TRANSFORMS_FILE

מחליפים את מה שכתוב בשדות הבאים:

  • TOPIC_ID: המזהה או השם של הנושא שרוצים ליצור.
  • TRANSFORMS_FILE: הנתיב לקובץ ההגדרה.

כדי ליצור מינוי, מריצים את הפקודה gcloud pubsub subscriptions create.

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --topic=projects/PROJECT_ID/topics/TOPIC_ID \
  --message-transforms-file=TRANSFORMS_FILE

מחליפים את מה שכתוב בשדות הבאים:

  • SUBSCRIPTION_ID: המזהה או השם של המינוי שרוצים ליצור.

  • PROJECT_ID: מזהה הפרויקט שמכיל את הנושא.

  • TOPIC_ID: המזהה של הנושא להרשמה.

  • TRANSFORMS_FILE: הנתיב לקובץ ההגדרה.

אפשר גם לאמת ולבדוק את ה-SMT לפני שיוצרים אותו. מידע נוסף זמין בדפים הבאים:

מגבלות

‫Pub/Sub אוכף מגבלות על משאבים ב-UDF כדי להבטיח פעולות טרנספורמציה יעילות. המגבלות כוללות:

  • מקסימום 20KB של קוד לכל UDF
  • עד 500 אלפיות השנייה של זמן ביצוע לכל הודעה
  • תמיכה רק ברכיבים מובנים בתקן ECMAScript
  • אין קריאות לממשקי API חיצוניים
  • אין ייבוא של ספריות חיצוניות

פונקציות UDF לדוגמה

הנה כמה פונקציות UDF לדוגמה לפרסום ולהרשמה. דוגמאות נוספות זמינות בספריית UDF.

פונקציה: המרה של מספר שלם שמייצג יום בשבוע למחרוזת התואמת

כשמוסיפים את הפונקציה הבאה להגדרת משתמש לנושא או למינוי, מתבצעים השינויים הבאים במהלך פרסום או מסירה של הודעה:

  1. שירות Pub/Sub מחיל את הפונקציה על ההודעה. אם ההודעה לא כוללת מטען ייעודי (payload) בפורמט JSON, הפונקציה UDF מחזירה שגיאה.

  2. הפונקציה UDF מחפשת שדה בשם dayOfWeek, ואם הערך של השדה הזה הוא מספר בין 0 ל-6, היא ממירה אותו ליום המתאים בשבוע, כמו Monday. אם השדה לא קיים או שהמספר לא נמצא בטווח 0 עד 6, הקוד מגדיר את השדה dayOfWeek לערך Unknown.

  3. ה-UDF מבצע סריאליזציה של המטען הייעודי (payload) ששונה בחזרה להודעה.

  4. ‫Pub/Sub מעביר את ההודעה המעודכנת לשלב הבא בצינור.

function intToString(message, metadata) {
  const data = JSON.parse(message.data);
  switch(`data["dayOfWeek"]`) {
    case 0:
      data["dayOfWeek"] = "Sunday";
      break;
    case 1:
      data["dayOfWeek"] = "Monday";
      break;
    case 2:
      data["dayOfWeek"] = "Tuesday";
      break;
    case 3:
      data["dayOfWeek"] = "Wednesday";
      break;
    case 4:
      data["dayOfWeek"] = "Thursday";
      break;
    case 5:
      data["dayOfWeek"] = "Friday";
      break;
    case 6:
      data["dayOfWeek"] = "Saturday";
      break;
    default:
      data["dayOfWeek"] = "Unknown";
  }
  message.data = JSON.stringify(data);
  return message;
}

פונקציה: צנזורה של מספר תעודת זהות

כשמוסיפים את הפונקציה הבאה להגדרת משתמש לנושא או למינוי, מתבצעים השינויים הבאים במהלך פרסום או מסירה של הודעה:

  1. שירות Pub/Sub מחיל את הפונקציה על ההודעה. אם ההודעה לא כוללת מטען ייעודי (payload) של JSON, הפונקציה UDF מחזירה שגיאה.

  2. ה-UDF מסיר את השדה ssn ממטען הייעודי (payload) של ההודעה (אם הוא קיים).

  3. ה-UDF מבצע סריאליזציה של המטען הייעודי (payload) ששונה בחזרה להודעה.

  4. ‫Pub/Sub מעביר את ההודעה המעודכנת לשלב הבא בצינור.

function redactSSN(message, metadata) {
  const data = JSON.parse(message.data);
  delete data['ssn'];
  message.data = JSON.stringify(data);
  return message;
}

פונקציה: סינון והעברה אוטומטית של אישור להודעות ספציפיות

כשמוסיפים את הפונקציה הבאה להגדרת משתמש לנושא או למינוי, מתבצעים השינויים הבאים במהלך פרסום או מסירה של הודעה:

  1. שירות Pub/Sub מחיל את הפונקציה על ההודעה. אם ההודעה לא כוללת מטען ייעודי (payload) בפורמט JSON, הפונקציה UDF מחזירה שגיאה.

  2. ה-UDF בודק אם מטען הייעודי מכיל שדה בשם region.

  3. אם הערך של השדה region הוא לא US, הפונקציה מחזירה null, וכתוצאה מכך Pub/Sub מסנן את ההודעה.

  4. אם הערך בשדה region הוא US, ‏ Pub/Sub מעביר את ההודעה המקורית לשלב הבא בצינור.

function filterForUSRegion(message, metadata) {
  const data = JSON.parse(message.data);
  if (data["region"] !== "US") {
    return null;
  }
  return message;
}

פונקציה: אימות תוכן ההודעה כדי לוודא שהסכום לא גדול מ-100

כשמוסיפים את הפונקציה הבאה להגדרת משתמש לנושא או למינוי, מתבצעים השינויים הבאים במהלך פרסום או מסירה של הודעה:

  1. שירות Pub/Sub מחיל את הפונקציה על ההודעה. אם ההודעה לא כוללת מטען ייעודי (payload) בפורמט JSON, הפונקציה UDF מחזירה שגיאה.

  2. ה-UDF בודק אם ההודעה מכילה שדה בשם amount.

  3. אם הערך של השדה amount גדול מ-100, הפונקציה מחזירה שגיאה.

  4. אם הערך של השדה amount לא גדול מ-100, הפונקציה מחזירה את ההודעה המקורית.

  5. לאחר מכן, Pub/Sub מסמן את ההודעה כהודעה שנכשלה או מעביר את ההודעה המקורית לשלב הבא בצינור.

function validateAmount(message, metadata) {
  const data = JSON.parse(message.data);
  if (data["amount"] > 100) {
    throw new Error("Amount is invalid");
  }
  return message;
}

המאמרים הבאים