【发布时间】:2015-10-11 19:38:27
【问题描述】:
我有一个 Google App Engine 应用程序,其中数据存储在 Google Cloud Datastore 中。我想使用 Dataflow 将部分数据放入 BigQuery,但我想我首先从 Datastore 获取一些信息并将其写入 Google Cloud Storage。我的代码如下所示:
public class DatastorePipeline {
private static final Logger LOG = LoggerFactory.getLogger(DatastorePipeline.class);
static class GetEmailFn extends DoFn<Entity, String> {
@Override
public void processElement(ProcessContext c) throws Exception {
Map<String, Value> properties = DatastoreHelper.getPropertyMap(c.element());
Value value = properties.get("email_address");
if(value != null) {
c.output(DatastoreHelper.getString(value));
}
}
}
public static void main(String[] args) {
Pipeline p = Pipeline.create(PipelineOptionsFactory.fromArgs(args).withValidation().create());
Query.Builder q = Query.newBuilder();
q.addKindBuilder().setName("User");
Query query = q.build();
DatastoreIO.Source source = DatastoreIO.source()
.withDataset("my-project-id")
.withQuery(query);
p.apply("ReadUsersFromDatastore", Read.from(source))
.apply(ParDo.named("GetEmailAddress").of(new GetEmailFn()))
.apply(TextIO.Write.to("gs://dataflow-output-bucket/emails.txt"));
p.run();
}
}
但是,当我尝试运行此程序时,在进行数据存储区查询时出现 403 错误:
Request failed with code 403, will NOT retry: https://www.googleapis.com/datastore/v1beta2/datasets/my-project-id/runQuery
我使用 Google Cloud Dataflow 插件从 Eclipse 运行它。运行没有数据存储读取的数据流作业可以正常工作。我做了一个
gcloud auth login
在运行作业之前,如教程中所述。我做错了什么?
编辑:这是完整的堆栈跟踪。
2015 年 10 月 11 日下午 12:03:13 (b6119cca307b4d9a):com.google.api.services.datastore.client.DatastoreException:未经授权。在 com.google.api.services.datastore.client.RemoteRpc.makeException(RemoteRpc.java:115) 在 com.google.api.services.datastore.client.RemoteRpc.call(RemoteRpc.java:81) 在 com.google .api.services.datastore.client.BaseDatastoreFactory$RemoteRpc.call(BaseDatastoreFactory.java:41) 在 com.google.api.services.datastore.client.Datastore.runQuery(Datastore.java:109) 在 com.google.api .services.datastore.client.QuerySplitterImpl.getScatterKeys(QuerySplitterImpl.java:189) 在 com.google.api.services.datastore.client.QuerySplitterImpl.getSplits(QuerySplitterImpl.java:75) 在 com.google.cloud.dataflow.sdk .io.DatastoreIO$Source.getSplitQueries(DatastoreIO.java:427) 在 com.google.cloud.dataflow.sdk.io.DatastoreIO$Source.splitIntoBundles(DatastoreIO.java:306) 在 com.google.cloud.dataflow.sdk .runners.dataflow.BasicSerializableSourceFormat.performSplit(BasicSerializableSourceFormat.java:318) 在 com.google.cloud.dataflow.sdk.runners.dataflow.BasicSerializableSourceFormat.performSourceOperation(BasicSerializa bleSourceFormat.java:167) 在 com.google.cloud.dataflow.sdk.runners.worker.SourceOperationExecutor.execute(SourceOperationExecutor.java:80) 在 com.google.cloud.dataflow.sdk.runners.worker.DataflowWorker.executeWork( DataflowWorker.java:257) 在 com.google.cloud.dataflow.sdk.runners.worker.DataflowWorker.doWork(DataflowWorker.java:193) 在 com.google.cloud.dataflow.sdk.runners.worker.DataflowWorker.getAndPerformWork( DataflowWorker.java:146) 在 com.google.cloud.dataflow.sdk.runners.worker.DataflowWorkerHarness$WorkerThread.doWork(DataflowWorkerHarness.java:164) 在 com.google.cloud.dataflow.sdk.runners.worker.DataflowWorkerHarness$ WorkerThread.call(DataflowWorkerHarness.java:145) at com.google.cloud.dataflow.sdk.runners.worker.DataflowWorkerHarness$WorkerThread.call(DataflowWorkerHarness.java:132) at java.util.concurrent.FutureTask.run(FutureTask. java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(T java.lang.Thread.run(Thread.java:745) 处的 readPoolExecutor.java:617) 原因:com.google.api.client.http.HttpResponseException: 403 Forbidden Unauthorized。在 com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1061) 在 com.google.api.services.datastore.client.RemoteRpc.call(RemoteRpc.java:78) ... 19 更多
回答:原来问题是我的项目根据我公司的域限制访问,这导致服务帐户无法连接。感谢 Dan 帮助我完成它!
【问题讨论】:
-
很抱歉给您带来了麻烦。您可以编辑问题以包含错误的完整堆栈跟踪吗?
-
看起来您正在使用
DataflowPipelineRunner(或Blocking变体)运行。DirectPipelineRunner是否也会出现同样的错误? -
另外,这个错误每次都会发生,而不是偶尔发生,对吗?
-
每次都会发生此错误,并且仅在 DataflowPipeLineRunner/Blocking 运行器上发生。它不会发生在 DirectPipelineRunner 上。
标签: java google-app-engine google-cloud-platform google-cloud-datastore google-cloud-dataflow