从 Google PubSub 中提取消息不起作用 - 权限被拒绝
Posted
技术标签:
【中文标题】从 Google PubSub 中提取消息不起作用 - 权限被拒绝【英文标题】:Pulling messages from Google PubSub not working - Permission denied 【发布时间】:2018-01-22 02:40:44 【问题描述】:我正在尝试从现有订阅中提取消息,但每次尝试都会收到 PERMISSION_DENIED 错误。但是,测试权限会为“pubsub.subscriptions.consume”返回“true”。也许它与使用现有订阅而不是创建新订阅有关?不过我还没有找到一种方法来做到这一点,而且网上的每个例子都是这样做的。
TopicName topic = TopicName.create("cloud-project", "sn-1000");
SubscriptionName subscription = SubscriptionName.create("cloud-project", "sn-1000");
String accountFile = "ServiceAccount_sn-1000.json";
CredentialsProvider credentialsProvider = FixedCredentialsProvider.create(
ServiceAccountCredentials.fromStream(new FileInputStream(accountFile))
);
SubscriptionAdminSettings subscriptionAdminSettings =
SubscriptionAdminSettings.defaultBuilder()
.setCredentialsProvider(credentialsProvider)
.build();
// THIS IS WHERE IT FAILS
SubscriptionAdminClient subscriptionAdminClient =
SubscriptionAdminClient.create(subscriptionAdminSettings);
subscriptionAdminClient.createSubscription(subscription, topic, PushConfig.getDefaultInstance(), 0);
Subscriber subscriber = Subscriber.defaultBuilder(subscription, new MyMessageReceiver()).build();
subscriber.addListener(new Subscriber.Listener()
@Override
public void failed(Subscriber.State from, Throwable failure)
// Handle failure. This is called when the Subscriber encountered a fatal error and is shutting down.
System.err.println(failure);
, MoreExecutors.directExecutor());
subscriber.startAsync().awaitRunning();
if(subscriber.state().equals(ApiService.State.FAILED))
subscriber.stopAsync().awaitTerminated();
return;
//Printing messages written to a buffer in the custom MyMessageReceiver class, which implements MessageReceiver
subscriber.stopAsync().awaitTerminated();
我在控制台中执行此代码时收到此错误:
com.google.api.gax.grpc.GrpcApiException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: User not authorized to perform this action.
at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:112)
at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:53)
at com.google.common.util.concurrent.Futures$4.run(Futures.java:1123)
at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:435)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:900)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:811)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:675)
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:466)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:442)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:76)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:512)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$700(ClientCallImpl.java:429)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:544)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:52)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:117)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: io.grpc.StatusRuntimeException: PERMISSION_DENIED: User not authorized to perform this action.
at io.grpc.Status.asRuntimeException(Status.java:543)
... 15 more
【问题讨论】:
你解决问题了吗? 【参考方案1】:失败的行是您尝试创建订阅的行,而不是您尝试使用消息的行。 “pubsub.subscriptions.consume”权限不足以创建订阅。 access control page 详细说明了执行不同操作所需的权限。为了创建订阅,所需的权限是包含 Cloud 项目的“pubsub.subscriptions.create”,以及请求主题的 pubsub.topics.attachSubscription。请注意,在项目 B 的主题 T 上创建项目 A 的订阅,则必须在项目 A 和主题 T 上授予适当的权限。”
如果订阅已经存在,则无需再次调用 createSubscription ,只需创建订阅者对象即可:
ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of("cloud-project", "sn-1000");
Subscriber subscriber = Subscriber.newBuilder(subscriptionName, new MyMessageReceiver()).build();
【讨论】:
以上是关于从 Google PubSub 中提取消息不起作用 - 权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章
获取 Google Cloud PubSub 中单条消息的大小
如何使用当前的 pubsub 订阅者从 google Pub/Sub 系统获取消息
如何在 Google Cloud App Engine 上使用 PubSub 创建订阅者,该订阅者通过 Publisher 从 Google Cloud App Engine Flex 收听消息?