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;
}
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;
}
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();
}
}
Aggregations