จะทริกเกอร์งานไปป์ไลน์ Cloud Dataflow จาก Cloud Function ใน Java ได้อย่างไร

Aug 21 2020

ฉันมีความต้องการที่จะทริกเกอร์ไปป์ไลน์ Cloud Dataflow จาก Cloud Functions แต่ฟังก์ชัน Cloud ต้องเขียนด้วย Java ดังนั้น Trigger for Cloud Function จึงเป็น Finalize / Create Event ของ Google Cloud Storage กล่าวคือเมื่อไฟล์ถูกอัปโหลดในที่เก็บข้อมูล GCS Cloud Function จะต้องทริกเกอร์ Cloud dataflow

เมื่อฉันสร้างไปป์ไลน์กระแสข้อมูล (ชุดงาน) และฉันดำเนินการไปป์ไลน์มันจะสร้างเทมเพลตไปป์ไลน์ Dataflow และสร้างงาน Dataflow

แต่เมื่อฉันสร้างฟังก์ชันคลาวด์ใน Java และอัปโหลดไฟล์สถานะจะขึ้นว่า "ตกลง" แต่จะไม่ทริกเกอร์ไปป์ไลน์กระแสข้อมูล

ฟังก์ชันคลาวด์

package com.example;

import com.example.Example.GCSEvent;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.dataflow.Dataflow;
import com.google.api.services.dataflow.model.CreateJobFromTemplateRequest;
import com.google.api.services.dataflow.model.RuntimeEnvironment;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.logging.Logger;

public class Example implements BackgroundFunction<GCSEvent> {
    private static final Logger logger = Logger.getLogger(Example.class.getName());

    @Override
    public void accept(GCSEvent event, Context context) throws IOException, GeneralSecurityException {
        logger.info("Event: " + context.eventId());
        logger.info("Event Type: " + context.eventType());


        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

        GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
        HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);


        Dataflow dataflowService = new Dataflow.Builder(httpTransport, jsonFactory, requestInitializer)
                .setApplicationName("Google Dataflow function Demo")
                .build();

        String projectId = "my-project-id";


        RuntimeEnvironment runtimeEnvironment = new RuntimeEnvironment();
        runtimeEnvironment.setBypassTempDirValidation(false);
        runtimeEnvironment.setTempLocation("gs://my-dataflow-job-bucket/tmp");
        CreateJobFromTemplateRequest createJobFromTemplateRequest = new CreateJobFromTemplateRequest();
        createJobFromTemplateRequest.setEnvironment(runtimeEnvironment);
        createJobFromTemplateRequest.setLocation("us-central1");
        createJobFromTemplateRequest.setGcsPath("gs://my-dataflow-job-bucket-staging/templates/cloud-dataflow-template");
        createJobFromTemplateRequest.setJobName("Dataflow-Cloud-Job");
        createJobFromTemplateRequest.setParameters(new HashMap<String,String>());
        createJobFromTemplateRequest.getParameters().put("inputFile","gs://cloud-dataflow-bucket-input/*.txt");
        dataflowService.projects().templates().create(projectId,createJobFromTemplateRequest);

        throw new UnsupportedOperationException("Not supported yet.");
    }

    public static class GCSEvent {
        String bucket;
        String name;
        String metageneration;
    }


}

pom.xml (ฟังก์ชันคลาวด์)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>cloudfunctions</groupId>
  <artifactId>http-function</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
  </properties>

  <dependencies>
  <!-- https://mvnrepository.com/artifact/com.google.auth/google-auth-library-credentials -->
<dependency>
    <groupId>com.google.auth</groupId>
    <artifactId>google-auth-library-credentials</artifactId>
    <version>0.21.1</version>
</dependency>

  <dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-dataflow</artifactId>
    <version>v1b3-rev207-1.20.0</version>
</dependency>
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.0.1</version>
    </dependency>
         <dependency>
    <groupId>com.google.auth</groupId>
    <artifactId>google-auth-library-oauth2-http</artifactId>
    <version>0.21.1</version>
</dependency>
  </dependencies>

  <!-- Required for Java 11 functions in the inline editor -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <excludes>
            <exclude>.google/</exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

บันทึกฟังก์ชันคลาวด์

ฉันอ่านบล็อกด้านล่าง (เพิ่มเพื่อการอ้างอิง) ซึ่งพวกเขาได้ทริกเกอร์กระแสข้อมูลจากที่เก็บข้อมูลบนคลาวด์ผ่านฟังก์ชันคลาวด์ แต่โค้ดถูกเขียนใน Node.js หรือ python แต่ฟังก์ชันคลาวด์ของฉันต้องเขียนด้วย java

ทริกเกอร์ไปป์ไลน์ Dataflow ผ่านฟังก์ชันคลาวด์ใน Node.js

https://dzone.com/articles/triggering-dataflow-pipelines-with-cloud-functions

ทริกเกอร์ไปป์ไลน์กระแสข้อมูลผ่านฟังก์ชันคลาวด์โดยใช้ python

https://medium.com/google-cloud/how-to-kick-off-a-dataflow-pipeline-via-cloud-functions-696927975d4e

ความช่วยเหลือใด ๆ เกี่ยวกับเรื่องนี้เป็นที่ชื่นชมอย่างมาก

คำตอบ

4 Karthikeyant1127 Sep 04 2020 at 11:50
RuntimeEnvironment runtimeEnvironment = new RuntimeEnvironment();
runtimeEnvironment.setBypassTempDirValidation(false);
runtimeEnvironment.setTempLocation("gs://karthiksfirstbucket/temp1");

LaunchTemplateParameters launchTemplateParameters = new LaunchTemplateParameters();
launchTemplateParameters.setEnvironment(runtimeEnvironment);
launchTemplateParameters.setJobName("newJob" + (new Date()).getTime());

Map<String, String> params = new HashMap<String, String>();
params.put("inputFile", "gs://karthiksfirstbucket/sample.txt");
params.put("output", "gs://karthiksfirstbucket/count1");
launchTemplateParameters.setParameters(params);
writer.write("4");
       
Dataflow.Projects.Templates.Launch launch = dataflowService.projects().templates().launch(projectId, launchTemplateParameters);            
launch.setGcsPath("gs://dataflow-templates-us-central1/latest/Word_Count");
launch.execute();

โค้ดด้านบนเปิดเทมเพลตและเรียกใช้งานไปป์ไลน์กระแสข้อมูล

  1. โดยใช้ข้อมูลประจำตัวเริ่มต้นของแอปพลิเคชัน (ซึ่งสามารถเปลี่ยนเป็นเครดิตผู้ใช้หรือเครดิตบริการ)
  2. ภูมิภาคเป็นภูมิภาคเริ่มต้น (ซึ่งสามารถเปลี่ยนแปลงได้)
  3. สร้างงานสำหรับทริกเกอร์ HTTP ทุกตัว (ทริกเกอร์สามารถเปลี่ยนแปลงได้)

คุณสามารถดูโค้ดทั้งหมดได้ด้านล่าง:

https://github.com/karthikeyan1127/Java_CloudFunction_DataFlow/blob/master/Hello.java