From ae53130293f565099b4be5cb6841378ac249863e Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Tue, 7 Sep 2021 16:51:08 -0400 Subject: [PATCH 01/13] NIFI-8491: - Adding support for configuring parameter context inheritance. --- .../canvas/new-parameter-context-dialog.jsp | 29 ++- .../css/new-parameter-context-dialog.css | 65 +++++- .../js/nf/canvas/nf-parameter-contexts.js | 215 +++++++++++++++++- 3 files changed, 304 insertions(+), 5 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp index d1e10a5d9214..090cbf54cbaa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp @@ -20,7 +20,7 @@
-
+
-
+
@@ -96,6 +96,31 @@
+
+
+
+
+ Available Parameter Contexts +
+
+
+
    +
    +
    +
    +
     
    +
    +
    +
    + Selected Parameter Context +
    +
    +
    +
      +
      +
      +
      +
      diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css index d24281dc7631..f5b7f92f0089 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css @@ -32,12 +32,12 @@ display: none; } -#parameter-context-dialog div.settings-left { +.parameter-context-tabs-content.split-65-35 div.settings-left { float: left; width: 65%; } -#parameter-context-dialog div.settings-right { +.parameter-context-tabs-content.split-65-35 div.settings-right { float: left; width: 33%; height: 100%; @@ -134,3 +134,64 @@ span.parameter-context-referencing-component-name { white-space: nowrap; margin-left: 6px; } + +/* inheritance */ + +#parameter-context-available, #parameter-context-selected { + list-style-type: none; + margin: 0px; + background: #eaeef0; + min-height: 32px; + margin-bottom: 5px; + padding: 2px; +} + +#parameter-context-available li, #parameter-context-selected li { + margin: 2px; + padding: 5px; + cursor: pointer; + font-size: 1em; + height: 12px; + overflow: hidden; +} + +#parameter-context-available li.unauthorized, #parameter-context-selected li.unauthorized { + color: #a8a8a8; + cursor: not-allowed; +} + +#parameter-context-available li { + background: #fff; + border-top: 1px solid #CCDADB; + border-right: 1px solid #CCDADB; + border-bottom: 1px solid #CCDADB; + border-left: 1px solid #CCDADB; + color: #004849; + font-weight: 500; + cursor: grab; + line-height: 32px; + height: 32px; + padding: 0px 10px; + box-shadow:0 1px 1px rgba(0,0,0,0.4); +} + +#parameter-context-selected li { + background: #355B6A; + border-top: 1px solid #AAC1CE; + border-right: 1px solid #85A6B8; + border-bottom: 1px solid #618BA3; + border-left: 1px solid #85A6B8; + color: #fff; + font-weight: bold; + line-height: 32px; + height: 32px; + padding: 0px 10px; +} + +#parameter-context-selected .draggable-control { + float: right; +} + +#parameter-context-selected .fa-remove, #parameter-context-selected .fa-question-circle { + color: #fff; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js index d8d3a5966062..7c2f5cd143eb 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js @@ -219,6 +219,7 @@ parameterData.setItems([]); resetUsage(); + resetInheritance(); // reset the last selected parameter lastSelectedId = null; @@ -300,6 +301,31 @@ return parameters; }; + /** + * Marshals the inherited parameter contexts. + */ + var marshalInheritedParameterContexts = function () { + if ($('#parameter-context-selected').hasClass('contains-unauthorized')) { + return null; + } else { + var parameterContextsGrid = $('#parameter-contexts-table').data('gridInstance'); + var parameterContextsData = parameterContextsGrid.getData(); + + var inheritedParameterContextIds = $('#parameter-context-selected').sortable('toArray'); + + return inheritedParameterContextIds.map(function (id) { + var parameterContext = parameterContextsData.getItemById(id); + return { + id: parameterContext.id, + component: { + id: parameterContext.component.id, + name: parameterContext.component.name + } + } + }); + } + }; + /** * Handles outstanding changes. * @@ -1085,6 +1111,7 @@ if (parameters.length === 0) { // nothing to update parameterContextEntity.component.parameters = []; + if ($('#parameter-context-name').val() === parameterContextEntity.component.name && $('#parameter-context-description-field').val() === parameterContextEntity.component.description) { close(); @@ -1095,6 +1122,12 @@ parameterContextEntity.component.parameters = parameters; } + // include the inherited parameter contexts + var inheritedParameterContexts = marshalInheritedParameterContexts(); + if (!nfCommon.isNull(inheritedParameterContexts)) { + parameterContextEntity.component.inheritedParameterContexts = inheritedParameterContexts; + } + parameterContextEntity.component.name = $('#parameter-context-name').val(); parameterContextEntity.component.description = $('#parameter-context-description-field').val(); @@ -1530,6 +1563,50 @@ } }; + /** + * Load the parameter context inheritance tab for the current parameterContextEntity. The current parameterContextEntity could be + * null if this is a new parameter context. + * + * @param parameterContextEntity the parameter context being edited or null if new + * @param readOnly whether the controls should be read only + */ + var loadParameterContextInheritance = function (parameterContextEntity, readOnly) { + var parameterContextsGrid = $('#parameter-contexts-table').data('gridInstance'); + var parameterContextsData = parameterContextsGrid.getData(); + var parameterContexts = parameterContextsData.getItems(); + + // determine if the specified parameter context contains any selected inherited parameter contexts the current user does not have permissions to + var hasSelectedUnauthorized = nfCommon.isNull(parameterContextEntity) ? false : parameterContextEntity.component.inheritedParameterContexts.some((selectedParameterContext) => { + return !selectedParameterContext.permissions.canRead; + }); + + // consider each parameter context and add to the listing of available or selected contexts based on the supplied parameterContextEntity + $.each(parameterContexts, function (i, availableParameterContext) { + // don't support inheriting from the current context + var isCurrent = nfCommon.isNull(parameterContextEntity) ? false : availableParameterContext.id === parameterContextEntity.id; + + // determine if this available parameter context is already selected + var isSelected = nfCommon.isNull(parameterContextEntity) ? false : parameterContextEntity.component.inheritedParameterContexts.some((selectedParameterContext) => { + return availableParameterContext.id === selectedParameterContext.id; + }); + + if (isSelected) { + addParameterContextInheritanceControl('#parameter-context-selected', availableParameterContext, true); + } else if (!isCurrent) { + addParameterContextInheritanceControl('#parameter-context-available', availableParameterContext, false); + } + }); + + sortAvailableParameterContexts(); + + if (readOnly || hasSelectedUnauthorized) { + $('#parameter-context-available, #parameter-context-selected').sortable('disable').sortable('refresh'); + $('#parameter-context-selected').addClass('contains-unauthorized'); + } else { + $('#parameter-context-available, #parameter-context-selected').sortable('enable').sortable('refresh'); + } + }; + var resetUsage = function () { // empty the containers var processorContainer = $('.parameter-context-referencing-processors'); @@ -1561,6 +1638,94 @@ updateReferencingComponentsBorder($('#parameter-referencing-components-container')); }; + /** + * Reset the inheritance tab. + */ + var resetInheritance = function () { + $('#parameter-context-available').empty(); + $('#parameter-context-selected').removeClass('contains-unauthorized').empty(); + }; + + /** + * Sorts the available parameter contexts. + */ + var sortAvailableParameterContexts = function () { + var availableParameterContextList = $('#parameter-context-available'); + availableParameterContextList.children('li') + .detach() + .sort(function (a, b) { + var a = $(a); + var b = $(b); + + // put unauthorized last + if (a.hasClass('unauthorized') && b.hasClass('unauthorized')) { + return 0; + } else if (a.hasClass('unauthorized')) { + return 1; + } else if (b.hasClass('unauthorized')) { + return -1; + } + + var nameA = a.text(); + var nameB = b.text(); + return nameA.localeCompare(nameB); + }) + .appendTo(availableParameterContextList); + }; + + /** + * Adds the specified parameter context to the list of available parameter contexts. + * + * @argument {jQuery} container The container for the parameter context + * @argument {object} parameterContext An available parameter context + * @argument {boolean} isSelected Whether the parameter context is selected (which is used to decide whether to provide a remove control) + */ + var addParameterContextInheritanceControl = function (container, parameterContext, isSelected) { + var label = parameterContext.id; + if (parameterContext.permissions.canRead) { + label = parameterContext.component.name; + } + + // add the parameter context to the specified list + var parameterContextElement = $('
    1. ').append($('').text(label)).attr('id', parameterContext.id).addClass('ui-state-default'); + if (!parameterContext.permissions.canRead) { + parameterContextElement.addClass('unauthorized'); + } else { + // add the description if applicable + if (!nfCommon.isBlank(parameterContext.component.description)) { + $('
      ').appendTo(parameterContextElement).qtip($.extend({ + content: nfCommon.escapeHtml(parameterContext.component.description) + }, nfCommon.config.tooltipConfig)); + } + + addDraggableControls(parameterContextElement, isSelected); + } + parameterContextElement.appendTo(container); + }; + + /** + * Adds the controls to the specified draggable element. + * + * @argument {jQuery} draggableElement + * @argument {boolean} isSelected + */ + var addDraggableControls = function (draggableElement, isSelected) { + if (isSelected) { + var removeIcon = $('
      ') + .on('click', function () { + // remove the remove ice + removeIcon.remove(); + + // restore to the available parameter contexts + $('#parameter-context-available').append(draggableElement); + + // resort the available parameter contexts + sortAvailableParameterContexts(); + }) + .appendTo(draggableElement); + } + } + /** * Performs the filtering. * @@ -1914,6 +2079,9 @@ }, { name: 'Parameters', tabContentId: 'parameter-context-parameters-tab-content' + }, { + name: 'Inheritance', + tabContentId: 'parameter-context-inheritance-tab-content' }], select: function () { // update the parameters table size in case this is the first time its rendered @@ -2382,6 +2550,7 @@ // create a new parameter context $('#new-parameter-context').on('click', function () { resetUsage(); + resetInheritance(); // new parameter contexts do not have an ID to show if (!$('#parameter-context-id-setting').hasClass('hidden')) { @@ -2424,10 +2593,47 @@ } }]).modal('show'); + loadParameterContextInheritance(null, false); + // set the initial focus $('#parameter-context-name').focus(); }); + // work around for https://bugs.jqueryui.com/ticket/6054 + let shouldAllowDrop = true; + + // make the parameter context containers sortable + $('#parameter-context-available').sortable({ + containment: $('#parameter-context-inheritance-tab-content'), + cancel: '.unauthorized', + connectWith: '#parameter-context-selected', + placeholder: 'available', + scroll: true, + opacity: 0.6, + beforeStop: function (event, ui) { + if ($('#parameter-context-available').find('.ui-sortable-placeholder').length) { + shouldAllowDrop = false; + } + }, + stop: function (event, ui) { + const allowDrop = shouldAllowDrop; + shouldAllowDrop = true; + return allowDrop; + } + }); + $('#parameter-context-selected').sortable({ + containment: $('#parameter-context-inheritance-tab-content'), + cancel: '.unauthorized', + placeholder: 'selected', + scroll: true, + opacity: 0.6, + receive: function (event, ui) { + addDraggableControls(ui.item, true); + console.log(ui); + } + }); + $('#parameter-context-available, #parameter-context-selected').disableSelection(); + // initialize the new parameter context dialog initNewParameterContextDialog(); @@ -2437,7 +2643,7 @@ if ($('#parameter-referencing-components-container').is(':visible')) { updateReferencingComponentsBorder($('#parameter-referencing-components-container')); } - }) + }); }, /** @@ -2460,6 +2666,11 @@ }) }; + var inheritedParameterContexts = marshalInheritedParameterContexts(); + if (!nfCommon.isNull(inheritedParameterContexts)) { + parameterContextEntity.component.inheritedParameterContexts = inheritedParameterContexts; + } + var addContext = $.ajax({ type: 'POST', url: config.urls.parameterContexts, @@ -2579,6 +2790,8 @@ loadParameters(parameterContextEntity, parameterToSelect, readOnly || !canWrite); + loadParameterContextInheritance(parameterContextEntity, readOnly || !canWrite); + var editModeButtonModel = [{ buttonText: 'Apply', color: { From 1ca73dde272b97638869d07674fd3ab89845a70f Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Wed, 8 Sep 2021 17:02:05 -0400 Subject: [PATCH 02/13] NIFI-8491: - Allowing changes to the parameter context inheritance to drive Apply disabled state. --- .../main/webapp/js/nf/canvas/nf-parameter-contexts.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js index 7c2f5cd143eb..785b8ef2e7e6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js @@ -1088,10 +1088,12 @@ var parameters = marshalParameters(); var proposedParamContextName = $('#parameter-context-name').val(); var proposedParamContextDesc = $('#parameter-context-description-field').val(); + var inheritedParameterContexts = marshalInheritedParameterContexts(); if (_.isEmpty(parameters) && proposedParamContextName === _.get(parameterContextEntity, 'component.name') && - proposedParamContextDesc === _.get(parameterContextEntity, 'component.description')) { + proposedParamContextDesc === _.get(parameterContextEntity, 'component.description') && + _.isEqual(_.get(parameterContextEntity, 'component.inheritedParameterContexts'), inheritedParameterContexts)) { return false; } else { @@ -1721,6 +1723,9 @@ // resort the available parameter contexts sortAvailableParameterContexts(); + + // update the buttons to possibly trigger the disabled state + $('#parameter-context-dialog').modal('refreshButtons'); }) .appendTo(draggableElement); } @@ -2629,7 +2634,9 @@ opacity: 0.6, receive: function (event, ui) { addDraggableControls(ui.item, true); - console.log(ui); + + // update the buttons to possibly trigger the disabled state + $('#parameter-context-dialog').modal('refreshButtons'); } }); $('#parameter-context-available, #parameter-context-selected').disableSelection(); From 5ba4610a08ab60a3f851fca831c1df41de484061 Mon Sep 17 00:00:00 2001 From: Joe Gresock Date: Wed, 8 Sep 2021 15:06:24 -0400 Subject: [PATCH 03/13] NIFI-8491: Updating StandardParameterContext#isAuthorized check --- .../nifi/parameter/StandardParameterContext.java | 16 ++++++++++++++++ .../apache/nifi/web/api/dto/EntityFactory.java | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java index e311770e8d7a..7bc09b12a8bf 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java @@ -678,6 +678,22 @@ public void authorize(final Authorizer authorizer, final RequestAction action, f } } + @Override + public boolean isAuthorized(final Authorizer authorizer, final RequestAction action, final NiFiUser user) { + boolean isAuthorized = ParameterContext.super.isAuthorized(authorizer, action, user); + + if (RequestAction.READ == action) { + for (final ParameterContext parameterContext : inheritedParameterContexts) { + isAuthorized &= parameterContext.isAuthorized(authorizer, action, user); + if (!isAuthorized) { + break; + } + } + } + + return isAuthorized; + } + @Override public Authorizable getParentAuthorizable() { return new Authorizable() { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java index 1d6d8bbba89c..9d5ad9eb21d9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java @@ -575,7 +575,7 @@ public ParameterContextEntity createParameterContextEntity(final ParameterContex final ParameterContextEntity entity = new ParameterContextEntity(); entity.setRevision(revision); if (dto != null) { - entity.setPermissions(permissions);; + entity.setPermissions(permissions); entity.setId(dto.getId()); if (permissions != null && permissions.getCanRead()) { From f1c9c4bc6b90d1593749ef83cb636a9564864732 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Fri, 10 Sep 2021 15:03:33 -0400 Subject: [PATCH 04/13] NIFI-8491: - Showing selected inherited parameter contexts in ready only form when appropriate. - Allowing available parameter contexts to be inherited by double clicking. - Removing support for rendering unauthorized inherited parameter contexts as they can no longer be opened. --- .../canvas/new-parameter-context-dialog.jsp | 47 ++++--- .../css/new-parameter-context-dialog.css | 4 + .../js/nf/canvas/nf-parameter-contexts.js | 131 ++++++++++-------- 3 files changed, 105 insertions(+), 77 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp index 090cbf54cbaa..63206c73d531 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp @@ -97,26 +97,41 @@
      -
      -
      -
      - Available Parameter Contexts -
      +
      +
      +
      +
      + Available Parameter Contexts +
      +
      +
      +
        +
        -
        -
          +
          +
           
          +
          +
          +
          + Selected Parameter Context +
          +
          +
          +
            +
            -
             
            -
            -
            -
            - Selected Parameter Context -
            -
            -
            -
              + diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css index f5b7f92f0089..24ecdf8e1846 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-parameter-context-dialog.css @@ -195,3 +195,7 @@ span.parameter-context-referencing-component-name { #parameter-context-selected .fa-remove, #parameter-context-selected .fa-question-circle { color: #fff; } + +#parameter-context-selected-read-only { + list-style: inside none decimal; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js index 785b8ef2e7e6..3863d153eb68 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js @@ -305,25 +305,21 @@ * Marshals the inherited parameter contexts. */ var marshalInheritedParameterContexts = function () { - if ($('#parameter-context-selected').hasClass('contains-unauthorized')) { - return null; - } else { - var parameterContextsGrid = $('#parameter-contexts-table').data('gridInstance'); - var parameterContextsData = parameterContextsGrid.getData(); + var parameterContextsGrid = $('#parameter-contexts-table').data('gridInstance'); + var parameterContextsData = parameterContextsGrid.getData(); - var inheritedParameterContextIds = $('#parameter-context-selected').sortable('toArray'); + var inheritedParameterContextIds = $('#parameter-context-selected').sortable('toArray'); - return inheritedParameterContextIds.map(function (id) { - var parameterContext = parameterContextsData.getItemById(id); - return { - id: parameterContext.id, - component: { - id: parameterContext.component.id, - name: parameterContext.component.name - } + return inheritedParameterContextIds.map(function (id) { + var parameterContext = parameterContextsData.getItemById(id); + return { + id: parameterContext.id, + component: { + id: parameterContext.component.id, + name: parameterContext.component.name } - }); - } + } + }); }; /** @@ -1109,13 +1105,15 @@ */ var updateParameterContext = function (parameterContextEntity) { var parameters = marshalParameters(); + var inheritedParameterContexts = marshalInheritedParameterContexts(); if (parameters.length === 0) { // nothing to update parameterContextEntity.component.parameters = []; - if ($('#parameter-context-name').val() === parameterContextEntity.component.name && - $('#parameter-context-description-field').val() === parameterContextEntity.component.description) { + if ($('#parameter-context-name').val() === _.get(parameterContextEntity, 'component.name') && + $('#parameter-context-description-field').val() === _.get(parameterContextEntity, 'component.description') && + _.isEqual(_.get(parameterContextEntity, 'component.inheritedParameterContexts'), inheritedParameterContexts)) { close(); return; @@ -1125,10 +1123,7 @@ } // include the inherited parameter contexts - var inheritedParameterContexts = marshalInheritedParameterContexts(); - if (!nfCommon.isNull(inheritedParameterContexts)) { - parameterContextEntity.component.inheritedParameterContexts = inheritedParameterContexts; - } + parameterContextEntity.component.inheritedParameterContexts = inheritedParameterContexts; parameterContextEntity.component.name = $('#parameter-context-name').val(); parameterContextEntity.component.description = $('#parameter-context-description-field').val(); @@ -1577,11 +1572,6 @@ var parameterContextsData = parameterContextsGrid.getData(); var parameterContexts = parameterContextsData.getItems(); - // determine if the specified parameter context contains any selected inherited parameter contexts the current user does not have permissions to - var hasSelectedUnauthorized = nfCommon.isNull(parameterContextEntity) ? false : parameterContextEntity.component.inheritedParameterContexts.some((selectedParameterContext) => { - return !selectedParameterContext.permissions.canRead; - }); - // consider each parameter context and add to the listing of available or selected contexts based on the supplied parameterContextEntity $.each(parameterContexts, function (i, availableParameterContext) { // don't support inheriting from the current context @@ -1592,20 +1582,31 @@ return availableParameterContext.id === selectedParameterContext.id; }); - if (isSelected) { - addParameterContextInheritanceControl('#parameter-context-selected', availableParameterContext, true); - } else if (!isCurrent) { - addParameterContextInheritanceControl('#parameter-context-available', availableParameterContext, false); + if (readOnly) { + if (isSelected) { + $('#parameter-context-selected-read-only').append($('
            1. ').text(availableParameterContext.component.name)); + } + } else { + if (isSelected) { + addParameterContextInheritanceControl(availableParameterContext, true); + } else if (!isCurrent) { + addParameterContextInheritanceControl(availableParameterContext, false); + } } }); sortAvailableParameterContexts(); - if (readOnly || hasSelectedUnauthorized) { - $('#parameter-context-available, #parameter-context-selected').sortable('disable').sortable('refresh'); - $('#parameter-context-selected').addClass('contains-unauthorized'); + if (readOnly) { + if ($('#parameter-context-selected-read-only').is(':empty')) { + $('#parameter-context-selected-read-only').append($('No value set')); + } + + $('#parameter-context-inheritance-container-read-only').show(); + $('#parameter-context-inheritance-container').hide(); } else { - $('#parameter-context-available, #parameter-context-selected').sortable('enable').sortable('refresh'); + $('#parameter-context-inheritance-container-read-only').hide(); + $('#parameter-context-inheritance-container').show(); } }; @@ -1645,7 +1646,8 @@ */ var resetInheritance = function () { $('#parameter-context-available').empty(); - $('#parameter-context-selected').removeClass('contains-unauthorized').empty(); + $('#parameter-context-selected').empty(); + $('#parameter-context-selected-read-only').empty(); }; /** @@ -1682,7 +1684,7 @@ * @argument {object} parameterContext An available parameter context * @argument {boolean} isSelected Whether the parameter context is selected (which is used to decide whether to provide a remove control) */ - var addParameterContextInheritanceControl = function (container, parameterContext, isSelected) { + var addParameterContextInheritanceControl = function (parameterContext, isSelected) { var label = parameterContext.id; if (parameterContext.permissions.canRead) { label = parameterContext.component.name; @@ -1700,35 +1702,34 @@ }, nfCommon.config.tooltipConfig)); } - addDraggableControls(parameterContextElement, isSelected); + if (isSelected) { + addControlsForSelectedParameterContext(parameterContextElement); + } } - parameterContextElement.appendTo(container); + parameterContextElement.appendTo(isSelected ? '#parameter-context-selected' : '#parameter-context-available'); }; /** - * Adds the controls to the specified draggable element. + * Adds the controls to the specified selected draggable element. * * @argument {jQuery} draggableElement - * @argument {boolean} isSelected */ - var addDraggableControls = function (draggableElement, isSelected) { - if (isSelected) { - var removeIcon = $('
              ') - .on('click', function () { - // remove the remove ice - removeIcon.remove(); + var addControlsForSelectedParameterContext = function (draggableElement) { + var removeIcon = $('
              ') + .on('click', function () { + // remove the remove ice + removeIcon.remove(); - // restore to the available parameter contexts - $('#parameter-context-available').append(draggableElement); + // restore to the available parameter contexts + $('#parameter-context-available').append(draggableElement); - // resort the available parameter contexts - sortAvailableParameterContexts(); + // resort the available parameter contexts + sortAvailableParameterContexts(); - // update the buttons to possibly trigger the disabled state - $('#parameter-context-dialog').modal('refreshButtons'); - }) - .appendTo(draggableElement); - } + // update the buttons to possibly trigger the disabled state + $('#parameter-context-dialog').modal('refreshButtons'); + }) + .appendTo(draggableElement); } /** @@ -2633,7 +2634,7 @@ scroll: true, opacity: 0.6, receive: function (event, ui) { - addDraggableControls(ui.item, true); + addControlsForSelectedParameterContext(ui.item); // update the buttons to possibly trigger the disabled state $('#parameter-context-dialog').modal('refreshButtons'); @@ -2641,6 +2642,16 @@ }); $('#parameter-context-available, #parameter-context-selected').disableSelection(); + // add a listener that will handle dblclick for all available authorized parameter context children + $(document).on('dblclick', '#parameter-context-available li:not(".unauthorized")', function() { + var availableParameterContextElement = $(this).detach().appendTo($('#parameter-context-selected')); + + addControlsForSelectedParameterContext(availableParameterContextElement); + + // update the buttons to possibly trigger the disabled state + $('#parameter-context-dialog').modal('refreshButtons'); + }); + // initialize the new parameter context dialog initNewParameterContextDialog(); @@ -2673,10 +2684,8 @@ }) }; - var inheritedParameterContexts = marshalInheritedParameterContexts(); - if (!nfCommon.isNull(inheritedParameterContexts)) { - parameterContextEntity.component.inheritedParameterContexts = inheritedParameterContexts; - } + // include the inherited parameter contexts + parameterContextEntity.component.inheritedParameterContexts = marshalInheritedParameterContexts(); var addContext = $.ajax({ type: 'POST', From fed39ef63c20c703cddff66de5afdcd1dc0bdcae Mon Sep 17 00:00:00 2001 From: Joe Gresock Date: Mon, 13 Sep 2021 22:44:14 -0400 Subject: [PATCH 05/13] NIFI-8491: Adding inherited param context verification earlier --- .../parameter/StandardParameterContext.java | 33 +++++++++++++------ .../nifi/parameter/ParameterContext.java | 9 ++++- .../dao/impl/StandardParameterContextDAO.java | 8 ++++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java index 7bc09b12a8bf..e7708605c9fa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/parameter/StandardParameterContext.java @@ -456,32 +456,45 @@ private void verifyNoCycles(final Stack traversedIds, final List inheritedParameterContexts) { + if (inheritedParameterContexts == null) { + return; + } + verifyNoCycles(inheritedParameterContexts); + + final Map currentEffectiveParameters = getEffectiveParameters(); + final Map effectiveProposedParameters = getEffectiveParameters(inheritedParameterContexts); + final Map effectiveParameterUpdates = getEffectiveParameterUpdates(currentEffectiveParameters, effectiveProposedParameters); + + try { + verifyCanSetParameters(currentEffectiveParameters, effectiveParameterUpdates); + } catch (final IllegalStateException e) { + // Wrap with a more accurate message + throw new IllegalStateException(String.format("Could not update inherited Parameter Contexts for Parameter Context [%s] because: %s", + name, e.getMessage()), e); + } + } + @Override public void setInheritedParameterContexts(final List inheritedParameterContexts) { - if (inheritedParameterContexts.equals(this.inheritedParameterContexts)) { + if (inheritedParameterContexts == null || inheritedParameterContexts.equals(this.inheritedParameterContexts)) { // No changes return; } + verifyCanSetInheritedParameterContexts(inheritedParameterContexts); + final Map parameterUpdates = new HashMap<>(); writeLock.lock(); try { this.version++; - verifyNoCycles(inheritedParameterContexts); final Map currentEffectiveParameters = getEffectiveParameters(); final Map effectiveProposedParameters = getEffectiveParameters(inheritedParameterContexts); final Map effectiveParameterUpdates = getEffectiveParameterUpdates(currentEffectiveParameters, effectiveProposedParameters); - try { - verifyCanSetParameters(currentEffectiveParameters, effectiveParameterUpdates); - } catch (final IllegalStateException e) { - // Wrap with a more accurate message - throw new IllegalStateException(String.format("Could not update inherited Parameter Contexts for Parameter Context [%s] because: %s", - name, e.getMessage()), e); - } - this.inheritedParameterContexts.clear(); this.inheritedParameterContexts.addAll(inheritedParameterContexts); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java index 670c9ce533fc..9e4c3063fbac 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/parameter/ParameterContext.java @@ -115,6 +115,13 @@ public interface ParameterContext extends ParameterLookup, ComponentAuthorizable */ ParameterReferenceManager getParameterReferenceManager(); + /** + * Verifies whether the given list of inherited parameter contexts can be set. This includes checking for + * circular references. + * @param inheritedParameterContexts the list of ParameterContexts from which to inherit parameters + */ + void verifyCanSetInheritedParameterContexts(List inheritedParameterContexts); + /** * Updates the ParameterContexts within this context to match the given list of ParameterContexts. All parameter in these * ParameterContexts are inherited by this ParameterContext, and can be referenced as if they were actually in this ParameterContext. @@ -125,7 +132,7 @@ public interface ParameterContext extends ParameterLookup, ComponentAuthorizable * * @param inheritedParameterContexts the list of ParameterContexts from which to inherit parameters, in priority order first to last * @throws IllegalStateException if the list of ParameterContexts is invalid (in case of a circular reference or - * in case {@link #verifyCanSetParameters(Map)} verifyCanSetParameters} would throw an exception) + * in case {@link #verifyCanSetParameters(Map) verifyCanSetParameters} would throw an exception) */ void setInheritedParameterContexts(List inheritedParameterContexts); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java index 1c8c3a2fcd38..f48fc0f411b1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardParameterContextDAO.java @@ -73,10 +73,12 @@ private void verifyInheritedParameterContextRefs(final ParameterContextDTO param if (inheritedParameterContexts != null) { resolveInheritedParameterContexts(parameterContextDto); // This will throw an exception if one is not found - inheritedParameterContexts.stream().forEach(entity -> flowManager.getParameterContextManager() + inheritedParameterContexts.forEach(entity -> flowManager.getParameterContextManager() .getParameterContext(entity.getComponent().getId())); } authorizeReferences(parameterContextDto); + + } @Override @@ -243,6 +245,10 @@ public void verifyUpdate(final ParameterContextDTO parameterContextDto, final bo verifyInheritedParameterContextRefs(parameterContextDto); final ParameterContext currentContext = getParameterContext(parameterContextDto.getId()); + + final List inheritedParameterContexts = getInheritedParameterContexts(parameterContextDto); + currentContext.verifyCanSetInheritedParameterContexts(inheritedParameterContexts); + for (final ParameterEntity parameterEntity : parameterContextDto.getParameters()) { final ParameterDTO parameterDto = parameterEntity.getParameter(); final String parameterName = parameterDto.getName(); From ed6479e5f8819c263efbfa98fec148f28f4b0a45 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Wed, 15 Sep 2021 11:03:03 -0400 Subject: [PATCH 06/13] NIFI-8491: - Addressing CI failures by rolling back to some order JS language spec to allow yui-compress to minify and compress. --- .../src/main/webapp/js/nf/canvas/nf-parameter-contexts.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js index 3863d153eb68..799a4562cbac 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js @@ -1578,7 +1578,7 @@ var isCurrent = nfCommon.isNull(parameterContextEntity) ? false : availableParameterContext.id === parameterContextEntity.id; // determine if this available parameter context is already selected - var isSelected = nfCommon.isNull(parameterContextEntity) ? false : parameterContextEntity.component.inheritedParameterContexts.some((selectedParameterContext) => { + var isSelected = nfCommon.isNull(parameterContextEntity) ? false : parameterContextEntity.component.inheritedParameterContexts.some(function (selectedParameterContext) { return availableParameterContext.id === selectedParameterContext.id; }); @@ -2606,7 +2606,7 @@ }); // work around for https://bugs.jqueryui.com/ticket/6054 - let shouldAllowDrop = true; + var shouldAllowDrop = true; // make the parameter context containers sortable $('#parameter-context-available').sortable({ From 98baa4e5529c21a1239aa5b7e0cdf781b48ced54 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Tue, 21 Sep 2021 16:57:44 -0400 Subject: [PATCH 07/13] NIFI-8491: - Ensuring selected context sort order is honored. - Ensuring the Apply button is correctly enabled. - Showing Pending Apply message when selected Parameter Context changes. - Ensuring the Parameter's tab is selected now that there is a third tab. --- .../canvas/new-parameter-context-dialog.jsp | 3 + .../src/main/webapp/css/dialog.css | 1 + .../css/new-parameter-context-dialog.css | 10 +++ .../js/nf/canvas/nf-parameter-contexts.js | 73 +++++++++++++++++-- 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp index 63206c73d531..c788921fdf00 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-parameter-context-dialog.jsp @@ -138,6 +138,9 @@
              +