From f48808b1f4b817203aa5fec92b2a90bfeefb59e9 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Tue, 12 Dec 2017 16:39:05 -0500 Subject: [PATCH] NIFI-4436: - Updating buckets permissions based on new model. - Adding check to ensure that flow name is non null before checking the length. - Adding versioned flow state to the Process Group tab in the Summary table. - Fixing issue with navigating to Controller Services from the local changes dialog. --- .../controller/status/ProcessGroupStatus.java | 16 +++++ .../registry/flow/VersionedFlowState.java | 0 .../status/ProcessGroupStatusSnapshotDTO.java | 14 ++++ .../web/api/entity/FlowBreadcrumbEntity.java | 10 +-- .../web/api/entity/ProcessGroupEntity.java | 10 +-- .../nifi/cluster/manager/StatusMerger.java | 6 ++ .../nifi/controller/FlowController.java | 70 ++++++++++--------- .../nifi/web/StandardNiFiServiceFacade.java | 7 +- .../apache/nifi/web/api/VersionsResource.java | 2 +- .../apache/nifi/web/api/dto/DtoFactory.java | 9 ++- .../nifi/web/api/dto/EntityFactory.java | 4 +- .../nf-ng-breadcrumbs-controller.js | 8 +-- .../webapp/js/nf/canvas/nf-flow-version.js | 5 +- .../webapp/js/nf/canvas/nf-process-group.js | 6 +- .../webapp/js/nf/summary/nf-summary-table.js | 55 ++++++++++++--- 15 files changed, 152 insertions(+), 70 deletions(-) rename {nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api => nifi-api}/src/main/java/org/apache/nifi/registry/flow/VersionedFlowState.java (100%) diff --git a/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java b/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java index b890c85089..e07d1c1cc4 100644 --- a/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java +++ b/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java @@ -16,6 +16,8 @@ */ package org.apache.nifi.controller.status; +import org.apache.nifi.registry.flow.VersionedFlowState; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -27,6 +29,7 @@ public class ProcessGroupStatus implements Cloneable { private String id; private String name; + private VersionedFlowState versionedFlowState; private Integer inputCount; private Long inputContentSize; private Integer outputCount; @@ -66,6 +69,14 @@ public class ProcessGroupStatus implements Cloneable { this.name = name; } + public VersionedFlowState getVersionedFlowState() { + return versionedFlowState; + } + + public void setVersionedFlowState(VersionedFlowState versionedFlowState) { + this.versionedFlowState = versionedFlowState; + } + public Integer getInputCount() { return inputCount; } @@ -399,6 +410,11 @@ public class ProcessGroupStatus implements Cloneable { target.setFlowFilesSent(target.getFlowFilesSent() + toMerge.getFlowFilesSent()); target.setBytesSent(target.getBytesSent() + toMerge.getBytesSent()); + // if the versioned flow state to merge is sync failure allow it to take precedence. + if (VersionedFlowState.SYNC_FAILURE.equals(toMerge.getVersionedFlowState())) { + target.setVersionedFlowState(VersionedFlowState.SYNC_FAILURE); + } + // connection status // sort by id final Map mergedConnectionMap = new HashMap<>(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/VersionedFlowState.java b/nifi-api/src/main/java/org/apache/nifi/registry/flow/VersionedFlowState.java similarity index 100% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/VersionedFlowState.java rename to nifi-api/src/main/java/org/apache/nifi/registry/flow/VersionedFlowState.java diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java index 3ae63550d4..82df92ea15 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java @@ -43,6 +43,8 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { private Collection inputPortStatusSnapshots; private Collection outputPortStatusSnapshots; + private String versionedFlowState; + private Integer flowFilesIn = 0; private Long bytesIn = 0L; private String input; @@ -102,6 +104,17 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { this.name = name; } + @ApiModelProperty(readOnly = true, + value = "The current state of the Process Group, as it relates to the Versioned Flow", + allowableValues = "LOCALLY_MODIFIED_DESCENDANT, LOCALLY_MODIFIED, STALE, LOCALLY_MODIFIED_AND_STALE, UP_TO_DATE") + public String getVersionedFlowState() { + return versionedFlowState; + } + + public void setVersionedFlowState(String versionedFlowState) { + this.versionedFlowState = versionedFlowState; + } + /** * @return active thread count for this process group */ @@ -477,6 +490,7 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { final ProcessGroupStatusSnapshotDTO other = new ProcessGroupStatusSnapshotDTO(); other.setId(getId()); other.setName(getName()); + other.setVersionedFlowState(getVersionedFlowState()); other.setBytesIn(getBytesIn()); other.setFlowFilesIn(getFlowFilesIn()); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java index 21f9742698..83934d2c8e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java @@ -30,7 +30,7 @@ public class FlowBreadcrumbEntity extends Entity { private String id; private PermissionsDTO permissions; - private String state; + private String versionedFlowState; private FlowBreadcrumbDTO breadcrumb; private FlowBreadcrumbEntity parentBreadcrumb; @@ -101,11 +101,11 @@ public class FlowBreadcrumbEntity extends Entity { @ApiModelProperty(readOnly = true, value = "The current state of the Process Group, as it relates to the Versioned Flow", allowableValues = "LOCALLY_MODIFIED_DESCENDANT, LOCALLY_MODIFIED, STALE, LOCALLY_MODIFIED_AND_STALE, UP_TO_DATE") - public String getState() { - return state; + public String getVersionedFlowState() { + return versionedFlowState; } - public void setState(String state) { - this.state = state; + public void setVersionedFlowState(String versionedFlowState) { + this.versionedFlowState = versionedFlowState; } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java index fe8d2d62b7..9cb7de6526 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupEntity.java @@ -40,7 +40,7 @@ public class ProcessGroupEntity extends ComponentEntity implements Permissible

authorizedActions = bucket.getAuthorizedActions(); + final Permissions regPermissions = bucket.getPermissions(); final PermissionsDTO permissions = new PermissionsDTO(); - permissions.setCanRead(authorizedActions.contains("read")); - permissions.setCanWrite(authorizedActions.contains("write")); + permissions.setCanRead(regPermissions.getCanRead()); + permissions.setCanWrite(regPermissions.getCanWrite()); return entityFactory.createBucketEntity(dto, permissions); }) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java index 1d4cd88fff..af9a515928 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java @@ -437,7 +437,7 @@ public class VersionsResource extends ApplicationResource { if (StringUtils.isEmpty(versionedFlowDto.getFlowName()) && StringUtils.isEmpty(versionedFlowDto.getFlowId())) { throw new IllegalArgumentException("The Flow Name or Flow ID must be supplied."); } - if (versionedFlowDto.getFlowName().length() > 1000) { + if (versionedFlowDto.getFlowName() != null && versionedFlowDto.getFlowName().length() > 1000) { throw new IllegalArgumentException("The Flow Name cannot exceed 1,000 characters"); } if (StringUtils.isEmpty(versionedFlowDto.getRegistryId())) { 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/DtoFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 5bdb0400bf..41983034d3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -16,8 +16,6 @@ */ package org.apache.nifi.web.api.dto; -import javax.ws.rs.WebApplicationException; - import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.action.Action; @@ -192,6 +190,7 @@ import org.apache.nifi.web.api.entity.VariableEntity; import org.apache.nifi.web.controller.ControllerFacade; import org.apache.nifi.web.revision.RevisionManager; +import javax.ws.rs.WebApplicationException; import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; @@ -955,6 +954,10 @@ public final class DtoFactory { snapshot.setId(processGroupStatus.getId()); snapshot.setName(processGroupStatus.getName()); + if (processGroupStatus.getVersionedFlowState() != null) { + snapshot.setVersionedFlowState(processGroupStatus.getVersionedFlowState().name()); + } + snapshot.setFlowFilesQueued(processGroupStatus.getQueuedCount()); snapshot.setBytesQueued(processGroupStatus.getQueuedContentSize()); snapshot.setBytesRead(processGroupStatus.getBytesRead()); @@ -2214,7 +2217,7 @@ public final class DtoFactory { final ComponentDifferenceDTO dto = new ComponentDifferenceDTO(); dto.setComponentName(component.getName()); - dto.setComponentType(component.getComponentType().name()); + dto.setComponentType(component.getComponentType().toString()); if (component instanceof InstantiatedVersionedComponent) { final InstantiatedVersionedComponent instantiatedComponent = (InstantiatedVersionedComponent) component; 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 6a73e3a2dd..566b519b35 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 @@ -241,7 +241,7 @@ public final class EntityFactory { entity.setSyncFailureCount(dto.getSyncFailureCount()); if (dto.getVersionControlInformation() != null) { - entity.setState(dto.getVersionControlInformation().getState()); + entity.setVersionedFlowState(dto.getVersionControlInformation().getState()); } entity.setBulletins(bulletins); // include bulletins as authorized descendant component bulletins should be available @@ -513,7 +513,7 @@ public final class EntityFactory { entity.setId(dto.getId()); if (dto.getVersionControlInformation() != null) { - entity.setState(dto.getVersionControlInformation().getState()); + entity.setVersionedFlowState(dto.getVersionControlInformation().getState()); } if (permissions != null && permissions.getCanRead()) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js index 64f21172bf..73315965b8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js @@ -103,7 +103,7 @@ * @returns {*} */ isTracking: function (breadcrumbEntity) { - return nfCommon.isDefinedAndNotNull(breadcrumbEntity.state); + return nfCommon.isDefinedAndNotNull(breadcrumbEntity.versionedFlowState); }, /** @@ -113,8 +113,8 @@ * @returns {string} */ getVersionControlClass: function (breadcrumbEntity) { - if (nfCommon.isDefinedAndNotNull(breadcrumbEntity.state)) { - var vciState = breadcrumbEntity.state; + if (nfCommon.isDefinedAndNotNull(breadcrumbEntity.versionedFlowState)) { + var vciState = breadcrumbEntity.versionedFlowState; if (vciState === 'SYNC_FAILURE') { return 'breadcrumb-version-control-gray fa fa-question' } else if (vciState === 'LOCALLY_MODIFIED_AND_STALE') { @@ -137,7 +137,7 @@ * @param breadcrumbEntity */ getVersionControlTooltip: function (breadcrumbEntity) { - if (nfCommon.isDefinedAndNotNull(breadcrumbEntity.state) && breadcrumbEntity.permissions.canRead) { + if (nfCommon.isDefinedAndNotNull(breadcrumbEntity.versionedFlowState) && breadcrumbEntity.permissions.canRead) { return nfCommon.getVersionControlTooltip(breadcrumbEntity.breadcrumb.versionControlInformation); } else { return 'This Process Group is not under version control.' diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js index 01a0a07bdc..b676f5b9ce 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js @@ -1602,10 +1602,9 @@ var processGroupId = $('#save-flow-version-process-group-id').text(); saveFlowVersion().done(function (response) { updateVersionControlInformation(processGroupId, response.versionControlInformation); - - // only hide the dialog if the flow version was successfully saved - $(this).modal('hide'); }); + + $(this).modal('hide'); } } }, { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js index 433c59f73a..50a38182da 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js @@ -91,7 +91,7 @@ * @param d */ var isUnderVersionControl = function (d) { - return nfCommon.isDefinedAndNotNull(d.state); + return nfCommon.isDefinedAndNotNull(d.versionedFlowState); }; /** @@ -1060,7 +1060,7 @@ 'visibility': isUnderVersionControl(processGroupData) ? 'visible' : 'hidden', 'fill': function () { if (isUnderVersionControl(processGroupData)) { - var vciState = processGroupData.state; + var vciState = processGroupData.versionedFlowState; if (vciState === 'SYNC_FAILURE') { return '#666666'; } else if (vciState === 'LOCALLY_MODIFIED_AND_STALE') { @@ -1079,7 +1079,7 @@ }) .text(function () { if (isUnderVersionControl(processGroupData)) { - var vciState = processGroupData.state; + var vciState = processGroupData.versionedFlowState; if (vciState === 'SYNC_FAILURE') { return '\uf128' } else if (vciState === 'LOCALLY_MODIFIED_AND_STALE') { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js index dbc3b70cfc..e54b441125 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js @@ -310,25 +310,25 @@ if (nfCommon.isDefinedAndNotNull(dataContext.activeThreadCount) && dataContext.activeThreadCount > 0) { activeThreadCount = '(' + nfCommon.escapeHtml(dataContext.activeThreadCount) + ')'; } - var classes = nfCommon.escapeHtml(value.toLowerCase()); - switch (nfCommon.escapeHtml(value.toLowerCase())) { + var classes; + switch (value.toLowerCase()) { case 'running': - classes += ' fa fa-play running'; + classes = 'fa fa-play running'; break; case 'stopped': - classes += ' fa fa-stop stopped'; + classes = 'fa fa-stop stopped'; break; case 'enabled': - classes += ' fa fa-flash enabled'; + classes = 'fa fa-flash enabled'; break; case 'disabled': - classes += ' icon icon-enable-false disabled'; + classes = 'icon icon-enable-false disabled'; break; case 'invalid': - classes += ' fa fa-warning invalid'; + classes = 'fa fa-warning invalid'; break; default: - classes += ''; + classes = ''; } var formattedValue = '

'; return formattedValue + '
' + nfCommon.escapeHtml(value) + '
' + nfCommon.escapeHtml(activeThreadCount) + '
'; @@ -1041,6 +1041,37 @@ formatter: nfCommon.genericValueFormatter }; + // define how the column is formatted + var versionStateFormatter = function (row, cell, value, columnDef, dataContext) { + var classes, label; + switch (value) { + case 'UP_TO_DATE': + classes = 'fa fa-check up-to-date'; + label = 'Up to date'; + break; + case 'LOCALLY_MODIFIED': + classes = 'fa fa-asterisk locally-modified'; + label = 'Locally modified'; + break; + case 'STALE': + classes = 'fa fa-arrow-circle-up stale'; + label = 'Stale'; + break; + case 'LOCALLY_MODIFIED_AND_STALE': + classes = 'fa fa-exclamation-circle locally-modified-and-stale'; + label = 'Locally modified and stale'; + break; + case 'SYNC_FAILURE': + classes = 'fa fa-question sync-failure'; + label = 'Sync failure'; + break; + default: + classes = ''; + label = ''; + } + return '
' + label + '
'; + }; + // define the column model for the summary table var processGroupsColumnModel = [ moreDetailsColumn, @@ -1052,6 +1083,14 @@ resizable: true, formatter: valueFormatter }, + { + id: 'versionedFlowState', + field: 'versionedFlowState', + name: 'Version State', + sortable: true, + resizable: true, + formatter: versionStateFormatter + }, transferredColumn, inputColumn, ioColumn,