Attività della funzione Cloud Functions

L'attività funzione Cloud Functions Functions consente di configurare ed eseguire Google Cloud Functions dalla tua integrazione. Google Cloud Functions è una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico in grado di rispondere agli eventi Cloud senza la necessità di gestire un ambiente server o di runtime.

Per saperne di più, consulta la documentazione di Google Cloud Functions.

Prima di iniziare

Assicurati di eseguire le attività seguenti nel progetto Google Cloud prima di configurare l'attività Cloud Functions.

  1. Abilita l'API Cloud Functions (cloudfunctions.googleapis.com).

    Abilita l'API Cloud Functions

  2. Assegna i seguenti ruoli IAM all'entità:
    • Amministratore Cloud Functions (roles/cloudfunctions.admin)
    • Editor di Application Integration (roles/integrations.integrationEditor)
    • Utente account di servizio (roles/iam.serviceAccountUser)

    Per informazioni sulla concessione dei ruoli alle entità, vedi Concessione, modifica e revoca dell'accesso.

  3. Per connetterti a Cloud Functions, assicurati di aver creato un profilo OAuth 2.0 o di aver collegato un account di servizio gestito dall'utente all'integrazione:
    • Se all'integrazione è collegato un account di servizio, assegna il ruolo IAM Invoker della funzione Cloud Functions a quell'account.

      Per informazioni sulla concessione dei ruoli a un account di servizio, vedi Gestire l'accesso agli account di servizio.

    • L'attività funzione Cloud Functions supporta solo i profili di autenticazione di tipo Token ID OIDC Google. Crea un profilo di autenticazione di tipo Token ID OIDC Google utilizzando l'account di servizio a cui è assegnato il ruolo IAM Invoker della funzione Cloud Functions. Se l'attività funzione Cloud Functions non richiede l'autenticazione, il campo Profilo di autenticazione nel riquadro di configurazione dell'attività può essere lasciato vuoto.

    Se per l'integrazione sono configurati sia un profilo ID OIDC sia un account di servizio gestito dall'utente, per impostazione predefinita viene utilizzato il profilo ID OIDC per l'autenticazione. Se non è configurato né il profilo ID OIDC né l'account di servizio gestito dall'utente, l'account di servizio predefinito (service-PROJECT_NUMBER@gcp-sa-apigee.iam.gserviceaccount.com) viene utilizzato per chiamare l'attività funzione Cloud Functions.

  4. Assicurati che i Controlli di servizio VPC NON siano configurati per l'Apigee Integration nel tuo progetto Google Cloud.

Configura l'attività della funzione Cloud Functions

Per configurare l'attività funzione Cloud Functions Functions nell'integrazione, segui questi passaggi:

  1. Nell'UI di Apigee, seleziona la tua organizzazione Apigee.
  2. Fai clic su Sviluppa > Integrazioni.
  3. Seleziona un'integrazione esistente o creane una nuova facendo clic su Crea integrazione.

    Se stai creando una nuova integrazione:

    1. Inserisci un nome e una descrizione nella finestra di dialogo Crea integrazione.
    2. Seleziona una regione per l'integrazione dall'elenco delle regioni supportate.
    3. Fai clic su Crea.

    Viene aperta l'integrazione nel designer dell'integrazione.

  4. Nella barra di navigazione integration designer, fai clic su +Aggiungi un'attività/un attivatore > Tasks per visualizzare l'elenco delle attività disponibili.
  5. Fai clic e posiziona l'elemento Cloud Function nell'editor di integrazione.
  6. Fai clic sull'elemento Cloud Function nel designer per aprire il riquadro di configurazione, quindi fai clic su Configura la funzione Cloud Functions.
  7. Nella finestra di dialogo Configurazione della funzione Cloud Functions, scegli una delle seguenti opzioni:
    • Collega funzione esistente. Seleziona questa opzione per collegare una Cloud Function esistente configurata nell'integrazione. Inserisci l'URL del trigger della funzione Cloud Functions.
    • Crea nuova funzione. Seleziona questa opzione per creare una nuova Cloud Function associata all'integrazione. Inserisci il Nome della funzione Cloud Functions e seleziona la regione della funzione dall'elenco a discesa.
  8. Fai clic su Salva.

    Una funzione Google Cloud di base viene creata nel progetto Google Cloud ed è associata all'integrazione. Il riquadro di configurazione dell'attività visualizza l'URL trigger e i Parametri attività della Cloud Function.

Modello di funzione Cloud Functions

Quando configuri la Cloud Function utilizzando una funzione Cloud Functions esistente, assicurati che i file di origine main.py, task.py e requirements.txt della funzione abbiano il seguente formato:

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

Modifica un'attività di funzione Cloud Function

La configurazione di un'attività di funzione Cloud Functions in Apigee Integration crea una Cloud Function attivata tramite HTTP di base nel progetto Google Cloud.

Per modificare un'attività di funzione Cloud Functions, segui questi passaggi:

  1. Nel riquadro di configurazione dell'attività, fai clic su Apri funzione Cloud Functions.

    Si aprirà la pagina Dettagli funzione nella Google Cloud Console.

  2. Fai clic su Modifica.
  3. La pagina Configurazione consente di modificare le impostazioni di configurazione predefinite della Cloud Function. Per ulteriori informazioni, consulta Configurazione di Cloud Functions.
  4. Fai clic su Avanti per modificare i file di codice sorgente della Cloud Function.

    Per impostazione predefinita, la Cloud Function contiene i seguenti file di origine:

    • main.py : questo file contiene il codice di inizializzazione per eseguire la Cloud Function dall'integrazione.
    • task.py : questo file contiene il codice eseguibile della Cloud Function. Scrivi lo script all'interno della funzione run(event). Questa funzione viene chiamata quando viene eseguita l'attività della funzione Cloud Function. L'oggetto event del file main.py contiene tutti i parametri dell'attività.

      Per informazioni su come utilizzare le variabili definite a livello di integrazione nello script, consulta Accedere alle variabili di integrazione.

  5. Fai clic su Esegui il deployment.

Accedi alle variabili di integrazione

Per accedere a una variabile di integrazione nella Cloud Function, devi passare la variabile sotto forma di parametri dell'attività all'attività funzione Cloud Functions Functions. I parametri dell'attività sono coppie chiave-valore in cui Chiave è il nome della variabile di riferimento utilizzata nel file di origine della funzione Cloud Function e Valore è il nome della variabile di integrazione corrispondente a cui punta la variabile di riferimento. Puoi aggiungere uno o più parametri dell'attività nella sezione Parametri attività del riquadro di configurazione dell'attività.

Per accedere alle variabili di integrazione dalla Cloud Function, vengono utilizzati i seguenti metodi:

  • set: scrive il valore in una variabile.
  • get: legge il valore di una variabile.

Ad esempio, se hai una variabile di integrazione denominata EmployeeName che vuoi utilizzare nel file di origine della funzione Cloud Function, definisci i seguenti parametri dell'attività:

  • Chiave: EmployeeKey
  • Valore: EmployeeName

Lo script di esempio seguente mostra l'utilizzo delle funzioni set e get per accedere alle variabili di integrazione definite.

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

Strategia di gestione degli errori

Una strategia di gestione degli errori per un'attività specifica l'azione da eseguire se l'attività non riesce a causa di un errore temporaneo. Per informazioni su come utilizzare una strategia di gestione degli errori e per conoscere i diversi tipi di strategie di gestione degli errori, consulta l'articolo sulle strategie di gestione degli errori.