NIFI-10775 Improve support for DescribedValue in PropertyDescriptor.Builder

This closes #6650.

Signed-off-by: Peter Turcsanyi <turcsanyi@apache.org>
This commit is contained in:
Nandor Soma Abonyi 2022-11-11 01:26:09 +01:00 committed by Peter Turcsanyi
parent bda624823b
commit 241d619138
No known key found for this signature in database
GPG Key ID: 55A813F1C3E553DC
3 changed files with 66 additions and 13 deletions

View File

@ -209,7 +209,6 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
return lastResult;
}
public static final class Builder {
private String displayName = null;
@ -322,7 +321,7 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
* 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 and Exception will be thrown. If the
* 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
@ -562,7 +561,6 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
return this;
}
/**
* 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.
@ -591,6 +589,38 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
return dependsOn(property, dependentValues);
}
/**
* 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.
*
* 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.
*
* 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 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);
int i = 1;
for (final DescribedValue additionalDependentValue : additionalDependentValues) {
dependentValues[i++] = toAllowableValue(additionalDependentValue);
}
return dependsOn(property, dependentValues);
}
private AllowableValue toAllowableValue(DescribedValue describedValue) {
return new AllowableValue(describedValue.getValue(), describedValue.getDisplayName(), describedValue.getDescription());
}
/**
* @return a PropertyDescriptor as configured
*

View File

@ -26,6 +26,7 @@ import org.mockito.Mockito;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -46,6 +47,7 @@ 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() {
@ -65,22 +67,43 @@ public class TestPropertyDescriptor {
}
@Test
void testPropertyDescriptorWithEnumValue() {
Builder enumDescriptorBuilder = new PropertyDescriptor.Builder()
void testAllowableValuesWithEnumValue() {
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder()
.name("enumAllowableValueDescriptor")
.allowableValues(EnumAllowableValue.class)
.defaultValue(EnumAllowableValue.GREEN.name());
.build();
final PropertyDescriptor propertyDescriptor = enumDescriptorBuilder.build();
assertNotNull(propertyDescriptor);
assertEquals(EnumAllowableValue.GREEN.name(), propertyDescriptor.getDefaultValue());
final List<AllowableValue> expectedAllowableValues = Arrays.stream(EnumAllowableValue.values())
.map(enumValue -> new AllowableValue(enumValue.name(), enumValue.getDisplayName(), enumValue.getDescription()))
.map(enumValue -> new AllowableValue(enumValue.getValue(), enumValue.getDisplayName(), enumValue.getDescription()))
.collect(Collectors.toList());
assertEquals(expectedAllowableValues, propertyDescriptor.getAllowableValues());
}
@Test
void testDependsOnWithEnumValue() {
final PropertyDescriptor dependentPropertyDescriptor = new PropertyDescriptor.Builder()
.name(DEPENDENT_PROPERTY_NAME)
.build();
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder()
.name("enumDependsOnDescriptor")
.dependsOn(dependentPropertyDescriptor, EnumAllowableValue.RED)
.build();
assertNotNull(propertyDescriptor);
final Set<PropertyDependency> dependencies = propertyDescriptor.getDependencies();
assertEquals(1, dependencies.size());
final PropertyDependency dependency = dependencies.iterator().next();
assertEquals(DEPENDENT_PROPERTY_NAME, dependency.getPropertyName());
final Set<String> dependentValues = dependency.getDependentValues();
assertEquals(1, dependentValues.size());
final String dependentValue = dependentValues.iterator().next();
assertEquals(EnumAllowableValue.RED.getValue(), dependentValue);
}
@Test
void testExternalResourceIgnoredIfELWithAttributesPresent() {
final PropertyDescriptor descriptor = new PropertyDescriptor.Builder()

View File

@ -69,7 +69,7 @@ public interface ElasticSearchClientService extends ControllerService, Verifiabl
.name("el-cs-username")
.displayName("Username")
.description("The username to use with XPack security.")
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.BASIC.getValue())
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.BASIC)
.required(false)
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
@ -79,7 +79,7 @@ public interface ElasticSearchClientService extends ControllerService, Verifiabl
.name("el-cs-password")
.displayName("Password")
.description("The password to use with XPack security.")
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.BASIC.getValue())
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.BASIC)
.required(false)
.sensitive(true)
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
@ -90,7 +90,7 @@ public interface ElasticSearchClientService extends ControllerService, Verifiabl
.name("api-key-id")
.displayName("API Key ID")
.description("Unique identifier of the API key.")
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.API_KEY.getValue())
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.API_KEY)
.required(false)
.sensitive(false)
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
@ -100,7 +100,7 @@ public interface ElasticSearchClientService extends ControllerService, Verifiabl
.name("api-key")
.displayName("API Key")
.description("Encoded API key.")
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.API_KEY.getValue())
.dependsOn(AUTHORIZATION_SCHEME, AuthorizationScheme.API_KEY)
.required(false)
.sensitive(true)
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)