Google cloud dataflow 价值提供者问题

Google cloud dataflow 价值提供者问题,google-cloud-dataflow,google-cloud-functions,google-api-nodejs-client,Google Cloud Dataflow,Google Cloud Functions,Google Api Nodejs Client,我试图获取从云函数传递到数据流模板的属性的值。我收到错误,因为传递的值是一个包装器,并且在编译期间使用.get()方法失败。由于这个错误 执行Java类时发生异常。null:InvocationTargetException:未从运行时上下文调用。 public interface MyOptions extends DataflowPipelineOptions { ... @Description("schema of csv file") ValueProvider<String&g

我试图获取从云函数传递到数据流模板的属性的值。我收到错误,因为传递的值是一个包装器,并且在编译期间使用
.get()
方法失败。由于这个错误
执行Java类时发生异常。null:InvocationTargetException:未从运行时上下文调用。

public interface MyOptions extends DataflowPipelineOptions {
...
@Description("schema of csv file")
ValueProvider<String> getHeader();
void setHeader(ValueProvider<String> header);
...
}

public static void main(String[] args) throws IOException {
...
    List<String> sideInputColumns = Arrays.asList(options.getHeader().get().split(","));
...
    //ultimately use the getHeaders as side inputs
    PCollection<String> input = p.apply(Create.of(sideInputColumns));
    final PCollectionView<List<String>> finalColumnView = input.apply(View.asList());
}
公共接口MyOptions扩展了DataflowPipelineOptions{
...
@说明(“csv文件的模式”)
ValueProvider getHeader();
无效设置标题(ValueProvider标题);
...
}
公共静态void main(字符串[]args)引发IOException{
...
List sideInputColumns=Arrays.asList(options.getHeader().get().split(“,”);
...
//最终使用getHeader作为侧输入
PCollection input=p.apply(Create.of(sideInputColumns));
final PCollectionView finalColumnView=input.apply(View.asList());
}

如何从ValueProvider类型中提取值?

管道构造期间,
ValueProvider的值不可用。因此,您需要组织管道,使其始终具有相同的结构,并序列化
ValueProvider
。在运行时,管道中的各个转换可以检查值以确定如何操作

根据您的示例,您可能需要执行以下操作。它创建一个元素,然后使用运行时计算的
DoFn
展开标题:

public static class HeaderDoFn extends DoFn<String, String> {
  private final ValueProvider<String> header;
  public HeaderDoFn(ValueProvider<String> header) {
    this.header = header;
  }

  @ProcessElement
  public void processElement(ProcessContext c) {
    // Ignore input element -- there should be exactly one
    for (String column : this.header().get().split(",")) {
      c.output(column);
    }
  }
}

public static void main(String[] args) throws IOException {
  PCollection<String> input = p
    .apply(Create.of("one")) // create a single element
    .apply(ParDo.of(new DoFn<String, String>() {
      @ProcessElement
      public void processElement(ProcessContext c) {
      }
    });

  // Note that the order of this list is not guaranteed. 
  final PCollectionView<List<String>> finalColumnView = 
    input.apply(View.asList());        
}
公共静态类HeaderDoFn扩展DoFn{
私人最终价值提供者标题;
公共标头(ValueProvider标头){
this.header=头;
}
@过程元素
公共void processElement(ProcessContext c){
//忽略输入元素——应该正好有一个
for(字符串列:this.header().get().split(“,”)){
c、 输出(列);
}
}
}
公共静态void main(字符串[]args)引发IOException{
PCollection输入=p
.apply(Create.of(“one”)//创建单个元素
.适用(新DoFn()的第{
@过程元素
公共void processElement(ProcessContext c){
}
});
//请注意,不保证此列表的顺序。
最终PCollectionView最终列视图=
input.apply(View.asList());
}

另一种选择是使用NestedValueProvider从该选项创建一个
ValueProvider
,并将该
ValueProvider
传递给必要的
DoFn
,而不是使用辅助输入。

请共享您的代码。我访问了谷歌的网站,与ValueProvider一起创建模板,但我在尝试im时遇到了问题完成结构。将选项传递给MyFn会给我一个错误“package.this”不能在静态上下文中引用。我做错了什么?更新了答案,为您的用例提供了两种可能性谢谢@Ben!在您的代码帮助下,我能够提取值。我只需要将它用于我需要的lol