in src/main/java/org/apache/nifi/components/PropertyDescriptor.java [827:909]
public ValidationResult validate(final String subject, final String configuredInput, final ValidationContext context) {
final ValidationResult.Builder resultBuilder = new ValidationResult.Builder()
.input(configuredInput)
.subject(subject);
if (configuredInput == null) {
return resultBuilder.valid(false)
.explanation("No value specified")
.build();
}
// If Expression Language is supported and is used in the property value, we cannot perform validation against the configured
// input unless the Expression Language is expressly limited to only env/syst properties variables. In that case, we can evaluate
// it and then validate the value after evaluating the Expression Language.
String input = configuredInput;
if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(configuredInput)) {
if (expressionLanguageScope != null && expressionLanguageScope == ExpressionLanguageScope.ENVIRONMENT) {
input = context.newPropertyValue(configuredInput).evaluateAttributeExpressions().getValue();
resultBuilder.input(input);
} else {
return resultBuilder.valid(true)
.explanation("Expression Language is present, so validation of property value cannot be performed")
.build();
}
}
// If the property can be text, then there's nothing to validate. Anything that is entered may be valid.
// This will be improved in the future, by allowing the user to specify the type of resource that is being referenced.
// Until then, we will simply require that the component perform any necessary validation.
final boolean allowsText = resourceDefinition.getResourceTypes().contains(ResourceType.TEXT);
if (allowsText) {
return resultBuilder.valid(true)
.explanation("Property allows for Resource Type of Text, so validation of property value cannot be performed")
.build();
}
final String[] splits = input.split(",");
if (resourceDefinition.getCardinality() == ResourceCardinality.SINGLE && splits.length > 1) {
return resultBuilder.valid(false)
.explanation("Property only supports a single Resource but " + splits.length + " resources were specified")
.build();
}
final Set<ResourceType> resourceTypes = resourceDefinition.getResourceTypes();
final List<String> nonExistentResources = new ArrayList<>();
int count = 0;
for (final String split : splits) {
final ResourceReference resourceReference = new StandardResourceReferenceFactory().createResourceReference(split, resourceDefinition);
if (resourceReference == null) {
continue;
}
count++;
final boolean accessible = resourceReference.isAccessible();
if (!accessible) {
nonExistentResources.add(resourceReference.getLocation());
continue;
}
if (!resourceTypes.contains(resourceReference.getResourceType())) {
return resultBuilder.valid(false)
.explanation("Specified Resource is a " + resourceReference.getResourceType().name() + " but this property does not allow this type of resource")
.build();
}
}
if (count == 0) {
return resultBuilder.valid(false)
.explanation("No resources were specified")
.build();
}
if (!nonExistentResources.isEmpty()) {
return resultBuilder.valid(false)
.explanation("The specified resource(s) do not exist or could not be accessed: " + nonExistentResources)
.build();
}
return resultBuilder.valid(true)
.build();
}