mirror of https://github.com/apache/nifi.git
NIFI-12573 Improved support for Enums in PropertyDescriptor.Builder
NIFI-12574 Add clearDefaultValue to PropertyDescriptor.Builder This closes #8211 Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
281a28c5d4
commit
4588c6c37e
|
@ -43,9 +43,8 @@ public class AllowableValue implements DescribedValue {
|
|||
* Constructs a new AllowableValue with the given value and display name and
|
||||
* no description
|
||||
*
|
||||
* @param value that is allowed
|
||||
* @param value that is allowed
|
||||
* @param displayName to display for the value
|
||||
*
|
||||
* @throws NullPointerException if either argument is null
|
||||
*/
|
||||
public AllowableValue(final String value, final String displayName) {
|
||||
|
@ -56,10 +55,9 @@ public class AllowableValue implements DescribedValue {
|
|||
* Constructs a new AllowableValue with the given value, display name, and
|
||||
* description
|
||||
*
|
||||
* @param value that is valid
|
||||
* @param value that is valid
|
||||
* @param displayName to show for the value
|
||||
* @param description of the value
|
||||
*
|
||||
* @throws NullPointerException if identifier or value is null
|
||||
*/
|
||||
public AllowableValue(final String value, final String displayName, final String description) {
|
||||
|
@ -68,6 +66,14 @@ public class AllowableValue implements DescribedValue {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
public static AllowableValue fromDescribedValue(final DescribedValue describedValue) {
|
||||
if (describedValue instanceof AllowableValue allowableValue) {
|
||||
return allowableValue;
|
||||
}
|
||||
|
||||
return new AllowableValue(describedValue.getValue(), describedValue.getDisplayName(), describedValue.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of this AllowableValue
|
||||
*/
|
||||
|
@ -106,8 +112,7 @@ public class AllowableValue implements DescribedValue {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof AllowableValue) {
|
||||
final AllowableValue other = (AllowableValue) obj;
|
||||
if (obj instanceof AllowableValue other) {
|
||||
return (this.value.equals(other.getValue()));
|
||||
} else if (obj instanceof String) {
|
||||
return this.value.equals(obj);
|
||||
|
|
|
@ -19,9 +19,9 @@ package org.apache.nifi.components;
|
|||
import org.apache.nifi.components.resource.ResourceCardinality;
|
||||
import org.apache.nifi.components.resource.ResourceDefinition;
|
||||
import org.apache.nifi.components.resource.ResourceReference;
|
||||
import org.apache.nifi.components.resource.StandardResourceReferenceFactory;
|
||||
import org.apache.nifi.components.resource.ResourceType;
|
||||
import org.apache.nifi.components.resource.StandardResourceDefinition;
|
||||
import org.apache.nifi.components.resource.StandardResourceReferenceFactory;
|
||||
import org.apache.nifi.controller.ControllerService;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
|
||||
|
@ -38,7 +38,6 @@ import java.util.Set;
|
|||
/**
|
||||
* An immutable object for holding information about a type of component
|
||||
* property.
|
||||
*
|
||||
*/
|
||||
public final class PropertyDescriptor implements Comparable<PropertyDescriptor> {
|
||||
|
||||
|
@ -123,15 +122,15 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
this.name = builder.name;
|
||||
this.description = builder.description;
|
||||
this.defaultValue = builder.defaultValue;
|
||||
this.allowableValues = builder.allowableValues == null ? null : Collections.unmodifiableList(new ArrayList<>(builder.allowableValues));
|
||||
this.allowableValues = builder.allowableValues == null ? null : List.copyOf(builder.allowableValues);
|
||||
this.required = builder.required;
|
||||
this.sensitive = builder.sensitive;
|
||||
this.dynamic = builder.dynamic;
|
||||
this.dynamicallyModifiesClasspath = builder.dynamicallyModifiesClasspath;
|
||||
this.expressionLanguageScope = builder.expressionLanguageScope;
|
||||
this.controllerServiceDefinition = builder.controllerServiceDefinition;
|
||||
this.validators = Collections.unmodifiableList(new ArrayList<>(builder.validators));
|
||||
this.dependencies = builder.dependencies == null ? Collections.emptySet() : Collections.unmodifiableSet(new HashSet<>(builder.dependencies));
|
||||
this.validators = List.copyOf(builder.validators);
|
||||
this.dependencies = builder.dependencies == null ? Collections.emptySet() : Set.copyOf(builder.dependencies);
|
||||
this.resourceDefinition = builder.resourceDefinition;
|
||||
}
|
||||
|
||||
|
@ -148,7 +147,7 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* If this descriptor has a set of allowable values then the given value is
|
||||
* only checked against the allowable values.
|
||||
*
|
||||
* @param input the value to validate
|
||||
* @param input the value to validate
|
||||
* @param context the context of validation
|
||||
* @return the result of validating the input
|
||||
*/
|
||||
|
@ -188,15 +187,15 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
final ControllerService service = context.getControllerServiceLookup().getControllerService(input);
|
||||
if (service == null) {
|
||||
return new ValidationResult.Builder()
|
||||
.input(input)
|
||||
.subject(getDisplayName())
|
||||
.valid(false)
|
||||
.explanation("Property references a Controller Service that does not exist")
|
||||
.build();
|
||||
.input(input)
|
||||
.subject(getDisplayName())
|
||||
.valid(false)
|
||||
.explanation("Property references a Controller Service that does not exist")
|
||||
.build();
|
||||
} else {
|
||||
return new ValidationResult.Builder()
|
||||
.valid(true)
|
||||
.build();
|
||||
.valid(true)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,15 +292,13 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
}
|
||||
|
||||
/**
|
||||
* Specifies the initial value and the default value that will be used
|
||||
* if the user does not specify a value. When {@link #build()} is
|
||||
* called, if Allowable Values have been set (see
|
||||
* {@link #allowableValues(AllowableValue...)}) and this value is not
|
||||
* one of those Allowable Values, an Exception will be thrown. If the
|
||||
* Allowable Values have been set using the
|
||||
* {@link #allowableValues(AllowableValue...)} method, the default value
|
||||
* should be set to the "Value" of the {@link AllowableValue} object
|
||||
* (see {@link AllowableValue#getValue()}).
|
||||
* Specifies the initial value and the default value that will be used if the user does not specify a value.
|
||||
* <p>
|
||||
* When {@link #build()} is called, if Allowable Values have been set (see {@link #allowableValues(DescribedValue...)} and overloads)
|
||||
* and this value is not one of those Allowable Values, an Exception will be thrown.
|
||||
* If the Allowable Values have been set, the default value should be set to
|
||||
* the "Value" of the {@link DescribedValue} object (see {@link DescribedValue#getValue()}).
|
||||
* There's an overload available for this (see {@link #defaultValue(DescribedValue)}).
|
||||
*
|
||||
* @param value default value
|
||||
* @return the builder
|
||||
|
@ -314,15 +311,12 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
}
|
||||
|
||||
/**
|
||||
* Specifies the initial value and the default value that will be used
|
||||
* if the user does not specify a value. When {@link #build()} is
|
||||
* called, if Allowable Values have been set (see
|
||||
* {@link #allowableValues(AllowableValue...)})
|
||||
* and the "Value" of the {@link DescribedValue} object is not
|
||||
* the "Value" of one of those Allowable Values, an Exception will be thrown.
|
||||
* If the Allowable Values have been set using the
|
||||
* {@link #allowableValues(AllowableValue...)} method, the default value
|
||||
* should be set providing the {@link AllowableValue} to this method.
|
||||
* Specifies the initial value and the default value that will be used if the user does not specify a value.
|
||||
* <p>
|
||||
* Sets the default value to the "Value" of the {@link DescribedValue} object.
|
||||
* When {@link #build()} is called, if Allowable Values have been set (see {@link #allowableValues(DescribedValue...)} and overloads)
|
||||
* and this value is not one of those Allowable Values, an Exception will be thrown.
|
||||
* In case there is not a restricted set of Allowable Values {@link #defaultValue(String)} may be used.
|
||||
*
|
||||
* @param value default value holder
|
||||
* @return the builder
|
||||
|
@ -331,6 +325,16 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
return defaultValue(value != null ? value.getValue() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the initial value and default value from this Property.
|
||||
*
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder clearDefaultValue() {
|
||||
this.defaultValue = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder dynamic(final boolean dynamic) {
|
||||
this.dynamic = dynamic;
|
||||
return this;
|
||||
|
@ -342,17 +346,17 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* libraries for the given component.
|
||||
* <p/>
|
||||
* NOTE: If a component contains a PropertyDescriptor where dynamicallyModifiesClasspath is set to true,
|
||||
* the component may also be annotated with @RequiresInstanceClassloading, in which case every class will
|
||||
* be loaded by a separate InstanceClassLoader for each processor instance.<br/>
|
||||
* It also allows to load native libraries from the extra classpath.
|
||||
* <p/>
|
||||
* One can chose to omit the annotation. In this case the loading of native libraries from the extra classpath
|
||||
* is not supported.
|
||||
* Also by default, classes will be loaded by a common NarClassLoader, however it's possible to acquire an
|
||||
* InstanceClassLoader by calling Thread.currentThread().getContextClassLoader() which can be used manually
|
||||
* to load required classes on an instance-by-instance basis
|
||||
* (by calling {@link Class#forName(String, boolean, ClassLoader)} for example).
|
||||
*
|
||||
* the component may also be annotated with @RequiresInstanceClassloading, in which case every class will
|
||||
* be loaded by a separate InstanceClassLoader for each processor instance.<br/>
|
||||
* It also allows to load native libraries from the extra classpath.
|
||||
* <p/>
|
||||
* One can choose to omit the annotation. In this case the loading of native libraries from the extra classpath
|
||||
* is not supported.
|
||||
* Also by default, classes will be loaded by a common NarClassLoader, however it's possible to acquire an
|
||||
* InstanceClassLoader by calling Thread.currentThread().getContextClassLoader() which can be used manually
|
||||
* to load required classes on an instance-by-instance basis
|
||||
* (by calling {@link Class#forName(String, boolean, ClassLoader)} for example).
|
||||
* <p>
|
||||
* Any property descriptor that dynamically modifies the classpath should also make use of the {@link #identifiesExternalResource(ResourceCardinality, ResourceType, ResourceType...)} method
|
||||
* to indicate that the property descriptor references external resources and optionally restrict which types of resources and how many resources the property allows.
|
||||
*
|
||||
|
@ -365,68 +369,99 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
}
|
||||
|
||||
/**
|
||||
* @param values contrained set of values
|
||||
* Sets the Allowable Values for this Property.
|
||||
*
|
||||
* @param values constrained set of values
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder allowableValues(final Set<String> values) {
|
||||
if (null != values) {
|
||||
this.allowableValues = new ArrayList<>();
|
||||
|
||||
for (final String value : values) {
|
||||
this.allowableValues.add(new AllowableValue(value, value));
|
||||
}
|
||||
this.allowableValues = values.stream().map(AllowableValue::new).toList();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Allowable Values for this Property.
|
||||
* <p>
|
||||
* Uses the {@link Enum#name()} of each value as "Value" for the {@link AllowableValue}.
|
||||
* In case the enum value is a {@link DescribedValue}, uses the information provided instead
|
||||
* (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()}, {@link DescribedValue#getDescription()}).
|
||||
*
|
||||
* @param values constrained set of values
|
||||
* @return the builder
|
||||
*/
|
||||
public <E extends Enum<E>> Builder allowableValues(final E[] values) {
|
||||
if (null != values) {
|
||||
this.allowableValues = new ArrayList<>();
|
||||
for (final E value : values) {
|
||||
allowableValues.add(new AllowableValue(value.name(), value.name()));
|
||||
}
|
||||
this.allowableValues = Arrays.stream(values)
|
||||
.map(enumValue -> enumValue instanceof DescribedValue describedValue
|
||||
? AllowableValue.fromDescribedValue(describedValue) : new AllowableValue(enumValue.name()))
|
||||
.toList();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores allowable values from an enum class.
|
||||
* @param enumClass an enum class that implements the DescribedValue interface and contains a set of values
|
||||
* @param <E> generic parameter for an enum class that implements the DescribedValue interface
|
||||
* Sets the Allowable Values for this Property.
|
||||
* <p>
|
||||
* Uses the {@link Enum#name()} of each value from {@link Class#getEnumConstants()} as "Value" for the {@link AllowableValue}.
|
||||
* In case the enum value is a {@link DescribedValue}, uses the information provided instead
|
||||
* (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()}, {@link DescribedValue#getDescription()}).
|
||||
*
|
||||
* @param enumClass an enum class that contains a set of values and optionally implements the DescribedValue interface
|
||||
* @param <E> generic parameter for an enum class, that may implement the DescribedValue interface
|
||||
* @return the builder
|
||||
*/
|
||||
public <E extends Enum<E> & DescribedValue> Builder allowableValues(final Class<E> enumClass) {
|
||||
this.allowableValues = new ArrayList<>();
|
||||
for (E enumValue : enumClass.getEnumConstants()) {
|
||||
this.allowableValues.add(new AllowableValue(enumValue.getValue(), enumValue.getDisplayName(), enumValue.getDescription()));
|
||||
}
|
||||
return this;
|
||||
public <E extends Enum<E>> Builder allowableValues(final Class<E> enumClass) {
|
||||
return allowableValues(enumClass.getEnumConstants());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores allowable values from a set of enum values.
|
||||
* @param enumValues a set of enum values that implements the DescribedValue interface
|
||||
* @param <E> generic parameter for the enum values' class that implements the DescribedValue interface
|
||||
* Sets the Allowable Values for this Property.
|
||||
* <p>
|
||||
* Uses the {@link Enum#name()} of each value of the {@link EnumSet} as "Value" for the {@link AllowableValue}.
|
||||
* In case the enum value is a {@link DescribedValue}, uses the information provided instead
|
||||
* (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()}, {@link DescribedValue#getDescription()}).
|
||||
*
|
||||
* @param enumValues an enum set that contains a set of values and optionally implements the DescribedValue interface
|
||||
* @param <E> generic parameter for an enum class, that may implement the DescribedValue interface
|
||||
* @return the builder
|
||||
*/
|
||||
public <E extends Enum<E> & DescribedValue> Builder allowableValues(final EnumSet<E> enumValues) {
|
||||
this.allowableValues = new ArrayList<>();
|
||||
for (E enumValue : enumValues) {
|
||||
this.allowableValues.add(new AllowableValue(enumValue.getValue(), enumValue.getDisplayName(), enumValue.getDescription()));
|
||||
public <E extends Enum<E>> Builder allowableValues(final EnumSet<E> enumValues) {
|
||||
if (null != enumValues) {
|
||||
this.allowableValues = enumValues.stream()
|
||||
.map(enumValue -> enumValue instanceof DescribedValue describedValue
|
||||
? AllowableValue.fromDescribedValue(describedValue) : new AllowableValue(enumValue.name()))
|
||||
.toList();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Allowable Values for this Property.
|
||||
*
|
||||
* @param values constrained set of values
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder allowableValues(final String... values) {
|
||||
if (null != values) {
|
||||
this.allowableValues = new ArrayList<>();
|
||||
for (final String value : values) {
|
||||
allowableValues.add(new AllowableValue(value, value));
|
||||
}
|
||||
this.allowableValues = Arrays.stream(values).map(AllowableValue::new).toList();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Allowable Values for this Property.
|
||||
* <p>
|
||||
* Uses the information provided by each {@link DescribedValue} (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()},
|
||||
* {@link DescribedValue#getDescription()}) to populate the {@link AllowableValue}s.
|
||||
*
|
||||
* @param values constrained set of values
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder allowableValues(final DescribedValue... values) {
|
||||
if (null != values) {
|
||||
this.allowableValues = Arrays.stream(values).map(AllowableValue::fromDescribedValue).toList();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -441,19 +476,6 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Allowable Values for this Property
|
||||
*
|
||||
* @param values contrained set of values
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder allowableValues(final AllowableValue... values) {
|
||||
if (null != values) {
|
||||
this.allowableValues = Arrays.asList(values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param required true if yes; false otherwise
|
||||
* @return the builder
|
||||
|
@ -498,7 +520,7 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* Service that implements the given interface
|
||||
*
|
||||
* @param controllerServiceDefinition the interface that is implemented
|
||||
* by the Controller Service
|
||||
* by the Controller Service
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder identifiesControllerService(final Class<? extends ControllerService> controllerServiceDefinition) {
|
||||
|
@ -533,12 +555,12 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* </li>
|
||||
* <li>If the ResourceCardinality is MULTIPLE, the given property value may consist of one or more resources, each separted by a comma and optional white space.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Generally, any property descriptor that makes use of the {@link #dynamicallyModifiesClasspath(boolean)} method to dynamically update its classpath should also
|
||||
* make use of this method, specifying which types of resources are allowed and how many.
|
||||
*
|
||||
* @param cardinality specifies how many resources the property should allow
|
||||
* @param resourceType the type of resource that is allowed
|
||||
* @param cardinality specifies how many resources the property should allow
|
||||
* @param resourceType the type of resource that is allowed
|
||||
* @param additionalResourceTypes if more than one type of resource is allowed, any resource type in addition to the given resource type may be provided
|
||||
* @return the builder
|
||||
*/
|
||||
|
@ -558,15 +580,15 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* Establishes a relationship between this Property and the given property by declaring that this Property is only relevant if the given Property has a non-null value.
|
||||
* Furthermore, if one or more explicit Allowable Values are provided, this Property will not be relevant unless the given Property's value is equal to one of the given Allowable Values.
|
||||
* If this method is called multiple times, each with a different dependency, then a relationship is established such that this Property is relevant only if all dependencies are satisfied.
|
||||
*
|
||||
* <p>
|
||||
* In the case that this property is NOT considered to be relevant (meaning that it depends on a property whose value is not specified, or whose value does not match one of the given
|
||||
* Allowable Values), the property will not be shown in the component's configuration in the User Interface. Additionally, this property's value will not be considered for
|
||||
* validation. That is, if this property is configured with an invalid value and this property depends on Property Foo, and Property Foo does not have a value set, then the component
|
||||
* will still be valid, because the value of this property is irrelevant.
|
||||
*
|
||||
* <p>
|
||||
* If the given property is not relevant (because its dependencies are not satisfied), this property is also considered not to be valid.
|
||||
*
|
||||
* @param property the property that must be set in order for this property to become relevant
|
||||
* @param property the property that must be set in order for this property to become relevant
|
||||
* @param dependentValues the possible values for the given property for which this Property is relevant
|
||||
* @return the builder
|
||||
*/
|
||||
|
@ -593,16 +615,16 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* Establishes a relationship between this Property and the given property by declaring that this Property is only relevant if the given Property has a value equal to one of the given
|
||||
* <code>String</code> arguments.
|
||||
* If this method is called multiple times, each with a different dependency, then a relationship is established such that this Property is relevant only if all dependencies are satisfied.
|
||||
*
|
||||
* <p>
|
||||
* In the case that this property is NOT considered to be relevant (meaning that it depends on a property whose value is not specified, or whose value does not match one of the given
|
||||
* Allowable Values), the property will not be shown in the component's configuration in the User Interface. Additionally, this property's value will not be considered for
|
||||
* validation. That is, if this property is configured with an invalid value and this property depends on Property Foo, and Property Foo does not have a value set, then the component
|
||||
* will still be valid, because the value of this property is irrelevant.
|
||||
*
|
||||
* <p>
|
||||
* If the given property is not relevant (because its dependencies are not satisfied), this property is also considered not to be valid.
|
||||
*
|
||||
* @param property the property that must be set in order for this property to become relevant
|
||||
* @param firstDependentValue the first value for the given property for which this Property is relevant
|
||||
* @param property the property that must be set in order for this property to become relevant
|
||||
* @param firstDependentValue the first value for the given property for which this Property is relevant
|
||||
* @param additionalDependentValues any other values for the given property for which this Property is relevant
|
||||
* @return the builder
|
||||
*/
|
||||
|
@ -621,25 +643,25 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* Establishes a relationship between this Property and the given property by declaring that this Property is only relevant if the given Property has a value equal to one of the given
|
||||
* {@link DescribedValue} arguments.
|
||||
* If this method is called multiple times, each with a different dependency, then a relationship is established such that this Property is relevant only if all dependencies are satisfied.
|
||||
*
|
||||
* <p>
|
||||
* In the case that this property is NOT considered to be relevant (meaning that it depends on a property whose value is not specified, or whose value does not match one of the given
|
||||
* Described Values), the property will not be shown in the component's configuration in the User Interface. Additionally, this property's value will not be considered for
|
||||
* validation. That is, if this property is configured with an invalid value and this property depends on Property Foo, and Property Foo does not have a value set, then the component
|
||||
* will still be valid, because the value of this property is irrelevant.
|
||||
*
|
||||
* <p>
|
||||
* If the given property is not relevant (because its dependencies are not satisfied), this property is also considered not to be valid.
|
||||
*
|
||||
* @param property the property that must be set in order for this property to become relevant
|
||||
* @param firstDependentValue the first value for the given property for which this Property is relevant
|
||||
* @param property the property that must be set in order for this property to become relevant
|
||||
* @param firstDependentValue the first value for the given property for which this Property is relevant
|
||||
* @param additionalDependentValues any other values for the given property for which this Property is relevant
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder dependsOn(final PropertyDescriptor property, final DescribedValue firstDependentValue, final DescribedValue... additionalDependentValues) {
|
||||
final AllowableValue[] dependentValues = new AllowableValue[additionalDependentValues.length + 1];
|
||||
dependentValues[0] = toAllowableValue(firstDependentValue);
|
||||
dependentValues[0] = AllowableValue.fromDescribedValue(firstDependentValue);
|
||||
int i = 1;
|
||||
for (final DescribedValue additionalDependentValue : additionalDependentValues) {
|
||||
dependentValues[i++] = toAllowableValue(additionalDependentValue);
|
||||
dependentValues[i++] = AllowableValue.fromDescribedValue(additionalDependentValue);
|
||||
}
|
||||
|
||||
return dependsOn(property, dependentValues);
|
||||
|
@ -655,16 +677,11 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
return this;
|
||||
}
|
||||
|
||||
private AllowableValue toAllowableValue(DescribedValue describedValue) {
|
||||
return new AllowableValue(describedValue.getValue(), describedValue.getDisplayName(), describedValue.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a PropertyDescriptor as configured
|
||||
*
|
||||
* @throws IllegalStateException if allowable values are configured but
|
||||
* no default value is set, or the default value is not contained within
|
||||
* the allowable values.
|
||||
* no default value is set, or the default value is not contained within
|
||||
* the allowable values.
|
||||
*/
|
||||
public PropertyDescriptor build() {
|
||||
if (name == null) {
|
||||
|
@ -740,18 +757,14 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(other instanceof PropertyDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof PropertyDescriptor otherPropertyDescriptor) {
|
||||
return this.name.equals(otherPropertyDescriptor.name);
|
||||
}
|
||||
|
||||
final PropertyDescriptor desc = (PropertyDescriptor) other;
|
||||
return this.name.equals(desc.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -768,7 +781,7 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
|
||||
private static final String POSITIVE_EXPLANATION = "Given value found in allowed set";
|
||||
private static final String NEGATIVE_EXPLANATION = "Given value not found in allowed set '%1$s'";
|
||||
private static final String VALUE_DEMARCATOR = ", ";
|
||||
private static final String VALUE_DELIMITER = ", ";
|
||||
private final String validStrings;
|
||||
private final Collection<String> validValues;
|
||||
|
||||
|
@ -780,20 +793,8 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
* @throws NullPointerException if the given validValues is null
|
||||
*/
|
||||
private ConstrainedSetValidator(final Collection<AllowableValue> validValues) {
|
||||
String validVals = "";
|
||||
if (!validValues.isEmpty()) {
|
||||
final StringBuilder valuesBuilder = new StringBuilder();
|
||||
for (final AllowableValue value : validValues) {
|
||||
valuesBuilder.append(value).append(VALUE_DEMARCATOR);
|
||||
}
|
||||
validVals = valuesBuilder.substring(0, valuesBuilder.length() - VALUE_DEMARCATOR.length());
|
||||
}
|
||||
validStrings = validVals;
|
||||
|
||||
this.validValues = new ArrayList<>(validValues.size());
|
||||
for (final AllowableValue value : validValues) {
|
||||
this.validValues.add(value.getValue());
|
||||
}
|
||||
this.validValues = validValues.stream().map(AllowableValue::getValue).toList();
|
||||
this.validStrings = String.join(VALUE_DELIMITER, this.validValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -824,13 +825,13 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
@Override
|
||||
public ValidationResult validate(final String subject, final String configuredInput, final ValidationContext context) {
|
||||
final ValidationResult.Builder resultBuilder = new ValidationResult.Builder()
|
||||
.input(configuredInput)
|
||||
.subject(subject);
|
||||
.input(configuredInput)
|
||||
.subject(subject);
|
||||
|
||||
if (configuredInput == null) {
|
||||
return resultBuilder.valid(false)
|
||||
.explanation("No value specified")
|
||||
.build();
|
||||
.explanation("No value specified")
|
||||
.build();
|
||||
}
|
||||
|
||||
// If Expression Language is supported and is used in the property value, we cannot perform validation against the configured
|
||||
|
@ -843,8 +844,8 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
resultBuilder.input(input);
|
||||
} else {
|
||||
return resultBuilder.valid(true)
|
||||
.explanation("Expression Language is present, so validation of property value cannot be performed")
|
||||
.build();
|
||||
.explanation("Expression Language is present, so validation of property value cannot be performed")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -854,15 +855,15 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
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();
|
||||
.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();
|
||||
.explanation("Property only supports a single Resource but " + splits.length + " resources were specified")
|
||||
.build();
|
||||
}
|
||||
|
||||
final Set<ResourceType> resourceTypes = resourceDefinition.getResourceTypes();
|
||||
|
@ -885,25 +886,25 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
|
||||
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();
|
||||
.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();
|
||||
.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();
|
||||
.explanation("The specified resource(s) do not exist or could not be accessed: " + nonExistentResources)
|
||||
.build();
|
||||
}
|
||||
|
||||
return resultBuilder.valid(true)
|
||||
.build();
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
package org.apache.nifi.components;
|
||||
|
||||
public enum EnumAllowableValue implements DescribedValue {
|
||||
public enum EnumDescribedValue implements DescribedValue {
|
||||
|
||||
GREEN {
|
||||
@Override
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.components;
|
||||
|
||||
public enum EnumNotDescribedValue {
|
||||
GREEN, RED, BLUE;
|
||||
}
|
|
@ -20,17 +20,16 @@ import org.apache.nifi.components.PropertyDescriptor.Builder;
|
|||
import org.apache.nifi.components.resource.ResourceCardinality;
|
||||
import org.apache.nifi.components.resource.ResourceType;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
@ -40,77 +39,180 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
|
||||
/**
|
||||
* Regression test for issue NIFI-49, to ensure that if a Processor's Property's
|
||||
* Default Value is not allowed, the Exception thrown should indicate what the
|
||||
* default value is
|
||||
*/
|
||||
public class TestPropertyDescriptor {
|
||||
|
||||
private static Builder invalidDescriptorBuilder;
|
||||
private static Builder validDescriptorBuilder;
|
||||
private static final String DEFAULT_VALUE = "Default Value";
|
||||
private static final String DEPENDENT_PROPERTY_NAME = "dependentProperty";
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
validDescriptorBuilder = new PropertyDescriptor.Builder().name("").allowableValues("Allowable Value", "Another Allowable Value").defaultValue("Allowable Value");
|
||||
invalidDescriptorBuilder = new PropertyDescriptor.Builder().name("").allowableValues("Allowable Value", "Another Allowable Value").defaultValue(DEFAULT_VALUE);
|
||||
@Nested
|
||||
class RegardingDefaultValue {
|
||||
@Test
|
||||
void supportsStringValues() {
|
||||
final PropertyDescriptor descriptor = builder().defaultValue(DEFAULT_VALUE).build();
|
||||
|
||||
assertEquals(DEFAULT_VALUE, descriptor.getDefaultValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsDescribedValuesValues() {
|
||||
final PropertyDescriptor descriptor = builder().defaultValue(EnumDescribedValue.GREEN).build();
|
||||
|
||||
assertEquals(EnumDescribedValue.GREEN.getValue(), descriptor.getDefaultValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test for issue NIFI-49, to ensure that if a Processor's Property's
|
||||
* Default Value is not allowed, the Exception thrown should indicate what the default value is
|
||||
*/
|
||||
@Test
|
||||
void throwsIllegalStateExceptionWhenDefaultValueNotInAllowableValues() {
|
||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> {
|
||||
builder().allowableValues("NOT DEFAULT", "OTHER NOT DEFAULT").defaultValue(DEFAULT_VALUE).build();
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("[" + DEFAULT_VALUE + "]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void canBeCleared() {
|
||||
final PropertyDescriptor descriptorWithDefault = builder().defaultValue(DEFAULT_VALUE).build();
|
||||
final PropertyDescriptor resetDescriptor = builder(descriptorWithDefault).clearDefaultValue().build();
|
||||
|
||||
assertNull(resetDescriptor.getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExceptionThrownByDescriptorWithInvalidDefaultValue() {
|
||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> invalidDescriptorBuilder.build());
|
||||
assertTrue(exception.getMessage().contains("[" + DEFAULT_VALUE + "]") );
|
||||
}
|
||||
@Nested
|
||||
class RegardingAllowableValues {
|
||||
|
||||
@Test
|
||||
void testNoExceptionThrownByPropertyDescriptorWithValidDefaultValue() {
|
||||
assertNotNull(validDescriptorBuilder.build());
|
||||
}
|
||||
private static final Comparator<AllowableValue> allowableValueComparator = Comparator.comparing(AllowableValue::getValue);
|
||||
private final List<AllowableValue> expectedMinimalAllowableValues =
|
||||
List.of(new AllowableValue("GREEN"), new AllowableValue("RED"), new AllowableValue("BLUE"));
|
||||
private final List<AllowableValue> expectedAllowableValuesWithDescription =
|
||||
Arrays.stream(EnumDescribedValue.values()).map(AllowableValue::fromDescribedValue).toList();
|
||||
|
||||
@Test
|
||||
void testDefaultValueWithDescribedValue() {
|
||||
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder()
|
||||
.name("defaultDescribedValueDescriptor")
|
||||
.defaultValue(EnumAllowableValue.GREEN)
|
||||
.build();
|
||||
@Test
|
||||
void supportsStringVarArgValues() {
|
||||
final List<AllowableValue> expected = expectedMinimalAllowableValues;
|
||||
|
||||
assertNotNull(propertyDescriptor);
|
||||
assertEquals(EnumAllowableValue.GREEN.getValue(), propertyDescriptor.getDefaultValue());
|
||||
}
|
||||
final PropertyDescriptor descriptor = builder().allowableValues("GREEN", "RED", "BLUE").build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
@Test
|
||||
void testAllowableValuesWithEnumClass() {
|
||||
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder()
|
||||
.name("enumAllowableValueDescriptor")
|
||||
.allowableValues(EnumAllowableValue.class)
|
||||
.build();
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
assertNotNull(propertyDescriptor);
|
||||
@Test
|
||||
void supportsStringSetValues() {
|
||||
final List<AllowableValue> expected = sort(expectedMinimalAllowableValues);
|
||||
|
||||
final List<AllowableValue> expectedAllowableValues = Arrays.stream(EnumAllowableValue.values())
|
||||
.map(enumValue -> new AllowableValue(enumValue.getValue(), enumValue.getDisplayName(), enumValue.getDescription()))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(expectedAllowableValues, propertyDescriptor.getAllowableValues());
|
||||
}
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(Set.of("GREEN", "RED", "BLUE")).build();
|
||||
// the iteration order of sets is not guaranteed by all implementations, thus we unify the order here
|
||||
final List<AllowableValue> actual = sort(descriptor.getAllowableValues());
|
||||
|
||||
@Test
|
||||
void testAllowableValuesWithEnumSet() {
|
||||
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder()
|
||||
.name("enumAllowableValueDescriptor")
|
||||
.allowableValues(EnumSet.of(
|
||||
EnumAllowableValue.GREEN,
|
||||
EnumAllowableValue.BLUE
|
||||
))
|
||||
.build();
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
assertNotNull(propertyDescriptor);
|
||||
@Test
|
||||
void supportsEnumArrayValues() {
|
||||
final List<AllowableValue> expected = expectedMinimalAllowableValues;
|
||||
|
||||
final List<AllowableValue> expectedAllowableValues = Stream.of(EnumAllowableValue.GREEN, EnumAllowableValue.BLUE)
|
||||
.map(enumValue -> new AllowableValue(enumValue.getValue(), enumValue.getDisplayName(), enumValue.getDescription()))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(expectedAllowableValues, propertyDescriptor.getAllowableValues());
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(EnumNotDescribedValue.values()).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
void supportsDescribedValueEnumArrayValues() {
|
||||
final List<AllowableValue> expected = expectedAllowableValuesWithDescription;
|
||||
|
||||
final Enum[] enumArray = EnumDescribedValue.values();
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(enumArray).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsEnumClassValues() {
|
||||
final List<AllowableValue> expected = expectedMinimalAllowableValues;
|
||||
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(EnumNotDescribedValue.class).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsDescribedValueEnumClassValues() {
|
||||
final List<AllowableValue> expected = expectedAllowableValuesWithDescription;
|
||||
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(EnumDescribedValue.class).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsEnumSetValues() {
|
||||
final List<AllowableValue> expected = expectedMinimalAllowableValues;
|
||||
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(EnumSet.allOf(EnumNotDescribedValue.class)).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsDescribedValueEnumSetValues() {
|
||||
final List<AllowableValue> expected = expectedAllowableValuesWithDescription;
|
||||
|
||||
final PropertyDescriptor descriptor = builder().allowableValues(EnumSet.allOf(EnumDescribedValue.class)).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsDescribedValueVarArgValues() {
|
||||
final List<AllowableValue> expected = expectedAllowableValuesWithDescription;
|
||||
|
||||
final PropertyDescriptor descriptor = builder()
|
||||
.allowableValues(EnumDescribedValue.GREEN, EnumDescribedValue.RED, EnumDescribedValue.BLUE).build();
|
||||
final List<AllowableValue> actual = descriptor.getAllowableValues();
|
||||
|
||||
assertEquals(expected, actual); // equals only compares getValue()
|
||||
assertEquals(displayNamesOf(expected), displayNamesOf(actual));
|
||||
assertEquals(descriptionsOf(expected), descriptionsOf(actual));
|
||||
}
|
||||
|
||||
private List<AllowableValue> sort(final List<AllowableValue> allowableValues) {
|
||||
return allowableValues.stream().sorted(allowableValueComparator).toList();
|
||||
}
|
||||
|
||||
private List<String> displayNamesOf(final List<AllowableValue> allowableValues) {
|
||||
return allowableValues.stream().map(AllowableValue::getDisplayName).toList();
|
||||
}
|
||||
|
||||
private List<String> descriptionsOf(final List<AllowableValue> allowableValues) {
|
||||
return allowableValues.stream().map(AllowableValue::getDescription).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -121,7 +223,7 @@ public class TestPropertyDescriptor {
|
|||
|
||||
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder()
|
||||
.name("enumDependsOnDescriptor")
|
||||
.dependsOn(dependentPropertyDescriptor, EnumAllowableValue.RED)
|
||||
.dependsOn(dependentPropertyDescriptor, EnumDescribedValue.RED)
|
||||
.build();
|
||||
|
||||
assertNotNull(propertyDescriptor);
|
||||
|
@ -133,17 +235,17 @@ public class TestPropertyDescriptor {
|
|||
final Set<String> dependentValues = dependency.getDependentValues();
|
||||
assertEquals(1, dependentValues.size());
|
||||
final String dependentValue = dependentValues.iterator().next();
|
||||
assertEquals(EnumAllowableValue.RED.getValue(), dependentValue);
|
||||
assertEquals(EnumDescribedValue.RED.getValue(), dependentValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExternalResourceIgnoredIfELWithAttributesPresent() {
|
||||
final PropertyDescriptor descriptor = new PropertyDescriptor.Builder()
|
||||
.name("dir")
|
||||
.identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.required(false)
|
||||
.build();
|
||||
.name("dir")
|
||||
.identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.required(false)
|
||||
.build();
|
||||
|
||||
final ValidationContext validationContext = Mockito.mock(ValidationContext.class);
|
||||
Mockito.when(validationContext.isExpressionLanguagePresent(anyString())).thenReturn(true);
|
||||
|
@ -159,11 +261,11 @@ public class TestPropertyDescriptor {
|
|||
@Test
|
||||
void testExternalResourceConsideredIfELVarRegistryPresent() {
|
||||
final PropertyDescriptor descriptor = new PropertyDescriptor.Builder()
|
||||
.name("dir")
|
||||
.identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE, ResourceType.DIRECTORY)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.ENVIRONMENT)
|
||||
.required(false)
|
||||
.build();
|
||||
.name("dir")
|
||||
.identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE, ResourceType.DIRECTORY)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.ENVIRONMENT)
|
||||
.required(false)
|
||||
.build();
|
||||
|
||||
final AtomicReference<String> variable = new AtomicReference<>("__my_var__");
|
||||
final ValidationContext validationContext = Mockito.mock(ValidationContext.class);
|
||||
|
@ -190,9 +292,9 @@ public class TestPropertyDescriptor {
|
|||
// Consider if Expression Language is not supported.
|
||||
Mockito.when(validationContext.isExpressionLanguageSupported(anyString())).thenReturn(false);
|
||||
final PropertyDescriptor withElNotAllowed = new PropertyDescriptor.Builder()
|
||||
.fromPropertyDescriptor(descriptor)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.NONE)
|
||||
.build();
|
||||
.fromPropertyDescriptor(descriptor)
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.NONE)
|
||||
.build();
|
||||
|
||||
// Expression will not be evaluated, so the directory being looked at will literally be ${TestPropertyDescriptor.Var1}
|
||||
assertFalse(withElNotAllowed.validate("${TestPropertyDescriptor.Var1}", validationContext).isValid());
|
||||
|
@ -232,4 +334,12 @@ public class TestPropertyDescriptor {
|
|||
assertTrue(pd2.getDependencies().isEmpty());
|
||||
assertNull(pd2.getAllowableValues());
|
||||
}
|
||||
|
||||
private Builder builder() {
|
||||
return new PropertyDescriptor.Builder().name("propertyName");
|
||||
}
|
||||
|
||||
private Builder builder(final PropertyDescriptor propertyDescriptor) {
|
||||
return new PropertyDescriptor.Builder().fromPropertyDescriptor(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue