Java 如何访问PAR中的管道选项?

Java 如何访问PAR中的管道选项?,java,google-cloud-dataflow,Java,Google Cloud Dataflow,TL;DR:在我的PAR中,我如何访问在作业创建时间传递给作业的参数? 我有两个模板,一个用于Dev,一个用于Prod,它们都工作得很好,只是每个模板中有一个值需要不同。到目前为止,我一直在“硬编码”这个值,然后我“运行”java程序来构建模板(使用DataflowRunner)。但这很容易出错,如果我不是很小心,我会尝试更新dev模板中的一些代码,但无意中仍然从prod模板中设置了这个值。不太好 这样,我认为管道选项是好的,我只是在一个不同的参数中传递,无论是在模板编译时,还是在模板运行时,但

TL;DR:在我的PAR中,我如何访问在作业创建时间传递给作业的参数? 我有两个模板,一个用于Dev,一个用于Prod,它们都工作得很好,只是每个模板中有一个值需要不同。到目前为止,我一直在“硬编码”这个值,然后我“运行”java程序来构建模板(使用DataflowRunner)。但这很容易出错,如果我不是很小心,我会尝试更新dev模板中的一些代码,但无意中仍然从prod模板中设置了这个值。不太好

这样,我认为管道选项是好的,我只是在一个不同的参数中传递,无论是在模板编译时,还是在模板运行时,但是我都有一段时间来访问PAR内的值。 如果我使用默认的运行程序并在本地运行管道,它可以正常工作,但是当我切换并构建模板时,值总是

null
。我可以用下面的代码重现这一点:

/*
进口。。。
*/
@抑制警告(“串行”)
公共类启动程序管道{
私有静态最终记录器LOG=LoggerFactory.getLogger(StarterPipeline.class);
静态字符串组织;
公共接口MyOptions扩展了PipelineOptions{
@说明(“组织Id”)
@默认值。字符串(“123-984-a”)
字符串getOrgId();
void setOrgId(字符串orgID);
}
公共静态void main(字符串[]args){
pipelineoptions工厂寄存器(MyOptions.class);
最终MyOptions选项=PipelineOptionsFactory.fromArgs(args).withValidation().create()
.as(MyOptions.class);
orgId=options.getOrgId();
日志信息(“orgId:+orgId”);
Pipeline p=Pipeline.create(选项);
PCollection someDataRows=p.apply(“从BQ获取数据”,Create.of(
“字符串1”、“字符串2”、“字符串3”
) );
apply(“打包到列表中”),ParDo.of(new DoFn(){
@过程元素
公共void processElement(ProcessContext c){
LOG.info(“你好?”);
LOG.info(“组织ID:+orgId”);
}
}));
p、 run();
}
}
云中的输出是:

 2018-09-20 (16:16:49) Hello?
 2018-09-20 (16:16:49) ORG ID: null
 2018-09-20 (16:16:51) Hello?
 2018-09-20 (16:16:51) ORG ID: null
 2018-09-20 (16:16:53) Hello?
 2018-09-20 (16:16:53) ORG ID: null
 ...
但在当地:

Sep 20, 2018 4:15:32 PM simplepipeline.StarterPipeline main
INFO: orgId: jomama47
Sep 20, 2018 4:15:35 PM simplepipeline.StarterPipeline$1 processElement
INFO: Hello? 
Sep 20, 2018 4:15:35 PM simplepipeline.StarterPipeline$1 processElement
INFO: ORG ID: jomama47
Sep 20, 2018 4:15:35 PM simplepipeline.StarterPipeline$1 processElement
INFO: Hello? 
Sep 20, 2018 4:15:35 PM simplepipeline.StarterPipeline$1 processElement
INFO: Hello? 
Sep 20, 2018 4:15:35 PM simplepipeline.StarterPipeline$1 processElement
INFO: ORG ID: jomama47
Sep 20, 2018 4:15:35 PM simplepipeline.StarterPipeline$1 processElement
INFO: ORG ID: jomama47
以下是我用于模板的构建参数:

--project=the-project
--stagingLocation=gs://staging.the-project.appspot.com/staging/
--tempLocation=gs://staging.the-project.appspot.com/temp/
--runner=DataflowRunner
--region=us-west1
--templateLocation=gs://staging.the-project.appspot.com/templates/NoobPipelineDev
--orgId=jomama47
至于本地:

--project=the-project
--tempLocation=gs://staging.the-project.appspot.com
--orgId=jomama47
当我在参数字段中的数据流控制台(浏览器)中创建作业时,我尝试将参数传递给该作业,作为
orgId
jomama77
,但结果仍然为null


抱歉发了这么长的帖子。

这里有两件事。首先,我建议使用,以便您可以在运行时为不同的
orgId
传递参数:

public interface MyOptions extends PipelineOptions {    
     @Description("Org Id")
     @Default.String("123-984-a")
     ValueProvider<String> getOrgId();
     void setOrgId(ValueProvider<String> orgID);   
}
其中,
CustomFn
的构造函数将其作为参数,并将其存储在
ValueProvider
中,以便可以从ParDo中访问它。请注意,现在需要使用
orgId.get()

这应该如预期的那样起作用:


太棒了。谢谢你写得这么好。这些文档的链接非常有用,我感谢你花了这么多时间来整理这些文档。很好用,谢谢!!
ValueProvider<String> orgId = options.getOrgId();
someDataRows.apply( "Package into a list", ParDo.of( new CustomFn(orgId)));
static class CustomFn extends DoFn<String, String> {
    // access options from wihtin the ParDo
    ValueProvider<String> orgId;
    public CustomFn(ValueProvider<String> orgId) {
        this.orgId = orgId;
    }

    @ProcessElement
    public void processElement( ProcessContext c ) {
      LOG.info( "Hello? " );
      LOG.info( "ORG ID: " + orgId.get() );
    }
}