Criar uma assinatura com SMTs

Este documento explica como criar uma assinatura do Pub/Sub com transformações de mensagem única (SMTs, na sigla em inglês).

As SMTs de assinatura permitem modificações leves nos dados e atributos das mensagens diretamente no Pub/Sub. Esse recurso permite a limpeza, filtragem ou conversão de formato de dados antes que as mensagens sejam entregues a um cliente assinante.

Para criar uma assinatura com SMTs, use o Google Cloud console, a Google Cloud CLI, a biblioteca de cliente ou a API Pub/Sub.

Antes de começar

Papéis e permissões necessárias

Para receber as permissões necessárias para criar uma assinatura com SMTs, peça ao administrador para conceder a você o papel do IAM de editor do Pub/Sub (roles/pubsub.editor) no projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Esse papel predefinido contém as permissões necessárias para criar uma assinatura com SMTs. Para acessar as permissões exatas que são necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

As seguintes permissões são necessárias para criar uma assinatura com SMTs:

  • Conceda a permissão de criar uma assinatura no projeto: pubsub.subscriptions.create

Essas permissões também podem ser concedidas com papéis personalizados ou outros papéis predefinidos.

Dependendo do tipo de assinatura, você pode precisar de permissões adicionais. Para conferir a lista exata de permissões, consulte o documento que discute a criação da assinatura específica. Por exemplo, se você estiver criando uma assinatura do BigQuery com SMTs, consulte Criar assinaturas do BigQuery.

Se você criar uma assinatura em um projeto diferente do tópico, conceda o papel roles/pubsub.subscriber ao principal do projeto que contém a assinatura no projeto que contém o tópico.

É possível configurar o controle de acesso no nível do projeto e no nível do recurso individual.

Criar uma assinatura com SMTs

Antes de criar uma assinatura com SMTs, consulte a documentação para Propriedades de uma assinatura.

Para criar uma assinatura do Pub/Sub com uma ou mais SMTs, siga estas etapas. É possível ativar até cinco SMTs por assinatura.

Console

  1. No Google Cloud console, acesse a página Assinaturas do Pub/Sub.

    Acessar "Assinaturas"

  2. Clique em Criar assinatura.

  3. No campo ID da assinatura, insira um ID para a assinatura. Para mais informações sobre como nomear assinaturas, consulte as diretrizes de nomenclatura.

  4. Em Transformações, clique em Adicionar uma transformação.

  5. Selecione o Tipo de transformação. Para mais informações sobre os tipos de SMT compatíveis, consulte Tipos de SMTs.

  6. Defina as propriedades de configuração da SMT. O conjunto de propriedades depende do tipo de SMT. Para mais informações, consulte a documentação desse tipo de SMT.

  7. Opcional. Para validar a SMT, clique em Validar. Se a SMT for válida, a mensagem "Validation passed" será exibida. Caso contrário, uma mensagem de erro será mostrada.

  8. Para adicionar outra transformação, clique em Adicionar uma transformação e repita as etapas anteriores.

    Para organizar as SMTs em uma ordem específica, clique em Mover para cima ou Mover para baixo. Para remover uma SMT, clique em Excluir.

  9. Opcional. Para testar uma SMT em uma mensagem de amostra, siga estas etapas:

    1. Clique em Testar transformações.

    2. Na janela Testar transformação, selecione a função que você quer testar.

    3. Na janela Mensagem de entrada, insira uma mensagem de amostra.

    4. Para adicionar um atributo à mensagem, clique em Adicionar um atributo e insira a chave e o valor do atributo. É possível adicionar vários atributos.

    5. Clique em Teste. O resultado da aplicação da SMT na mensagem é mostrado em Mensagem de saída.

    6. Para fechar a janela Testar transformações, clique em Fechar.

    Se você criar mais de uma SMT, poderá testar toda a sequência de transformações da seguinte maneira:

    1. Teste a primeira SMT na sequência, conforme descrito nas etapas anteriores.
    2. Selecione a próxima SMT. A mensagem de entrada é preenchida previamente com a mensagem de saída do teste anterior.
    3. Continue testando as SMTs em ordem para garantir que toda a sequência funcione conforme o esperado.
  10. Clique em Criar para criar a assinatura.

gcloud

  1. No Google Cloud console, ative o Cloud Shell.

    Ativar o Cloud Shell

    Na parte de baixo do Google Cloud console, uma sessão do Cloud Shell é iniciada e exibe um prompt de linha de comando. O Cloud Shell é um ambiente shell com a Google Cloud CLI já instalada e com valores já definidos para o projeto atual. A inicialização da sessão pode levar alguns segundos.

  2. Crie um arquivo YAML ou JSON que defina uma ou mais SMTs. A definição YAML ou JSON depende do tipo de SMT. Para mais informações, consulte Tipos de SMTs.

    Se o arquivo incluir mais de uma SMT, o Pub/Sub as executará na ordem listada.

  3. Opcional. Para validar uma SMT, execute o gcloud pubsub message-transforms validate comando:

    gcloud pubsub message-transforms validate \
      --message-transform-file=TRANSFORM_FILE
    

    Substitua:

    • TRANSFORM_FILE: o caminho para um arquivo YAML ou JSON que define uma única SMT. Se você estiver criando várias SMTs, valide-as individualmente.
  4. Opcional. Para testar uma ou mais SMTs em uma mensagem de amostra do Pub/Sub execute o gcloud pubsub message-transforms test comando:

    gcloud pubsub message-transforms test \
      --message-transforms-file=TRANSFORMS_FILE \
      --message=MESSAGE \
      --attribute=ATTRIBUTES
    

    Substitua:

    • TRANSFORMS_FILE: o caminho para um arquivo YAML ou JSON que define uma ou mais SMTs.
    • MESSAGE: o corpo da mensagem de amostra.
    • ATTRIBUTES: opcional. Uma lista separada por vírgulas de atributos de mensagem. Cada atributo é um par de chave-valor formatado como KEY="VALUE".

    O comando executa as SMTs em ordem, usando a saída de cada SMT como entrada para a próxima. O comando gera os resultados de cada etapa.

  5. Para criar a assinatura, execute o gcloud pubsub subscriptions create comando:

    gcloud pubsub subscriptions create SUBSCRIPTION_ID \
        --topic=projects/PROJECT_ID/topics/TOPIC_ID \
        --message-transforms-file=TRANSFORMS_FILE
    

    Substitua:

    • SUBSCRIPTION_ID: o ID ou nome da assinatura que você quer criar. Para diretrizes sobre como nomear uma assinatura, consulte Nomes de recursos. O nome de uma assinatura é imutável.

    • PROJECT_ID: o ID do projeto que contém o tópico.

    • TOPIC_ID: o ID do tópico a que você quer se inscrever.

    • TRANSFORMS_FILE: o caminho para um arquivo YAML ou JSON que define uma ou mais SMTs.

C#

Antes de tentar esse exemplo, siga as instruções de configuração do C# em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C# .


using Google.Cloud.PubSub.V1;
using System;

public class CreateSubscriptionWithSingleMessageTransformSample
{
    public Subscription CreateSubscriptionWithSingleMessageTransform(string projectId, string topicId, string subscriptionId)
    {
        SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
        TopicName topicName = TopicName.FromProjectTopic(projectId, topicId);

        SubscriptionName subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);
        MessageTransform removeSSNTransform = new MessageTransform
        {
            JavascriptUdf = new JavaScriptUDF
            {
                FunctionName = "redactSsn",
                Code = "function redactSsn(message, metadata) {"
                + "   const data = JSON.parse(message.data);"
                + "   delete data['ssn'];"
                + "   message.data = JSON.stringify(data);"
                + "   return message;"
                + "}"
            },
        };

        var subscription = subscriber.CreateSubscription(new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            MessageTransforms = { removeSSNTransform },
        });
        Console.WriteLine($"Subscription {subscription.Name} created with SMT.");

        return subscription;
    }
}

Java

Antes de tentar essa amostra, siga as instruções de configuração do Java em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub para Java (em inglês).

import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.JavaScriptUDF;
import com.google.pubsub.v1.MessageTransform;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.Subscription;
import java.io.IOException;

public class CreateSubscriptionWithSmtExample {
  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String topicId = "your-topic-id";
    String subscriptionId = "your-subscription-id";

    createSubscriptionWithSmtExample(projectId, topicId, subscriptionId);
  }

  public static void createSubscriptionWithSmtExample(
      String projectId, String topicId, String subscriptionId) throws IOException {

    // UDF that removes the 'ssn' field, if present
    String code =
        "function redactSSN(message, metadata) {"
            + "  const data = JSON.parse(message.data);"
            + "  delete data['ssn'];"
            + "  message.data = JSON.stringify(data);"
            + "  return message;"
            + "}";
    String functionName = "redactSSN";

    JavaScriptUDF udf =
        JavaScriptUDF.newBuilder().setCode(code).setFunctionName(functionName).build();
    MessageTransform transform = MessageTransform.newBuilder().setJavascriptUdf(udf).build();

    try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {

      ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
      ProjectSubscriptionName subscriptionName =
          ProjectSubscriptionName.of(projectId, subscriptionId);

      Subscription subscription =
          subscriptionAdminClient.createSubscription(
              Subscription.newBuilder()
                  .setName(subscriptionName.toString())
                  .setTopic(topicName.toString())
                  // Add the UDF message transform
                  .addMessageTransforms(transform)
                  .build());

      System.out.println("Created subscription with SMT: " + subscription.getAllFields());
    }
  }
}

Python

Antes de tentar esse exemplo, siga as instruções de configuração do Python em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Pub/Sub.

from google.cloud import pubsub_v1
from google.pubsub_v1.types import JavaScriptUDF, MessageTransform

# TODO(developer): Choose an existing topic.
# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"

publisher = pubsub_v1.PublisherClient()
subscriber = pubsub_v1.SubscriberClient()
topic_path = publisher.topic_path(project_id, topic_id)
subscription_path = subscriber.subscription_path(project_id, subscription_id)

code = """function redactSSN(message, metadata) {
            const data = JSON.parse(message.data);
            delete data['ssn'];
            message.data = JSON.stringify(data);
            return message;
            }"""
udf = JavaScriptUDF(code=code, function_name="redactSSN")
transforms = [MessageTransform(javascript_udf=udf)]

with subscriber:
    subscription = subscriber.create_subscription(
        request={
            "name": subscription_path,
            "topic": topic_path,
            "message_transforms": transforms,
        }
    )
    print(f"Created subscription with SMT: {subscription}")

Go

O exemplo a seguir usa a versão principal da biblioteca de cliente do Go Pub/Sub (v2). Se você ainda estiver usando a biblioteca v1, consulte o guia de migração para a v2. Para conferir uma lista de exemplos de código v1, consulte os exemplos de código obsoletos.

Antes de tentar esse exemplo, siga as instruções de configuração do Go em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Go.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub/v2"
	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
)

// createSubscriptionWithSMT creates a subscription with a single message transform function applied.
func createSubscriptionWithSMT(w io.Writer, projectID, topicID, subID string) error {
	// projectID := "my-project-id"
	// topicID := "my-topic"
	// subID := "my-sub"
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	code := `function redactSSN(message, metadata) {
			const data = JSON.parse(message.data);
			delete data['ssn'];
			message.data = JSON.stringify(data);
			return message;
		}`

	transform := &pubsubpb.MessageTransform{
		Transform: &pubsubpb.MessageTransform_JavascriptUdf{
			JavascriptUdf: &pubsubpb.JavaScriptUDF{
				FunctionName: "redactSSN",
				Code:         code,
			},
		},
	}

	sub := &pubsubpb.Subscription{
		Name:              fmt.Sprintf("projects/%s/subscriptions/%s", projectID, subID),
		Topic:             fmt.Sprintf("projects/%s/topics/%s", projectID, topicID),
		MessageTransforms: []*pubsubpb.MessageTransform{transform},
	}
	sub, err = client.SubscriptionAdminClient.CreateSubscription(ctx, sub)
	if err != nil {
		return fmt.Errorf("CreateSubscription: %w", err)
	}
	fmt.Fprintf(w, "Created subscription with message transform: %v\n", sub)
	return nil
}

Como as SMTs interagem com outros recursos de assinatura

Considere os seguintes pontos ao usar uma SMT de assinatura.

Filtragem

Se a assinatura usar SMTs e filtros integrados do Pub/Sub, o filtro será aplicado antes da SMT. Isso tem as seguintes implicações:

  • Se a SMT alterar os atributos da mensagem, o filtro do Pub/Sub não será aplicado ao novo conjunto de atributos.
  • A SMT não será aplicada a mensagens filtradas pelo filtro do Pub/Sub.
  • Se a SMT filtrar mensagens, esteja ciente do impacto no monitoramento do backlog de assinaturas.
  • Se você conectar uma assinatura a um pipeline do Dataflow, não use uma SMT de assinatura para filtrar mensagens, porque isso interrompe o escalonamento automático do Dataflow.

Ordenação das mensagens

Se você definir uma SMT em uma assinatura que tenha a ordenação ativada e a execução da SMT gerar um erro, as mensagens subsequentes para a mesma chave de ordenação não serão entregues ao assinante. Para evitar esse problema, configure um tópico de mensagens inativas na assinatura para remover a mensagem não processada do backlog de mensagens.

A seguir