Benutzerdefinierte Funktionen (UDFs) – Übersicht

Eine benutzerdefinierte JavaScript-Funktion (User-Defined Function, UDF) ist eine Art von Transformation für einzelne Nachrichten (Single Message Transform, SMT). UDFs bieten eine flexible Möglichkeit, benutzerdefinierte Transformations logik in Pub/Sub zu implementieren, ähnlich wie bei benutzerdefinierten JavaScript-Funktionen in BigQuery.

UDFs akzeptieren eine einzelne Nachricht als Eingabe, führen die definierten Aktionen für die Eingabe aus und geben das Ergebnis des Prozesses zurück.

UDFs haben die folgenden Schlüsseleigenschaften:

  • Code:Der JavaScript-Code, der die Transformationslogik definiert.

  • Funktionsname:Der Name der JavaScript-Funktion im bereitgestellten Code, die Pub/Sub auf Nachrichten anwendet.

JavaScript-Funktion erstellen

Der UDF-Code muss eine Funktion mit der folgenden Signatur enthalten:

  /**
  * 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`
  }

Eingaben

Die Funktion akzeptiert die folgenden Eingaben:

  • message -Argument:Ein JavaScript-Objekt, das die Pub/Sub-Nachricht darstellt. Es enthält die folgenden Eigenschaften:

    • data: (String, erforderlich) Die Nachrichtennutzlast.

    • attributes: (Object<String, String>, optional) Eine Map mit Schlüssel-Wert Paaren, die Nachrichtenattribute darstellen.

  • metadata -Argument:Ein JavaScript-Objekt mit unveränderlichen Metadaten zur Pub/Sub-Nachricht:

    • message_id: (String, optional) Die eindeutige ID der Nachricht.

    • publish_time: (String, optional) Die Veröffentlichungszeit der Nachricht im RFC 3339-Format (JJJJ-MM-TTTHH:mm:ssZ).

    • ordering_key: (String, optional) Der Sortierschlüssel der Nachricht, falls zutreffend.

Ausgaben

Die Funktion muss einen der folgenden Werte zurückgeben:

  • Wenn Sie eine Nachricht transformieren möchten, bearbeiten Sie den Inhalt von message.data und message.attributes und geben Sie das geänderte message-Objekt zurück.

  • Wenn Sie eine Nachricht filtern möchten, geben Sie null zurück.

Anforderungen an Eingabe und Ausgabe

  • Wenn die UDF die Nachrichtennutzlast transformiert, müssen die Eingabe- und Ausgabenutzlast UTF-8-codierte Strings sein.
  • Wenn die UDF die Nachrichtennutzlast nicht transformiert, kann die Nutzlast eine beliebige Codierung verwenden.
  • Schlüssel-Wert-Paare für Attribute müssen UTF-8-codierte Strings sein.

So transformieren UDFs eine Nachricht

Das Ergebnis der Ausführung einer UDF für eine Nachricht kann eines der folgenden sein:

  • Die UDF transformiert eine Nachricht.

  • Die UDF gibt null zurück.

    • SMTs für Themen: Pub/Sub gibt eine Erfolgsmeldung an den Publisher zurück und fügt der Antwort eine Nachrichten-ID für die gefilterten Nachrichten hinzu. Pub/Sub speichert die Nachricht nicht und sendet sie nicht an Abonnenten.

    • SMTs für Abos: Pub/Sub bestätigt die Zustellung der Nachricht, ohne sie an einen Abonnenten zu senden.

  • Die UDF gibt einen Fehler aus.

    • SMTs für Themen: Pub/Sub gibt den Fehler an den Publisher zurück und veröffentlicht keine der Nachrichten.

    • SMTs für Abos: Pub/Sub bestätigt die Nachricht negativ.

UDF-SMT erstellen

SMTs können für Pub/Sub-Themen oder -Abos konfiguriert werden.

  • SMTs für Themen werden ausgeführt, bevor Pub/Sub die Nachricht speichert. Die Ergebnisse sind für alle Abonnenten verfügbar.
  • SMTs für Abos werden ausgeführt, bevor die Nachricht zugestellt wird. Die Ergebnisse sind nur für dieses Abo verfügbar.

Console

  1. Rufen Sie in der Google Cloud Console die Seite Pub/Sub-Themen auf.

    Themen aufrufen

  2. Erstellen Sie ein Thema oder ein Abo.

    • Wenn Sie ein Thema erstellen möchten, klicken Sie auf Thema erstellen. Die Seite Thema erstellen wird geöffnet.

    • So erstellen Sie ein Abo:

      1. Klicken Sie auf den Namen des Themas, für das Sie das Abo erstellen möchten.

      2. Klicken Sie auf Abo erstellen. Die Seite Abo zum Thema hinzufügen wird geöffnet.

  3. Klicken Sie unter Transformationen auf Transformation hinzufügen.

  4. Wählen Sie unter Transformationstyp die Option JavaScript-UDF aus.

  5. Geben Sie im Feld Funktionsname den Namen der JavaScript-Funktion ein, die von der SMT aufgerufen wird. Beispiel: redactSSN.

  6. Geben Sie im Textbereich den Code für die UDF ein. Beispiel:

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

    Der Code muss eine Funktion enthalten, deren Name mit dem Feld Funktionsname übereinstimmt.

  7. Wenn die SMT nicht sofort aktiv sein soll, wählen Sie Transformation deaktivieren aus. Wenn diese Option ausgewählt ist, wird die SMT mit dem Thema erstellt, aber nicht für eingehende Nachrichten ausgeführt. Nachdem das Thema erstellt wurde, können Sie es bearbeiten, um die SMT zu aktivieren.

  8. Klicken Sie auf Erstellen, um das Thema oder Abo zu erstellen.

gcloud

Definitionsdatei erstellen

Erstellen Sie eine YAML- oder JSON-Datei, die die UDF-SMT definiert.

YAML

- javascriptUdf:
    code: { FUNCTION_CODE }
    functionName: FUNCTION_NAME

JSON

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

Ersetzen Sie Folgendes:

  • FUNCTION_CODE: Der JavaScript-Code für die UDF. Der Code muss eine Funktion enthalten, deren Name mit dem Feld functionName übereinstimmt. Beispiel:

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
    
  • FUNCTION_NAME: Der Name der JavaScript Funktion, die von der SMT aufgerufen wird. Beispiel: redactSSN.

Thema oder Abo erstellen

Führen Sie den gcloud pubsub topics create Befehl aus, um ein Thema zu erstellen.

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

Ersetzen Sie Folgendes:

  • TOPIC_ID: Die ID oder der Name des Themas, das Sie erstellen möchten.
  • TRANSFORMS_FILE: Der Pfad zur Definitionsdatei.

Führen Sie den gcloud pubsub subscriptions create Befehl aus, um ein Abo zu erstellen.

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

Ersetzen Sie Folgendes:

  • SUBSCRIPTION_ID: Die ID oder der Name des Abos , das erstellt werden soll.

  • PROJECT_ID: Die ID des Projekts, das das Thema enthält.

  • TOPIC_ID: Die ID des Themas, das abonniert werden soll.

  • TRANSFORMS_FILE: Der Pfad zur Definitionsdatei.

Optional können Sie die SMT validieren und testen, bevor Sie sie erstellen. Weitere Informationen finden Sie auf den folgenden Seiten:

Beschränkungen

Pub/Sub erzwingt Ressourcenlimits für UDFs, um effiziente Transformationsvorgänge zu gewährleisten. Die Beschränkungen umfassen:

  • Maximal 20 KB Code pro UDF
  • Maximale Ausführungszeit von 500 ms pro Nachricht
  • Unterstützung nur für integrierte ECMAScript-Standards
  • Keine Aufrufe externer APIs
  • Keine Importe externer Bibliotheken

Beispiel-UDFs

Hier sind einige Beispiel-UDFs für die Veröffentlichung und das Abonnieren. Weitere Beispiele finden Sie in der UDF-Bibliothek.

Funktion: Ganzzahl für Wochentag in entsprechenden String konvertieren

Wenn Sie die folgende UDF einem Thema oder Abo hinzufügen, werden bei der Veröffentlichung oder Zustellung von Nachrichten die folgenden Änderungen vorgenommen:

  1. Pub/Sub wendet die Funktion auf die Nachricht an. Wenn die Nachricht keine JSON-Nutzlast hat, gibt die UDF einen Fehler aus.

  2. Die UDF sucht nach einem Feld namens dayOfWeek und konvertiert den Wert dieses Felds, wenn er eine Zahl zwischen 0 und 6 ist, in einen entsprechenden Wochentag wie Monday. Wenn das Feld nicht vorhanden ist oder die Zahl nicht im Bereich von 0 bis 6 liegt, wird das Feld dayOfWeek im Code auf Unknown gesetzt.

  3. Die UDF serialisiert die geänderte Nutzlast wieder in die Nachricht.

  4. Pub/Sub übergibt die aktualisierte Nachricht an den nächsten Schritt in Ihrer Pipeline.

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;
}

Funktion: Sozialversicherungsnummer unkenntlich machen

Wenn Sie die folgende UDF einem Thema oder Abo hinzufügen, werden bei der Veröffentlichung oder Zustellung von Nachrichten die folgenden Änderungen vorgenommen:

  1. Pub/Sub wendet die Funktion auf die Nachricht an. Wenn die Nachricht keine JSON-Nutzlast hat, gibt die UDF einen Fehler aus.

  2. Die UDF entfernt das Feld ssn aus der Nachrichtennutzlast (falls vorhanden).

  3. Die UDF serialisiert die geänderte Nutzlast wieder in die Nachricht.

  4. Pub/Sub übergibt die aktualisierte Nachricht an den nächsten Schritt in Ihrer Pipeline.

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

Funktion: Bestimmte Nachrichten herausfiltern und automatisch bestätigen

Wenn Sie die folgende UDF einem Thema oder Abo hinzufügen, werden bei der Veröffentlichung oder Zustellung von Nachrichten die folgenden Änderungen vorgenommen:

  1. Pub/Sub wendet die Funktion auf die Nachricht an. Wenn die Nachricht keine JSON-Nutzlast hat, gibt die UDF einen Fehler aus.

  2. Die UDF prüft, ob die Nutzlast ein Feld namens region enthält.

  3. Wenn der Wert des Felds region nicht US ist, gibt die Funktion „null“ zurück, wodurch Pub/Sub die Nachricht herausfiltert.

  4. Wenn der Wert des Felds region gleich US ist, übergibt Pub/Sub die ursprüngliche Nachricht an den nächsten Schritt in Ihrer Pipeline.

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

Funktion: Nachrichteninhalt validieren, um sicherzustellen, dass der Betrag nicht größer als 100 ist

Wenn Sie die folgende UDF einem Thema oder Abo hinzufügen, werden bei der Veröffentlichung oder Zustellung von Nachrichten die folgenden Änderungen vorgenommen:

  1. Pub/Sub wendet die Funktion auf die Nachricht an. Wenn die Nachricht keine JSON-Nutzlast hat, gibt die UDF einen Fehler aus.

  2. Die UDF prüft, ob die Nachricht ein Feld namens amount enthält.

  3. Wenn der Wert des Felds amount größer als 100 ist, gibt die Funktion einen Fehler aus.

  4. Wenn der Wert des Felds amount nicht größer als 100 ist, gibt die Funktion die ursprüngliche Nachricht zurück.

  5. Pub/Sub markiert die Nachricht dann entweder als fehlgeschlagen oder übergibt die ursprüngliche Nachricht an den nächsten Schritt in Ihrer Pipeline.

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

Nächste Schritte