mirror of https://github.com/apache/nifi.git
NIFI-9936 Added DescribedValue in PropertyDescriptor Builder for AllowableValues
This closes #5977 Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
fbfdcdca9f
commit
a97c20cdb2
|
@ -23,7 +23,7 @@ import java.util.Objects;
|
|||
* Represents a valid value for a {@link PropertyDescriptor}
|
||||
* </p>
|
||||
*/
|
||||
public class AllowableValue {
|
||||
public class AllowableValue implements DescribedValue {
|
||||
|
||||
private final String value;
|
||||
private final String displayName;
|
||||
|
@ -71,6 +71,7 @@ public class AllowableValue {
|
|||
/**
|
||||
* @return the value of this AllowableValue
|
||||
*/
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
@ -78,6 +79,7 @@ public class AllowableValue {
|
|||
/**
|
||||
* @return a human-readable name for this AllowableValue
|
||||
*/
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
@ -86,6 +88,7 @@ public class AllowableValue {
|
|||
* @return a description for this value, or <code>null</code> if no
|
||||
* description was provided
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Describes a component property value with display name and description.
|
||||
*/
|
||||
public interface DescribedValue {
|
||||
|
||||
/**
|
||||
* @return the property value as a string
|
||||
*/
|
||||
String getValue();
|
||||
|
||||
/**
|
||||
* @return the property display name as a string
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
/**
|
||||
* @return the proeprty description as a string
|
||||
*/
|
||||
String getDescription();
|
||||
}
|
|
@ -396,6 +396,20 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores allowable values from an enum class.
|
||||
* @param enumClass an enum class that implements the Allowable interface and contains a set of values
|
||||
* @param <E> generic parameter for an enum class that implements the Allowable 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param values constrained set of values
|
||||
* @return the builder
|
||||
|
@ -569,7 +583,7 @@ public final class PropertyDescriptor implements Comparable<PropertyDescriptor>
|
|||
public Builder dependsOn(final PropertyDescriptor property, final String firstDependentValue, final String... additionalDependentValues) {
|
||||
final AllowableValue[] dependentValues = new AllowableValue[additionalDependentValues.length + 1];
|
||||
dependentValues[0] = new AllowableValue(firstDependentValue);
|
||||
int i=1;
|
||||
int i = 1;
|
||||
for (final String additionalDependentValue : additionalDependentValues) {
|
||||
dependentValues[i++] = new AllowableValue(additionalDependentValue);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 EnumAllowableValue implements DescribedValue {
|
||||
|
||||
GREEN {
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "GreenDisplayName";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "GreenDescription";
|
||||
}
|
||||
},
|
||||
|
||||
RED {
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "RedDisplayName";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "RedDescription";
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return name();
|
||||
}
|
||||
}
|
|
@ -23,11 +23,13 @@ import org.apache.nifi.expression.ExpressionLanguageScope;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
@ -43,7 +45,7 @@ public class TestPropertyDescriptor {
|
|||
|
||||
private static Builder invalidDescriptorBuilder;
|
||||
private static Builder validDescriptorBuilder;
|
||||
private static String DEFAULT_VALUE = "Default Value";
|
||||
private static final String DEFAULT_VALUE = "Default Value";
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
|
@ -52,18 +54,35 @@ public class TestPropertyDescriptor {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionThrownByDescriptorWithInvalidDefaultValue() {
|
||||
void testExceptionThrownByDescriptorWithInvalidDefaultValue() {
|
||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> invalidDescriptorBuilder.build());
|
||||
assertTrue(exception.getMessage().contains("[" + DEFAULT_VALUE + "]") );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoExceptionThrownByPropertyDescriptorWithValidDefaultValue() {
|
||||
void testNoExceptionThrownByPropertyDescriptorWithValidDefaultValue() {
|
||||
assertNotNull(validDescriptorBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExternalResourceIgnoredIfELWithAttributesPresent() {
|
||||
void testPropertyDescriptorWithEnumValue() {
|
||||
Builder enumDescriptorBuilder = new PropertyDescriptor.Builder()
|
||||
.name("enumAllowableValueDescriptor")
|
||||
.allowableValues(EnumAllowableValue.class)
|
||||
.defaultValue(EnumAllowableValue.GREEN.name());
|
||||
|
||||
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()))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(expectedAllowableValues, propertyDescriptor.getAllowableValues());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExternalResourceIgnoredIfELWithAttributesPresent() {
|
||||
final PropertyDescriptor descriptor = new PropertyDescriptor.Builder()
|
||||
.name("dir")
|
||||
.identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE)
|
||||
|
@ -74,19 +93,16 @@ public class TestPropertyDescriptor {
|
|||
final ValidationContext validationContext = Mockito.mock(ValidationContext.class);
|
||||
Mockito.when(validationContext.isExpressionLanguagePresent(anyString())).thenReturn(true);
|
||||
Mockito.when(validationContext.isExpressionLanguageSupported(anyString())).thenReturn(true);
|
||||
Mockito.when(validationContext.newPropertyValue(anyString())).thenAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(final InvocationOnMock invocation) throws Throwable {
|
||||
final String inputArg = invocation.getArgument(0);
|
||||
return inputArg.replace("${TestPropertyDescriptor.Var1}", "__my_var__").replaceAll("\\$\\{.*}", "");
|
||||
}
|
||||
Mockito.when(validationContext.newPropertyValue(anyString())).thenAnswer(invocation -> {
|
||||
final String inputArg = invocation.getArgument(0);
|
||||
return inputArg.replace("${TestPropertyDescriptor.Var1}", "__my_var__").replaceAll("\\$\\{.*}", "");
|
||||
});
|
||||
|
||||
assertTrue(descriptor.validate("${TestPropertyDescriptor.Var1}", validationContext).isValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExternalResourceConsideredIfELVarRegistryPresent() {
|
||||
void testExternalResourceConsideredIfELVarRegistryPresent() {
|
||||
final PropertyDescriptor descriptor = new PropertyDescriptor.Builder()
|
||||
.name("dir")
|
||||
.identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE, ResourceType.DIRECTORY)
|
||||
|
@ -98,17 +114,14 @@ public class TestPropertyDescriptor {
|
|||
final ValidationContext validationContext = Mockito.mock(ValidationContext.class);
|
||||
Mockito.when(validationContext.isExpressionLanguagePresent(anyString())).thenReturn(true);
|
||||
Mockito.when(validationContext.isExpressionLanguageSupported(anyString())).thenReturn(true);
|
||||
Mockito.when(validationContext.newPropertyValue(anyString())).thenAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(final InvocationOnMock invocation) {
|
||||
final String inputArg = invocation.getArgument(0);
|
||||
final String evaluatedValue = inputArg.replace("${TestPropertyDescriptor.Var1}", variable.get().replaceAll("\\$\\{.*}", ""));
|
||||
Mockito.when(validationContext.newPropertyValue(anyString())).thenAnswer(invocation -> {
|
||||
final String inputArg = invocation.getArgument(0);
|
||||
final String evaluatedValue = inputArg.replace("${TestPropertyDescriptor.Var1}", variable.get().replaceAll("\\$\\{.*}", ""));
|
||||
|
||||
final PropertyValue propertyValue = Mockito.mock(PropertyValue.class);
|
||||
Mockito.when(propertyValue.getValue()).thenReturn(evaluatedValue);
|
||||
Mockito.when(propertyValue.evaluateAttributeExpressions()).thenReturn(propertyValue);
|
||||
return propertyValue;
|
||||
}
|
||||
final PropertyValue propertyValue = Mockito.mock(PropertyValue.class);
|
||||
Mockito.when(propertyValue.getValue()).thenReturn(evaluatedValue);
|
||||
Mockito.when(propertyValue.evaluateAttributeExpressions()).thenReturn(propertyValue);
|
||||
return propertyValue;
|
||||
});
|
||||
|
||||
// Should not be valid because Expression Language scope is VARIABLE_REGISTRY, so the ${TestPropertyDescriptor.Var1} will be replaced with
|
||||
|
|
Loading…
Reference in New Issue