【问题标题】:Google Dataflow Pipeline creation fails with 400: Bad Request / invalid grantGoogle Dataflow Pipeline 创建失败并显示 400:错误请求/无效授权
【发布时间】:2018-09-25 19:27:19
【问题描述】:

一年多来,我一直在为谷歌数据流构建和创建模板。我从来没有遇到过使用options.setTemplateLocation(templatePath); 调用创建模板并将它们上传到gcs 的问题。从今天开始,使用Pipeline.create(options); 创建管道并在eclipse 中运行java 程序时,出现以下异常:

Exception in thread "main" java.lang.RuntimeException: Failed to construct instance from factory method DataflowRunner#fromOptions(interface org.apache.beam.sdk.options.PipelineOptions)
    at org.apache.beam.sdk.util.InstanceBuilder.buildFromMethod(InstanceBuilder.java:233)
    at org.apache.beam.sdk.util.InstanceBuilder.build(InstanceBuilder.java:162)
    at org.apache.beam.sdk.PipelineRunner.fromOptions(PipelineRunner.java:52)
    at org.apache.beam.sdk.Pipeline.create(Pipeline.java:142)
    at mypackage.PipelineCreation.getTemplatePipeline(PipelineCreation.java:34)
    at myotherpackage.Main.main(Main.java:51)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.beam.sdk.util.InstanceBuilder.buildFromMethod(InstanceBuilder.java:222)
    ... 5 more
Caused by: java.lang.RuntimeException: Unable to verify that GCS bucket gs://my-projects-staging-bucket exists.
    at org.apache.beam.sdk.extensions.gcp.storage.GcsPathValidator.verifyPathIsAccessible(GcsPathValidator.java:92)
    at org.apache.beam.sdk.extensions.gcp.storage.GcsPathValidator.validateOutputFilePrefixSupported(GcsPathValidator.java:61)
    at org.apache.beam.runners.dataflow.DataflowRunner.fromOptions(DataflowRunner.java:228)
    ... 10 more
Caused by: com.google.api.client.http.HttpResponseException: 400 Bad Request
{
  "error" : "invalid_grant",
  "error_description" : "Bad Request"
}
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1070)
    at com.google.auth.oauth2.UserCredentials.refreshAccessToken(UserCredentials.java:207)
    at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:149)
    at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:135)
    at com.google.auth.http.HttpCredentialsAdapter.initialize(HttpCredentialsAdapter.java:96)
    at com.google.cloud.hadoop.util.ChainingHttpRequestInitializer.initialize(ChainingHttpRequestInitializer.java:52)
    at com.google.api.client.http.HttpRequestFactory.buildRequest(HttpRequestFactory.java:93)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.buildHttpRequest(AbstractGoogleClientRequest.java:300)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at com.google.cloud.hadoop.util.ResilientOperation$AbstractGoogleClientRequestExecutor.call(ResilientOperation.java:166)
    at com.google.cloud.hadoop.util.ResilientOperation.retry(ResilientOperation.java:66)
    at org.apache.beam.sdk.util.GcsUtil.getBucket(GcsUtil.java:505)
    at org.apache.beam.sdk.util.GcsUtil.bucketAccessible(GcsUtil.java:492)
    at org.apache.beam.sdk.util.GcsUtil.bucketAccessible(GcsUtil.java:457)
    at org.apache.beam.sdk.extensions.gcp.storage.GcsPathValidator.verifyPathIsAccessible(GcsPathValidator.java:88)
    ... 12 more

我今天使用另一个帐户登录到 gcloud,但再次使用与项目关联的帐户作为“所有者”和gcloud auth login 登录。 我也重新启动了 Eclipse,但同样的错误不断发生。此外,当尝试在本地运行管道时,我收到另一个错误,但还有“invalid_grant”“错误请求”内容。重启笔记本电脑也没有效果。

我的 pom 用 2.2.0 版本定义了 google-cloud-dataflow-java-sdk-all,升级到 2.5.0 没有效果。

我可以从命令行使用 gsutil 将数据复制到存储桶。但是,当使用mvn compile exec:java -Dexec.mainClass=mypackage.Main 从命令行运行 java 程序时,我仍然会遇到相同的错误。

我创建模板管道的函数如下所示:

public static Pipeline getTemplatePipeline(String jobName, String templatePath){
        DataflowPipelineOptions options = PipelineOptionsFactory.as(DataflowPipelineOptions.class);
        options.setProject("my-project-id");
        options.setRunner(DataflowRunner.class);
        options.setStagingLocation("gs://my-projects-staging-bucket/binaries");
        options.setTempLocation("gs://my-projects-staging-bucket/binaries/tmp");
        options.setGcpTempLocation("gs://my-projects-staging-bucket/binaries/tmp");
        options.setZone("europe-west3-a");
        options.setWorkerMachineType("n1-standard-2");
        options.setJobName(jobName);
        options.setMaxNumWorkers(2);
        options.setDiskSizeGb(40);
        options.setTemplateLocation(templatePath);
        return Pipeline.create(options);
    }

非常感谢任何帮助。

【问题讨论】:

    标签: google-cloud-storage google-cloud-dataflow google-authentication bad-request


    【解决方案1】:

    您不必使用服务帐户,仍然可以使用 gcloud,您应该使用以下命令并使用您的帐户登录:

    gcloud auth application-default login
    

    【讨论】:

    • 不推荐这样做并会生成警告:警告:您的应用程序已使用来自 Google Cloud SDK 的最终用户凭据进行身份验证。我们建议大多数服务器应用程序改用服务帐户。如果您的应用程序继续使用来自 Cloud SDK 的最终用户凭据,您可能会收到“超出配额”或“API 未启用”错误。有关服务帐户的更多信息,请参阅cloud.google.com/docs/authentication
    【解决方案2】:

    我在快速入门docs 中找到了解决方案。

    gcloud auth 似乎不再使用,您必须使用服务帐户。因此,就像在文档中一样,我创建了一个角色为“项目/所有者”的服务帐户,并将其 json 文件下载到 $path。

    然后在我的 Mac 上我使用 export GOOGLE_APPLICATION_CREDENTIALS="$path" 并在同一个会话中使用问题中提到的命令来编译和执行 java 程序。

    【讨论】:

    • 如果您对某事不是 100% 确定,请尽量不要误导他人。 gcloud auth 仍在使用中,设置 GOOGLE_APPLICATION_CREDENTIALS 也是一个选项。两者都工作正常
    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 2023-01-25
    • 2020-09-05
    • 2020-12-28
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多