Cloud Functions Funktion-Aufgabe

Mit der Cloud Functions-Aufgabe können Sie Google Cloud Functions aus Ihrer Integration heraus konfigurieren und ausführen. Google Cloud Functions ist eine ressourcensparende Computing-Lösung, mit der Entwickler zweckgebundene, eigenständige Funktionen erstellen können, die auf Cloud-Ereignisse reagieren und keine eigene Server- oder Laufzeitumgebung benötigen.

Weitere Informationen finden Sie in der Google Cloud Functions-Dokumentation.

Hinweise

Führen Sie folgende Aufgaben in Ihrem Google Cloud-Projekt aus, bevor Sie die Cloud Functions-Aufgabe konfigurieren.

  1. Aktivieren Sie die Cloud Functions API (cloudfunctions.googleapis.com).

    Cloud Functions API aktivieren

  2. Weisen Sie Ihrem Hauptkonto die folgenden IAM-Rollen zu:
    • Cloud Functions Admin (roles/cloudfunctions.admin)
    • Application Integration Editor (roles/integrations.integrationEditor)
    • Dienstkontonutzer (roles/iam.serviceAccountUser)

    Informationen zum Zuweisen von Rollen für Hauptkonten finden Sie unter Zugriff auf Ressourcen erteilen, ändern und entziehen.

  3. Wenn Sie eine Verbindung zu Cloud Functions herstellen möchten, müssen Sie entweder ein OAuth 2.0-Profil erstellt oder ein nutzerverwaltetes Dienstkonto an Ihre Integration angehängt haben.
    • Wenn Ihre Integration ein Dienstkonto hat, weisen Sie diesem Dienstkonto die IAM-Rolle Cloud Functions-Aufrufer zu.

      Informationen zum Zuweisen von Rollen zu einem Dienstkonto finden Sie unter Zugriff auf Dienstkonten verwalten.

    • Die Cloud Functions-Aufgabe unterstützt nur Authentifizierungsprofile vom Typ OIDC-ID-Token von Google. Erstellen Sie mithilfe des Dienstkontos ein Authentifizierungsprofil vom Typ OIDC-ID-Token von Google mit der zugewiesenen IAM-Rolle Cloud Functions-Aufrufer. Wenn für die Cloud Functions-Aufgabe keine Authentifizierung erforderlich ist, kann das Feld Authentifizierungsprofil im Konfigurationsbereich der Aufgabe leer bleiben.

    Wenn in Ihrer Integration sowohl ein OIDC-ID-Profil als auch ein vom Nutzer verwaltetes Dienstkonto konfiguriert sind, wird standardmäßig das OIDC-ID-Profil zur Authentifizierung verwendet. Wenn weder das OIDC-ID-Profil noch das nutzerverwaltete Dienstkonto konfiguriert ist, wird die Cloud Functions-Aufgabe mit dem Standarddienstkonto (service-PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com) aufgerufen.

  4. Achten Sie darauf, dass VPC Service Controls NICHT für die Apigee Integration in Ihrem Google Cloud-Projekt eingerichtet ist.

Cloud Functions-Aufgabe konfigurieren

Führen Sie folgende Schritte aus, um die Cloud Functions-Aufgabe in Ihrer Einbindung zu konfigurieren:

  1. Wählen Sie in der Apigee-Benutzeroberfläche Ihre Apigee-Organisation aus.
  2. Klicken Sie auf Entwickeln > Integrationen.
  3. Wählen Sie eine vorhandene Integration aus oder erstellen Sie eine neue Integration, indem Sie auf Integration erstellen klicken.

    Wenn Sie eine neue Integration erstellen, gehen Sie so vor:

    1. Geben Sie im Dialogfeld Integration erstellen einen Namen und eine Beschreibung ein.
    2. Wählen Sie eine Region für die Integration aus der Liste der unterstützten Regionen aus.
    3. Klicken Sie auf Erstellen.

    Dadurch wird die Integration auf der Seite Integrationsdesigner geöffnet.

  4. Klicken Sie in der Navigationsleiste Integrationsdesigner auf + Aufgabe/Trigger hinzufügen > Aufgaben, um die Liste der verfügbaren Aufgaben aufzurufen.
  5. Klicken Sie auf das Element Cloud Functions und platzieren Sie es im Integrationseditor.
  6. Klicken Sie auf das Cloud Functions-Element im Designer, um den Konfigurationsbereich zu öffnen, und klicken Sie dann auf Cloud Functions konfigurieren.
  7. Wählen Sie im Dialogfeld Cloud Functions-Konfiguration eine der folgenden Optionen aus:
    • Vorhandene Funktion verknüpfen. Wählen Sie diese Option aus, um eine vorhandene Cloud Functions-Funktion zu verknüpfen, die in der Integration konfiguriert ist. Geben Sie die Cloud Functions-Trigger-URL ein.
    • Neue Funktion erstellen. Wählen Sie diese Option aus, um eine neue Cloud Functions-Funktion zu erstellen, die mit der Integration verknüpft ist. Geben Sie den Namen der Cloud Functions-Funktion ein und wählen Sie aus der Drop-down-Liste die Funktionsregion aus.
  8. Klicken Sie auf Speichern.

    In Ihrem Google Cloud-Projekt wird eine einfache Google Cloud-Funktion erstellt und mit Ihrer Integration verknüpft. Im Bereich der Aufgabenkonfiguration werden die Trigger-URL und die Aufgabenparameter der Cloud Functions-Funktion angezeigt.

Vorlage für die Cloud Functions-Funktion

Achten Sie beim Konfigurieren der Cloud Functions-Funktion mit einer vorhandenen Cloud Functions-Funktion darauf, dass die Quelldateien main.py, task.py und requirements.txt der Funktion das folgende Format haben:

task.py

  # Sample Code:
  # print(event.get('task_string_key'))
  # event.set('task_int_array_key', [456, 789]);
  # event.log('some logging')

  def run(event):
    """Actual cloud function custom logic.
    Args:
      event : event object in main.py that contains all parameters.
    """
    return

main.py

  """Un-editable platform wrapper which invokes user code."""
import traceback

from flask import json
from flask import jsonify
from task import run

VALUE_NAME = [
    'stringValue', 'intValue', 'doubleValue', 'booleanValue', 'protoValue'
]
ARRAY_VALUE_NAME = {
    'stringArray': 'stringValues',
    'intArray': 'intValues',
    'doubleArray': 'doubleValues',
    'booleanArray': 'booleanValues',
    'protoArray': 'protoValues'
}
VALUE_TYPE_URL = 'type.googleapis.com/google.protobuf.Value'
CLOUD_FUNCTION_EXCEPTION_KEY = 'CloudFunctionException'
CLOUD_FUNCTION_LOGGING_KEY = 'CloudFunctionLogging'

class _Event(object):
  """Event object."""

  def __init__(self, json_payload):
    self._event_params = json_payload.get('eventParameters', dict())
    self._task_params = json_payload.get('taskParameters', dict())
    self._log = []
    print('Event param is ' + str(self._event_params))
    print('Task param is ' + str(self._task_params))

  def set(self, key, value):
    """Set the event parameters key-value.

    Args:
      key: parameter key.
      value: parameter value.
    """
    new_param = self._create_param(key, value)
    param = self._get_param_by_key(key)
    if param is None:
      if 'parameters' not in self._event_params:
        self._event_params['parameters'] = []
      self._event_params['parameters'].append(new_param)
    else:
      param['value'] = new_param['value']

  def _create_param(self, key, value):
    """Create a new parameter with given key value pair.

    Args:
      key: parameter key.
      value: parameter value.

    Returns:
      parameter.
    """
    new_param = {}
    new_param['key'] = key
    if isinstance(value, str):
      new_param['value'] = {'stringValue': value}
    elif isinstance(value, int):
      new_param['value'] = {'intValue': value}
    elif isinstance(value, float):
      new_param['value'] = {'doubleValue': value}
    elif isinstance(value, bool):
      new_param['value'] = {'booleanValue': value}
    elif isinstance(value, dict):
      if 'type@' in value:
        new_param['value'] = {'protoValue': value}
      else:
        new_param['value'] = {
            'protoValue': {
                '@type': 'type.googleapis.com/google.protobuf.Value',
                'value': value
            }
        }
    elif isinstance(value, list):
      if not value:
        raise RuntimeError('Cannot create a param with empty list')
      if any(not isinstance(val, type(value[0])) for val in value):
        print('Not all elements in the list have the same type')
        new_param['value'] = {
            'protoValue': {
                '@type': 'type.googleapis.com/google.protobuf.Value',
                'value': value
            }
        }
      elif isinstance(value[0], str):
        new_param['value'] = {'stringArray': {'stringValues': value}}
      elif isinstance(value[0], int):
        new_param['value'] = {'intArray': {'intValues': value}}
      elif isinstance(value[0], float):
        new_param['value'] = {'doubleArray': {'doubleValues': value}}
      elif isinstance(value[0], bool):
        new_param['value'] = {'booleanArray': {'booleanValues': value}}
      elif isinstance(value[0], dict):
        if all('@type' in val and val['@type'] == value[0]['@type']
               for val in value):
          new_param['value'] = {'protoArray': {'protoValues': value}}
        else:
          new_param['value'] = {
              'protoValue': {
                  '@type': 'type.googleapis.com/google.protobuf.Value',
                  'value': value
              }
          }
      else:
        raise RuntimeError('The type ' + type(value[0]) +
                           ' in the list is not supported')
    else:
      raise RuntimeError('Value ' + str(value) + ' has the type ' +
                         type(value) + ' that is not supported')
    return new_param

  def get(self, key):
    """Get the event parameter value for specified key.

    Args:
      key: parameter key.

    Returns:
      Parameter value.
    """
    param = self._get_param_by_key(key)
    if param is None:
      raise RuntimeError('Can not find param with key ' + key)
    return self._get_param_value(param)

  def _get_param_by_key(self, key):
    """Get the parameter for specified key.

    Args:
      key: parameter key.

    Returns:
      Parameter.
    """
    param = self._get_param_by_key_from_params(key, self._task_params)
    if param is None:
      return self._get_param_by_key_from_params(key, self._event_params)
    value = self._get_param_value(param)
    if isinstance(value, str) and len(value) > 2 and value.startswith(
        '$') and value.endswith('$'):
      return self._get_param_by_key_from_params(value[1:-1], self._event_params)
    return param

  def _get_param_by_key_from_params(self, key, params):
    """Get the parameter for specified key from event parameters.

    Args:
      key: parameter key.
      params: event parameters.

    Returns:
      Parameter.
    """
    if not isinstance(params, dict) or 'parameters' not in params:
      return None
    for param in params['parameters']:
      if param['key'] == key:
        return param
    return None

  def _get_param_value(self, param):
    """Get the parameter value for specified parameter.

    Args:
      param: parameter.

    Returns:
      Parameter value.
    """
    value = param['value']
    if len(value) != 1:
      raise RuntimeError('param does not have size of 1')
    for value_name in VALUE_NAME:
      if value_name in value:
        if value_name == 'protoValue' and value[value_name][
            '@type'] == VALUE_TYPE_URL:
          return value[value_name]['value']
        return value[value_name]
    for array_value_name in ARRAY_VALUE_NAME:
      if array_value_name in value:
        return value[array_value_name][ARRAY_VALUE_NAME[array_value_name]]
    raise RuntimeError('Cannot get value from param ' + str(param))

  def set_error(self):
    """Set the cloud function error to event parameters in order for user to see on IP."""

    self.set(CLOUD_FUNCTION_EXCEPTION_KEY, traceback.format_exc())

  def log(self, message):
    self._log.append(str(message))

  def get_response(self):
    """Get the response that can be returned to IP.

    Returns:
      The response text or any set of values that can be turned into a
      Response object using
      `make_response
      <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
    """
    if self._log:
      self.set(CLOUD_FUNCTION_LOGGING_KEY, self._log)
    res = {
        'eventParameters': self._event_params,
    }
    return jsonify(**json.loads(json.htmlsafe_dumps(res)))

def execute_function(request):
  """Entry point of the cloud function.

  Args:
    request (flask.Request): HTTP request object.

  Returns:
    The response text or any set of values that can be turned into a
    Response object using
    `make_response
    <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
  """
  try:
    request_json = request.get_json(silent=True)
    event = _Event(request_json)
    run(event)
  except:
    event.set_error()
  return event.get_response()

requirements.txt

# Function dependencies, for example:
# package>=version

Cloud Functions Funktion-Aufgabe bearbeiten

Beim Konfigurieren einer Cloud Functions-Funktion in der Apigee-Einbindung wird eine grundlegende HTTP-ausgelöste Cloud Functions-Funktion in Ihrem Google Cloud-Projekt erstellt.

Führen Sie die folgenden Schritte aus, um eine Cloud Functions-Funktion zu bearbeiten:

  1. Klicken Sie im Konfigurationsbereich der Aufgabe auf Cloud Functions öffnen.

    Sie werden zur Seite Funktionsdetails in der Google Cloud Console weitergeleitet.

  2. Klicken Sie auf Bearbeiten.
  3. Auf der Seite Konfiguration können Sie die Standardkonfigurationseinstellungen der Cloud Functions-Funktion bearbeiten. Weitere Informationen finden Sie unter Cloud Functions konfigurieren.
  4. Klicken Sie auf Weiter, um die Quellcodedateien von Cloud Function zu bearbeiten.

    Eine Cloud Functions-Funktion enthält standardmäßig folgende Quelldateien:

    • main.py: Diese Datei enthält den Initialisierungscode zum Ausführen der Cloud Functions-Funktion aus Ihrer Einbindung.
    • task.py: Diese Datei enthält den ausführbaren Code der Cloud Functions-Funktion. Schreiben Sie das Skript in die Funktion run(event). Diese Funktion wird aufgerufen, wenn die Cloud Functions-Aufgabe ausgeführt wird. Das Objekt event aus der Datei main.py enthält alle Aufgabenparameter.

      Informationen zur Verwendung der auf der Integrationsebene Ihres Skripts definierten Variablen finden Sie unter Zugriffsintegrationsvariablen.

  5. Klicken Sie auf Bereitstellen.

Auf Integrationsvariablen zugreifen

Für den Zugriff auf eine Integrationsvariable in Ihrer Cloud Functions-Funktion müssen Sie die Variable in Form von Aufgabenparametern an die Cloud Functions-Aufgabe übergeben. Bei den Aufgabenparametern handelt es sich um Schlüssel/Wert-Paare, wobei Schlüssel der Name der in Ihrer Cloud Function-Quelldatei verwendeten Referenzvariable und Wert der entsprechende Name der Integrationsvariable ist, auf die die Referenzvariable zeigt. Sie können einen oder mehrere Aufgabenparameter im Abschnitt Aufgabenparameter des Aufgabenkonfigurationsbereichs hinzufügen.

Die folgenden Methoden werden verwendet, um von Ihrer Cloud Functions-Funktion auf Integrationsvariablen zuzugreifen:

  • set: Legt den Wert auf eine Variable fest.
  • get: Ruft den Wert einer Variablen ab.

Wenn Sie beispielsweise eine Integrationsvariable mit dem Namen EmployeeName haben, die Sie in Ihrer Cloud Functions-Quelldatei verwenden möchten, definieren Sie folgende Aufgabenparameter:

  • Key: EmployeeKey
  • Wert: EmployeeName

Das folgende Beispielskript zeigt die Verwendung von set- und get-Funktionen zum Zugriff auf definierte Integrationsvariablen.

def run(event):
  # Read the integration variable EmployeeName using the reference variable EmployeeKey
  value = event.get('EmployeeKey');
  # Change the integration variable EmployeeName value using the reference variable EmployeeKey
  newValue = event.set('EmployeeKey' , 'XYZ');
  # The new value of the integration variable is retained throughout the Cloud Function task.
  return

Fehlerbehebungsstrategie

Eine Strategie zur Fehlerbehandlung für eine Aufgabe legt die Aktion fest, die ausgeführt werden soll, wenn die Aufgabe aufgrund eines temporären Fehlers fehlschlägt. Informationen zur Verwendung einer Fehlerbehandlungsstrategie und zu den verschiedenen Arten von Fehlerbehandlungsstrategien finden Sie unter Strategien zur Fehlerbehebung.