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 <matt.c.gilman@gmail.com>

This closes #6073
This commit is contained in:
exceptionfactory 2022-05-25 20:36:31 -05:00 committed by GitHub
parent f66540eb6d
commit 83316736f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 189 additions and 97 deletions

View File

@ -996,6 +996,12 @@ public abstract class AbstractComponentNode implements ComponentNode {
return foundApiDependency; return foundApiDependency;
} }
@Override
public boolean isSensitiveDynamicProperty(final String name) {
Objects.requireNonNull(name, "Property Name required");
return sensitiveDynamicPropertyNames.get().contains(name);
}
@Override @Override
public PropertyDescriptor getPropertyDescriptor(final String name) { public PropertyDescriptor getPropertyDescriptor(final String name) {
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(extensionManager, getComponent().getClass(), getComponent().getIdentifier())) { try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(extensionManager, getComponent().getClass(), getComponent().getIdentifier())) {

View File

@ -261,6 +261,11 @@ public interface ComponentNode extends ComponentAuthorizable {
*/ */
PropertyDescriptor getPropertyDescriptor(String name); PropertyDescriptor getPropertyDescriptor(String name);
/**
* @param name Property Name
* @return Sensitive Dynamic Property status
*/
boolean isSensitiveDynamicProperty(String name);
@Override @Override
default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) { default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {

View File

@ -616,9 +616,10 @@ public interface NiFiServiceFacade {
* *
* @param id id * @param id id
* @param property property * @param property property
* @param sensitive requested sensitive status
* @return descriptor * @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. * Gets all the Processor transfer objects for this controller.
@ -2046,9 +2047,10 @@ public interface NiFiServiceFacade {
* *
* @param id id * @param id id
* @param property property * @param property property
* @param sensitive requested sensitive status
* @return property * @return property
*/ */
PropertyDescriptorDTO getControllerServicePropertyDescriptor(String id, String property); PropertyDescriptorDTO getControllerServicePropertyDescriptor(String id, String property, boolean sensitive);
/** /**
* Gets the references for specified controller service. * Gets the references for specified controller service.
@ -2168,9 +2170,10 @@ public interface NiFiServiceFacade {
* *
* @param id id * @param id id
* @param property property * @param property property
* @param sensitive requested sensitive status
* @return descriptor * @return descriptor
*/ */
PropertyDescriptorDTO getReportingTaskPropertyDescriptor(String id, String property); PropertyDescriptorDTO getReportingTaskPropertyDescriptor(String id, String property, boolean sensitive);
/** /**
* Updates the specified reporting task. * Updates the specified reporting task.

View File

@ -3642,15 +3642,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @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); final ProcessorNode processor = processorDAO.getProcessor(id);
PropertyDescriptor descriptor = processor.getPropertyDescriptor(property); final PropertyDescriptor descriptor = getPropertyDescriptor(processor, property, sensitive);
// 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();
}
return dtoFactory.createPropertyDescriptorDto(descriptor, processor.getProcessGroup().getIdentifier()); return dtoFactory.createPropertyDescriptorDto(descriptor, processor.getProcessGroup().getIdentifier());
} }
@ -4511,15 +4505,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @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); final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(id);
PropertyDescriptor descriptor = controllerService.getPropertyDescriptor(property); final PropertyDescriptor descriptor = getPropertyDescriptor(controllerService, property, sensitive);
// 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 String groupId = controllerService.getProcessGroup() == null ? null : controllerService.getProcessGroup().getIdentifier(); final String groupId = controllerService.getProcessGroup() == null ? null : controllerService.getProcessGroup().getIdentifier();
return dtoFactory.createPropertyDescriptorDto(descriptor, groupId); return dtoFactory.createPropertyDescriptorDto(descriptor, groupId);
} }
@ -4555,15 +4543,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @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); final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(id);
PropertyDescriptor descriptor = reportingTask.getPropertyDescriptor(property); final PropertyDescriptor descriptor = getPropertyDescriptor(reportingTask, property, sensitive);
// 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();
}
return dtoFactory.createPropertyDescriptorDto(descriptor, null); 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 @Override
public void verifyPublicInputPortUniqueness(final String portId, final String portName) { public void verifyPublicInputPortUniqueness(final String portId, final String portName) {
inputPortDAO.verifyPublicPortUniqueness(portId, portName); inputPortDAO.verifyPublicPortUniqueness(portId, portName);

View File

@ -281,12 +281,7 @@ public class ControllerServiceResource extends ApplicationResource {
}); });
// get the property descriptor // get the property descriptor
final PropertyDescriptorDTO descriptor = serviceFacade.getControllerServicePropertyDescriptor(id, propertyName); final PropertyDescriptorDTO descriptor = serviceFacade.getControllerServicePropertyDescriptor(id, propertyName, sensitive);
// Adjust sensitive status for dynamic properties when sensitive status enabled
if (descriptor.isDynamic() && sensitive) {
descriptor.setSensitive(true);
}
// generate the response entity // generate the response entity
final PropertyDescriptorEntity entity = new PropertyDescriptorEntity(); final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();

View File

@ -427,12 +427,7 @@ public class ProcessorResource extends ApplicationResource {
}); });
// get the property descriptor // get the property descriptor
final PropertyDescriptorDTO descriptor = serviceFacade.getProcessorPropertyDescriptor(id, propertyName); final PropertyDescriptorDTO descriptor = serviceFacade.getProcessorPropertyDescriptor(id, propertyName, sensitive);
// Adjust sensitive status for dynamic properties when sensitive status enabled
if (descriptor.isDynamic() && sensitive) {
descriptor.setSensitive(true);
}
// generate the response entity // generate the response entity
final PropertyDescriptorEntity entity = new PropertyDescriptorEntity(); final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();

View File

@ -267,12 +267,7 @@ public class ReportingTaskResource extends ApplicationResource {
}); });
// get the property descriptor // get the property descriptor
final PropertyDescriptorDTO descriptor = serviceFacade.getReportingTaskPropertyDescriptor(id, propertyName); final PropertyDescriptorDTO descriptor = serviceFacade.getReportingTaskPropertyDescriptor(id, propertyName, sensitive);
// Adjust sensitive status for dynamic properties when sensitive status enabled
if (descriptor.isDynamic() && sensitive) {
descriptor.setSensitive(true);
}
// generate the response entity // generate the response entity
final PropertyDescriptorEntity entity = new PropertyDescriptorEntity(); final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();

View File

@ -108,4 +108,4 @@
bottom: 0; bottom: 0;
width: 100%; width: 100%;
height: 32px; height: 32px;
} }

View File

@ -105,6 +105,7 @@
_) { _) {
var groupId = null; var groupId = null;
var supportsSensitiveDynamicProperties = false;
var propertyVerificationCallback = null; var propertyVerificationCallback = null;
var COMBO_MIN_WIDTH = 212; var COMBO_MIN_WIDTH = 212;
var EDITOR_MIN_WIDTH = 212; var EDITOR_MIN_WIDTH = 212;
@ -1211,7 +1212,8 @@
contentType: 'application/json' contentType: 'application/json'
}).done(function (response) { }).done(function (response) {
// load the descriptor and update the property // 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; var descriptor = descriptorResponse.propertyDescriptor;
// store the descriptor for use later // store the descriptor for use later
@ -1600,6 +1602,10 @@
hidden: true hidden: true
})); }));
// Delete property descriptor
var descriptors = table.data('descriptors');
delete descriptors[property.property];
// prevents standard edit logic // prevents standard edit logic
e.stopImmediatePropagation(); e.stopImmediatePropagation();
} else if (target.hasClass('go-to-service')) { } else if (target.hasClass('go-to-service')) {
@ -1829,6 +1835,17 @@
return properties; 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. * Performs the filtering.
* *
@ -2028,21 +2045,35 @@
var newPropertyDialogMarkup = var newPropertyDialogMarkup =
'<div id="new-property-dialog" class="dialog cancellable small-dialog hidden">' + '<div id="new-property-dialog" class="dialog cancellable small-dialog hidden">' +
'<div class="dialog-content">' + '<div class="dialog-content">' +
'<div>' + '<div class="setting">' +
'<div class="setting-name">Property name</div>' + '<div class="setting-name">Property name</div>' +
'<div class="setting-field new-property-name-container">' + '<div class="setting-field new-property-name-container">' +
'<input class="new-property-name" type="text"/>' + '<input class="new-property-name" type="text"/>' +
'</div>' + '</div>' +
'</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>' +
'</div>'; '</div>';
var newPropertyDialog = $(newPropertyDialogMarkup).appendTo(options.dialogContainer); var newPropertyDialog = $(newPropertyDialogMarkup).appendTo(options.dialogContainer);
var newPropertyNameField = newPropertyDialog.find('input.new-property-name'); 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({ newPropertyDialog.modal({
headerText: 'Add Property', headerText: 'Add Property',
scrollableContentStyle: 'scrollable',
buttons: [{ buttons: [{
buttonText: 'Ok', buttonText: 'Ok',
color: { color: {
@ -2088,9 +2119,10 @@
} }
}); });
if (existingItem === null) { if (existingItem === null || existingItem.hidden === true) {
// load the descriptor and add the property // load the descriptor with requested sensitive status
options.descriptorDeferred(propertyName).done(function (response) { var sensitive = valueSensitiveField.prop('checked');
options.descriptorDeferred(propertyName, sensitive).done(function (response) {
var descriptor = response.propertyDescriptor; var descriptor = response.propertyDescriptor;
// store the descriptor for use later // store the descriptor for use later
@ -2099,47 +2131,49 @@
descriptors[descriptor.name] = descriptor; descriptors[descriptor.name] = descriptor;
} }
// add a row for the new property // add the property when existing item not found
var id = propertyData.getItems().length; if (existingItem === null) {
propertyData.addItem({ // add a row for the new property
id: id, var id = propertyData.getItems().length;
hidden: false, propertyData.addItem({
property: propertyName, id: id,
displayName: propertyName, hidden: false,
previousValue: null, property: propertyName,
value: null, displayName: propertyName,
type: 'userDefined' previousValue: null,
}); value: null,
type: 'userDefined'
});
// select the new properties row // select the new properties row
var row = propertyData.getRowById(id); var row = propertyData.getRowById(id);
propertyGrid.setActiveCell(row, propertyGrid.getColumnIndex('value')); propertyGrid.setActiveCell(row, propertyGrid.getColumnIndex('value'));
propertyGrid.editActiveCell(); 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 { } else {
// if this row is currently hidden, clear the value and show it nfDialog.showOkDialog({
if (existingItem.hidden === true) { headerText: 'Property Exists',
propertyData.updateItem(existingItem.id, $.extend(existingItem, { dialogContent: 'A property with this name already exists.'
hidden: false, });
previousValue: null, // select the existing properties row
value: null var row = propertyData.getRowById(existingItem.id);
})); propertyGrid.setSelectedRows([row]);
propertyGrid.scrollRowIntoView(row);
// 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);
}
} }
} else { } else {
nfDialog.showOkDialog({ nfDialog.showOkDialog({
@ -2184,6 +2218,15 @@
// set the initial focus // set the initial focus
newPropertyNameField.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); }).appendTo(addProperty);
// build the control to trigger verification // build the control to trigger verification
@ -2333,6 +2376,22 @@
return properties; 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 * Sets the current group id. This is used to indicate where inline Controller Services are created
* and to obtain the parameter context. * 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. * Sets the property verification callback.
*/ */

View File

@ -120,6 +120,7 @@
if ($.isEmptyObject(properties) === false) { if ($.isEmptyObject(properties) === false) {
controllerServiceDto['properties'] = properties; controllerServiceDto['properties'] = properties;
} }
controllerServiceDto['sensitiveDynamicPropertyNames'] = $('#controller-service-properties').propertytable('getSensitiveDynamicPropertyNames');
// create the controller service entity // create the controller service entity
var controllerServiceEntity = {}; var controllerServiceEntity = {};
@ -1518,14 +1519,16 @@
* Gets a property descriptor for the controller service currently being configured. * Gets a property descriptor for the controller service currently being configured.
* *
* @param {type} propertyName * @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'); var controllerServiceEntity = $('#controller-service-configuration').data('controllerServiceDetails');
return $.ajax({ return $.ajax({
type: 'GET', type: 'GET',
url: controllerServiceEntity.uri + '/descriptors', url: controllerServiceEntity.uri + '/descriptors',
data: { data: {
propertyName: propertyName propertyName: propertyName,
sensitive: sensitive
}, },
dataType: 'json' dataType: 'json'
}).fail(nfErrorHandler.handleAjaxError); }).fail(nfErrorHandler.handleAjaxError);
@ -2113,6 +2116,7 @@
// load the property table // load the property table
$('#controller-service-properties') $('#controller-service-properties')
.propertytable('setGroupId', controllerService.parentGroupId) .propertytable('setGroupId', controllerService.parentGroupId)
.propertytable('setSupportsSensitiveDynamicProperties', controllerService.supportsSensitiveDynamicProperties)
.propertytable('loadProperties', controllerService.properties, controllerService.descriptors, controllerServiceHistory.propertyHistory) .propertytable('loadProperties', controllerService.properties, controllerService.descriptors, controllerServiceHistory.propertyHistory)
.propertytable('setPropertyVerificationCallback', function (proposedProperties) { .propertytable('setPropertyVerificationCallback', function (proposedProperties) {
nfVerify.verify(controllerService['id'], controllerServiceEntity['uri'], proposedProperties, referencedAttributes, handleVerificationResults, $('#controller-service-properties-verification-results-listing')); nfVerify.verify(controllerService['id'], controllerServiceEntity['uri'], proposedProperties, referencedAttributes, handleVerificationResults, $('#controller-service-properties-verification-results-listing'));
@ -2257,6 +2261,7 @@
// load the property table // load the property table
$('#controller-service-properties') $('#controller-service-properties')
.propertytable('setGroupId', controllerService.parentGroupId) .propertytable('setGroupId', controllerService.parentGroupId)
.propertytable('setSupportsSensitiveDynamicProperties', controllerService.supportsSensitiveDynamicProperties)
.propertytable('loadProperties', controllerService.properties, controllerService.descriptors, controllerServiceHistory.propertyHistory); .propertytable('loadProperties', controllerService.properties, controllerService.descriptors, controllerServiceHistory.propertyHistory);
// show the details // show the details

View File

@ -387,6 +387,10 @@
processorConfigDto['properties'] = properties; processorConfigDto['properties'] = properties;
} }
if (processor.supportsSensitiveDynamicProperties === true) {
processorConfigDto['sensitiveDynamicPropertyNames'] = $('#processor-properties').propertytable('getSensitiveDynamicPropertyNames');
}
// create the processor dto // create the processor dto
var processorDto = {}; var processorDto = {};
processorDto['id'] = $('#processor-id').text(); processorDto['id'] = $('#processor-id').text();
@ -697,14 +701,15 @@
readOnly: false, readOnly: false,
supportsGoTo: true, supportsGoTo: true,
dialogContainer: '#new-processor-property-container', dialogContainer: '#new-processor-property-container',
descriptorDeferred: function (propertyName) { descriptorDeferred: function (propertyName, sensitive) {
var processor = $('#processor-configuration').data('processorDetails'); var processor = $('#processor-configuration').data('processorDetails');
var d = nfProcessor.get(processor.id); var d = nfProcessor.get(processor.id);
return $.ajax({ return $.ajax({
type: 'GET', type: 'GET',
url: d.uri + '/descriptors', url: d.uri + '/descriptors',
data: { data: {
propertyName: propertyName propertyName: propertyName,
sensitive: sensitive
}, },
dataType: 'json' dataType: 'json'
}).fail(nfErrorHandler.handleAjaxError); }).fail(nfErrorHandler.handleAjaxError);
@ -1094,6 +1099,7 @@
// load the property table // load the property table
$('#processor-properties') $('#processor-properties')
.propertytable('setGroupId', processor.parentGroupId) .propertytable('setGroupId', processor.parentGroupId)
.propertytable('setSupportsSensitiveDynamicProperties', processor.supportsSensitiveDynamicProperties)
.propertytable('loadProperties', processor.config.properties, processor.config.descriptors, processorHistory.propertyHistory) .propertytable('loadProperties', processor.config.properties, processor.config.descriptors, processorHistory.propertyHistory)
.propertytable('setPropertyVerificationCallback', function (proposedProperties) { .propertytable('setPropertyVerificationCallback', function (proposedProperties) {
nfVerify.verify(processor['id'], processorResponse['uri'], proposedProperties, referencedAttributes, handleVerificationResults, $('#processor-properties-verification-results-listing')); nfVerify.verify(processor['id'], processorResponse['uri'], proposedProperties, referencedAttributes, handleVerificationResults, $('#processor-properties-verification-results-listing'));

View File

@ -168,6 +168,7 @@
if ($.isEmptyObject(properties) === false) { if ($.isEmptyObject(properties) === false) {
reportingTaskDto['properties'] = properties; reportingTaskDto['properties'] = properties;
} }
reportingTaskDto['sensitiveDynamicPropertyNames'] = $('#reporting-task-properties').propertytable('getSensitiveDynamicPropertyNames');
// create the reporting task entity // create the reporting task entity
var reportingTaskEntity = {}; var reportingTaskEntity = {};
@ -313,14 +314,16 @@
* Gets a property descriptor for the controller service currently being configured. * Gets a property descriptor for the controller service currently being configured.
* *
* @param {type} propertyName * @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'); var details = $('#reporting-task-configuration').data('reportingTaskDetails');
return $.ajax({ return $.ajax({
type: 'GET', type: 'GET',
url: details.uri + '/descriptors', url: details.uri + '/descriptors',
data: { data: {
propertyName: propertyName propertyName: propertyName,
sensitive: sensitive
}, },
dataType: 'json' dataType: 'json'
}).fail(nfErrorHandler.handleAjaxError); }).fail(nfErrorHandler.handleAjaxError);
@ -643,6 +646,7 @@
// load the property table // load the property table
$('#reporting-task-properties') $('#reporting-task-properties')
.propertytable('setGroupId', null) .propertytable('setGroupId', null)
.propertytable('setSupportsSensitiveDynamicProperties', reportingTask.supportsSensitiveDynamicProperties)
.propertytable('loadProperties', reportingTask.properties, reportingTask.descriptors, reportingTaskHistory.propertyHistory) .propertytable('loadProperties', reportingTask.properties, reportingTask.descriptors, reportingTaskHistory.propertyHistory)
.propertytable('setPropertyVerificationCallback', function (proposedProperties) { .propertytable('setPropertyVerificationCallback', function (proposedProperties) {
nfVerify.verify(reportingTask['id'], reportingTaskEntity['uri'], proposedProperties, referencedAttributes, handleVerificationResults, $('#reporting-task-properties-verification-results-listing')); nfVerify.verify(reportingTask['id'], reportingTaskEntity['uri'], proposedProperties, referencedAttributes, handleVerificationResults, $('#reporting-task-properties-verification-results-listing'));
@ -767,6 +771,7 @@
// load the property table // load the property table
$('#reporting-task-properties') $('#reporting-task-properties')
.propertytable('setGroupId', null) .propertytable('setGroupId', null)
.propertytable('setSupportsSensitiveDynamicProperties', reportingTask.supportsSensitiveDynamicProperties)
.propertytable('loadProperties', reportingTask.properties, reportingTask.descriptors, reportingTaskHistory.propertyHistory); .propertytable('loadProperties', reportingTask.properties, reportingTask.descriptors, reportingTaskHistory.propertyHistory);
// show the details // show the details

View File

@ -20,6 +20,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.nifi.annotation.behavior.DynamicProperty; import org.apache.nifi.annotation.behavior.DynamicProperty;
import org.apache.nifi.annotation.behavior.Restricted; import org.apache.nifi.annotation.behavior.Restricted;
import org.apache.nifi.annotation.behavior.Restriction; 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.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags; import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.lifecycle.OnScheduled; 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) * 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"}) @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 " @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 " + "as variables (context, log, and vmMetrics, respectively) to the script for further processing. The context makes various information available such "

View File

@ -22,6 +22,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.nifi.annotation.behavior.DynamicProperties; import org.apache.nifi.annotation.behavior.DynamicProperties;
import org.apache.nifi.annotation.behavior.DynamicProperty; import org.apache.nifi.annotation.behavior.DynamicProperty;
import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading; 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.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags; import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.lifecycle.OnDisabled; 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. * Implementation of for Database Connection Pooling Service. Apache DBCP is used for connection pooling functionality.
* *
*/ */
@SupportsSensitiveDynamicProperties
@Tags({ "dbcp", "jdbc", "database", "connection", "pooling", "store" }) @Tags({ "dbcp", "jdbc", "database", "connection", "pooling", "store" })
@CapabilityDescription("Provides Database Connection Pooling Service. Connections can be asked from pool and returned after usage.") @CapabilityDescription("Provides Database Connection Pooling Service. Connections can be asked from pool and returned after usage.")
@DynamicProperties({ @DynamicProperties({