This is an automated email from the ASF dual-hosted git repository. markap14 pushed a commit to branch NIFI-15258 in repository https://gitbox.apache.org/repos/asf/nifi.git
commit 6af93e06f57de23e6a3c94a13d5fae3dfa8bb150 Author: Mark Payne <[email protected]> AuthorDate: Wed Jan 21 12:49:44 2026 -0500 NIFI-15481: Updated ConnectorActions to reflect that starting is not … (#10782) * NIFI-15481: Updated ConnectorActions to reflect that starting is not allowed when invalid. Also updated ValidationState to ensure that we don't return any ValidationResult with a valid flag of true as a 'validation error'. * NIFI-15481: Addressed review feedback --- .../components/validation/ValidationState.java | 16 ++++++++-- .../nifi/controller/AbstractComponentNode.java | 12 +++++--- .../connector/StandardConnectorNode.java | 36 ++++++++++------------ 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/components/validation/ValidationState.java b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/components/validation/ValidationState.java index 184f891d45..d1efd43ab9 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/components/validation/ValidationState.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/components/validation/ValidationState.java @@ -20,14 +20,26 @@ package org.apache.nifi.components.validation; import org.apache.nifi.components.ValidationResult; import java.util.Collection; +import java.util.Collections; public class ValidationState { private final ValidationStatus status; private final Collection<ValidationResult> validationErrors; - public ValidationState(final ValidationStatus status, final Collection<ValidationResult> validationErrors) { + public ValidationState(final ValidationStatus status, final Collection<ValidationResult> validationResults) { this.status = status; - this.validationErrors = validationErrors; + // Ensure that if we are provided any valid results, they are filtered out because we only want to store validation failures. + this.validationErrors = removeValidResults(validationResults); + } + + private Collection<ValidationResult> removeValidResults(final Collection<ValidationResult> validationResults) { + if (validationResults.isEmpty()) { + return Collections.emptyList(); + } + + return validationResults.stream() + .filter(vr -> !vr.isValid()) + .toList(); } public ValidationStatus getStatus() { diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java index ca7c6f9065..ecaa4d3f31 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java @@ -867,13 +867,15 @@ public abstract class AbstractComponentNode implements ComponentNode { @Override public ValidationState performValidation(final ValidationContext validationContext) { - final Collection<ValidationResult> results; + final Collection<ValidationResult> allResults; try (final NarCloseable ignored = NarCloseable.withComponentNarLoader(extensionManager, getComponent().getClass(), getIdentifier())) { - results = computeValidationErrors(validationContext); + allResults = computeValidationErrors(validationContext); } - final ValidationStatus status = results.isEmpty() ? ValidationStatus.VALID : ValidationStatus.INVALID; - final ValidationState validationState = new ValidationState(status, results); + final Collection<ValidationResult> invalidResults = allResults.isEmpty() ? Collections.emptyList() + : allResults.stream().filter(result -> !result.isValid()).toList(); + final ValidationStatus status = invalidResults.isEmpty() ? ValidationStatus.VALID : ValidationStatus.INVALID; + final ValidationState validationState = new ValidationState(status, invalidResults); return validationState; } @@ -892,7 +894,7 @@ public abstract class AbstractComponentNode implements ComponentNode { } protected Collection<ValidationResult> computeValidationErrors(final ValidationContext validationContext) { - Throwable failureCause = null; + Throwable failureCause; try { if (!sensitiveDynamicPropertyNames.get().isEmpty() && !isSupportsSensitiveDynamicProperties()) { diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/components/connector/StandardConnectorNode.java b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/components/connector/StandardConnectorNode.java index 2bb5793432..afb6e37bd9 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/components/connector/StandardConnectorNode.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/components/connector/StandardConnectorNode.java @@ -809,7 +809,6 @@ public class StandardConnectorNode implements ConnectorNode { final ValidationState state = performValidation(); if (state.getStatus() == ValidationStatus.INVALID) { final List<String> validationFailureExplanations = state.getValidationErrors().stream() - .filter(result -> !result.isValid()) .map(ValidationResult::getExplanation) .toList(); @@ -894,6 +893,7 @@ public class StandardConnectorNode implements ConnectorNode { if (currentState == ConnectorState.UPDATED || currentState == ConnectorState.UPDATE_FAILED) { return !hasActiveThread(getActiveFlowContext().getManagedProcessGroup()); } + return false; } @@ -905,8 +905,16 @@ public class StandardConnectorNode implements ConnectorNode { allowed = false; reason = "Connector is not stopped"; } else { - allowed = true; - reason = null; + final Collection<ValidationResult> validationResults = getValidationErrors(); + if (validationResults.isEmpty()) { + allowed = true; + reason = null; + } else { + allowed = false; + reason = "Connector is not valid: " + validationResults.stream() + .map(ValidationResult::getExplanation) + .collect(Collectors.joining("; ")); + } } return new StandardConnectorAction("START", "Start the connector", allowed, reason); @@ -954,24 +962,14 @@ public class StandardConnectorNode implements ConnectorNode { } private ConnectorAction createPurgeFlowFilesAction(final boolean stopped, final boolean dataQueued) { - final boolean allowed; - final String reason; - - if (!stopped) { - allowed = false; - reason = "Connector must be stopped"; - } else if (!dataQueued) { - allowed = false; - reason = "No data is queued"; - } else { - allowed = true; - reason = null; - } - - return new StandardConnectorAction("PURGE_FLOWFILES", "Purge all FlowFiles from the connector, dropping all data without processing it", allowed, reason); + return createDataQueuedAction(stopped, dataQueued, "PURGE_FLOWFILES", "Purge all FlowFiles from the connector, dropping all data without processing it"); } private ConnectorAction createDrainFlowFilesAction(final boolean stopped, final boolean dataQueued) { + return createDataQueuedAction(stopped, dataQueued, "DRAIN_FLOWFILES", "Process data that is currently in the flow but do not ingest any additional data"); + } + + private static ConnectorAction createDataQueuedAction(final boolean stopped, final boolean dataQueued, final String actionName, final String description) { final boolean allowed; final String reason; @@ -986,7 +984,7 @@ public class StandardConnectorNode implements ConnectorNode { reason = null; } - return new StandardConnectorAction("DRAIN_FLOWFILES", "Process data that is currently in the flow but do not ingest any additional data", allowed, reason); + return new StandardConnectorAction(actionName, description, allowed, reason); } private ConnectorAction createApplyUpdatesAction(final ConnectorState currentState) {
