Google Cloud Functions in C#

1. Introduzione

Funzioni di Google Cloud Run è una piattaforma di serverless computing basata su eventi. Le funzioni di Cloud Run ti consentono di scrivere il codice senza preoccuparti del provisioning delle risorse o della scalabilità per gestire i requisiti mutevoli.

Esistono due tipi di funzioni Cloud Run:

  • Le funzioni HTTP rispondono alle richieste HTTP.
  • Le funzioni evento vengono attivate da eventi, ad esempio la pubblicazione di un messaggio in Cloud Pub/Sub o il caricamento di un file in Cloud Storage.

efb3268e3b74ed4f.png

Questo codelab ti guiderà nella creazione delle tue funzioni Cloud Run in C#. Nello specifico, eseguirai il deployment di funzioni C# che rispondono a HTTP e CloudEvents da varie origini Google Cloud.

Obiettivi didattici

  • di Functions per .NET.
  • Come scrivere una funzione HTTP.
  • Come scrivere una funzione attivata da eventi in risposta agli eventi di Cloud Storage.
  • Come scrivere una funzione attivata da eventi che risponda agli eventi Cloud Pub/Sub.
  • Come scrivere una funzione attivata da evento che risponda a qualsiasi tipo di evento.

2. Configurazione e requisiti

Configurazione dell'ambiente a tuo ritmo

  1. Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Il Nome progetto è il nome visualizzato dei partecipanti del progetto. Si tratta di una stringa di caratteri non utilizzata dalle API di Google. Puoi aggiornarlo in qualsiasi momento.
  • L'ID progetto deve essere univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). La console Cloud genera automaticamente una stringa univoca; in genere non è importante quale sia. Nella maggior parte dei codelab, dovrai fare riferimento all'ID progetto (in genere identificato come PROJECT_ID). Se l'ID generato non ti piace, puoi generarne un altro casuale. In alternativa, puoi provare il tuo e vedere se è disponibile. Non può essere modificato dopo questo passaggio e rimarrà invariato per tutta la durata del progetto.
  • Per informazione, c'è un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, dovrai abilitare la fatturazione nella console Cloud per utilizzare le API/risorse Cloud. L'esecuzione di questo codelab non dovrebbe costare molto, se non del tutto. Per arrestare le risorse in modo da non incorrere in fatturazione oltre questo tutorial, puoi eliminare le risorse che hai creato o l'intero progetto. I nuovi utenti di Google Cloud sono idonei al programma prova senza costi di 300$.

Avvia Cloud Shell

Anche se Google Cloud può essere utilizzato da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.

Nella console Google Cloud, fai clic sull'icona di Cloud Shell nella barra degli strumenti in alto a destra:

55efc1aaa7a4d3ad.png

Dovrebbe richiedere solo pochi istanti per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere qualcosa di simile a questo:

7ffe5cbb04455448.png

Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Tutto il lavoro in questo codelab può essere svolto all'interno di un browser. Non occorre installare nulla.

3. Prima di iniziare

In Cloud Shell, esegui il seguente comando per abilitare i servizi richiesti:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  run.googleapis.com

Ora imposta la tua regione.

REGION=<YOUR_REGION>

Per questo codelab, creerai un account di servizio con le autorizzazioni EventArc richieste e il ruolo Invoker di Cloud Run per ricevere un evento da Cloud Storage e richiamare la funzione Cloud Run.

Crea innanzitutto l'account di servizio.

PROJECT_ID=$(gcloud config get-value core/project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

SERVICE_ACCOUNT="cloud-run-functions"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run functions Eventarc service account"

Quindi, concedi il ruolo Event Receiver di Eventarc (roles/eventarc.eventReceiver) nel progetto all'account di servizio associato all'trigger Eventarc in modo che l'trigger possa ricevere eventi dai fornitori di eventi.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/eventarc.eventReceiver

Concedi quindi all'account di servizio il ruolo Invoker di Cloud Run in modo che possa richiamare la funzione.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

4. Framework di funzioni per .NET

Functions Framework for .NET è un framework FaaS (Functions as a Service) open source per scrivere funzioni .NET portatili, offerto dal team di Google Cloud Functions.

Il framework di Functions ti consente di scrivere funzioni leggere eseguite in molti ambienti diversi, tra cui:

  • Funzioni di Google Cloud Run
  • La tua macchina di sviluppo locale
  • Cloud Run e Cloud Run su GKE
  • Ambienti basati su Knative

In questo codelab utilizzerai Functions Framework for .NET e i relativi modelli per creare ed eseguire il deployment di Cloud Functions in C#.

In Cloud Shell, esegui il seguente comando per installare i modelli Cloud Functions per dotnet:

dotnet new install Google.Cloud.Functions.Templates

Verranno installati 3 modelli per dotnet. Ogni modello è disponibile in C#, F# e VB (ma in questo lab utilizzerai solo C#). Per verificare che i modelli siano installati, esegui il seguente comando:

dotnet new list

Templates                                                 Short Name            
-----------------------------------------------------------------------
Google Cloud Functions CloudEvent Function                gcf-event
Google Cloud Functions CloudEvent Function (Untyped)      gcf-untyped-event
Google Cloud Functions HttpFunction                       gcf-http

5. Funzione HTTP

Creerai ed eseguirai il deployment di una funzione HTTP in risposta alle richieste HTTP.

Crea una funzione HTTP utilizzando il modello gcf-http:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

Vengono creati un progetto e un file Function.cs che rispondono alle richieste HTTP.

Modifica il framework target in net8.0 nel file .csproj:

<TargetFramework>net8.0</TargetFramework>

Per eseguire il deployment di una funzione Cloud Run direttamente in Cloud Run, esegui questo comando:

gcloud beta run deploy hello-http-function \
    --source . \
    --function HelloHttp.Function \
    --base-image dotnet8 \
    --region $REGION \
    --allow-unauthenticated

Se preferisci eseguire il deployment come Cloud Functions 2ª gen., utilizza il seguente comando:

gcloud functions deploy hello-http-function \
    --allow-unauthenticated \
    --entry-point HelloHttp.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-http

Una volta eseguito il deployment della funzione, puoi richiamarla utilizzando il seguente comando curl:

SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)')

curl $SERVICE_URL

6. Funzione CloudEvent - GCS

Creerai ed eseguirai il deployment di una funzione CloudEvent in risposta agli eventi di Google Cloud Storage (GCS).

Innanzitutto, crea un bucket Cloud Storage. Questo è il bucket da cui ascolterai gli eventi in seguito:

BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

Crea una funzione CloudEvent utilizzando il modello gcf-event:

cd ..
mkdir HelloGcs
cd HelloGcs
dotnet new gcf-event

Vengono creati un progetto e un file Function.cs che rispondono alle richieste di CloudEvent. Analizza inoltre i dati di CloudEvent in StorageObjectData.

Modifica il framework target in net8.0 nel file .csproj:

<TargetFramework>net8.0</TargetFramework>

Per eseguire il deployment di una funzione Cloud Run direttamente in Cloud Run, devi prima eseguire il deployment della funzione e poi creare un trigger per la funzione.

gcloud beta run deploy hello-gcs-function \
      --source . \
      --function HelloGcs.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Ora crea il trigger per la funzione Cloud Run

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-gcs-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-gcs-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

Se preferisci eseguire il deployment come Cloud Functions (2a gen), puoi utilizzare il comando seguente per eseguire il deployment della funzione utilizzando i flag trigger-event e trigger-resource:

gcloud functions deploy hello-gcs-function \
    --allow-unauthenticated \
    --entry-point HelloGcs.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --service-account=$SERVICE_ACCOUNT_ADDRESS

Dopo un paio di minuti, la funzione dovrebbe essere visibile nella console Cloud:

c28654d74bb31420.png

Attiva la funzione caricando un file nel bucket di archiviazione:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Verifica che la funzione sia stata attivata leggendo i log:

Per una funzione Cloud Run, puoi eseguire questo comando:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Per una funzione di 2ª generazione, puoi eseguire questo comando:

gcloud functions logs read hello-gcs-function \
    --gen2 \
    --region us-central1

7. Funzione CloudEvent - Pub/Sub

Creerai ed eseguirai il deployment di una funzione CloudEvent che risponde agli eventi Cloud Pub/Sub.

Innanzitutto, crea un argomento Cloud Pub/Sub che emette eventi:

TOPIC_NAME=cloud-functions-topic
gcloud pubsub topics create ${TOPIC_NAME}

Crea una funzione CloudEvent utilizzando il modello gcf-event:

cd ..
mkdir HelloPubSub
cd HelloPubSub
dotnet new gcf-event

Viene creato un progetto e un file Function.cs che risponde alle richieste CloudEvent. Inoltre, analizza i dati di CloudEvent in StorageObjectData per impostazione predefinita.

Modifica il framework target in net8.0 nel file .csproj:

<TargetFramework>net8.0</TargetFramework>

Modifica StorageObjectData in MessagePublishedData per analizzare i messaggi Pub/Sub. Google.Events.Protobuf.Cloud.Storage.V1 modificato in Google.Events.Protobuf.Cloud.PubSub.V1.

Alla fine, la funzione dovrebbe avere il seguente aspetto:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.PubSub.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloPubSub;

public class Function : ICloudEventFunction<MessagePublishedData>
{
    public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
    {
        var nameFromMessage = data.Message?.TextData;
        var name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
        Console.WriteLine($"Hello {name}");
        return Task.CompletedTask;
    }
}

Per eseguire il deployment di una funzione Cloud Run direttamente in Cloud Run, devi prima eseguire il deployment della funzione e poi creare un trigger per la funzione.

gcloud beta run deploy hello-pubsub-function \
      --source . \
      --function HelloPubSub.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated \
      --service-account=$SERVICE_ACCOUNT_ADDRESS

Ora crea il trigger per la funzione Cloud Run

gcloud eventarc triggers create my-pubsub-trigger \
    --location=$REGION \
    --service-account=$SERVICE_ACCOUNT_ADDRESS \
    --destination-run-service=hello-pubsub-function \
    --destination-run-region=$REGION \
    --destination-run-path="/" \
    --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
    --transport-topic=projects/$PROJECT_ID/topics/$TOPIC_NAME

Se preferisci eseguire il deployment come Cloud Functions 2ª gen., puoi utilizzare il seguente comando per eseguire il deployment della funzione utilizzando il flag trigger-topic:

gcloud functions deploy hello-pubsub-function \
    --allow-unauthenticated \
    --entry-point HelloPubSub.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-topic ${TOPIC_NAME}

Dopo un paio di minuti, la funzione dovrebbe essere visibile nella console Cloud:

3443808da7caf3bc.png

Attiva la funzione pubblicando un messaggio nell'argomento:

gcloud pubsub topics publish ${TOPIC_NAME} --message="World"

Verifica che la funzione sia stata attivata leggendo i log.

Per una funzione Cloud Run, puoi eseguire questo comando:

gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json

Per una funzione di 2ª generazione, puoi eseguire questo comando:

gcloud functions logs read hello-pubsub-function \
    --gen2 \
    --region us-central1

8. Funzione CloudEvent - Non digitata

Se stai conducendo esperimenti con CloudEvents e non hai ancora un modello di dati del payload a cui vuoi eseguire il commit o vuoi che la tua funzione possa gestire qualsiasi evento Cloud, puoi utilizzare una funzione CloudEvent non tipizzata.

Crea una funzione CloudEvent utilizzando il modello gcf-untyped-event:

cd ..
mkdir HelloUntyped
cd HelloUntyped
dotnet new gcf-untyped-event

Vengono creati un progetto e un file Function.cs che risponde alle richieste CloudEvent senza alcun tentativo di analizzare i dati del CloudEvent.

Modifica il framework target in net8.0 nel file .csproj:

<TargetFramework>net8.0</TargetFramework>

Per eseguire il deployment di una funzione Cloud Run direttamente in Cloud Run, devi prima eseguire il deployment della funzione e poi creare un trigger per la funzione.

gcloud beta run deploy hello-untyped-function \
      --source . \
      --function HelloUntyped.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Ora crea il trigger per la funzione Cloud Run

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-untyped-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-untyped-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

Se preferisci eseguire il deployment come Cloud Functions (2a gen), puoi utilizzare il comando seguente per eseguire il deployment della funzione utilizzando i flag trigger-event e trigger-resource:

gcloud functions deploy hello-untyped-function \
    --allow-unauthenticated \
    --entry-point HelloUntyped.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME}

La funzione viene attivata quando un file viene caricato in un bucket di archiviazione.

Dopo un paio di minuti, la funzione dovrebbe essere visibile in Cloud Console:

afe56530826787c6.png

Attiva la funzione caricando un file nel bucket di archiviazione:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Verifica che la funzione sia stata attivata leggendo i log.

Per una funzione Cloud Run, puoi eseguire questo comando:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Per una funzione di 2a generazione, puoi eseguire questo comando:

gcloud functions logs read hello-untyped-function \
    --gen2 \
    --region us-central1

9. Complimenti!

Complimenti per aver completato il codelab.

Argomenti trattati

  • di Functions per .NET.
  • Come scrivere una funzione Cloud HTTP.
  • Come scrivere una funzione CloudEvent in risposta agli eventi Cloud Storage.
  • Come scrivere una funzione CloudEvent in risposta agli eventi Cloud Pub/Sub.
  • Come scrivere una funzione CloudEvent che risponda a qualsiasi tipo di evento.