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 2023/12/05 04:35:19 UTC
(nifi) branch support/nifi-1.x updated: NIFI-12446 Refactor FilterAttribute to align with code conventions
This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch support/nifi-1.x
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/support/nifi-1.x by this push:
new c565e08ccc NIFI-12446 Refactor FilterAttribute to align with code conventions
c565e08ccc is described below
commit c565e08ccca6c1fce17b1d3de49d7a160cfbee38
Author: EndzeitBegins <16...@users.noreply.github.com>
AuthorDate: Fri Dec 1 17:46:29 2023 +0100
NIFI-12446 Refactor FilterAttribute to align with code conventions
This closes #8098
Signed-off-by: David Handermann <ex...@apache.org>
---
.../nifi/processors/standard/FilterAttribute.java | 210 ++++++++++++---------
.../processors/standard/TestFilterAttribute.java | 14 +-
2 files changed, 129 insertions(+), 95 deletions(-)
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/FilterAttribute.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/FilterAttribute.java
index 0822868a02..8a913cddf2 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/FilterAttribute.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/FilterAttribute.java
@@ -23,7 +23,7 @@ import org.apache.nifi.annotation.behavior.SupportsBatching;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.lifecycle.OnScheduled;
-import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.DescribedValue;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.flowfile.FlowFile;
@@ -34,7 +34,6 @@ import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.util.StandardValidators;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
@@ -52,87 +51,58 @@ import java.util.stream.Collectors;
public class FilterAttribute extends AbstractProcessor {
public static final Relationship REL_SUCCESS = new Relationship.Builder()
- .description("All successful FlowFiles are routed to this relationship").name("success").build();
-
- private final static Set<Relationship> relationships = Collections.singleton(REL_SUCCESS);
-
-
- public static final AllowableValue FILTER_MODE_VALUE_RETAIN = new AllowableValue(
- "RETAIN",
- "Retain",
- "Retains only the attributes matching the filter, all other attributes are removed."
- );
-
- public static final AllowableValue FILTER_MODE_VALUE_REMOVE = new AllowableValue(
- "REMOVE",
- "Remove",
- "Removes the attributes matching the filter, all other attributes are retained."
- );
+ .name("success")
+ .description("All successful FlowFiles are routed to this relationship")
+ .build();
public static final PropertyDescriptor FILTER_MODE = new PropertyDescriptor.Builder()
- .name("FILTER_MODE")
- .displayName("Filter mode")
+ .name("Filter Mode")
+ .displayName("Filter Mode")
.description("Specifies the strategy to apply on filtered attributes. Either 'Remove' or 'Retain' only the matching attributes.")
.required(true)
- .allowableValues(FILTER_MODE_VALUE_RETAIN, FILTER_MODE_VALUE_REMOVE)
+ .allowableValues(FilterMode.class)
.expressionLanguageSupported(ExpressionLanguageScope.NONE)
- .defaultValue(FILTER_MODE_VALUE_RETAIN.getValue())
+ .defaultValue(FilterMode.RETAIN.getValue())
.build();
- public static final AllowableValue MATCHING_STRATEGY_VALUE_ENUMERATION = new AllowableValue(
- "ENUMERATION",
- "Enumerate attributes",
- "Provides a set of attribute keys to filter for, separated by a comma delimiter ','."
- );
-
- public static final AllowableValue MATCHING_STRATEGY_VALUE_REGEX = new AllowableValue(
- "REGEX",
- "Use regular expression",
- "Provides a regular expression to match keys of attributes to filter for."
- );
-
public static final PropertyDescriptor MATCHING_STRATEGY = new PropertyDescriptor.Builder()
- .name("MATCHING_STRATEGY")
- .displayName("Attribute matching strategy")
+ .name("Attribute Matching Strategy")
+ .displayName("Attribute Matching Strategy")
.description("Specifies the strategy to filter attributes by.")
.required(true)
- .allowableValues(MATCHING_STRATEGY_VALUE_ENUMERATION, MATCHING_STRATEGY_VALUE_REGEX)
.expressionLanguageSupported(ExpressionLanguageScope.NONE)
- .defaultValue(MATCHING_STRATEGY_VALUE_ENUMERATION.getValue())
+ .allowableValues(MatchingStrategy.class)
+ .defaultValue(MatchingStrategy.ENUMERATION.getValue())
.build();
- public static final PropertyDescriptor ATTRIBUTE_SET = new PropertyDescriptor.Builder()
- .name("ATTRIBUTE_SET")
- .displayName("Set of attributes to filter")
+ public static final PropertyDescriptor ATTRIBUTE_ENUMERATION = new PropertyDescriptor.Builder()
+ .name("Filtered Attributes")
+ .displayName("Filtered Attributes")
.description("A set of attribute names to filter from FlowFiles. Each attribute name is separated by the comma delimiter ','.")
.required(true)
- .dependsOn(MATCHING_STRATEGY, MATCHING_STRATEGY_VALUE_ENUMERATION)
+ .dependsOn(MATCHING_STRATEGY, MatchingStrategy.ENUMERATION.getValue())
.addValidator(StandardValidators.NON_BLANK_VALIDATOR)
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
.build();
- public static final PropertyDescriptor ATTRIBUTE_REGEX = new PropertyDescriptor.Builder()
- .name("ATTRIBUTE_REGEX")
- .displayName("Regular expression to filter attributes")
+ public static final PropertyDescriptor ATTRIBUTE_PATTERN = new PropertyDescriptor.Builder()
+ .name("Filtered Attributes Pattern")
+ .displayName("Filtered Attributes Pattern")
.description("A regular expression to match names of attributes to filter from FlowFiles.")
.required(true)
- .dependsOn(MATCHING_STRATEGY, MATCHING_STRATEGY_VALUE_REGEX)
+ .dependsOn(MATCHING_STRATEGY, MatchingStrategy.PATTERN.getValue())
.addValidator(StandardValidators.REGULAR_EXPRESSION_WITH_EL_VALIDATOR)
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
.build();
private final static String DELIMITER_VALUE = ",";
- private final static List<PropertyDescriptor> properties;
+ private final static Set<Relationship> relationships = Collections.singleton(REL_SUCCESS);
+ private final static List<PropertyDescriptor> properties = Collections.unmodifiableList(
+ Arrays.asList(FILTER_MODE, MATCHING_STRATEGY, ATTRIBUTE_ENUMERATION, ATTRIBUTE_PATTERN)
+ );
- static {
- List<PropertyDescriptor> _propertyDescriptors = new ArrayList<>();
- _propertyDescriptors.add(FILTER_MODE);
- _propertyDescriptors.add(MATCHING_STRATEGY);
- _propertyDescriptors.add(ATTRIBUTE_SET);
- _propertyDescriptors.add(ATTRIBUTE_REGEX);
- properties = Collections.unmodifiableList(_propertyDescriptors);
- }
+ private volatile Predicate<String> cachedMatchingPredicate;
@Override
public Set<Relationship> getRelationships() {
@@ -144,8 +114,6 @@ public class FilterAttribute extends AbstractProcessor {
return properties;
}
- private volatile Predicate<String> cachedMatchingPredicate;
-
@OnScheduled
public void onScheduled(final ProcessContext context) {
final MatchingStrategy matchingStrategy = getMatchingStrategy(context);
@@ -153,11 +121,11 @@ public class FilterAttribute extends AbstractProcessor {
cachedMatchingPredicate = null;
if (matchingStrategy == MatchingStrategy.ENUMERATION
- && !context.getProperty(ATTRIBUTE_SET).isExpressionLanguagePresent()) {
+ && !context.getProperty(ATTRIBUTE_ENUMERATION).isExpressionLanguagePresent()) {
cachedMatchingPredicate = determineMatchingPredicateBasedOnEnumeration(context, null);
}
- if (matchingStrategy == MatchingStrategy.REGEX
- && !context.getProperty(ATTRIBUTE_REGEX).isExpressionLanguagePresent()) {
+ if (matchingStrategy == MatchingStrategy.PATTERN
+ && !context.getProperty(ATTRIBUTE_PATTERN).isExpressionLanguagePresent()) {
cachedMatchingPredicate = determineMatchingPredicateBasedOnRegex(context, null);
}
}
@@ -196,11 +164,11 @@ public class FilterAttribute extends AbstractProcessor {
switch (matchingStrategy) {
case ENUMERATION:
return determineMatchingPredicateBasedOnEnumeration(context, flowFile);
- case REGEX:
+ case PATTERN:
return determineMatchingPredicateBasedOnRegex(context, flowFile);
default:
throw new IllegalArgumentException(
- "Cannot determine matching predicate for unsupported strategy " + matchingStrategy + " !"
+ "Cannot determine matching predicate for unsupported strategy [" + matchingStrategy + "]"
);
}
}
@@ -211,7 +179,7 @@ public class FilterAttribute extends AbstractProcessor {
Set<String> attributeSet = Arrays.stream(attributeSetDeclaration.split(Pattern.quote(delimiter)))
.map(String::trim)
- .filter(attributeName -> !attributeName.trim().isEmpty())
+ .filter(attributeName -> !attributeName.isEmpty())
.collect(Collectors.toSet());
return attributeSet::contains;
@@ -226,29 +194,19 @@ public class FilterAttribute extends AbstractProcessor {
/* properties */
private static FilterMode getFilterMode(ProcessContext context) {
- final String rawFilterMode = context
- .getProperty(FILTER_MODE)
- .getValue();
-
- if (FILTER_MODE_VALUE_REMOVE.getValue().equals(rawFilterMode)) {
- return FilterMode.REMOVE;
- }
- return FilterMode.RETAIN;
+ return FilterMode.fromValue(
+ context.getProperty(FILTER_MODE).getValue()
+ );
}
private static MatchingStrategy getMatchingStrategy(ProcessContext context) {
- final String rawMatchingStrategy = context
- .getProperty(MATCHING_STRATEGY)
- .getValue();
-
- if (MATCHING_STRATEGY_VALUE_REGEX.getValue().equals(rawMatchingStrategy)) {
- return MatchingStrategy.REGEX;
- }
- return MatchingStrategy.ENUMERATION;
+ return MatchingStrategy.fromValue(
+ context.getProperty(MATCHING_STRATEGY).getValue()
+ );
}
private static String getAttributeSet(ProcessContext context, FlowFile flowFile) {
- return context.getProperty(ATTRIBUTE_SET).evaluateAttributeExpressions(flowFile).getValue();
+ return context.getProperty(ATTRIBUTE_ENUMERATION).evaluateAttributeExpressions(flowFile).getValue();
}
private static String getDelimiter() {
@@ -257,17 +215,93 @@ public class FilterAttribute extends AbstractProcessor {
private static Pattern getAttributeRegex(ProcessContext context, FlowFile flowFile) {
return Pattern.compile(
- context.getProperty(ATTRIBUTE_REGEX).evaluateAttributeExpressions(flowFile).getValue()
+ context.getProperty(ATTRIBUTE_PATTERN).evaluateAttributeExpressions(flowFile).getValue()
+ );
+ }
+
+ enum FilterMode implements DescribedValue {
+ RETAIN(
+ "Retain",
+ "Retains only the attributes matching the filter, all other attributes are removed."
+ ),
+ REMOVE(
+ "Remove",
+ "Removes the attributes matching the filter, all other attributes are retained."
);
+
+ private final String value;
+ private final String description;
+
+ FilterMode(final String value, final String description) {
+ this.value = value;
+ this.description = description;
+ }
+
+ @Override
+ public String getValue() {
+ return this.value;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return this.value;
+ }
+
+ @Override
+ public String getDescription() {
+ return this.description;
+ }
+
+ public static FilterMode fromValue(final String value) {
+ return FilterAttribute.enumConstantFromValue(FilterMode.class, value);
+ }
}
- private enum FilterMode {
- RETAIN,
- REMOVE,
+ enum MatchingStrategy implements DescribedValue {
+ ENUMERATION(
+ "Enumerate attributes",
+ "Provides a set of attribute keys to filter for, separated by a comma delimiter ','."
+ ),
+ PATTERN(
+ "Use regular expression",
+ "Provides a regular expression to match keys of attributes to filter for."
+ );
+
+ private final String value;
+ private final String description;
+
+ MatchingStrategy(final String value, final String description) {
+ this.value = value;
+ this.description = description;
+ }
+
+ @Override
+ public String getValue() {
+ return this.value;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return this.value;
+ }
+
+ @Override
+ public String getDescription() {
+ return this.description;
+ }
+
+ public static MatchingStrategy fromValue(final String value) {
+ return FilterAttribute.enumConstantFromValue(MatchingStrategy.class, value);
+ }
}
- private enum MatchingStrategy {
- ENUMERATION,
- REGEX,
+ private static <E extends Enum<E> & DescribedValue> E enumConstantFromValue(final Class<E> enumClass, final String value) {
+ for (E enumConstant : enumClass.getEnumConstants()) {
+ if (enumConstant.getValue().equals(value)) {
+ return enumConstant;
+ }
+ }
+
+ throw new IllegalArgumentException(String.format("Unknown %s value [%s]", enumClass.getSimpleName(), value));
}
-}
+}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestFilterAttribute.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestFilterAttribute.java
index 4f9c36a63d..b9e2b9f8d6 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestFilterAttribute.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestFilterAttribute.java
@@ -90,7 +90,7 @@ class TestFilterAttribute {
@BeforeEach
void setUp() {
- runner.setProperty(FilterAttribute.FILTER_MODE, FilterAttribute.FILTER_MODE_VALUE_REMOVE);
+ runner.setProperty(FilterAttribute.FILTER_MODE, FilterAttribute.FilterMode.REMOVE.getValue());
}
@Test
@@ -199,8 +199,8 @@ class TestFilterAttribute {
}
private void runTestWith(Map<String, String> attributes, String attributeSet, Set<String> expectedAttributes) {
- runner.setProperty(FilterAttribute.MATCHING_STRATEGY, FilterAttribute.MATCHING_STRATEGY_VALUE_ENUMERATION);
- runner.setProperty(FilterAttribute.ATTRIBUTE_SET, attributeSet);
+ runner.setProperty(FilterAttribute.MATCHING_STRATEGY, FilterAttribute.MatchingStrategy.ENUMERATION.getValue());
+ runner.setProperty(FilterAttribute.ATTRIBUTE_ENUMERATION, attributeSet);
final MockFlowFile input = runner.enqueue(exampleContent, attributes);
final Map<String, String> inputAttributes = input.getAttributes();
@@ -268,7 +268,7 @@ class TestFilterAttribute {
@BeforeEach
void setUp() {
- runner.setProperty(FilterAttribute.FILTER_MODE, FilterAttribute.FILTER_MODE_VALUE_REMOVE);
+ runner.setProperty(FilterAttribute.FILTER_MODE, FilterAttribute.FilterMode.REMOVE.getValue());
}
@Test
@@ -321,8 +321,8 @@ class TestFilterAttribute {
}
private void runTestWith(Map<String, String> attributes, String regexPattern, Set<String> expectedAttributes) {
- runner.setProperty(FilterAttribute.MATCHING_STRATEGY, FilterAttribute.MATCHING_STRATEGY_VALUE_REGEX);
- runner.setProperty(FilterAttribute.ATTRIBUTE_REGEX, regexPattern);
+ runner.setProperty(FilterAttribute.MATCHING_STRATEGY, FilterAttribute.MatchingStrategy.PATTERN.getValue());
+ runner.setProperty(FilterAttribute.ATTRIBUTE_PATTERN, regexPattern);
final MockFlowFile input = runner.enqueue(exampleContent, attributes);
final Map<String, String> inputAttributes = input.getAttributes();
@@ -357,7 +357,7 @@ class TestFilterAttribute {
"bar", "" + i
));
}
- runner.setProperty(FilterAttribute.ATTRIBUTE_SET, "foo");
+ runner.setProperty(FilterAttribute.ATTRIBUTE_ENUMERATION, "foo");
runner.run(flowFileCount);
runner.assertAllFlowFilesTransferred(FilterAttribute.REL_SUCCESS, flowFileCount);