Como testar localmente uma Google Cloud Function com trigger de tópico PubSub

Estou trabalhando em um projeto de monitoramento de dados com Google Cloud Functions e, para agilizar e evitar custos desnecessários, queria testar a ativação de uma GCF com um gatilho de evento (tópico no PubSub)

O primeiro passo é iniciar o emulador de PubSub, nesse caso ele vai rodar na porta 8043, para o projeto odesenvolvedor

Criando um emulador do PubSub

gcloud beta emulators pubsub start \
    --project=odesenvolvedor \
    --host-port='localhost:8043'Code language: JavaScript (javascript)

É esperado que você veja no terminal o log do emulador, com alguns detalhes da exeução e indicando que ele está rodando e em qual porta:

[pubsub] INFO: Server started, listening on 8043Code language: CSS (css)

Você vai precisar criar um tópico, em outro terminal execute:

curl -s -X PUT 'http://localhost:8043/v1/projects/odesenvolvedor/topics/mytopic'Code language: JavaScript (javascript)

Agora vamos especificar o endpoint de assinatura do push

curl -s -X PUT 'http://localhost:8043/v1/projects/odesenvolvedor/subscriptions/mysub' \
    -H 'Content-Type: application/json' \
    --data '{"topic":"projects/odesenvolvedor/topics/mytopic","pushConfig":{"pushEndpoint":"http://localhost:8080/projects/odesenvolvedor/topics/mytopic"}}'Code language: JavaScript (javascript)

Enviando uma mensagem para o PubSub

Com o emulador rodando você pode disparar novas mensagens fazendo um post para o emulador (no nosso exmeplo, localhost:8043) indicando o projeto, tópico e ação.

Para publicar uma mensagem no terminal, você pode usar o comando abaixo, lembrando que o data da mensagem deve estar codificado em base64.

curl -s -X POST 'http://localhost:8043/v1/projects/odesenvolvedor/topics/mytopic:publish' \
    -H 'Content-Type: application/json' \
    --data '{"messages":[{"data":"eyJmb28iOiJiYXIifQ=="}]}'Code language: JavaScript (javascript)

Você também pode usar uma ferramenta como Postman para fazer os envios, configurando método como POST, a url como http://localhost:8043/v1/projects/odesenvolvedor/topics/mytopic:publish e o tipo de conteúdo como application/json, enviando a mensagem no corpo do post.

Rodando uma Cloud Function local que escute o evento

Antes de criar a função, você precisa definir as variáveis de ambiente para que sua função utilize o PubSub do emulador e não tente se conectar ao PubSub da Google Cloud, para isso execute o comando abaixo, trocando o id do projeto:

gcloud beta emulators pubsub env-init
export PUBSUB_EMULATOR_HOST=[::1]:8432
export PUBSUB_PROJECT_ID=odesenvolvedorCode language: JavaScript (javascript)

Com o emulador rodando e sabendo como enviar uma mensagem para um tópico, falta apenas criarmos uma função que ouça o tópico.

Crie a função na sua linguagem favorita, no exemplo abaixo uma função em Python:

import json
import base64

def minha_gcf(event, _context = None):
    payload = base64.b64decode(event['data']).decode('utf-8')
    payload = json.loads(payload)
    print(payload)
    return "OK"Code language: JavaScript (javascript)

Agora é só rodar esta função localmente, avisando que ela deve ouvir os eventos do PubSub:

functions_framework --debug --port 8080 --target=minha_gcf --signature-type=event

O importante aí é o –signature-type=event, mesmo sendo uma função local rodando na porta 8080 ela irá escutar os eventos do PubSub

Ao enviar novas mensagens para seu emulador do PubSub, sua função será executada.