Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nifi-docs/src/main/asciidoc/administration-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2496,6 +2496,10 @@ public boolean isInitialized() {
return initialized.get();
}

public boolean isAutoResumeState() {
return nifiProperties.getAutoResumeState();
}

public boolean isFlowSynchronized() {
return flowSynchronized.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
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;
Expand Down Expand Up @@ -1173,11 +1174,15 @@ private void inheritControllerServices(final FlowController controller, final Ve

// 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);
}
}

Expand Down Expand Up @@ -1587,5 +1592,14 @@ protected void startNow(final ReportingTaskNode reportingTask) {
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);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Loading