This is an automated email from the ASF dual-hosted git repository.
pvillard31 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 f5e20e3687f NIFI-16285 Allow existing illegal Parameter names to load
(#11616)
f5e20e3687f is described below
commit f5e20e3687f3eee9fecb3a6b59a5b542390616ef
Author: skeossei <[email protected]>
AuthorDate: Thu Sep 3 10:58:57 2026 -0700
NIFI-16285 Allow existing illegal Parameter names to load (#11616)
Do not validate Parameter names during flow inherit so a persisted
flow.json.gz with a legacy illegal name can start and be deleted via REST.
Log a warning when inherit encounters an illegal Parameter name and add
coverage for loading that name into a new or existing Parameter Context.
---
.../nifi/parameter/ParameterNameValidator.java | 6 +-
.../nifi/parameter/ParameterNameValidatorTest.java | 3 +
.../serialization/VersionedFlowSynchronizer.java | 6 +-
.../VersionedFlowSynchronizerTest.java | 80 +++++++++++++++++++---
4 files changed, 83 insertions(+), 12 deletions(-)
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterNameValidator.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterNameValidator.java
index 21bc03b268a..f193f8512e9 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterNameValidator.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterNameValidator.java
@@ -24,8 +24,12 @@ public final class ParameterNameValidator {
private ParameterNameValidator() {
}
+ public static boolean isValid(final String parameterName) {
+ return parameterName != null &&
VALID_PARAMETER_NAME_PATTERN.matcher(parameterName).matches();
+ }
+
public static void validate(final String parameterName) {
- if (parameterName == null ||
!VALID_PARAMETER_NAME_PATTERN.matcher(parameterName).matches()) {
+ if (!isValid(parameterName)) {
throw new IllegalArgumentException("Request contains an illegal
Parameter Name (" + parameterName
+ "). Parameter names may only include letters, numbers,
spaces, and the special characters .-_");
}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/parameter/ParameterNameValidatorTest.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/parameter/ParameterNameValidatorTest.java
index 5e867c6d854..3d26c914bed 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/parameter/ParameterNameValidatorTest.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/parameter/ParameterNameValidatorTest.java
@@ -19,12 +19,14 @@ package org.apache.nifi.parameter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class ParameterNameValidatorTest {
@Test
void testValidParameterName() {
+ assertTrue(ParameterNameValidator.isValid("Parameter Name-1.0"));
assertDoesNotThrow(() -> ParameterNameValidator.validate("Parameter
Name-1.0"));
}
@@ -32,6 +34,7 @@ class ParameterNameValidatorTest {
void testInvalidParameterName() {
final String parameterName = "PARAMETER_{{ ENVIRONMENT }}";
+ assertFalse(ParameterNameValidator.isValid(parameterName));
final IllegalArgumentException exception =
assertThrows(IllegalArgumentException.class,
() -> ParameterNameValidator.validate(parameterName));
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
index 3fb116e4d47..bfee5269475 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
@@ -954,14 +954,16 @@ public class VersionedFlowSynchronizer implements
FlowSynchronizer {
final Map<String, Parameter> parameters = new HashMap<>();
for (final VersionedParameter versioned :
versionedParameterContext.getParameters()) {
- ParameterNameValidator.validate(versioned.getName());
+ final String name = versioned.getName();
+ if (!ParameterNameValidator.isValid(name)) {
+ logger.warn("An invalid Parameter name was found and will be
loaded so it can be removed");
+ }
final boolean provided = providerBacked || versioned.isProvided();
final String parameterValue;
final String rawValue = versioned.getValue();
if (rawValue == null) {
parameterValue = null;
} else if (provided) {
- final String name = versioned.getName();
final Parameter providedParameter =
providedParameters.get(name);
if (providedParameter == null) {
logger.warn("Parameter Context [{}] Provided Parameter
[{}] not found", versionedParameterContext.getIdentifier(), name);
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizerTest.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizerTest.java
index d541e7bfabe..221f730de0f 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizerTest.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizerTest.java
@@ -48,6 +48,7 @@ import org.apache.nifi.groups.BundleUpdateStrategy;
import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.parameter.Parameter;
+import org.apache.nifi.parameter.ParameterContext;
import org.apache.nifi.parameter.ParameterDescriptor;
import org.apache.nifi.parameter.ParameterGroup;
import org.apache.nifi.parameter.ParameterProvider;
@@ -82,7 +83,6 @@ import java.util.concurrent.CompletableFuture;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -370,34 +370,96 @@ class VersionedFlowSynchronizerTest {
}
@Test
- void testSyncRejectsInvalidParameterName() {
+ void testSyncLoadsInvalidParameterName() {
setRootGroup();
setFlowController();
final String invalidParameterName = "PARAMETER_{{ ENVIRONMENT }}";
+ final String parameterValue = "parameter-value";
+ final String contextId = "parameter-context-id";
+ final String contextName = "parameter-context";
final StandardParameterContextManager contextManager = new
StandardParameterContextManager();
+ stubParameterContextResolution(contextManager);
+ when(flowManager.createParameterContext(any(), any(), any(), any(),
any(), any())).thenAnswer(invocation -> {
+ final StandardParameterContext created = new
StandardParameterContext.Builder()
+ .id(invocation.getArgument(0))
+ .name(invocation.getArgument(1))
+ .parameterReferenceManager(ParameterReferenceManager.EMPTY)
+ .build();
+ created.setParameters(invocation.getArgument(3));
+ contextManager.addParameterContext(created);
+ return created;
+ });
+
+ stubInvalidVersionedParameterContext(invalidParameterName,
parameterValue, contextId, contextName);
+
+ assertDoesNotThrow(() ->
+ versionedFlowSynchronizer.sync(flowController, dataFlow,
flowService, BundleUpdateStrategy.USE_SPECIFIED_OR_GHOST));
+
+ final ParameterContext loadedContext =
contextManager.getParameterContext(contextId);
+ assertLoadedInvalidParameter(loadedContext, invalidParameterName,
parameterValue);
+ }
+
+ @Test
+ void testSyncReconcilesExistingInvalidParameterName() {
+ setRootGroup();
+ setFlowController();
+
+ final String invalidParameterName = "PARAMETER_{{ ENVIRONMENT }}";
+ final String parameterValue = "parameter-value";
+ final String contextId = "parameter-context-id";
+ final String contextName = "parameter-context";
+
+ final StandardParameterContext existingContext = new
StandardParameterContext.Builder()
+ .id(contextId)
+ .name(contextName)
+ .parameterReferenceManager(ParameterReferenceManager.EMPTY)
+ .build();
+
existingContext.setParameters(Collections.singletonMap(invalidParameterName,
+ new Parameter.Builder()
+ .name(invalidParameterName)
+ .value("previous-value")
+ .sensitive(true)
+ .build()));
+
+ final StandardParameterContextManager contextManager = new
StandardParameterContextManager();
+ contextManager.addParameterContext(existingContext);
+ stubParameterContextResolution(contextManager);
+ stubInvalidVersionedParameterContext(invalidParameterName,
parameterValue, contextId, contextName);
+
+ assertDoesNotThrow(() ->
+ versionedFlowSynchronizer.sync(flowController, dataFlow,
flowService, BundleUpdateStrategy.USE_SPECIFIED_OR_GHOST));
+
+ assertLoadedInvalidParameter(existingContext, invalidParameterName,
parameterValue);
+ }
+
+ private void stubParameterContextResolution(final
StandardParameterContextManager contextManager) {
when(flowManager.getParameterContextManager()).thenReturn(contextManager);
doAnswer(invocation -> {
invocation.getArgument(0, Runnable.class).run();
return null;
}).when(flowManager).withParameterContextResolution(any());
+ }
+ private void stubInvalidVersionedParameterContext(final String
invalidParameterName, final String parameterValue,
+ final String contextId, final String contextName) {
final VersionedParameter versionedParameter = new VersionedParameter();
versionedParameter.setName(invalidParameterName);
versionedParameter.setSensitive(true);
- versionedParameter.setValue("parameter-value");
+ versionedParameter.setValue(parameterValue);
final VersionedParameterContext versionedParameterContext = new
VersionedParameterContext();
-
versionedParameterContext.setInstanceIdentifier("parameter-context-id");
- versionedParameterContext.setName("parameter-context");
+ versionedParameterContext.setInstanceIdentifier(contextId);
+ versionedParameterContext.setName(contextName);
versionedParameterContext.setParameters(Collections.singleton(versionedParameter));
when(versionedDataflow.getParameterContexts()).thenReturn(List.of(versionedParameterContext));
+ }
- final FlowSynchronizationException exception =
assertThrows(FlowSynchronizationException.class, () ->
- versionedFlowSynchronizer.sync(flowController, dataFlow,
flowService, BundleUpdateStrategy.USE_SPECIFIED_OR_GHOST));
- final IllegalArgumentException cause =
assertInstanceOf(IllegalArgumentException.class, exception.getCause());
- assertTrue(cause.getMessage().contains(invalidParameterName));
+ private void assertLoadedInvalidParameter(final ParameterContext context,
final String invalidParameterName, final String parameterValue) {
+ final Optional<Parameter> loaded =
context.getParameter(invalidParameterName);
+ assertTrue(loaded.isPresent(), "Illegal Parameter already present in
the flow must be loaded so it can be removed");
+ assertEquals(parameterValue, loaded.get().getValue());
}
private void setRootGroup() {