适用于 Java 的 Google Cloud Pub/Sub 客户端库不使用本地模拟器

Kak*_*aji 5 java scala google-cloud-platform google-cloud-pubsub

我正在尝试使用 Google 云 Pub/Sub 模拟器来测试我的 scala 应用程序。文件说明如下 -

\n\n
\n

运行 env-init 命令确定并设置模拟器使用的环境变量。请注意,按照这些说明操作后,代码中的 Google Cloud Pub/Sub 客户端库将调用在本地实例中运行的 API,而不是生产 API。

\n
\n\n

但是,当我发布消息或创建主题时,它会在云中执行,而不是在本地模拟器上执行。println(s"ENV: ${sys.env("PUBSUB_EMULATOR_HOST")}")我已确认使用which prints正确设置了环境变量ENV: localhost:8085

\n\n

我尝试强制库使用我的本地设置,如下所示

\n\n
val settings = TopicAdminSettings.defaultBuilder()\n  .setChannelProvider(InstantiatingChannelProvider.newBuilder()\n    .setEndpoint("localhost:8085")\n      .setCredentialsProvider(TopicAdminSettings.defaultCredentialsProviderBuilder().build())\n    .build())\n  .build()\n\nval topicAdminClient = TopicAdminClient.create(settings)\ntopicAdminClient.createTopic(topicName)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样我成功地将请求发送到我的本地设置,但这会导致以下错误 -

\n\n
[pubsub] 6 14, 2017 2:49:11 \xe5\x8d\x88\xe5\xbe\x8c io.gapi.emulators.grpc.GrpcServer$3 operationComplete\n[pubsub] INFO: Adding handler(s) to newly registered Channel.\n[pubsub] 6 14, 2017 2:49:11 \xe5\x8d\x88\xe5\xbe\x8cio.gapi.emulators.netty.HttpVersionRoutingHandler channelRead\n[pubsub] INFO: Detected non-HTTP/2 connection.\n[pubsub] 6 14, 2017 2:49:11 \xe5\x8d\x88\xe5\xbe\x8c io.gapi.emulators.netty.NotFoundHandler handleRequest\n[pubsub] INFO: Unknown request URI: /bad-request\n[pubsub] 6 14, 2017 2:49:35 \xe5\x8d\x88\xe5\xbe\x8c io.gapi.emulators.grpc.GrpcServer$3 operationComplete\n[pubsub] INFO: Adding handler(s) to newly registered Channel.\n[pubsub] 6 14, 2017 2:49:35 \xe5\x8d\x88\xe5\xbe\x8c io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead\n[pubsub] INFO: Detected non-HTTP/2 connection.\n[pubsub] 6 14, 2017 2:49:35 \xe5\x8d\x88\xe5\xbe\x8c io.gapi.emulators.netty.NotFoundHandler handleRequest\n[pubsub] INFO: Unknown request URI: /bad-request\n
Run Code Online (Sandbox Code Playgroud)\n\n

我按如下方式启动模拟器 -

\n\n
PC-12041:random kakaji$ sudo gcloud beta emulators pubsub start\nPassword:\nExecuting: /usr/local/google-cloud-sdk/platform/pubsub-emulator/bin/cloud-pubsub-emulator --host=localhost --port=8085\n[pubsub] This is the Google Pub/Sub fake.\n[pubsub] Implementation may be incomplete or differ from the real system.\n[pubsub] 6 14, 2017 2:59:21 \xe5\x8d\x88\xe5\xbe\x8c com.google.cloud.pubsub.testing.v1.Main main\n[pubsub] INFO: IAM integration is disabled. IAM policy methods and ACL checks are not supported\n[pubsub] 6 14, 2017 2:59:21 \xe5\x8d\x88\xe5\xbe\x8c io.grpc.internal.ManagedChannelImpl <init>\n[pubsub] INFO: [ManagedChannelImpl@77b52d12] Created with target localhost:8085\n[pubsub] 6 14, 2017 2:59:21 \xe5\x8d\x88\xe5\xbe\x8c io.gapi.emulators.netty.NettyUtil applyJava7LongHostnameWorkaround\n[pubsub] INFO: Unable to apply Java 7 long hostname workaround.\n[pubsub] 6 14, 2017 2:59:21 \xe5\x8d\x88\xe5\xbe\x8c com.google.cloud.pubsub.testing.v1.Main main\n[pubsub] INFO: Server started, listening on 8085\n
Run Code Online (Sandbox Code Playgroud)\n

tob*_*obi 0

The Google Cloud Pub/Sub docs mention that Java and C# client libraries do not automatically connect to the emulator host via PUBSUB_EMULATOR_HOST.

Instead, you should do the following (extracted from the docs):

String hostport = System.getenv("PUBSUB_EMULATOR_HOST");
ManagedChannel channel = ManagedChannelBuilder.forTarget(hostport).usePlaintext().build();
CredentialsProvider credentialsProvider = NoCredentialsProvider.create();

// Publisher that connects to the emulator
TopicName topicName = TopicName.of("my-project-id", "my-topic-id");

// Set the channel and credentials provider when creating a `Publisher`.
// Similarly for Subscriber
Publisher publisher =
    Publisher.newBuilder(topicName)
        .setChannelProvider(channelProvider)
        .setCredentialsProvider(credentialsProvider)
        .build();
Run Code Online (Sandbox Code Playgroud)

You may want to check if PUBSUB_EMULATOR_HOST is set and only then set NoCredentialsProvider and the custom ManagedChannel on the builder.