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 0adf611a4b7 NIFI-16155 Apply autoResumeState to scheduling Controller
Services (#11488)
0adf611a4b7 is described below
commit 0adf611a4b764231cfddac613a6b7928353f256b
Author: Bryan Bende <[email protected]>
AuthorDate: Wed Jul 29 17:12:20 2026 -0400
NIFI-16155 Apply autoResumeState to scheduling Controller Services (#11488)
Signed-off-by: David Handermann <[email protected]>
---
.../src/main/asciidoc/administration-guide.adoc | 2 +-
.../org/apache/nifi/controller/FlowController.java | 4 ++
.../serialization/VersionedFlowSynchronizer.java | 22 +++++--
.../AutoResumeStateControllerServiceIT.java | 77 ++++++++++++++++++++++
4 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 2e9e77981b9..138a50631f8 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -2889,7 +2889,7 @@ This cleanup mechanism takes into account only
automatically created archived _f
|`nifi.flow.configuration.archive.max.time`*|The lifespan of archived
_flow.json_ files. NiFi will delete expired archive files when it updates
_flow.json_ if this property is specified. Expiration is determined based on
current system time and the last modified timestamp of an archived _flow.json_.
If no archive limitation is specified in _nifi.properties_, NiFi removes
archives older than `30 days`.
|`nifi.flow.configuration.archive.max.storage`*|The total data size allowed
for the archived _flow.json_ files. NiFi will delete the oldest archive files
until the total archived file size becomes less than this configuration value,
if this property is specified. If no archive limitation is specified in
_nifi.properties_, NiFi uses `500 MB` for this.
|`nifi.flow.configuration.archive.max.count`*|The number of archive files
allowed. NiFi will delete the oldest archive files so that only N latest
archives can be kept, if this property is specified.
-|`nifi.flowcontroller.autoResumeState`|Indicates whether -upon restart- the
components on the NiFi graph should return to their last state. When running in
cluster, all nodes should have the same value. The default value is `true`.
+|`nifi.flowcontroller.autoResumeState`|Indicates whether -upon restart- the
components on the NiFi graph, including Processors, Controller Services, and
other schedulable components, should return to their last state. When running
in cluster, all nodes should have the same value. The default value is `true`.
|`nifi.flowcontroller.graceful.shutdown.period`|Indicates the shutdown period.
The default value is `10 secs`.
|`nifi.flowcontroller.registry.sync.interval`|Specifies the default recurring
interval at which NiFi synchronizes the flow configuration with Flow Registry
Clients. The default value is `30 min`. This value is used for any Flow
Registry Client that does not configure its own `Synchronization Interval`
property; a Flow Registry Client that sets that property is synchronized at its
own interval instead.
|`nifi.flowservice.writedelay.interval`|When many changes are made to the
_flow.json_, this property specifies how long to wait before writing out the
changes, so as to batch the changes into a single write. The default value is
`500 ms`.
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
index bc899dfd194..4953965ff88 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
@@ -2496,6 +2496,10 @@ public class FlowController implements
ReportingTaskProvider, FlowAnalysisRulePr
return initialized.get();
}
+ public boolean isAutoResumeState() {
+ return nifiProperties.getAutoResumeState();
+ }
+
public boolean isFlowSynchronized() {
return flowSynchronized.get();
}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
index 11a1de113df..8036b7b7c65 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
@@ -108,6 +108,7 @@ import org.apache.nifi.scheduling.SchedulingStrategy;
import org.apache.nifi.services.FlowService;
import org.apache.nifi.util.BundleUtils;
import org.apache.nifi.util.FlowDifferenceFilters;
+import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.util.file.FileUtils;
import org.apache.nifi.web.api.dto.BundleDTO;
import org.slf4j.Logger;
@@ -1173,11 +1174,15 @@ public class VersionedFlowSynchronizer implements
FlowSynchronizer {
// Enable any Controller-level services that are intended to be
enabled.
if (!toEnable.isEmpty()) {
-
controller.getControllerServiceProvider().enableControllerServices(toEnable);
+ if (controller.isInitialized() || controller.isAutoResumeState()) {
+
controller.getControllerServiceProvider().enableControllerServices(toEnable);
- // Validate Controller-level services
- for (final ControllerServiceNode serviceNode : toEnable) {
- serviceNode.performValidation();
+ // Validate Controller-level services
+ for (final ControllerServiceNode serviceNode : toEnable) {
+ serviceNode.performValidation();
+ }
+ } else {
+ logger.info("Leaving {} root Controller Services disabled
because {} is false", toEnable.size(), NiFiProperties.AUTO_RESUME_STATE);
}
}
@@ -1587,5 +1592,14 @@ public class VersionedFlowSynchronizer implements
FlowSynchronizer {
protected void startNow(final ProcessGroup statelessGroup) {
flowController.startProcessGroup(statelessGroup);
}
+
+ @Override
+ protected void enableNow(final Collection<ControllerServiceNode>
controllerServices) {
+ if (flowController.isInitialized() ||
flowController.isAutoResumeState()) {
+ super.enableNow(controllerServices);
+ } else {
+ logger.info("Leaving {} Controller Services disabled because
{} is false", controllerServices.size(), NiFiProperties.AUTO_RESUME_STATE);
+ }
+ }
}
}
diff --git
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/restart/AutoResumeStateControllerServiceIT.java
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/restart/AutoResumeStateControllerServiceIT.java
new file mode 100644
index 00000000000..7a4c64a21d6
--- /dev/null
+++
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/restart/AutoResumeStateControllerServiceIT.java
@@ -0,0 +1,77 @@
+/*
+ * 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.tests.system.restart;
+
+import org.apache.nifi.tests.system.NiFiSystemIT;
+import org.apache.nifi.toolkit.client.NiFiClientException;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.api.entity.ControllerServiceEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+class AutoResumeStateControllerServiceIT extends NiFiSystemIT {
+
+ private static final String ENABLED = "ENABLED";
+
+ @Override
+ protected boolean isDestroyEnvironmentAfterEachTest() {
+ return true;
+ }
+
+ @Override
+ protected boolean isAllowFactoryReuse() {
+ return false;
+ }
+
+ @Test
+ void testRootControllerServiceNotResumedWhenAutoResumeDisabled() throws
NiFiClientException, IOException {
+ final ControllerServiceEntity service =
getClientUtil().createRootLevelControllerService("StandardCountService");
+ getClientUtil().enableControllerService(service);
+ getClientUtil().waitForControllerServiceRunStatus(service.getId(),
ENABLED);
+
+ restartWithAutoResumeStateDisabled();
+
+ final ControllerServiceEntity serviceAfterRestart =
getNifiClient().getControllerServicesClient().getControllerService(service.getId());
+ assertNotEquals(ENABLED,
serviceAfterRestart.getComponent().getState());
+ }
+
+ @Test
+ void testProcessGroupControllerServiceNotResumedWhenAutoResumeDisabled()
throws NiFiClientException, IOException {
+ final ProcessGroupEntity processGroup =
getClientUtil().createProcessGroup("Auto Resume Test", "root");
+ final ControllerServiceEntity service =
getClientUtil().createControllerService("StandardCountService",
processGroup.getId());
+ getClientUtil().enableControllerService(service);
+ getClientUtil().waitForControllerServiceRunStatus(service.getId(),
ENABLED);
+
+ restartWithAutoResumeStateDisabled();
+
+ final ControllerServiceEntity serviceAfterRestart =
getNifiClient().getControllerServicesClient().getControllerService(service.getId());
+ assertNotEquals(ENABLED,
serviceAfterRestart.getComponent().getState());
+ }
+
+ private void restartWithAutoResumeStateDisabled() throws IOException {
+ getNiFiInstance().stop();
+ getNiFiInstance().setProperty(NiFiProperties.AUTO_RESUME_STATE,
"false");
+ getNiFiInstance().start(true);
+
+ setupClient();
+ }
+}