Google Cloud Functions in C#

1. Introduzione

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

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

  • Framework di Functions per .NET.
  • Come scrivere una funzione HTTP.
  • Come scrivere una funzione attivata da eventi che risponda agli eventi 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 del progetto è il nome visualizzato per i partecipanti al 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 tua informazione, esiste un terzo valore, un Numero 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 generare costi oltre questo tutorial, puoi eliminare le risorse che hai creato o l'intero progetto. I nuovi utenti di Google Cloud possono partecipare al programma Prova senza costi di 300$.

Avvia Cloud Shell

Sebbene Google Cloud possa 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 contiene tutti gli strumenti di sviluppo di cui avrai bisogno. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione di rete. Tutto il lavoro in questo codelab può essere svolto in un browser. Non devi 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

Imposta la 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

Poi, concedi 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 che vengono eseguite in molti ambienti diversi, tra cui:

  • Funzioni 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 che risponde alle richieste HTTP.

Crea una funzione HTTP utilizzando il modello gcf-http:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

Viene creato un progetto e un file Function.cs che risponde 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 su Cloud Run, esegui il seguente 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 eseguita il deployment della funzione, puoi invocarla 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 che risponde agli eventi di Google Cloud Storage (GCS).

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

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

Viene creato un progetto e un file Function.cs che risponde alle richieste 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 l'attivatore 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 2ª gen., puoi utilizzare il seguente comando 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 in Cloud Console:

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 l'attivatore 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 in Cloud Console:

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 - Senza tipo

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 l'attivatore 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 2ª gen., puoi utilizzare il seguente comando 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 2ª 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

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