NIFI-430: Added isExpressionLanguageSupported and isExpressionLanguagePresent methods to ValidationContext

This commit is contained in:
Mark Payne 2015-03-23 15:02:03 -04:00
parent 220ec94c09
commit 2429e0540f
6 changed files with 175 additions and 21 deletions

View File

@ -187,9 +187,8 @@ public abstract class AbstractConfigurableComponent implements ConfigurableCompo
}
public final List<PropertyDescriptor> getPropertyDescriptors() {
final List<PropertyDescriptor> descriptors = new ArrayList<>();
descriptors.addAll(getSupportedPropertyDescriptors());
return descriptors;
final List<PropertyDescriptor> supported = getSupportedPropertyDescriptors();
return supported == null ? Collections.<PropertyDescriptor>emptyList() :new ArrayList<>(supported);
}
@Override

View File

@ -79,4 +79,23 @@ public interface ValidationContext {
* @return
*/
String getAnnotationData();
/**
* Returns <code>true</code> if the given value contains a NiFi Expression Language expression,
* <code>false</code> if it does not
*
* @param value
* @return
*/
boolean isExpressionLanguagePresent(String value);
/**
* Returns <code>true</code> if the property with the given name supports the NiFi Expression Language,
* <code>false</code> if the property does not support the Expression Language or is not a valid property
* name
*
* @param propertyName
* @return
*/
boolean isExpressionLanguageSupported(String propertyName);
}

View File

@ -46,7 +46,10 @@ public class StandardValidators {
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
final ValidationResult.Builder builder = new ValidationResult.Builder();
builder.subject(subject).input(input);
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return builder.valid(true).explanation("Contains Expression Language").build();
}
try {
FlowFile.KeyValidator.validateKey(input);
builder.valid(true);
@ -63,7 +66,10 @@ public class StandardValidators {
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
final ValidationResult.Builder builder = new ValidationResult.Builder();
builder.subject("Property Name").input(subject);
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return builder.valid(true).explanation("Contains Expression Language").build();
}
try {
FlowFile.KeyValidator.validateKey(subject);
builder.valid(true);
@ -78,6 +84,10 @@ public class StandardValidators {
public static final Validator POSITIVE_INTEGER_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
String reason = null;
try {
final int intVal = Integer.parseInt(value);
@ -96,6 +106,10 @@ public class StandardValidators {
public static final Validator POSITIVE_LONG_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
String reason = null;
try {
final long longVal = Long.parseLong(value);
@ -123,6 +137,10 @@ public class StandardValidators {
public static final Validator BOOLEAN_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
final boolean valid = "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value);
final String explanation = valid ? null : "Value must be 'true' or 'false'";
return new ValidationResult.Builder().subject(subject).input(value).valid(valid).explanation(explanation).build();
@ -132,6 +150,10 @@ public class StandardValidators {
public static final Validator INTEGER_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
String reason = null;
try {
Integer.parseInt(value);
@ -146,6 +168,10 @@ public class StandardValidators {
public static final Validator LONG_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
String reason = null;
try {
Long.parseLong(value);
@ -160,6 +186,10 @@ public class StandardValidators {
public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
String reason = null;
try {
final int intVal = Integer.parseInt(value);
@ -178,6 +208,10 @@ public class StandardValidators {
public static final Validator CHARACTER_SET_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
String reason = null;
try {
if (!Charset.isSupported(value)) {
@ -201,6 +235,10 @@ public class StandardValidators {
public static final Validator URI_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
try {
new URI(input);
return new ValidationResult.Builder().subject(subject).input(input).explanation("Valid URI").valid(true).build();
@ -215,6 +253,10 @@ public class StandardValidators {
public static final Validator ATTRIBUTE_EXPRESSION_LANGUAGE_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
try {
context.newExpressionLanguageCompiler().compile(input);
return new ValidationResult.Builder().subject(subject).input(input).valid(true).build();
@ -228,6 +270,10 @@ public class StandardValidators {
public static final Validator TIME_PERIOD_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
if (input == null) {
return new ValidationResult.Builder().subject(subject).input(input).valid(false).explanation("Time Period cannot be null").build();
}
@ -242,6 +288,10 @@ public class StandardValidators {
public static final Validator DATA_SIZE_VALIDATOR = new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
if (input == null) {
return new ValidationResult.Builder().subject(subject).input(input).valid(false).explanation("Data Size cannot be null").build();
}
@ -268,6 +318,10 @@ public class StandardValidators {
return new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
try {
final String evaluatedInput = context.newPropertyValue(input).evaluateAttributeExpressions().getValue();
new URL(evaluatedInput);
@ -292,6 +346,10 @@ public class StandardValidators {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
final ValidationResult vr = DATA_SIZE_VALIDATOR.validate(subject, input, context);
if(!vr.isValid()){
return vr;
@ -313,6 +371,10 @@ public class StandardValidators {
return new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
final boolean matches = pattern.matcher(input).matches();
return new ValidationResult.Builder()
.input(input)
@ -394,6 +456,10 @@ public class StandardValidators {
return new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
String reason = null;
try {
final long longVal = Long.parseLong(input);
@ -436,6 +502,10 @@ public class StandardValidators {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
if (input == null) {
return new ValidationResult.Builder().subject(subject).input(input).valid(false).explanation("Time Period cannot be null").build();
}
@ -469,6 +539,10 @@ public class StandardValidators {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
final String substituted;
if (allowEL) {
try {
@ -500,6 +574,10 @@ public class StandardValidators {
@Override
public ValidationResult validate(final String subject, final String value, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(value) ) {
return new ValidationResult.Builder().subject(subject).input(value).explanation("Expression Language Present").valid(true).build();
}
final String substituted;
if (allowEL) {
try {
@ -541,6 +619,10 @@ public class StandardValidators {
return new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if ( context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input) ) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").build();
}
final ControllerService svc = context.getControllerServiceLookup().getControllerService(input);
if (svc == null) {

View File

@ -21,10 +21,11 @@ import static org.junit.Assert.assertTrue;
import java.util.concurrent.TimeUnit;
import org.apache.nifi.components.ValidationContext;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.components.Validator;
import org.junit.Test;
import org.mockito.Mockito;
public class TestStandardValidators {
@ -33,22 +34,24 @@ public class TestStandardValidators {
Validator val = StandardValidators.createTimePeriodValidator(1L, TimeUnit.SECONDS, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
ValidationResult vr;
vr = val.validate("TimePeriodTest", "0 sense made", null);
final ValidationContext validationContext = Mockito.mock(ValidationContext.class);
vr = val.validate("TimePeriodTest", "0 sense made", validationContext);
assertFalse(vr.isValid());
vr = val.validate("TimePeriodTest", null, null);
vr = val.validate("TimePeriodTest", null, validationContext);
assertFalse(vr.isValid());
vr = val.validate("TimePeriodTest", "0 secs", null);
vr = val.validate("TimePeriodTest", "0 secs", validationContext);
assertFalse(vr.isValid());
vr = val.validate("TimePeriodTest", "999 millis", null);
vr = val.validate("TimePeriodTest", "999 millis", validationContext);
assertFalse(vr.isValid());
vr = val.validate("TimePeriodTest", "999999999 nanos", null);
vr = val.validate("TimePeriodTest", "999999999 nanos", validationContext);
assertFalse(vr.isValid());
vr = val.validate("TimePeriodTest", "1 sec", null);
vr = val.validate("TimePeriodTest", "1 sec", validationContext);
assertTrue(vr.isValid());
}
@ -57,28 +60,29 @@ public class TestStandardValidators {
Validator val = StandardValidators.createDataSizeBoundsValidator(100, 1000);
ValidationResult vr;
vr = val.validate("DataSizeBounds", "5 GB", null);
final ValidationContext validationContext = Mockito.mock(ValidationContext.class);
vr = val.validate("DataSizeBounds", "5 GB", validationContext);
assertFalse(vr.isValid());
vr = val.validate("DataSizeBounds", "0 B", null);
vr = val.validate("DataSizeBounds", "0 B", validationContext);
assertFalse(vr.isValid());
vr = val.validate("DataSizeBounds", "99 B", null);
vr = val.validate("DataSizeBounds", "99 B", validationContext);
assertFalse(vr.isValid());
vr = val.validate("DataSizeBounds", "100 B", null);
vr = val.validate("DataSizeBounds", "100 B", validationContext);
assertTrue(vr.isValid());
vr = val.validate("DataSizeBounds", "999 B", null);
vr = val.validate("DataSizeBounds", "999 B", validationContext);
assertTrue(vr.isValid());
vr = val.validate("DataSizeBounds", "1000 B", null);
vr = val.validate("DataSizeBounds", "1000 B", validationContext);
assertTrue(vr.isValid());
vr = val.validate("DataSizeBounds", "1001 B", null);
vr = val.validate("DataSizeBounds", "1001 B", validationContext);
assertFalse(vr.isValid());
vr = val.validate("DataSizeBounds", "water", null);
vr = val.validate("DataSizeBounds", "water", validationContext);
assertFalse(vr.isValid());
}

View File

@ -16,9 +16,13 @@
*/
package org.apache.nifi.util;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.nifi.attribute.expression.language.Query;
import org.apache.nifi.attribute.expression.language.Query.Range;
import org.apache.nifi.attribute.expression.language.StandardExpressionLanguageCompiler;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
@ -30,9 +34,16 @@ import org.apache.nifi.expression.ExpressionLanguageCompiler;
public class MockValidationContext implements ValidationContext, ControllerServiceLookup {
private final MockProcessContext context;
private final Map<String, Boolean> expressionLanguageSupported;
public MockValidationContext(final MockProcessContext processContext) {
this.context = processContext;
final Map<PropertyDescriptor, String> properties = processContext.getProperties();
expressionLanguageSupported = new HashMap<>(properties.size());
for ( final PropertyDescriptor descriptor : properties.keySet() ) {
expressionLanguageSupported.put(descriptor.getName(), descriptor.isExpressionLanguageSupported());
}
}
@Override
@ -90,4 +101,20 @@ public class MockValidationContext implements ValidationContext, ControllerServi
public boolean isControllerServiceEnabled(final ControllerService service) {
return context.isControllerServiceEnabled(service);
}
@Override
public boolean isExpressionLanguagePresent(final String value) {
if ( value == null ) {
return false;
}
final List<Range> elRanges = Query.extractExpressionRanges(value);
return (elRanges != null && !elRanges.isEmpty());
}
@Override
public boolean isExpressionLanguageSupported(final String propertyName) {
final Boolean supported = expressionLanguageSupported.get(propertyName);
return Boolean.TRUE.equals(supported);
}
}

View File

@ -18,10 +18,12 @@ package org.apache.nifi.processor;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.nifi.attribute.expression.language.PreparedQuery;
import org.apache.nifi.attribute.expression.language.Query;
import org.apache.nifi.attribute.expression.language.Query.Range;
import org.apache.nifi.attribute.expression.language.StandardExpressionLanguageCompiler;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
@ -37,6 +39,7 @@ public class StandardValidationContext implements ValidationContext {
private final ControllerServiceProvider controllerServiceProvider;
private final Map<PropertyDescriptor, String> properties;
private final Map<PropertyDescriptor, PreparedQuery> preparedQueries;
private final Map<String, Boolean> expressionLanguageSupported;
private final String annotationData;
public StandardValidationContext(final ControllerServiceProvider controllerServiceProvider, final Map<PropertyDescriptor, String> properties, final String annotationData) {
@ -44,7 +47,7 @@ public class StandardValidationContext implements ValidationContext {
this.properties = new HashMap<>(properties);
this.annotationData = annotationData;
preparedQueries = new HashMap<>();
preparedQueries = new HashMap<>(properties.size());
for (final Map.Entry<PropertyDescriptor, String> entry : properties.entrySet()) {
final PropertyDescriptor desc = entry.getKey();
String value = entry.getValue();
@ -56,6 +59,10 @@ public class StandardValidationContext implements ValidationContext {
preparedQueries.put(desc, pq);
}
expressionLanguageSupported = new HashMap<>(properties.size());
for ( final PropertyDescriptor descriptor : properties.keySet() ) {
expressionLanguageSupported.put(descriptor.getName(), descriptor.isExpressionLanguageSupported());
}
}
@Override
@ -94,4 +101,20 @@ public class StandardValidationContext implements ValidationContext {
public ControllerServiceLookup getControllerServiceLookup() {
return controllerServiceProvider;
}
@Override
public boolean isExpressionLanguagePresent(final String value) {
if ( value == null ) {
return false;
}
final List<Range> elRanges = Query.extractExpressionRanges(value);
return (elRanges != null && !elRanges.isEmpty());
}
@Override
public boolean isExpressionLanguageSupported(final String propertyName) {
final Boolean supported = expressionLanguageSupported.get(propertyName);
return Boolean.TRUE.equals(supported);
}
}