From 572dfed78a579150adcedf416c600aaba0ab7efc Mon Sep 17 00:00:00 2001 From: Jeff Storck Date: Fri, 1 Jul 2016 20:49:49 -0400 Subject: [PATCH] NIFI-1876 Implements merging of responses to successful requests based on authorization, returning the most restrictive response - Added StandardHttpResponseMergerSpec for testing response merging - Added Permissible interface - Added nifi-api/controller/archive to ProcessGroupEndpointMerger - Removed AbstractMultiEntityEndpoint.java, not used anymore - Implemented reponse merging for GET requests where there are some successful and problematic responses, returning most restrictive one. - Updated nf-settings.js with ControllerConfigurationEntity property rename from controllerConfiguration to component - Implemented merging of status DTOs based on read permission NIFI-2264 Implemented merging of status history results based on readability permissions - Added StatusHistoryEndpointMergerSpec to test merging of status history based on read permission NIFI-1876 Added merging for labels, funnels, and controller service references. NIFI-1876 Added Label and Funnel merging to FlowMerger.java NIFI-1876 Added replication of request for process group controller services - Updated merging code for Status and Status History based on read permissions NIFI-1876 Fixed issue with node status snapshots all looking like they came from one node Updated ProcessGroupStatusSnapshotDTO to contain status snapshot entities to retain readability permission Added entity classes for ConnectionStatusSnapshotDTO, PortStatusSnapshotDTO, ProcessGroupStatusSnapshotDTO, ProcessorStatusSnapshotDTO, and RemoteProcessGroupStatusSnapshotDTO Updated PropertyDescriptorDTO to contain AllowableValueEntity to retain readability permission Added entity class for AllowableValueDTO Moved AllowableValueDTO to its own top-level class Updated DtoFactory to get permissions for status snapshot entities Updated StatusMerger to merge status snapshot entities Signed-off-by: jpercivall --- .../nifi/web/api/dto/AllowableValueDTO.java | 77 ++++ .../nifi/web/api/dto/PermissionsDTO.java | 6 +- .../web/api/dto/PropertyDescriptorDTO.java | 79 +---- .../nifi/web/api/dto/ReadablePermission.java | 29 ++ .../nifi/web/api/dto/WritablePermission.java | 29 ++ .../api/dto/status/ClusterPortStatusDTO.java | 94 ----- .../api/dto/status/ConnectionStatusDTO.java | 15 +- .../status/ConnectionStatusSnapshotDTO.java | 2 +- .../NodeRemotePortStatusSnapshotDTO.java | 77 ---- .../web/api/dto/status/PortStatusDTO.java | 9 +- .../api/dto/status/PortStatusSnapshotDTO.java | 4 +- .../api/dto/status/ProcessGroupStatusDTO.java | 11 +- .../status/ProcessGroupStatusSnapshotDTO.java | 45 +-- .../api/dto/status/ProcessorStatusDTO.java | 11 +- .../status/ProcessorStatusSnapshotDTO.java | 4 +- .../api/dto/status/RemotePortStatusDTO.java | 114 ------ .../RemoteProcessGroupStatusSnapshotDTO.java | 4 +- ...sEntity.java => AllowableValueEntity.java} | 34 +- .../nifi/web/api/entity/ConnectionEntity.java | 2 +- .../api/entity/ConnectionStatusEntity.java | 13 +- .../ConnectionStatusSnapshotEntity.java | 74 ++++ .../entity/ControllerConfigurationEntity.java | 6 +- .../api/entity/ControllerServiceEntity.java | 2 +- .../nifi/web/api/entity/FunnelEntity.java | 2 +- .../nifi/web/api/entity/LabelEntity.java | 2 +- .../nifi/web/api/entity/Permissible.java | 34 ++ .../nifi/web/api/entity/PortEntity.java | 4 +- .../nifi/web/api/entity/PortStatusEntity.java | 13 +- .../api/entity/PortStatusSnapshotEntity.java | 75 ++++ .../web/api/entity/ProcessGroupEntity.java | 2 +- .../api/entity/ProcessGroupStatusEntity.java | 14 +- .../ProcessGroupStatusSnapshotEntity.java | 74 ++++ .../nifi/web/api/entity/ProcessorEntity.java | 2 +- .../web/api/entity/ProcessorStatusEntity.java | 13 +- .../entity/ProcessorStatusSnapshotEntity.java | 74 ++++ .../api/entity/RemoteProcessGroupEntity.java | 2 +- .../RemoteProcessGroupStatusEntity.java | 13 +- ...emoteProcessGroupStatusSnapshotEntity.java | 75 ++++ .../web/api/entity/ReportingTaskEntity.java | 4 +- .../web/api/entity/StatusHistoryEntity.java | 16 +- .../nifi-framework-cluster/pom.xml | 13 +- .../http/StandardHttpResponseMerger.java | 25 +- .../AbstractMultiEntityEndpoint.java | 99 ------ .../endpoints/ConnectionEndpointMerger.java | 12 +- .../ConnectionStatusEndpiontMerger.java | 48 ++- .../endpoints/ConnectionsEndpointMerger.java | 6 +- ...ControllerConfigurationEndpointMerger.java | 51 +++ .../ControllerServiceEndpointMerger.java | 3 +- .../endpoints/CountersEndpointMerger.java | 2 +- .../http/endpoints/FlowMerger.java | 35 +- .../http/endpoints/FunnelEndpointMerger.java | 55 +++ .../http/endpoints/FunnelsEndpointMerger.java | 71 ++++ .../endpoints/GroupStatusEndpointMerger.java | 36 +- .../http/endpoints/LabelEndpointMerger.java | 55 +++ .../http/endpoints/LabelsEndpointMerger.java | 71 ++++ .../http/endpoints/PortEndpointMerger.java | 4 +- .../endpoints/PortStatusEndpointMerger.java | 50 ++- .../endpoints/ProcessGroupEndpointMerger.java | 11 +- .../endpoints/ProcessorEndpointMerger.java | 4 +- .../ProcessorStatusEndpointMerger.java | 47 ++- .../RemoteProcessGroupEndpointMerger.java | 3 +- ...emoteProcessGroupStatusEndpointMerger.java | 48 ++- .../ReportingTaskEndpointMerger.java | 3 +- .../StatusHistoryEndpointMerger.java | 9 +- .../manager/ComponentEntityMerger.java | 65 ++-- .../manager/ComponentEntityStatusMerger.java | 35 ++ .../manager/ConnectionEntityMerger.java | 28 +- .../manager/ConnectionsEntityMerger.java | 4 +- .../ControllerServiceEntityMerger.java | 42 ++- .../ControllerServicesEntityMerger.java | 4 +- .../cluster/manager/FunnelEntityMerger.java | 23 ++ .../cluster/manager/FunnelsEntityMerger.java | 39 +++ .../cluster/manager/LabelEntityMerger.java | 23 ++ .../cluster/manager/LabelsEntityMerger.java | 39 +++ .../cluster/manager/PermissionsDtoMerger.java | 37 ++ .../cluster/manager/PortEntityMerger.java | 35 +- .../cluster/manager/PortsEntityMerger.java | 4 +- .../manager/ProcessGroupEntityMerger.java | 29 +- .../manager/ProcessGroupsEntityMerger.java | 4 +- .../manager/ProcessorEntityMerger.java | 33 +- .../manager/ProcessorsEntityMerger.java | 4 +- .../RemoteProcessGroupEntityMerger.java | 33 +- .../RemoteProcessGroupsEntityMerger.java | 4 +- .../manager/ReportingTaskEntityMerger.java | 6 +- .../manager/ReportingTasksEntityMerger.java | 4 +- .../nifi/cluster/manager/StatusMerger.java | 211 ++++++++--- .../StandardHttpResponseMergerSpec.groovy | 217 ++++++++++++ .../StatusHistoryEndpointMergerSpec.groovy | 88 +++++ .../manager/ConnectionEntityMergerSpec.groovy | 72 ++++ .../ControllerServiceEntityMergerSpec.groovy | 103 ++++++ .../manager/LabelEntityMergerSpec.groovy | 61 ++++ .../PermissionBasedStatusMergerSpec.groovy | 328 ++++++++++++++++++ .../RemoteProcessGroupStatusDescriptor.java | 6 +- .../apache/nifi/web/NiFiServiceFacade.java | 32 +- .../nifi/web/StandardNiFiServiceFacade.java | 140 ++++++-- .../StandardNiFiWebConfigurationContext.java | 5 +- .../nifi/web/api/ControllerResource.java | 4 +- .../org/apache/nifi/web/api/FlowResource.java | 113 +----- .../apache/nifi/web/api/dto/DtoFactory.java | 49 ++- .../nifi/web/api/dto/EntityFactory.java | 189 +++++++++- .../main/webapp/js/nf/canvas/nf-settings.js | 10 +- 101 files changed, 3024 insertions(+), 1020 deletions(-) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AllowableValueDTO.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReadablePermission.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/WritablePermission.java delete mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterPortStatusDTO.java delete mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java delete mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java rename nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/{ClusterPortStatusEntity.java => AllowableValueEntity.java} (56%) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusSnapshotEntity.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/Permissible.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusSnapshotEntity.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusSnapshotEntity.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusSnapshotEntity.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusSnapshotEntity.java delete mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/AbstractMultiEntityEndpoint.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerConfigurationEndpointMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelEndpointMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelsEndpointMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelEndpointMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelsEndpointMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityStatusMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelEntityMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelsEntityMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelEntityMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelsEntityMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PermissionsDtoMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMergerSpec.groovy create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMergerSpec.groovy create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ConnectionEntityMergerSpec.groovy create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMergerSpec.groovy create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/LabelEntityMergerSpec.groovy create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/PermissionBasedStatusMergerSpec.groovy diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AllowableValueDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AllowableValueDTO.java new file mode 100644 index 0000000000..24c937eebe --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AllowableValueDTO.java @@ -0,0 +1,77 @@ +package org.apache.nifi.web.api.dto; + +import com.wordnik.swagger.annotations.ApiModelProperty; + +import javax.xml.bind.annotation.XmlType; + +/** + * The allowable values for a property with a constrained set of options. + */ +@XmlType(name = "allowableValue") +public class AllowableValueDTO { + + private String displayName; + private String value; + private String description; + + /** + * @return the human-readable value that is allowed for this PropertyDescriptor + */ + @ApiModelProperty( + value = "A human readable value that is allowed for the property descriptor." + ) + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + /** + * @return the value for this allowable value + */ + @ApiModelProperty( + value = "A value that is allowed for the property descriptor." + ) + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * @return a description of this Allowable Value, or null if no description is given + */ + @ApiModelProperty( + value = "A description for this allowable value." + ) + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof AllowableValueDTO)) { + return false; + } + + final AllowableValueDTO other = (AllowableValueDTO) obj; + return (this.value.equals(other.getValue())); + } + + @Override + public int hashCode() { + return 23984731 + 17 * value.hashCode(); + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PermissionsDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PermissionsDTO.java index dc5b7f94cc..8039cda880 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PermissionsDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PermissionsDTO.java @@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlType; * Details for the access configuration. */ @XmlType(name = "permission") -public class PermissionsDTO { +public class PermissionsDTO implements ReadablePermission, WritablePermission { private Boolean canRead; private Boolean canWrite; @@ -36,10 +36,12 @@ public class PermissionsDTO { value = "Indicates whether the user can read a given resource.", readOnly = true ) + @Override public Boolean getCanRead() { return canRead; } + @Override public void setCanRead(Boolean canRead) { this.canRead = canRead; } @@ -51,10 +53,12 @@ public class PermissionsDTO { value = "Indicates whether the user can write a given resource.", readOnly = true ) + @Override public Boolean getCanWrite() { return canWrite; } + @Override public void setCanWrite(Boolean canWrite) { this.canWrite = canWrite; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java index 500420b77a..b85e30feea 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java @@ -17,6 +17,8 @@ package org.apache.nifi.web.api.dto; import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.entity.AllowableValueEntity; + import java.util.List; import javax.xml.bind.annotation.XmlType; @@ -30,7 +32,7 @@ public class PropertyDescriptorDTO { private String displayName; private String description; private String defaultValue; - private List allowableValues; + private List allowableValues; private Boolean required; private Boolean sensitive; private Boolean dynamic; @@ -43,11 +45,11 @@ public class PropertyDescriptorDTO { @ApiModelProperty( value = "Allowable values for the property. If empty then the allowed values are not constrained." ) - public List getAllowableValues() { + public List getAllowableValues() { return allowableValues; } - public void setAllowableValues(List allowableValues) { + public void setAllowableValues(List allowableValues) { this.allowableValues = allowableValues; } @@ -177,75 +179,4 @@ public class PropertyDescriptorDTO { this.identifiesControllerService = identifiesControllerService; } - /** - * The allowable values for a property with a constrained set of options. - */ - @XmlType(name = "allowableValue") - public static class AllowableValueDTO { - - private String displayName; - private String value; - private String description; - - /** - * @return the human-readable value that is allowed for this PropertyDescriptor - */ - @ApiModelProperty( - value = "A human readable value that is allowed for the property descriptor." - ) - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - /** - * @return the value for this allowable value - */ - @ApiModelProperty( - value = "A value that is allowed for the property descriptor." - ) - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - /** - * @return a description of this Allowable Value, or null if no description is given - */ - @ApiModelProperty( - value = "A description for this allowable value." - ) - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof AllowableValueDTO)) { - return false; - } - - final AllowableValueDTO other = (AllowableValueDTO) obj; - return (this.value.equals(other.getValue())); - } - - @Override - public int hashCode() { - return 23984731 + 17 * value.hashCode(); - } - } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReadablePermission.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReadablePermission.java new file mode 100644 index 0000000000..536c23c3bd --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReadablePermission.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.dto; + +import com.wordnik.swagger.annotations.ApiModelProperty; + +public interface ReadablePermission { + @ApiModelProperty( + value = "Indicates whether the user can read a given resource.", + readOnly = true + ) + Boolean getCanRead(); + + void setCanRead(Boolean canRead); +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/WritablePermission.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/WritablePermission.java new file mode 100644 index 0000000000..3eb286e9a6 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/WritablePermission.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.dto; + +import com.wordnik.swagger.annotations.ApiModelProperty; + +public interface WritablePermission { + @ApiModelProperty( + value = "Indicates whether the user can write a given resource.", + readOnly = true + ) + Boolean getCanWrite(); + + void setCanWrite(Boolean canWrite); +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterPortStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterPortStatusDTO.java deleted file mode 100644 index 372bb70e30..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterPortStatusDTO.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.nifi.web.api.dto.status; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import java.util.Collection; -import java.util.Date; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.apache.nifi.web.api.dto.util.TimeAdapter; - -/** - * DTO for serializing the a port's status across the cluster. - */ -@XmlType(name = "clusterPortStatus") -public class ClusterPortStatusDTO { - - private Collection nodePortStatus; - private Date statsLastRefreshed; - private String portId; - private String portName; - - /** - * @return the time the status were last refreshed - */ - @XmlJavaTypeAdapter(TimeAdapter.class) - @ApiModelProperty( - value = "The time the status was last refreshed." - ) - public Date getStatsLastRefreshed() { - return statsLastRefreshed; - } - - public void setStatsLastRefreshed(Date statsLastRefreshed) { - this.statsLastRefreshed = statsLastRefreshed; - } - - /** - * @return port status from each node in the cluster - */ - @ApiModelProperty( - value = "The port status for each node." - ) - public Collection getNodePortStatus() { - return nodePortStatus; - } - - public void setNodePortStatus(Collection nodePortStatus) { - this.nodePortStatus = nodePortStatus; - } - - /** - * @return port id - */ - @ApiModelProperty( - value = "The id of the port." - ) - public String getPortId() { - return portId; - } - - public void setPortId(String portId) { - this.portId = portId; - } - - /** - * @return port name - */ - @ApiModelProperty( - value = "The name of the port." - ) - public String getPortName() { - return portName; - } - - public void setPortName(String portName) { - this.portName = portName; - } - -} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java index b9bfd00a03..395ce7cc32 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java @@ -17,15 +17,14 @@ package org.apache.nifi.web.api.dto.status; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.util.TimeAdapter; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimeAdapter; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; @XmlType(name = "connectionStatus") public class ConnectionStatusDTO implements Cloneable { @@ -37,9 +36,10 @@ public class ConnectionStatusDTO implements Cloneable { private String sourceId; private String sourceName; private String destinationId; - private String destinationName; + private String destinationName; private ConnectionStatusSnapshotDTO aggregateSnapshot; + private List nodeSnapshots; @ApiModelProperty("The ID of the connection") @@ -145,6 +145,7 @@ public class ConnectionStatusDTO implements Cloneable { other.setSourceName(getSourceName()); other.setAggregateSnapshot(getAggregateSnapshot().clone()); + final List nodeStatuses = getNodeSnapshots(); final List nodeStatusClones = new ArrayList<>(nodeStatuses.size()); for (final NodeConnectionStatusSnapshotDTO nodeStatus : nodeStatuses) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java index 928fc71ae9..ba40534982 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java @@ -17,6 +17,7 @@ package org.apache.nifi.web.api.dto.status; import com.wordnik.swagger.annotations.ApiModelProperty; + import javax.xml.bind.annotation.XmlType; /** @@ -250,7 +251,6 @@ public class ConnectionStatusSnapshotDTO implements Cloneable { this.bytesQueued = bytesQueued; } - @Override public ConnectionStatusSnapshotDTO clone() { final ConnectionStatusSnapshotDTO other = new ConnectionStatusSnapshotDTO(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java deleted file mode 100644 index 3cd93bc405..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.nifi.web.api.dto.status; - -import javax.xml.bind.annotation.XmlType; - -import com.wordnik.swagger.annotations.ApiModelProperty; - -@XmlType(name = "nodeRemotePortStatusSnapshot") -public class NodeRemotePortStatusSnapshotDTO implements Cloneable { - private String nodeId; - private String address; - private Integer apiPort; - - private RemotePortStatusDTO statusSnapshot; - - @ApiModelProperty("The unique ID that identifies the node") - public String getNodeId() { - return nodeId; - } - - public void setNodeId(String nodeId) { - this.nodeId = nodeId; - } - - @ApiModelProperty("The API address of the node") - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - @ApiModelProperty("The API port used to communicate with the node") - public Integer getApiPort() { - return apiPort; - } - - public void setApiPort(Integer apiPort) { - this.apiPort = apiPort; - } - - @ApiModelProperty("The remote port status snapshot from the node.") - public RemotePortStatusDTO getStatusSnapshot() { - return statusSnapshot; - } - - public void setStatusSnapshot(RemotePortStatusDTO statusSnapshot) { - this.statusSnapshot = statusSnapshot; - } - - @Override - public NodeRemotePortStatusSnapshotDTO clone() { - final NodeRemotePortStatusSnapshotDTO other = new NodeRemotePortStatusSnapshotDTO(); - other.setNodeId(getNodeId()); - other.setAddress(getAddress()); - other.setApiPort(getApiPort()); - other.setStatusSnapshot(getStatusSnapshot().clone()); - return other; - } -} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java index 5e44e7133b..dd24bccaa6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java @@ -17,14 +17,13 @@ package org.apache.nifi.web.api.dto.status; -import java.util.Date; -import java.util.List; +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.util.TimeAdapter; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimeAdapter; +import java.util.Date; +import java.util.List; @XmlType(name = "portStatus") public class PortStatusDTO { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java index b5f11e5b18..9e3093198c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java @@ -16,10 +16,10 @@ */ package org.apache.nifi.web.api.dto.status; -import javax.xml.bind.annotation.XmlType; - import com.wordnik.swagger.annotations.ApiModelProperty; +import javax.xml.bind.annotation.XmlType; + /** * The status for a port in this NiFi. */ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java index 1df212a75e..190658a71c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java @@ -17,14 +17,13 @@ package org.apache.nifi.web.api.dto.status; -import java.util.Date; -import java.util.List; +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.util.TimeAdapter; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimeAdapter; +import java.util.Date; +import java.util.List; @XmlType(name = "processGroupStatus") public class ProcessGroupStatusDTO implements Cloneable { @@ -44,7 +43,7 @@ public class ProcessGroupStatusDTO implements Cloneable { this.id = id; } - @ApiModelProperty("The name of the PRocess Group") + @ApiModelProperty("The name of the Process Group") public String getName() { return name; } 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 e5c61dd610..047748038f 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 @@ -17,6 +17,11 @@ package org.apache.nifi.web.api.dto.status; import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.entity.ConnectionStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.PortStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusSnapshotEntity; import javax.xml.bind.annotation.XmlType; import java.util.ArrayList; @@ -31,12 +36,12 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { private String id; private String name; - private Collection connectionStatus; - private Collection processorStatus; - private Collection processGroupStatus; - private Collection remoteProcessGroupStatus; - private Collection inputPortStatus; - private Collection outputPortStatus; + private Collection connectionStatus; + private Collection processorStatus; + private Collection processGroupStatus; + private Collection remoteProcessGroupStatus; + private Collection inputPortStatus; + private Collection outputPortStatus; private Integer flowFilesIn = 0; private Long bytesIn = 0L; @@ -115,11 +120,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { * @return The status of all connections */ @ApiModelProperty("The status of all conenctions in the process group.") - public Collection getConnectionStatusSnapshots() { + public Collection getConnectionStatusSnapshots() { return connectionStatus; } - public void setConnectionStatusSnapshots(Collection connectionStatus) { + public void setConnectionStatusSnapshots(Collection connectionStatus) { this.connectionStatus = connectionStatus; } @@ -129,11 +134,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { * @return The status of all process groups */ @ApiModelProperty("The status of all process groups in the process group.") - public Collection getProcessGroupStatusSnapshots() { + public Collection getProcessGroupStatusSnapshots() { return processGroupStatus; } - public void setProcessGroupStatusSnapshots(Collection processGroupStatus) { + public void setProcessGroupStatusSnapshots(Collection processGroupStatus) { this.processGroupStatus = processGroupStatus; } @@ -143,11 +148,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { * @return The status of all remote process groups */ @ApiModelProperty("The status of all remote process groups in the process group.") - public Collection getRemoteProcessGroupStatusSnapshots() { + public Collection getRemoteProcessGroupStatusSnapshots() { return remoteProcessGroupStatus; } - public void setRemoteProcessGroupStatusSnapshots(final Collection remoteProcessGroupStatus) { + public void setRemoteProcessGroupStatusSnapshots(final Collection remoteProcessGroupStatus) { this.remoteProcessGroupStatus = remoteProcessGroupStatus; } @@ -157,11 +162,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { * @return The status of all processors */ @ApiModelProperty("The status of all processors in the process group.") - public Collection getProcessorStatusSnapshots() { + public Collection getProcessorStatusSnapshots() { return processorStatus; } - public void setProcessorStatusSnapshots(Collection processorStatus) { + public void setProcessorStatusSnapshots(Collection processorStatus) { this.processorStatus = processorStatus; } @@ -171,11 +176,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { * @return The status of all input ports */ @ApiModelProperty("The status of all input ports in the process group.") - public Collection getInputPortStatusSnapshots() { + public Collection getInputPortStatusSnapshots() { return inputPortStatus; } - public void setInputPortStatusSnapshots(Collection inputPortStatus) { + public void setInputPortStatusSnapshots(Collection inputPortStatus) { this.inputPortStatus = inputPortStatus; } @@ -185,11 +190,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { * @return The status of all output ports */ @ApiModelProperty("The status of all output ports in the process group.") - public Collection getOutputPortStatusSnapshots() { + public Collection getOutputPortStatusSnapshots() { return outputPortStatus; } - public void setOutputPortStatusSnapshots(Collection outputPortStatus) { + public void setOutputPortStatusSnapshots(Collection outputPortStatus) { this.outputPortStatus = outputPortStatus; } @@ -512,8 +517,8 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable { other.setOutputPortStatusSnapshots(copy(getOutputPortStatusSnapshots())); if (processGroupStatus != null) { - final List childGroups = new ArrayList<>(); - for (final ProcessGroupStatusSnapshotDTO procGroupStatus : processGroupStatus) { + final List childGroups = new ArrayList<>(); + for (final ProcessGroupStatusSnapshotEntity procGroupStatus : processGroupStatus) { childGroups.add(procGroupStatus.clone()); } other.setProcessGroupStatusSnapshots(childGroups); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java index a4729c4aca..4e4e9fcfca 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java @@ -17,15 +17,14 @@ package org.apache.nifi.web.api.dto.status; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.util.TimeAdapter; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimeAdapter; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; /** * DTO for serializing the status of a processor. diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java index 032fb57564..73bc85eddc 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java @@ -16,10 +16,10 @@ */ package org.apache.nifi.web.api.dto.status; -import javax.xml.bind.annotation.XmlType; - import com.wordnik.swagger.annotations.ApiModelProperty; +import javax.xml.bind.annotation.XmlType; + /** * DTO for serializing the status of a processor. */ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java deleted file mode 100644 index a6723c7735..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.nifi.web.api.dto.status; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import javax.xml.bind.annotation.XmlType; - -/** - * The status of a Port on a remote NiFi instance. - */ -@XmlType(name = "remotePortStatus") -public class RemotePortStatusDTO implements Cloneable { - - private String id; - private String connectionId; - private String name; - private Boolean running; - private Boolean exists; - - /** - * @return id of the connection this remote port is connected to - */ - @ApiModelProperty( - value = "The id of the conneciton the remote is connected to." - ) - public String getConnectionId() { - return connectionId; - } - - public void setConnectionId(String connectionId) { - this.connectionId = connectionId; - } - - /** - * @return id of the remote port - */ - @ApiModelProperty( - value = "The id of the remote port." - ) - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - /** - * @return name of the remote port - */ - @ApiModelProperty( - value = "The name of the remote port." - ) - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - /** - * @return whether or not the remote port exists - */ - @ApiModelProperty( - value = "Whether or not the remote port exists." - ) - public Boolean getExists() { - return exists; - } - - public void setExists(Boolean exists) { - this.exists = exists; - } - - /** - * @return whether or not the remote port is running - */ - @ApiModelProperty( - value = "Whether or not the remote port is running." - ) - public Boolean getRunning() { - return running; - } - - public void setRunning(Boolean running) { - this.running = running; - } - - @Override - public RemotePortStatusDTO clone() { - final RemotePortStatusDTO other = new RemotePortStatusDTO(); - other.setId(getId()); - other.setName(getName()); - other.setConnectionId(getConnectionId()); - other.setExists(getExists()); - other.setRunning(getRunning()); - return other; - } -} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java index 85e3a242f5..3693d6609e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java @@ -31,7 +31,7 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable { private String name; private String targetUri; private String transmissionStatus; - private Integer activeThreadCount; + private Integer activeThreadCount = 0; private Integer flowFilesSent = 0; private Long bytesSent = 0L; @@ -174,7 +174,6 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable { this.bytesReceived = bytesReceived; } - @Override public RemoteProcessGroupStatusSnapshotDTO clone() { final RemoteProcessGroupStatusSnapshotDTO other = new RemoteProcessGroupStatusSnapshotDTO(); @@ -193,5 +192,4 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable { return other; } - } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterPortStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AllowableValueEntity.java similarity index 56% rename from nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterPortStatusEntity.java rename to nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AllowableValueEntity.java index 477b6ec7dc..d8c64754b1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterPortStatusEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AllowableValueEntity.java @@ -16,28 +16,36 @@ */ package org.apache.nifi.web.api.entity; -import javax.xml.bind.annotation.XmlRootElement; -import org.apache.nifi.web.api.dto.status.ClusterPortStatusDTO; +import org.apache.nifi.web.api.dto.AllowableValueDTO; +import org.apache.nifi.web.api.dto.ReadablePermission; /** - * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ClusterPortStatusDTO. + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a AllowableValueDTO. */ -@XmlRootElement(name = "clusterPortStatusEntity") -public class ClusterPortStatusEntity extends Entity { - - private ClusterPortStatusDTO clusterPortStatus; +public class AllowableValueEntity extends Entity implements ReadablePermission { + private AllowableValueDTO allowableValue; + private Boolean canRead; /** - * The ClusterPortStatusDTO that is being serialized. + * The AllowableValueDTO that is being serialized. * - * @return The ClusterPortStatusDTO object + * @return The AllowableValueDTO object */ - public ClusterPortStatusDTO getClusterPortStatus() { - return clusterPortStatus; + public AllowableValueDTO getAllowableValue() { + return allowableValue; } - public void setClusterPortStatus(ClusterPortStatusDTO clusterPortStatus) { - this.clusterPortStatus = clusterPortStatus; + public void setAllowableValue(AllowableValueDTO allowableValue) { + this.allowableValue = allowableValue; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java index 86aa1ee892..6e4b25c52f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java @@ -28,7 +28,7 @@ import java.util.List; * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds a reference to a ConnectionDTO. */ @XmlRootElement(name = "connectionEntity") -public class ConnectionEntity extends ComponentEntity { +public class ConnectionEntity extends ComponentEntity implements Permissible { private ConnectionDTO component; private ConnectionStatusDTO status; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java index 8b623310a7..cb1be91e0d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.web.api.entity; +import org.apache.nifi.web.api.dto.ReadablePermission; import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import javax.xml.bind.annotation.XmlRootElement; @@ -24,9 +25,10 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ConnectionStatusDTO. */ @XmlRootElement(name = "connectionStatusEntity") -public class ConnectionStatusEntity extends Entity { +public class ConnectionStatusEntity extends Entity implements ReadablePermission { private ConnectionStatusDTO connectionStatus; + private Boolean canRead; /** * The ConnectionStatusDTO that is being serialized. @@ -41,4 +43,13 @@ public class ConnectionStatusEntity extends Entity { this.connectionStatus = connectionStatus; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusSnapshotEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusSnapshotEntity.java new file mode 100644 index 0000000000..9e1374ad4b --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusSnapshotEntity.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.ReadablePermission; +import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ConnectionStatusSnapshotDTO. + */ +public class ConnectionStatusSnapshotEntity extends Entity implements ReadablePermission, Cloneable { + private String id; + private ConnectionStatusSnapshotDTO connectionStatusSnapshot; + private Boolean canRead; + + /** + * @return The connection id + */ + @ApiModelProperty("The id of the connection.") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * The ConnectionStatusSnapshotDTO that is being serialized. + * + * @return The ConnectionStatusSnapshotDTO object + */ + public ConnectionStatusSnapshotDTO getConnectionStatusSnapshot() { + return connectionStatusSnapshot; + } + + public void setConnectionStatusSnapshot(ConnectionStatusSnapshotDTO connectionStatusSnapshot) { + this.connectionStatusSnapshot = connectionStatusSnapshot; + } + + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } + + @Override + public ConnectionStatusSnapshotEntity clone() { + final ConnectionStatusSnapshotEntity other = new ConnectionStatusSnapshotEntity(); + other.setCanRead(this.getCanRead()); + other.setConnectionStatusSnapshot(this.getConnectionStatusSnapshot().clone()); + + return other; + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java index c7aa0cd5da..fe0708dc43 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java @@ -30,7 +30,7 @@ import java.util.Date; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ControllerConfigurationDTO. */ @XmlRootElement(name = "controllerConfigurationEntity") -public class ControllerConfigurationEntity extends Entity { +public class ControllerConfigurationEntity extends Entity implements Permissible { private Date currentTime; private ControllerConfigurationDTO controllerConfiguration; @@ -63,11 +63,11 @@ public class ControllerConfigurationEntity extends Entity { @ApiModelProperty( value = "The controller configuration." ) - public ControllerConfigurationDTO getControllerConfiguration() { + public ControllerConfigurationDTO getComponent() { return controllerConfiguration; } - public void setControllerConfiguration(ControllerConfigurationDTO controllerConfiguration) { + public void setComponent(ControllerConfigurationDTO controllerConfiguration) { this.controllerConfiguration = controllerConfiguration; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerServiceEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerServiceEntity.java index bd7284310f..c9c3be318f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerServiceEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerServiceEntity.java @@ -23,7 +23,7 @@ import org.apache.nifi.web.api.dto.ControllerServiceDTO; * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds a reference to a controller service. */ @XmlRootElement(name = "controllerServiceEntity") -public class ControllerServiceEntity extends ComponentEntity { +public class ControllerServiceEntity extends ComponentEntity implements Permissible { private ControllerServiceDTO component; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FunnelEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FunnelEntity.java index 54ff2ed7ae..da40bbd5a8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FunnelEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FunnelEntity.java @@ -23,7 +23,7 @@ import org.apache.nifi.web.api.dto.FunnelDTO; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a FunnelDTO. */ @XmlRootElement(name = "funnelEntity") -public class FunnelEntity extends ComponentEntity { +public class FunnelEntity extends ComponentEntity implements Permissible { private FunnelDTO component; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LabelEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LabelEntity.java index 48e2aa7c79..4cc9d3e33f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LabelEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/LabelEntity.java @@ -25,7 +25,7 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a LabelDTO. */ @XmlRootElement(name = "labelEntity") -public class LabelEntity extends ComponentEntity { +public class LabelEntity extends ComponentEntity implements Permissible { private DimensionsDTO dimensions; private LabelDTO component; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/Permissible.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/Permissible.java new file mode 100644 index 0000000000..04c56adb89 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/Permissible.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import org.apache.nifi.web.api.dto.PermissionsDTO; + +/** + * Provides access to a component given an {@link org.apache.nifi.web.api.dto.PermissionsDTO}. This is intended to be used by classes that extend {@link Entity}. + * @param type of component + */ +public interface Permissible { + + PermissionsDTO getPermissions(); + + void setPermissions(PermissionsDTO permissions); + + DtoType getComponent(); + + void setComponent(DtoType dto); +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortEntity.java index 1594664b90..ff77979497 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortEntity.java @@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds a reference to an input PortDTO. */ @XmlRootElement(name = "portEntity") -public class PortEntity extends ComponentEntity { +public class PortEntity extends ComponentEntity implements Permissible { private PortDTO component; private PortStatusDTO status; @@ -35,10 +35,12 @@ public class PortEntity extends ComponentEntity { /** * @return input PortDTO that are being serialized */ + @Override public PortDTO getComponent() { return component; } + @Override public void setComponent(PortDTO component) { this.component = component; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java index e0b49c498f..4672400171 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.web.api.entity; +import org.apache.nifi.web.api.dto.ReadablePermission; import org.apache.nifi.web.api.dto.status.PortStatusDTO; import javax.xml.bind.annotation.XmlRootElement; @@ -24,9 +25,10 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a PortStatusDTO. */ @XmlRootElement(name = "portStatusEntity") -public class PortStatusEntity extends Entity { +public class PortStatusEntity extends Entity implements ReadablePermission { private PortStatusDTO portStatus; + private Boolean canRead; /** * The PortStatusDTO that is being serialized. @@ -41,4 +43,13 @@ public class PortStatusEntity extends Entity { this.portStatus = portStatus; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusSnapshotEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusSnapshotEntity.java new file mode 100644 index 0000000000..d44fab4ecb --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusSnapshotEntity.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.ReadablePermission; +import org.apache.nifi.web.api.dto.status.PortStatusSnapshotDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a + * PortStatusSnapshotDTO. + */ +public class PortStatusSnapshotEntity extends Entity implements ReadablePermission { + private String id; + private PortStatusSnapshotDTO portStatusSnapshot; + private Boolean canRead; + + /** + * @return The port id + */ + @ApiModelProperty("The id of the port.") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * The PortStatusSnapshotDTO that is being serialized. + * + * @return The PortStatusSnapshotDTO object + */ + public PortStatusSnapshotDTO getPortStatusSnapshot() { + return portStatusSnapshot; + } + + public void setPortStatusSnapshot(PortStatusSnapshotDTO portStatusSnapshot) { + this.portStatusSnapshot = portStatusSnapshot; + } + + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } + + @Override + public PortStatusSnapshotEntity clone() { + final PortStatusSnapshotEntity other = new PortStatusSnapshotEntity(); + other.setCanRead(this.getCanRead()); + other.setPortStatusSnapshot(this.getPortStatusSnapshot().clone()); + + return other; + } +} 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 7cc30d7d04..93bcee1c90 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 @@ -29,7 +29,7 @@ import java.util.Date; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessGroupDTO. */ @XmlRootElement(name = "processGroupEntity") -public class ProcessGroupEntity extends ComponentEntity { +public class ProcessGroupEntity extends ComponentEntity implements Permissible { private ProcessGroupDTO component; private ProcessGroupStatusDTO status; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusEntity.java index d7d857f3a1..f380ca9270 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusEntity.java @@ -17,15 +17,18 @@ package org.apache.nifi.web.api.entity; import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.nifi.web.api.dto.ReadablePermission; import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; /** * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessGroupStatusDTO. */ @XmlRootElement(name = "processGroupStatusEntity") -public class ProcessGroupStatusEntity extends Entity { +public class ProcessGroupStatusEntity extends Entity implements ReadablePermission { private ProcessGroupStatusDTO processGroupStatus; + private Boolean canRead; /** * The ProcessGroupStatusDTO that is being serialized. @@ -40,4 +43,13 @@ public class ProcessGroupStatusEntity extends Entity { this.processGroupStatus = processGroupStatus; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusSnapshotEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusSnapshotEntity.java new file mode 100644 index 0000000000..6434b326fd --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupStatusSnapshotEntity.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.ReadablePermission; +import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessGroupStatusSnapshotDTO. + */ +public class ProcessGroupStatusSnapshotEntity extends Entity implements ReadablePermission, Cloneable { + private String id; + private ProcessGroupStatusSnapshotDTO processGroupStatusSnapshot; + private Boolean canRead; + + /** + * @return The process group id + */ + @ApiModelProperty("The id of the process group.") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * The ProcessGroupStatusSnapshotDTO that is being serialized. + * + * @return The ProcessGroupStatusSnapshotDTO object + */ + public ProcessGroupStatusSnapshotDTO getProcessGroupStatusSnapshot() { + return processGroupStatusSnapshot; + } + + public void setProcessGroupStatusSnapshot(ProcessGroupStatusSnapshotDTO processGroupStatusSnapshot) { + this.processGroupStatusSnapshot = processGroupStatusSnapshot; + } + + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } + + @Override + public ProcessGroupStatusSnapshotEntity clone() { + final ProcessGroupStatusSnapshotEntity other = new ProcessGroupStatusSnapshotEntity(); + other.setCanRead(this.getCanRead()); + other.setProcessGroupStatusSnapshot(this.getProcessGroupStatusSnapshot().clone()); + + return other; + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java index cda843cf6d..bfea1b5333 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java @@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessorDTO. */ @XmlRootElement(name = "processorEntity") -public class ProcessorEntity extends ComponentEntity { +public class ProcessorEntity extends ComponentEntity implements Permissible { private ProcessorDTO component; private String inputRequirement; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java index 0c2170cb8b..30e5a5728f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.web.api.entity; +import org.apache.nifi.web.api.dto.ReadablePermission; import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; import javax.xml.bind.annotation.XmlRootElement; @@ -24,9 +25,10 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessorStatusDTO. */ @XmlRootElement(name = "processorStatusEntity") -public class ProcessorStatusEntity extends Entity { +public class ProcessorStatusEntity extends Entity implements ReadablePermission { private ProcessorStatusDTO processorStatus; + private Boolean canRead; /** * The ProcessorStatusDTO that is being serialized. @@ -41,4 +43,13 @@ public class ProcessorStatusEntity extends Entity { this.processorStatus = processorStatus; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusSnapshotEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusSnapshotEntity.java new file mode 100644 index 0000000000..57b8636304 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusSnapshotEntity.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.ReadablePermission; +import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessorStatusSnapshotDTO. + */ +public class ProcessorStatusSnapshotEntity extends Entity implements ReadablePermission { + private String id; + private ProcessorStatusSnapshotDTO processorStatusSnapshot; + private Boolean canRead; + + /** + * @return The processor id + */ + @ApiModelProperty("The id of the processor.") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * The ProcessorStatusSnapshotDTO that is being serialized. + * + * @return The ProcessorStatusSnapshotDTO object + */ + public ProcessorStatusSnapshotDTO getProcessorStatusSnapshot() { + return processorStatusSnapshot; + } + + public void setProcessorStatusSnapshot(ProcessorStatusSnapshotDTO processorStatusSnapshot) { + this.processorStatusSnapshot = processorStatusSnapshot; + } + + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } + + @Override + public ProcessorStatusSnapshotEntity clone() { + final ProcessorStatusSnapshotEntity other = new ProcessorStatusSnapshotEntity(); + other.setCanRead(this.getCanRead()); + other.setProcessorStatusSnapshot(this.getProcessorStatusSnapshot().clone()); + + return other; + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupEntity.java index 84f13f22f3..ee44c27486 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupEntity.java @@ -26,7 +26,7 @@ import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a RemoteProcessGroupDTO. */ @XmlRootElement(name = "remoteProcessGroupEntity") -public class RemoteProcessGroupEntity extends ComponentEntity { +public class RemoteProcessGroupEntity extends ComponentEntity implements Permissible { private RemoteProcessGroupDTO component; private RemoteProcessGroupStatusDTO status; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java index a5031ab1a8..3520d029ad 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.web.api.entity; +import org.apache.nifi.web.api.dto.ReadablePermission; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import javax.xml.bind.annotation.XmlRootElement; @@ -24,9 +25,10 @@ import javax.xml.bind.annotation.XmlRootElement; * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a RemoteProcessGroupStatusDTO. */ @XmlRootElement(name = "remoteProcessGroupStatusEntity") -public class RemoteProcessGroupStatusEntity extends Entity { +public class RemoteProcessGroupStatusEntity extends Entity implements ReadablePermission { private RemoteProcessGroupStatusDTO remoteProcessGroupStatus; + private Boolean canRead; /** * The RemoteProcessGroupStatusDTO that is being serialized. @@ -41,4 +43,13 @@ public class RemoteProcessGroupStatusEntity extends Entity { this.remoteProcessGroupStatus = remoteProcessGroupStatus; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusSnapshotEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusSnapshotEntity.java new file mode 100644 index 0000000000..fe3f54706a --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusSnapshotEntity.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.ReadablePermission; +import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a + * RemoteProcessGroupStatusSnapshotDTO. + */ +public class RemoteProcessGroupStatusSnapshotEntity extends Entity implements ReadablePermission { + private String id; + private RemoteProcessGroupStatusSnapshotDTO remoteProcessGroupStatusSnapshot; + private Boolean canRead; + + /** + * @return The remote process group id + */ + @ApiModelProperty("The id of the remote processo group.") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * The RemoteProcessGroupStatusSnapshotDTO that is being serialized. + * + * @return The RemoteProcessGroupStatusSnapshotDTO object + */ + public RemoteProcessGroupStatusSnapshotDTO getRemoteProcessGroupStatusSnapshot() { + return remoteProcessGroupStatusSnapshot; + } + + public void setRemoteProcessGroupStatusSnapshot(RemoteProcessGroupStatusSnapshotDTO remoteProcessGroupStatusSnapshot) { + this.remoteProcessGroupStatusSnapshot = remoteProcessGroupStatusSnapshot; + } + + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } + + @Override + public RemoteProcessGroupStatusSnapshotEntity clone() { + final RemoteProcessGroupStatusSnapshotEntity other = new RemoteProcessGroupStatusSnapshotEntity(); + other.setCanRead(this.getCanRead()); + other.setRemoteProcessGroupStatusSnapshot(this.getRemoteProcessGroupStatusSnapshot().clone()); + + return other; + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ReportingTaskEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ReportingTaskEntity.java index e58de14f40..a7bf6b3763 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ReportingTaskEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ReportingTaskEntity.java @@ -24,17 +24,19 @@ import org.apache.nifi.web.api.dto.ReportingTaskDTO; * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds a reference to a reporting task. */ @XmlRootElement(name = "reportingTaskEntity") -public class ReportingTaskEntity extends ComponentEntity { +public class ReportingTaskEntity extends ComponentEntity implements Permissible { private ReportingTaskDTO component; /** * @return reporting task that is being serialized */ + @Override public ReportingTaskDTO getComponent() { return component; } + @Override public void setComponent(ReportingTaskDTO component) { this.component = component; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/StatusHistoryEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/StatusHistoryEntity.java index 98891ffb25..96c0a3080c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/StatusHistoryEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/StatusHistoryEntity.java @@ -16,16 +16,19 @@ */ package org.apache.nifi.web.api.entity; -import javax.xml.bind.annotation.XmlRootElement; +import org.apache.nifi.web.api.dto.ReadablePermission; import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; +import javax.xml.bind.annotation.XmlRootElement; + /** * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a StatusHistoryDTO. */ @XmlRootElement(name = "statusHistoryEntity") -public class StatusHistoryEntity extends Entity { +public class StatusHistoryEntity extends Entity implements ReadablePermission { private StatusHistoryDTO statusHistory; + private Boolean canRead; /** * The StatusHistoryDTO that is being serialized. @@ -40,4 +43,13 @@ public class StatusHistoryEntity extends Entity { this.statusHistory = statusHistory; } + @Override + public Boolean getCanRead() { + return canRead; + } + + @Override + public void setCanRead(Boolean canRead) { + this.canRead = canRead; + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml index 79b8d6d20f..2acae8f041 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml @@ -151,7 +151,18 @@ testng test - + + + + org.spockframework + spock-core + test + + + cglib + cglib-nodep + test + diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java index f5e7d98a6e..784eb2f7a8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java @@ -23,6 +23,7 @@ import org.apache.nifi.cluster.coordination.http.endpoints.ConnectionEndpointMer import org.apache.nifi.cluster.coordination.http.endpoints.ConnectionStatusEndpiontMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ConnectionsEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ControllerBulletinsEndpointMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.ControllerConfigurationEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceReferenceEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServicesEndpointMerger; @@ -33,8 +34,12 @@ import org.apache.nifi.cluster.coordination.http.endpoints.DropRequestEndpiontMe import org.apache.nifi.cluster.coordination.http.endpoints.FlowConfigurationEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.FlowMerger; import org.apache.nifi.cluster.coordination.http.endpoints.FlowSnippetEndpointMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.FunnelEndpointMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.FunnelsEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.GroupStatusEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.InputPortsEndpointMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.LabelEndpointMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.LabelsEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ListFlowFilesEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.OutputPortsEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.PortEndpointMerger; @@ -107,9 +112,14 @@ public class StandardHttpResponseMerger implements HttpResponseMerger { endpointMergers.add(new SystemDiagnosticsEndpointMerger()); endpointMergers.add(new CountersEndpointMerger()); endpointMergers.add(new FlowMerger()); + endpointMergers.add(new ControllerConfigurationEndpointMerger()); endpointMergers.add(new CurrentUserEndpointMerger()); endpointMergers.add(new FlowConfigurationEndpointMerger()); endpointMergers.add(new TemplatesEndpointMerger()); + endpointMergers.add(new LabelEndpointMerger()); + endpointMergers.add(new LabelsEndpointMerger()); + endpointMergers.add(new FunnelEndpointMerger()); + endpointMergers.add(new FunnelsEndpointMerger()); } public StandardHttpResponseMerger() { @@ -141,10 +151,17 @@ public class StandardHttpResponseMerger implements HttpResponseMerger { final Set successResponses = nodeResponses.stream().filter(p -> p.is2xx()).collect(Collectors.toSet()); final Set problematicResponses = nodeResponses.stream().filter(p -> !p.is2xx()).collect(Collectors.toSet()); - // Choose any of the successful responses to be the 'chosen one'. - final NodeResponse clientResponse = successResponses.iterator().next(); - - final EndpointResponseMerger merger = getEndpointResponseMerger(uri, httpMethod); + final NodeResponse clientResponse; + if ("GET".equalsIgnoreCase(httpMethod) && problematicResponses.size() > 0) { + // If there are problematic responses, at least one of the nodes couldn't complete the request + clientResponse = problematicResponses.stream().filter(p -> p.getStatus() >= 400 && p.getStatus() < 500).findFirst().orElse( + problematicResponses.stream().filter(p -> p.getStatus() > 500).findFirst().orElse(problematicResponses.iterator().next())); + return clientResponse; + } else { + // Choose any of the successful responses to be the 'chosen one'. + clientResponse = successResponses.iterator().next(); + } + EndpointResponseMerger merger = getEndpointResponseMerger(uri, httpMethod); if (merger == null) { return clientResponse; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/AbstractMultiEntityEndpoint.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/AbstractMultiEntityEndpoint.java deleted file mode 100644 index d72814b94b..0000000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/AbstractMultiEntityEndpoint.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.nifi.cluster.coordination.http.endpoints; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.nifi.cluster.coordination.http.EndpointResponseMerger; -import org.apache.nifi.cluster.manager.NodeResponse; -import org.apache.nifi.cluster.protocol.NodeIdentifier; -import org.apache.nifi.web.api.entity.Entity; - -public abstract class AbstractMultiEntityEndpoint implements EndpointResponseMerger { - - @Override - public final NodeResponse merge(final URI uri, final String method, final Set successfulResponses, final Set problematicResponses, final NodeResponse clientResponse) { - if (!canHandle(uri, method)) { - throw new IllegalArgumentException("Cannot use Endpoint Mapper of type " + getClass().getSimpleName() + " to map responses for URI " + uri + ", HTTP Method " + method); - } - - final EntityType responseEntity = clientResponse.getClientResponse().getEntity(getEntityClass()); - final Set dtos = getDtos(responseEntity); - - final Map> dtoMap = new HashMap<>(); - for (final NodeResponse nodeResponse : successfulResponses) { - final EntityType nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(getEntityClass()); - final Set nodeDtos = getDtos(nodeResponseEntity); - - for (final DtoType nodeDto : nodeDtos) { - final NodeIdentifier nodeId = nodeResponse.getNodeId(); - Map innerMap = dtoMap.get(nodeId); - if (innerMap == null) { - innerMap = new HashMap<>(); - dtoMap.put(getComponentId(nodeDto), innerMap); - } - - innerMap.put(nodeResponse.getNodeId(), nodeDto); - } - } - - for (final DtoType dto : dtos) { - final String componentId = getComponentId(dto); - final Map mergeMap = dtoMap.get(componentId); - - mergeResponses(dto, mergeMap, successfulResponses, problematicResponses); - } - - // create a new client response - return new NodeResponse(clientResponse, responseEntity); - } - - - /** - * @return the class that represents the type of Entity that is expected by this response mapper - */ - protected abstract Class getEntityClass(); - - /** - * Extracts the DTOs from the given entity - * - * @param entity the entity to extract the DTOs from - * @return the DTOs from the given entity - */ - protected abstract Set getDtos(EntityType entity); - - /** - * Extracts the ID of the component that the DTO refers to - * @param dto the DTO to extract the ID from - * @return the ID of the component that the DTO refers to - */ - protected abstract String getComponentId(DtoType dto); - - /** - * Merges the responses from all nodes in the given map into the single given DTO - * - * @param clientDto the DTO to merge responses into - * @param dtoMap the responses from all nodes - * @param successfulResponses the responses from nodes that completed the request successfully - * @param problematicResponses the responses from nodes that did not complete the request successfully - */ - protected abstract void mergeResponses(final DtoType clientDto, Map dtoMap, Set successfulResponses, Set problematicResponses); -} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionEndpointMerger.java index 30c6f77007..a8dca2ec01 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionEndpointMerger.java @@ -29,14 +29,15 @@ import java.util.Set; import java.util.regex.Pattern; public class ConnectionEndpointMerger extends AbstractSingleEntityEndpoint implements EndpointResponseMerger { - public static final Pattern PROCESSORS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/connections"); - public static final Pattern PROCESSOR_URI_PATTERN = Pattern.compile("/nifi-api/connections/[a-f0-9\\-]{36}"); + public static final Pattern CONNECTIONS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/connections"); + public static final Pattern CONNECTION_URI_PATTERN = Pattern.compile("/nifi-api/connections/[a-f0-9\\-]{36}"); + private final ConnectionEntityMerger connectionEntityMerger = new ConnectionEntityMerger(); @Override public boolean canHandle(final URI uri, final String method) { - if (("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && (PROCESSOR_URI_PATTERN.matcher(uri.getPath()).matches())) { + if (("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && (CONNECTION_URI_PATTERN.matcher(uri.getPath()).matches())) { return true; - } else if ("POST".equalsIgnoreCase(method) && PROCESSORS_URI_PATTERN.matcher(uri.getPath()).matches()) { + } else if ("POST".equalsIgnoreCase(method) && CONNECTIONS_URI_PATTERN.matcher(uri.getPath()).matches()) { return true; } @@ -48,11 +49,10 @@ public class ConnectionEndpointMerger extends AbstractSingleEntityEndpoint entityMap, final Set successfulResponses, final Set problematicResponses) { - ConnectionEntityMerger.mergeConnections(clientEntity, entityMap); + connectionEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionStatusEndpiontMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionStatusEndpiontMerger.java index 05bf0f52d3..ab700dc0be 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionStatusEndpiontMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionStatusEndpiontMerger.java @@ -17,18 +17,21 @@ package org.apache.nifi.cluster.coordination.http.endpoints; -import java.net.URI; -import java.util.ArrayList; -import java.util.Map; -import java.util.regex.Pattern; - +import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger; +import org.apache.nifi.cluster.manager.NodeResponse; import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import org.apache.nifi.web.api.dto.status.NodeConnectionStatusSnapshotDTO; import org.apache.nifi.web.api.entity.ConnectionStatusEntity; -public class ConnectionStatusEndpiontMerger extends AbstractNodeStatusEndpoint { +import java.net.URI; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class ConnectionStatusEndpiontMerger extends AbstractSingleEntityEndpoint implements ComponentEntityStatusMerger { public static final Pattern CONNECTION_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/connections/[a-f0-9\\-]{36}/status"); @Override @@ -42,17 +45,19 @@ public class ConnectionStatusEndpiontMerger extends AbstractNodeStatusEndpoint entityMap, Set successfulResponses, + Set problematicResponses) { + final ConnectionStatusDTO mergedConnectionStatus = clientEntity.getConnectionStatus(); + mergedConnectionStatus.setNodeSnapshots(new ArrayList<>()); - @Override - protected void mergeResponses(ConnectionStatusDTO clientDto, Map dtoMap, NodeIdentifier selectedNodeId) { - final ConnectionStatusDTO mergedConnectionStatus = clientDto; - mergedConnectionStatus.setNodeSnapshots(new ArrayList()); + final NodeIdentifier selectedNodeId = entityMap.entrySet().stream() + .filter(e -> e.getValue() == clientEntity) + .map(e -> e.getKey()) + .findFirst() + .orElse(null); final NodeConnectionStatusSnapshotDTO selectedNodeSnapshot = new NodeConnectionStatusSnapshotDTO(); - selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); + selectedNodeSnapshot.setStatusSnapshot(mergedConnectionStatus.getAggregateSnapshot().clone()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); @@ -60,15 +65,22 @@ public class ConnectionStatusEndpiontMerger extends AbstractNodeStatusEndpoint entry : dtoMap.entrySet()) { + for (final Map.Entry entry : entityMap.entrySet()) { final NodeIdentifier nodeId = entry.getKey(); - final ConnectionStatusDTO nodeConnectionStatus = entry.getValue(); - if (nodeConnectionStatus == clientDto) { + final ConnectionStatusEntity nodeConnectionStatusEntity = entry.getValue(); + final ConnectionStatusDTO nodeConnectionStatus = nodeConnectionStatusEntity.getConnectionStatus(); + if (nodeConnectionStatus == mergedConnectionStatus) { continue; } - StatusMerger.merge(mergedConnectionStatus, nodeConnectionStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + mergeStatus(mergedConnectionStatus, clientEntity.getCanRead(), nodeConnectionStatus, nodeConnectionStatusEntity.getCanRead(), nodeId); } } + @Override + public void mergeStatus(ConnectionStatusDTO clientStatus, boolean clientStatusReadablePermission, ConnectionStatusDTO status, boolean statusReadablePermission, + NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionsEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionsEndpointMerger.java index 661350d519..07104f4981 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionsEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ConnectionsEndpointMerger.java @@ -53,11 +53,11 @@ public class ConnectionsEndpointMerger implements EndpointResponseMerger { final Set nodeConnectionEntities = nodeResponseEntity.getConnections(); for (final ConnectionEntity nodeConnectionEntity : nodeConnectionEntities) { - final NodeIdentifier nodeId = nodeResponse.getNodeId(); - Map innerMap = entityMap.get(nodeId); + final String nodeConnectionEntityId = nodeConnectionEntity.getId(); + Map innerMap = entityMap.get(nodeConnectionEntityId); if (innerMap == null) { innerMap = new HashMap<>(); - entityMap.put(nodeConnectionEntity.getId(), innerMap); + entityMap.put(nodeConnectionEntityId, innerMap); } innerMap.put(nodeResponse.getNodeId(), nodeConnectionEntity); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerConfigurationEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerConfigurationEndpointMerger.java new file mode 100644 index 0000000000..4e7af172e2 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerConfigurationEndpointMerger.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.coordination.http.endpoints.AbstractSingleEntityEndpoint; +import org.apache.nifi.cluster.manager.NodeResponse; +import org.apache.nifi.cluster.manager.PermissionsDtoMerger; +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; + +import java.net.URI; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class ControllerConfigurationEndpointMerger extends AbstractSingleEntityEndpoint { + public static final Pattern CONTROLLER_CONFIGURATION_URI_PATTERN = Pattern.compile("/nifi-api/controller/config"); + + @Override + protected Class getEntityClass() { + return ControllerConfigurationEntity.class; + } + + @Override + protected void mergeResponses(ControllerConfigurationEntity clientEntity, Map entityMap, Set successfulResponses, + Set problematicResponses) { + entityMap.values().stream().forEach(controllerConfigurationDTO -> PermissionsDtoMerger.mergePermissions(clientEntity.getPermissions(), controllerConfigurationDTO.getPermissions())); + if (!clientEntity.getPermissions().getCanRead() && clientEntity.getComponent() != null) { + clientEntity.setComponent(null); + } + } + + @Override + public boolean canHandle(URI uri, String method) { + return ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && CONTROLLER_CONFIGURATION_URI_PATTERN.matcher(uri.getPath()).matches(); + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerServiceEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerServiceEndpointMerger.java index 879d3b533f..65714f3df6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerServiceEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ControllerServiceEndpointMerger.java @@ -32,6 +32,7 @@ public class ControllerServiceEndpointMerger extends AbstractSingleEntityEndpoin public static final String CONTROLLER_CONTROLLER_SERVICES_URI = "/nifi-api/controller/controller-services"; public static final Pattern PROCESS_GROUPS_CONTROLLER_SERVICES_URI = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/controller-services"); public static final Pattern CONTROLLER_SERVICE_URI_PATTERN = Pattern.compile("/nifi-api/controller-services/[a-f0-9\\-]{36}"); + private final ControllerServiceEntityMerger controllerServiceEntityMerger = new ControllerServiceEntityMerger(); @Override public boolean canHandle(URI uri, String method) { @@ -53,6 +54,6 @@ public class ControllerServiceEndpointMerger extends AbstractSingleEntityEndpoin protected void mergeResponses(ControllerServiceEntity clientEntity, Map entityMap, Set successfulResponses, Set problematicResponses) { - ControllerServiceEntityMerger.mergeControllerServices(clientEntity, entityMap); + controllerServiceEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CountersEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CountersEndpointMerger.java index 22b82b3f31..c3bc156e3e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CountersEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CountersEndpointMerger.java @@ -29,7 +29,7 @@ import org.apache.nifi.web.api.dto.NodeCountersSnapshotDTO; import org.apache.nifi.web.api.entity.CountersEntity; public class CountersEndpointMerger extends AbstractNodeStatusEndpoint { - public static final Pattern COUNTERS_URI_PATTERN = Pattern.compile("/nifi-api/controller/counters"); + public static final Pattern COUNTERS_URI_PATTERN = Pattern.compile("/nifi-api/counters"); @Override public boolean canHandle(URI uri, String method) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowMerger.java index 0cbf2135a3..ad15fa1269 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowMerger.java @@ -18,6 +18,8 @@ package org.apache.nifi.cluster.coordination.http.endpoints; import org.apache.nifi.cluster.manager.ConnectionsEntityMerger; +import org.apache.nifi.cluster.manager.FunnelsEntityMerger; +import org.apache.nifi.cluster.manager.LabelsEntityMerger; import org.apache.nifi.cluster.manager.NodeResponse; import org.apache.nifi.cluster.manager.PortsEntityMerger; import org.apache.nifi.cluster.manager.ProcessGroupsEntityMerger; @@ -36,10 +38,7 @@ import org.apache.nifi.web.api.entity.ProcessorEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import java.net.URI; -import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -73,11 +72,13 @@ public class FlowMerger extends AbstractSingleDTOEndpoint clientOutputPorts = flowDto.getOutputPorts(); final Set clientRemoteProcessGroups = flowDto.getRemoteProcessGroups(); final Set clientProcessGroups = flowDto.getProcessGroups(); + final Set clientLabels = flowDto.getLabels(); + final Set clientFunnels = flowDto.getFunnels(); final Map> connections = new HashMap<>(); - final Map> funnels = new HashMap<>(); + final Map> funnels = new HashMap<>(); final Map> inputPorts = new HashMap<>(); - final Map> labels = new HashMap<>(); + final Map> labels = new HashMap<>(); final Map> outputPorts = new HashMap<>(); final Map> processors = new HashMap<>(); final Map> rpgs = new HashMap<>(); @@ -95,7 +96,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint new ArrayList<>()).add(entity); + funnels.computeIfAbsent(entity.getId(), id -> new HashMap<>()).computeIfAbsent(nodeIdentifier, nodeId -> entity); } for (final PortEntity entity : nodeFlowDto.getInputPorts()) { @@ -107,7 +108,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint new ArrayList<>()).add(entity); + labels.computeIfAbsent(entity.getId(), id -> new HashMap<>()).computeIfAbsent(nodeIdentifier, nodeId -> entity); } for (final ProcessorEntity entity : nodeFlowDto.getProcessors()) { @@ -131,11 +132,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint mergedFunnels = new HashSet<>(); - for (final List funnelList : funnels.values()) { - mergedFunnels.add(mergeFunnels(funnelList)); - } - flowDto.setFunnels(mergedFunnels); + FunnelsEntityMerger.mergeFunnels(clientFunnels, funnels); // Merge input ports PortsEntityMerger.mergePorts(clientInputPorts, inputPorts); @@ -144,11 +141,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint mergedLabels = new HashSet<>(); - for (final List labelList : labels.values()) { - mergedLabels.add(mergeLabels(labelList)); - } - flowDto.setLabels(mergedLabels); + LabelsEntityMerger.mergeLabels(clientLabels, labels); // Merge processors ProcessorsEntityMerger.mergeProcessors(clientProcessors, processors); @@ -159,12 +152,4 @@ public class FlowMerger extends AbstractSingleDTOEndpoint funnels) { - return funnels.get(0); - } - - private LabelEntity mergeLabels(final List labels) { - return labels.get(0); - } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelEndpointMerger.java new file mode 100644 index 0000000000..1e9af9631b --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelEndpointMerger.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.manager.FunnelEntityMerger; +import org.apache.nifi.cluster.manager.NodeResponse; +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.FunnelEntity; + +import java.net.URI; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class FunnelEndpointMerger extends AbstractSingleEntityEndpoint { + public static final Pattern FUNNELS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/funnels"); + public static final Pattern FUNNEL_URI_PATTERN = Pattern.compile("/nifi-api/funnels/[a-f0-9\\-]{36}"); + + final private FunnelEntityMerger funnelEntityMerger = new FunnelEntityMerger(); + + @Override + protected Class getEntityClass() { + return FunnelEntity.class; + } + + @Override + protected void mergeResponses(FunnelEntity clientEntity, Map entityMap, Set successfulResponses, Set problematicResponses) { + funnelEntityMerger.merge(clientEntity, entityMap); + } + + @Override + public boolean canHandle(URI uri, String method) { + if (("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && (FUNNEL_URI_PATTERN.matcher(uri.getPath()).matches())) { + return true; + } else if ("POST".equalsIgnoreCase(method) && FUNNELS_URI_PATTERN.matcher(uri.getPath()).matches()) { + return true; + } + + return false; + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelsEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelsEndpointMerger.java new file mode 100644 index 0000000000..bbe394f842 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FunnelsEndpointMerger.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.coordination.http.EndpointResponseMerger; +import org.apache.nifi.cluster.manager.FunnelsEntityMerger; +import org.apache.nifi.cluster.manager.NodeResponse; +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.FunnelEntity; +import org.apache.nifi.web.api.entity.FunnelsEntity; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class FunnelsEndpointMerger implements EndpointResponseMerger { + public static final Pattern FUNNELS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/funnels"); + + @Override + public boolean canHandle(URI uri, String method) { + return "GET".equalsIgnoreCase(method) && FUNNELS_URI_PATTERN.matcher(uri.getPath()).matches(); + } + + @Override + public NodeResponse merge(URI uri, String method, Set successfulResponses, Set problematicResponses, NodeResponse clientResponse) { + if (!canHandle(uri, method)) { + throw new IllegalArgumentException("Cannot use Endpoint Mapper of type " + getClass().getSimpleName() + " to map responses for URI " + uri + ", HTTP Method " + method); + } + + final FunnelsEntity responseEntity = clientResponse.getClientResponse().getEntity(FunnelsEntity.class); + final Set funnelEntities = responseEntity.getFunnels(); + + final Map> entityMap = new HashMap<>(); + for (final NodeResponse nodeResponse : successfulResponses) { + final FunnelsEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(FunnelsEntity.class); + final Set nodeFunnelEntities = nodeResponseEntity.getFunnels(); + + for (final FunnelEntity nodeFunnelEntity : nodeFunnelEntities) { + final String nodeFunnelEntityId = nodeFunnelEntity.getId(); + Map innerMap = entityMap.get(nodeFunnelEntityId); + if (innerMap == null) { + innerMap = new HashMap<>(); + entityMap.put(nodeFunnelEntityId, innerMap); + } + + innerMap.put(nodeResponse.getNodeId(), nodeFunnelEntity); + } + } + + FunnelsEntityMerger.mergeFunnels(funnelEntities, entityMap); + + // create a new client response + return new NodeResponse(clientResponse, responseEntity); + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java index 88239028ae..106f6140e0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java @@ -17,6 +17,8 @@ package org.apache.nifi.cluster.coordination.http.endpoints; +import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger; +import org.apache.nifi.cluster.manager.NodeResponse; import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO; @@ -26,9 +28,10 @@ import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import java.net.URI; import java.util.ArrayList; import java.util.Map; +import java.util.Set; import java.util.regex.Pattern; -public class GroupStatusEndpointMerger extends AbstractNodeStatusEndpoint { +public class GroupStatusEndpointMerger extends AbstractSingleEntityEndpoint implements ComponentEntityStatusMerger { public static final Pattern GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/status"); @Override @@ -42,32 +45,41 @@ public class GroupStatusEndpointMerger extends AbstractNodeStatusEndpoint entityMap, Set successfulResponses, + Set problematicResponses) { + final ProcessGroupStatusDTO mergedProcessGroupStatus = clientEntity.getProcessGroupStatus(); + mergedProcessGroupStatus.setNodeSnapshots(new ArrayList<>()); - @Override - protected void mergeResponses(ProcessGroupStatusDTO clientDto, Map dtoMap, NodeIdentifier selectedNodeId) { - final ProcessGroupStatusDTO mergedProcessGroupStatus = clientDto; - mergedProcessGroupStatus.setNodeSnapshots(new ArrayList()); + final NodeIdentifier selectedNodeId = entityMap.entrySet().stream() + .filter(e -> e.getValue() == clientEntity) + .map(e -> e.getKey()) + .findFirst() + .orElse(null); final NodeProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessGroupStatusSnapshotDTO(); - selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); + selectedNodeSnapshot.setStatusSnapshot(mergedProcessGroupStatus.getAggregateSnapshot().clone()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); mergedProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot); - for (final Map.Entry entry : dtoMap.entrySet()) { + for (final Map.Entry entry : entityMap.entrySet()) { final NodeIdentifier nodeId = entry.getKey(); - final ProcessGroupStatusDTO nodeProcessGroupStatus = entry.getValue(); + final ProcessGroupStatusEntity nodeProcessGroupStatusEntity = entry.getValue(); + final ProcessGroupStatusDTO nodeProcessGroupStatus = nodeProcessGroupStatusEntity.getProcessGroupStatus(); if (nodeProcessGroupStatus == mergedProcessGroupStatus) { continue; } - StatusMerger.merge(mergedProcessGroupStatus, nodeProcessGroupStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + mergeStatus(mergedProcessGroupStatus, clientEntity.getCanRead(), nodeProcessGroupStatus, nodeProcessGroupStatusEntity.getCanRead(), nodeId); } } + @Override + public void mergeStatus(ProcessGroupStatusDTO clientStatus, boolean clientStatusReadablePermission, ProcessGroupStatusDTO status, boolean statusReadablePermission, + NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelEndpointMerger.java new file mode 100644 index 0000000000..7bd9e0fcc5 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelEndpointMerger.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.manager.LabelEntityMerger; +import org.apache.nifi.cluster.manager.NodeResponse; +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.LabelEntity; + +import java.net.URI; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class LabelEndpointMerger extends AbstractSingleEntityEndpoint { + public static final Pattern LABELS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/labels"); + public static final Pattern LABEL_URI_PATTERN = Pattern.compile("/nifi-api/labels/[a-f0-9\\-]{36}"); + + final private LabelEntityMerger labelEntityMerger = new LabelEntityMerger(); + + @Override + protected Class getEntityClass() { + return LabelEntity.class; + } + + @Override + protected void mergeResponses(LabelEntity clientEntity, Map entityMap, Set successfulResponses, Set problematicResponses) { + labelEntityMerger.merge(clientEntity, entityMap); + } + + @Override + public boolean canHandle(URI uri, String method) { + if (("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && (LABEL_URI_PATTERN.matcher(uri.getPath()).matches())) { + return true; + } else if ("POST".equalsIgnoreCase(method) && LABELS_URI_PATTERN.matcher(uri.getPath()).matches()) { + return true; + } + + return false; + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelsEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelsEndpointMerger.java new file mode 100644 index 0000000000..48574cdbc9 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/LabelsEndpointMerger.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.coordination.http.EndpointResponseMerger; +import org.apache.nifi.cluster.manager.LabelsEntityMerger; +import org.apache.nifi.cluster.manager.NodeResponse; +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.LabelEntity; +import org.apache.nifi.web.api.entity.LabelsEntity; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class LabelsEndpointMerger implements EndpointResponseMerger { + public static final Pattern LABELS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/labels"); + + @Override + public boolean canHandle(URI uri, String method) { + return "GET".equalsIgnoreCase(method) && LABELS_URI_PATTERN.matcher(uri.getPath()).matches(); + } + + @Override + public NodeResponse merge(URI uri, String method, Set successfulResponses, Set problematicResponses, NodeResponse clientResponse) { + if (!canHandle(uri, method)) { + throw new IllegalArgumentException("Cannot use Endpoint Mapper of type " + getClass().getSimpleName() + " to map responses for URI " + uri + ", HTTP Method " + method); + } + + final LabelsEntity responseEntity = clientResponse.getClientResponse().getEntity(LabelsEntity.class); + final Set labelEntities = responseEntity.getLabels(); + + final Map> entityMap = new HashMap<>(); + for (final NodeResponse nodeResponse : successfulResponses) { + final LabelsEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(LabelsEntity.class); + final Set nodeLabelEntities = nodeResponseEntity.getLabels(); + + for (final LabelEntity nodeLabelEntity : nodeLabelEntities) { + final String nodeLabelEntityId = nodeLabelEntity.getId(); + Map innerMap = entityMap.get(nodeLabelEntityId); + if (innerMap == null) { + innerMap = new HashMap<>(); + entityMap.put(nodeLabelEntityId, innerMap); + } + + innerMap.put(nodeResponse.getNodeId(), nodeLabelEntity); + } + } + + LabelsEntityMerger.mergeLabels(labelEntities, entityMap); + + // create a new client response + return new NodeResponse(clientResponse, responseEntity); + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortEndpointMerger.java index 8ea63843a3..33843ae162 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortEndpointMerger.java @@ -34,6 +34,7 @@ public class PortEndpointMerger extends AbstractSingleEntityEndpoint public static final Pattern OUTPUT_PORTS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/output-ports"); public static final Pattern OUTPUT_PORT_URI_PATTERN = Pattern.compile("/nifi-api/output-ports/[a-f0-9\\-]{36}"); + private final PortEntityMerger portEntityMerger = new PortEntityMerger(); @Override public boolean canHandle(final URI uri, final String method) { @@ -65,11 +66,10 @@ public class PortEndpointMerger extends AbstractSingleEntityEndpoint return PortEntity.class; } - @Override protected void mergeResponses(final PortEntity clientEntity, final Map entityMap, final Set successfulResponses, final Set problematicResponses) { - PortEntityMerger.mergePorts(clientEntity, entityMap); + portEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortStatusEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortStatusEndpointMerger.java index 5c570f0c6c..ac5d4790ae 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortStatusEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/PortStatusEndpointMerger.java @@ -17,18 +17,21 @@ package org.apache.nifi.cluster.coordination.http.endpoints; -import java.net.URI; -import java.util.ArrayList; -import java.util.Map; -import java.util.regex.Pattern; - +import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger; +import org.apache.nifi.cluster.manager.NodeResponse; import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.status.NodePortStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.PortStatusDTO; import org.apache.nifi.web.api.entity.PortStatusEntity; -public class PortStatusEndpointMerger extends AbstractNodeStatusEndpoint { +import java.net.URI; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class PortStatusEndpointMerger extends AbstractSingleEntityEndpoint implements ComponentEntityStatusMerger { public static final Pattern INPUT_PORT_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/input-ports/[a-f0-9\\-]{36}/status"); public static final Pattern OUTPUT_PORT_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/output-ports/[a-f0-9\\-]{36}/status"); @@ -43,17 +46,21 @@ public class PortStatusEndpointMerger extends AbstractNodeStatusEndpoint entityMap, Set successfulResponses, Set problematicResponses) { + final PortStatusDTO mergedPortStatus = clientEntity.getPortStatus(); + mergedPortStatus.setNodeSnapshots(new ArrayList<>()); - @Override - protected void mergeResponses(PortStatusDTO clientDto, Map dtoMap, NodeIdentifier selectedNodeId) { - final PortStatusDTO mergedPortStatus = clientDto; - mergedPortStatus.setNodeSnapshots(new ArrayList()); + final NodeIdentifier selectedNodeId = entityMap.entrySet().stream() + .filter(e -> e.getValue() == clientEntity) + .map(e -> e.getKey()) + .findFirst() + .orElse(null); + if (selectedNodeId == null) { + throw new IllegalArgumentException("Attempted to merge Status request but could not find the appropriate Node Identifier"); + } final NodePortStatusSnapshotDTO selectedNodeSnapshot = new NodePortStatusSnapshotDTO(); - selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); + selectedNodeSnapshot.setStatusSnapshot(mergedPortStatus.getAggregateSnapshot().clone()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); @@ -61,15 +68,22 @@ public class PortStatusEndpointMerger extends AbstractNodeStatusEndpoint entry : dtoMap.entrySet()) { + for (final Map.Entry entry : entityMap.entrySet()) { final NodeIdentifier nodeId = entry.getKey(); - final PortStatusDTO nodePortStatus = entry.getValue(); - if (nodePortStatus == clientDto) { + final PortStatusEntity nodePortStatusEntity = entry.getValue(); + final PortStatusDTO nodePortStatus = nodePortStatusEntity.getPortStatus(); + if (nodePortStatus == mergedPortStatus) { continue; } - StatusMerger.merge(mergedPortStatus, nodePortStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + mergeStatus(mergedPortStatus, clientEntity.getCanRead(), nodePortStatus, nodePortStatusEntity.getCanRead(), nodeId); } } + @Override + public void mergeStatus(PortStatusDTO clientStatus, boolean clientStatusReadablePermission, PortStatusDTO status, boolean statusReadablePermission, + NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessGroupEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessGroupEndpointMerger.java index 6b9b080d35..4bd7dfd33d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessGroupEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessGroupEndpointMerger.java @@ -30,10 +30,17 @@ import java.util.regex.Pattern; public class ProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint implements EndpointResponseMerger { public static final Pattern PROCESS_GROUP_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))"); + public static final Pattern CONTROLLER_ARCHIVE_URI_PATTERN = Pattern.compile("/nifi-api/controller/archive"); + private ProcessGroupEntityMerger processGroupEntityMerger = new ProcessGroupEntityMerger(); @Override public boolean canHandle(final URI uri, final String method) { - return ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && PROCESS_GROUP_URI_PATTERN.matcher(uri.getPath()).matches(); + if ("GET".equalsIgnoreCase(method) && (PROCESS_GROUP_URI_PATTERN.matcher(uri.getPath()).matches() || CONTROLLER_ARCHIVE_URI_PATTERN.matcher(uri.getPath()).matches())) { + return true; + } else if ("PUT".equalsIgnoreCase(method) && PROCESS_GROUP_URI_PATTERN.matcher(uri.getPath()).matches()) { + return true; + } + return false; } @Override @@ -43,6 +50,6 @@ public class ProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint entityMap, Set successfulResponses, Set problematicResponses) { - ProcessGroupEntityMerger.mergeProcessGroups(clientEntity, entityMap); + processGroupEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorEndpointMerger.java index b8202c8609..747cc12ebe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorEndpointMerger.java @@ -31,6 +31,7 @@ import java.util.regex.Pattern; public class ProcessorEndpointMerger extends AbstractSingleEntityEndpoint implements EndpointResponseMerger { public static final Pattern PROCESSORS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/processors"); public static final Pattern PROCESSOR_URI_PATTERN = Pattern.compile("/nifi-api/processors/[a-f0-9\\-]{36}"); + private final ProcessorEntityMerger processorEntityMerger = new ProcessorEntityMerger(); @Override public boolean canHandle(final URI uri, final String method) { @@ -48,11 +49,10 @@ public class ProcessorEndpointMerger extends AbstractSingleEntityEndpoint entityMap, final Set successfulResponses, final Set problematicResponses) { - ProcessorEntityMerger.mergeProcessors(clientEntity, entityMap); + processorEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorStatusEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorStatusEndpointMerger.java index 8fdceb1de6..63758e26b6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorStatusEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ProcessorStatusEndpointMerger.java @@ -17,18 +17,21 @@ package org.apache.nifi.cluster.coordination.http.endpoints; -import java.net.URI; -import java.util.ArrayList; -import java.util.Map; -import java.util.regex.Pattern; - +import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger; +import org.apache.nifi.cluster.manager.NodeResponse; import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.status.NodeProcessorStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; import org.apache.nifi.web.api.entity.ProcessorStatusEntity; -public class ProcessorStatusEndpointMerger extends AbstractNodeStatusEndpoint { +import java.net.URI; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class ProcessorStatusEndpointMerger extends AbstractSingleEntityEndpoint implements ComponentEntityStatusMerger { public static final Pattern PROCESSOR_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/processors/[a-f0-9\\-]{36}/status"); @Override @@ -42,17 +45,19 @@ public class ProcessorStatusEndpointMerger extends AbstractNodeStatusEndpoint entityMap, Set successfulResponses, + Set problematicResponses) { + final ProcessorStatusDTO mergedProcessorStatus = clientEntity.getProcessorStatus(); + mergedProcessorStatus.setNodeSnapshots(new ArrayList<>()); - @Override - protected void mergeResponses(ProcessorStatusDTO clientDto, Map dtoMap, NodeIdentifier selectedNodeId) { - final ProcessorStatusDTO mergedProcessorStatus = clientDto; - mergedProcessorStatus.setNodeSnapshots(new ArrayList()); + final NodeIdentifier selectedNodeId = entityMap.entrySet().stream() + .filter(e -> e.getValue() == clientEntity) + .map(e -> e.getKey()) + .findFirst() + .orElse(null); final NodeProcessorStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessorStatusSnapshotDTO(); - selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); + selectedNodeSnapshot.setStatusSnapshot(mergedProcessorStatus.getAggregateSnapshot().clone()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); @@ -60,15 +65,21 @@ public class ProcessorStatusEndpointMerger extends AbstractNodeStatusEndpoint entry : dtoMap.entrySet()) { + for (final Map.Entry entry : entityMap.entrySet()) { final NodeIdentifier nodeId = entry.getKey(); - final ProcessorStatusDTO nodeProcessorStatus = entry.getValue(); - if (nodeProcessorStatus == clientDto) { + final ProcessorStatusEntity nodeProcessorStatusEntity = entry.getValue(); + final ProcessorStatusDTO nodeProcessorStatus = nodeProcessorStatusEntity.getProcessorStatus(); + if (nodeProcessorStatus == mergedProcessorStatus) { continue; } - StatusMerger.merge(mergedProcessorStatus, nodeProcessorStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + mergeStatus(mergedProcessorStatus, clientEntity.getCanRead(), nodeProcessorStatus, nodeProcessorStatusEntity.getCanRead(), nodeId); } } + @Override + public void mergeStatus(ProcessorStatusDTO clientStatus, boolean clientStatusReadablePermission, ProcessorStatusDTO status, boolean statusReadablePermission, NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupEndpointMerger.java index e130e5ec28..e32c2533c4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupEndpointMerger.java @@ -31,6 +31,7 @@ import java.util.regex.Pattern; public class RemoteProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint implements EndpointResponseMerger { public static final Pattern REMOTE_PROCESS_GROUPS_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/remote-process-groups"); public static final Pattern REMOTE_PROCESS_GROUP_URI_PATTERN = Pattern.compile("/nifi-api/remote-process-groups/[a-f0-9\\-]{36}"); + private final RemoteProcessGroupEntityMerger remoteProcessGroupEntityMerger = new RemoteProcessGroupEntityMerger(); @Override public boolean canHandle(final URI uri, final String method) { @@ -52,6 +53,6 @@ public class RemoteProcessGroupEndpointMerger extends AbstractSingleEntityEndpoi protected void mergeResponses(RemoteProcessGroupEntity clientEntity, Map entityMap, Set successfulResponses, Set problematicResponses) { - RemoteProcessGroupEntityMerger.mergeRemoteProcessGroups(clientEntity, entityMap); + remoteProcessGroupEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupStatusEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupStatusEndpointMerger.java index d2056f7b56..3f49c590b4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupStatusEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/RemoteProcessGroupStatusEndpointMerger.java @@ -17,18 +17,21 @@ package org.apache.nifi.cluster.coordination.http.endpoints; -import java.net.URI; -import java.util.ArrayList; -import java.util.Map; -import java.util.regex.Pattern; - +import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger; +import org.apache.nifi.cluster.manager.NodeResponse; import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.status.NodeRemoteProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; -public class RemoteProcessGroupStatusEndpointMerger extends AbstractNodeStatusEndpoint { +import java.net.URI; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class RemoteProcessGroupStatusEndpointMerger extends AbstractSingleEntityEndpoint implements ComponentEntityStatusMerger { public static final Pattern REMOTE_PROCESS_GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/remote-process-groups/[a-f0-9\\-]{36}/status"); @Override @@ -42,17 +45,19 @@ public class RemoteProcessGroupStatusEndpointMerger extends AbstractNodeStatusEn } @Override - protected RemoteProcessGroupStatusDTO getDto(RemoteProcessGroupStatusEntity entity) { - return entity.getRemoteProcessGroupStatus(); - } + protected void mergeResponses(RemoteProcessGroupStatusEntity clientEntity, Map entityMap, Set successfulResponses, + Set problematicResponses) { + final RemoteProcessGroupStatusDTO mergedRemoteProcessGroupStatus = clientEntity.getRemoteProcessGroupStatus(); + mergedRemoteProcessGroupStatus.setNodeSnapshots(new ArrayList<>()); - @Override - protected void mergeResponses(RemoteProcessGroupStatusDTO clientDto, Map dtoMap, NodeIdentifier selectedNodeId) { - final RemoteProcessGroupStatusDTO mergedRemoteProcessGroupStatus = clientDto; - mergedRemoteProcessGroupStatus.setNodeSnapshots(new ArrayList()); + final NodeIdentifier selectedNodeId = entityMap.entrySet().stream() + .filter(e -> e.getValue() == clientEntity) + .map(e -> e.getKey()) + .findFirst() + .orElse(null); final NodeRemoteProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO(); - selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); + selectedNodeSnapshot.setStatusSnapshot(mergedRemoteProcessGroupStatus.getAggregateSnapshot().clone()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); @@ -60,15 +65,22 @@ public class RemoteProcessGroupStatusEndpointMerger extends AbstractNodeStatusEn mergedRemoteProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot); // merge the other nodes - for (final Map.Entry entry : dtoMap.entrySet()) { + for (final Map.Entry entry : entityMap.entrySet()) { final NodeIdentifier nodeId = entry.getKey(); - final RemoteProcessGroupStatusDTO nodeRemoteProcessGroupStatus = entry.getValue(); - if (nodeRemoteProcessGroupStatus == clientDto) { + final RemoteProcessGroupStatusEntity nodeRemoteProcessGroupStatusEntity = entry.getValue(); + final RemoteProcessGroupStatusDTO nodeRemoteProcessGroupStatus = nodeRemoteProcessGroupStatusEntity.getRemoteProcessGroupStatus(); + if (nodeRemoteProcessGroupStatus == mergedRemoteProcessGroupStatus) { continue; } - StatusMerger.merge(mergedRemoteProcessGroupStatus, nodeRemoteProcessGroupStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + mergeStatus(mergedRemoteProcessGroupStatus, clientEntity.getCanRead(), nodeRemoteProcessGroupStatus, nodeRemoteProcessGroupStatusEntity.getCanRead(), nodeId); } } + @Override + public void mergeStatus(RemoteProcessGroupStatusDTO clientStatus, boolean clientStatusReadablePermission, RemoteProcessGroupStatusDTO status, boolean statusReadablePermission, + NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ReportingTaskEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ReportingTaskEndpointMerger.java index b3a7cccd5b..d17459d5bf 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ReportingTaskEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/ReportingTaskEndpointMerger.java @@ -31,6 +31,7 @@ import java.util.regex.Pattern; public class ReportingTaskEndpointMerger extends AbstractSingleEntityEndpoint implements EndpointResponseMerger { public static final String REPORTING_TASKS_URI = "/nifi-api/controller/reporting-tasks"; public static final Pattern REPORTING_TASK_URI_PATTERN = Pattern.compile("/nifi-api/reporting-tasks/[a-f0-9\\-]{36}"); + private final ReportingTaskEntityMerger reportingTaskEntityMerger = new ReportingTaskEntityMerger(); @Override public boolean canHandle(URI uri, String method) { @@ -50,6 +51,6 @@ public class ReportingTaskEndpointMerger extends AbstractSingleEntityEndpoint entityMap, Set successfulResponses, Set problematicResponses) { - ReportingTaskEntityMerger.mergeReportingTasks(clientEntity, entityMap); + reportingTaskEntityMerger.merge(clientEntity, entityMap); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMerger.java index 8d782e92d1..507c1fb9ad 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMerger.java @@ -21,6 +21,7 @@ import java.net.URI; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -111,10 +112,15 @@ public class StatusHistoryEndpointMerger implements EndpointResponseMerger { StatusHistoryDTO lastStatusHistory = null; final List nodeStatusSnapshots = new ArrayList<>(successfulResponses.size()); + LinkedHashMap noReadPermissionsComponentDetails = null; for (final NodeResponse nodeResponse : successfulResponses) { final StatusHistoryEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(StatusHistoryEntity.class); final StatusHistoryDTO nodeStatus = nodeResponseEntity.getStatusHistory(); lastStatusHistory = nodeStatus; + if (noReadPermissionsComponentDetails == null && !nodeResponseEntity.getCanRead()) { + // If component details from a history with no read permissions is encountered for the first time, hold on to them to be used in the merged response + noReadPermissionsComponentDetails = nodeStatus.getComponentDetails(); + } final NodeIdentifier nodeId = nodeResponse.getNodeId(); final NodeStatusSnapshotsDTO nodeStatusSnapshot = new NodeStatusSnapshotsDTO(); @@ -130,12 +136,13 @@ public class StatusHistoryEndpointMerger implements EndpointResponseMerger { clusterStatusHistory.setGenerated(new Date()); clusterStatusHistory.setNodeSnapshots(nodeStatusSnapshots); if (lastStatusHistory != null) { - clusterStatusHistory.setComponentDetails(lastStatusHistory.getComponentDetails()); + clusterStatusHistory.setComponentDetails(noReadPermissionsComponentDetails == null ? lastStatusHistory.getComponentDetails() : noReadPermissionsComponentDetails); clusterStatusHistory.setFieldDescriptors(lastStatusHistory.getFieldDescriptors()); } final StatusHistoryEntity clusterEntity = new StatusHistoryEntity(); clusterEntity.setStatusHistory(clusterStatusHistory); + clusterEntity.setCanRead(noReadPermissionsComponentDetails == null); return new NodeResponse(clientResponse, clusterEntity); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityMerger.java index 580ba87469..f01c1beb8e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityMerger.java @@ -19,6 +19,7 @@ package org.apache.nifi.cluster.manager; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.BulletinDTO; import org.apache.nifi.web.api.entity.ComponentEntity; +import org.apache.nifi.web.api.entity.Permissible; import java.util.ArrayList; import java.util.Collections; @@ -29,35 +30,57 @@ import java.util.Map; import static org.apache.nifi.cluster.manager.BulletinMerger.BULLETIN_COMPARATOR; import static org.apache.nifi.reporting.BulletinRepository.MAX_BULLETINS_PER_COMPONENT; -public class ComponentEntityMerger { +public interface ComponentEntityMerger { /** - * Merges the ComponentEntity responses. + * Merges the ComponentEntity responses according to their {@link org.apache.nifi.web.api.dto.PermissionsDTO}s. Responsible for invoking + * {@link ComponentEntityMerger#mergeComponents(EntityType, Map)}. * * @param clientEntity the entity being returned to the client - * @param entityMap all node responses + * @param entityMap all node responses */ - public static void mergeComponents(final ComponentEntity clientEntity, final Map entityMap) { - final Map> bulletinDtos = new HashMap<>(); - for (final Map.Entry entry : entityMap.entrySet()) { - final NodeIdentifier nodeIdentifier = entry.getKey(); - final ComponentEntity entity = entry.getValue(); - - // consider the bulletins if present and authorized - if (entity.getBulletins() != null) { - entity.getBulletins().forEach(bulletin -> { - bulletinDtos.computeIfAbsent(nodeIdentifier, nodeId -> new ArrayList<>()).add(bulletin); - }); - } + @SuppressWarnings("unchecked") + default void merge(final EntityType clientEntity, final Map entityMap) { + for (final Map.Entry entry : entityMap.entrySet()) { + final EntityType entity = entry.getValue(); + PermissionsDtoMerger.mergePermissions(clientEntity.getPermissions(), entity.getPermissions()); } - clientEntity.setBulletins(BulletinMerger.mergeBulletins(bulletinDtos)); - // sort the results - Collections.sort(clientEntity.getBulletins(), BULLETIN_COMPARATOR); + if (clientEntity.getPermissions().getCanRead()) { + final Map> bulletinDtos = new HashMap<>(); + for (final Map.Entry entry : entityMap.entrySet()) { + final NodeIdentifier nodeIdentifier = entry.getKey(); + final ComponentEntity entity = entry.getValue(); - // prune the response to only include the max number of bulletins - if (clientEntity.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) { - clientEntity.setBulletins(clientEntity.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT)); + // consider the bulletins if present and authorized + if (entity.getBulletins() != null) { + entity.getBulletins().forEach(bulletin -> { + bulletinDtos.computeIfAbsent(nodeIdentifier, nodeId -> new ArrayList<>()).add(bulletin); + }); + } + } + clientEntity.setBulletins(BulletinMerger.mergeBulletins(bulletinDtos)); + + // sort the results + Collections.sort(clientEntity.getBulletins(), BULLETIN_COMPARATOR); + + // prune the response to only include the max number of bulletins + if (clientEntity.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) { + clientEntity.setBulletins(clientEntity.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT)); + } + + mergeComponents(clientEntity, entityMap); + } else { + clientEntity.setBulletins(null); + clientEntity.setComponent(null); // unchecked warning suppressed } } + + /** + * Performs the merging of the entities. This method should not be called directly, it will be called by {@link ComponentEntityMerger#merge}. + * @param clientEntity the entity being returned to the client + * @param entityMap all node responses + */ + default void mergeComponents(final EntityType clientEntity, final Map entityMap) { + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityStatusMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityStatusMerger.java new file mode 100644 index 0000000000..0ed1e8a596 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ComponentEntityStatusMerger.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager; + +import org.apache.nifi.cluster.protocol.NodeIdentifier; + +public interface ComponentEntityStatusMerger { + + /** + * Merges status into clientStatus based on the given permissions. + * + * @param clientStatus The status that will be returned to the client after merging + * @param clientStatusReadablePermission The read permission of the status that will be returned to the client after merging + * @param status The status to be merged into the client status + * @param statusReadablePermission The read permission of the status to be merged into the client status + * @param statusNodeIdentifier The {@link NodeIdentifier} of the node from which status was received + */ + void mergeStatus(final StatusDtoType clientStatus, final boolean clientStatusReadablePermission, final StatusDtoType status, + final boolean statusReadablePermission, final NodeIdentifier statusNodeIdentifier); + +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionEntityMerger.java index 75dea4c7fc..89ac179534 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionEntityMerger.java @@ -17,25 +17,29 @@ package org.apache.nifi.cluster.manager; import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import org.apache.nifi.web.api.entity.ConnectionEntity; import java.util.Map; -public class ConnectionEntityMerger { +public class ConnectionEntityMerger implements ComponentEntityMerger, ComponentEntityStatusMerger { - /** - * Merges the ConnectionEntity responses. - * - * @param clientEntity the entity being returned to the client - * @param entityMap all node responses - */ - public static void mergeConnections(final ConnectionEntity clientEntity, final Map entityMap) { - for (final Map.Entry entry : entityMap.entrySet()) { + @Override + public void merge(ConnectionEntity clientEntity, Map entityMap) { + ComponentEntityMerger.super.merge(clientEntity, entityMap); + for (Map.Entry entry : entityMap.entrySet()) { final NodeIdentifier nodeId = entry.getKey(); - final ConnectionEntity entity = entry.getValue(); - if (entity != clientEntity) { - StatusMerger.merge(clientEntity.getStatus(), entity.getStatus(), nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + final ConnectionEntity entityStatus = entry.getValue(); + if (entityStatus != clientEntity) { + mergeStatus(clientEntity.getStatus(), clientEntity.getPermissions().getCanRead(), entry.getValue().getStatus(), entry.getValue().getPermissions().getCanRead(), entry.getKey()); } } } + + @Override + public void mergeStatus(ConnectionStatusDTO clientStatus, boolean clientStatusReadablePermission, ConnectionStatusDTO status, boolean statusReadablePermission, + NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionsEntityMerger.java index 42a93505ba..dafa3af42f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionsEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ConnectionsEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class ConnectionsEntityMerger { + private static final ConnectionEntityMerger connectionEntityMerger = new ConnectionEntityMerger(); + /** * Merges multiple ConnectionEntity responses. * @@ -32,7 +34,7 @@ public class ConnectionsEntityMerger { */ public static void mergeConnections(final Set connectionEntities, final Map> entityMap) { for (final ConnectionEntity entity : connectionEntities) { - ConnectionEntityMerger.mergeConnections(entity, entityMap.get(entity.getId())); + connectionEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMerger.java index 8c9f0c8855..02d8e7e61c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMerger.java @@ -20,6 +20,7 @@ import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.web.api.dto.ControllerServiceDTO; import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO; +import org.apache.nifi.web.api.dto.PermissionsDTO; import org.apache.nifi.web.api.entity.ControllerServiceEntity; import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity; @@ -27,15 +28,16 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -public class ControllerServiceEntityMerger { +public class ControllerServiceEntityMerger implements ComponentEntityMerger { /** * Merges the ControllerServiceEntity responses. * * @param clientEntity the entity being returned to the client - * @param entityMap all node responses + * @param entityMap all node responses */ - public static void mergeControllerServices(final ControllerServiceEntity clientEntity, final Map entityMap) { + @Override + public void mergeComponents(final ControllerServiceEntity clientEntity, final Map entityMap) { final ControllerServiceDTO clientDto = clientEntity.getComponent(); final Map dtoMap = new HashMap<>(); for (final Map.Entry entry : entityMap.entrySet()) { @@ -44,8 +46,6 @@ public class ControllerServiceEntityMerger { dtoMap.put(entry.getKey(), nodeControllerServiceDto); } - ComponentEntityMerger.mergeComponents(clientEntity, entityMap); - mergeDtos(clientDto, dtoMap); } @@ -99,6 +99,7 @@ public class ControllerServiceEntityMerger { final Map activeThreadCounts = new HashMap<>(); final Map states = new HashMap<>(); + final Map canReads = new HashMap<>(); for (final Map.Entry> nodeEntry : referencingComponentMap.entrySet()) { final Set nodeReferencingComponents = nodeEntry.getValue(); @@ -126,6 +127,17 @@ public class ControllerServiceEntityMerger { states.put(nodeReferencingComponent.getId(), ControllerServiceState.ENABLING.name()); } } + + // handle read permissions + final PermissionsDTO mergedPermissions = canReads.get(nodeReferencingComponent.getId()); + final PermissionsDTO permissions = nodeReferencingComponentEntity.getPermissions(); + if (permissions != null) { + if (mergedPermissions == null) { + canReads.put(nodeReferencingComponent.getId(), permissions); + } else { + PermissionsDtoMerger.mergePermissions(mergedPermissions, permissions); + } + } } } } @@ -133,14 +145,20 @@ public class ControllerServiceEntityMerger { // go through each referencing components if (referencingComponents != null) { for (final ControllerServiceReferencingComponentEntity referencingComponent : referencingComponents) { - final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId()); - if (activeThreadCount != null) { - referencingComponent.getComponent().setActiveThreadCount(activeThreadCount); - } + final PermissionsDTO permissions = canReads.get(referencingComponent.getId()); + if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) { + final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId()); + if (activeThreadCount != null) { + referencingComponent.getComponent().setActiveThreadCount(activeThreadCount); + } - final String state = states.get(referencingComponent.getId()); - if (state != null) { - referencingComponent.getComponent().setState(state); + final String state = states.get(referencingComponent.getId()); + if (state != null) { + referencingComponent.getComponent().setState(state); + } + } else { + referencingComponent.setPermissions(permissions); + referencingComponent.setComponent(null); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServicesEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServicesEntityMerger.java index ca97af6f02..cfaabf75cb 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServicesEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ControllerServicesEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class ControllerServicesEntityMerger { + private static final ControllerServiceEntityMerger controllerServiceEntityMerger = new ControllerServiceEntityMerger(); + /** * Merges multiple ControllerServiceEntity responses. * @@ -32,7 +34,7 @@ public class ControllerServicesEntityMerger { */ public static void mergeControllerServices(final Set controllerServiceEntities, final Map> entityMap) { for (final ControllerServiceEntity entity : controllerServiceEntities) { - ControllerServiceEntityMerger.mergeControllerServices(entity, entityMap.get(entity.getId())); + controllerServiceEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelEntityMerger.java new file mode 100644 index 0000000000..51402cb8c2 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelEntityMerger.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager; + +import org.apache.nifi.web.api.entity.FunnelEntity; + +public class FunnelEntityMerger implements ComponentEntityMerger { + // No specific merging needs to be done beyond what the ComponentEntityMerger does by default +} \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelsEntityMerger.java new file mode 100644 index 0000000000..2b5db3dfdd --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/FunnelsEntityMerger.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager; + +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.FunnelEntity; + +import java.util.Map; +import java.util.Set; + +public class FunnelsEntityMerger { + private static final FunnelEntityMerger funnelEntityMerger = new FunnelEntityMerger(); + + /** + * Merges multiple {@link FunnelEntity} responses. + * + * @param funnelEntities entities being returned to the client + * @param entityMap all node responses + */ + public static void mergeFunnels(final Set funnelEntities, final Map> entityMap) { + for (final FunnelEntity entity : funnelEntities) { + funnelEntityMerger.merge(entity, entityMap.get(entity.getId())); + } + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelEntityMerger.java new file mode 100644 index 0000000000..aae472651a --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelEntityMerger.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager; + +import org.apache.nifi.web.api.entity.LabelEntity; + +public class LabelEntityMerger implements ComponentEntityMerger { + // No specific merging needs to be done beyond what the ComponentEntityMerger does by default +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelsEntityMerger.java new file mode 100644 index 0000000000..4015d20121 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/LabelsEntityMerger.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager; + +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.entity.LabelEntity; + +import java.util.Map; +import java.util.Set; + +public class LabelsEntityMerger { + private static final LabelEntityMerger labelEntityMerger = new LabelEntityMerger(); + + /** + * Merges multiple {@link LabelEntity} responses. + * + * @param labelEntities entities being returned to the client + * @param entityMap all node responses + */ + public static void mergeLabels(final Set labelEntities, final Map> entityMap) { + for (final LabelEntity entity : labelEntities) { + labelEntityMerger.merge(entity, entityMap.get(entity.getId())); + } + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PermissionsDtoMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PermissionsDtoMerger.java new file mode 100644 index 0000000000..688a5941a4 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PermissionsDtoMerger.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager; + +import org.apache.nifi.web.api.dto.PermissionsDTO; + +public class PermissionsDtoMerger { + + /** + * Merges multiple {@link PermissionsDTO}s. + * + * @param mergedEntityPermissions the {@link PermissionsDTO} representing the merged permissions + * @param entityPermissions an {@link PermissionsDTO} to be merged + */ + public static void mergePermissions(PermissionsDTO mergedEntityPermissions, PermissionsDTO entityPermissions) { + if (mergedEntityPermissions.getCanRead() && !entityPermissions.getCanRead()) { + mergedEntityPermissions.setCanRead(false); + } + if (mergedEntityPermissions.getCanWrite() && !entityPermissions.getCanWrite()) { + mergedEntityPermissions.setCanWrite(false); + } + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortEntityMerger.java index 37c922fb11..cd73084f04 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortEntityMerger.java @@ -18,13 +18,26 @@ package org.apache.nifi.cluster.manager; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.PortDTO; +import org.apache.nifi.web.api.dto.status.PortStatusDTO; import org.apache.nifi.web.api.entity.PortEntity; import java.util.HashMap; import java.util.Map; import java.util.Set; -public class PortEntityMerger { +public class PortEntityMerger implements ComponentEntityMerger, ComponentEntityStatusMerger { + + @Override + public void merge(PortEntity clientEntity, Map entityMap) { + ComponentEntityMerger.super.merge(clientEntity, entityMap); + for (Map.Entry entry : entityMap.entrySet()) { + final NodeIdentifier nodeId = entry.getKey(); + final PortEntity entityStatus = entry.getValue(); + if (entityStatus != clientEntity) { + mergeStatus(clientEntity.getStatus(), clientEntity.getPermissions().getCanRead(), entry.getValue().getStatus(), entry.getValue().getPermissions().getCanRead(), entry.getKey()); + } + } + } /** * Merges the PortEntity responses. @@ -32,7 +45,8 @@ public class PortEntityMerger { * @param clientEntity the entity being returned to the client * @param entityMap all node responses */ - public static void mergePorts(final PortEntity clientEntity, final Map entityMap) { + @Override + public void mergeComponents(PortEntity clientEntity, Map entityMap) { final PortDTO clientDto = clientEntity.getComponent(); final Map dtoMap = new HashMap<>(); for (final Map.Entry entry : entityMap.entrySet()) { @@ -41,19 +55,16 @@ public class PortEntityMerger { dtoMap.put(entry.getKey(), nodePortDto); } - for (final Map.Entry entry : entityMap.entrySet()) { - final NodeIdentifier nodeId = entry.getKey(); - final PortEntity entity = entry.getValue(); - if (entity != clientEntity) { - StatusMerger.merge(clientEntity.getStatus(), entity.getStatus(), nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); - } - } - - ComponentEntityMerger.mergeComponents(clientEntity, entityMap); - mergeDtos(clientDto, dtoMap); } + @Override + public void mergeStatus(PortStatusDTO clientStatus, boolean clientStatusReadablePermission, PortStatusDTO status, boolean statusReadablePermission, NodeIdentifier + statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } + private static void mergeDtos(final PortDTO clientDto, final Map dtoMap) { // if unauthorized for the client dto, simple return if (clientDto == null) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortsEntityMerger.java index 894ce5b02f..a72132cdf8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortsEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/PortsEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class PortsEntityMerger { + private static final PortEntityMerger portEntityMerger = new PortEntityMerger(); + /** * Merges multiple PortEntity responses. * @@ -32,7 +34,7 @@ public class PortsEntityMerger { */ public static void mergePorts(final Set portEntities, final Map> entityMap) { for (final PortEntity entity : portEntities) { - PortEntityMerger.mergePorts(entity, entityMap.get(entity.getId())); + portEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupEntityMerger.java index a9a1b40505..67278a7bb6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupEntityMerger.java @@ -17,27 +17,28 @@ package org.apache.nifi.cluster.manager; import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; import org.apache.nifi.web.api.entity.ProcessGroupEntity; import java.util.Map; -public class ProcessGroupEntityMerger { +public class ProcessGroupEntityMerger implements ComponentEntityMerger, ComponentEntityStatusMerger { - /** - * Merges the ProcessorGroupEntity responses. - * - * @param clientEntity the entity being returned to the client - * @param entityMap all node responses - */ - public static void mergeProcessGroups(final ProcessGroupEntity clientEntity, final Map entityMap) { - for (final Map.Entry entry : entityMap.entrySet()) { - final NodeIdentifier nodeId = entry.getKey(); - final ProcessGroupEntity entity = entry.getValue(); - if (entity != clientEntity) { - StatusMerger.merge(clientEntity.getStatus(), entity.getStatus(), nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); + @Override + public void merge(ProcessGroupEntity clientEntity, Map entityMap) { + ComponentEntityMerger.super.merge(clientEntity, entityMap); + for (Map.Entry entry : entityMap.entrySet()) { + final ProcessGroupEntity entityStatus = entry.getValue(); + if (entityStatus != clientEntity) { + mergeStatus(clientEntity.getStatus(), clientEntity.getPermissions().getCanRead(), entry.getValue().getStatus(), entry.getValue().getPermissions().getCanRead(), entry.getKey()); } } + } - ComponentEntityMerger.mergeComponents(clientEntity, entityMap); + @Override + public void mergeStatus(ProcessGroupStatusDTO clientStatus, boolean clientStatusReadablePermission, ProcessGroupStatusDTO status, boolean statusReadablePermission, + NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupsEntityMerger.java index 6a0e519f03..26134877f1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupsEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessGroupsEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class ProcessGroupsEntityMerger { + private static final ProcessGroupEntityMerger processGroupEntityMerger = new ProcessGroupEntityMerger(); + /** * Merges multiple ProcessGroupEntity responses. * @@ -32,7 +34,7 @@ public class ProcessGroupsEntityMerger { */ public static void mergeProcessGroups(final Set processGroupEntities, final Map> entityMap) { for (final ProcessGroupEntity entity : processGroupEntities) { - ProcessGroupEntityMerger.mergeProcessGroups(entity, entityMap.get(entity.getId())); + processGroupEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorEntityMerger.java index e730791e20..f3dbf1b396 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorEntityMerger.java @@ -18,13 +18,25 @@ package org.apache.nifi.cluster.manager; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.ProcessorDTO; +import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; import org.apache.nifi.web.api.entity.ProcessorEntity; import java.util.HashMap; import java.util.Map; import java.util.Set; -public class ProcessorEntityMerger { +public class ProcessorEntityMerger implements ComponentEntityMerger, ComponentEntityStatusMerger { + @Override + public void merge(ProcessorEntity clientEntity, Map entityMap) { + ComponentEntityMerger.super.merge(clientEntity, entityMap); + for (Map.Entry entry : entityMap.entrySet()) { + final NodeIdentifier nodeId = entry.getKey(); + final ProcessorEntity entityStatus = entry.getValue(); + if (entityStatus != clientEntity) { + mergeStatus(clientEntity.getStatus(), clientEntity.getPermissions().getCanRead(), entry.getValue().getStatus(), entry.getValue().getPermissions().getCanRead(), entry.getKey()); + } + } + } /** * Merges the ProcessorEntity responses. @@ -32,7 +44,7 @@ public class ProcessorEntityMerger { * @param clientEntity the entity being returned to the client * @param entityMap all node responses */ - public static void mergeProcessors(final ProcessorEntity clientEntity, final Map entityMap) { + public void mergeComponents(final ProcessorEntity clientEntity, final Map entityMap) { final ProcessorDTO clientDto = clientEntity.getComponent(); final Map dtoMap = new HashMap<>(); for (final Map.Entry entry : entityMap.entrySet()) { @@ -41,19 +53,16 @@ public class ProcessorEntityMerger { dtoMap.put(entry.getKey(), nodeProcDto); } - for (final Map.Entry entry : entityMap.entrySet()) { - final NodeIdentifier nodeId = entry.getKey(); - final ProcessorEntity entity = entry.getValue(); - if (entity != clientEntity) { - StatusMerger.merge(clientEntity.getStatus(), entity.getStatus(), nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); - } - } - - ComponentEntityMerger.mergeComponents(clientEntity, entityMap); - mergeDtos(clientDto, dtoMap); } + @Override + public void mergeStatus(ProcessorStatusDTO clientStatus, boolean clientStatusReadablePermission, ProcessorStatusDTO status, boolean statusReadablePermission, NodeIdentifier + statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } + private static void mergeDtos(final ProcessorDTO clientDto, final Map dtoMap) { // if unauthorized for the client dto, simple return if (clientDto == null) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorsEntityMerger.java index cf4ef7d0cc..21b4f7e62c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorsEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ProcessorsEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class ProcessorsEntityMerger { + private static final ProcessorEntityMerger processorEntityMerger = new ProcessorEntityMerger(); + /** * Merges multiple ProcessorEntity responses. * @@ -32,7 +34,7 @@ public class ProcessorsEntityMerger { */ public static void mergeProcessors(final Set processorEntities, final Map> entityMap) { for (final ProcessorEntity entity : processorEntities) { - ProcessorEntityMerger.mergeProcessors(entity, entityMap.get(entity.getId())); + processorEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupEntityMerger.java index 241528551e..3209e025c1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupEntityMerger.java @@ -20,6 +20,7 @@ import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.RemoteProcessGroupContentsDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; +import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import java.util.HashMap; @@ -27,7 +28,18 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -public class RemoteProcessGroupEntityMerger { +public class RemoteProcessGroupEntityMerger implements ComponentEntityMerger, ComponentEntityStatusMerger { + @Override + public void merge(RemoteProcessGroupEntity clientEntity, Map entityMap) { + ComponentEntityMerger.super.merge(clientEntity, entityMap); + for (Map.Entry entry : entityMap.entrySet()) { + final NodeIdentifier nodeId = entry.getKey(); + final RemoteProcessGroupEntity entityStatus = entry.getValue(); + if (entityStatus != clientEntity) { + mergeStatus(clientEntity.getStatus(), clientEntity.getPermissions().getCanRead(), entry.getValue().getStatus(), entry.getValue().getPermissions().getCanRead(), entry.getKey()); + } + } + } /** * Merges the RemoteProcessGroupEntity responses. @@ -35,7 +47,7 @@ public class RemoteProcessGroupEntityMerger { * @param clientEntity the entity being returned to the client * @param entityMap all node responses */ - public static void mergeRemoteProcessGroups(final RemoteProcessGroupEntity clientEntity, final Map entityMap) { + public void mergeComponents(final RemoteProcessGroupEntity clientEntity, final Map entityMap) { final RemoteProcessGroupDTO clientDto = clientEntity.getComponent(); final Map dtoMap = new HashMap<>(); for (final Map.Entry entry : entityMap.entrySet()) { @@ -44,19 +56,16 @@ public class RemoteProcessGroupEntityMerger { dtoMap.put(entry.getKey(), nodeProcDto); } - for (final Map.Entry entry : entityMap.entrySet()) { - final NodeIdentifier nodeId = entry.getKey(); - final RemoteProcessGroupEntity entity = entry.getValue(); - if (entity != clientEntity) { - StatusMerger.merge(clientEntity.getStatus(), entity.getStatus(), nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); - } - } - - ComponentEntityMerger.mergeComponents(clientEntity, entityMap); - mergeDtos(clientDto, dtoMap); } + @Override + public void mergeStatus(RemoteProcessGroupStatusDTO clientStatus, boolean clientStatusReadablePermission, RemoteProcessGroupStatusDTO status, + boolean statusReadablePermission, NodeIdentifier statusNodeIdentifier) { + StatusMerger.merge(clientStatus, clientStatusReadablePermission, status, statusReadablePermission, statusNodeIdentifier.getId(), statusNodeIdentifier.getApiAddress(), + statusNodeIdentifier.getApiPort()); + } + private static void mergeDtos(final RemoteProcessGroupDTO clientDto, final Map dtoMap) { // if unauthorized for the client dto, simple return if (clientDto == null) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupsEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupsEntityMerger.java index 8c94aa385c..d7cf99259e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupsEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/RemoteProcessGroupsEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class RemoteProcessGroupsEntityMerger { + private static final RemoteProcessGroupEntityMerger remoteProcessGroupEntityMerger = new RemoteProcessGroupEntityMerger(); + /** * Merges multiple RemoteProcessGroupEntity responses. * @@ -32,7 +34,7 @@ public class RemoteProcessGroupsEntityMerger { */ public static void mergeRemoteProcessGroups(final Set remoteProcessGroupEntities, final Map> entityMap) { for (final RemoteProcessGroupEntity entity : remoteProcessGroupEntities) { - RemoteProcessGroupEntityMerger.mergeRemoteProcessGroups(entity, entityMap.get(entity.getId())); + remoteProcessGroupEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTaskEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTaskEntityMerger.java index 8f0b281f72..552983dd21 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTaskEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTaskEntityMerger.java @@ -24,7 +24,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -public class ReportingTaskEntityMerger { +public class ReportingTaskEntityMerger implements ComponentEntityMerger { /** * Merges the ReportingTaskEntity responses. @@ -32,7 +32,7 @@ public class ReportingTaskEntityMerger { * @param clientEntity the entity being returned to the client * @param entityMap all node responses */ - public static void mergeReportingTasks(final ReportingTaskEntity clientEntity, final Map entityMap) { + public void mergeComponents(final ReportingTaskEntity clientEntity, final Map entityMap) { final ReportingTaskDTO clientDto = clientEntity.getComponent(); final Map dtoMap = new HashMap<>(); for (final Map.Entry entry : entityMap.entrySet()) { @@ -41,8 +41,6 @@ public class ReportingTaskEntityMerger { dtoMap.put(entry.getKey(), nodeReportingTaskDto); } - ComponentEntityMerger.mergeComponents(clientEntity, entityMap); - mergeDtos(clientDto, dtoMap); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTasksEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTasksEntityMerger.java index 764f4d0fdc..516e32d246 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTasksEntityMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ReportingTasksEntityMerger.java @@ -24,6 +24,8 @@ import java.util.Set; public class ReportingTasksEntityMerger { + private static final ReportingTaskEntityMerger reportingTaskEntityMerger = new ReportingTaskEntityMerger(); + /** * Merges multiple ReportingTaskEntity responses. * @@ -32,7 +34,7 @@ public class ReportingTasksEntityMerger { */ public static void mergeReportingTasks(final Set reportingTaskEntities, final Map> entityMap) { for (final ReportingTaskEntity entity : reportingTaskEntities) { - ReportingTaskEntityMerger.mergeReportingTasks(entity, entityMap.get(entity.getId())); + reportingTaskEntityMerger.merge(entity, entityMap.get(entity.getId())); } } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java index c886747052..7ad9e84433 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java @@ -45,6 +45,11 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO; +import org.apache.nifi.web.api.entity.ConnectionStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.PortStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusSnapshotEntity; import java.util.ArrayList; import java.util.Collection; @@ -72,8 +77,14 @@ public class StatusMerger { target.setQueued(prettyPrint(target.getFlowFilesQueued(), target.getBytesQueued())); } - public static void merge(final ProcessGroupStatusDTO target, final ProcessGroupStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) { - merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); + public static void merge(final ProcessGroupStatusDTO target, final boolean targetReadablePermission, final ProcessGroupStatusDTO toMerge, final boolean toMergeReadablePermission, + final String nodeId, final String nodeAddress, final Integer nodeApiPort) { + if (targetReadablePermission && !toMergeReadablePermission) { + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + } + + merge(target.getAggregateSnapshot(), targetReadablePermission, toMerge.getAggregateSnapshot(), toMergeReadablePermission); if (target.getNodeSnapshots() != null) { final NodeProcessGroupStatusSnapshotDTO nodeSnapshot = new NodeProcessGroupStatusSnapshotDTO(); @@ -86,11 +97,25 @@ public class StatusMerger { } } - public static void merge(final ProcessGroupStatusSnapshotDTO target, final ProcessGroupStatusSnapshotDTO toMerge) { + public static void merge(final ProcessGroupStatusSnapshotEntity target, ProcessGroupStatusSnapshotEntity toMerge) { if (target == null || toMerge == null) { return; } + merge(target.getProcessGroupStatusSnapshot(), target.getCanRead(), toMerge.getProcessGroupStatusSnapshot(), toMerge.getCanRead()); + } + + public static void merge(final ProcessGroupStatusSnapshotDTO target, final boolean targetReadablePermission, final ProcessGroupStatusSnapshotDTO toMerge, + final boolean toMergeReadablePermission) { + if (target == null || toMerge == null) { + return; + } + + if (targetReadablePermission && !toMergeReadablePermission) { + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + } + target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn()); target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn()); @@ -117,13 +142,13 @@ public class StatusMerger { // connection status // sort by id - final Map mergedConnectionMap = new HashMap<>(); - for (final ConnectionStatusSnapshotDTO status : replaceNull(target.getConnectionStatusSnapshots())) { + final Map mergedConnectionMap = new HashMap<>(); + for (final ConnectionStatusSnapshotEntity status : replaceNull(target.getConnectionStatusSnapshots())) { mergedConnectionMap.put(status.getId(), status); } - for (final ConnectionStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getConnectionStatusSnapshots())) { - ConnectionStatusSnapshotDTO merged = mergedConnectionMap.get(statusToMerge.getId()); + for (final ConnectionStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getConnectionStatusSnapshots())) { + ConnectionStatusSnapshotEntity merged = mergedConnectionMap.get(statusToMerge.getId()); if (merged == null) { mergedConnectionMap.put(statusToMerge.getId(), statusToMerge.clone()); continue; @@ -134,13 +159,13 @@ public class StatusMerger { target.setConnectionStatusSnapshots(mergedConnectionMap.values()); // processor status - final Map mergedProcessorMap = new HashMap<>(); - for (final ProcessorStatusSnapshotDTO status : replaceNull(target.getProcessorStatusSnapshots())) { + final Map mergedProcessorMap = new HashMap<>(); + for (final ProcessorStatusSnapshotEntity status : replaceNull(target.getProcessorStatusSnapshots())) { mergedProcessorMap.put(status.getId(), status); } - for (final ProcessorStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getProcessorStatusSnapshots())) { - ProcessorStatusSnapshotDTO merged = mergedProcessorMap.get(statusToMerge.getId()); + for (final ProcessorStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getProcessorStatusSnapshots())) { + ProcessorStatusSnapshotEntity merged = mergedProcessorMap.get(statusToMerge.getId()); if (merged == null) { mergedProcessorMap.put(statusToMerge.getId(), statusToMerge.clone()); continue; @@ -152,13 +177,13 @@ public class StatusMerger { // input ports - final Map mergedInputPortMap = new HashMap<>(); - for (final PortStatusSnapshotDTO status : replaceNull(target.getInputPortStatusSnapshots())) { + final Map mergedInputPortMap = new HashMap<>(); + for (final PortStatusSnapshotEntity status : replaceNull(target.getInputPortStatusSnapshots())) { mergedInputPortMap.put(status.getId(), status); } - for (final PortStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getInputPortStatusSnapshots())) { - PortStatusSnapshotDTO merged = mergedInputPortMap.get(statusToMerge.getId()); + for (final PortStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getInputPortStatusSnapshots())) { + PortStatusSnapshotEntity merged = mergedInputPortMap.get(statusToMerge.getId()); if (merged == null) { mergedInputPortMap.put(statusToMerge.getId(), statusToMerge.clone()); continue; @@ -169,13 +194,13 @@ public class StatusMerger { target.setInputPortStatusSnapshots(mergedInputPortMap.values()); // output ports - final Map mergedOutputPortMap = new HashMap<>(); - for (final PortStatusSnapshotDTO status : replaceNull(target.getOutputPortStatusSnapshots())) { + final Map mergedOutputPortMap = new HashMap<>(); + for (final PortStatusSnapshotEntity status : replaceNull(target.getOutputPortStatusSnapshots())) { mergedOutputPortMap.put(status.getId(), status); } - for (final PortStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getOutputPortStatusSnapshots())) { - PortStatusSnapshotDTO merged = mergedOutputPortMap.get(statusToMerge.getId()); + for (final PortStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getOutputPortStatusSnapshots())) { + PortStatusSnapshotEntity merged = mergedOutputPortMap.get(statusToMerge.getId()); if (merged == null) { mergedOutputPortMap.put(statusToMerge.getId(), statusToMerge.clone()); continue; @@ -186,13 +211,13 @@ public class StatusMerger { target.setOutputPortStatusSnapshots(mergedOutputPortMap.values()); // child groups - final Map mergedGroupMap = new HashMap<>(); - for (final ProcessGroupStatusSnapshotDTO status : replaceNull(target.getProcessGroupStatusSnapshots())) { + final Map mergedGroupMap = new HashMap<>(); + for (final ProcessGroupStatusSnapshotEntity status : replaceNull(target.getProcessGroupStatusSnapshots())) { mergedGroupMap.put(status.getId(), status); } - for (final ProcessGroupStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getProcessGroupStatusSnapshots())) { - ProcessGroupStatusSnapshotDTO merged = mergedGroupMap.get(statusToMerge.getId()); + for (final ProcessGroupStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getProcessGroupStatusSnapshots())) { + ProcessGroupStatusSnapshotEntity merged = mergedGroupMap.get(statusToMerge.getId()); if (merged == null) { mergedGroupMap.put(statusToMerge.getId(), statusToMerge.clone()); continue; @@ -203,13 +228,13 @@ public class StatusMerger { target.setOutputPortStatusSnapshots(mergedOutputPortMap.values()); // remote groups - final Map mergedRemoteGroupMap = new HashMap<>(); - for (final RemoteProcessGroupStatusSnapshotDTO status : replaceNull(target.getRemoteProcessGroupStatusSnapshots())) { + final Map mergedRemoteGroupMap = new HashMap<>(); + for (final RemoteProcessGroupStatusSnapshotEntity status : replaceNull(target.getRemoteProcessGroupStatusSnapshots())) { mergedRemoteGroupMap.put(status.getId(), status); } - for (final RemoteProcessGroupStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getRemoteProcessGroupStatusSnapshots())) { - RemoteProcessGroupStatusSnapshotDTO merged = mergedRemoteGroupMap.get(statusToMerge.getId()); + for (final RemoteProcessGroupStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getRemoteProcessGroupStatusSnapshots())) { + RemoteProcessGroupStatusSnapshotEntity merged = mergedRemoteGroupMap.get(statusToMerge.getId()); if (merged == null) { mergedRemoteGroupMap.put(statusToMerge.getId(), statusToMerge.clone()); continue; @@ -221,7 +246,7 @@ public class StatusMerger { } private static Collection replaceNull(final Collection collection) { - return (collection == null) ? Collections. emptyList() : collection; + return (collection == null) ? Collections.emptyList() : collection; } @@ -230,7 +255,7 @@ public class StatusMerger { * {@link ProcessGroupStatusSnapshotDTO#setInput(String)} will be called with the pretty-printed form of the * FlowFile counts and sizes retrieved via {@link ProcessGroupStatusSnapshotDTO#getFlowFilesIn()} and * {@link ProcessGroupStatusSnapshotDTO#getBytesIn()}. - * + *

* This logic is performed here, rather than in the DTO itself because the DTO needs to be kept purely * getters & setters - otherwise the automatic marshalling and unmarshalling to/from JSON becomes very * complicated. @@ -250,8 +275,16 @@ public class StatusMerger { target.setSent(prettyPrint(target.getFlowFilesSent(), target.getBytesSent())); } - public static void merge(final RemoteProcessGroupStatusDTO target, final RemoteProcessGroupStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) { - merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); + public static void merge(final RemoteProcessGroupStatusDTO target, final boolean targetReadablePermission, final RemoteProcessGroupStatusDTO toMerge, + final boolean toMergeReadablePermission, final String nodeId, final String nodeAddress, final Integer nodeApiPort) { + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + target.setTargetUri(toMerge.getTargetUri()); + } + + merge(target.getAggregateSnapshot(), targetReadablePermission, toMerge.getAggregateSnapshot(), toMergeReadablePermission); if (target.getNodeSnapshots() != null) { final NodeRemoteProcessGroupStatusSnapshotDTO nodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO(); @@ -264,8 +297,15 @@ public class StatusMerger { } } - public static void merge(final PortStatusDTO target, final PortStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) { - merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); + public static void merge(final PortStatusDTO target, final boolean targetReadablePermission, final PortStatusDTO toMerge, final boolean toMergeReadablePermission, final String nodeId, + final String nodeAddress, final Integer nodeApiPort) { + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + } + + merge(target.getAggregateSnapshot(), targetReadablePermission, toMerge.getAggregateSnapshot(), toMergeReadablePermission); if (target.getNodeSnapshots() != null) { final NodePortStatusSnapshotDTO nodeSnapshot = new NodePortStatusSnapshotDTO(); @@ -278,8 +318,19 @@ public class StatusMerger { } } - public static void merge(final ConnectionStatusDTO target, final ConnectionStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) { - merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); + public static void merge(final ConnectionStatusDTO target, final boolean targetReadablePermission, final ConnectionStatusDTO toMerge, final boolean toMergeReadablePermission, + final String nodeId, final String nodeAddress, final Integer nodeApiPort) { + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + target.setSourceId(toMerge.getSourceId()); + target.setSourceName(toMerge.getSourceName()); + target.setDestinationId(toMerge.getDestinationId()); + target.setDestinationName(toMerge.getDestinationName()); + } + + merge(target.getAggregateSnapshot(), targetReadablePermission, toMerge.getAggregateSnapshot(), toMergeReadablePermission); if (target.getNodeSnapshots() != null) { final NodeConnectionStatusSnapshotDTO nodeSnapshot = new NodeConnectionStatusSnapshotDTO(); @@ -292,8 +343,16 @@ public class StatusMerger { } } - public static void merge(final ProcessorStatusDTO target, final ProcessorStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) { - merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); + public static void merge(final ProcessorStatusDTO target, final boolean targetReadablePermission, final ProcessorStatusDTO toMerge, final boolean toMergeReadablePermission, + final String nodeId, final String nodeAddress, final Integer nodeApiPort) { + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + target.setType(toMerge.getType()); + } + + merge(target.getAggregateSnapshot(), targetReadablePermission, toMerge.getAggregateSnapshot(), toMergeReadablePermission); if (target.getNodeSnapshots() != null) { final NodeProcessorStatusSnapshotDTO nodeSnapshot = new NodeProcessorStatusSnapshotDTO(); @@ -306,11 +365,27 @@ public class StatusMerger { } } - public static void merge(final ProcessorStatusSnapshotDTO target, final ProcessorStatusSnapshotDTO toMerge) { + public static void merge(final ProcessorStatusSnapshotEntity target, ProcessorStatusSnapshotEntity toMerge) { if (target == null || toMerge == null) { return; } + merge(target.getProcessorStatusSnapshot(), target.getCanRead(), toMerge.getProcessorStatusSnapshot(), toMerge.getCanRead()); + } + + public static void merge(final ProcessorStatusSnapshotDTO target, final boolean targetReadablePermission, final ProcessorStatusSnapshotDTO toMerge, + final boolean toMergeReadablePermission) { + if (target == null || toMerge == null) { + return; + } + + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + target.setType(toMerge.getType()); + } + // if the status to merge is invalid allow it to take precedence. whether the // processor run status is disabled/stopped/running is part of the flow configuration // and should not differ amongst nodes. however, whether a processor is invalid @@ -345,12 +420,30 @@ public class StatusMerger { target.setTasksDuration(FormatUtils.formatHoursMinutesSeconds(target.getTasksDurationNanos(), TimeUnit.NANOSECONDS)); } - - public static void merge(final ConnectionStatusSnapshotDTO target, final ConnectionStatusSnapshotDTO toMerge) { + public static void merge(final ConnectionStatusSnapshotEntity target, ConnectionStatusSnapshotEntity toMerge) { if (target == null || toMerge == null) { return; } + merge(target.getConnectionStatusSnapshot(), target.getCanRead(), toMerge.getConnectionStatusSnapshot(), toMerge.getCanRead()); + } + + public static void merge(final ConnectionStatusSnapshotDTO target, final boolean targetReadablePermission, final ConnectionStatusSnapshotDTO toMerge, + final boolean toMergeReadablePermission) { + if (target == null || toMerge == null) { + return; + } + + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + target.setSourceId(toMerge.getSourceId()); + target.setSourceName(toMerge.getSourceName()); + target.setDestinationId(toMerge.getDestinationId()); + target.setDestinationName(toMerge.getDestinationName()); + } + target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn()); target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn()); target.setFlowFilesOut(target.getFlowFilesOut() + toMerge.getFlowFilesOut()); @@ -369,8 +462,27 @@ public class StatusMerger { } + public static void merge(final RemoteProcessGroupStatusSnapshotEntity target, RemoteProcessGroupStatusSnapshotEntity toMerge) { + if (target == null || toMerge == null) { + return; + } + + merge(target.getRemoteProcessGroupStatusSnapshot(), target.getCanRead(), toMerge.getRemoteProcessGroupStatusSnapshot(), toMerge.getCanRead()); + } + + public static void merge(final RemoteProcessGroupStatusSnapshotDTO target, final boolean targetReadablePermission, final RemoteProcessGroupStatusSnapshotDTO toMerge, + final boolean toMergeReadablePermission) { + if (target == null || toMerge == null) { + return; + } + + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + target.setTargetUri(toMerge.getTargetUri()); + } - public static void merge(final RemoteProcessGroupStatusSnapshotDTO target, final RemoteProcessGroupStatusSnapshotDTO toMerge) { final String transmittingValue = TransmissionStatus.Transmitting.name(); if (transmittingValue.equals(target.getTransmissionStatus()) || transmittingValue.equals(toMerge.getTransmissionStatus())) { target.setTransmissionStatus(transmittingValue); @@ -391,12 +503,25 @@ public class StatusMerger { } - - public static void merge(final PortStatusSnapshotDTO target, final PortStatusSnapshotDTO toMerge) { + public static void merge(final PortStatusSnapshotEntity target, PortStatusSnapshotEntity toMerge) { if (target == null || toMerge == null) { return; } + merge(target.getPortStatusSnapshot(), target.getCanRead(), toMerge.getPortStatusSnapshot(), toMerge.getCanRead()); + } + + public static void merge(final PortStatusSnapshotDTO target, final boolean targetReadablePermission, final PortStatusSnapshotDTO toMerge, final boolean toMergeReadablePermission) { + if (target == null || toMerge == null) { + return; + } + + if (targetReadablePermission && !toMergeReadablePermission) { + target.setGroupId(toMerge.getGroupId()); + target.setId(toMerge.getId()); + target.setName(toMerge.getName()); + } + target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount()); target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn()); target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn()); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMergerSpec.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMergerSpec.groovy new file mode 100644 index 0000000000..bd9b265527 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMergerSpec.groovy @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http + +import com.sun.jersey.api.client.ClientResponse +import org.apache.nifi.cluster.manager.NodeResponse +import org.apache.nifi.cluster.protocol.NodeIdentifier +import org.apache.nifi.util.NiFiProperties +import org.apache.nifi.web.api.dto.AccessPolicyDTO +import org.apache.nifi.web.api.dto.ConnectionDTO +import org.apache.nifi.web.api.dto.ControllerConfigurationDTO +import org.apache.nifi.web.api.dto.FunnelDTO +import org.apache.nifi.web.api.dto.LabelDTO +import org.apache.nifi.web.api.dto.PermissionsDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO +import org.apache.nifi.web.api.entity.ConnectionEntity +import org.apache.nifi.web.api.entity.ConnectionsEntity +import org.apache.nifi.web.api.entity.ControllerConfigurationEntity +import org.apache.nifi.web.api.entity.FunnelEntity +import org.apache.nifi.web.api.entity.FunnelsEntity +import org.apache.nifi.web.api.entity.LabelEntity +import org.apache.nifi.web.api.entity.LabelsEntity +import org.codehaus.jackson.map.ObjectMapper +import org.codehaus.jackson.map.SerializationConfig +import org.codehaus.jackson.map.annotate.JsonSerialize +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector +import spock.lang.Specification +import spock.lang.Unroll + +@Unroll +class StandardHttpResponseMergerSpec extends Specification { + + def setup() { + System.setProperty NiFiProperties.PROPERTIES_FILE_PATH, "src/test/resources/conf/nifi.properties" + } + + def cleanup() { + System.clearProperty NiFiProperties.PROPERTIES_FILE_PATH + } + + def "MergeResponses: mixed HTTP GET response statuses, expecting #expectedStatus"() { + given: + def responseMerger = new StandardHttpResponseMerger() + def requestUri = new URI('http://server/resource') + def requestId = UUID.randomUUID().toString() + def Map> mockToRequestEntity = [:] + def nodeResponseSet = nodeResponseData.collect { + int n = it.node + def clientResponse = Mock(ClientResponse) + mockToRequestEntity.put clientResponse, it + new NodeResponse(new NodeIdentifier("cluster-node-$n", 'addr', n, 'sktaddr', n * 10, 'stsaddr', n * 100, n * 1000, false, null), "get", requestUri, clientResponse, 500L, requestId) + } as Set + + when: + def returnedResponse = responseMerger.mergeResponses(requestUri, 'get', nodeResponseSet).getStatus() + + then: + mockToRequestEntity.entrySet().forEach { + ClientResponse mockClientResponse = it.key + _ * mockClientResponse.getStatus() >> it.value.status + } + 0 * _ + returnedResponse == expectedStatus + + where: + nodeResponseData || expectedStatus + [[node: 1, status: 200], [node: 2, status: 200], [node: 3, status: 401]] as Set || 401 + [[node: 1, status: 200], [node: 2, status: 200], [node: 3, status: 403]] as Set || 403 + [[node: 1, status: 200], [node: 2, status: 403], [node: 3, status: 500]] as Set || 403 + [[node: 1, status: 200], [node: 2, status: 200], [node: 3, status: 500]] as Set || 500 + } + + def "MergeResponses: #responseEntities.size() HTTP 200 #httpMethod responses for #requestUriPart"() { + given: "json serialization setup" + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + + and: "setup of the data to be used in the test" + def responseMerger = new StandardHttpResponseMerger() + def requestUri = new URI("http://server/$requestUriPart") + def requestId = UUID.randomUUID().toString() + def Map mockToRequestEntity = [:] + def n = 0 + def nodeResponseSet = responseEntities.collect { + ++n + def clientResponse = Mock(ClientResponse) + mockToRequestEntity.put clientResponse, it + new NodeResponse(new NodeIdentifier("cluster-node-$n", 'addr', n, 'sktaddr', n * 10, 'stsaddr', n * 100, n * 1000, false, null), "get", requestUri, clientResponse, 500L, requestId) + } as Set + + when: + def returnedResponse = responseMerger.mergeResponses(requestUri, httpMethod, nodeResponseSet) + + then: + mockToRequestEntity.entrySet().forEach { + ClientResponse mockClientResponse = it.key + def entity = it.value + _ * mockClientResponse.getStatus() >> 200 + 1 * mockClientResponse.getEntity(_) >> entity + } + responseEntities.size() == mockToRequestEntity.size() + 0 * _ + def returnedJson = mapper.writeValueAsString(returnedResponse.getUpdatedEntity()) + def expectedJson = mapper.writeValueAsString(expectedEntity) + returnedJson == expectedJson + + where: + requestUriPart | httpMethod | responseEntities || + expectedEntity + 'nifi-api/controller/config' | 'get' | [ + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10)), + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: false), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10)), + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10))] || + // expectedEntity + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: false), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10)) + 'nifi-api/controller/config' | 'put' | [ + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10)), + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: false), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10)), + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10))] || + // expectedEntity + new ControllerConfigurationEntity(permissions: new PermissionsDTO(canRead: true, canWrite: false), + component: new ControllerConfigurationDTO(maxEventDrivenThreadCount: 10, maxTimerDrivenThreadCount: 10)) + "nifi-api/process-groups/${UUID.randomUUID()}/connections" | 'get' | [ + new ConnectionsEntity(connections: [new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: new + ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300)), component: new ConnectionDTO())] as Set), + new ConnectionsEntity(connections: [new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), status: new + ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 100)))] as Set), + new ConnectionsEntity(connections: [new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: new + ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 500)), component: new ConnectionDTO())] as Set)] || + // expectedEntity + new ConnectionsEntity(connections: [new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), + status: new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 900, + input: '0 (900 bytes)', output: '0 (0 bytes)', queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: 0)))] as Set) + "nifi-api/process-groups/${UUID.randomUUID()}/connections" | 'post' | [ + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: + new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300)), component: new ConnectionDTO()), + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), status: + new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300))), + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: + new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300)), component: new ConnectionDTO())] || + // expectedEntity + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), + status: new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 900, input: '0 (900 bytes)', + output: '0 (0 bytes)', queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: 0))) + "nifi-api/connections/${UUID.randomUUID()}" | 'get' | [ + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: + new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 400)), component: new ConnectionDTO()), + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), status: + new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300))), + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: + new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300)), component: new ConnectionDTO())] || + // expectedEntity + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), + status: new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 1000, + input: '0 (1,000 bytes)', output: '0 (0 bytes)', queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: 0))) + "nifi-api/process-groups/${UUID.randomUUID()}/labels" | 'get' | [ + new LabelsEntity(labels: [new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO())] as Set), + new LabelsEntity(labels: [new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false))] as Set), + new LabelsEntity(labels: [new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO())] as Set)] || + // expectedEntity + new LabelsEntity(labels: [new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false))] as Set) + "nifi-api/process-groups/${UUID.randomUUID()}/labels" | 'post' | [ + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO()), + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)), + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO())] || + // expectedEntity + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)) + "nifi-api/labels/${UUID.randomUUID()}" | 'get' | [ + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO()), + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)), + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO())] || + // expectedEntity + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)) + "nifi-api/process-groups/${UUID.randomUUID()}/funnels" | 'get' | [ + new FunnelsEntity(funnels: [new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new FunnelDTO())] as Set), + new FunnelsEntity(funnels: [new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false))] as Set), + new FunnelsEntity(funnels: [new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new FunnelDTO())] as Set)] || + // expectedEntity + new FunnelsEntity(funnels: [new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false))] as Set) + "nifi-api/process-groups/${UUID.randomUUID()}/funnels" | 'post' | [ + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new FunnelDTO()), + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)), + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new FunnelDTO())] || + // expectedEntity + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)) + "nifi-api/funnels/${UUID.randomUUID()}" | 'get' | [ + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new FunnelDTO()), + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)), + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new FunnelDTO())] || + // expectedEntity + new FunnelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)) + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMergerSpec.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMergerSpec.groovy new file mode 100644 index 0000000000..69dd82a9a5 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/endpoints/StatusHistoryEndpointMergerSpec.groovy @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.coordination.http.endpoints + +import com.sun.jersey.api.client.ClientResponse +import org.apache.nifi.cluster.manager.NodeResponse +import org.apache.nifi.cluster.protocol.NodeIdentifier +import org.apache.nifi.util.NiFiProperties +import org.apache.nifi.web.api.dto.status.StatusHistoryDTO +import org.apache.nifi.web.api.entity.StatusHistoryEntity +import org.codehaus.jackson.map.ObjectMapper +import org.codehaus.jackson.map.SerializationConfig +import org.codehaus.jackson.map.annotate.JsonSerialize +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector +import spock.lang.Specification +import spock.lang.Unroll + +class StatusHistoryEndpointMergerSpec extends Specification { + + def setup() { + System.setProperty NiFiProperties.PROPERTIES_FILE_PATH, "src/test/resources/conf/nifi.properties" + } + + def cleanup() { + System.clearProperty NiFiProperties.PROPERTIES_FILE_PATH + } + + @Unroll + def "Merge component details based on permission"() { + given: "json serialization setup" + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + + and: "setup of the data to be used in the test" + def merger = new StatusHistoryEndpointMerger() + def requestUri = new URI("http://server/$requestUriPart") + def requestId = UUID.randomUUID().toString() + def Map mockToRequestEntity = [:] + def n = 0 + def nodeResponseSet = responseEntities.collect { + ++n + def clientResponse = Mock(ClientResponse) + mockToRequestEntity.put clientResponse, it + new NodeResponse(new NodeIdentifier("cluster-node-$n", 'addr', n, 'sktaddr', n * 10, 'stsaddr', n * 100, n * 1000, false, null), "get", requestUri, clientResponse, 500L, requestId) + } as Set + + when: + def returnedResponse = merger.merge(requestUri, httpMethod, nodeResponseSet, [] as Set, nodeResponseSet[0]) + + then: + mockToRequestEntity.entrySet().forEach { + ClientResponse mockClientResponse = it.key + def entity = it.value + _ * mockClientResponse.getStatus() >> 200 + 1 * mockClientResponse.getEntity(_) >> entity + } + responseEntities.size() == mockToRequestEntity.size() + 0 * _ + (returnedResponse.getUpdatedEntity() as StatusHistoryEntity).canRead == expectedEntity.canRead + (returnedResponse.getUpdatedEntity() as StatusHistoryEntity).statusHistory.componentDetails == expectedEntity.statusHistory.componentDetails + + where: + requestUriPart | httpMethod | responseEntities || + expectedEntity + "/nifi-api/flow/connections/${UUID.randomUUID()}/status/history" | 'get' | [ + new StatusHistoryEntity(canRead: true, statusHistory: new StatusHistoryDTO(componentDetails: [key1: 'real', key2: 'real'], nodeSnapshots: [], aggregateSnapshots: [])), + new StatusHistoryEntity(canRead: false, statusHistory: new StatusHistoryDTO(componentDetails: [key1: 'hidden', key2: 'hidden'], nodeSnapshots: [], aggregateSnapshots: [])), + new StatusHistoryEntity(canRead: true, statusHistory: new StatusHistoryDTO(componentDetails: [key1: 'real', key2: 'real'], nodeSnapshots: [], aggregateSnapshots: [])) + ] || + new StatusHistoryEntity(canRead: false, statusHistory: new StatusHistoryDTO(componentDetails: [key1: 'hidden', key2: 'hidden'], nodeSnapshots: [], aggregateSnapshots: [])) + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ConnectionEntityMergerSpec.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ConnectionEntityMergerSpec.groovy new file mode 100644 index 0000000000..3f819753b1 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ConnectionEntityMergerSpec.groovy @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager + +import org.apache.nifi.cluster.protocol.NodeIdentifier +import org.apache.nifi.web.api.dto.ConnectionDTO +import org.apache.nifi.web.api.dto.ControllerConfigurationDTO +import org.apache.nifi.web.api.dto.PermissionsDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO +import org.apache.nifi.web.api.entity.ConnectionEntity +import org.apache.nifi.web.api.entity.ConnectionsEntity +import org.apache.nifi.web.api.entity.ControllerConfigurationEntity +import org.codehaus.jackson.map.ObjectMapper +import org.codehaus.jackson.map.SerializationConfig +import org.codehaus.jackson.map.annotate.JsonSerialize +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector +import spock.lang.Specification +import spock.lang.Unroll + +class ConnectionEntityMergerSpec extends Specification { + + @Unroll + def "Merge"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)) + def entity = nodeEntityMap.entrySet().first().value + + when: + new ConnectionEntityMerger().merge(entity, nodeEntityMap) + + then: + def mergedEntityJson = mapper.writeValueAsString(entity) + def expectedJson = mapper.writeValueAsString(expectedMergedEntity) + mergedEntityJson == expectedJson + + where: + nodeEntityMap || + expectedMergedEntity + [(createNodeIdentifier(1)): new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: new + ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 300)), component: new ConnectionDTO()), + (createNodeIdentifier(2)): new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), status: new + ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 100))), + (createNodeIdentifier(3)): new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), status: new + ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 500)), component: new ConnectionDTO())] || + new ConnectionEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), + status: new ConnectionStatusDTO(aggregateSnapshot: new ConnectionStatusSnapshotDTO(bytesIn: 900, input: '0 (900 bytes)', + output: '0 (0 bytes)', queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: 0))) + + } + + def createNodeIdentifier(int id) { + new NodeIdentifier("cluster-node-$id", 'addr', id, 'sktaddr', id * 10, 'stsaddr', id * 100, id * 1000, false, null) + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMergerSpec.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMergerSpec.groovy new file mode 100644 index 0000000000..8b2c76c677 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/ControllerServiceEntityMergerSpec.groovy @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager + +import org.apache.nifi.cluster.protocol.NodeIdentifier +import org.apache.nifi.controller.service.ControllerServiceState +import org.apache.nifi.web.api.dto.ConnectionDTO +import org.apache.nifi.web.api.dto.ControllerServiceDTO +import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO +import org.apache.nifi.web.api.dto.PermissionsDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO +import org.apache.nifi.web.api.entity.ConnectionEntity +import org.apache.nifi.web.api.entity.ControllerServiceEntity +import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity +import org.codehaus.jackson.map.ObjectMapper +import org.codehaus.jackson.map.SerializationConfig +import org.codehaus.jackson.map.annotate.JsonSerialize +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector +import spock.lang.Specification +import spock.lang.Unroll + +@Unroll +class ControllerServiceEntityMergerSpec extends Specification { + def "MergeComponents"() { + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)) + def entity = nodeEntityMap.entrySet().first().value + + when: + new ControllerServiceEntityMerger().merge(entity, nodeEntityMap) + + then: + def mergedEntityJson = mapper.writeValueAsString(entity) + def expectedJson = mapper.writeValueAsString(expectedMergedEntity) + mergedEntityJson == expectedJson + + where: + nodeEntityMap || + expectedMergedEntity + // Simple ControllerServiceEntity merging + [(createNodeIdentifier(1)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO()), + (createNodeIdentifier(2)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false), + component: new ControllerServiceDTO()), + (createNodeIdentifier(3)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO())] || + new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)) + // Controller Reference merging for canRead==false + [(createNodeIdentifier(1)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 1, state: ControllerServiceState.ENABLING.name()))])), + (createNodeIdentifier(2)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: false, canWrite: false), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 1, state: ControllerServiceState.ENABLING.name()))])), + (createNodeIdentifier(3)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 1, state: ControllerServiceState.ENABLING.name()))]))] || + new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + bulletins: [], + component: new ControllerServiceDTO(validationErrors: [], + referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: false, canWrite: false))])) + // Controller Reference merging for canRead==true + [(createNodeIdentifier(1)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 1, state: ControllerServiceState.ENABLING.name()))])), + (createNodeIdentifier(2)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 1, state: ControllerServiceState.ENABLING.name()))])), + (createNodeIdentifier(3)): new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 1, state: ControllerServiceState.ENABLING.name()))]))] || + new ControllerServiceEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), + bulletins: [], + component: new ControllerServiceDTO(validationErrors: [], + referencingComponents: [new ControllerServiceReferencingComponentEntity(permissions: new PermissionsDTO(canRead: true, canWrite: true), + component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 3, state: ControllerServiceState.ENABLING.name()))])) + } + + def "MergeControllerServiceReferences"() { + + } + + def createNodeIdentifier(int id) { + new NodeIdentifier("cluster-node-$id", 'addr', id, 'sktaddr', id * 10, 'stsaddr', id * 100, id * 1000, false, null) + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/LabelEntityMergerSpec.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/LabelEntityMergerSpec.groovy new file mode 100644 index 0000000000..5ebdf0ebe0 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/LabelEntityMergerSpec.groovy @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager + +import org.apache.nifi.cluster.protocol.NodeIdentifier +import org.apache.nifi.web.api.dto.LabelDTO +import org.apache.nifi.web.api.dto.PermissionsDTO +import org.apache.nifi.web.api.entity.LabelEntity +import org.codehaus.jackson.map.ObjectMapper +import org.codehaus.jackson.map.SerializationConfig +import org.codehaus.jackson.map.annotate.JsonSerialize +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector +import spock.lang.Specification +import spock.lang.Unroll + +@Unroll +class LabelEntityMergerSpec extends Specification { + def "Merge"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)) + def entity = nodeEntityMap.entrySet().first().value + + when: + new LabelEntityMerger().merge(entity, nodeEntityMap) + + then: + def mergedEntityJson = mapper.writeValueAsString(entity) + def expectedJson = mapper.writeValueAsString(expectedMergedEntity) + mergedEntityJson == expectedJson + + where: + nodeEntityMap || + expectedMergedEntity + [(createNodeIdentifier(1)): new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO(label: 'label')), + (createNodeIdentifier(2)): new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)), + (createNodeIdentifier(3)): new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: true, canWrite: true), component: new LabelDTO(label: 'label'))] || + new LabelEntity(id: '1', permissions: new PermissionsDTO(canRead: false, canWrite: false)) + + } + + def createNodeIdentifier(int id) { + new NodeIdentifier("cluster-node-$id", 'addr', id, 'sktaddr', id * 10, 'stsaddr', id * 100, id * 1000, false, null) + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/PermissionBasedStatusMergerSpec.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/PermissionBasedStatusMergerSpec.groovy new file mode 100644 index 0000000000..f922fffa9b --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/manager/PermissionBasedStatusMergerSpec.groovy @@ -0,0 +1,328 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.cluster.manager + +import org.apache.nifi.cluster.protocol.NodeIdentifier +import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO +import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO +import org.apache.nifi.web.api.dto.status.ControllerStatusDTO +import org.apache.nifi.web.api.dto.status.PortStatusDTO +import org.apache.nifi.web.api.dto.status.PortStatusSnapshotDTO +import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO +import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO +import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO +import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO +import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO +import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO +import org.codehaus.jackson.map.ObjectMapper +import org.codehaus.jackson.map.SerializationConfig +import org.codehaus.jackson.map.annotate.JsonSerialize +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector +import spock.lang.Specification +import spock.lang.Unroll + +@Unroll +class PermissionBasedStatusMergerSpec extends Specification { + def "Merge ConnectionStatusDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead, 'nodeid', 'nodeaddress', 1234) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new ConnectionStatusDTO(groupId: 'real', id: 'real', name: 'real', sourceId: 'real', sourceName: 'real', destinationId: 'real', destinationName: 'real') | true | + new ConnectionStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', + destinationName: 'hidden') | false || + new ConnectionStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', + destinationName: 'hidden') + new ConnectionStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', destinationName: 'hidden') | false | + new ConnectionStatusDTO(groupId: 'real', id: 'real', name: 'real', sourceId: 'real', sourceName: 'real', destinationId: 'real', destinationName: 'real') | true || + new ConnectionStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', destinationName: 'hidden') + } + + def "Merge ConnectionStatusSnapshotDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new ConnectionStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real', sourceId: 'real', sourceName: 'real', destinationId: 'real', destinationName: 'real') | true | + new ConnectionStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', + destinationName: 'hidden') | false || + new ConnectionStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', + destinationName: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: '0') + new ConnectionStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', + destinationName: 'hidden') | false | + new ConnectionStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real', sourceId: 'real', sourceName: 'real', destinationId: 'real', destinationName: 'real') | true || + new ConnectionStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', sourceId: 'hidden', sourceName: 'hidden', destinationId: 'hidden', + destinationName: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: '0') + } + + def "Merge PortStatusDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead, 'nodeid', 'nodeaddress', 1234) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new PortStatusDTO(groupId: 'real', id: 'real', name: 'real') | true | + new PortStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden') | false || + new PortStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden') + new PortStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden') | false | + new PortStatusDTO(groupId: 'real', id: 'real', name: 'real') | true || + new PortStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden') + } + + def "Merge PortStatusSnapshotDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new PortStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real') | true | + new PortStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden') | false || + new PortStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', transmitting: false) + new PortStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden') | false | + new PortStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real') | true || + new PortStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', transmitting: false) + } + + def "Merge ProcessGroupStatusDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead, 'nodeid', 'nodeaddress', 1234) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new ProcessGroupStatusDTO(id: 'real', name: 'real') | true | new ProcessGroupStatusDTO(id: 'hidden', name: 'hidden') | false || + new ProcessGroupStatusDTO(id: 'hidden', name: 'hidden') + new ProcessGroupStatusDTO(id: 'hidden', name: 'hidden') | false | new ProcessGroupStatusDTO(id: 'real', name: 'real') | true || + new ProcessGroupStatusDTO(id: 'hidden', name: 'hidden') + } + + def "Merge ProcessGroupStatusSnapshotDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new ProcessGroupStatusSnapshotDTO(id: 'real', name: 'real') | true | new ProcessGroupStatusSnapshotDTO(id: 'hidden', name: 'hidden') | false || + new ProcessGroupStatusSnapshotDTO(id: 'hidden', name: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', transferred: '0 (0 bytes)', read: '0 bytes', written: '0' + + ' bytes', + queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: '0', received: '0 (0 bytes)', sent: '0 (0 bytes)', connectionStatusSnapshots: [], inputPortStatusSnapshots: [], + outputPortStatusSnapshots: [], processorStatusSnapshots: [], remoteProcessGroupStatusSnapshots: []) + new ProcessGroupStatusSnapshotDTO(id: 'hidden', name: 'hidden') | false | new ProcessGroupStatusSnapshotDTO(id: 'real', name: 'real') | true || + new ProcessGroupStatusSnapshotDTO(id: 'hidden', name: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', transferred: '0 (0 bytes)', read: '0 bytes', written: '0 bytes', + queued: '0 (0 bytes)', queuedSize: '0 bytes', queuedCount: '0', received: '0 (0 bytes)', sent: '0 (0 bytes)', connectionStatusSnapshots: [], inputPortStatusSnapshots: [], + outputPortStatusSnapshots: [], processorStatusSnapshots: [], remoteProcessGroupStatusSnapshots: []) + } + + def "Merge ProcessorStatusDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead, 'nodeid', 'nodeaddress', 1234) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new ProcessorStatusDTO(groupId: 'real', id: 'real', name: 'real', type: 'real') | true | + new ProcessorStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden') | false || + new ProcessorStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden') + new ProcessorStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden') | false | + new ProcessorStatusDTO(groupId: 'real', id: 'real', name: 'real', type: 'real') | true || + new ProcessorStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden') + } + + def "Merge ProcessorStatusSnapshotDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new ProcessorStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden') | false | + new ProcessorStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real', type: 'real') | true || + new ProcessorStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', read: '0 bytes', + written: '0 bytes', tasks: '0', tasksDuration: '00:00:00.000') + new ProcessorStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real', type: 'real') | true | + new ProcessorStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden') | false || + new ProcessorStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', type: 'hidden', input: '0 (0 bytes)', output: '0 (0 bytes)', read: '0 bytes', + written: '0 bytes', tasks: '0', tasksDuration: '00:00:00.000') + } + + def "Merge RemoteProcessGroupStatusDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead, 'nodeid', 'nodeaddress', 1234) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new RemoteProcessGroupStatusDTO(groupId: 'real', id: 'real', name: 'real', targetUri: 'real') | true | + new RemoteProcessGroupStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden') | false || + new RemoteProcessGroupStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden') + new RemoteProcessGroupStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden') | false | + new RemoteProcessGroupStatusDTO(groupId: 'real', id: 'real', name: 'real', targetUri: 'real') | true || + new RemoteProcessGroupStatusDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden') + } + + def "Merge RemoteProcessGroupStatusSnapshotDTO"() { + given: + def mapper = new ObjectMapper(); + def jaxbIntrospector = new JaxbAnnotationIntrospector(); + def SerializationConfig serializationConfig = mapper.getSerializationConfig(); + mapper.setSerializationConfig(serializationConfig.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL).withAnnotationIntrospector(jaxbIntrospector)); + def merger = new StatusMerger() + + when: + merger.merge(target, targetCanRead, toMerge, toMergeCanRead) + + then: + def returnedJson = mapper.writeValueAsString(target) + def expectedJson = mapper.writeValueAsString(expectedDto) + returnedJson == expectedJson + + where: + target | targetCanRead | + toMerge | toMergeCanRead || + expectedDto + new RemoteProcessGroupStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real', targetUri: 'real') | true | + new RemoteProcessGroupStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden') | false || + new RemoteProcessGroupStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden', received: '0 (0 bytes)', sent: '0 (0 bytes)') + new RemoteProcessGroupStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden') | false | + new RemoteProcessGroupStatusSnapshotDTO(groupId: 'real', id: 'real', name: 'real', targetUri: 'real') | true || + new RemoteProcessGroupStatusSnapshotDTO(groupId: 'hidden', id: 'hidden', name: 'hidden', targetUri: 'hidden', received: '0 (0 bytes)', sent: '0 (0 bytes)') + } +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java index a114a00d2c..5875249ea5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java @@ -17,12 +17,12 @@ package org.apache.nifi.controller.status.history; -import java.util.List; -import java.util.concurrent.TimeUnit; - import org.apache.nifi.controller.status.RemoteProcessGroupStatus; import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter; +import java.util.List; +import java.util.concurrent.TimeUnit; + public enum RemoteProcessGroupStatusDescriptor { SENT_BYTES(new StandardMetricDescriptor("sentBytes", "Bytes Sent (5 mins)", diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 08a56e249e..ee5487f2a4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -63,15 +63,10 @@ import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO; import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO; import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO; import org.apache.nifi.web.api.dto.search.SearchResultsDTO; -import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import org.apache.nifi.web.api.dto.status.ControllerStatusDTO; -import org.apache.nifi.web.api.dto.status.PortStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; -import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; import org.apache.nifi.web.api.entity.AccessPolicyEntity; import org.apache.nifi.web.api.entity.ConnectionEntity; +import org.apache.nifi.web.api.entity.ConnectionStatusEntity; import org.apache.nifi.web.api.entity.ControllerBulletinsEntity; import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; import org.apache.nifi.web.api.entity.ControllerServiceEntity; @@ -82,14 +77,19 @@ import org.apache.nifi.web.api.entity.FlowEntity; import org.apache.nifi.web.api.entity.FunnelEntity; import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.PortEntity; +import org.apache.nifi.web.api.entity.PortStatusEntity; import org.apache.nifi.web.api.entity.ProcessGroupEntity; import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ProcessorEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; import org.apache.nifi.web.api.entity.ScheduleComponentsEntity; import org.apache.nifi.web.api.entity.SnippetEntity; +import org.apache.nifi.web.api.entity.StatusHistoryEntity; import org.apache.nifi.web.api.entity.TemplateEntity; import org.apache.nifi.web.api.entity.UserEntity; import org.apache.nifi.web.api.entity.UserGroupEntity; @@ -290,7 +290,7 @@ public interface NiFiServiceFacade { * @param groupId group * @return The process group status */ - ProcessGroupStatusDTO getProcessGroupStatus(String groupId); + ProcessGroupStatusEntity getProcessGroupStatus(String groupId, boolean recursive); /** * Gets the process group status history. @@ -298,7 +298,7 @@ public interface NiFiServiceFacade { * @param groupId id * @return history */ - StatusHistoryDTO getProcessGroupStatusHistory(String groupId); + StatusHistoryEntity getProcessGroupStatusHistory(String groupId); /** * Returns the controller status. @@ -455,7 +455,7 @@ public interface NiFiServiceFacade { * @param id id * @return status */ - ProcessorStatusDTO getProcessorStatus(String id); + ProcessorStatusEntity getProcessorStatus(String id); /** * Gets the processor status history. @@ -463,7 +463,7 @@ public interface NiFiServiceFacade { * @param id id * @return history */ - StatusHistoryDTO getProcessorStatusHistory(String id); + StatusHistoryEntity getProcessorStatusHistory(String id); /** * Get the descriptor for the specified property of the specified processor. @@ -540,7 +540,7 @@ public interface NiFiServiceFacade { * @param connectionId connection * @return status */ - ConnectionStatusDTO getConnectionStatus(String connectionId); + ConnectionStatusEntity getConnectionStatus(String connectionId); /** * Gets the status history of the specified connection. @@ -548,7 +548,7 @@ public interface NiFiServiceFacade { * @param connectionId connection * @return history */ - StatusHistoryDTO getConnectionStatusHistory(String connectionId); + StatusHistoryEntity getConnectionStatusHistory(String connectionId); /** * Creates a new Relationship target. @@ -708,7 +708,7 @@ public interface NiFiServiceFacade { * @param inputPortId input port * @return status */ - PortStatusDTO getInputPortStatus(String inputPortId); + PortStatusEntity getInputPortStatus(String inputPortId); /** * Determines if the input port could be updated. @@ -777,7 +777,7 @@ public interface NiFiServiceFacade { * @param outputPortId output port * @return status */ - PortStatusDTO getOutputPortStatus(String outputPortId); + PortStatusEntity getOutputPortStatus(String outputPortId); /** * Determines if the output port could be updated. @@ -937,7 +937,7 @@ public interface NiFiServiceFacade { * @param id remote process group * @return status */ - RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(String id); + RemoteProcessGroupStatusEntity getRemoteProcessGroupStatus(String id); /** * Gets the remote process group status history. @@ -945,7 +945,7 @@ public interface NiFiServiceFacade { * @param id The id of the remote process group * @return history */ - StatusHistoryDTO getRemoteProcessGroupStatusHistory(String id); + StatusHistoryEntity getRemoteProcessGroupStatusHistory(String id); /** * Verifies the specified remote process group can be updated. diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index 56d6595ab8..f5cb078c8e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -1,3 +1,4 @@ +/* /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -139,14 +140,17 @@ import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO; import org.apache.nifi.web.api.dto.search.SearchResultsDTO; import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import org.apache.nifi.web.api.dto.status.ControllerStatusDTO; +import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.PortStatusDTO; import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; +import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; import org.apache.nifi.web.api.entity.AccessPolicyEntity; import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; import org.apache.nifi.web.api.entity.ConnectionEntity; +import org.apache.nifi.web.api.entity.ConnectionStatusEntity; import org.apache.nifi.web.api.entity.ControllerBulletinsEntity; import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; import org.apache.nifi.web.api.entity.ControllerServiceEntity; @@ -158,14 +162,19 @@ import org.apache.nifi.web.api.entity.FlowEntity; import org.apache.nifi.web.api.entity.FunnelEntity; import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.PortEntity; +import org.apache.nifi.web.api.entity.PortStatusEntity; import org.apache.nifi.web.api.entity.ProcessGroupEntity; import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ProcessorEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; import org.apache.nifi.web.api.entity.ScheduleComponentsEntity; import org.apache.nifi.web.api.entity.SnippetEntity; +import org.apache.nifi.web.api.entity.StatusHistoryEntity; import org.apache.nifi.web.api.entity.TemplateEntity; import org.apache.nifi.web.api.entity.TenantEntity; import org.apache.nifi.web.api.entity.UserEntity; @@ -850,6 +859,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public ConnectionEntity deleteConnection(final Revision revision, final String connectionId) { final Connection connection = connectionDAO.getConnection(connectionId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); final ConnectionDTO snapshot = deleteComponent( revision, connection.getResource(), @@ -857,7 +867,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { false, // no policies to remove dtoFactory.createConnectionDto(connection)); - return entityFactory.createConnectionEntity(snapshot, null, null, null); + return entityFactory.createConnectionEntity(snapshot, null, permissions, null); } @Override @@ -884,6 +894,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public ProcessorEntity deleteProcessor(final Revision revision, final String processorId) { final ProcessorNode processor = processorDAO.getProcessor(processorId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); final ProcessorDTO snapshot = deleteComponent( revision, processor.getResource(), @@ -891,12 +902,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createProcessorDto(processor)); - return entityFactory.createProcessorEntity(snapshot, null, null, null, null); + return entityFactory.createProcessorEntity(snapshot, null, permissions, null, null); } @Override public LabelEntity deleteLabel(final Revision revision, final String labelId) { final Label label = labelDAO.getLabel(labelId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label); final LabelDTO snapshot = deleteComponent( revision, label.getResource(), @@ -904,12 +916,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createLabelDto(label)); - return entityFactory.createLabelEntity(snapshot, null, null); + return entityFactory.createLabelEntity(snapshot, null, permissions); } @Override public UserEntity deleteUser(final Revision revision, final String userId) { final User user = userDAO.getUser(userId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); final Set userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream() .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null; final Set policyEntities = user != null ? userGroupDAO.getAccessPoliciesForUser(userId).stream() @@ -933,12 +946,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { false, // no user specific policies to remove dtoFactory.createUserDto(user, userGroups, policyEntities)); - return entityFactory.createUserEntity(snapshot, null, null); + return entityFactory.createUserEntity(snapshot, null, permissions); } @Override public UserGroupEntity deleteUserGroup(final Revision revision, final String userGroupId) { final Group userGroup = userGroupDAO.getUserGroup(userGroupId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); final Set users = userGroup != null ? userGroup.getUsers().stream() .map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null; @@ -961,12 +975,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { false, // no user group specific policies to remove dtoFactory.createUserGroupDto(userGroup, users)); - return entityFactory.createUserGroupEntity(snapshot, null, null); + return entityFactory.createUserGroupEntity(snapshot, null, permissions); } @Override public AccessPolicyEntity deleteAccessPolicy(final Revision revision, final String accessPolicyId) { final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyId)); final Set userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null; final Set users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null; final AccessPolicyDTO snapshot = deleteComponent( @@ -987,12 +1002,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users)); - return entityFactory.createAccessPolicyEntity(snapshot, null, null); + return entityFactory.createAccessPolicyEntity(snapshot, null, permissions); } @Override public FunnelEntity deleteFunnel(final Revision revision, final String funnelId) { final Funnel funnel = funnelDAO.getFunnel(funnelId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel); final FunnelDTO snapshot = deleteComponent( revision, funnel.getResource(), @@ -1000,7 +1016,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createFunnelDto(funnel)); - return entityFactory.createFunnelEntity(snapshot, null, null); + return entityFactory.createFunnelEntity(snapshot, null, permissions); } /** @@ -1131,6 +1147,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public PortEntity deleteInputPort(final Revision revision, final String inputPortId) { final Port port = inputPortDAO.getPort(inputPortId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port); final PortDTO snapshot = deleteComponent( revision, port.getResource(), @@ -1138,12 +1155,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createPortDto(port)); - return entityFactory.createPortEntity(snapshot, null, null, null, null); + return entityFactory.createPortEntity(snapshot, null, permissions, null, null); } @Override public PortEntity deleteOutputPort(final Revision revision, final String outputPortId) { final Port port = outputPortDAO.getPort(outputPortId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port); final PortDTO snapshot = deleteComponent( revision, port.getResource(), @@ -1151,12 +1169,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createPortDto(port)); - return entityFactory.createPortEntity(snapshot, null, null, null, null); + return entityFactory.createPortEntity(snapshot, null, permissions, null, null); } @Override public ProcessGroupEntity deleteProcessGroup(final Revision revision, final String groupId) { final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); // grab the resources in the snippet so we can delete the policies afterwards final Set groupResources = new HashSet<>(); @@ -1180,12 +1199,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { // delete all applicable component policies groupResources.forEach(groupResource -> cleanUpPolicies(groupResource)); - return entityFactory.createProcessGroupEntity(snapshot, null, null, null, null); + return entityFactory.createProcessGroupEntity(snapshot, null, permissions, null, null); } @Override public RemoteProcessGroupEntity deleteRemoteProcessGroup(final Revision revision, final String remoteProcessGroupId) { final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); final RemoteProcessGroupDTO snapshot = deleteComponent( revision, remoteProcessGroup.getResource(), @@ -1193,7 +1213,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup)); - return entityFactory.createRemoteProcessGroupEntity(snapshot, null, null, null, null); + return entityFactory.createRemoteProcessGroupEntity(snapshot, null, permissions, null, null); } @Override @@ -1846,6 +1866,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public ControllerServiceEntity deleteControllerService(final Revision revision, final String controllerServiceId) { final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService); final ControllerServiceDTO snapshot = deleteComponent( revision, controllerService.getResource(), @@ -1853,7 +1874,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createControllerServiceDto(controllerService)); - return entityFactory.createControllerServiceEntity(snapshot, null, null, null); + return entityFactory.createControllerServiceEntity(snapshot, null, permissions, null); } @@ -1900,6 +1921,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public ReportingTaskEntity deleteReportingTask(final Revision revision, final String reportingTaskId) { final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask); final ReportingTaskDTO snapshot = deleteComponent( revision, reportingTask.getResource(), @@ -1907,7 +1929,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { true, dtoFactory.createReportingTaskDto(reportingTask)); - return entityFactory.createReportingTaskEntity(snapshot, null, null, null); + return entityFactory.createReportingTaskEntity(snapshot, null, permissions, null); } @Override @@ -2001,8 +2023,33 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public ProcessGroupStatusDTO getProcessGroupStatus(final String groupId) { - return dtoFactory.createProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(groupId)); + public ProcessGroupStatusEntity getProcessGroupStatus(final String groupId, final boolean recursive) { + final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); + final ProcessGroupStatusDTO dto = dtoFactory.createProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(groupId)); + + // prune the response as necessary + if (!recursive) { + pruneChildGroups(dto.getAggregateSnapshot()); + if (dto.getNodeSnapshots() != null) { + for (final NodeProcessGroupStatusSnapshotDTO nodeSnapshot : dto.getNodeSnapshots()) { + pruneChildGroups(nodeSnapshot.getStatusSnapshot()); + } + } + } + + return entityFactory.createProcessGroupStatusEntity(dto, permissions); + } + + private void pruneChildGroups(final ProcessGroupStatusSnapshotDTO snapshot) { + for (final ProcessGroupStatusSnapshotDTO childProcessGroupStatus : snapshot.getProcessGroupStatusSnapshots()) { + childProcessGroupStatus.setConnectionStatusSnapshots(null); + childProcessGroupStatus.setProcessGroupStatusSnapshots(null); + childProcessGroupStatus.setInputPortStatusSnapshots(null); + childProcessGroupStatus.setOutputPortStatusSnapshots(null); + childProcessGroupStatus.setProcessorStatusSnapshots(null); + childProcessGroupStatus.setRemoteProcessGroupStatusSnapshots(null); + } } @Override @@ -2103,13 +2150,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public ConnectionStatusDTO getConnectionStatus(final String connectionId) { - return dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionId)); + public ConnectionStatusEntity getConnectionStatus(final String connectionId) { + final Connection connection = connectionDAO.getConnection(connectionId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); + final ConnectionStatusDTO dto = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionId)); + return entityFactory.createConnectionStatusEntity(dto, permissions); } @Override - public StatusHistoryDTO getConnectionStatusHistory(final String connectionId) { - return controllerFacade.getConnectionStatusHistory(connectionId); + public StatusHistoryEntity getConnectionStatusHistory(final String connectionId) { + final Connection connection = connectionDAO.getConnection(connectionId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); + final StatusHistoryDTO dto = controllerFacade.getConnectionStatusHistory(connectionId); + return entityFactory.createStatusHistoryEntity(dto, permissions); } private ProcessorEntity createProcessorEntity(final ProcessorNode processor) { @@ -2198,13 +2251,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public ProcessorStatusDTO getProcessorStatus(final String id) { - return dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(id)); + public ProcessorStatusEntity getProcessorStatus(final String id) { + final ProcessorNode processor = processorDAO.getProcessor(id); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); + final ProcessorStatusDTO dto = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(id)); + return entityFactory.createProcessorStatusEntity(dto, permissions); } @Override - public StatusHistoryDTO getProcessorStatusHistory(final String id) { - return controllerFacade.getProcessorStatusHistory(id); + public StatusHistoryEntity getProcessorStatusHistory(final String id) { + final ProcessorNode processor = processorDAO.getProcessor(id); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); + final StatusHistoryDTO dto = controllerFacade.getProcessorStatusHistory(id); + return entityFactory.createStatusHistoryEntity(dto, permissions); } private boolean authorizeBulletin(final Bulletin bulletin) { @@ -2696,8 +2755,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public PortStatusDTO getInputPortStatus(final String inputPortId) { - return dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortId)); + public PortStatusEntity getInputPortStatus(final String inputPortId) { + final Port inputPort = inputPortDAO.getPort(inputPortId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(inputPort); + final PortStatusDTO dto = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortId)); + return entityFactory.createPortStatusEntity(dto, permissions); } @Override @@ -2707,8 +2769,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public PortStatusDTO getOutputPortStatus(final String outputPortId) { - return dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortId)); + public PortStatusEntity getOutputPortStatus(final String outputPortId) { + final Port outputPort = outputPortDAO.getPort(outputPortId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(outputPort); + final PortStatusDTO dto = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortId)); + return entityFactory.createPortStatusEntity(dto, permissions); } @Override @@ -2718,13 +2783,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(final String id) { - return dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(id)); + public RemoteProcessGroupStatusEntity getRemoteProcessGroupStatus(final String id) { + final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(id); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); + final RemoteProcessGroupStatusDTO dto = dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(id)); + return entityFactory.createRemoteProcessGroupStatusEntity(dto, permissions); } @Override - public StatusHistoryDTO getRemoteProcessGroupStatusHistory(final String id) { - return controllerFacade.getRemoteProcessGroupStatusHistory(id); + public StatusHistoryEntity getRemoteProcessGroupStatusHistory(final String id) { + final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(id); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); + final StatusHistoryDTO dto = controllerFacade.getRemoteProcessGroupStatusHistory(id); + return entityFactory.createStatusHistoryEntity(dto, permissions); } @Override @@ -2870,8 +2941,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public StatusHistoryDTO getProcessGroupStatusHistory(final String groupId) { - return controllerFacade.getProcessGroupStatusHistory(groupId); + public StatusHistoryEntity getProcessGroupStatusHistory(final String groupId) { + final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); + final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); + final StatusHistoryDTO dto = controllerFacade.getProcessGroupStatusHistory(groupId); + return entityFactory.createStatusHistoryEntity(dto, permissions); } private boolean authorizeAction(final Action action) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java index 3800161b15..73d4a0f3ca 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java @@ -47,6 +47,7 @@ import org.apache.nifi.controller.reporting.ReportingTaskProvider; import org.apache.nifi.registry.VariableRegistry; import org.apache.nifi.controller.service.ControllerServiceProvider; import org.apache.nifi.util.NiFiProperties; +import org.apache.nifi.web.api.dto.AllowableValueDTO; import org.apache.nifi.web.api.dto.ControllerServiceDTO; import org.apache.nifi.web.api.dto.ProcessorConfigDTO; import org.apache.nifi.web.api.dto.ProcessorDTO; @@ -476,11 +477,11 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration for(String key : processorConfig.getDescriptors().keySet()){ PropertyDescriptorDTO descriptor = processorConfig.getDescriptors().get(key); - List allowableValuesDTO = descriptor.getAllowableValues(); + List allowableValuesDTO = descriptor.getAllowableValues(); Map allowableValues = new HashMap<>(); if(allowableValuesDTO != null) { - for (PropertyDescriptorDTO.AllowableValueDTO value : allowableValuesDTO) { + for (AllowableValueDTO value : allowableValuesDTO) { allowableValues.put(value.getValue(), value.getDisplayName()); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java index e622b04d2a..4063a72b73 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java @@ -184,7 +184,7 @@ public class ControllerResource extends ApplicationResource { required = true ) final ControllerConfigurationEntity configEntity) { - if (configEntity == null || configEntity.getControllerConfiguration() == null) { + if (configEntity == null || configEntity.getComponent() == null) { throw new IllegalArgumentException("Controller configuration must be specified"); } @@ -205,7 +205,7 @@ public class ControllerResource extends ApplicationResource { }, null, () -> { - final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getControllerConfiguration()); + final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getComponent()); return clusterContext(generateOkResponse(entity)).build(); } ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java index 151a9c82a3..8dcbd73a83 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java @@ -61,15 +61,7 @@ import org.apache.nifi.web.api.dto.flow.FlowDTO; import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO; import org.apache.nifi.web.api.dto.search.NodeSearchResultDTO; import org.apache.nifi.web.api.dto.search.SearchResultsDTO; -import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import org.apache.nifi.web.api.dto.status.ControllerStatusDTO; -import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO; -import org.apache.nifi.web.api.dto.status.PortStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO; -import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; -import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; import org.apache.nifi.web.api.entity.AboutEntity; import org.apache.nifi.web.api.entity.ActionEntity; import org.apache.nifi.web.api.entity.BannerEntity; @@ -465,6 +457,10 @@ public class FlowResource extends ApplicationResource { authorizeFlow(); + if (isReplicateRequest()) { + return replicate(HttpMethod.GET); + } + // get all the controller services final Set controllerServices = serviceFacade.getControllerServices(groupId); controllerServiceResource.populateRemainingControllerServiceEntitiesContent(controllerServices); @@ -1273,13 +1269,7 @@ public class FlowResource extends ApplicationResource { } // get the specified processor status - final ProcessorStatusDTO processorStatus = serviceFacade.getProcessorStatus(id); - - // generate the response entity - final ProcessorStatusEntity entity = new ProcessorStatusEntity(); - entity.setProcessorStatus(processorStatus); - - // generate the response + final ProcessorStatusEntity entity = serviceFacade.getProcessorStatus(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1352,13 +1342,7 @@ public class FlowResource extends ApplicationResource { } // get the specified input port status - final PortStatusDTO portStatus = serviceFacade.getInputPortStatus(id); - - // generate the response entity - final PortStatusEntity entity = new PortStatusEntity(); - entity.setPortStatus(portStatus); - - // generate the response + final PortStatusEntity entity = serviceFacade.getInputPortStatus(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1431,13 +1415,7 @@ public class FlowResource extends ApplicationResource { } // get the specified output port status - final PortStatusDTO portStatus = serviceFacade.getOutputPortStatus(id); - - // generate the response entity - final PortStatusEntity entity = new PortStatusEntity(); - entity.setPortStatus(portStatus); - - // generate the response + final PortStatusEntity entity = serviceFacade.getOutputPortStatus(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1510,13 +1488,7 @@ public class FlowResource extends ApplicationResource { } // get the specified remote process group status - final RemoteProcessGroupStatusDTO remoteProcessGroupStatus = serviceFacade.getRemoteProcessGroupStatus(id); - - // generate the response entity - final RemoteProcessGroupStatusEntity entity = new RemoteProcessGroupStatusEntity(); - entity.setRemoteProcessGroupStatus(remoteProcessGroupStatus); - - // generate the response + final RemoteProcessGroupStatusEntity entity = serviceFacade.getRemoteProcessGroupStatus(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1597,37 +1569,10 @@ public class FlowResource extends ApplicationResource { } // get the status - final ProcessGroupStatusDTO statusReport = serviceFacade.getProcessGroupStatus(groupId); - - // prune the response as necessary - if (!recursive) { - pruneChildGroups(statusReport.getAggregateSnapshot()); - if (statusReport.getNodeSnapshots() != null) { - for (final NodeProcessGroupStatusSnapshotDTO nodeSnapshot : statusReport.getNodeSnapshots()) { - pruneChildGroups(nodeSnapshot.getStatusSnapshot()); - } - } - } - - // create the response entity - final ProcessGroupStatusEntity entity = new ProcessGroupStatusEntity(); - entity.setProcessGroupStatus(statusReport); - - // generate the response + final ProcessGroupStatusEntity entity = serviceFacade.getProcessGroupStatus(groupId, recursive); return clusterContext(generateOkResponse(entity)).build(); } - private void pruneChildGroups(final ProcessGroupStatusSnapshotDTO snapshot) { - for (final ProcessGroupStatusSnapshotDTO childProcessGroupStatus : snapshot.getProcessGroupStatusSnapshots()) { - childProcessGroupStatus.setConnectionStatusSnapshots(null); - childProcessGroupStatus.setProcessGroupStatusSnapshots(null); - childProcessGroupStatus.setInputPortStatusSnapshots(null); - childProcessGroupStatus.setOutputPortStatusSnapshots(null); - childProcessGroupStatus.setProcessorStatusSnapshots(null); - childProcessGroupStatus.setRemoteProcessGroupStatusSnapshots(null); - } - } - /** * Retrieves the specified connection status. * @@ -1697,13 +1642,7 @@ public class FlowResource extends ApplicationResource { } // get the specified connection status - final ConnectionStatusDTO connectionStatus = serviceFacade.getConnectionStatus(id); - - // generate the response entity - final ConnectionStatusEntity entity = new ConnectionStatusEntity(); - entity.setConnectionStatus(connectionStatus); - - // generate the response + final ConnectionStatusEntity entity = serviceFacade.getConnectionStatus(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1753,13 +1692,7 @@ public class FlowResource extends ApplicationResource { } // get the specified processor status history - final StatusHistoryDTO processorStatusHistory = serviceFacade.getProcessorStatusHistory(id); - - // generate the response entity - final StatusHistoryEntity entity = new StatusHistoryEntity(); - entity.setStatusHistory(processorStatusHistory); - - // generate the response + final StatusHistoryEntity entity = serviceFacade.getProcessorStatusHistory(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1805,13 +1738,7 @@ public class FlowResource extends ApplicationResource { } // get the specified processor status history - final StatusHistoryDTO processGroupStatusHistory = serviceFacade.getProcessGroupStatusHistory(groupId); - - // generate the response entity - final StatusHistoryEntity entity = new StatusHistoryEntity(); - entity.setStatusHistory(processGroupStatusHistory); - - // generate the response + final StatusHistoryEntity entity = serviceFacade.getProcessGroupStatusHistory(groupId); return clusterContext(generateOkResponse(entity)).build(); } @@ -1857,13 +1784,7 @@ public class FlowResource extends ApplicationResource { } // get the specified processor status history - final StatusHistoryDTO remoteProcessGroupStatusHistory = serviceFacade.getRemoteProcessGroupStatusHistory(id); - - // generate the response entity - final StatusHistoryEntity entity = new StatusHistoryEntity(); - entity.setStatusHistory(remoteProcessGroupStatusHistory); - - // generate the response + final StatusHistoryEntity entity = serviceFacade.getRemoteProcessGroupStatusHistory(id); return clusterContext(generateOkResponse(entity)).build(); } @@ -1909,13 +1830,7 @@ public class FlowResource extends ApplicationResource { } // get the specified processor status history - final StatusHistoryDTO connectionStatusHistory = serviceFacade.getConnectionStatusHistory(id); - - // generate the response entity - final StatusHistoryEntity entity = new StatusHistoryEntity(); - entity.setStatusHistory(connectionStatusHistory); - - // generate the response + final StatusHistoryEntity entity = serviceFacade.getConnectionStatusHistory(id); return clusterContext(generateOkResponse(entity)).build(); } 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 e847b8b731..119e4777ea 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 @@ -110,7 +110,6 @@ import org.apache.nifi.util.FormatUtils; import org.apache.nifi.util.StringUtils; import org.apache.nifi.web.FlowModification; import org.apache.nifi.web.Revision; -import org.apache.nifi.web.api.dto.PropertyDescriptorDTO.AllowableValueDTO; import org.apache.nifi.web.api.dto.action.ActionDTO; import org.apache.nifi.web.api.dto.action.HistoryDTO; import org.apache.nifi.web.api.dto.action.component.details.ComponentDetailsDTO; @@ -141,7 +140,12 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; +import org.apache.nifi.web.api.entity.ConnectionStatusSnapshotEntity; import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity; +import org.apache.nifi.web.api.entity.PortStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusSnapshotEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusSnapshotEntity; import org.apache.nifi.web.api.entity.TenantEntity; import org.apache.nifi.web.controller.ControllerFacade; import org.apache.nifi.web.revision.RevisionManager; @@ -900,73 +904,86 @@ public final class DtoFactory { return processGroupStatusDto; } - public ProcessGroupStatusDTO createProcessGroupStatusDto(final ProcessGroupStatus processGroupStatus) { + public ProcessGroupStatusDTO createProcessGroupStatusDto(final ProcessGroup processGroup, final ProcessGroupStatus processGroupStatus) { final ProcessGroupStatusDTO processGroupStatusDto = createConciseProcessGroupStatusDto(processGroupStatus); final ProcessGroupStatusSnapshotDTO snapshot = processGroupStatusDto.getAggregateSnapshot(); // processor status - final Collection processorStatDtoCollection = new ArrayList<>(); - snapshot.setProcessorStatusSnapshots(processorStatDtoCollection); + final Collection processorStatusSnapshotEntities = new ArrayList<>(); + snapshot.setProcessorStatusSnapshots(processorStatusSnapshotEntities); final Collection processorStatusCollection = processGroupStatus.getProcessorStatus(); if (processorStatusCollection != null) { for (final ProcessorStatus processorStatus : processorStatusCollection) { final ProcessorStatusDTO processorStatusDto = createProcessorStatusDto(processorStatus); - processorStatDtoCollection.add(processorStatusDto.getAggregateSnapshot()); + final ProcessorNode processor = processGroup.findProcessor(processorStatusDto.getId()); + final PermissionsDTO processorPermissions = createPermissionsDto(processor); + processorStatusSnapshotEntities.add(entityFactory.createProcessorStatusSnapshotEntity(processorStatusDto.getAggregateSnapshot(), processorPermissions)); } } // connection status - final Collection connectionStatusDtoCollection = new ArrayList<>(); + final Collection connectionStatusDtoCollection = new ArrayList<>(); snapshot.setConnectionStatusSnapshots(connectionStatusDtoCollection); final Collection connectionStatusCollection = processGroupStatus.getConnectionStatus(); if (connectionStatusCollection != null) { for (final ConnectionStatus connectionStatus : connectionStatusCollection) { final ConnectionStatusDTO connectionStatusDto = createConnectionStatusDto(connectionStatus); - connectionStatusDtoCollection.add(connectionStatusDto.getAggregateSnapshot()); + final Connection connection = processGroup.findConnection(connectionStatusDto.getId()); + final PermissionsDTO connectionPermissions = createPermissionsDto(connection); + connectionStatusDtoCollection.add(entityFactory.createConnectionStatusSnapshotEntity(connectionStatusDto.getAggregateSnapshot(), connectionPermissions)); } } // local child process groups - final Collection childProcessGroupStatusDtoCollection = new ArrayList<>(); + final Collection childProcessGroupStatusDtoCollection = new ArrayList<>(); snapshot.setProcessGroupStatusSnapshots(childProcessGroupStatusDtoCollection); final Collection childProcessGroupStatusCollection = processGroupStatus.getProcessGroupStatus(); if (childProcessGroupStatusCollection != null) { for (final ProcessGroupStatus childProcessGroupStatus : childProcessGroupStatusCollection) { - final ProcessGroupStatusDTO childProcessGroupStatusDto = createProcessGroupStatusDto(childProcessGroupStatus); - childProcessGroupStatusDtoCollection.add(childProcessGroupStatusDto.getAggregateSnapshot()); + final ProcessGroupStatusDTO childProcessGroupStatusDto = createProcessGroupStatusDto(processGroup, childProcessGroupStatus); + final ProcessGroup childProcessGroup = processGroup.findProcessGroup(childProcessGroupStatusDto.getId()); + final PermissionsDTO childProcessGroupPermissions = createPermissionsDto(childProcessGroup); + childProcessGroupStatusDtoCollection.add(entityFactory.createProcessGroupStatusSnapshotEntity(childProcessGroupStatusDto.getAggregateSnapshot(), childProcessGroupPermissions)); } } // remote child process groups - final Collection childRemoteProcessGroupStatusDtoCollection = new ArrayList<>(); + final Collection childRemoteProcessGroupStatusDtoCollection = new ArrayList<>(); snapshot.setRemoteProcessGroupStatusSnapshots(childRemoteProcessGroupStatusDtoCollection); final Collection childRemoteProcessGroupStatusCollection = processGroupStatus.getRemoteProcessGroupStatus(); if (childRemoteProcessGroupStatusCollection != null) { for (final RemoteProcessGroupStatus childRemoteProcessGroupStatus : childRemoteProcessGroupStatusCollection) { final RemoteProcessGroupStatusDTO childRemoteProcessGroupStatusDto = createRemoteProcessGroupStatusDto(childRemoteProcessGroupStatus); - childRemoteProcessGroupStatusDtoCollection.add(childRemoteProcessGroupStatusDto.getAggregateSnapshot()); + final RemoteProcessGroup remoteProcessGroup = processGroup.findRemoteProcessGroup(childRemoteProcessGroupStatusDto.getId()); + final PermissionsDTO remoteProcessGroupPermissions = createPermissionsDto(remoteProcessGroup); + childRemoteProcessGroupStatusDtoCollection.add(entityFactory.createRemoteProcessGroupStatusSnapshotEntity(childRemoteProcessGroupStatusDto.getAggregateSnapshot(), + remoteProcessGroupPermissions)); } } // input ports - final Collection inputPortStatusDtoCollection = new ArrayList<>(); + final Collection inputPortStatusDtoCollection = new ArrayList<>(); snapshot.setInputPortStatusSnapshots(inputPortStatusDtoCollection); final Collection inputPortStatusCollection = processGroupStatus.getInputPortStatus(); if (inputPortStatusCollection != null) { for (final PortStatus portStatus : inputPortStatusCollection) { final PortStatusDTO portStatusDto = createPortStatusDto(portStatus); - inputPortStatusDtoCollection.add(portStatusDto.getAggregateSnapshot()); + final Port inputPort = processGroup.findInputPort(portStatus.getId()); + final PermissionsDTO inputPortPermissions = createPermissionsDto(inputPort); + inputPortStatusDtoCollection.add(entityFactory.createPortStatusSnapshotEntity(portStatusDto.getAggregateSnapshot(), inputPortPermissions)); } } // output ports - final Collection outputPortStatusDtoCollection = new ArrayList<>(); + final Collection outputPortStatusDtoCollection = new ArrayList<>(); snapshot.setOutputPortStatusSnapshots(outputPortStatusDtoCollection); final Collection outputPortStatusCollection = processGroupStatus.getOutputPortStatus(); if (outputPortStatusCollection != null) { for (final PortStatus portStatus : outputPortStatusCollection) { final PortStatusDTO portStatusDto = createPortStatusDto(portStatus); - outputPortStatusDtoCollection.add(portStatusDto.getAggregateSnapshot()); + final Port outputPort = processGroup.findOutputPort(portStatus.getId()); + final PermissionsDTO outputPortPermissions = createPermissionsDto(outputPort); + outputPortStatusDtoCollection.add(entityFactory.createPortStatusSnapshotEntity(portStatusDto.getAggregateSnapshot(), outputPortPermissions)); } } 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 e3e30d5086..00e239c238 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 @@ -19,13 +19,21 @@ package org.apache.nifi.web.api.dto; import org.apache.nifi.web.api.dto.flow.FlowBreadcrumbDTO; import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO; import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; +import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.PortStatusDTO; +import org.apache.nifi.web.api.dto.status.PortStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; +import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; +import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; +import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO; +import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; import org.apache.nifi.web.api.entity.AccessPolicyEntity; import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; import org.apache.nifi.web.api.entity.ConnectionEntity; +import org.apache.nifi.web.api.entity.ConnectionStatusEntity; +import org.apache.nifi.web.api.entity.ConnectionStatusSnapshotEntity; import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; import org.apache.nifi.web.api.entity.ControllerServiceEntity; import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity; @@ -33,13 +41,22 @@ import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity; import org.apache.nifi.web.api.entity.FunnelEntity; import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.PortEntity; +import org.apache.nifi.web.api.entity.PortStatusEntity; +import org.apache.nifi.web.api.entity.PortStatusSnapshotEntity; import org.apache.nifi.web.api.entity.ProcessGroupEntity; import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; +import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity; import org.apache.nifi.web.api.entity.ProcessorEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusEntity; +import org.apache.nifi.web.api.entity.ProcessorStatusSnapshotEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; +import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusSnapshotEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; import org.apache.nifi.web.api.entity.SnippetEntity; +import org.apache.nifi.web.api.entity.StatusHistoryEntity; import org.apache.nifi.web.api.entity.TenantEntity; import org.apache.nifi.web.api.entity.UserEntity; import org.apache.nifi.web.api.entity.UserGroupEntity; @@ -49,20 +66,105 @@ import java.util.List; public final class EntityFactory { + private static final String NO_PERMISSIONS_MESSAGE = "No permissions were associated with this request"; + + public StatusHistoryEntity createStatusHistoryEntity(final StatusHistoryDTO statusHistory, final PermissionsDTO permissions) { + final StatusHistoryEntity entity = new StatusHistoryEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setStatusHistory(statusHistory); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public ProcessorStatusEntity createProcessorStatusEntity(final ProcessorStatusDTO status, final PermissionsDTO permissions) { + final ProcessorStatusEntity entity = new ProcessorStatusEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setProcessorStatus(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public ProcessorStatusSnapshotEntity createProcessorStatusSnapshotEntity(final ProcessorStatusSnapshotDTO status, final PermissionsDTO permissions) { + final ProcessorStatusSnapshotEntity entity = new ProcessorStatusSnapshotEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setProcessorStatusSnapshot(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public ConnectionStatusEntity createConnectionStatusEntity(final ConnectionStatusDTO status, final PermissionsDTO permissions) { + final ConnectionStatusEntity entity = new ConnectionStatusEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setConnectionStatus(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public ConnectionStatusSnapshotEntity createConnectionStatusSnapshotEntity(final ConnectionStatusSnapshotDTO status, final PermissionsDTO permissions) { + final ConnectionStatusSnapshotEntity entity = new ConnectionStatusSnapshotEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setConnectionStatusSnapshot(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public ProcessGroupStatusEntity createProcessGroupStatusEntity(final ProcessGroupStatusDTO status, final PermissionsDTO permissions) { + final ProcessGroupStatusEntity entity = new ProcessGroupStatusEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setProcessGroupStatus(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public ProcessGroupStatusSnapshotEntity createProcessGroupStatusSnapshotEntity(final ProcessGroupStatusSnapshotDTO status, final PermissionsDTO permissions) { + final ProcessGroupStatusSnapshotEntity entity = new ProcessGroupStatusSnapshotEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setProcessGroupStatusSnapshot(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public RemoteProcessGroupStatusEntity createRemoteProcessGroupStatusEntity(final RemoteProcessGroupStatusDTO status, final PermissionsDTO permissions) { + final RemoteProcessGroupStatusEntity entity = new RemoteProcessGroupStatusEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setRemoteProcessGroupStatus(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public RemoteProcessGroupStatusSnapshotEntity createRemoteProcessGroupStatusSnapshotEntity(final RemoteProcessGroupStatusSnapshotDTO status, final PermissionsDTO permissions) { + final RemoteProcessGroupStatusSnapshotEntity entity = new RemoteProcessGroupStatusSnapshotEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setRemoteProcessGroupStatusSnapshot(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public PortStatusEntity createPortStatusEntity(final PortStatusDTO status, final PermissionsDTO permissions) { + final PortStatusEntity entity = new PortStatusEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setPortStatus(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + + public PortStatusSnapshotEntity createPortStatusSnapshotEntity(final PortStatusSnapshotDTO status, final PermissionsDTO permissions) { + final PortStatusSnapshotEntity entity = new PortStatusSnapshotEntity(); + entity.setCanRead(permissions.getCanRead()); + entity.setPortStatusSnapshot(status); // always set the status, as it's always allowed... just need to provide permission context for merging responses + return entity; + } + public ControllerConfigurationEntity createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ControllerConfigurationEntity entity = new ControllerConfigurationEntity(); entity.setRevision(revision); entity.setCurrentTime(new Date()); if (dto != null) { entity.setPermissions(permissions); - if (permissions != null && permissions.getCanRead()) { - entity.setControllerConfiguration(dto); + if (permissions.getCanRead()) { + entity.setComponent(dto); } } return entity; } public ProcessGroupFlowEntity createProcessGroupFlowEntity(final ProcessGroupFlowDTO dto, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ProcessGroupFlowEntity entity = new ProcessGroupFlowEntity(); entity.setProcessGroupFlow(dto); entity.setPermissions(permissions); @@ -72,6 +174,9 @@ public final class EntityFactory { public ProcessorEntity createProcessorEntity(final ProcessorDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final ProcessorStatusDTO status, final List bulletins) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ProcessorEntity entity = new ProcessorEntity(); entity.setRevision(revision); if (dto != null) { @@ -80,7 +185,7 @@ public final class EntityFactory { entity.setId(dto.getId()); entity.setInputRequirement(dto.getInputRequirement()); entity.setPosition(dto.getPosition()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); entity.setBulletins(bulletins); } @@ -89,6 +194,9 @@ public final class EntityFactory { } public PortEntity createPortEntity(final PortDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final PortStatusDTO status, final List bulletins) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final PortEntity entity = new PortEntity(); entity.setRevision(revision); if (dto != null) { @@ -97,7 +205,7 @@ public final class EntityFactory { entity.setId(dto.getId()); entity.setPosition(dto.getPosition()); entity.setPortType(dto.getType()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); entity.setBulletins(bulletins); } @@ -108,6 +216,9 @@ public final class EntityFactory { public ProcessGroupEntity createProcessGroupEntity(final ProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final ProcessGroupStatusDTO status, final List bulletins) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ProcessGroupEntity entity = new ProcessGroupEntity(); entity.setRevision(revision); entity.setCurrentTime(new Date()); @@ -133,6 +244,9 @@ public final class EntityFactory { } public LabelEntity createLabelEntity(final LabelDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final LabelEntity entity = new LabelEntity(); entity.setRevision(revision); if (dto != null) { @@ -145,7 +259,7 @@ public final class EntityFactory { dimensions.setWidth(dto.getWidth()); entity.setDimensions(dimensions); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -153,13 +267,16 @@ public final class EntityFactory { } public UserEntity createUserEntity(final UserDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final UserEntity entity = new UserEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -167,13 +284,16 @@ public final class EntityFactory { } public TenantEntity createTenantEntity(final TenantDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final TenantEntity entity = new TenantEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -181,13 +301,16 @@ public final class EntityFactory { } public AccessPolicySummaryEntity createAccessPolicySummaryEntity(final AccessPolicySummaryDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final AccessPolicySummaryEntity entity = new AccessPolicySummaryEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -195,13 +318,16 @@ public final class EntityFactory { } public UserGroupEntity createUserGroupEntity(final UserGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final UserGroupEntity entity = new UserGroupEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -209,6 +335,9 @@ public final class EntityFactory { } public AccessPolicyEntity createAccessPolicyEntity(final AccessPolicyDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final AccessPolicyEntity entity = new AccessPolicyEntity(); entity.setRevision(revision); entity.setGenerated(new Date()); @@ -216,7 +345,7 @@ public final class EntityFactory { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -224,13 +353,16 @@ public final class EntityFactory { } public FunnelEntity createFunnelEntity(final FunnelDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final FunnelEntity entity = new FunnelEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); entity.setPosition(dto.getPosition()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -238,6 +370,9 @@ public final class EntityFactory { } public ConnectionEntity createConnectionEntity(final ConnectionDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final ConnectionStatusDTO status) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ConnectionEntity entity = new ConnectionEntity(); entity.setRevision(revision); if (dto != null) { @@ -254,7 +389,7 @@ public final class EntityFactory { entity.setDestinationId(dto.getDestination().getId()); entity.setDestinationGroupId(dto.getDestination().getGroupId()); entity.setDestinationType(dto.getDestination().getType()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -264,6 +399,9 @@ public final class EntityFactory { public RemoteProcessGroupEntity createRemoteProcessGroupEntity(final RemoteProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final RemoteProcessGroupStatusDTO status, final List bulletins) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final RemoteProcessGroupEntity entity = new RemoteProcessGroupEntity(); entity.setRevision(revision); if (dto != null) { @@ -273,7 +411,7 @@ public final class EntityFactory { entity.setPosition(dto.getPosition()); entity.setInputPortCount(dto.getInputPortCount()); entity.setOutputPortCount(dto.getOutputPortCount()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); entity.setBulletins(bulletins); } @@ -282,12 +420,15 @@ public final class EntityFactory { } public RemoteProcessGroupPortEntity createRemoteProcessGroupPortEntity(final RemoteProcessGroupPortDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setRemoteProcessGroupPort(dto); } } @@ -302,12 +443,15 @@ public final class EntityFactory { } public ReportingTaskEntity createReportingTaskEntity(final ReportingTaskDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final List bulletins) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ReportingTaskEntity entity = new ReportingTaskEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); entity.setBulletins(bulletins); } @@ -317,13 +461,16 @@ public final class EntityFactory { } public ControllerServiceEntity createControllerServiceEntity(final ControllerServiceDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final List bulletins) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ControllerServiceEntity entity = new ControllerServiceEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); entity.setPosition(dto.getPosition()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); entity.setBulletins(bulletins); } @@ -334,12 +481,15 @@ public final class EntityFactory { public ControllerServiceReferencingComponentEntity createControllerServiceReferencingComponentEntity( final ControllerServiceReferencingComponentDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final ControllerServiceReferencingComponentEntity entity = new ControllerServiceReferencingComponentEntity(); entity.setRevision(revision); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setComponent(dto); } } @@ -348,11 +498,14 @@ public final class EntityFactory { } public FlowBreadcrumbEntity createFlowBreadcrumbEntity(final FlowBreadcrumbDTO dto, final PermissionsDTO permissions) { + if (permissions == null || permissions.getCanRead() == null) { + throw new IllegalStateException(NO_PERMISSIONS_MESSAGE); + } final FlowBreadcrumbEntity entity = new FlowBreadcrumbEntity(); if (dto != null) { entity.setPermissions(permissions); entity.setId(dto.getId()); - if (permissions != null && permissions.getCanRead()) { + if (permissions.getCanRead()) { entity.setBreadcrumb(dto); } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js index 713a2c2d1e..eb0180b654 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js @@ -62,7 +62,7 @@ nf.Settings = (function () { 'version': version } }), - 'controllerConfiguration': configuration + 'component': configuration }; // save the new configuration details @@ -860,8 +860,8 @@ nf.Settings = (function () { if (response.permissions.canWrite) { // populate the settings - $('#maximum-timer-driven-thread-count-field').removeClass('unset').val(response.controllerConfiguration.maxTimerDrivenThreadCount); - $('#maximum-event-driven-thread-count-field').removeClass('unset').val(response.controllerConfiguration.maxEventDrivenThreadCount); + $('#maximum-timer-driven-thread-count-field').removeClass('unset').val(response.component.maxTimerDrivenThreadCount); + $('#maximum-event-driven-thread-count-field').removeClass('unset').val(response.component.maxEventDrivenThreadCount); setEditable(true); @@ -872,8 +872,8 @@ nf.Settings = (function () { } else { if (response.permissions.canRead) { // populate the settings - $('#read-only-maximum-timer-driven-thread-count-field').removeClass('unset').text(response.controllerConfiguration.maxTimerDrivenThreadCount); - $('#read-only-maximum-event-driven-thread-count-field').removeClass('unset').text(response.controllerConfiguration.maxEventDrivenThreadCount); + $('#read-only-maximum-timer-driven-thread-count-field').removeClass('unset').text(response.component.maxTimerDrivenThreadCount); + $('#read-only-maximum-event-driven-thread-count-field').removeClass('unset').text(response.component.maxEventDrivenThreadCount); } else { setUnauthorizedText(); }