【问题标题】:How to create GoogleCredential object referencing the service account json file in Dataflow?如何在 Dataflow 中创建引用服务帐户 json 文件的 GoogleCredential 对象?
【发布时间】:2018-04-30 14:18:10
【问题描述】:

我已经编写了一个管道来通过引用G suite java-quickstart 来提取 G Suite 活动日志,其中代码读取 client_secret.json 文件,如下所示,

InputStream in = new FileInputStream("D://mypath/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

管道在本地(runner=DirectRunner)中按预期运行,但在云上执行时,相同的代码会因 java.io.FileNotFoundException 异常而失败(runner=DataflowRunner)

我了解本地路径在云端执行时无效。这里有什么建议吗?

更新:

我已将代码修改如下,我可以读取 client_secrets.json 文件

    InputStream in =
    Activities.class.getResourceAsStream("client_secret.json");

实际问题在于创建凭证对象

private static   java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
         ".credentials/admin-reports_v1-java-quickstart");
private static final List<String> SCOPES = Arrays.asList(ReportsScopes.ADMIN_REPORTS_AUDIT_READONLY);

static {
    try {
        HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
    } catch (Throwable t) {
        t.printStackTrace();
        System.exit(1);
    }
}

public static Credential authorize() throws IOException {
    // Load client secrets.
    InputStream in =
    Activities.class.getResourceAsStream("client_secret.json");

    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

    // Build flow and trigger user authorization request.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
            clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();
    Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
    System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
    return credential;
}

观察:

本地执行:

  1. 在初始执行时,程序会尝试打开浏览器以授权请求并将经过身份验证的对象存储在文件 - “StoredCredential”中。
  2. 在进一步执行时,存储的文件用于进行 API 调用。

在云端运行(DataFlowRunner):

  1. 当我检查日志时,dataflow 会尝试打开浏览器来验证请求并停在那里。

我需要什么?

如何修改GoogleAuthorizationCodeFlow.Builder,以便在作为数据流管道运行时可以创建凭证对象?

【问题讨论】:

  • 您要寻找的预期结果是什么?
  • @noogui 更新了我的帖子。请看一看。

标签: google-cloud-dataflow google-admin-sdk apache-beam


【解决方案1】:

我找到了使用服务帐户创建 GoogleCredential 对象的解决方案。下面是它的代码。

    public static Credential authorize() throws IOException, GeneralSecurityException {

        String emailAddress = "service_account.iam.gserviceaccount.com";
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(emailAddress)
                .setServiceAccountPrivateKeyFromP12File(Activities.class.getResourceAsStream("MYFILE.p12"))
                .setServiceAccountScopes(Collections.singleton(ReportsScopes.ADMIN_REPORTS_AUDIT_READONLY))
                .setServiceAccountUser("USER_NAME")
                .build();

        return credential;
    }

【讨论】:

    【解决方案2】:

    您可以尝试在本地多次运行该程序吗?我想知道的是,如果“StoredCredential”文件可用,它会起作用吗?还是会尝试再次加载浏览器?

    如果是这样,您能否确定存储该文件的正确位置,并将其副本从 GCS 下载到 Dataflow 工作线程?应该有 API 来下载与数据流 SDK jar 捆绑在一起的 GCS 文件。所以你应该可以使用它们来下载凭证文件。

    【讨论】:

    • 试图找到存放“StoredCredential”文件的正确位置,但失败了。最后,找到了一种使用现在可以使用的服务帐户创建凭据对象的方法。发布解决方案作为答案。
    猜你喜欢
    • 2015-11-08
    • 2021-09-27
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2013-01-20
    相关资源
    最近更新 更多