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

markap14 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 6e674d8c77 NIFI-15267 Perform validation when enabling Controller 
Services (#10572)
6e674d8c77 is described below

commit 6e674d8c77b402a4438fb41f55e98f345dd0bdbe
Author: David Handermann <[email protected]>
AuthorDate: Tue Dec 2 11:11:00 2025 -0600

    NIFI-15267 Perform validation when enabling Controller Services (#10572)
    
    - Updated StandardControllerServiceNode enable method to perform validation 
before checking status
    - Added system test with 12 Controller Services that require property 
renaming
    - Added incremental delay for validation and enabling
---
 .../service/StandardControllerServiceNode.java     |  85 ++-
 .../system/MigratePropertiesCountService.java      |  69 ++
 .../org.apache.nifi.controller.ControllerService   |   1 +
 .../SpawnedStandaloneNiFiInstanceFactory.java      |   9 +-
 .../ControllerServiceEnablingFailureIT.java        |  96 +++
 .../migration/MigratePropertiesCountServiceIT.java | 105 ++++
 .../system/migration/PropertyMigrationIT.java      |  10 +
 .../controller-service-enabling-failure/flow.json  |  95 +++
 .../resources/flows/migrate-properties/flow.json   | 695 +++++++++++++++++++++
 9 files changed, 1129 insertions(+), 36 deletions(-)

diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
index 1ebd2237c6..ac0e91fada 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
@@ -73,7 +73,9 @@ import org.slf4j.LoggerFactory;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URL;
+import java.time.Duration;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -99,6 +101,8 @@ public class StandardControllerServiceNode extends 
AbstractComponentNode impleme
 
     private static final Logger LOG = 
LoggerFactory.getLogger(StandardControllerServiceNode.class);
 
+    private static final long INCREMENTAL_VALIDATION_DELAY_MS = 1000;
+    private static final Duration MAXIMUM_DELAY = Duration.ofMinutes(10);
 
     private final AtomicReference<ControllerServiceDetails> 
controllerServiceHolder = new AtomicReference<>(null);
     private final ControllerServiceProvider serviceProvider;
@@ -612,47 +616,51 @@ public class StandardControllerServiceNode extends 
AbstractComponentNode impleme
             this.active.set(true);
         }
 
+        final AtomicLong enablingDelay = new AtomicLong(0);
+        final AtomicLong validationDelay = new AtomicLong(0);
         final ControllerServiceProvider controllerServiceProvider = 
this.serviceProvider;
-        final StandardControllerServiceNode service = this;
-        AtomicLong enablingAttemptCount = new AtomicLong(0);
+        final StandardControllerServiceNode serviceNode = this;
         scheduler.execute(new Runnable() {
             @Override
             public void run() {
-                final ConfigurationContext configContext = new 
StandardConfigurationContext(StandardControllerServiceNode.this, 
controllerServiceProvider, null);
+                final ConfigurationContext configContext = new 
StandardConfigurationContext(serviceNode, controllerServiceProvider, null);
 
                 if (!isActive()) {
-                    LOG.warn("Enabling {} stopped: no active status", 
StandardControllerServiceNode.this);
+                    LOG.warn("Enabling {} stopped: no active status", 
serviceNode);
                     stateTransition.disable();
                     future.complete(null);
                     return;
                 }
 
-                final ValidationStatus validationStatus = 
getValidationStatus();
-                if (validationStatus != ValidationStatus.VALID) {
-                    final ValidationState validationState = 
getValidationState();
-                    LOG.debug("Enabling {} failed: Validation Status [{}] 
Errors {} Attempt [{}] Retrying...",
-                        StandardControllerServiceNode.this, validationStatus, 
validationState.getValidationErrors(), enablingAttemptCount.get());
-
-                    enablingAttemptCount.incrementAndGet();
-                    if (enablingAttemptCount.get() == 120 || 
enablingAttemptCount.get() % 3600 == 0) {
-                        final ControllerService controllerService = 
getControllerServiceImplementation();
-                        final ComponentLog componentLog = new 
SimpleProcessLogger(getIdentifier(), controllerService,
-                                new 
StandardLoggingContext(StandardControllerServiceNode.this));
-                        componentLog.error("Enabling {} failed: Validation 
Status [{}] Errors {}",
-                                service, validationStatus, 
validationState.getValidationErrors());
-                    }
+                // Perform Validation and evaluate status before continuing
+                performValidation();
+                final ValidationState validationState = getValidationState();
+                final ValidationStatus validationStatus = 
validationState.getStatus();
+                if (validationStatus == ValidationStatus.VALID) {
+                    LOG.debug("Enabling {} proceeding after performing 
validation", serviceNode);
+                } else if (completeExceptionallyOnFailure) {
+                    final Collection<ValidationResult> errors = 
validationState.getValidationErrors();
+                    final String message = "Enabling %s failed: Validation 
Status [%s] Errors %s".formatted(serviceNode, validationStatus, errors);
+                    future.completeExceptionally(new 
IllegalStateException(message));
+                } else {
+                    final long selectedValidationDelay = 
getDelay(validationDelay, INCREMENTAL_VALIDATION_DELAY_MS);
 
-                    try {
-                        scheduler.schedule(this, 1, TimeUnit.SECONDS);
-                    } catch (final RejectedExecutionException 
rejectedExecutionException) {
-                        LOG.error("Enabling {} failed: Validation Status [{}] 
Errors {}", StandardControllerServiceNode.this, validationStatus, 
validationState.getValidationErrors(),
-                                rejectedExecutionException);
+                    // Log warning on repeated validation rescheduling
+                    if (selectedValidationDelay > MAXIMUM_DELAY.toMillis()) {
+                        final Collection<ValidationResult> errors = 
validationState.getValidationErrors();
+                        LOG.warn("Validation rescheduled in {} ms for {} 
Errors {}", selectedValidationDelay, serviceNode, errors);
                     }
 
-                    if (completeExceptionallyOnFailure) {
-                        future.completeExceptionally(new 
IllegalStateException("Cannot enable " + StandardControllerServiceNode.this + " 
because it is not valid"));
+                    try {
+                        scheduler.schedule(this, selectedValidationDelay, 
TimeUnit.MILLISECONDS);
+                        LOG.debug("Validation rescheduled in {} ms for {}", 
selectedValidationDelay, serviceNode);
+                    } catch (final RejectedExecutionException e) {
+                        LOG.error("Validation rescheduling rejected for {}", 
serviceNode, e);
+                        final Collection<ValidationResult> errors = 
validationState.getValidationErrors();
+                        final String message = "Enabling %s rejected: 
Validation Status [%s] Errors %s".formatted(serviceNode, validationStatus, 
errors);
+                        future.completeExceptionally(new 
IllegalStateException(message));
                     }
-
+                    // Enable command rescheduled or rejected
                     return;
                 }
 
@@ -668,14 +676,14 @@ public class StandardControllerServiceNode extends 
AbstractComponentNode impleme
                     }
 
                     if (!shouldEnable) {
-                        LOG.info("Disabling {} after enabled due to disable 
action initiated", service);
+                        LOG.info("Disabling {} after enabled due to disable 
action initiated", serviceNode);
                         // Can only happen if user initiated DISABLE operation 
before service finished enabling. It's state will be
                         // set to DISABLING (see disable() operation)
                         invokeDisable(configContext);
                         stateTransition.disable();
                         future.complete(null);
                     } else {
-                        LOG.info("Enabled {}", service);
+                        LOG.info("Enabled {}", serviceNode);
                     }
                 } catch (final Exception e) {
                     if (completeExceptionallyOnFailure) {
@@ -683,13 +691,14 @@ public class StandardControllerServiceNode extends 
AbstractComponentNode impleme
                     }
 
                     final Throwable cause = e instanceof 
InvocationTargetException ? e.getCause() : e;
-                    final ComponentLog componentLog = new 
SimpleProcessLogger(getIdentifier(), controllerService,
-                            new 
StandardLoggingContext(StandardControllerServiceNode.this));
+                    final ComponentLog componentLog = new 
SimpleProcessLogger(getIdentifier(), controllerService, new 
StandardLoggingContext(serviceNode));
                     componentLog.error("Failed to invoke @OnEnabled method", 
cause);
                     invokeDisable(configContext);
 
                     if (isActive()) {
-                        scheduler.schedule(this, administrativeYieldMillis, 
TimeUnit.MILLISECONDS);
+                        // Increment enabling delay to avoid excessive retries
+                        final long selectedEnablingDelay = 
getDelay(enablingDelay, administrativeYieldMillis);
+                        scheduler.schedule(this, selectedEnablingDelay, 
TimeUnit.MILLISECONDS);
                     } else {
                         stateTransition.disable();
                     }
@@ -700,7 +709,6 @@ public class StandardControllerServiceNode extends 
AbstractComponentNode impleme
         return future;
     }
 
-
     /**
      * Will atomically disable this service by invoking its @OnDisabled 
operation.
      * It uses CAS operation on {@link #stateTransition} to transition this 
service
@@ -871,4 +879,17 @@ public class StandardControllerServiceNode extends 
AbstractComponentNode impleme
     protected void performFlowAnalysisOnThis() {
         getValidationContextFactory().getFlowAnalyzer().ifPresent(flowAnalyzer 
-> flowAnalyzer.analyzeControllerService(this));
     }
+
+    private long getDelay(final AtomicLong trackedDelay, final long 
incrementalDelay) {
+        final long selectedDelay;
+
+        final long currentDelay = trackedDelay.get();
+        if (currentDelay > MAXIMUM_DELAY.toMillis()) {
+            selectedDelay = currentDelay;
+        } else {
+            selectedDelay = trackedDelay.addAndGet(incrementalDelay);
+        }
+
+        return selectedDelay;
+    }
 }
diff --git 
a/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/java/org/apache/nifi/cs/tests/system/MigratePropertiesCountService.java
 
b/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/java/org/apache/nifi/cs/tests/system/MigratePropertiesCountService.java
new file mode 100644
index 0000000000..338705aa21
--- /dev/null
+++ 
b/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/java/org/apache/nifi/cs/tests/system/MigratePropertiesCountService.java
@@ -0,0 +1,69 @@
+/*
+ * 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.cs.tests.system;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.migration.PropertyConfiguration;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class MigratePropertiesCountService extends AbstractControllerService 
implements CountService {
+    private static final String PREVIOUS_START_VALUE_PROPERTY_NAME = 
"start-value";
+
+    private static final String PREVIOUS_COUNT_SERVICE_PROPERTY_NAME = 
"count-service";
+
+    static final PropertyDescriptor START_VALUE = new 
PropertyDescriptor.Builder()
+            .name("Start Value")
+            .description("Initial value for counting")
+            .required(true)
+            .addValidator(StandardValidators.LONG_VALIDATOR)
+            .defaultValue("0")
+            .build();
+
+    static final PropertyDescriptor COUNT_SERVICE = new 
PropertyDescriptor.Builder()
+            .name("Count Service")
+            .description("Count Service for testing Controller Service 
dependencies")
+            .required(false)
+            .identifiesControllerService(CountService.class)
+            .build();
+
+    private static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS = 
List.of(
+            START_VALUE,
+            COUNT_SERVICE
+    );
+
+    private final AtomicLong counter = new AtomicLong();
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        return PROPERTY_DESCRIPTORS;
+    }
+
+    @Override
+    public void migrateProperties(final PropertyConfiguration 
propertyConfiguration) {
+        
propertyConfiguration.renameProperty(PREVIOUS_START_VALUE_PROPERTY_NAME, 
START_VALUE.getName());
+        
propertyConfiguration.renameProperty(PREVIOUS_COUNT_SERVICE_PROPERTY_NAME, 
COUNT_SERVICE.getName());
+    }
+
+    @Override
+    public long count() {
+        return counter.getAndIncrement();
+    }
+}
diff --git 
a/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
 
b/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
index 2983552663..a4da9272ec 100644
--- 
a/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
+++ 
b/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions-services/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
@@ -20,6 +20,7 @@ org.apache.nifi.cs.tests.system.LifecycleFailureService
 org.apache.nifi.cs.tests.system.SensitiveDynamicPropertiesService
 org.apache.nifi.cs.tests.system.StandardCountService
 org.apache.nifi.cs.tests.system.StandardSleepService
+org.apache.nifi.cs.tests.system.MigratePropertiesCountService
 org.apache.nifi.cs.tests.system.MigrationService
 org.apache.nifi.cs.tests.system.MockCSVReader
 org.apache.nifi.cs.tests.system.MockCSVWriter
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
index 9e40a1c00a..a8240c02ac 100644
--- 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/SpawnedStandaloneNiFiInstanceFactory.java
@@ -270,9 +270,10 @@ public class SpawnedStandaloneNiFiInstanceFactory 
implements NiFiInstanceFactory
                         }
 
                         try {
-                            Thread.sleep(1000L);
-                        } catch (InterruptedException ex) {
-                            logger.debug("NiFi Startup sleep interrupted", ex);
+                            TimeUnit.SECONDS.sleep(1);
+                        } catch (InterruptedException interrupted) {
+                            logger.warn("NiFi Startup sleep interrupted", 
interrupted);
+                            break;
                         }
                     }
                 }
@@ -282,7 +283,7 @@ public class SpawnedStandaloneNiFiInstanceFactory 
implements NiFiInstanceFactory
         @Override
         public void stop() {
             if (process == null) {
-                logger.info("NiFi Shutdown Ignored (runNiFi==null) [{}]", 
instanceDirectory.getName());
+                logger.debug("NiFi Shutdown request ignored [{}]", 
instanceDirectory.getName());
                 return;
             }
 
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/controllerservice/ControllerServiceEnablingFailureIT.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/controllerservice/ControllerServiceEnablingFailureIT.java
new file mode 100644
index 0000000000..d5ad90883a
--- /dev/null
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/controllerservice/ControllerServiceEnablingFailureIT.java
@@ -0,0 +1,96 @@
+/*
+ * 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.controllerservice;
+
+import org.apache.nifi.components.validation.ValidationStatus;
+import org.apache.nifi.stream.io.GZIPOutputStream;
+import org.apache.nifi.tests.system.InstanceConfiguration;
+import org.apache.nifi.tests.system.NiFiInstanceFactory;
+import org.apache.nifi.tests.system.NiFiSystemIT;
+import org.apache.nifi.tests.system.SpawnedStandaloneNiFiInstanceFactory;
+import org.apache.nifi.toolkit.client.NiFiClientException;
+import org.apache.nifi.web.api.dto.status.ControllerServiceStatusDTO;
+import org.apache.nifi.web.api.entity.ControllerServiceEntity;
+import org.apache.nifi.web.api.entity.ControllerServicesEntity;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ControllerServiceEnablingFailureIT extends NiFiSystemIT {
+    private static final String PARENT_GROUP_ID = 
"c1a920de-019a-1000-6510-f3bca7dd9c69";
+
+    private static final String ENABLING_STATUS = "ENABLING";
+
+    /**
+     * Get Instance Factory using flow.json with property names that require 
renaming
+     *
+     * @return NiFi Instance Factory
+     */
+    @Override
+    public NiFiInstanceFactory getInstanceFactory() {
+        final Path flowJsonInputPath = 
Paths.get("src/test/resources/flows/controller-service-enabling-failure/flow.json");
+        final Path flowJsonOutputPath = 
Paths.get("target/controller-service-enabling-failure-flow.json.gz").toAbsolutePath();
+        try (
+                InputStream inputStream = 
Files.newInputStream(flowJsonInputPath);
+                OutputStream outputStream = new 
GZIPOutputStream(Files.newOutputStream(flowJsonOutputPath))
+        ) {
+            inputStream.transferTo(outputStream);
+        } catch (final IOException e) {
+            throw new UncheckedIOException("Failed to compress Flow 
Configuration [%s]".formatted(flowJsonInputPath), e);
+        }
+
+        return new SpawnedStandaloneNiFiInstanceFactory(
+            new InstanceConfiguration.Builder()
+                    
.bootstrapConfig("src/test/resources/conf/default/bootstrap.conf")
+                    .instanceDirectory("target/standalone-instance")
+                    .flowJson(flowJsonOutputPath.toFile())
+                    .overrideNifiProperties(getNifiPropertiesOverrides())
+                    .build()
+        );
+    }
+
+    @Override
+    protected boolean isAllowFactoryReuse() {
+        return false;
+    }
+
+    @Override
+    protected boolean isDestroyEnvironmentAfterEachTest() {
+        return true;
+    }
+
+    @Test
+    void testControllerServices() throws NiFiClientException, IOException {
+        final ControllerServicesEntity servicesEntity = 
getNifiClient().getFlowClient().getControllerServices(PARENT_GROUP_ID);
+        assertEquals(1, servicesEntity.getControllerServices().size());
+
+        final ControllerServiceEntity controllerService = 
servicesEntity.getControllerServices().iterator().next();
+        final ControllerServiceStatusDTO status = 
controllerService.getStatus();
+        assertEquals(ValidationStatus.VALID.toString(), 
status.getValidationStatus());
+
+        // ENABLING but not ENABLED based on LifecycleFailureService 
implementation and framework enabling attempts
+        assertEquals(ENABLING_STATUS, status.getRunStatus());
+    }
+}
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/MigratePropertiesCountServiceIT.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/MigratePropertiesCountServiceIT.java
new file mode 100644
index 0000000000..3d73beef47
--- /dev/null
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/MigratePropertiesCountServiceIT.java
@@ -0,0 +1,105 @@
+/*
+ * 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.migration;
+
+import org.apache.nifi.stream.io.GZIPOutputStream;
+import org.apache.nifi.tests.system.InstanceConfiguration;
+import org.apache.nifi.tests.system.NiFiInstanceFactory;
+import org.apache.nifi.tests.system.NiFiSystemIT;
+import org.apache.nifi.tests.system.SpawnedStandaloneNiFiInstanceFactory;
+import org.apache.nifi.toolkit.client.NiFiClientException;
+import org.apache.nifi.web.api.entity.ControllerServicesEntity;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class MigratePropertiesCountServiceIT extends NiFiSystemIT {
+    private static final String PARENT_GROUP_ID = 
"c1a920de-019a-1000-6510-f3bca7dd9c69";
+
+    private static final int CONFIGURED_CONTROLLER_SERVICES = 12;
+
+    /**
+     * Override setup method with Timeout annotation to verify Controller 
Service validation timing
+     *
+     * @param testInfo Test Information
+     * @throws IOException Thrown on setup failures
+     */
+    @Timeout(value = 45, unit = TimeUnit.SECONDS)
+    @BeforeEach
+    @Override
+    public void setup(final TestInfo testInfo) throws IOException {
+        super.setup(testInfo);
+    }
+
+    /**
+     * Get Instance Factory using flow.json with property names that require 
renaming
+     *
+     * @return NiFi Instance Factory
+     */
+    @Override
+    public NiFiInstanceFactory getInstanceFactory() {
+        final Path flowJsonInputPath = 
Paths.get("src/test/resources/flows/migrate-properties/flow.json");
+        final Path flowJsonOutputPath = 
Paths.get("target/migrate-properties-flow.json.gz").toAbsolutePath();
+        try (
+                InputStream inputStream = 
Files.newInputStream(flowJsonInputPath);
+                OutputStream outputStream = new 
GZIPOutputStream(Files.newOutputStream(flowJsonOutputPath))
+        ) {
+            inputStream.transferTo(outputStream);
+        } catch (final IOException e) {
+            throw new UncheckedIOException("Failed to compress Flow 
Configuration [%s]".formatted(flowJsonInputPath), e);
+        }
+
+        return new SpawnedStandaloneNiFiInstanceFactory(
+            new InstanceConfiguration.Builder()
+                    
.bootstrapConfig("src/test/resources/conf/default/bootstrap.conf")
+                    .instanceDirectory("target/standalone-instance")
+                    .flowJson(flowJsonOutputPath.toFile())
+                    .overrideNifiProperties(getNifiPropertiesOverrides())
+                    .build()
+        );
+    }
+
+    @Override
+    protected boolean isAllowFactoryReuse() {
+        return false;
+    }
+
+    @Override
+    protected boolean isDestroyEnvironmentAfterEachTest() {
+        return true;
+    }
+
+    @Test
+    void testControllerServices() throws NiFiClientException, IOException {
+        getClientUtil().waitForControllerServicesEnabled(PARENT_GROUP_ID);
+
+        final ControllerServicesEntity servicesEntity = 
getNifiClient().getFlowClient().getControllerServices(PARENT_GROUP_ID);
+        assertEquals(CONFIGURED_CONTROLLER_SERVICES, 
servicesEntity.getControllerServices().size());
+    }
+}
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/PropertyMigrationIT.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/PropertyMigrationIT.java
index cde7059a52..4c74e0fbd1 100644
--- 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/PropertyMigrationIT.java
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/migration/PropertyMigrationIT.java
@@ -52,6 +52,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 public class PropertyMigrationIT extends NiFiSystemIT {
     private static final String SERVICE = "Service";
 
+    @Override
+    protected boolean isAllowFactoryReuse() {
+        return false;
+    }
+
+    @Override
+    protected boolean isDestroyEnvironmentAfterEachTest() {
+        return true;
+    }
+
     @AfterEach
     public void restoreNars() {
         // Stop the NiFi instance, ensure that the 
nifi-system-test-extensions-nar and nifi-alternate-config-extensions bundles
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/flows/controller-service-enabling-failure/flow.json
 
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/flows/controller-service-enabling-failure/flow.json
new file mode 100644
index 0000000000..32dd9ba211
--- /dev/null
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/flows/controller-service-enabling-failure/flow.json
@@ -0,0 +1,95 @@
+{
+  "encodingVersion": {
+    "majorVersion": 2,
+    "minorVersion": 0
+  },
+  "maxTimerDrivenThreadCount": 10,
+  "registries": [],
+  "parameterContexts": [],
+  "parameterProviders": [],
+  "controllerServices": [],
+  "reportingTasks": [],
+  "flowAnalysisRules": [],
+  "rootGroup": {
+    "identifier": "10b0aac8-4c39-3a71-807a-60128ba1ef34",
+    "instanceIdentifier": "35e0b881-019a-1000-190e-b9f7878b3cad",
+    "name": "NiFi Flow",
+    "comments": "",
+    "position": {
+      "x": 0.0,
+      "y": 0.0
+    },
+    "processGroups": [
+      {
+        "identifier": "f22b1174-292d-337a-8115-83282e1ef4d4",
+        "instanceIdentifier": "c1a920de-019a-1000-6510-f3bca7dd9c69",
+        "name": "snapshot",
+        "comments": "",
+        "position": {
+          "x": -305.75,
+          "y": -385.75
+        },
+        "processGroups": [],
+        "remoteProcessGroups": [],
+        "processors": [],
+        "inputPorts": [],
+        "outputPorts": [],
+        "connections": [],
+        "labels": [],
+        "funnels": [],
+        "controllerServices": [
+          {
+            "identifier": "405590bc-42ab-352b-8b4c-10b1295437bb",
+            "instanceIdentifier": "c1ee80be-019a-1000-7fd0-7ecf915c9eb6",
+            "name": "LifecycleFailureService-0",
+            "comments": "",
+            "type": "org.apache.nifi.cs.tests.system.LifecycleFailureService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "Enable Failure Count": "1000"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          }
+        ],
+        "defaultFlowFileExpiration": "0 sec",
+        "defaultBackPressureObjectThreshold": 10000,
+        "defaultBackPressureDataSizeThreshold": "1 GB",
+        "scheduledState": "ENABLED",
+        "executionEngine": "INHERITED",
+        "maxConcurrentTasks": 1,
+        "statelessFlowTimeout": "1 min",
+        "flowFileConcurrency": "UNBOUNDED",
+        "flowFileOutboundPolicy": "STREAM_WHEN_AVAILABLE",
+        "componentType": "PROCESS_GROUP",
+        "groupIdentifier": "10b0aac8-4c39-3a71-807a-60128ba1ef34"
+      }
+    ],
+    "remoteProcessGroups": [],
+    "processors": [],
+    "inputPorts": [],
+    "outputPorts": [],
+    "connections": [],
+    "labels": [],
+    "funnels": [],
+    "controllerServices": [],
+    "defaultFlowFileExpiration": "0 sec",
+    "defaultBackPressureObjectThreshold": 10000,
+    "defaultBackPressureDataSizeThreshold": "1 GB",
+    "scheduledState": "ENABLED",
+    "executionEngine": "INHERITED",
+    "maxConcurrentTasks": 1,
+    "statelessFlowTimeout": "1 min",
+    "flowFileConcurrency": "UNBOUNDED",
+    "flowFileOutboundPolicy": "STREAM_WHEN_AVAILABLE",
+    "componentType": "PROCESS_GROUP"
+  }
+}
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/flows/migrate-properties/flow.json
 
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/flows/migrate-properties/flow.json
new file mode 100644
index 0000000000..69ba4d5399
--- /dev/null
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/flows/migrate-properties/flow.json
@@ -0,0 +1,695 @@
+{
+  "encodingVersion": {
+    "majorVersion": 2,
+    "minorVersion": 0
+  },
+  "maxTimerDrivenThreadCount": 10,
+  "registries": [],
+  "parameterContexts": [],
+  "parameterProviders": [],
+  "controllerServices": [],
+  "reportingTasks": [],
+  "flowAnalysisRules": [],
+  "rootGroup": {
+    "identifier": "10b0aac8-4c39-3a71-807a-60128ba1ef34",
+    "instanceIdentifier": "35e0b881-019a-1000-190e-b9f7878b3cad",
+    "name": "NiFi Flow",
+    "comments": "",
+    "position": {
+      "x": 0.0,
+      "y": 0.0
+    },
+    "processGroups": [
+      {
+        "identifier": "f22b1174-292d-337a-8115-83282e1ef4d4",
+        "instanceIdentifier": "c1a920de-019a-1000-6510-f3bca7dd9c69",
+        "name": "snapshot",
+        "comments": "",
+        "position": {
+          "x": -305.75,
+          "y": -385.75
+        },
+        "processGroups": [],
+        "remoteProcessGroups": [],
+        "processors": [
+          {
+            "identifier": "c1abdf6d-019a-1000-2d20-0e2dba89a292",
+            "instanceIdentifier": "0a622da4-8558-3409-f294-32010ae622ab",
+            "name": "CountFlowFiles",
+            "comments": "",
+            "position": {
+              "x": -1168.0,
+              "y": -896.0
+            },
+            "type": "org.apache.nifi.processors.tests.system.CountFlowFiles",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "count-service": "c1a97022-019a-1000-4c72-79bb12714423"
+            },
+            "propertyDescriptors": {},
+            "style": {},
+            "schedulingPeriod": "0 sec",
+            "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": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "f4ed9bc0-a7e5-3281-92a7-9dc2062ef51c",
+            "instanceIdentifier": "c1c4d1a2-019a-1000-6f39-378a0b7e670b",
+            "name": "CountFlowFiles",
+            "comments": "",
+            "position": {
+              "x": -1672.0,
+              "y": -680.0
+            },
+            "type": "org.apache.nifi.processors.tests.system.CountFlowFiles",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "count-service": "c1a97022-019a-1000-4c72-79bb12714423"
+            },
+            "propertyDescriptors": {},
+            "style": {},
+            "schedulingPeriod": "0 sec",
+            "schedulingStrategy": "TIMER_DRIVEN",
+            "executionNode": "ALL",
+            "penaltyDuration": "30 sec",
+            "yieldDuration": "1 sec",
+            "bulletinLevel": "WARN",
+            "runDurationMillis": 0,
+            "concurrentlySchedulableTaskCount": 1,
+            "autoTerminatedRelationships": [
+              "success"
+            ],
+            "scheduledState": "ENABLED",
+            "retryCount": 10,
+            "retriedRelationships": [],
+            "backoffMechanism": "PENALIZE_FLOWFILE",
+            "maxBackoffPeriod": "10 mins",
+            "componentType": "PROCESSOR",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "786eeeb4-7026-327a-97de-c4cf3066d0da",
+            "instanceIdentifier": "c1aaf194-019a-1000-97b4-9de5c6038a2d",
+            "name": "CountFlowFiles",
+            "comments": "",
+            "position": {
+              "x": -1672.0,
+              "y": -896.0
+            },
+            "type": "org.apache.nifi.processors.tests.system.CountFlowFiles",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "count-service": "c1a97022-019a-1000-4c72-79bb12714423"
+            },
+            "propertyDescriptors": {},
+            "style": {},
+            "schedulingPeriod": "0 sec",
+            "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": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "c1abf8ce-019a-1000-3c4f-fb9ff2068e93",
+            "instanceIdentifier": "8712e667-3cf5-3bb9-0472-3dba5c99d00b",
+            "name": "CountFlowFiles",
+            "comments": "",
+            "position": {
+              "x": -2224.0,
+              "y": -896.0
+            },
+            "type": "org.apache.nifi.processors.tests.system.CountFlowFiles",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "count-service": "c1a97022-019a-1000-4c72-79bb12714423"
+            },
+            "propertyDescriptors": {},
+            "style": {},
+            "schedulingPeriod": "0 sec",
+            "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": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          }
+        ],
+        "inputPorts": [],
+        "outputPorts": [],
+        "connections": [
+          {
+            "identifier": "99ce85cb-2864-3eb1-b0ca-c2c3ab295e35",
+            "instanceIdentifier": "c1c53629-019a-1000-76d3-d440f14a6480",
+            "name": "",
+            "source": {
+              "id": "c1abf8ce-019a-1000-3c4f-fb9ff2068e93",
+              "type": "PROCESSOR",
+              "groupId": "f22b1174-292d-337a-8115-83282e1ef4d4",
+              "name": "CountFlowFiles",
+              "comments": "",
+              "instanceIdentifier": "8712e667-3cf5-3bb9-0472-3dba5c99d00b"
+            },
+            "destination": {
+              "id": "f4ed9bc0-a7e5-3281-92a7-9dc2062ef51c",
+              "type": "PROCESSOR",
+              "groupId": "f22b1174-292d-337a-8115-83282e1ef4d4",
+              "name": "CountFlowFiles",
+              "comments": "",
+              "instanceIdentifier": "c1c4d1a2-019a-1000-6f39-378a0b7e670b"
+            },
+            "labelIndex": 0,
+            "zIndex": 2,
+            "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": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "6a471e1d-32a8-34fc-95d6-cd30dba2b103",
+            "instanceIdentifier": "c1c4dc92-019a-1000-45fa-61adf7b9ee58",
+            "name": "",
+            "source": {
+              "id": "786eeeb4-7026-327a-97de-c4cf3066d0da",
+              "type": "PROCESSOR",
+              "groupId": "f22b1174-292d-337a-8115-83282e1ef4d4",
+              "name": "CountFlowFiles",
+              "comments": "",
+              "instanceIdentifier": "c1aaf194-019a-1000-97b4-9de5c6038a2d"
+            },
+            "destination": {
+              "id": "f4ed9bc0-a7e5-3281-92a7-9dc2062ef51c",
+              "type": "PROCESSOR",
+              "groupId": "f22b1174-292d-337a-8115-83282e1ef4d4",
+              "name": "CountFlowFiles",
+              "comments": "",
+              "instanceIdentifier": "c1c4d1a2-019a-1000-6f39-378a0b7e670b"
+            },
+            "labelIndex": 0,
+            "zIndex": 1,
+            "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": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "a2a51f78-cc69-36f6-bafc-e441e60ef6a4",
+            "instanceIdentifier": "c1e2bdec-019a-1000-d263-f93dd48054e8",
+            "name": "",
+            "source": {
+              "id": "c1abdf6d-019a-1000-2d20-0e2dba89a292",
+              "type": "PROCESSOR",
+              "groupId": "f22b1174-292d-337a-8115-83282e1ef4d4",
+              "name": "CountFlowFiles",
+              "comments": "",
+              "instanceIdentifier": "0a622da4-8558-3409-f294-32010ae622ab"
+            },
+            "destination": {
+              "id": "f4ed9bc0-a7e5-3281-92a7-9dc2062ef51c",
+              "type": "PROCESSOR",
+              "groupId": "f22b1174-292d-337a-8115-83282e1ef4d4",
+              "name": "CountFlowFiles",
+              "comments": "",
+              "instanceIdentifier": "c1c4d1a2-019a-1000-6f39-378a0b7e670b"
+            },
+            "labelIndex": 0,
+            "zIndex": 3,
+            "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": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          }
+        ],
+        "labels": [],
+        "funnels": [],
+        "controllerServices": [
+          {
+            "identifier": "405590bc-42ab-352b-8b4c-10b1295437bb",
+            "instanceIdentifier": "c1ee80be-019a-1000-7fd0-7ecf915c9eb6",
+            "name": "MigratePropertiesCountService-7",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "7"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "e6c0212a-ffeb-3479-ad45-6fc1906fbd87",
+            "instanceIdentifier": "c1eef06d-019a-1000-5923-def423e8e89b",
+            "name": "MigratePropertiesCountService-9",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "9"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "17f78983-e657-394c-9cd5-139edc287bfe",
+            "instanceIdentifier": "c1ee4d01-019a-1000-25d5-bcadd1cc2fbc",
+            "name": "MigratePropertiesCountService-6",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "6"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "e3ba5c31-d8e5-3d36-9d3c-2dc3f29d6371",
+            "instanceIdentifier": "c1ef2fd2-019a-1000-5814-e3b14cfd7185",
+            "name": "MigratePropertiesCountService-10",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "10"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "cf07376e-5c10-33b2-93d5-a9a4ee7c1c04",
+            "instanceIdentifier": "c1e6a9dd-019a-1000-99be-b7ea048419e6",
+            "name": "MigratePropertiesCountService-1",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "1"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "35881ce8-2803-3c0a-b38b-4c78a1d63d3a",
+            "instanceIdentifier": "c1a97022-019a-1000-4c72-79bb12714423",
+            "name": "MigratePropertiesCountService-0",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "0",
+              "count-service": "c1e6a9dd-019a-1000-99be-b7ea048419e6"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "4eff7e6a-7cfb-3869-b1bc-41a145d4f1ed",
+            "instanceIdentifier": "c1ef6d12-019a-1000-47a7-66a2e1fa14ed",
+            "name": "MigratePropertiesCountService-11",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "11"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "0f317a14-3462-3626-a64d-4228684dd344",
+            "instanceIdentifier": "c1eda538-019a-1000-b04f-ff355d6624fe",
+            "name": "MigratePropertiesCountService-3",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "3"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "04ec1f18-76bd-3d01-8317-7fccefea6e5c",
+            "instanceIdentifier": "c1ee16d6-019a-1000-eb16-178b7923f20f",
+            "name": "MigratePropertiesCountService-5",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "5"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "b6018d5e-1adb-38b2-9527-fe12638ba1ee",
+            "instanceIdentifier": "c1eddb74-019a-1000-eef7-db50e1ab98db",
+            "name": "MigratePropertiesCountService-4",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "4"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "e350d312-eb5d-3074-94f0-634de4384db2",
+            "instanceIdentifier": "c1ed6d0c-019a-1000-c334-064873c94518",
+            "name": "MigratePropertiesCountService-2",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "2"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          },
+          {
+            "identifier": "44b0e2cf-f2b6-31e0-8ae4-fb840d3651f0",
+            "instanceIdentifier": "c1eeb8d9-019a-1000-63b7-23f4e1eb2cdf",
+            "name": "MigratePropertiesCountService-8",
+            "comments": "",
+            "type": 
"org.apache.nifi.cs.tests.system.MigratePropertiesCountService",
+            "bundle": {
+              "group": "org.apache.nifi",
+              "artifact": "nifi-system-test-extensions-services-nar",
+              "version": "2.7.0-SNAPSHOT"
+            },
+            "properties": {
+              "start-value": "8"
+            },
+            "propertyDescriptors": {},
+            "controllerServiceApis": [
+              {
+                "type": "org.apache.nifi.cs.tests.system.CountService",
+                "bundle": {
+                  "group": "org.apache.nifi",
+                  "artifact": "nifi-system-test-extensions-services-api-nar",
+                  "version": "2.7.0-SNAPSHOT"
+                }
+              }
+            ],
+            "scheduledState": "ENABLED",
+            "bulletinLevel": "WARN",
+            "componentType": "CONTROLLER_SERVICE",
+            "groupIdentifier": "f22b1174-292d-337a-8115-83282e1ef4d4"
+          }
+        ],
+        "defaultFlowFileExpiration": "0 sec",
+        "defaultBackPressureObjectThreshold": 10000,
+        "defaultBackPressureDataSizeThreshold": "1 GB",
+        "scheduledState": "ENABLED",
+        "executionEngine": "INHERITED",
+        "maxConcurrentTasks": 1,
+        "statelessFlowTimeout": "1 min",
+        "flowFileConcurrency": "UNBOUNDED",
+        "flowFileOutboundPolicy": "STREAM_WHEN_AVAILABLE",
+        "componentType": "PROCESS_GROUP",
+        "groupIdentifier": "10b0aac8-4c39-3a71-807a-60128ba1ef34"
+      }
+    ],
+    "remoteProcessGroups": [],
+    "processors": [],
+    "inputPorts": [],
+    "outputPorts": [],
+    "connections": [],
+    "labels": [],
+    "funnels": [],
+    "controllerServices": [],
+    "defaultFlowFileExpiration": "0 sec",
+    "defaultBackPressureObjectThreshold": 10000,
+    "defaultBackPressureDataSizeThreshold": "1 GB",
+    "scheduledState": "ENABLED",
+    "executionEngine": "INHERITED",
+    "maxConcurrentTasks": 1,
+    "statelessFlowTimeout": "1 min",
+    "flowFileConcurrency": "UNBOUNDED",
+    "flowFileOutboundPolicy": "STREAM_WHEN_AVAILABLE",
+    "componentType": "PROCESS_GROUP"
+  }
+}

Reply via email to