From c90f00d0e7377cb3c80c56d33eb29c67a41cdf15 Mon Sep 17 00:00:00 2001 From: Pierre Villard Date: Thu, 31 Oct 2024 13:55:18 +0100 Subject: [PATCH] NIFI-13952 - Flow Analysis Rule to restrict backpressure configuration --- .../nifi-standard-rules/pom.xml | 19 +- .../rules/RestrictBackpressureSettings.java | 242 ++++++++++++++++++ ....apache.nifi.flowanalysis.FlowAnalysisRule | 3 +- .../rules/AbstractFlowAnalaysisRuleTest.java | 91 +++++++ .../RestrictBackpressureSettingsTest.java | 80 ++++++ .../RestrictBackpressureSettings.json | 1 + ...trictBackpressureSettings_noViolation.json | 1 + 7 files changed, 433 insertions(+), 4 deletions(-) create mode 100644 nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettings.java create mode 100644 nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/AbstractFlowAnalaysisRuleTest.java create mode 100644 nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettingsTest.java create mode 100644 nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings.json create mode 100644 nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings_noViolation.json diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/pom.xml b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/pom.xml index d215b3b0c1..921fc19238 100644 --- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/pom.xml +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/pom.xml @@ -23,7 +23,20 @@ nifi-standard-rules jar - - - + + + + + + org.apache.rat + apache-rat-plugin + + + src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings_noViolation.json + src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings.json + + + + + \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettings.java b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettings.java new file mode 100644 index 0000000000..0b4b3260e0 --- /dev/null +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettings.java @@ -0,0 +1,242 @@ +/* + * 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.flowanalysis.rules; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.components.ValidationContext; +import org.apache.nifi.components.ValidationResult; +import org.apache.nifi.flow.VersionedComponent; +import org.apache.nifi.flow.VersionedConnection; +import org.apache.nifi.flow.VersionedProcessGroup; +import org.apache.nifi.flow.VersionedProcessor; +import org.apache.nifi.flowanalysis.AbstractFlowAnalysisRule; +import org.apache.nifi.flowanalysis.FlowAnalysisRuleContext; +import org.apache.nifi.flowanalysis.GroupAnalysisResult; +import org.apache.nifi.processor.DataUnit; +import org.apache.nifi.processor.util.StandardValidators; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Tags({"connection", "backpressure"}) +@CapabilityDescription("This rule will generate a violation if backpressure settings of a connection exceed configured thresholds. " + + "Improper configuration of backpressure settings can lead to decreased performances because of excessive swapping as well as " + + "to filled up content repository with too much in-flight data in NiFi.") +public class RestrictBackpressureSettings extends AbstractFlowAnalysisRule { + + public static final PropertyDescriptor COUNT_MIN = new PropertyDescriptor.Builder() + .name("Minimum Backpressure Object Count Threshold") + .description("This is the minimum value that should be set for the Object Count backpressure setting on connections. " + + "This can be used to prevent a user from setting a value of 0 which disables backpressure based on count.") + .required(true) + .addValidator(StandardValidators.POSITIVE_LONG_VALIDATOR) + .defaultValue("1") + .build(); + + public static final PropertyDescriptor COUNT_MAX = new PropertyDescriptor.Builder() + .name("Maximum Backpressure Object Count Threshold") + .description("This is the maximum value that should be set for the Object Count backpressure setting on connections. " + + "This can be used to prevent a user from setting a very high value that may be leading to a lot of swapping.") + .required(true) + .addValidator(StandardValidators.POSITIVE_LONG_VALIDATOR) + .defaultValue("10000") + .build(); + + public static final PropertyDescriptor SIZE_MIN = new PropertyDescriptor.Builder() + .name("Minimum Backpressure Data Size Threshold") + .description("This is the minimum value that should be set for the Data Size backpressure setting on connections. " + + "This can be used to prevent a user from setting a value of 0 which disables backpressure based on size.") + .required(true) + .addValidator(StandardValidators.DATA_SIZE_VALIDATOR) + .defaultValue("1 MB") + .build(); + + public static final PropertyDescriptor SIZE_MAX = new PropertyDescriptor.Builder() + .name("Maximum Backpressure Data Size Threshold") + .description("This is the maximum value that should be set for the Data Size backpressure setting on connections. " + + "This can be used to prevent a user from setting a very high value that may be filling up the content repo.") + .required(true) + .addValidator(StandardValidators.DATA_SIZE_VALIDATOR) + .defaultValue("1 GB") + .build(); + + private static final List PROPERTIES = List.of( + COUNT_MIN, + COUNT_MAX, + SIZE_MIN, + SIZE_MAX + ); + + @Override + protected Collection customValidate(ValidationContext validationContext) { + final List results = new ArrayList(); + + final long minCount = validationContext.getProperty(COUNT_MIN).asLong(); + final long maxCount = validationContext.getProperty(COUNT_MAX).asLong(); + final double minSize = validationContext.getProperty(SIZE_MIN).asDataSize(DataUnit.B); + final double maxSize = validationContext.getProperty(SIZE_MAX).asDataSize(DataUnit.B); + + if (minCount > maxCount) { + results.add( + new ValidationResult.Builder() + .subject(COUNT_MIN.getName()) + .valid(false) + .explanation("Value of '" + COUNT_MIN.getName() + "' cannot be strictly greater than '" + COUNT_MAX.getName() + "'") + .build()); + } + if (Double.compare(minSize, maxSize) > 0) { + results.add( + new ValidationResult.Builder() + .subject(SIZE_MIN.getName()) + .valid(false) + .explanation("Value of '" + SIZE_MIN.getName() + "' cannot be strictly greater than '" + SIZE_MAX.getName() + "'") + .build()); + } + + return results; + } + + @Override + protected List getSupportedPropertyDescriptors() { + return PROPERTIES; + } + + @Override + public Collection analyzeProcessGroup(VersionedProcessGroup pg, FlowAnalysisRuleContext context) { + final Collection results = new HashSet(); + + final long minCount = context.getProperty(COUNT_MIN).asLong(); + final long maxCount = context.getProperty(COUNT_MAX).asLong(); + final double minSize = context.getProperty(SIZE_MIN).asDataSize(DataUnit.B); + final double maxSize = context.getProperty(SIZE_MAX).asDataSize(DataUnit.B); + + // Map of all id/components to generate more human readable violations + final Map idComponent = Stream.of( + pg.getFunnels().stream(), + pg.getProcessors().stream(), + pg.getInputPorts().stream(), + pg.getOutputPorts().stream() + ).flatMap(c -> c) + .collect(Collectors.toMap(c -> c.getIdentifier(), Function.identity())); + + pg.getConnections().stream().forEach( + connection -> { + if (connection.getBackPressureObjectThreshold() < minCount) { + results.add(buildViolation(connection, + idComponent.get(connection.getSource().getId()), + idComponent.get(connection.getDestination().getId()), + BackpressureViolationType.BP_COUNT_THRESHOLD_BELOW_LIMIT, + getViolationMessage(BackpressureViolationType.BP_COUNT_THRESHOLD_BELOW_LIMIT, connection.getBackPressureObjectThreshold().toString(), Long.toString(minCount)))); + } + if (connection.getBackPressureObjectThreshold() > maxCount) { + results.add(buildViolation(connection, + idComponent.get(connection.getSource().getId()), + idComponent.get(connection.getDestination().getId()), + BackpressureViolationType.BP_COUNT_THRESHOLD_ABOVE_LIMIT, + getViolationMessage(BackpressureViolationType.BP_COUNT_THRESHOLD_ABOVE_LIMIT, connection.getBackPressureObjectThreshold().toString(), Long.toString(maxCount)))); + } + final double sizeThreshold = DataUnit.parseDataSize(connection.getBackPressureDataSizeThreshold(), DataUnit.B); + if (Double.compare(sizeThreshold, minSize) < 0) { + results.add(buildViolation(connection, + idComponent.get(connection.getSource().getId()), + idComponent.get(connection.getDestination().getId()), + BackpressureViolationType.BP_SIZE_THRESHOLD_BELOW_LIMIT, + getViolationMessage(BackpressureViolationType.BP_SIZE_THRESHOLD_BELOW_LIMIT, connection.getBackPressureDataSizeThreshold(), context.getProperty(SIZE_MIN).getValue()))); + } + if (Double.compare(sizeThreshold, maxSize) > 0) { + results.add(buildViolation(connection, + idComponent.get(connection.getSource().getId()), + idComponent.get(connection.getDestination().getId()), + BackpressureViolationType.BP_SIZE_THRESHOLD_ABOVE_LIMIT, + getViolationMessage(BackpressureViolationType.BP_SIZE_THRESHOLD_ABOVE_LIMIT, connection.getBackPressureDataSizeThreshold(), context.getProperty(SIZE_MAX).getValue()))); + } + } + ); + + return results; + } + + private GroupAnalysisResult buildViolation(final VersionedConnection connection, final VersionedComponent source, + final VersionedComponent destination, final BackpressureViolationType backpressureViolationType, final String violationMessage) { + if (!(source instanceof VersionedProcessor) && !(destination instanceof VersionedProcessor)) { + // connection between two components that are not processors and cannot be invalid, setting violation on connection + return GroupAnalysisResult.forComponent(connection, + connection.getIdentifier() + "_" + backpressureViolationType.getId(), + getLocationMessage(connection, source, destination) + violationMessage).build(); + } else if (source instanceof VersionedProcessor) { + // defining violation on source processor + return GroupAnalysisResult.forComponent(source, + connection.getIdentifier() + "_" + backpressureViolationType.getId(), + getLocationMessage(connection, source, destination) + violationMessage).build(); + } else { + // defining violation on destination processor + return GroupAnalysisResult.forComponent(destination, + connection.getIdentifier() + "_" + backpressureViolationType.getId(), + getLocationMessage(connection, source, destination) + violationMessage).build(); + } + } + + private String getLocationMessage(final VersionedConnection connection, final VersionedComponent source, final VersionedComponent destination) { + if (source == null || destination == null) { + return "The connection [" + connection.getIdentifier() + "] is violating the rule for backpressure settings. "; + } + return "The connection [" + connection.getIdentifier() + "] connecting " + source.getName() + " [" + source.getIdentifier() + "] to " + + destination.getName() + " [" + destination.getIdentifier() + "] is violating the rule for backpressure settings. "; + } + + private String getViolationMessage(final BackpressureViolationType backpressureViolationType, final String configured, final String limit) { + switch (backpressureViolationType) { + case BP_COUNT_THRESHOLD_ABOVE_LIMIT: + return "The connection is configured with a Backpressure Count Threshold of " + configured + " and it should be lesser or equal than " + limit + "."; + case BP_COUNT_THRESHOLD_BELOW_LIMIT: + return "The connection is configured with a Backpressure Count Threshold of " + configured + " and it should be greater or equal than " + limit + "."; + case BP_SIZE_THRESHOLD_ABOVE_LIMIT: + return "The connection is configured with a Backpressure Data Size Threshold of " + configured + " and it should be lesser or equal than " + limit + "."; + case BP_SIZE_THRESHOLD_BELOW_LIMIT: + return "The connection is configured with a Backpressure Data Size Threshold of " + configured + " and it should be greater or equal than " + limit + "."; + default: + return null; + } + } + + private enum BackpressureViolationType { + + BP_COUNT_THRESHOLD_BELOW_LIMIT("BackpressureCountThresholdTooLow"), + BP_COUNT_THRESHOLD_ABOVE_LIMIT("BackpressureCountThresholdTooHigh"), + BP_SIZE_THRESHOLD_BELOW_LIMIT("BackpressureSizeThresholdTooLow"), + BP_SIZE_THRESHOLD_ABOVE_LIMIT("BackpressureSizeThresholdTooHigh"); + + private String id; + + BackpressureViolationType(String id) { + this.id = id; + } + + public String getId() { + return this.id; + } + + } +} diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/resources/META-INF/services/org.apache.nifi.flowanalysis.FlowAnalysisRule b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/resources/META-INF/services/org.apache.nifi.flowanalysis.FlowAnalysisRule index 14d82e4560..8206669997 100644 --- a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/resources/META-INF/services/org.apache.nifi.flowanalysis.FlowAnalysisRule +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/main/resources/META-INF/services/org.apache.nifi.flowanalysis.FlowAnalysisRule @@ -13,4 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -org.apache.nifi.flowanalysis.rules.DisallowComponentType \ No newline at end of file +org.apache.nifi.flowanalysis.rules.DisallowComponentType +org.apache.nifi.flowanalysis.rules.RestrictBackpressureSettings \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/AbstractFlowAnalaysisRuleTest.java b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/AbstractFlowAnalaysisRuleTest.java new file mode 100644 index 0000000000..5961b3ae0f --- /dev/null +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/AbstractFlowAnalaysisRuleTest.java @@ -0,0 +1,91 @@ +/* + * 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.flowanalysis.rules; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.mockito.ArgumentMatchers.any; + +import java.io.FileInputStream; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.nifi.attribute.expression.language.StandardPropertyValue; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.components.PropertyValue; +import org.apache.nifi.components.ValidationContext; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.flow.VersionedProcessGroup; +import org.apache.nifi.flowanalysis.AbstractFlowAnalysisRule; +import org.apache.nifi.flowanalysis.FlowAnalysisRuleContext; +import org.apache.nifi.flowanalysis.GroupAnalysisResult; +import org.apache.nifi.registry.flow.RegisteredFlowSnapshot; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@ExtendWith(MockitoExtension.class) +public abstract class AbstractFlowAnalaysisRuleTest { + + private static final ObjectMapper FLOW_MAPPER = new ObjectMapper(); + protected Map properties = new HashMap(); + protected T rule; + + @Mock + protected FlowAnalysisRuleContext flowAnalysisRuleContext; + + @Mock + protected ConfigurationContext configurationContext; + + @Mock + protected ValidationContext validationContext; + + protected abstract T initializeRule(); + + @BeforeEach + public void setup() { + rule = initializeRule(); + Mockito.lenient().when(flowAnalysisRuleContext.getProperty(any())).thenAnswer(invocation -> { + return properties.get(invocation.getArgument(0)); + }); + Mockito.lenient().when(configurationContext.getProperty(any())).thenAnswer(invocation -> { + return properties.get(invocation.getArgument(0)); + }); + Mockito.lenient().when(validationContext.getProperty(any())).thenAnswer(invocation -> { + return properties.get(invocation.getArgument(0)); + }); + } + + protected void setProperty(PropertyDescriptor propertyDescriptor, String value) { + properties.put(propertyDescriptor, new StandardPropertyValue(value, null, null)); + } + + private VersionedProcessGroup getProcessGroup(String flowDefinition) throws Exception { + final RegisteredFlowSnapshot flowSnapshot = FLOW_MAPPER.readValue(new FileInputStream(flowDefinition), RegisteredFlowSnapshot.class); + return flowSnapshot.getFlowContents(); + } + + protected void testAnalyzeProcessGroup(String flowDefinition, List expected) throws Exception { + final Collection actual = rule.analyzeProcessGroup(getProcessGroup(flowDefinition), flowAnalysisRuleContext); + assertIterableEquals(expected, actual.stream().map(r -> r.getComponent().get().getInstanceIdentifier()).sorted().toList()); + } +} diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettingsTest.java b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettingsTest.java new file mode 100644 index 0000000000..d088d85121 --- /dev/null +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/java/org/apache/nifi/flowanalysis/rules/RestrictBackpressureSettingsTest.java @@ -0,0 +1,80 @@ +/* + * 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.flowanalysis.rules; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class RestrictBackpressureSettingsTest extends AbstractFlowAnalaysisRuleTest { + + @Override + protected RestrictBackpressureSettings initializeRule() { + return new RestrictBackpressureSettings(); + } + + @BeforeEach + @Override + public void setup() { + super.setup(); + setProperty(RestrictBackpressureSettings.COUNT_MIN, RestrictBackpressureSettings.COUNT_MIN.getDefaultValue()); + setProperty(RestrictBackpressureSettings.COUNT_MAX, RestrictBackpressureSettings.COUNT_MAX.getDefaultValue()); + setProperty(RestrictBackpressureSettings.SIZE_MIN, RestrictBackpressureSettings.SIZE_MIN.getDefaultValue()); + setProperty(RestrictBackpressureSettings.SIZE_MAX, RestrictBackpressureSettings.SIZE_MAX.getDefaultValue()); + } + + @Test + public void testWrongCountConfiguration() { + setProperty(RestrictBackpressureSettings.COUNT_MIN, "100"); + setProperty(RestrictBackpressureSettings.COUNT_MAX, "10"); + assertFalse(rule.customValidate(validationContext).isEmpty()); + } + + @Test + public void testWrongSizeConfiguration() { + setProperty(RestrictBackpressureSettings.SIZE_MIN, "1GB"); + setProperty(RestrictBackpressureSettings.SIZE_MAX, "1MB"); + assertFalse(rule.customValidate(validationContext).isEmpty()); + } + + @Test + public void testNoViolations() throws Exception { + testAnalyzeProcessGroup( + "src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings_noViolation.json", + List.of() + ); + } + + @Test + public void testViolations() throws Exception { + testAnalyzeProcessGroup( + "src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings.json", + List.of( + "e26f20c1-0192-1000-ff8b-bcf395c02076", // processor GenerateFlowFile connecting to UpdateAttribute + "e26f3857-0192-1000-776a-3d62e15f75dc", // processor UpdateAttribute connecting to funnel + "e26f3857-0192-1000-776a-3d62e15f75dc", // processor UpdateAttribute connecting from funnel + "e26fd0d5-0192-1000-ee3d-f90141590475", // connection from funnel to funnel + "e27073f8-0192-1000-cf43-9c41e69eadd2", // connection from output port to funnel + "e270eaa4-0192-1000-0622-8f9af5319328" // connection from funnel to input port + ) + ); + } + +} diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings.json b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings.json new file mode 100644 index 0000000000..15403f601c --- /dev/null +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings.json @@ -0,0 +1 @@ +{"flowContents":{"identifier":"d846f5a8-343e-3bda-8c49-4413dde11686","instanceIdentifier":"e26effa4-0192-1000-7826-18bfabd139ac","name":"RestrictBackpressureSettings","comments":"","position":{"x":1787.6793181202202,"y":391.0950428985503},"processGroups":[{"identifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d","instanceIdentifier":"e270189e-0192-1000-8aba-e274768ade7e","name":"EmbeddedProcessGroup","comments":"","position":{"x":-408.0,"y":216.0},"processGroups":[],"remoteProcessGroups":[],"processors":[{"identifier":"aa55546e-8ea7-3276-90ab-0c4b420297e5","instanceIdentifier":"e27038cf-0192-1000-1662-801cfccb85fb","name":"GenerateFlowFile","comments":"","position":{"x":-392.0,"y":-144.0},"type":"org.apache.nifi.processors.standard.GenerateFlowFile","bundle":{"group":"org.apache.nifi","artifact":"nifi-standard-nar","version":"2.0.0-SNAPSHOT"},"properties":{"character-set":"UTF-8","File Size":"0B","mime-type":null,"generate-ff-custom-text":null,"Batch Size":"1","Unique FlowFiles":"false","Data Format":"Text"},"propertyDescriptors":{"character-set":{"name":"character-set","displayName":"Character Set","identifiesControllerService":false,"sensitive":false,"dynamic":false},"File Size":{"name":"File Size","displayName":"File Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"mime-type":{"name":"mime-type","displayName":"Mime Type","identifiesControllerService":false,"sensitive":false,"dynamic":false},"generate-ff-custom-text":{"name":"generate-ff-custom-text","displayName":"Custom Text","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Batch Size":{"name":"Batch Size","displayName":"Batch Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Unique FlowFiles":{"name":"Unique FlowFiles","displayName":"Unique FlowFiles","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Data Format":{"name":"Data Format","displayName":"Data Format","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"1 min","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":0,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":[],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"},{"identifier":"905b896f-b267-32e4-9c72-2399757d7aad","instanceIdentifier":"e270c1f6-0192-1000-a019-53616442b6c2","name":"UpdateAttribute","comments":"","position":{"x":312.0,"y":128.0},"type":"org.apache.nifi.processors.attributes.UpdateAttribute","bundle":{"group":"org.apache.nifi","artifact":"nifi-update-attribute-nar","version":"2.0.0-SNAPSHOT"},"properties":{"Delete Attributes Expression":null,"Store State":"Do not store state","canonical-value-lookup-cache-size":"100","Stateful Variables Initial Value":null},"propertyDescriptors":{"Delete Attributes Expression":{"name":"Delete Attributes Expression","displayName":"Delete Attributes Expression","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Store State":{"name":"Store State","displayName":"Store State","identifiesControllerService":false,"sensitive":false,"dynamic":false},"canonical-value-lookup-cache-size":{"name":"canonical-value-lookup-cache-size","displayName":"Cache Value Lookup Cache Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Stateful Variables Initial Value":{"name":"Stateful Variables Initial Value","displayName":"Stateful Variables Initial Value","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"0 sec","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":25,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":["success"],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"inputPorts":[{"identifier":"5aa1a366-1c99-39e7-90b2-526d327eacf8","instanceIdentifier":"e270a7d2-0192-1000-4b49-b7a20716fa6b","name":"input","position":{"x":-227.0000091008809,"y":117.99999088368702},"type":"INPUT_PORT","concurrentlySchedulableTaskCount":1,"scheduledState":"ENABLED","allowRemoteAccess":false,"portFunction":"STANDARD","componentType":"INPUT_PORT","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"outputPorts":[{"identifier":"292428fc-fe6c-3420-9cf3-fc09587cd56e","instanceIdentifier":"e2704f0f-0192-1000-d1d9-0629c2e8e158","name":"output","position":{"x":295.9999908991191,"y":-91.00000911631298},"type":"OUTPUT_PORT","concurrentlySchedulableTaskCount":1,"scheduledState":"ENABLED","allowRemoteAccess":false,"portFunction":"STANDARD","componentType":"OUTPUT_PORT","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"connections":[{"identifier":"7539bdc8-3dd2-3636-ae44-201abecdbfb9","instanceIdentifier":"e2705bd1-0192-1000-6dad-2b1959453b79","name":"","source":{"id":"aa55546e-8ea7-3276-90ab-0c4b420297e5","type":"PROCESSOR","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"GenerateFlowFile","comments":"","instanceIdentifier":"e27038cf-0192-1000-1662-801cfccb85fb"},"destination":{"id":"292428fc-fe6c-3420-9cf3-fc09587cd56e","type":"OUTPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"output","instanceIdentifier":"e2704f0f-0192-1000-d1d9-0629c2e8e158"},"labelIndex":0,"zIndex":0,"selectedRelationships":["success"],"backPressureObjectThreshold":100000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"},{"identifier":"366f7db1-c00b-30b9-a55a-f75f3d40a10f","instanceIdentifier":"e270d1b3-0192-1000-1407-369fa7dfe9ee","name":"","source":{"id":"5aa1a366-1c99-39e7-90b2-526d327eacf8","type":"INPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"input","instanceIdentifier":"e270a7d2-0192-1000-4b49-b7a20716fa6b"},"destination":{"id":"905b896f-b267-32e4-9c72-2399757d7aad","type":"PROCESSOR","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"UpdateAttribute","comments":"","instanceIdentifier":"e270c1f6-0192-1000-a019-53616442b6c2"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"10 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"labels":[],"funnels":[],"controllerServices":[],"defaultFlowFileExpiration":"0 sec","defaultBackPressureObjectThreshold":10000,"defaultBackPressureDataSizeThreshold":"1 GB","scheduledState":"ENABLED","executionEngine":"INHERITED","maxConcurrentTasks":1,"statelessFlowTimeout":"1 min","componentType":"PROCESS_GROUP","flowFileOutboundPolicy":"STREAM_WHEN_AVAILABLE","flowFileConcurrency":"UNBOUNDED","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"remoteProcessGroups":[],"processors":[{"identifier":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc","name":"UpdateAttribute","comments":"","position":{"x":232.0,"y":-216.0},"type":"org.apache.nifi.processors.attributes.UpdateAttribute","bundle":{"group":"org.apache.nifi","artifact":"nifi-update-attribute-nar","version":"2.0.0-SNAPSHOT"},"properties":{"Delete Attributes Expression":null,"Store State":"Do not store state","canonical-value-lookup-cache-size":"100","Stateful Variables Initial Value":null},"propertyDescriptors":{"Delete Attributes Expression":{"name":"Delete Attributes Expression","displayName":"Delete Attributes Expression","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Store State":{"name":"Store State","displayName":"Store State","identifiesControllerService":false,"sensitive":false,"dynamic":false},"canonical-value-lookup-cache-size":{"name":"canonical-value-lookup-cache-size","displayName":"Cache Value Lookup Cache Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Stateful Variables Initial Value":{"name":"Stateful Variables Initial Value","displayName":"Stateful Variables Initial Value","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"0 sec","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":25,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":[],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"84ca6d91-c383-34d0-8545-a27387acdabb","instanceIdentifier":"e26f20c1-0192-1000-ff8b-bcf395c02076","name":"GenerateFlowFile","comments":"","position":{"x":-472.0,"y":-232.0},"type":"org.apache.nifi.processors.standard.GenerateFlowFile","bundle":{"group":"org.apache.nifi","artifact":"nifi-standard-nar","version":"2.0.0-SNAPSHOT"},"properties":{"character-set":"UTF-8","File Size":"0B","mime-type":null,"generate-ff-custom-text":null,"Batch Size":"1","Unique FlowFiles":"false","Data Format":"Text"},"propertyDescriptors":{"character-set":{"name":"character-set","displayName":"Character Set","identifiesControllerService":false,"sensitive":false,"dynamic":false},"File Size":{"name":"File Size","displayName":"File Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"mime-type":{"name":"mime-type","displayName":"Mime Type","identifiesControllerService":false,"sensitive":false,"dynamic":false},"generate-ff-custom-text":{"name":"generate-ff-custom-text","displayName":"Custom Text","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Batch Size":{"name":"Batch Size","displayName":"Batch Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Unique FlowFiles":{"name":"Unique FlowFiles","displayName":"Unique FlowFiles","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Data Format":{"name":"Data Format","displayName":"Data Format","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"1 min","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":0,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":[],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"inputPorts":[],"outputPorts":[],"connections":[{"identifier":"d676965e-fd5d-3790-b008-dca3e47cc2cf","instanceIdentifier":"e27073f8-0192-1000-cf43-9c41e69eadd2","name":"","source":{"id":"292428fc-fe6c-3420-9cf3-fc09587cd56e","type":"OUTPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"output","instanceIdentifier":"e2704f0f-0192-1000-d1d9-0629c2e8e158"},"destination":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":100000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"67162d32-8bac-3306-a143-5b10c88b345e","instanceIdentifier":"e26f4ded-0192-1000-b21b-23c498138f39","name":"","source":{"id":"84ca6d91-c383-34d0-8545-a27387acdabb","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"GenerateFlowFile","comments":"","instanceIdentifier":"e26f20c1-0192-1000-ff8b-bcf395c02076"},"destination":{"id":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"UpdateAttribute","comments":"","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc"},"labelIndex":0,"zIndex":0,"selectedRelationships":["success"],"backPressureObjectThreshold":0,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"dfbb4dc1-1f80-3102-b6b0-6b2557fc056a","instanceIdentifier":"e2717989-0192-1000-3d06-d6ae392ca1bd","name":"","source":{"id":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"UpdateAttribute","comments":"","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc"},"destination":{"id":"94c722c5-94a3-3d20-8a1b-ecd4b6948149","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fbc81-0192-1000-5c4e-2b3b19088532"},"labelIndex":0,"zIndex":0,"selectedRelationships":["success"],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"0 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"da573419-8fcb-3918-969c-71fc8f759c1e","instanceIdentifier":"e26fd0d5-0192-1000-ee3d-f90141590475","name":"","source":{"id":"94c722c5-94a3-3d20-8a1b-ecd4b6948149","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fbc81-0192-1000-5c4e-2b3b19088532"},"destination":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"10 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"a1b2134c-2132-3a66-bdd3-632192e7e1e0","instanceIdentifier":"e2716319-0192-1000-8e8e-1418566faa42","name":"","source":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"destination":{"id":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"UpdateAttribute","comments":"","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":1000000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"234c33fc-7962-3de7-bae1-0b3f6b211c70","instanceIdentifier":"e270eaa4-0192-1000-0622-8f9af5319328","name":"","source":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"destination":{"id":"5aa1a366-1c99-39e7-90b2-526d327eacf8","type":"INPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"input","instanceIdentifier":"e270a7d2-0192-1000-4b49-b7a20716fa6b"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"10 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[{"x":352.0,"y":280.0}],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"labels":[],"funnels":[{"identifier":"94c722c5-94a3-3d20-8a1b-ecd4b6948149","instanceIdentifier":"e26fbc81-0192-1000-5c4e-2b3b19088532","position":{"x":-278.89053176231346,"y":50.36534866201407},"componentType":"FUNNEL","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"17a37393-376f-3399-865d-665853b10d47","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb","position":{"x":390.4401741769484,"y":57.74767262457948},"componentType":"FUNNEL","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"controllerServices":[],"defaultFlowFileExpiration":"0 sec","defaultBackPressureObjectThreshold":10000,"defaultBackPressureDataSizeThreshold":"1 GB","scheduledState":"ENABLED","executionEngine":"INHERITED","maxConcurrentTasks":1,"statelessFlowTimeout":"1 min","componentType":"PROCESS_GROUP","flowFileOutboundPolicy":"STREAM_WHEN_AVAILABLE","flowFileConcurrency":"UNBOUNDED"},"externalControllerServices":{},"parameterContexts":{},"flowEncodingVersion":"1.0","parameterProviders":{},"latest":false} \ No newline at end of file diff --git a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings_noViolation.json b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings_noViolation.json new file mode 100644 index 0000000000..1dc178ec8a --- /dev/null +++ b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-rules/src/test/resources/RestrictBackpressureSettings/RestrictBackpressureSettings_noViolation.json @@ -0,0 +1 @@ +{"flowContents":{"identifier":"d846f5a8-343e-3bda-8c49-4413dde11686","instanceIdentifier":"e26effa4-0192-1000-7826-18bfabd139ac","name":"RestrictBackpressureSettings","comments":"","position":{"x":1787.6793181202202,"y":391.0950428985503},"processGroups":[{"identifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d","instanceIdentifier":"e270189e-0192-1000-8aba-e274768ade7e","name":"EmbeddedProcessGroup","comments":"","position":{"x":-408.0,"y":216.0},"processGroups":[],"remoteProcessGroups":[],"processors":[{"identifier":"aa55546e-8ea7-3276-90ab-0c4b420297e5","instanceIdentifier":"e27038cf-0192-1000-1662-801cfccb85fb","name":"GenerateFlowFile","comments":"","position":{"x":-392.0,"y":-144.0},"type":"org.apache.nifi.processors.standard.GenerateFlowFile","bundle":{"group":"org.apache.nifi","artifact":"nifi-standard-nar","version":"2.0.0-SNAPSHOT"},"properties":{"character-set":"UTF-8","File Size":"0B","mime-type":null,"generate-ff-custom-text":null,"Batch Size":"1","Unique FlowFiles":"false","Data Format":"Text"},"propertyDescriptors":{"character-set":{"name":"character-set","displayName":"Character Set","identifiesControllerService":false,"sensitive":false,"dynamic":false},"File Size":{"name":"File Size","displayName":"File Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"mime-type":{"name":"mime-type","displayName":"Mime Type","identifiesControllerService":false,"sensitive":false,"dynamic":false},"generate-ff-custom-text":{"name":"generate-ff-custom-text","displayName":"Custom Text","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Batch Size":{"name":"Batch Size","displayName":"Batch Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Unique FlowFiles":{"name":"Unique FlowFiles","displayName":"Unique FlowFiles","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Data Format":{"name":"Data Format","displayName":"Data Format","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"1 min","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":0,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":[],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"},{"identifier":"905b896f-b267-32e4-9c72-2399757d7aad","instanceIdentifier":"e270c1f6-0192-1000-a019-53616442b6c2","name":"UpdateAttribute","comments":"","position":{"x":312.0,"y":128.0},"type":"org.apache.nifi.processors.attributes.UpdateAttribute","bundle":{"group":"org.apache.nifi","artifact":"nifi-update-attribute-nar","version":"2.0.0-SNAPSHOT"},"properties":{"Delete Attributes Expression":null,"Store State":"Do not store state","canonical-value-lookup-cache-size":"100","Stateful Variables Initial Value":null},"propertyDescriptors":{"Delete Attributes Expression":{"name":"Delete Attributes Expression","displayName":"Delete Attributes Expression","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Store State":{"name":"Store State","displayName":"Store State","identifiesControllerService":false,"sensitive":false,"dynamic":false},"canonical-value-lookup-cache-size":{"name":"canonical-value-lookup-cache-size","displayName":"Cache Value Lookup Cache Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Stateful Variables Initial Value":{"name":"Stateful Variables Initial Value","displayName":"Stateful Variables Initial Value","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"0 sec","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":25,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":["success"],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"inputPorts":[{"identifier":"5aa1a366-1c99-39e7-90b2-526d327eacf8","instanceIdentifier":"e270a7d2-0192-1000-4b49-b7a20716fa6b","name":"input","position":{"x":-227.0000091008809,"y":117.99999088368702},"type":"INPUT_PORT","concurrentlySchedulableTaskCount":1,"scheduledState":"ENABLED","allowRemoteAccess":false,"portFunction":"STANDARD","componentType":"INPUT_PORT","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"outputPorts":[{"identifier":"292428fc-fe6c-3420-9cf3-fc09587cd56e","instanceIdentifier":"e2704f0f-0192-1000-d1d9-0629c2e8e158","name":"output","position":{"x":295.9999908991191,"y":-91.00000911631298},"type":"OUTPUT_PORT","concurrentlySchedulableTaskCount":1,"scheduledState":"ENABLED","allowRemoteAccess":false,"portFunction":"STANDARD","componentType":"OUTPUT_PORT","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"connections":[{"identifier":"7539bdc8-3dd2-3636-ae44-201abecdbfb9","instanceIdentifier":"e2705bd1-0192-1000-6dad-2b1959453b79","name":"","source":{"id":"aa55546e-8ea7-3276-90ab-0c4b420297e5","type":"PROCESSOR","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"GenerateFlowFile","comments":"","instanceIdentifier":"e27038cf-0192-1000-1662-801cfccb85fb"},"destination":{"id":"292428fc-fe6c-3420-9cf3-fc09587cd56e","type":"OUTPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"output","instanceIdentifier":"e2704f0f-0192-1000-d1d9-0629c2e8e158"},"labelIndex":0,"zIndex":0,"selectedRelationships":["success"],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"},{"identifier":"366f7db1-c00b-30b9-a55a-f75f3d40a10f","instanceIdentifier":"e270d1b3-0192-1000-1407-369fa7dfe9ee","name":"","source":{"id":"5aa1a366-1c99-39e7-90b2-526d327eacf8","type":"INPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"input","instanceIdentifier":"e270a7d2-0192-1000-4b49-b7a20716fa6b"},"destination":{"id":"905b896f-b267-32e4-9c72-2399757d7aad","type":"PROCESSOR","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"UpdateAttribute","comments":"","instanceIdentifier":"e270c1f6-0192-1000-a019-53616442b6c2"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"fb55e92a-7d8e-31b7-b45e-702050f9749d"}],"labels":[],"funnels":[],"controllerServices":[],"defaultFlowFileExpiration":"0 sec","defaultBackPressureObjectThreshold":10000,"defaultBackPressureDataSizeThreshold":"1 GB","scheduledState":"ENABLED","executionEngine":"INHERITED","maxConcurrentTasks":1,"statelessFlowTimeout":"1 min","componentType":"PROCESS_GROUP","flowFileOutboundPolicy":"STREAM_WHEN_AVAILABLE","flowFileConcurrency":"UNBOUNDED","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"remoteProcessGroups":[],"processors":[{"identifier":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc","name":"UpdateAttribute","comments":"","position":{"x":232.0,"y":-216.0},"type":"org.apache.nifi.processors.attributes.UpdateAttribute","bundle":{"group":"org.apache.nifi","artifact":"nifi-update-attribute-nar","version":"2.0.0-SNAPSHOT"},"properties":{"Delete Attributes Expression":null,"Store State":"Do not store state","canonical-value-lookup-cache-size":"100","Stateful Variables Initial Value":null},"propertyDescriptors":{"Delete Attributes Expression":{"name":"Delete Attributes Expression","displayName":"Delete Attributes Expression","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Store State":{"name":"Store State","displayName":"Store State","identifiesControllerService":false,"sensitive":false,"dynamic":false},"canonical-value-lookup-cache-size":{"name":"canonical-value-lookup-cache-size","displayName":"Cache Value Lookup Cache Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Stateful Variables Initial Value":{"name":"Stateful Variables Initial Value","displayName":"Stateful Variables Initial Value","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"0 sec","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":25,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":[],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"84ca6d91-c383-34d0-8545-a27387acdabb","instanceIdentifier":"e26f20c1-0192-1000-ff8b-bcf395c02076","name":"GenerateFlowFile","comments":"","position":{"x":-472.0,"y":-232.0},"type":"org.apache.nifi.processors.standard.GenerateFlowFile","bundle":{"group":"org.apache.nifi","artifact":"nifi-standard-nar","version":"2.0.0-SNAPSHOT"},"properties":{"character-set":"UTF-8","File Size":"0B","mime-type":null,"generate-ff-custom-text":null,"Batch Size":"1","Unique FlowFiles":"false","Data Format":"Text"},"propertyDescriptors":{"character-set":{"name":"character-set","displayName":"Character Set","identifiesControllerService":false,"sensitive":false,"dynamic":false},"File Size":{"name":"File Size","displayName":"File Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"mime-type":{"name":"mime-type","displayName":"Mime Type","identifiesControllerService":false,"sensitive":false,"dynamic":false},"generate-ff-custom-text":{"name":"generate-ff-custom-text","displayName":"Custom Text","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Batch Size":{"name":"Batch Size","displayName":"Batch Size","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Unique FlowFiles":{"name":"Unique FlowFiles","displayName":"Unique FlowFiles","identifiesControllerService":false,"sensitive":false,"dynamic":false},"Data Format":{"name":"Data Format","displayName":"Data Format","identifiesControllerService":false,"sensitive":false,"dynamic":false}},"style":{},"schedulingPeriod":"1 min","schedulingStrategy":"TIMER_DRIVEN","executionNode":"ALL","penaltyDuration":"30 sec","yieldDuration":"1 sec","bulletinLevel":"WARN","runDurationMillis":0,"concurrentlySchedulableTaskCount":1,"autoTerminatedRelationships":[],"scheduledState":"ENABLED","retryCount":10,"retriedRelationships":[],"backoffMechanism":"PENALIZE_FLOWFILE","maxBackoffPeriod":"10 mins","componentType":"PROCESSOR","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"inputPorts":[],"outputPorts":[],"connections":[{"identifier":"d676965e-fd5d-3790-b008-dca3e47cc2cf","instanceIdentifier":"e27073f8-0192-1000-cf43-9c41e69eadd2","name":"","source":{"id":"292428fc-fe6c-3420-9cf3-fc09587cd56e","type":"OUTPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"output","instanceIdentifier":"e2704f0f-0192-1000-d1d9-0629c2e8e158"},"destination":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"67162d32-8bac-3306-a143-5b10c88b345e","instanceIdentifier":"e26f4ded-0192-1000-b21b-23c498138f39","name":"","source":{"id":"84ca6d91-c383-34d0-8545-a27387acdabb","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"GenerateFlowFile","comments":"","instanceIdentifier":"e26f20c1-0192-1000-ff8b-bcf395c02076"},"destination":{"id":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"UpdateAttribute","comments":"","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc"},"labelIndex":0,"zIndex":0,"selectedRelationships":["success"],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"dfbb4dc1-1f80-3102-b6b0-6b2557fc056a","instanceIdentifier":"e2717989-0192-1000-3d06-d6ae392ca1bd","name":"","source":{"id":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"UpdateAttribute","comments":"","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc"},"destination":{"id":"94c722c5-94a3-3d20-8a1b-ecd4b6948149","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fbc81-0192-1000-5c4e-2b3b19088532"},"labelIndex":0,"zIndex":0,"selectedRelationships":["success"],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"da573419-8fcb-3918-969c-71fc8f759c1e","instanceIdentifier":"e26fd0d5-0192-1000-ee3d-f90141590475","name":"","source":{"id":"94c722c5-94a3-3d20-8a1b-ecd4b6948149","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fbc81-0192-1000-5c4e-2b3b19088532"},"destination":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"a1b2134c-2132-3a66-bdd3-632192e7e1e0","instanceIdentifier":"e2716319-0192-1000-8e8e-1418566faa42","name":"","source":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"destination":{"id":"c4d73a47-2c5a-3f57-9a29-49788913d7d2","type":"PROCESSOR","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"UpdateAttribute","comments":"","instanceIdentifier":"e26f3857-0192-1000-776a-3d62e15f75dc"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"234c33fc-7962-3de7-bae1-0b3f6b211c70","instanceIdentifier":"e270eaa4-0192-1000-0622-8f9af5319328","name":"","source":{"id":"17a37393-376f-3399-865d-665853b10d47","type":"FUNNEL","groupId":"d846f5a8-343e-3bda-8c49-4413dde11686","name":"Funnel","comments":"","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb"},"destination":{"id":"5aa1a366-1c99-39e7-90b2-526d327eacf8","type":"INPUT_PORT","groupId":"fb55e92a-7d8e-31b7-b45e-702050f9749d","name":"input","instanceIdentifier":"e270a7d2-0192-1000-4b49-b7a20716fa6b"},"labelIndex":0,"zIndex":0,"selectedRelationships":[""],"backPressureObjectThreshold":10000,"backPressureDataSizeThreshold":"1 GB","flowFileExpiration":"0 sec","prioritizers":[],"bends":[{"x":352.0,"y":280.0}],"loadBalanceStrategy":"DO_NOT_LOAD_BALANCE","partitioningAttribute":"","loadBalanceCompression":"DO_NOT_COMPRESS","componentType":"CONNECTION","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"labels":[],"funnels":[{"identifier":"94c722c5-94a3-3d20-8a1b-ecd4b6948149","instanceIdentifier":"e26fbc81-0192-1000-5c4e-2b3b19088532","position":{"x":-278.89053176231346,"y":50.36534866201407},"componentType":"FUNNEL","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"},{"identifier":"17a37393-376f-3399-865d-665853b10d47","instanceIdentifier":"e26fc51d-0192-1000-2ada-2db85f6623fb","position":{"x":390.4401741769484,"y":57.74767262457948},"componentType":"FUNNEL","groupIdentifier":"d846f5a8-343e-3bda-8c49-4413dde11686"}],"controllerServices":[],"defaultFlowFileExpiration":"0 sec","defaultBackPressureObjectThreshold":10000,"defaultBackPressureDataSizeThreshold":"1 GB","scheduledState":"ENABLED","executionEngine":"INHERITED","maxConcurrentTasks":1,"statelessFlowTimeout":"1 min","componentType":"PROCESS_GROUP","flowFileOutboundPolicy":"STREAM_WHEN_AVAILABLE","flowFileConcurrency":"UNBOUNDED"},"externalControllerServices":{},"parameterContexts":{},"flowEncodingVersion":"1.0","parameterProviders":{},"latest":false} \ No newline at end of file