Repository: incubator-beam Updated Branches: refs/heads/master cdb7ba165 -> ae06f759f
Add method to output runtime options Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/ee52318f Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/ee52318f Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/ee52318f Branch: refs/heads/master Commit: ee52318f2512c6661823e4f546f84dbc2caa955b Parents: cdb7ba1 Author: sammcveety <sam.mcve...@gmail.com> Authored: Fri Oct 21 12:50:01 2016 -0400 Committer: Dan Halperin <dhalp...@google.com> Committed: Mon Nov 28 20:24:38 2016 -0800 ---------------------------------------------------------------------- .../beam/sdk/options/PipelineOptions.java | 7 ++++++ .../sdk/options/PipelineOptionsFactory.java | 1 + .../sdk/options/ProxyInvocationHandler.java | 26 ++++++++++++++++++++ .../beam/sdk/options/PipelineOptionsTest.java | 24 ++++++++++++++++++ 4 files changed, 58 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/ee52318f/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptions.java ---------------------------------------------------------------------- diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptions.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptions.java index 2139ed9..ddb040d 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptions.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptions.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.auto.service.AutoService; import com.google.common.base.MoreObjects; import java.lang.reflect.Proxy; +import java.util.Map; import java.util.ServiceLoader; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicLong; @@ -322,6 +323,12 @@ public interface PipelineOptions extends HasDisplayData { } /** + * Returns a map of properties which correspond to {@link ValueProvider.RuntimeValueProvider}, + * keyed by the property name. The value is a map containing type and default information. + */ + Map<String, Map<String, Object>> outputRuntimeOptions(); + + /** * Provides a unique ID for this {@link PipelineOptions} object, assigned at graph * construction time. */ http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/ee52318f/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java ---------------------------------------------------------------------- diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java index 6009867..9805489 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java @@ -1219,6 +1219,7 @@ public class PipelineOptionsFactory { // Ignore methods on the base PipelineOptions interface. try { knownMethods.add(iface.getMethod("as", Class.class)); + knownMethods.add(iface.getMethod("outputRuntimeOptions")); knownMethods.add(iface.getMethod("populateDisplayData", DisplayData.Builder.class)); } catch (NoSuchMethodException | SecurityException e) { throw new RuntimeException(e); http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/ee52318f/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java ---------------------------------------------------------------------- diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java index 86f9918..a0e3ec2 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java @@ -48,6 +48,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.Arrays; @@ -130,6 +131,8 @@ class ProxyInvocationHandler implements InvocationHandler { return equals(args[0]); } else if (args == null && "hashCode".equals(method.getName())) { return hashCode(); + } else if (args == null && "outputRuntimeOptions".equals(method.getName())) { + return outputRuntimeOptions((PipelineOptions) proxy); } else if (args != null && "as".equals(method.getName()) && args[0] instanceof Class) { @SuppressWarnings("unchecked") Class<? extends PipelineOptions> clazz = (Class<? extends PipelineOptions>) args[0]; @@ -242,6 +245,29 @@ class ProxyInvocationHandler implements InvocationHandler { } /** + * Returns a map of properties which correspond to {@link RuntimeValueProvider}. + */ + public Map<String, Map<String, Object>> outputRuntimeOptions(PipelineOptions options) { + Set<PipelineOptionSpec> optionSpecs = PipelineOptionsReflector.getOptionSpecs(knownInterfaces); + Map<String, Map<String, Object>> properties = Maps.newHashMap(); + + for (PipelineOptionSpec spec : optionSpecs) { + if (spec.getGetterMethod().getReturnType().equals(ValueProvider.class)) { + Object vp = invoke(options, spec.getGetterMethod(), null); + if (((ValueProvider) vp).isAccessible()) { + continue; + } + Map<String, Object> property = Maps.newHashMap(); + property.put("type", + ((ParameterizedType) spec.getGetterMethod() + .getGenericReturnType()).getActualTypeArguments()[0]); + properties.put(spec.getName(), property); + } + } + return properties; + } + + /** * Nested class to handle display data in order to set the display data namespace to something * sensible. */ http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/ee52318f/sdks/java/core/src/test/java/org/apache/beam/sdk/options/PipelineOptionsTest.java ---------------------------------------------------------------------- diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/options/PipelineOptionsTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/options/PipelineOptionsTest.java index 70a6c98..f7ff45d 100644 --- a/sdks/java/core/src/test/java/org/apache/beam/sdk/options/PipelineOptionsTest.java +++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/options/PipelineOptionsTest.java @@ -17,10 +17,13 @@ */ package org.apache.beam.sdk.options; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.collect.ImmutableMap; import java.util.List; +import java.util.Map; import java.util.Set; import org.junit.Rule; import org.junit.Test; @@ -70,4 +73,25 @@ public class PipelineOptionsTest { BaseTestOptions options = PipelineOptionsFactory.create().as(BaseTestOptions.class); assertNotNull(options); } + + private interface ValueProviderOptions extends PipelineOptions { + ValueProvider<Boolean> getBool(); + void setBool(ValueProvider<Boolean> value); + + ValueProvider<String> getString(); + void setString(ValueProvider<String> value); + + String getNotAValueProvider(); + void setNotAValueProvider(String value); + } + + @Test + public void testOutputRuntimeOptions() { + ValueProviderOptions options = + PipelineOptionsFactory.fromArgs( + new String[]{"--string=baz"}).as(ValueProviderOptions.class); + Map<String, ?> expected = ImmutableMap.of( + "bool", ImmutableMap.of("type", Boolean.class)); + assertEquals(expected, options.outputRuntimeOptions()); + } }