Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google cloud dataflow 如何集成测试写入Bigtable的数据流管道?_Google Cloud Dataflow_Apache Beam_Google Cloud Bigtable - Fatal编程技术网

Google cloud dataflow 如何集成测试写入Bigtable的数据流管道?

Google cloud dataflow 如何集成测试写入Bigtable的数据流管道?,google-cloud-dataflow,apache-beam,google-cloud-bigtable,Google Cloud Dataflow,Apache Beam,Google Cloud Bigtable,据报道, 通常,在您的系统上执行本地单元测试更快、更简单 管道代码,而不是调试管道的远程执行 我想为我的Beam/Dataflow应用程序使用测试驱动开发,该应用程序因此写入Bigtable 然而,在Beam测试文档之后,我陷入了一个僵局——PAssert没有用处,因为输出PCollection包含org.apache.hadoop.hbase.client.Put对象,这些对象不会覆盖equals方法 我也不想让PCollection对它们进行验证,因为 直接获取PCollection的内容是

据报道,

通常,在您的系统上执行本地单元测试更快、更简单 管道代码,而不是调试管道的远程执行

我想为我的Beam/Dataflow应用程序使用测试驱动开发,该应用程序因此写入Bigtable

然而,在Beam测试文档之后,我陷入了一个僵局——PAssert没有用处,因为输出PCollection包含org.apache.hadoop.hbase.client.Put对象,这些对象不会覆盖equals方法

我也不想让PCollection对它们进行验证,因为

直接获取PCollection的内容是不可能的 ApacheBeam或Dataflow管道更像是什么的查询计划 应进行处理,PCollection为逻辑 计划中的中间节点,而不是包含数据

那么,除了手动运行之外,我如何测试这个管道呢?我使用的是Maven和JUnit(在Java中,因为这似乎是所有的软件都支持的)。

可以用来为此编写集成测试:

  • 配置并将测试用例的结尾从*test更改为*IT,以作为集成测试运行
  • 在gcloud sdk的命令行上安装Bigtable Emulator:

    gcloud components install bigtable   
    
    请注意,这一必要步骤将降低代码的可移植性(例如,它会在您的构建系统上运行吗?在其他开发人员的机器上运行吗?),因此我将在部署到构建系统之前使用Docker对其进行容器化

  • 按照以下步骤将emulator插件添加到pom

  • 使用和查看设置会话和表

  • 按照Beam文档正常编写测试,但不使用PAssert,而是实际调用CloudBigtableIO.WriteTable,然后使用HBase客户端从表中读取数据进行验证

下面是一个集成测试示例:

package adair.example;

import static org.apache.hadoop.hbase.util.Bytes.toBytes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.transforms.Create;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import org.hamcrest.collection.IsIterableContainingInAnyOrder;
import org.junit.Assert;
import org.junit.Test;

import com.google.cloud.bigtable.beam.CloudBigtableIO;
import com.google.cloud.bigtable.beam.CloudBigtableTableConfiguration;
import com.google.cloud.bigtable.hbase.BigtableConfiguration;

/**
 *  A simple integration test example for use with the Bigtable Emulator maven plugin.
 */
public class DataflowWriteExampleIT {

  private static final String PROJECT_ID = "fake";
  private static final String INSTANCE_ID = "fakeinstance";
  private static final String TABLE_ID = "example_table";
  private static final String COLUMN_FAMILY = "cf";
  private static final String COLUMN_QUALIFIER = "cq";

  private static final CloudBigtableTableConfiguration TABLE_CONFIG =
    new CloudBigtableTableConfiguration.Builder()
      .withProjectId(PROJECT_ID)
      .withInstanceId(INSTANCE_ID)
      .withTableId(TABLE_ID)
      .build();

  public static final List<String> VALUES_TO_PUT = Arrays
    .asList("hello", "world", "introducing", "Bigtable", "plus", "Dataflow", "IT");

  @Test
  public void testPipelineWrite() throws IOException {
    try (Connection connection = BigtableConfiguration.connect(PROJECT_ID, INSTANCE_ID)) {
      Admin admin = connection.getAdmin();
      createTable(admin);

      List<Mutation> puts = createTestPuts();

      //Use Dataflow to write the data--this is where you'd call the pipeline you want to test.
      Pipeline p = Pipeline.create();
      p.apply(Create.of(puts)).apply(CloudBigtableIO.writeToTable(TABLE_CONFIG));
      p.run().waitUntilFinish();

      //Read the data from the table using the regular hbase api for validation
      ResultScanner scanner = getTableScanner(connection);
      List<String> resultValues = new ArrayList<>();
      for (Result row : scanner) {
        String cellValue = getRowValue(row);
        System.out.println("Found value in table: " + cellValue);
        resultValues.add(cellValue);
      }

      Assert.assertThat(resultValues,
        IsIterableContainingInAnyOrder.containsInAnyOrder(VALUES_TO_PUT.toArray()));
    }
  }

  private void createTable(Admin admin) throws IOException {
    HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(TABLE_ID));
    tableDesc.addFamily(new HColumnDescriptor(COLUMN_FAMILY));

    admin.createTable(tableDesc);
  }

  private ResultScanner getTableScanner(Connection connection) throws IOException {
    Scan scan = new Scan();
    Table table = connection.getTable(TableName.valueOf(TABLE_ID));
    return table.getScanner(scan);
  }

  private String getRowValue(Result row) {
    return Bytes.toString(row.getValue(toBytes(COLUMN_FAMILY), toBytes(COLUMN_QUALIFIER)));
  }

  private List<Mutation> createTestPuts() {
    return VALUES_TO_PUT
          .stream()
          .map(this::stringToPut)
          .collect(Collectors.toList());
  }

  private Mutation stringToPut(String cellValue){
    String key = UUID.randomUUID().toString();
    Put put = new Put(toBytes(key));
    put.addColumn(toBytes(COLUMN_FAMILY), toBytes(COLUMN_QUALIFIER), toBytes(cellValue));
    return put;
  }

}
package adair.example;
导入静态org.apache.hadoop.hbase.util.Bytes.toBytes;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入java.util.UUID;
导入java.util.stream.collector;
导入org.apache.beam.sdk.Pipeline;
导入org.apache.beam.sdk.transforms.Create;
导入org.apache.hadoop.hbase.HColumnDescriptor;
导入org.apache.hadoop.hbase.HTableDescriptor;
导入org.apache.hadoop.hbase.TableName;
导入org.apache.hadoop.hbase.client.Admin;
导入org.apache.hadoop.hbase.client.Connection;
导入org.apache.hadoop.hbase.client.Mutation;
导入org.apache.hadoop.hbase.client.Put;
导入org.apache.hadoop.hbase.client.Result;
导入org.apache.hadoop.hbase.client.ResultScanner;
导入org.apache.hadoop.hbase.client.Scan;
导入org.apache.hadoop.hbase.client.Table;
导入org.apache.hadoop.hbase.util.Bytes;
导入org.hamcrest.collection.isiterablecaininganyorder;
导入org.junit.Assert;
导入org.junit.Test;
导入com.google.cloud.bigtable.beam.CloudBigtableIO;
导入com.google.cloud.bigtable.beam.cloudbigtableconfiguration;
导入com.google.cloud.bigtable.hbase.BigtableConfiguration;
/**
*一个用于Bigtable Emulator maven插件的简单集成测试示例。
*/
公共类DataflowWriteExampleIT{
私有静态最终字符串项目\u ID=“false”;
私有静态最终字符串实例\u ID=“fakeinstance”;
私有静态最终字符串表\u ID=“example\u TABLE”;
私有静态最终字符串列\u FAMILY=“cf”;
私有静态最终字符串列\u QUALIFIER=“cq”;
私有静态最终CloudBigTableConfiguration表_CONFIG=
新的CloudBigTableConfiguration.Builder()
.withProjectId(项目ID)
.withInstanceId(实例ID)
.withTableId(表格ID)
.build();
公共静态最终列表值\u到\u PUT=数组
.asList(“hello”、“world”、“Introduction”、“Bigtable”、“plus”、“Dataflow”、“IT”);
@试验
public void testPipelineWrite()引发IOException{
try(Connection=BigtableConfiguration.connect(项目ID、实例ID)){
Admin=connection.getAdmin();
创建表(管理);
List put=createTestPuts();
//使用数据流来写入数据——这是调用要测试的管道的地方。
Pipeline p=Pipeline.create();
p、 apply(Create.of(put)).apply(CloudBigtableIO.writeToTable(TABLE_CONFIG));
p、 run().waitUntilFinish();
//使用常规hbase api从表中读取数据进行验证
结果扫描程序=getTableScanner(连接);
List resultValues=new ArrayList();
用于(结果行:扫描仪){
字符串cellValue=getRowValue(行);
System.out.println(“在表中找到的值:“+cellValue”);
结果值。添加(单元格值);
}
Assert.assertThat(结果值,
ISiterableContainingAnyOrder.containsInAnyOrder(值0到0 PUT.toArray());
}
}
私有void createTable(Admin)引发IOException{
HTableDescriptor tableDesc=新的HTableDescriptor(TableName.valueOf(TABLE_ID));
tableDesc.addFamily(新的HColumnScriptor(COLUMN_FAMILY));
管理员createTable(tableDesc);
}
私有结果扫描程序getTableScanner(连接)引发IOException{
扫描=新扫描();
Table Table=connection.getTable(TableName.valueOf(Table_ID));
返回表。getScanner(扫描);
}
私有字符串getRowValue(结果行){
返回Bytes.toString(row.getValue(toBytes(COLUMN_FAMILY),toBytes(COLUMN_限定符));
}
私有列表createTestPuts(){
返回值\u到\u PUT
.stream()
.map(this::stringToPut)
.collect(Collectors.toList());
}
私有变异stringToPut(字符串单元格值){
字符串键=UUID.randomUUID().toString();
Put Put=新Put(toBytes(键));
addColumn(toBytes(COLUMN_族)、toBytes(COLUMN_限定符)、toBytes(cellValue));
回售;
}
}