You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ex...@apache.org on 2022/04/28 15:05:44 UTC

[nifi] branch main updated: NIFI-9936 Added DescribedValue in PropertyDescriptor Builder for AllowableValues

This is an automated email from the ASF dual-hosted git repository.

exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new a97c20cdb2 NIFI-9936 Added DescribedValue in PropertyDescriptor Builder for AllowableValues
a97c20cdb2 is described below

commit a97c20cdb23fb124e8559a7392279500e7515530
Author: Lehel <le...@hotmail.com>
AuthorDate: Tue Apr 19 18:37:20 2022 +0200

    NIFI-9936 Added DescribedValue in PropertyDescriptor Builder for AllowableValues
    
    This closes #5977
    
    Signed-off-by: David Handermann <ex...@apache.org>
---
 .../org/apache/nifi/components/AllowableValue.java |  5 +-
 .../org/apache/nifi/components/DescribedValue.java | 38 ++++++++++++++
 .../apache/nifi/components/PropertyDescriptor.java | 16 +++++-
 .../apache/nifi/components/EnumAllowableValue.java | 49 +++++++++++++++++
 .../nifi/components/TestPropertyDescriptor.java    | 61 +++++++++++++---------
 5 files changed, 143 insertions(+), 26 deletions(-)

diff --git a/nifi-api/src/main/java/org/apache/nifi/components/AllowableValue.java b/nifi-api/src/main/java/org/apache/nifi/components/AllowableValue.java
index a4809616d6..b8303ae122 100644
--- a/nifi-api/src/main/java/org/apache/nifi/components/AllowableValue.java
+++ b/nifi-api/src/main/java/org/apache/nifi/components/AllowableValue.java
@@ -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;
     }
diff --git a/nifi-api/src/main/java/org/apache/nifi/components/DescribedValue.java b/nifi-api/src/main/java/org/apache/nifi/components/DescribedValue.java
new file mode 100644
index 0000000000..e52740714d
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/components/DescribedValue.java
@@ -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();
+}
diff --git a/nifi-api/src/main/java/org/apache/nifi/components/PropertyDescriptor.java b/nifi-api/src/main/java/org/apache/nifi/components/PropertyDescriptor.java
index e550b83bfb..b36a2a46d8 100644
--- a/nifi-api/src/main/java/org/apache/nifi/components/PropertyDescriptor.java
+++ b/nifi-api/src/main/java/org/apache/nifi/components/PropertyDescriptor.java
@@ -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);
             }
diff --git a/nifi-api/src/test/java/org/apache/nifi/components/EnumAllowableValue.java b/nifi-api/src/test/java/org/apache/nifi/components/EnumAllowableValue.java
new file mode 100644
index 0000000000..02aed04ebd
--- /dev/null
+++ b/nifi-api/src/test/java/org/apache/nifi/components/EnumAllowableValue.java
@@ -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();
+    }
+}
diff --git a/nifi-api/src/test/java/org/apache/nifi/components/TestPropertyDescriptor.java b/nifi-api/src/test/java/org/apache/nifi/components/TestPropertyDescriptor.java
index bab58f7078..8fb9fab584 100644
--- a/nifi-api/src/test/java/org/apache/nifi/components/TestPropertyDescriptor.java
+++ b/nifi-api/src/test/java/org/apache/nifi/components/TestPropertyDescriptor.java
@@ -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("\\$\\{.*}", ""));
-
-                final PropertyValue propertyValue = Mockito.mock(PropertyValue.class);
-                Mockito.when(propertyValue.getValue()).thenReturn(evaluatedValue);
-                Mockito.when(propertyValue.evaluateAttributeExpressions()).thenReturn(propertyValue);
-                return propertyValue;
-            }
+        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;
         });
 
         // Should not be valid because Expression Language scope is VARIABLE_REGISTRY, so the ${TestPropertyDescriptor.Var1} will be replaced with