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 index d5f1db9d7bee..aa7afadfd07d 100644 --- 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 @@ -1882,14 +1882,14 @@ public void synchronize(final ParameterContext parameterContext, final Versioned } private void collectValueAndReferences(final ParameterContext parameterContext, final Map valueAndRef) { - parameterContext.getEffectiveParameters() + parameterContext.getRawEffectiveParameters() .forEach((pd, param) -> valueAndRef.put(pd.getName(), getValueAndReferences(param))); } protected Set getUpdatedParameterNames(final ParameterContext parameterContext, final VersionedParameterContext proposed) { final Map originalValues = new HashMap<>(); collectValueAndReferences(parameterContext, originalValues); - parameterContext.getEffectiveParameters().forEach((pd, param) -> originalValues.put(pd.getName(), getValueAndReferences(param))); + parameterContext.getRawEffectiveParameters().forEach((pd, param) -> originalValues.put(pd.getName(), getValueAndReferences(param))); final Map proposedValues = new HashMap<>(); if (proposed != null) { @@ -1899,7 +1899,7 @@ protected Set getUpdatedParameterNames(final ParameterContext parameterC final ParameterContext inheritedContext = getParameterContextByName(name); if (inheritedContext != null) { collectValueAndReferences(inheritedContext, proposedValues); - inheritedContext.getEffectiveParameters().forEach((pd, param) -> proposedValues.put(pd.getName(), getValueAndReferences(param))); + inheritedContext.getRawEffectiveParameters().forEach((pd, param) -> proposedValues.put(pd.getName(), getValueAndReferences(param))); } } } diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java index 59655ecc5108..ad2d6987d77c 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java @@ -354,6 +354,11 @@ public Map getEffectiveParameters() { } } + @Override + public Map getRawEffectiveParameters() { + return getMergedEffectiveParametersReadLocked(); + } + @Override public Map getEffectiveParameterUpdates(final Map parameterUpdates, final List inheritedParameterContexts) { Objects.requireNonNull(parameterUpdates, "Parameter Updates must be specified"); diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/test/java/org/apache/nifi/parameter/TestStandardParameterContext.java b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/test/java/org/apache/nifi/parameter/TestStandardParameterContext.java index e350056e64e3..992be669bab0 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/test/java/org/apache/nifi/parameter/TestStandardParameterContext.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/test/java/org/apache/nifi/parameter/TestStandardParameterContext.java @@ -962,6 +962,50 @@ public void testParameterValueReferenceResolution() { assertEquals("myserver.example.com", effective.get(new ParameterDescriptor.Builder().name("db_host").build()).getValue()); } + @Test + public void testGetRawEffectiveParametersPreservesAliasValue() { + final StandardParameterContextManager parameterContextLookup = new StandardParameterContextManager(); + + final ParameterContext s = createParameterContext("s", parameterContextLookup); + addProvidedParameter(s, "db_host", "myserver.example.com"); + addProvidedParameter(s, "db_port", "3306"); + + final ParameterContext p = createParameterContext("p", parameterContextLookup); + addParameter(p, "host", "#{db_host}"); + addParameter(p, "port", "#{db_port}"); + addParameter(p, "plain", "literal_value"); + + p.setInheritedParameterContexts(List.of(s)); + + final Map raw = p.getRawEffectiveParameters(); + assertEquals("#{db_host}", raw.get(new ParameterDescriptor.Builder().name("host").build()).getValue()); + assertEquals("#{db_port}", raw.get(new ParameterDescriptor.Builder().name("port").build()).getValue()); + assertEquals("literal_value", raw.get(new ParameterDescriptor.Builder().name("plain").build()).getValue()); + + assertEquals("myserver.example.com", raw.get(new ParameterDescriptor.Builder().name("db_host").build()).getValue()); + assertEquals("3306", raw.get(new ParameterDescriptor.Builder().name("db_port").build()).getValue()); + + final Map effective = p.getEffectiveParameters(); + assertEquals("myserver.example.com", effective.get(new ParameterDescriptor.Builder().name("host").build()).getValue()); + assertEquals("3306", effective.get(new ParameterDescriptor.Builder().name("port").build()).getValue()); + } + + @Test + public void testGetRawEffectiveParametersWithNoInheritance() { + final StandardParameterContextManager parameterContextLookup = new StandardParameterContextManager(); + + final ParameterContext p = createParameterContext("p", parameterContextLookup); + addParameter(p, "a", "#{b}"); + addParameter(p, "b", "concrete"); + + final Map raw = p.getRawEffectiveParameters(); + assertEquals("#{b}", raw.get(new ParameterDescriptor.Builder().name("a").build()).getValue()); + assertEquals("concrete", raw.get(new ParameterDescriptor.Builder().name("b").build()).getValue()); + + final Map effective = p.getEffectiveParameters(); + assertEquals("concrete", effective.get(new ParameterDescriptor.Builder().name("a").build()).getValue()); + } + @Test public void testParameterValueReferenceResolvesQuotedName() { final StandardParameterContextManager parameterContextLookup = new StandardParameterContextManager(); diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java index 7323db1718ff..44e02f7d9291 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java @@ -99,6 +99,20 @@ public interface ParameterContext extends ParameterLookup, ComponentAuthorizable */ Map getEffectiveParameters(); + /** + * Returns the merged effective parameter map -- identical in shape to {@link #getEffectiveParameters()} -- + * but WITHOUT resolving one-to-one parameter value references. Local aliases retain their literal + * #{otherName} values. Use this method for display, persistence comparison, or any other + * read-side use where the raw, user-authored value matters. Use {@link #getEffectiveParameters()} + * when components require fully-resolved values for runtime substitution. + * + * @return a Map that contains all Parameters in the context and all nested ParameterContexts, keyed by their + * descriptors, without parameter value reference resolution applied + */ + default Map getRawEffectiveParameters() { + return getEffectiveParameters(); + } + /** * Returns a map from parameter name to Parameter, representing all parameters that would be effectively * updated if the provided configuration was applied. Only parameters that would be effectively updated or added are diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 0e09c68ea04f..e9d1a9644962 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -1522,7 +1522,7 @@ public ParameterContextDTO createParameterContextDto(final ParameterContext para dto.setBoundProcessGroups(boundGroups); final Set parameterEntities = new LinkedHashSet<>(); - final Map parameters = includeInheritedParameters ? parameterContext.getEffectiveParameters() + final Map parameters = includeInheritedParameters ? parameterContext.getRawEffectiveParameters() : parameterContext.getParameters(); for (final Parameter parameter : parameters.values()) { parameterEntities.add(createParameterEntity(parameterContext, parameter, revisionManager, parameterContextLookup)); diff --git a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/parameters/ParameterContextIT.java b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/parameters/ParameterContextIT.java index 987dc7cc00bc..f0dc1976e557 100644 --- a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/parameters/ParameterContextIT.java +++ b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/parameters/ParameterContextIT.java @@ -1406,6 +1406,42 @@ public void testParameterValueReferenceUserManagedUpdatePropagation() throws NiF } } + @Test + public void testParameterAliasDisplayedAsRawValue() throws NiFiClientException, IOException { + final Set sParams = new HashSet<>(); + sParams.add(createParameterEntity("db_host", null, false, "myserver.example.com")); + final ParameterContextEntity sContextEntity = createParameterContextEntity("S_RawDisplay", "Inherited context", + sParams, Collections.emptyList(), null, null); + final ParameterContextEntity createdS = getNifiClient().getParamContextClient().createParamContext(sContextEntity); + + final Set pParams = new HashSet<>(); + pParams.add(createParameterEntity("host", null, false, "#{db_host}")); + final ParameterContextEntity pContextEntity = createParameterContextEntity("P_RawDisplay", "Parent context with alias", + pParams, Collections.singletonList(createdS), null, null); + final ParameterContextEntity createdP = getNifiClient().getParamContextClient().createParamContext(pContextEntity); + + final ParameterContextEntity fetched = getNifiClient().getParamContextClient().getParamContext(createdP.getId(), true); + final Set parameters = fetched.getComponent().getParameters(); + + final ParameterDTO hostDto = parameters.stream() + .map(ParameterEntity::getParameter) + .filter(p -> "host".equals(p.getName())) + .findFirst() + .orElse(null); + assertNotNull(hostDto); + assertFalse(hostDto.getInherited() != null && hostDto.getInherited()); + assertEquals("#{db_host}", hostDto.getValue()); + + final ParameterDTO dbHostDto = parameters.stream() + .map(ParameterEntity::getParameter) + .filter(p -> "db_host".equals(p.getName())) + .findFirst() + .orElse(null); + assertNotNull(dbHostDto); + assertTrue(dbHostDto.getInherited()); + assertEquals("myserver.example.com", dbHostDto.getValue()); + } + protected void assertAsset(final AssetEntity asset, final String expectedName) { assertNotNull(asset); assertNotNull(asset.getAsset());