Skip to content

Commit 2b4b582

Browse files
committed
fix: Patch NiFi to avoid FlowSynchronizationException issue
1 parent c98be7e commit 2b4b582

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
From bc590ca0aceb644e0bd03d48ff48e77897bccfad Mon Sep 17 00:00:00 2001
2+
From: Andrew Kenworthy <andrew.kenworthy@stackable.tech>
3+
Date: Wed, 29 Apr 2026 17:32:02 +0200
4+
Subject: check services are disabled before calling updateControllerService
5+
6+
---
7+
...tandardVersionedComponentSynchronizer.java | 40 ++++++++++++++++---
8+
1 file changed, 34 insertions(+), 6 deletions(-)
9+
10+
diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
11+
index 092d2f7e7b..dbdbe166f3 100644
12+
--- a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
13+
+++ b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
14+
@@ -745,17 +745,45 @@ public class StandardVersionedComponentSynchronizer implements VersionedComponen
15+
updateControllerService(addedService, proposedService, topLevelGroup);
16+
}
17+
18+
- // Update all of the Controller Services to match the VersionedControllerService
19+
+ // Update all Controller Services to match the VersionedControllerService.
20+
+ // Services may be ENABLED here if the outer "affected components" pass did not
21+
+ // disable them (e.g. COMPONENT_ADDED diffs are skipped by AffectedComponentSet).
22+
+ // We must disable before calling updateControllerService, which calls setProperties
23+
+ // which calls verifyModifiable and throws IllegalStateException on ENABLED services.
24+
+ final long stopTimeout = System.currentTimeMillis() + syncOptions.getComponentStopTimeout().toMillis();
25+
for (final Map.Entry<ControllerServiceNode, VersionedControllerService> entry : services.entrySet()) {
26+
final ControllerServiceNode service = entry.getKey();
27+
final VersionedControllerService proposedService = entry.getValue();
28+
29+
if (updatedVersionedComponentIds.contains(proposedService.getIdentifier())) {
30+
- updateControllerService(service, proposedService, topLevelGroup);
31+
- // Any existing component that is modified during synchronization may have its properties reverted to a pre-migration state,
32+
- // so we then add it to the set to allow migrateProperties to be called again to get it back to the migrated state
33+
- createdAndModifiedExtensions.add(new CreatedOrModifiedExtension(service, getPropertyValues(service)));
34+
- LOG.info("Updated {}", service);
35+
+ final Set<ComponentNode> referencesToRestart = new HashSet<>();
36+
+ final Set<ControllerServiceNode> servicesToRestart = new HashSet<>();
37+
+
38+
+ try {
39+
+ try {
40+
+ stopControllerService(service, proposedService, stopTimeout,
41+
+ syncOptions.getComponentStopTimeoutAction(),
42+
+ referencesToRestart, servicesToRestart, syncOptions);
43+
+ } catch (final FlowSynchronizationException | TimeoutException e) {
44+
+ LOG.error("Failed to stop Controller Service {} before updating", service, e);
45+
+ throw new RuntimeException(e);
46+
+ } catch (final InterruptedException e) {
47+
+ Thread.currentThread().interrupt();
48+
+ LOG.error("Interrupted while stopping Controller Service {}", service, e);
49+
+ throw new RuntimeException(e);
50+
+ }
51+
+ updateControllerService(service, proposedService, topLevelGroup);
52+
+ createdAndModifiedExtensions.add(new CreatedOrModifiedExtension(service, getPropertyValues(service)));
53+
+ LOG.info("Updated {}", service);
54+
+ } finally {
55+
+ // Re-enable services and restart components that were stopped for the update,
56+
+ // restoring the controller to its pre-update running state.
57+
+ if (proposedService.getScheduledState() != org.apache.nifi.flow.ScheduledState.DISABLED) {
58+
+ context.getControllerServiceProvider().enableControllerServicesAsync(servicesToRestart);
59+
+ context.getControllerServiceProvider().scheduleReferencingComponents(
60+
+ service, referencesToRestart, context.getComponentScheduler());
61+
+ }
62+
+ }
63+
}
64+
}
65+

0 commit comments

Comments
 (0)