This is an automated email from the ASF dual-hosted git repository.
mcgilman 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 265ef593a6 NIFI-13653 Fixed Sensitive Dynamic Property Update Handling
(#9175)
265ef593a6 is described below
commit 265ef593a6f84e082428f3f123a2b8af1a564af7
Author: David Handermann <[email protected]>
AuthorDate: Tue Aug 13 08:34:44 2024 -0500
NIFI-13653 Fixed Sensitive Dynamic Property Update Handling (#9175)
- Avoided removing Sensitive Dynamic Property Names unless the property
itself is removed
This closes #9175
---
.../nifi/controller/AbstractComponentNode.java | 23 ++++++++++++++++------
.../nifi/controller/TestAbstractComponentNode.java | 11 ++++++++++-
2 files changed, 27 insertions(+), 7 deletions(-)
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 dc188e223d..c13cd54ead 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
@@ -261,18 +261,17 @@ public abstract class AbstractComponentNode implements
ComponentNode {
*
* @param properties Property Names and Values to be updated
* @param allowRemovalOfRequiredProperties Allow Removal of Required
Properties
- * @param updatedSensitiveDynamicPropertyNames Requested Sensitive Dynamic
Property Names replaces current configuration
+ * @param requestedSensitiveDynamicPropertyNames Requested Sensitive
Dynamic Property Names adds to current configuration
*/
@Override
- public void setProperties(final Map<String, String> properties, final
boolean allowRemovalOfRequiredProperties, final Set<String>
updatedSensitiveDynamicPropertyNames) {
+ public void setProperties(final Map<String, String> properties, final
boolean allowRemovalOfRequiredProperties, final Set<String>
requestedSensitiveDynamicPropertyNames) {
if (properties == null) {
return;
}
lock.lock();
try {
- Objects.requireNonNull(updatedSensitiveDynamicPropertyNames,
"Sensitive Dynamic Property Names required");
-
sensitiveDynamicPropertyNames.getAndSet(updatedSensitiveDynamicPropertyNames);
+ Objects.requireNonNull(requestedSensitiveDynamicPropertyNames,
"Sensitive Dynamic Property Names required");
verifyCanUpdateProperties(properties);
@@ -282,6 +281,8 @@ public abstract class AbstractComponentNode implements
ComponentNode {
final PropertyConfigurationMapper configurationMapper = new
PropertyConfigurationMapper();
final Map<String, PropertyConfiguration> configurationMap =
configurationMapper.mapRawPropertyValuesToPropertyConfiguration(this,
properties);
+ final Set<String> removedPropertyNames = new LinkedHashSet<>();
+
try (final NarCloseable narCloseable =
NarCloseable.withComponentNarLoader(extensionManager,
getComponent().getClass(), id)) {
boolean classpathChanged = false;
for (final Map.Entry<String, String> entry :
properties.entrySet()) {
@@ -289,7 +290,7 @@ public abstract class AbstractComponentNode implements
ComponentNode {
// Set sensitive status on dynamic properties after
getting canonical representation of Property Descriptor
final PropertyDescriptor componentDescriptor =
getComponent().getPropertyDescriptor(propertyName);
- final PropertyDescriptor descriptor =
componentDescriptor.isDynamic() &&
updatedSensitiveDynamicPropertyNames.contains(propertyName)
+ final PropertyDescriptor descriptor =
componentDescriptor.isDynamic() &&
requestedSensitiveDynamicPropertyNames.contains(propertyName)
? new
PropertyDescriptor.Builder().fromPropertyDescriptor(componentDescriptor).sensitive(true).build()
: componentDescriptor;
@@ -306,7 +307,10 @@ public abstract class AbstractComponentNode implements
ComponentNode {
}
if (propertyName != null && entry.getValue() == null) {
- removeProperty(propertyName,
allowRemovalOfRequiredProperties);
+ final boolean removed = removeProperty(propertyName,
allowRemovalOfRequiredProperties);
+ if (removed) {
+ removedPropertyNames.add(propertyName);
+ }
} else if (propertyName != null) {
// Use the EL-Agnostic Parameter Parser to gather the
list of referenced Parameters. We do this because we want to keep track of
which parameters
// are referenced, regardless of whether or not they
are referenced from within an EL Expression. However, we also will need to
derive a different ParameterTokenList
@@ -323,6 +327,13 @@ public abstract class AbstractComponentNode implements
ComponentNode {
}
}
+ // Update Sensitive Dynamic Property Names
+ final Set<String> updatedSensitiveDynamicPropertyNames = new
LinkedHashSet<>(sensitiveDynamicPropertyNames.get());
+
updatedSensitiveDynamicPropertyNames.addAll(requestedSensitiveDynamicPropertyNames);
+ // Remove Sensitive Dynamic Property Names for removed
properties
+
updatedSensitiveDynamicPropertyNames.removeAll(removedPropertyNames);
+
sensitiveDynamicPropertyNames.getAndSet(updatedSensitiveDynamicPropertyNames);
+
// Determine the updated Classloader Isolation Key, if
applicable.
final String updatedIsolationKey =
determineClasloaderIsolationKey();
final boolean classloaderIsolationKeyChanged =
!Objects.equals(initialIsolationKey, updatedIsolationKey);
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/controller/TestAbstractComponentNode.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/controller/TestAbstractComponentNode.java
index 2b4abbc10d..31589b0543 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/controller/TestAbstractComponentNode.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/test/java/org/apache/nifi/controller/TestAbstractComponentNode.java
@@ -343,11 +343,12 @@ public class TestAbstractComponentNode {
assertTrue(sensitivePropertyDescriptor.isDynamic());
assertTrue(sensitivePropertyDescriptor.isSensitive());
+ // Set Properties without updating Sensitive Dynamic Property Names
node.setProperties(properties, false, Collections.emptySet());
final PropertyDescriptor updatedPropertyDescriptor =
node.getPropertyDescriptor(PROPERTY_NAME);
assertTrue(updatedPropertyDescriptor.isDynamic());
- assertFalse(updatedPropertyDescriptor.isSensitive());
+ assertTrue(updatedPropertyDescriptor.isSensitive());
final Map<PropertyDescriptor, PropertyConfiguration>
configuredProperties = node.getProperties();
final PropertyDescriptor configuredPropertyDescriptor =
configuredProperties.keySet()
@@ -357,6 +358,14 @@ public class TestAbstractComponentNode {
.orElseThrow(() -> new IllegalStateException("Property Name
not found"));
assertTrue(configuredPropertyDescriptor.isDynamic());
assertFalse(configuredPropertyDescriptor.isSensitive());
+
+ // Set Properties with value removed to update Sensitive Dynamic
Property Names
+ final Map<String, String> removedProperties =
Collections.singletonMap(PROPERTY_NAME, null);
+ node.setProperties(removedProperties, false, Collections.emptySet());
+
+ final PropertyDescriptor removedPropertyDescriptor =
node.getPropertyDescriptor(PROPERTY_NAME);
+ assertTrue(removedPropertyDescriptor.isDynamic());
+ assertFalse(removedPropertyDescriptor.isSensitive());
}
private ValidationContext getServiceValidationContext(final
ControllerServiceState serviceState, final ControllerServiceProvider
serviceProvider) {