From 289f73e4b0317231378382baede7f9fa5007ef68 Mon Sep 17 00:00:00 2001 From: Mark Payne Date: Tue, 20 Aug 2024 10:17:48 -0400 Subject: [PATCH] NIFI-12991: Fixed issue in which we recursively validate that we can change Execution Engine of a group, but without changing the top level, inherited groups can't actually be changed; instead, replaced logic to ensure that we can change the top level, that we don't validate the constraint that a STATELESS group cannot have a STATEFUL child, and then validate that all descendant groups can be updated, but without checking the descendants' parent groups --- .../nifi/groups/StandardProcessGroup.java | 21 ++++++++++++++++++- .../org/apache/nifi/groups/ProcessGroup.java | 6 ++++++ .../service/mock/MockProcessGroup.java | 4 ++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java index 952b2ec39634..01da985f2b43 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java @@ -4406,6 +4406,23 @@ public void verifyCanSetExecutionEngine(final ExecutionEngine executionEngine) { } } + // Ensure that we are not changing a parent to Stateless when a child is explicitly set to STANDARD. + if (resolvedProposedEngine == ExecutionEngine.STATELESS) { + for (final ProcessGroup descendant : findAllProcessGroups()) { + final ExecutionEngine descendantEngine = descendant.getExecutionEngine(); + if (descendantEngine == ExecutionEngine.STANDARD) { + throw new IllegalStateException("A Process Group using the Stateless Engine may not have a child Process Group using the Standard Engine. Cannot set Execution Engine of " + this + + " to Stateless because it has a child Process Group " + descendant + " using the Standard Engine"); + } + } + } + + verifyCanUpdateExecutionEngine(); + } + + @Override + public void verifyCanUpdateExecutionEngine() { + // Ensure that no components are running / services enabled. for (final ProcessorNode processor : getProcessors()) { if (processor.isRunning()) { throw new IllegalStateException("Cannot change Execution Engine for " + this + " while components are running. " + processor + " is currently running."); @@ -4432,6 +4449,7 @@ public void verifyCanSetExecutionEngine(final ExecutionEngine executionEngine) { } } + // Ensure that there is no data queued. for (final Connection connection : getConnections()) { final boolean queueEmpty = connection.getFlowFileQueue().isEmpty(); if (!queueEmpty) { @@ -4439,9 +4457,10 @@ public void verifyCanSetExecutionEngine(final ExecutionEngine executionEngine) { } } + // Ensure that all descendants are in a good state for updating the execution engine. for (final ProcessGroup child : getProcessGroups()) { if (child.getExecutionEngine() == ExecutionEngine.INHERITED) { - child.verifyCanSetExecutionEngine(executionEngine); + child.verifyCanUpdateExecutionEngine(); } } } diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java index a2822995bc4d..40f94f38ad14 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java @@ -1214,6 +1214,12 @@ public interface ProcessGroup extends ComponentAuthorizable, Positionable, Versi */ void verifyCanSetExecutionEngine(ExecutionEngine executionEngine); + /** + * Verifies that the Process Group is in a state in which the Execution Engine can be changed. + * @throws IllegalStateException if the Execution Engine cannot be changed at this time + */ + void verifyCanUpdateExecutionEngine(); + /** * Sets the maximum number on concurrent tasks that can be run in this Process Group if using the Stateless Execution Engine * @param maxConcurrentTasks the maximum number of concurrent tasks diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java index f08ec1e8734d..a7d1409935de 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java @@ -866,6 +866,10 @@ public ExecutionEngine resolveExecutionEngine() { public void verifyCanSetExecutionEngine(final ExecutionEngine executionEngine) { } + @Override + public void verifyCanUpdateExecutionEngine() { + } + @Override public void setMaxConcurrentTasks(final int maxConcurrentTasks) { }