Search in sources :

Example 1 with Required

use of org.apache.beam.sdk.options.Validation.Required in project beam by apache.

the class PipelineOptionsValidator method validate.

/**
   * Validates that the passed {@link PipelineOptions} conforms to all the validation criteria from
   * the passed in interface.
   *
   * <p>Note that the interface requested must conform to the validation criteria specified on
   * {@link PipelineOptions#as(Class)}.
   *
   * @param klass The interface to fetch validation criteria from.
   * @param options The {@link PipelineOptions} to validate.
   * @return The type
   */
public static <T extends PipelineOptions> T validate(Class<T> klass, PipelineOptions options) {
    checkNotNull(klass);
    checkNotNull(options);
    checkArgument(Proxy.isProxyClass(options.getClass()));
    checkArgument(Proxy.getInvocationHandler(options) instanceof ProxyInvocationHandler);
    // Ensure the methods for T are registered on the ProxyInvocationHandler
    T asClassOptions = options.as(klass);
    ProxyInvocationHandler handler = (ProxyInvocationHandler) Proxy.getInvocationHandler(asClassOptions);
    SortedSetMultimap<String, Method> requiredGroups = TreeMultimap.create(Ordering.natural(), PipelineOptionsFactory.MethodNameComparator.INSTANCE);
    for (Method method : ReflectHelpers.getClosureOfMethodsOnInterface(klass)) {
        Required requiredAnnotation = method.getAnnotation(Validation.Required.class);
        if (requiredAnnotation != null) {
            if (requiredAnnotation.groups().length > 0) {
                for (String requiredGroup : requiredAnnotation.groups()) {
                    requiredGroups.put(requiredGroup, method);
                }
            } else {
                checkArgument(handler.invoke(asClassOptions, method, null) != null, "Missing required value for [%s, \"%s\"]. ", method, getDescription(method));
            }
        }
    }
    for (String requiredGroup : requiredGroups.keySet()) {
        if (!verifyGroup(handler, asClassOptions, requiredGroups.get(requiredGroup))) {
            throw new IllegalArgumentException("Missing required value for group [" + requiredGroup + "]. At least one of the following properties " + Collections2.transform(requiredGroups.get(requiredGroup), ReflectHelpers.METHOD_FORMATTER) + " required. Run with --help=" + klass.getSimpleName() + " for more information.");
        }
    }
    return asClassOptions;
}
Also used : Required(org.apache.beam.sdk.options.Validation.Required) Method(java.lang.reflect.Method)

Example 2 with Required

use of org.apache.beam.sdk.options.Validation.Required in project beam by apache.

the class PipelineOptionsValidator method validate.

private static <T extends PipelineOptions> T validate(Class<T> klass, PipelineOptions options, boolean isCli) {
    checkNotNull(klass);
    checkNotNull(options);
    checkArgument(Proxy.isProxyClass(options.getClass()));
    checkArgument(Proxy.getInvocationHandler(options) instanceof ProxyInvocationHandler);
    // Ensure the methods for T are registered on the ProxyInvocationHandler
    T asClassOptions = options.as(klass);
    ProxyInvocationHandler handler = (ProxyInvocationHandler) Proxy.getInvocationHandler(asClassOptions);
    SortedSetMultimap<String, Method> requiredGroups = TreeMultimap.create(Ordering.natural(), PipelineOptionsFactory.MethodNameComparator.INSTANCE);
    for (Method method : ReflectHelpers.getClosureOfMethodsOnInterface(klass)) {
        Required requiredAnnotation = method.getAnnotation(Validation.Required.class);
        if (requiredAnnotation != null) {
            if (requiredAnnotation.groups().length > 0) {
                for (String requiredGroup : requiredAnnotation.groups()) {
                    requiredGroups.put(requiredGroup, method);
                }
            } else {
                if (isCli) {
                    checkArgument(handler.invoke(asClassOptions, method, null) != null, "Missing required value for [--%s, \"%s\"]. ", handler.getOptionName(method), getDescription(method));
                } else {
                    checkArgument(handler.invoke(asClassOptions, method, null) != null, "Missing required value for [%s, \"%s\"]. ", method, getDescription(method));
                }
            }
        }
    }
    for (String requiredGroup : requiredGroups.keySet()) {
        if (!verifyGroup(handler, asClassOptions, requiredGroups.get(requiredGroup))) {
            throw new IllegalArgumentException("Missing required value for group [" + requiredGroup + "]. At least one of the following properties " + Collections2.transform(requiredGroups.get(requiredGroup), ReflectHelpers::formatMethod) + " required. Run with --help=" + klass.getSimpleName() + " for more information.");
        }
    }
    return asClassOptions;
}
Also used : Required(org.apache.beam.sdk.options.Validation.Required) Method(java.lang.reflect.Method)

Example 3 with Required

use of org.apache.beam.sdk.options.Validation.Required in project beam by apache.

the class PipelineOptionsFactory method printHelp.

/**
 * Outputs the set of options available to be set for the passed in {@link PipelineOptions}
 * interface. The output is in a human readable format. The format is:
 *
 * <pre>
 * OptionGroup:
 *     ... option group description ...
 *
 *  --option1={@code <type>} or list of valid enum choices
 *     Default: value (if available, see {@link Default})
 *     ... option description ... (if available, see {@link Description})
 *     Required groups (if available, see {@link Required})
 *  --option2={@code <type>} or list of valid enum choices
 *     Default: value (if available, see {@link Default})
 *     ... option description ... (if available, see {@link Description})
 *     Required groups (if available, see {@link Required})
 * </pre>
 *
 * This method will attempt to format its output to be compatible with a terminal window.
 */
public static void printHelp(PrintStream out, Class<? extends PipelineOptions> iface) {
    checkNotNull(out);
    checkNotNull(iface);
    CACHE.get().validateWellFormed(iface);
    Set<PipelineOptionSpec> properties = PipelineOptionsReflector.getOptionSpecs(iface, true);
    RowSortedTable<Class<?>, String, Method> ifacePropGetterTable = TreeBasedTable.create(ClassNameComparator.INSTANCE, Ordering.natural());
    for (PipelineOptionSpec prop : properties) {
        ifacePropGetterTable.put(prop.getDefiningInterface(), prop.getName(), prop.getGetterMethod());
    }
    for (Map.Entry<Class<?>, Map<String, Method>> ifaceToPropertyMap : ifacePropGetterTable.rowMap().entrySet()) {
        Class<?> currentIface = ifaceToPropertyMap.getKey();
        Map<String, Method> propertyNamesToGetters = ifaceToPropertyMap.getValue();
        SortedSetMultimap<String, String> requiredGroupNameToProperties = getRequiredGroupNamesToProperties(propertyNamesToGetters);
        out.format("%s:%n", currentIface.getName());
        Description ifaceDescription = currentIface.getAnnotation(Description.class);
        if (ifaceDescription != null && ifaceDescription.value() != null) {
            prettyPrintDescription(out, ifaceDescription);
        }
        out.println();
        List<@KeyFor("propertyNamesToGetters") String> lists = Lists.newArrayList(propertyNamesToGetters.keySet());
        lists.sort(String.CASE_INSENSITIVE_ORDER);
        for (String propertyName : lists) {
            Method method = propertyNamesToGetters.get(propertyName);
            String printableType = method.getReturnType().getSimpleName();
            if (method.getReturnType().isEnum()) {
                Object @Nullable [] enumConstants = method.getReturnType().getEnumConstants();
                assert enumConstants != null : "@AssumeAssertion(nullness): checked that it is an enum";
                printableType = Joiner.on(" | ").join(method.getReturnType().getEnumConstants());
            }
            out.format("  --%s=<%s>%n", propertyName, printableType);
            Optional<String> defaultValue = getDefaultValueFromAnnotation(method);
            if (defaultValue.isPresent()) {
                out.format("    Default: %s%n", defaultValue.get());
            }
            @Nullable Description methodDescription = method.getAnnotation(Description.class);
            if (methodDescription != null && methodDescription.value() != null) {
                prettyPrintDescription(out, methodDescription);
            }
            prettyPrintRequiredGroups(out, method.getAnnotation(Validation.Required.class), requiredGroupNameToProperties);
        }
        out.println();
    }
}
Also used : Method(java.lang.reflect.Method) AnnotatedMethod(com.fasterxml.jackson.databind.introspect.AnnotatedMethod) Required(org.apache.beam.sdk.options.Validation.Required) ImmutableMap(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Aggregations

Method (java.lang.reflect.Method)3 Required (org.apache.beam.sdk.options.Validation.Required)3 AnnotatedMethod (com.fasterxml.jackson.databind.introspect.AnnotatedMethod)1 Map (java.util.Map)1 SortedMap (java.util.SortedMap)1 TreeMap (java.util.TreeMap)1 ImmutableMap (org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableMap)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1