如何在 Dataflow 中创建引用服务帐户 json 文件的 GoogleCredential 对象?

How to create GoogleCredential object referencing the service account json file in Dataflow?

我编写了一个管道来提取 G 套件 activity 日志,方法是引用 G suite java-quickstart,其中代码读取 client_secret.json 文件,如下所示,

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

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

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

更新:

我修改了下面的代码,我可以读取 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 以便在 运行 作为数据流管道时创建凭据对象?

你能在本地多次尝试 运行 该程序吗?我想知道的是,如果 "StoredCredential" 文件可用,它会正常工作吗?还是会再次尝试加载浏览器?

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

我找到了使用服务帐户创建 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;
    }