You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2019/02/08 15:52:24 UTC

[nifi] branch master updated: NIFI-6008: When a Processor is Terminated, call its #onPropertyModified method for properties whose value differs from the default value. Previously, it was called if the value differs from the current value (which it never will since we are only restoring the current values for the Processor). This results in ensuring that #onPr #onPropertyModified is correctly called when a component is reloaded

This is an automated email from the ASF dual-hosted git repository.

bbende pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/master by this push:
     new 4e914ce  NIFI-6008: When a Processor is Terminated, call its #onPropertyModified method for properties whose value differs from the default value. Previously, it was called if the value differs from the current value (which it never will since we are only restoring the current values for the Processor). This results in ensuring that #onPr #onPropertyModified is correctly called when a component is reloaded
4e914ce is described below

commit 4e914cea1f4c12b7ea020c40a155398a52b89ecf
Author: Mark Payne <ma...@hotmail.com>
AuthorDate: Thu Feb 7 16:56:22 2019 -0500

    NIFI-6008: When a Processor is Terminated, call its #onPropertyModified method for properties whose value differs from the default value. Previously, it was called if the value differs from the current value (which it never will since we are only restoring the current values for the Processor). This results in ensuring that #onPr #onPropertyModified is correctly called when a component is reloaded
    
    This closes #3296.
    
    Signed-off-by: Bryan Bende <bb...@apache.org>
---
 .../nifi/controller/AbstractComponentNode.java      | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java
index e17682e..1f03923 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractComponentNode.java
@@ -56,6 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 public abstract class AbstractComponentNode implements ComponentNode {
@@ -185,7 +186,8 @@ public abstract class AbstractComponentNode implements ComponentNode {
                     if (entry.getKey() != null && entry.getValue() == null) {
                         removeProperty(entry.getKey(), allowRemovalOfRequiredProperties);
                     } else if (entry.getKey() != null) {
-                        setProperty(entry.getKey(), CharacterFilterUtils.filterInvalidXmlCharacters(entry.getValue()));
+                        final String updatedValue = CharacterFilterUtils.filterInvalidXmlCharacters(entry.getValue());
+                        setProperty(entry.getKey(), updatedValue, this.properties::get);
                     }
                 }
 
@@ -210,16 +212,16 @@ public abstract class AbstractComponentNode implements ComponentNode {
     }
 
     // Keep setProperty/removeProperty private so that all calls go through setProperties
-    private void setProperty(final String name, final String value) {
+    private void setProperty(final String name, final String value, final Function<PropertyDescriptor, String> valueToCompareFunction) {
         if (null == name || null == value) {
             throw new IllegalArgumentException("Name or Value can not be null");
         }
 
         final PropertyDescriptor descriptor = getComponent().getPropertyDescriptor(name);
-
+        final String propertyModComparisonValue = valueToCompareFunction.apply(descriptor);
         final String oldValue = properties.put(descriptor, value);
-        if (!value.equals(oldValue)) {
 
+        if (!value.equals(oldValue)) {
             if (descriptor.getControllerServiceDefinition() != null) {
                 if (oldValue != null) {
                     final ControllerServiceNode oldNode = serviceProvider.getControllerServiceNode(oldValue);
@@ -233,7 +235,12 @@ public abstract class AbstractComponentNode implements ComponentNode {
                     newNode.addReference(this);
                 }
             }
+        }
 
+        // In the case of a component "reload", we want to call onPropertyModified when the value is changed from the descriptor's default.
+        // However, we do not want to update any controller service references because those are tied to the ComponentNode. We only want to
+        // allow the newly created component's internal state to be updated.
+        if (!value.equals(propertyModComparisonValue)) {
             try {
                 onPropertyModified(descriptor, oldValue, value);
             } catch (final Exception e) {
@@ -309,10 +316,12 @@ public abstract class AbstractComponentNode implements ComponentNode {
 
     @Override
     public void refreshProperties() {
-        // use setProperty instead of setProperties so we can bypass the class loading logic
+        // use setProperty instead of setProperties so we can bypass the class loading logic.
+        // Consider value changed if it is different than the PropertyDescriptor's default value because we need to call the #onPropertiesModified
+        // method on the component if the current value is not the default value, since the component itself is being reloaded.
         getProperties().entrySet().stream()
                 .filter(e -> e.getKey() != null && e.getValue() != null)
-                .forEach(e -> setProperty(e.getKey().getName(), e.getValue()));
+                .forEach(e -> setProperty(e.getKey().getName(), e.getValue(), PropertyDescriptor::getDefaultValue));
     }
 
     /**