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(); }