SMT로 주제 만들기

이 문서에서는 단일 메시지 변환 (SMT)을 사용하여 Pub/Sub 주제를 만드는 방법을 설명합니다.

주제 SMT를 사용하면 Pub/Sub 내에서 직접 메시지 데이터와 속성을 가볍게 수정할 수 있습니다. 이 기능을 사용하면 메시지가 주제에 게시되기 전에 데이터 정리, 필터링 또는 형식 변환을 할 수 있습니다.

SMT로 주제를 만들려면 Google Cloud 콘솔, Google Cloud CLI, 클라이언트 라이브러리, Pub/Sub API를 사용하면 됩니다.

시작하기 전에

필수 역할 및 권한

SMT로 주제를 만드는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 Pub/Sub 편집자 (roles/pubsub.editor) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 SMT로 주제를 만드는 데 필요한 권한이 포함되어 있습니다. 필요한 정확한 권한을 보려면 필수 권한 섹션을 펼치세요.

필수 권한

SMT로 주제를 만들려면 다음 권한이 필요합니다.

  • 프로젝트에 주제 만들기 권한을 부여합니다. pubsub.topics.create

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.

프로젝트 수준 및 개별 리소스 수준에서 액세스 제어를 구성할 수 있습니다.

SMT로 주제 만들기

SMT를 사용하여 주제를 만들기 전에 주제의 속성 문서를 검토하세요.

하나 이상의 SMT로 Pub/Sub를 만들려면 다음 단계를 수행하세요.

콘솔

  1. Google Cloud 콘솔에서 Pub/Sub 주제 페이지로 이동합니다.

    주제로 이동

  2. 주제 만들기를 클릭합니다.

  3. 주제 ID 필드에 주제의 ID를 입력합니다. 주제 이름 지정에 대한 자세한 내용은 이름 지정 가이드라인을 참고하세요.

  4. 변환에서 변환 추가를 클릭합니다.

  5. 함수 이름을 입력합니다. 예를 들면 redactSSN입니다.

  6. SMT가 즉시 활성화되지 않도록 하려면 변환 사용 중지를 선택합니다. 이 옵션을 선택하면 SMT가 주제와 함께 생성되지만 수신 메시지에서는 실행되지 않습니다. 주제가 생성된 후 주제를 수정하여 SMT를 사용 설정할 수 있습니다.

  7. 텍스트 영역에 SMT 코드를 입력합니다. 예를 들면 다음과 같습니다.

    function redactSSN(message, metadata) {
      const data = JSON.parse(message.data);
      delete data['ssn'];
      message.data = JSON.stringify(data);
      return message;
    }
    
  8. 선택사항입니다. SMT를 검사하려면 검사를 클릭합니다. SMT가 유효하면 "Validation passed" 메시지가 표시됩니다. 그렇지 않으면 오류 메시지가 표시됩니다.

  9. 변환을 추가하려면 변환 추가를 클릭하고 이전 단계를 반복합니다.

    SMT를 특정 순서로 정렬하려면 위로 이동 또는 아래로 이동을 클릭합니다. SMT를 삭제하려면 삭제를 클릭합니다.

  10. 선택사항입니다. 샘플 메시지에서 SMT를 테스트하려면 다음 단계를 수행하세요.

    1. 변환 테스트를 클릭합니다.

    2. 변환 테스트 창에서 테스트할 함수를 선택합니다.

    3. 메시지 입력 창에 샘플 메시지를 입력합니다.

    4. 메시지에 속성을 추가하려면 속성 추가를 클릭하고 속성의 키와 값을 입력합니다. 속성을 여러 개 추가할 수 있습니다.

    5. 테스트를 클릭합니다. 메시지에 SMT를 적용한 결과가 출력 메시지에 표시됩니다.

    6. 변환 테스트 창을 닫으려면 닫기를 클릭합니다.

    SMT를 두 개 이상 만드는 경우 다음과 같이 변환의 전체 시퀀스를 테스트할 수 있습니다.

    1. 이전 단계에 설명된 대로 시퀀스에서 첫 번째 SMT를 테스트합니다.
    2. 다음 SMT를 선택합니다. 입력 메시지는 이전 테스트의 출력 메시지로 미리 채워집니다.
    3. 전체 시퀀스가 예상대로 작동하는지 확인하기 위해 순서대로 SMT를 계속 테스트합니다.
  11. 만들기를 클릭하여 주제를 만듭니다.

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 하나 이상의 SMT를 정의하는 YAML 또는 JSON 파일을 만듭니다. SMT가 두 개 이상인 경우 나열된 순서대로 메시지에 실행됩니다.

    다음은 YAML 변환 파일의 예입니다.

    - javascriptUdf:
        code: >
            function redactSSN(message, metadata) {
              const data = JSON.parse(message.data);
              delete data['ssn'];
              message.data = JSON.stringify(data);
              return message;
            }
        functionName: redactSSN
    
  3. 선택사항입니다. SMT를 검증하려면 gcloud pubsub message-transforms validate 명령어를 실행합니다.

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

    다음을 바꿉니다.

    • TRANSFORM_FILE: 단일 SMT를 정의하는 YAML 또는 JSON 파일의 경로입니다. SMT를 여러 개 만드는 경우 개별적으로 검증해야 합니다.
  4. 선택사항입니다. 샘플 Pub/Sub 메시지에서 하나 이상의 SMT를 테스트하려면 gcloud pubsub message-transforms test 명령어를 실행합니다.

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

    다음을 바꿉니다.

    • TRANSFORMS_FILE: 하나 이상의 SMT를 정의하는 YAML 또는 JSON 파일의 경로입니다.
    • MESSAGE: 샘플 메시지의 본문입니다.
    • ATTRIBUTES: 선택사항. 메시지 속성의 쉼표로 구분된 목록입니다. 각 속성은 KEY="VALUE"로 형식이 지정된 키-값 쌍입니다.

    이 명령어는 각 SMT의 출력을 다음 SMT의 입력으로 사용하여 SMT를 순서대로 실행합니다. 명령어는 각 단계의 결과를 출력합니다.

  5. 주제를 만들려면 gcloud pubsub topics create 명령어를 실행합니다.

    gcloud pubsub topics create TOPIC_ID \
      --message-transforms-file=TRANSFORMS_FILE
    

    다음을 바꿉니다.

    • TOPIC_ID: 만들려는 주제의 ID 또는 이름입니다. 주제 이름 지정에 관한 가이드라인은 리소스 이름을 참고하세요. 주제 이름은 변경할 수 없습니다.
    • TRANSFORMS_FILE: 하나 이상의 SMT를 정의하는 YAML 또는 JSON 파일의 경로입니다.
  6. 자바

    이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 Java 설정 안내를 따르세요. 자세한 내용은 Pub/Sub 자바 API 참조 문서를 참조하세요.

    
    import com.google.api.gax.rpc.AlreadyExistsException;
    import com.google.cloud.pubsub.v1.TopicAdminClient;
    import com.google.pubsub.v1.JavaScriptUDF;
    import com.google.pubsub.v1.MessageTransform;
    import com.google.pubsub.v1.Topic;
    import com.google.pubsub.v1.TopicName;
    import java.io.IOException;
    
    public class CreateTopicWithSmtExample {
    
      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";
    
        createTopicWithSmtExample(projectId, topicId);
      }
    
      public static void createTopicWithSmtExample(String projectId, String topicId)
          throws IOException {
        TopicName topicName = TopicName.of(projectId, topicId);
    
        // 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 (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
    
          Topic topic =
              topicAdminClient.createTopic(
                  Topic.newBuilder()
                      .setName(topicName.toString())
                      // Add the UDF message transform
                      .addMessageTransforms(transform)
                      .build());
    
          System.out.println("Created topic with SMT: " + topic.getName());
        } catch (AlreadyExistsException e) {
          System.out.println(topicName + "already exists.");
        }
      }
    }

    Python

    이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 Python 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Python API 참조 문서를 참조하세요.

    from google.cloud import pubsub_v1
    from google.pubsub_v1.types import JavaScriptUDF, MessageTransform, Topic
    
    # TODO(developer)
    # project_id = "your-project-id"
    # topic_id = "your-topic-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)]
    
    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(project_id, topic_id)
    
    request = Topic(name=topic_path, message_transforms=transforms)
    
    topic = publisher.create_topic(request=request)
    
    print(f"Created topic: {topic.name} with SMT")

    Go

    다음 샘플에서는 Go Pub/Sub 클라이언트 라이브러리의 주요 버전 (v2)을 사용합니다. 아직 v1 라이브러리를 사용하고 있다면 v2로의 마이그레이션 가이드를 참고하세요. v1 코드 샘플 목록을 보려면 지원 중단된 코드 샘플을 참고하세요.

    이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 Go 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Go API 참고 문서를 참조하세요.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	"cloud.google.com/go/pubsub/v2"
    	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
    )
    
    // createTopicWithSMT creates a topic with a single message transform function applied.
    func createTopicWithSMT(w io.Writer, projectID, topicID string) error {
    	// projectID := "my-project-id"
    	// topicID := "my-topic"
    	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,
    			},
    		},
    	}
    
    	topic := &pubsubpb.Topic{
    		Name:              fmt.Sprintf("projects/%s/topics/%s", projectID, topicID),
    		MessageTransforms: []*pubsubpb.MessageTransform{transform},
    	}
    
    	topic, err = client.TopicAdminClient.CreateTopic(ctx, topic)
    	if err != nil {
    		return fmt.Errorf("CreateTopic: %w", err)
    	}
    
    	fmt.Fprintf(w, "Created topic with message transform: %v\n", topic)
    	return nil
    }
    

다음 단계