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 83316736f8 NIFI-9959 Add UI Support for Sensitive Dynamic Properties 
(#6073)
83316736f8 is described below

commit 83316736f8f2c657c96aca6d6346f53be061b4d7
Author: exceptionfactory <[email protected]>
AuthorDate: Wed May 25 20:36:31 2022 -0500

    NIFI-9959 Add UI Support for Sensitive Dynamic Properties (#6073)
    
    * NIFI-9959 Added UI Support for Sensitive Dynamic Properties
    
    - Added SupportsSensitiveDynamicProperties to DBCPConnectionPool and 
ScriptedReportingTask
    
    * NIFI-9959 Added sensitive parameter argument for Controller Service 
descriptors
    
    * NIFI-9959 Adjusted sensitive property descriptor handling to support 
changing status
    
    * NIFI-9959 Added info icon for Sensitive Value field
    
    * NIFI-9959 Corrected handling of descriptor for existing dynamic properties
    
    * NIFI-9959 Cleaning up dialog markup.
    
    Co-authored-by: Matt Gilman <[email protected]>
    
    This closes #6073
---
 .../nifi/controller/AbstractComponentNode.java     |   6 +
 .../org/apache/nifi/controller/ComponentNode.java  |   5 +
 .../org/apache/nifi/web/NiFiServiceFacade.java     |   9 +-
 .../apache/nifi/web/StandardNiFiServiceFacade.java |  53 +++----
 .../nifi/web/api/ControllerServiceResource.java    |   7 +-
 .../org/apache/nifi/web/api/ProcessorResource.java |   7 +-
 .../apache/nifi/web/api/ReportingTaskResource.java |   7 +-
 .../main/webapp/js/jquery/modal/jquery.modal.css   |   2 +-
 .../jquery/propertytable/jquery.propertytable.js   | 160 +++++++++++++++------
 .../webapp/js/nf/canvas/nf-controller-service.js   |   9 +-
 .../js/nf/canvas/nf-processor-configuration.js     |  10 +-
 .../main/webapp/js/nf/canvas/nf-reporting-task.js  |   9 +-
 .../reporting/script/ScriptedReportingTask.java    |   2 +
 .../org/apache/nifi/dbcp/DBCPConnectionPool.java   |   2 +
 14 files changed, 190 insertions(+), 98 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 c2f7636a7a..32361f6576 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
@@ -996,6 +996,12 @@ public abstract class AbstractComponentNode implements 
ComponentNode {
         return foundApiDependency;
     }
 
+    @Override
+    public boolean isSensitiveDynamicProperty(final String name) {
+        Objects.requireNonNull(name, "Property Name required");
+        return sensitiveDynamicPropertyNames.get().contains(name);
+    }
+
     @Override
     public PropertyDescriptor getPropertyDescriptor(final String name) {
         try (final NarCloseable narCloseable = 
NarCloseable.withComponentNarLoader(extensionManager, 
getComponent().getClass(), getComponent().getIdentifier())) {
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ComponentNode.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ComponentNode.java
index 136dac5fef..3be5204bb5 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ComponentNode.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ComponentNode.java
@@ -261,6 +261,11 @@ public interface ComponentNode extends 
ComponentAuthorizable {
      */
     PropertyDescriptor getPropertyDescriptor(String name);
 
+    /**
+     * @param name Property Name
+     * @return Sensitive Dynamic Property status
+     */
+    boolean isSensitiveDynamicProperty(String name);
 
     @Override
     default AuthorizationResult checkAuthorization(Authorizer authorizer, 
RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index ea78af85ae..aa75f20234 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -616,9 +616,10 @@ public interface NiFiServiceFacade {
      *
      * @param id id
      * @param property property
+     * @param sensitive requested sensitive status
      * @return descriptor
      */
-    PropertyDescriptorDTO getProcessorPropertyDescriptor(String id, String 
property);
+    PropertyDescriptorDTO getProcessorPropertyDescriptor(String id, String 
property, boolean sensitive);
 
     /**
      * Gets all the Processor transfer objects for this controller.
@@ -2046,9 +2047,10 @@ public interface NiFiServiceFacade {
      *
      * @param id id
      * @param property property
+     * @param sensitive requested sensitive status
      * @return property
      */
-    PropertyDescriptorDTO getControllerServicePropertyDescriptor(String id, 
String property);
+    PropertyDescriptorDTO getControllerServicePropertyDescriptor(String id, 
String property, boolean sensitive);
 
     /**
      * Gets the references for specified controller service.
@@ -2168,9 +2170,10 @@ public interface NiFiServiceFacade {
      *
      * @param id id
      * @param property property
+     * @param sensitive requested sensitive status
      * @return descriptor
      */
-    PropertyDescriptorDTO getReportingTaskPropertyDescriptor(String id, String 
property);
+    PropertyDescriptorDTO getReportingTaskPropertyDescriptor(String id, String 
property, boolean sensitive);
 
     /**
      * Updates the specified reporting task.
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index ff96408805..aa39cb6d7a 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -3642,15 +3642,9 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
-    public PropertyDescriptorDTO getProcessorPropertyDescriptor(final String 
id, final String property) {
+    public PropertyDescriptorDTO getProcessorPropertyDescriptor(final String 
id, final String property, final boolean sensitive) {
         final ProcessorNode processor = processorDAO.getProcessor(id);
-        PropertyDescriptor descriptor = 
processor.getPropertyDescriptor(property);
-
-        // return an invalid descriptor if the processor doesn't support this 
property
-        if (descriptor == null) {
-            descriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
-        }
-
+        final PropertyDescriptor descriptor = getPropertyDescriptor(processor, 
property, sensitive);
         return dtoFactory.createPropertyDescriptorDto(descriptor, 
processor.getProcessGroup().getIdentifier());
     }
 
@@ -4511,15 +4505,9 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
-    public PropertyDescriptorDTO getControllerServicePropertyDescriptor(final 
String id, final String property) {
+    public PropertyDescriptorDTO getControllerServicePropertyDescriptor(final 
String id, final String property, final boolean sensitive) {
         final ControllerServiceNode controllerService = 
controllerServiceDAO.getControllerService(id);
-        PropertyDescriptor descriptor = 
controllerService.getPropertyDescriptor(property);
-
-        // return an invalid descriptor if the controller service doesn't 
support this property
-        if (descriptor == null) {
-            descriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
-        }
-
+        final PropertyDescriptor descriptor = 
getPropertyDescriptor(controllerService, property, sensitive);
         final String groupId = controllerService.getProcessGroup() == null ? 
null : controllerService.getProcessGroup().getIdentifier();
         return dtoFactory.createPropertyDescriptorDto(descriptor, groupId);
     }
@@ -4555,15 +4543,9 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
-    public PropertyDescriptorDTO getReportingTaskPropertyDescriptor(final 
String id, final String property) {
+    public PropertyDescriptorDTO getReportingTaskPropertyDescriptor(final 
String id, final String property, final boolean sensitive) {
         final ReportingTaskNode reportingTask = 
reportingTaskDAO.getReportingTask(id);
-        PropertyDescriptor descriptor = 
reportingTask.getPropertyDescriptor(property);
-
-        // return an invalid descriptor if the reporting task doesn't support 
this property
-        if (descriptor == null) {
-            descriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
-        }
-
+        final PropertyDescriptor descriptor = 
getPropertyDescriptor(reportingTask, property, sensitive);
         return dtoFactory.createPropertyDescriptorDto(descriptor, null);
     }
 
@@ -5887,6 +5869,29 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         };
     }
 
+    private PropertyDescriptor getPropertyDescriptor(final ComponentNode 
componentNode, final String property, final boolean sensitive) {
+        final PropertyDescriptor propertyDescriptor;
+
+        final PropertyDescriptor componentDescriptor = 
componentNode.getPropertyDescriptor(property);
+        if (componentDescriptor == null) {
+            propertyDescriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
+        } else if (
+                componentDescriptor.isDynamic() && (
+                        // Allow setting sensitive status for properties 
marked as sensitive in previous requests
+                        componentNode.isSensitiveDynamicProperty(property) || (
+                                // Allow setting sensitive status for 
properties not marked as sensitive in supporting components
+                                !componentDescriptor.isSensitive() && 
componentNode.isSupportsSensitiveDynamicProperties()
+                        )
+                )
+        ) {
+            propertyDescriptor = new 
PropertyDescriptor.Builder().fromPropertyDescriptor(componentDescriptor).sensitive(sensitive).build();
+        } else {
+            propertyDescriptor = componentDescriptor;
+        }
+
+        return propertyDescriptor;
+    }
+
     @Override
     public void verifyPublicInputPortUniqueness(final String portId, final 
String portName) {
         inputPortDAO.verifyPublicPortUniqueness(portId, portName);
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
index e22a672b4f..928a649e1d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
@@ -281,12 +281,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
         });
 
         // get the property descriptor
-        final PropertyDescriptorDTO descriptor = 
serviceFacade.getControllerServicePropertyDescriptor(id, propertyName);
-
-        // Adjust sensitive status for dynamic properties when sensitive 
status enabled
-        if (descriptor.isDynamic() && sensitive) {
-            descriptor.setSensitive(true);
-        }
+        final PropertyDescriptorDTO descriptor = 
serviceFacade.getControllerServicePropertyDescriptor(id, propertyName, 
sensitive);
 
         // generate the response entity
         final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index f16c28ff31..440981737d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -427,12 +427,7 @@ public class ProcessorResource extends ApplicationResource 
{
         });
 
         // get the property descriptor
-        final PropertyDescriptorDTO descriptor = 
serviceFacade.getProcessorPropertyDescriptor(id, propertyName);
-
-        // Adjust sensitive status for dynamic properties when sensitive 
status enabled
-        if (descriptor.isDynamic() && sensitive) {
-            descriptor.setSensitive(true);
-        }
+        final PropertyDescriptorDTO descriptor = 
serviceFacade.getProcessorPropertyDescriptor(id, propertyName, sensitive);
 
         // generate the response entity
         final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
index 3f32e6b1fc..114af5d64b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
@@ -267,12 +267,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
         });
 
         // get the property descriptor
-        final PropertyDescriptorDTO descriptor = 
serviceFacade.getReportingTaskPropertyDescriptor(id, propertyName);
-
-        // Adjust sensitive status for dynamic properties when sensitive 
status enabled
-        if (descriptor.isDynamic() && sensitive) {
-            descriptor.setSensitive(true);
-        }
+        final PropertyDescriptorDTO descriptor = 
serviceFacade.getReportingTaskPropertyDescriptor(id, propertyName, sensitive);
 
         // generate the response entity
         final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.css
index 1795d6d099..f12da2989e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.css
@@ -108,4 +108,4 @@
     bottom: 0;
     width: 100%;
     height: 32px;
-}
\ No newline at end of file
+}
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
index 5ec357f7a6..6c482bb3e7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
@@ -105,6 +105,7 @@
                   _) {
 
     var groupId = null;
+    var supportsSensitiveDynamicProperties = false;
     var propertyVerificationCallback = null;
     var COMBO_MIN_WIDTH = 212;
     var EDITOR_MIN_WIDTH = 212;
@@ -1211,7 +1212,8 @@
                         contentType: 'application/json'
                     }).done(function (response) {
                         // load the descriptor and update the property
-                        
configurationOptions.descriptorDeferred(item.property).done(function 
(descriptorResponse) {
+                        // Controller Service dynamic property descriptors 
will not be marked as sensitive
+                        configurationOptions.descriptorDeferred(item.property, 
false).done(function (descriptorResponse) {
                             var descriptor = 
descriptorResponse.propertyDescriptor;
 
                             // store the descriptor for use later
@@ -1600,6 +1602,10 @@
                         hidden: true
                     }));
 
+                    // Delete property descriptor
+                    var descriptors = table.data('descriptors');
+                    delete descriptors[property.property];
+
                     // prevents standard edit logic
                     e.stopImmediatePropagation();
                 } else if (target.hasClass('go-to-service')) {
@@ -1829,6 +1835,17 @@
         return properties;
     };
 
+    var getSensitiveDynamicPropertyNames = function (table) {
+        var sensitiveDynamicPropertyNames = [];
+        var descriptors = table.data('descriptors');
+        $.each(descriptors, function () {
+            if (nfCommon.isSensitiveProperty(this) === true && 
nfCommon.isDynamicProperty(this) === true) {
+                sensitiveDynamicPropertyNames.push(this.name);
+            }
+        });
+        return sensitiveDynamicPropertyNames;
+    };
+
     /**
      * Performs the filtering.
      *
@@ -2028,21 +2045,35 @@
                         var newPropertyDialogMarkup =
                             '<div id="new-property-dialog" class="dialog 
cancellable small-dialog hidden">' +
                                 '<div class="dialog-content">' +
-                                    '<div>' +
-                                    '<div class="setting-name">Property 
name</div>' +
+                                    '<div class="setting">' +
+                                        '<div class="setting-name">Property 
name</div>' +
                                         '<div class="setting-field 
new-property-name-container">' +
                                             '<input class="new-property-name" 
type="text"/>' +
                                         '</div>' +
                                     '</div>' +
+                                    '<div class="setting">' +
+                                        '<div class="setting-name">Sensitive 
Value ' +
+                                            '<span class="fa 
fa-question-circle" alt="Info"' +
+                                                ' title="Components must 
declare support for Sensitive Dynamic Properties to enable selection of 
Sensitive Value status.' +
+                                                ' Components that flag dynamic 
properties as sensitive do not allow Sensitive Value status to be changed."' +
+                                            '>' +
+                                            '</span>' +
+                                        '</div>' +
+                                        '<div class="setting-field">' +
+                                            '<input 
id="value-sensitive-radio-button" type="radio" name="sensitive" 
value="sensitive" /> Yes' +
+                                            '<input 
id="value-not-sensitive-radio-button" type="radio" name="sensitive" 
value="plain" style="margin-left: 20px;"/> No' +
+                                        '</div>' +
+                                    '</div>' +
                                 '</div>' +
                             '</div>';
 
                         var newPropertyDialog = 
$(newPropertyDialogMarkup).appendTo(options.dialogContainer);
                         var newPropertyNameField = 
newPropertyDialog.find('input.new-property-name');
+                        var valueSensitiveField = 
newPropertyDialog.find('#value-sensitive-radio-button');
+                        var valueNotSensitiveField = 
newPropertyDialog.find('#value-not-sensitive-radio-button');
 
                         newPropertyDialog.modal({
                             headerText: 'Add Property',
-                            scrollableContentStyle: 'scrollable',
                             buttons: [{
                                 buttonText: 'Ok',
                                 color: {
@@ -2088,9 +2119,10 @@
                                     }
                                 });
 
-                                if (existingItem === null) {
-                                    // load the descriptor and add the property
-                                    
options.descriptorDeferred(propertyName).done(function (response) {
+                                if (existingItem === null || 
existingItem.hidden === true) {
+                                    // load the descriptor with requested 
sensitive status
+                                    var sensitive = 
valueSensitiveField.prop('checked');
+                                    options.descriptorDeferred(propertyName, 
sensitive).done(function (response) {
                                         var descriptor = 
response.propertyDescriptor;
 
                                         // store the descriptor for use later
@@ -2099,47 +2131,49 @@
                                             descriptors[descriptor.name] = 
descriptor;
                                         }
 
-                                        // add a row for the new property
-                                        var id = 
propertyData.getItems().length;
-                                        propertyData.addItem({
-                                            id: id,
-                                            hidden: false,
-                                            property: propertyName,
-                                            displayName: propertyName,
-                                            previousValue: null,
-                                            value: null,
-                                            type: 'userDefined'
-                                        });
-
-                                        // select the new properties row
-                                        var row = propertyData.getRowById(id);
-                                        propertyGrid.setActiveCell(row, 
propertyGrid.getColumnIndex('value'));
-                                        propertyGrid.editActiveCell();
+                                        // add the property when existing item 
not found
+                                        if (existingItem === null) {
+                                            // add a row for the new property
+                                            var id = 
propertyData.getItems().length;
+                                            propertyData.addItem({
+                                                id: id,
+                                                hidden: false,
+                                                property: propertyName,
+                                                displayName: propertyName,
+                                                previousValue: null,
+                                                value: null,
+                                                type: 'userDefined'
+                                            });
+
+                                            // select the new properties row
+                                            var row = 
propertyData.getRowById(id);
+                                            propertyGrid.setActiveCell(row, 
propertyGrid.getColumnIndex('value'));
+                                            propertyGrid.editActiveCell();
+                                        } else {
+                                            // if this row is currently 
hidden, clear the value and show it
+                                            
propertyData.updateItem(existingItem.id, $.extend(existingItem, {
+                                                hidden: false,
+                                                previousValue: null,
+                                                value: null
+                                            }));
+
+                                            // select the new properties row
+                                            var row = 
propertyData.getRowById(existingItem.id);
+                                            propertyGrid.invalidateRow(row);
+                                            propertyGrid.render();
+                                            propertyGrid.setActiveCell(row, 
propertyGrid.getColumnIndex('value'));
+                                            propertyGrid.editActiveCell();
+                                        }
                                     });
                                 } else {
-                                    // if this row is currently hidden, clear 
the value and show it
-                                    if (existingItem.hidden === true) {
-                                        
propertyData.updateItem(existingItem.id, $.extend(existingItem, {
-                                            hidden: false,
-                                            previousValue: null,
-                                            value: null
-                                        }));
-
-                                        // select the new properties row
-                                        var row = 
propertyData.getRowById(existingItem.id);
-                                        propertyGrid.setActiveCell(row, 
propertyGrid.getColumnIndex('value'));
-                                        propertyGrid.editActiveCell();
-                                    } else {
-                                        nfDialog.showOkDialog({
-                                            headerText: 'Property Exists',
-                                            dialogContent: 'A property with 
this name already exists.'
-                                        });
-
-                                        // select the existing properties row
-                                        var row = 
propertyData.getRowById(existingItem.id);
-                                        propertyGrid.setSelectedRows([row]);
-                                        propertyGrid.scrollRowIntoView(row);
-                                    }
+                                    nfDialog.showOkDialog({
+                                        headerText: 'Property Exists',
+                                        dialogContent: 'A property with this 
name already exists.'
+                                    });
+                                    // select the existing properties row
+                                    var row = 
propertyData.getRowById(existingItem.id);
+                                    propertyGrid.setSelectedRows([row]);
+                                    propertyGrid.scrollRowIntoView(row);
                                 }
                             } else {
                                 nfDialog.showOkDialog({
@@ -2184,6 +2218,15 @@
 
                             // set the initial focus
                             newPropertyNameField.focus();
+
+                            // Set initial Sensitive Value radio button status
+                            valueSensitiveField.prop('checked', false);
+                            valueNotSensitiveField.prop('checked', true);
+
+                            // Set disabled status based on component support 
indicated
+                            var sensitiveFieldDisabled = 
supportsSensitiveDynamicProperties !== true;
+                            valueSensitiveField.prop('disabled', 
sensitiveFieldDisabled);
+                            valueNotSensitiveField.prop('disabled', 
sensitiveFieldDisabled);
                         }).appendTo(addProperty);
 
                         // build the control to trigger verification
@@ -2333,6 +2376,22 @@
             return properties;
         },
 
+        /**
+         * Get Sensitive Dynamic Property Names based on Property Descriptor 
status
+         */
+        getSensitiveDynamicPropertyNames: function () {
+            var sensitiveDynamicPropertyNames = [];
+
+            this.each(function () {
+                // get the property grid data
+                var table = $(this).find('div.property-table');
+                sensitiveDynamicPropertyNames = 
getSensitiveDynamicPropertyNames(table);
+                return false;
+            });
+
+            return sensitiveDynamicPropertyNames;
+        },
+
         /**
          * Sets the current group id. This is used to indicate where inline 
Controller Services are created
          * and to obtain the parameter context.
@@ -2343,6 +2402,15 @@
             });
         },
 
+        /**
+         * Set Support status for Sensitive Dynamic Properties
+         */
+        setSupportsSensitiveDynamicProperties: function 
(currentSupportsSensitiveDynamicProperties) {
+            return this.each(function () {
+                supportsSensitiveDynamicProperties = 
currentSupportsSensitiveDynamicProperties;
+            });
+        },
+
         /**
          * Sets the property verification callback.
          */
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
index d232b1ab16..9b3a902ac6 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
@@ -120,6 +120,7 @@
         if ($.isEmptyObject(properties) === false) {
             controllerServiceDto['properties'] = properties;
         }
+        controllerServiceDto['sensitiveDynamicPropertyNames'] = 
$('#controller-service-properties').propertytable('getSensitiveDynamicPropertyNames');
 
         // create the controller service entity
         var controllerServiceEntity = {};
@@ -1518,14 +1519,16 @@
      * Gets a property descriptor for the controller service currently being 
configured.
      *
      * @param {type} propertyName
+     * @param {type} sensitive Requested sensitive status
      */
-    var getControllerServicePropertyDescriptor = function (propertyName) {
+    var getControllerServicePropertyDescriptor = function (propertyName, 
sensitive) {
         var controllerServiceEntity = 
$('#controller-service-configuration').data('controllerServiceDetails');
         return $.ajax({
             type: 'GET',
             url: controllerServiceEntity.uri + '/descriptors',
             data: {
-                propertyName: propertyName
+                propertyName: propertyName,
+                sensitive: sensitive
             },
             dataType: 'json'
         }).fail(nfErrorHandler.handleAjaxError);
@@ -2113,6 +2116,7 @@
                 // load the property table
                 $('#controller-service-properties')
                     .propertytable('setGroupId', 
controllerService.parentGroupId)
+                    .propertytable('setSupportsSensitiveDynamicProperties', 
controllerService.supportsSensitiveDynamicProperties)
                     .propertytable('loadProperties', 
controllerService.properties, controllerService.descriptors, 
controllerServiceHistory.propertyHistory)
                     .propertytable('setPropertyVerificationCallback', function 
(proposedProperties) {
                         nfVerify.verify(controllerService['id'], 
controllerServiceEntity['uri'], proposedProperties, referencedAttributes, 
handleVerificationResults, 
$('#controller-service-properties-verification-results-listing'));
@@ -2257,6 +2261,7 @@
                 // load the property table
                 $('#controller-service-properties')
                     .propertytable('setGroupId', 
controllerService.parentGroupId)
+                    .propertytable('setSupportsSensitiveDynamicProperties', 
controllerService.supportsSensitiveDynamicProperties)
                     .propertytable('loadProperties', 
controllerService.properties, controllerService.descriptors, 
controllerServiceHistory.propertyHistory);
 
                 // show the details
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
index dd04ec0bb5..b802c3b4b0 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
@@ -387,6 +387,10 @@
             processorConfigDto['properties'] = properties;
         }
 
+        if (processor.supportsSensitiveDynamicProperties === true) {
+            processorConfigDto['sensitiveDynamicPropertyNames'] = 
$('#processor-properties').propertytable('getSensitiveDynamicPropertyNames');
+        }
+
         // create the processor dto
         var processorDto = {};
         processorDto['id'] = $('#processor-id').text();
@@ -697,14 +701,15 @@
                 readOnly: false,
                 supportsGoTo: true,
                 dialogContainer: '#new-processor-property-container',
-                descriptorDeferred: function (propertyName) {
+                descriptorDeferred: function (propertyName, sensitive) {
                     var processor = 
$('#processor-configuration').data('processorDetails');
                     var d = nfProcessor.get(processor.id);
                     return $.ajax({
                         type: 'GET',
                         url: d.uri + '/descriptors',
                         data: {
-                            propertyName: propertyName
+                            propertyName: propertyName,
+                            sensitive: sensitive
                         },
                         dataType: 'json'
                     }).fail(nfErrorHandler.handleAjaxError);
@@ -1094,6 +1099,7 @@
                     // load the property table
                     $('#processor-properties')
                         .propertytable('setGroupId', processor.parentGroupId)
+                        
.propertytable('setSupportsSensitiveDynamicProperties', 
processor.supportsSensitiveDynamicProperties)
                         .propertytable('loadProperties', 
processor.config.properties, processor.config.descriptors, 
processorHistory.propertyHistory)
                         .propertytable('setPropertyVerificationCallback', 
function (proposedProperties) {
                             nfVerify.verify(processor['id'], 
processorResponse['uri'], proposedProperties, referencedAttributes, 
handleVerificationResults, 
$('#processor-properties-verification-results-listing'));
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
index 7b5c21b98a..853fc301ef 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
@@ -168,6 +168,7 @@
         if ($.isEmptyObject(properties) === false) {
             reportingTaskDto['properties'] = properties;
         }
+        reportingTaskDto['sensitiveDynamicPropertyNames'] = 
$('#reporting-task-properties').propertytable('getSensitiveDynamicPropertyNames');
 
         // create the reporting task entity
         var reportingTaskEntity = {};
@@ -313,14 +314,16 @@
      * Gets a property descriptor for the controller service currently being 
configured.
      *
      * @param {type} propertyName
+     * @param {type} sensitive Requested sensitive status
      */
-    var getReportingTaskPropertyDescriptor = function (propertyName) {
+    var getReportingTaskPropertyDescriptor = function (propertyName, 
sensitive) {
         var details = 
$('#reporting-task-configuration').data('reportingTaskDetails');
         return $.ajax({
             type: 'GET',
             url: details.uri + '/descriptors',
             data: {
-                propertyName: propertyName
+                propertyName: propertyName,
+                sensitive: sensitive
             },
             dataType: 'json'
         }).fail(nfErrorHandler.handleAjaxError);
@@ -643,6 +646,7 @@
                 // load the property table
                 $('#reporting-task-properties')
                     .propertytable('setGroupId', null)
+                    .propertytable('setSupportsSensitiveDynamicProperties', 
reportingTask.supportsSensitiveDynamicProperties)
                     .propertytable('loadProperties', reportingTask.properties, 
reportingTask.descriptors, reportingTaskHistory.propertyHistory)
                     .propertytable('setPropertyVerificationCallback', function 
(proposedProperties) {
                         nfVerify.verify(reportingTask['id'], 
reportingTaskEntity['uri'], proposedProperties, referencedAttributes, 
handleVerificationResults, 
$('#reporting-task-properties-verification-results-listing'));
@@ -767,6 +771,7 @@
                 // load the property table
                 $('#reporting-task-properties')
                     .propertytable('setGroupId', null)
+                    .propertytable('setSupportsSensitiveDynamicProperties', 
reportingTask.supportsSensitiveDynamicProperties)
                     .propertytable('loadProperties', reportingTask.properties, 
reportingTask.descriptors, reportingTaskHistory.propertyHistory);
 
                 // show the details
diff --git 
a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
 
b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
index f6a7c33c66..941200863f 100644
--- 
a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
+++ 
b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
@@ -20,6 +20,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.nifi.annotation.behavior.DynamicProperty;
 import org.apache.nifi.annotation.behavior.Restricted;
 import org.apache.nifi.annotation.behavior.Restriction;
+import org.apache.nifi.annotation.behavior.SupportsSensitiveDynamicProperties;
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
 import org.apache.nifi.annotation.documentation.Tags;
 import org.apache.nifi.annotation.lifecycle.OnScheduled;
@@ -54,6 +55,7 @@ import java.util.Map;
 /**
  * A Reporting task whose body is provided by a script (via supported JSR-223 
script engines)
  */
+@SupportsSensitiveDynamicProperties
 @Tags({"reporting", "script", "execute", "groovy", "python", "jython", 
"jruby", "ruby", "javascript", "js", "lua", "luaj"})
 @CapabilityDescription("Provides reporting and status information to a script. 
ReportingContext, ComponentLog, and VirtualMachineMetrics objects are made 
available "
         + "as variables (context, log, and vmMetrics, respectively) to the 
script for further processing. The context makes various information available 
such "
diff --git 
a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
 
b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
index 78f5c347c9..051d2cd1e5 100644
--- 
a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
+++ 
b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java
@@ -22,6 +22,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.apache.nifi.annotation.behavior.DynamicProperties;
 import org.apache.nifi.annotation.behavior.DynamicProperty;
 import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
+import org.apache.nifi.annotation.behavior.SupportsSensitiveDynamicProperties;
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
 import org.apache.nifi.annotation.documentation.Tags;
 import org.apache.nifi.annotation.lifecycle.OnDisabled;
@@ -70,6 +71,7 @@ import static 
org.apache.nifi.components.ConfigVerificationResult.Outcome.SUCCES
  * Implementation of for Database Connection Pooling Service. Apache DBCP is 
used for connection pooling functionality.
  *
  */
+@SupportsSensitiveDynamicProperties
 @Tags({ "dbcp", "jdbc", "database", "connection", "pooling", "store" })
 @CapabilityDescription("Provides Database Connection Pooling Service. 
Connections can be asked from pool and returned after usage.")
 @DynamicProperties({

Reply via email to