NIFI-1876 Implements merging of responses to successful requests based on authorization, returning the most restrictive response - Added StandardHttpResponseMergerSpec for testing response merging - Added Permissible interface - Added nifi-api/controller/archive to ProcessGroupEndpointMerger - Removed AbstractMultiEntityEndpoint.java, not used anymore - Implemented reponse merging for GET requests where there are some successful and problematic responses, returning most restrictive one. - Updated nf-settings.js with ControllerConfigurationEntity property rename from controllerConfiguration to component - Implemented merging of status DTOs based on read permission NIFI-2264 Implemented merging of status history results based on readability permissions - Added StatusHistoryEndpointMergerSpec to test merging of status history based on read permission

NIFI-1876 Added merging for labels, funnels, and controller service references.

NIFI-1876 Added Label and Funnel merging to FlowMerger.java

NIFI-1876 Added replication of request for process group controller services
 - Updated merging code for Status and Status History based on read permissions

NIFI-1876 Fixed issue with node status snapshots all looking like they came from one node
Updated ProcessGroupStatusSnapshotDTO to contain status snapshot entities to retain readability permission
Added entity classes for ConnectionStatusSnapshotDTO, PortStatusSnapshotDTO, ProcessGroupStatusSnapshotDTO, ProcessorStatusSnapshotDTO, and RemoteProcessGroupStatusSnapshotDTO
Updated PropertyDescriptorDTO to contain AllowableValueEntity to retain readability permission
Added entity class for AllowableValueDTO
Moved AllowableValueDTO to its own top-level class
Updated DtoFactory to get permissions for status snapshot entities
Updated StatusMerger to merge status snapshot entities

Signed-off-by: jpercivall <joepercivall@yahoo.com>
This commit is contained in:
Jeff Storck 2016-07-01 20:49:49 -04:00 committed by jpercivall
parent a9675552d9
commit 572dfed78a
101 changed files with 3024 additions and 1020 deletions

View File

@ -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 <code>null</code> 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();
}
}

View File

@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlType;
* Details for the access configuration. * Details for the access configuration.
*/ */
@XmlType(name = "permission") @XmlType(name = "permission")
public class PermissionsDTO { public class PermissionsDTO implements ReadablePermission, WritablePermission {
private Boolean canRead; private Boolean canRead;
private Boolean canWrite; private Boolean canWrite;
@ -36,10 +36,12 @@ public class PermissionsDTO {
value = "Indicates whether the user can read a given resource.", value = "Indicates whether the user can read a given resource.",
readOnly = true readOnly = true
) )
@Override
public Boolean getCanRead() { public Boolean getCanRead() {
return canRead; return canRead;
} }
@Override
public void setCanRead(Boolean canRead) { public void setCanRead(Boolean canRead) {
this.canRead = canRead; this.canRead = canRead;
} }
@ -51,10 +53,12 @@ public class PermissionsDTO {
value = "Indicates whether the user can write a given resource.", value = "Indicates whether the user can write a given resource.",
readOnly = true readOnly = true
) )
@Override
public Boolean getCanWrite() { public Boolean getCanWrite() {
return canWrite; return canWrite;
} }
@Override
public void setCanWrite(Boolean canWrite) { public void setCanWrite(Boolean canWrite) {
this.canWrite = canWrite; this.canWrite = canWrite;
} }

View File

@ -17,6 +17,8 @@
package org.apache.nifi.web.api.dto; package org.apache.nifi.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty; import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.entity.AllowableValueEntity;
import java.util.List; import java.util.List;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
@ -30,7 +32,7 @@ public class PropertyDescriptorDTO {
private String displayName; private String displayName;
private String description; private String description;
private String defaultValue; private String defaultValue;
private List<AllowableValueDTO> allowableValues; private List<AllowableValueEntity> allowableValues;
private Boolean required; private Boolean required;
private Boolean sensitive; private Boolean sensitive;
private Boolean dynamic; private Boolean dynamic;
@ -43,11 +45,11 @@ public class PropertyDescriptorDTO {
@ApiModelProperty( @ApiModelProperty(
value = "Allowable values for the property. If empty then the allowed values are not constrained." value = "Allowable values for the property. If empty then the allowed values are not constrained."
) )
public List<AllowableValueDTO> getAllowableValues() { public List<AllowableValueEntity> getAllowableValues() {
return allowableValues; return allowableValues;
} }
public void setAllowableValues(List<AllowableValueDTO> allowableValues) { public void setAllowableValues(List<AllowableValueEntity> allowableValues) {
this.allowableValues = allowableValues; this.allowableValues = allowableValues;
} }
@ -177,75 +179,4 @@ public class PropertyDescriptorDTO {
this.identifiesControllerService = identifiesControllerService; 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 <code>null</code> 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();
}
}
} }

View File

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

View File

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

View File

@ -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<NodePortStatusDTO> 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<NodePortStatusDTO> getNodePortStatus() {
return nodePortStatus;
}
public void setNodePortStatus(Collection<NodePortStatusDTO> 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;
}
}

View File

@ -17,15 +17,14 @@
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import java.util.ArrayList; import com.wordnik.swagger.annotations.ApiModelProperty;
import java.util.Date; import org.apache.nifi.web.api.dto.util.TimeAdapter;
import java.util.List;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.ArrayList;
import com.wordnik.swagger.annotations.ApiModelProperty; import java.util.Date;
import org.apache.nifi.web.api.dto.util.TimeAdapter; import java.util.List;
@XmlType(name = "connectionStatus") @XmlType(name = "connectionStatus")
public class ConnectionStatusDTO implements Cloneable { public class ConnectionStatusDTO implements Cloneable {
@ -37,9 +36,10 @@ public class ConnectionStatusDTO implements Cloneable {
private String sourceId; private String sourceId;
private String sourceName; private String sourceName;
private String destinationId; private String destinationId;
private String destinationName;
private String destinationName;
private ConnectionStatusSnapshotDTO aggregateSnapshot; private ConnectionStatusSnapshotDTO aggregateSnapshot;
private List<NodeConnectionStatusSnapshotDTO> nodeSnapshots; private List<NodeConnectionStatusSnapshotDTO> nodeSnapshots;
@ApiModelProperty("The ID of the connection") @ApiModelProperty("The ID of the connection")
@ -145,6 +145,7 @@ public class ConnectionStatusDTO implements Cloneable {
other.setSourceName(getSourceName()); other.setSourceName(getSourceName());
other.setAggregateSnapshot(getAggregateSnapshot().clone()); other.setAggregateSnapshot(getAggregateSnapshot().clone());
final List<NodeConnectionStatusSnapshotDTO> nodeStatuses = getNodeSnapshots(); final List<NodeConnectionStatusSnapshotDTO> nodeStatuses = getNodeSnapshots();
final List<NodeConnectionStatusSnapshotDTO> nodeStatusClones = new ArrayList<>(nodeStatuses.size()); final List<NodeConnectionStatusSnapshotDTO> nodeStatusClones = new ArrayList<>(nodeStatuses.size());
for (final NodeConnectionStatusSnapshotDTO nodeStatus : nodeStatuses) { for (final NodeConnectionStatusSnapshotDTO nodeStatus : nodeStatuses) {

View File

@ -17,6 +17,7 @@
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import com.wordnik.swagger.annotations.ApiModelProperty; import com.wordnik.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
/** /**
@ -250,7 +251,6 @@ public class ConnectionStatusSnapshotDTO implements Cloneable {
this.bytesQueued = bytesQueued; this.bytesQueued = bytesQueued;
} }
@Override @Override
public ConnectionStatusSnapshotDTO clone() { public ConnectionStatusSnapshotDTO clone() {
final ConnectionStatusSnapshotDTO other = new ConnectionStatusSnapshotDTO(); final ConnectionStatusSnapshotDTO other = new ConnectionStatusSnapshotDTO();

View File

@ -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;
}
}

View File

@ -17,14 +17,13 @@
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import java.util.Date; import com.wordnik.swagger.annotations.ApiModelProperty;
import java.util.List; import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
import com.wordnik.swagger.annotations.ApiModelProperty; import java.util.List;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
@XmlType(name = "portStatus") @XmlType(name = "portStatus")
public class PortStatusDTO { public class PortStatusDTO {

View File

@ -16,10 +16,10 @@
*/ */
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import javax.xml.bind.annotation.XmlType;
import com.wordnik.swagger.annotations.ApiModelProperty; import com.wordnik.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlType;
/** /**
* The status for a port in this NiFi. * The status for a port in this NiFi.
*/ */

View File

@ -17,14 +17,13 @@
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import java.util.Date; import com.wordnik.swagger.annotations.ApiModelProperty;
import java.util.List; import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
import com.wordnik.swagger.annotations.ApiModelProperty; import java.util.List;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
@XmlType(name = "processGroupStatus") @XmlType(name = "processGroupStatus")
public class ProcessGroupStatusDTO implements Cloneable { public class ProcessGroupStatusDTO implements Cloneable {
@ -44,7 +43,7 @@ public class ProcessGroupStatusDTO implements Cloneable {
this.id = id; this.id = id;
} }
@ApiModelProperty("The name of the PRocess Group") @ApiModelProperty("The name of the Process Group")
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -17,6 +17,11 @@
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import com.wordnik.swagger.annotations.ApiModelProperty; 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 javax.xml.bind.annotation.XmlType;
import java.util.ArrayList; import java.util.ArrayList;
@ -31,12 +36,12 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
private String id; private String id;
private String name; private String name;
private Collection<ConnectionStatusSnapshotDTO> connectionStatus; private Collection<ConnectionStatusSnapshotEntity> connectionStatus;
private Collection<ProcessorStatusSnapshotDTO> processorStatus; private Collection<ProcessorStatusSnapshotEntity> processorStatus;
private Collection<ProcessGroupStatusSnapshotDTO> processGroupStatus; private Collection<ProcessGroupStatusSnapshotEntity> processGroupStatus;
private Collection<RemoteProcessGroupStatusSnapshotDTO> remoteProcessGroupStatus; private Collection<RemoteProcessGroupStatusSnapshotEntity> remoteProcessGroupStatus;
private Collection<PortStatusSnapshotDTO> inputPortStatus; private Collection<PortStatusSnapshotEntity> inputPortStatus;
private Collection<PortStatusSnapshotDTO> outputPortStatus; private Collection<PortStatusSnapshotEntity> outputPortStatus;
private Integer flowFilesIn = 0; private Integer flowFilesIn = 0;
private Long bytesIn = 0L; private Long bytesIn = 0L;
@ -115,11 +120,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
* @return The status of all connections * @return The status of all connections
*/ */
@ApiModelProperty("The status of all conenctions in the process group.") @ApiModelProperty("The status of all conenctions in the process group.")
public Collection<ConnectionStatusSnapshotDTO> getConnectionStatusSnapshots() { public Collection<ConnectionStatusSnapshotEntity> getConnectionStatusSnapshots() {
return connectionStatus; return connectionStatus;
} }
public void setConnectionStatusSnapshots(Collection<ConnectionStatusSnapshotDTO> connectionStatus) { public void setConnectionStatusSnapshots(Collection<ConnectionStatusSnapshotEntity> connectionStatus) {
this.connectionStatus = connectionStatus; this.connectionStatus = connectionStatus;
} }
@ -129,11 +134,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
* @return The status of all process groups * @return The status of all process groups
*/ */
@ApiModelProperty("The status of all process groups in the process group.") @ApiModelProperty("The status of all process groups in the process group.")
public Collection<ProcessGroupStatusSnapshotDTO> getProcessGroupStatusSnapshots() { public Collection<ProcessGroupStatusSnapshotEntity> getProcessGroupStatusSnapshots() {
return processGroupStatus; return processGroupStatus;
} }
public void setProcessGroupStatusSnapshots(Collection<ProcessGroupStatusSnapshotDTO> processGroupStatus) { public void setProcessGroupStatusSnapshots(Collection<ProcessGroupStatusSnapshotEntity> processGroupStatus) {
this.processGroupStatus = processGroupStatus; this.processGroupStatus = processGroupStatus;
} }
@ -143,11 +148,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
* @return The status of all remote process groups * @return The status of all remote process groups
*/ */
@ApiModelProperty("The status of all remote process groups in the process group.") @ApiModelProperty("The status of all remote process groups in the process group.")
public Collection<RemoteProcessGroupStatusSnapshotDTO> getRemoteProcessGroupStatusSnapshots() { public Collection<RemoteProcessGroupStatusSnapshotEntity> getRemoteProcessGroupStatusSnapshots() {
return remoteProcessGroupStatus; return remoteProcessGroupStatus;
} }
public void setRemoteProcessGroupStatusSnapshots(final Collection<RemoteProcessGroupStatusSnapshotDTO> remoteProcessGroupStatus) { public void setRemoteProcessGroupStatusSnapshots(final Collection<RemoteProcessGroupStatusSnapshotEntity> remoteProcessGroupStatus) {
this.remoteProcessGroupStatus = remoteProcessGroupStatus; this.remoteProcessGroupStatus = remoteProcessGroupStatus;
} }
@ -157,11 +162,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
* @return The status of all processors * @return The status of all processors
*/ */
@ApiModelProperty("The status of all processors in the process group.") @ApiModelProperty("The status of all processors in the process group.")
public Collection<ProcessorStatusSnapshotDTO> getProcessorStatusSnapshots() { public Collection<ProcessorStatusSnapshotEntity> getProcessorStatusSnapshots() {
return processorStatus; return processorStatus;
} }
public void setProcessorStatusSnapshots(Collection<ProcessorStatusSnapshotDTO> processorStatus) { public void setProcessorStatusSnapshots(Collection<ProcessorStatusSnapshotEntity> processorStatus) {
this.processorStatus = processorStatus; this.processorStatus = processorStatus;
} }
@ -171,11 +176,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
* @return The status of all input ports * @return The status of all input ports
*/ */
@ApiModelProperty("The status of all input ports in the process group.") @ApiModelProperty("The status of all input ports in the process group.")
public Collection<PortStatusSnapshotDTO> getInputPortStatusSnapshots() { public Collection<PortStatusSnapshotEntity> getInputPortStatusSnapshots() {
return inputPortStatus; return inputPortStatus;
} }
public void setInputPortStatusSnapshots(Collection<PortStatusSnapshotDTO> inputPortStatus) { public void setInputPortStatusSnapshots(Collection<PortStatusSnapshotEntity> inputPortStatus) {
this.inputPortStatus = inputPortStatus; this.inputPortStatus = inputPortStatus;
} }
@ -185,11 +190,11 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
* @return The status of all output ports * @return The status of all output ports
*/ */
@ApiModelProperty("The status of all output ports in the process group.") @ApiModelProperty("The status of all output ports in the process group.")
public Collection<PortStatusSnapshotDTO> getOutputPortStatusSnapshots() { public Collection<PortStatusSnapshotEntity> getOutputPortStatusSnapshots() {
return outputPortStatus; return outputPortStatus;
} }
public void setOutputPortStatusSnapshots(Collection<PortStatusSnapshotDTO> outputPortStatus) { public void setOutputPortStatusSnapshots(Collection<PortStatusSnapshotEntity> outputPortStatus) {
this.outputPortStatus = outputPortStatus; this.outputPortStatus = outputPortStatus;
} }
@ -512,8 +517,8 @@ public class ProcessGroupStatusSnapshotDTO implements Cloneable {
other.setOutputPortStatusSnapshots(copy(getOutputPortStatusSnapshots())); other.setOutputPortStatusSnapshots(copy(getOutputPortStatusSnapshots()));
if (processGroupStatus != null) { if (processGroupStatus != null) {
final List<ProcessGroupStatusSnapshotDTO> childGroups = new ArrayList<>(); final List<ProcessGroupStatusSnapshotEntity> childGroups = new ArrayList<>();
for (final ProcessGroupStatusSnapshotDTO procGroupStatus : processGroupStatus) { for (final ProcessGroupStatusSnapshotEntity procGroupStatus : processGroupStatus) {
childGroups.add(procGroupStatus.clone()); childGroups.add(procGroupStatus.clone());
} }
other.setProcessGroupStatusSnapshots(childGroups); other.setProcessGroupStatusSnapshots(childGroups);

View File

@ -17,15 +17,14 @@
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import java.util.ArrayList; import com.wordnik.swagger.annotations.ApiModelProperty;
import java.util.Date; import org.apache.nifi.web.api.dto.util.TimeAdapter;
import java.util.List;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.ArrayList;
import com.wordnik.swagger.annotations.ApiModelProperty; import java.util.Date;
import org.apache.nifi.web.api.dto.util.TimeAdapter; import java.util.List;
/** /**
* DTO for serializing the status of a processor. * DTO for serializing the status of a processor.

View File

@ -16,10 +16,10 @@
*/ */
package org.apache.nifi.web.api.dto.status; package org.apache.nifi.web.api.dto.status;
import javax.xml.bind.annotation.XmlType;
import com.wordnik.swagger.annotations.ApiModelProperty; import com.wordnik.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlType;
/** /**
* DTO for serializing the status of a processor. * DTO for serializing the status of a processor.
*/ */

View File

@ -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;
}
}

View File

@ -31,7 +31,7 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable {
private String name; private String name;
private String targetUri; private String targetUri;
private String transmissionStatus; private String transmissionStatus;
private Integer activeThreadCount; private Integer activeThreadCount = 0;
private Integer flowFilesSent = 0; private Integer flowFilesSent = 0;
private Long bytesSent = 0L; private Long bytesSent = 0L;
@ -174,7 +174,6 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable {
this.bytesReceived = bytesReceived; this.bytesReceived = bytesReceived;
} }
@Override @Override
public RemoteProcessGroupStatusSnapshotDTO clone() { public RemoteProcessGroupStatusSnapshotDTO clone() {
final RemoteProcessGroupStatusSnapshotDTO other = new RemoteProcessGroupStatusSnapshotDTO(); final RemoteProcessGroupStatusSnapshotDTO other = new RemoteProcessGroupStatusSnapshotDTO();
@ -193,5 +192,4 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable {
return other; return other;
} }
} }

View File

@ -16,28 +16,36 @@
*/ */
package org.apache.nifi.web.api.entity; package org.apache.nifi.web.api.entity;
import javax.xml.bind.annotation.XmlRootElement; import org.apache.nifi.web.api.dto.AllowableValueDTO;
import org.apache.nifi.web.api.dto.status.ClusterPortStatusDTO; 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 AllowableValueEntity extends Entity implements ReadablePermission {
public class ClusterPortStatusEntity extends Entity { private AllowableValueDTO allowableValue;
private Boolean canRead;
private ClusterPortStatusDTO clusterPortStatus;
/** /**
* The ClusterPortStatusDTO that is being serialized. * The AllowableValueDTO that is being serialized.
* *
* @return The ClusterPortStatusDTO object * @return The AllowableValueDTO object
*/ */
public ClusterPortStatusDTO getClusterPortStatus() { public AllowableValueDTO getAllowableValue() {
return clusterPortStatus; return allowableValue;
} }
public void setClusterPortStatus(ClusterPortStatusDTO clusterPortStatus) { public void setAllowableValue(AllowableValueDTO allowableValue) {
this.clusterPortStatus = clusterPortStatus; this.allowableValue = allowableValue;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -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. * 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") @XmlRootElement(name = "connectionEntity")
public class ConnectionEntity extends ComponentEntity { public class ConnectionEntity extends ComponentEntity implements Permissible<ConnectionDTO> {
private ConnectionDTO component; private ConnectionDTO component;
private ConnectionStatusDTO status; private ConnectionStatusDTO status;

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.nifi.web.api.entity; 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 org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
import javax.xml.bind.annotation.XmlRootElement; 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. * 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") @XmlRootElement(name = "connectionStatusEntity")
public class ConnectionStatusEntity extends Entity { public class ConnectionStatusEntity extends Entity implements ReadablePermission {
private ConnectionStatusDTO connectionStatus; private ConnectionStatusDTO connectionStatus;
private Boolean canRead;
/** /**
* The ConnectionStatusDTO that is being serialized. * The ConnectionStatusDTO that is being serialized.
@ -41,4 +43,13 @@ public class ConnectionStatusEntity extends Entity {
this.connectionStatus = connectionStatus; this.connectionStatus = connectionStatus;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -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;
}
}

View File

@ -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. * 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") @XmlRootElement(name = "controllerConfigurationEntity")
public class ControllerConfigurationEntity extends Entity { public class ControllerConfigurationEntity extends Entity implements Permissible<ControllerConfigurationDTO> {
private Date currentTime; private Date currentTime;
private ControllerConfigurationDTO controllerConfiguration; private ControllerConfigurationDTO controllerConfiguration;
@ -63,11 +63,11 @@ public class ControllerConfigurationEntity extends Entity {
@ApiModelProperty( @ApiModelProperty(
value = "The controller configuration." value = "The controller configuration."
) )
public ControllerConfigurationDTO getControllerConfiguration() { public ControllerConfigurationDTO getComponent() {
return controllerConfiguration; return controllerConfiguration;
} }
public void setControllerConfiguration(ControllerConfigurationDTO controllerConfiguration) { public void setComponent(ControllerConfigurationDTO controllerConfiguration) {
this.controllerConfiguration = controllerConfiguration; this.controllerConfiguration = controllerConfiguration;
} }

View File

@ -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. * 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") @XmlRootElement(name = "controllerServiceEntity")
public class ControllerServiceEntity extends ComponentEntity { public class ControllerServiceEntity extends ComponentEntity implements Permissible<ControllerServiceDTO> {
private ControllerServiceDTO component; private ControllerServiceDTO component;

View File

@ -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. * 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") @XmlRootElement(name = "funnelEntity")
public class FunnelEntity extends ComponentEntity { public class FunnelEntity extends ComponentEntity implements Permissible<FunnelDTO> {
private FunnelDTO component; private FunnelDTO component;

View File

@ -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. * 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") @XmlRootElement(name = "labelEntity")
public class LabelEntity extends ComponentEntity { public class LabelEntity extends ComponentEntity implements Permissible<LabelDTO> {
private DimensionsDTO dimensions; private DimensionsDTO dimensions;
private LabelDTO component; private LabelDTO component;

View File

@ -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 <DtoType> type of component
*/
public interface Permissible<DtoType> {
PermissionsDTO getPermissions();
void setPermissions(PermissionsDTO permissions);
DtoType getComponent();
void setComponent(DtoType dto);
}

View File

@ -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. * 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") @XmlRootElement(name = "portEntity")
public class PortEntity extends ComponentEntity { public class PortEntity extends ComponentEntity implements Permissible<PortDTO> {
private PortDTO component; private PortDTO component;
private PortStatusDTO status; private PortStatusDTO status;
@ -35,10 +35,12 @@ public class PortEntity extends ComponentEntity {
/** /**
* @return input PortDTO that are being serialized * @return input PortDTO that are being serialized
*/ */
@Override
public PortDTO getComponent() { public PortDTO getComponent() {
return component; return component;
} }
@Override
public void setComponent(PortDTO component) { public void setComponent(PortDTO component) {
this.component = component; this.component = component;
} }

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.nifi.web.api.entity; 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 org.apache.nifi.web.api.dto.status.PortStatusDTO;
import javax.xml.bind.annotation.XmlRootElement; 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. * 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") @XmlRootElement(name = "portStatusEntity")
public class PortStatusEntity extends Entity { public class PortStatusEntity extends Entity implements ReadablePermission {
private PortStatusDTO portStatus; private PortStatusDTO portStatus;
private Boolean canRead;
/** /**
* The PortStatusDTO that is being serialized. * The PortStatusDTO that is being serialized.
@ -41,4 +43,13 @@ public class PortStatusEntity extends Entity {
this.portStatus = portStatus; this.portStatus = portStatus;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -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;
}
}

View File

@ -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. * 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") @XmlRootElement(name = "processGroupEntity")
public class ProcessGroupEntity extends ComponentEntity { public class ProcessGroupEntity extends ComponentEntity implements Permissible<ProcessGroupDTO> {
private ProcessGroupDTO component; private ProcessGroupDTO component;
private ProcessGroupStatusDTO status; private ProcessGroupStatusDTO status;

View File

@ -17,15 +17,18 @@
package org.apache.nifi.web.api.entity; package org.apache.nifi.web.api.entity;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.apache.nifi.web.api.dto.ReadablePermission;
import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; 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. * 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") @XmlRootElement(name = "processGroupStatusEntity")
public class ProcessGroupStatusEntity extends Entity { public class ProcessGroupStatusEntity extends Entity implements ReadablePermission {
private ProcessGroupStatusDTO processGroupStatus; private ProcessGroupStatusDTO processGroupStatus;
private Boolean canRead;
/** /**
* The ProcessGroupStatusDTO that is being serialized. * The ProcessGroupStatusDTO that is being serialized.
@ -40,4 +43,13 @@ public class ProcessGroupStatusEntity extends Entity {
this.processGroupStatus = processGroupStatus; this.processGroupStatus = processGroupStatus;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -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;
}
}

View File

@ -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. * 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") @XmlRootElement(name = "processorEntity")
public class ProcessorEntity extends ComponentEntity { public class ProcessorEntity extends ComponentEntity implements Permissible<ProcessorDTO> {
private ProcessorDTO component; private ProcessorDTO component;
private String inputRequirement; private String inputRequirement;

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.nifi.web.api.entity; 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 org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
import javax.xml.bind.annotation.XmlRootElement; 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. * 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") @XmlRootElement(name = "processorStatusEntity")
public class ProcessorStatusEntity extends Entity { public class ProcessorStatusEntity extends Entity implements ReadablePermission {
private ProcessorStatusDTO processorStatus; private ProcessorStatusDTO processorStatus;
private Boolean canRead;
/** /**
* The ProcessorStatusDTO that is being serialized. * The ProcessorStatusDTO that is being serialized.
@ -41,4 +43,13 @@ public class ProcessorStatusEntity extends Entity {
this.processorStatus = processorStatus; this.processorStatus = processorStatus;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -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;
}
}

View File

@ -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. * 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") @XmlRootElement(name = "remoteProcessGroupEntity")
public class RemoteProcessGroupEntity extends ComponentEntity { public class RemoteProcessGroupEntity extends ComponentEntity implements Permissible<RemoteProcessGroupDTO> {
private RemoteProcessGroupDTO component; private RemoteProcessGroupDTO component;
private RemoteProcessGroupStatusDTO status; private RemoteProcessGroupStatusDTO status;

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.nifi.web.api.entity; 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 org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
import javax.xml.bind.annotation.XmlRootElement; 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. * 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") @XmlRootElement(name = "remoteProcessGroupStatusEntity")
public class RemoteProcessGroupStatusEntity extends Entity { public class RemoteProcessGroupStatusEntity extends Entity implements ReadablePermission {
private RemoteProcessGroupStatusDTO remoteProcessGroupStatus; private RemoteProcessGroupStatusDTO remoteProcessGroupStatus;
private Boolean canRead;
/** /**
* The RemoteProcessGroupStatusDTO that is being serialized. * The RemoteProcessGroupStatusDTO that is being serialized.
@ -41,4 +43,13 @@ public class RemoteProcessGroupStatusEntity extends Entity {
this.remoteProcessGroupStatus = remoteProcessGroupStatus; this.remoteProcessGroupStatus = remoteProcessGroupStatus;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -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;
}
}

View File

@ -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. * 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") @XmlRootElement(name = "reportingTaskEntity")
public class ReportingTaskEntity extends ComponentEntity { public class ReportingTaskEntity extends ComponentEntity implements Permissible<ReportingTaskDTO> {
private ReportingTaskDTO component; private ReportingTaskDTO component;
/** /**
* @return reporting task that is being serialized * @return reporting task that is being serialized
*/ */
@Override
public ReportingTaskDTO getComponent() { public ReportingTaskDTO getComponent() {
return component; return component;
} }
@Override
public void setComponent(ReportingTaskDTO component) { public void setComponent(ReportingTaskDTO component) {
this.component = component; this.component = component;
} }

View File

@ -16,16 +16,19 @@
*/ */
package org.apache.nifi.web.api.entity; 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 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. * 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") @XmlRootElement(name = "statusHistoryEntity")
public class StatusHistoryEntity extends Entity { public class StatusHistoryEntity extends Entity implements ReadablePermission {
private StatusHistoryDTO statusHistory; private StatusHistoryDTO statusHistory;
private Boolean canRead;
/** /**
* The StatusHistoryDTO that is being serialized. * The StatusHistoryDTO that is being serialized.
@ -40,4 +43,13 @@ public class StatusHistoryEntity extends Entity {
this.statusHistory = statusHistory; this.statusHistory = statusHistory;
} }
@Override
public Boolean getCanRead() {
return canRead;
}
@Override
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
} }

View File

@ -151,7 +151,18 @@
<artifactId>testng</artifactId> <artifactId>testng</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- Spock testing dependencies-->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -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.ConnectionStatusEndpiontMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.ConnectionsEndpointMerger; 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.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.ControllerServiceEndpointMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceReferenceEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceReferenceEndpointMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServicesEndpointMerger; 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.FlowConfigurationEndpointMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.FlowMerger; 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.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.GroupStatusEndpointMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.InputPortsEndpointMerger; 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.ListFlowFilesEndpointMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.OutputPortsEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.OutputPortsEndpointMerger;
import org.apache.nifi.cluster.coordination.http.endpoints.PortEndpointMerger; 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 SystemDiagnosticsEndpointMerger());
endpointMergers.add(new CountersEndpointMerger()); endpointMergers.add(new CountersEndpointMerger());
endpointMergers.add(new FlowMerger()); endpointMergers.add(new FlowMerger());
endpointMergers.add(new ControllerConfigurationEndpointMerger());
endpointMergers.add(new CurrentUserEndpointMerger()); endpointMergers.add(new CurrentUserEndpointMerger());
endpointMergers.add(new FlowConfigurationEndpointMerger()); endpointMergers.add(new FlowConfigurationEndpointMerger());
endpointMergers.add(new TemplatesEndpointMerger()); endpointMergers.add(new TemplatesEndpointMerger());
endpointMergers.add(new LabelEndpointMerger());
endpointMergers.add(new LabelsEndpointMerger());
endpointMergers.add(new FunnelEndpointMerger());
endpointMergers.add(new FunnelsEndpointMerger());
} }
public StandardHttpResponseMerger() { public StandardHttpResponseMerger() {
@ -141,10 +151,17 @@ public class StandardHttpResponseMerger implements HttpResponseMerger {
final Set<NodeResponse> successResponses = nodeResponses.stream().filter(p -> p.is2xx()).collect(Collectors.toSet()); final Set<NodeResponse> successResponses = nodeResponses.stream().filter(p -> p.is2xx()).collect(Collectors.toSet());
final Set<NodeResponse> problematicResponses = nodeResponses.stream().filter(p -> !p.is2xx()).collect(Collectors.toSet()); final Set<NodeResponse> problematicResponses = nodeResponses.stream().filter(p -> !p.is2xx()).collect(Collectors.toSet());
// Choose any of the successful responses to be the 'chosen one'. final NodeResponse clientResponse;
final NodeResponse clientResponse = successResponses.iterator().next(); if ("GET".equalsIgnoreCase(httpMethod) && problematicResponses.size() > 0) {
// If there are problematic responses, at least one of the nodes couldn't complete the request
final EndpointResponseMerger merger = getEndpointResponseMerger(uri, httpMethod); 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) { if (merger == null) {
return clientResponse; return clientResponse;
} }

View File

@ -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<EntityType extends Entity, DtoType> implements EndpointResponseMerger {
@Override
public final NodeResponse merge(final URI uri, final String method, final Set<NodeResponse> successfulResponses, final Set<NodeResponse> 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<DtoType> dtos = getDtos(responseEntity);
final Map<String, Map<NodeIdentifier, DtoType>> dtoMap = new HashMap<>();
for (final NodeResponse nodeResponse : successfulResponses) {
final EntityType nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(getEntityClass());
final Set<DtoType> nodeDtos = getDtos(nodeResponseEntity);
for (final DtoType nodeDto : nodeDtos) {
final NodeIdentifier nodeId = nodeResponse.getNodeId();
Map<NodeIdentifier, DtoType> 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<NodeIdentifier, DtoType> 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<EntityType> 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<DtoType> 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<NodeIdentifier, DtoType> dtoMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses);
}

View File

@ -29,14 +29,15 @@ import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class ConnectionEndpointMerger extends AbstractSingleEntityEndpoint<ConnectionEntity> implements EndpointResponseMerger { public class ConnectionEndpointMerger extends AbstractSingleEntityEndpoint<ConnectionEntity> 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 CONNECTIONS_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 CONNECTION_URI_PATTERN = Pattern.compile("/nifi-api/connections/[a-f0-9\\-]{36}");
private final ConnectionEntityMerger connectionEntityMerger = new ConnectionEntityMerger();
@Override @Override
public boolean canHandle(final URI uri, final String method) { 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; 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; return true;
} }
@ -48,11 +49,10 @@ public class ConnectionEndpointMerger extends AbstractSingleEntityEndpoint<Conne
return ConnectionEntity.class; return ConnectionEntity.class;
} }
@Override @Override
protected void mergeResponses(final ConnectionEntity clientEntity, final Map<NodeIdentifier, ConnectionEntity> entityMap, final Set<NodeResponse> successfulResponses, protected void mergeResponses(final ConnectionEntity clientEntity, final Map<NodeIdentifier, ConnectionEntity> entityMap, final Set<NodeResponse> successfulResponses,
final Set<NodeResponse> problematicResponses) { final Set<NodeResponse> problematicResponses) {
ConnectionEntityMerger.mergeConnections(clientEntity, entityMap); connectionEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -17,18 +17,21 @@
package org.apache.nifi.cluster.coordination.http.endpoints; package org.apache.nifi.cluster.coordination.http.endpoints;
import java.net.URI; import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger;
import java.util.ArrayList; import org.apache.nifi.cluster.manager.NodeResponse;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.manager.StatusMerger;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
import org.apache.nifi.web.api.dto.status.NodeConnectionStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.NodeConnectionStatusSnapshotDTO;
import org.apache.nifi.web.api.entity.ConnectionStatusEntity; import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
public class ConnectionStatusEndpiontMerger extends AbstractNodeStatusEndpoint<ConnectionStatusEntity, ConnectionStatusDTO> { 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<ConnectionStatusEntity> implements ComponentEntityStatusMerger<ConnectionStatusDTO> {
public static final Pattern CONNECTION_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/connections/[a-f0-9\\-]{36}/status"); public static final Pattern CONNECTION_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/connections/[a-f0-9\\-]{36}/status");
@Override @Override
@ -42,17 +45,19 @@ public class ConnectionStatusEndpiontMerger extends AbstractNodeStatusEndpoint<C
} }
@Override @Override
protected ConnectionStatusDTO getDto(ConnectionStatusEntity entity) { protected void mergeResponses(ConnectionStatusEntity clientEntity, Map<NodeIdentifier, ConnectionStatusEntity> entityMap, Set<NodeResponse> successfulResponses,
return entity.getConnectionStatus(); Set<NodeResponse> problematicResponses) {
} final ConnectionStatusDTO mergedConnectionStatus = clientEntity.getConnectionStatus();
mergedConnectionStatus.setNodeSnapshots(new ArrayList<>());
@Override final NodeIdentifier selectedNodeId = entityMap.entrySet().stream()
protected void mergeResponses(ConnectionStatusDTO clientDto, Map<NodeIdentifier, ConnectionStatusDTO> dtoMap, NodeIdentifier selectedNodeId) { .filter(e -> e.getValue() == clientEntity)
final ConnectionStatusDTO mergedConnectionStatus = clientDto; .map(e -> e.getKey())
mergedConnectionStatus.setNodeSnapshots(new ArrayList<NodeConnectionStatusSnapshotDTO>()); .findFirst()
.orElse(null);
final NodeConnectionStatusSnapshotDTO selectedNodeSnapshot = new NodeConnectionStatusSnapshotDTO(); final NodeConnectionStatusSnapshotDTO selectedNodeSnapshot = new NodeConnectionStatusSnapshotDTO();
selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); selectedNodeSnapshot.setStatusSnapshot(mergedConnectionStatus.getAggregateSnapshot().clone());
selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
@ -60,15 +65,22 @@ public class ConnectionStatusEndpiontMerger extends AbstractNodeStatusEndpoint<C
mergedConnectionStatus.getNodeSnapshots().add(selectedNodeSnapshot); mergedConnectionStatus.getNodeSnapshots().add(selectedNodeSnapshot);
// merge the other nodes // merge the other nodes
for (final Map.Entry<NodeIdentifier, ConnectionStatusDTO> entry : dtoMap.entrySet()) { for (final Map.Entry<NodeIdentifier, ConnectionStatusEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeId = entry.getKey(); final NodeIdentifier nodeId = entry.getKey();
final ConnectionStatusDTO nodeConnectionStatus = entry.getValue(); final ConnectionStatusEntity nodeConnectionStatusEntity = entry.getValue();
if (nodeConnectionStatus == clientDto) { final ConnectionStatusDTO nodeConnectionStatus = nodeConnectionStatusEntity.getConnectionStatus();
if (nodeConnectionStatus == mergedConnectionStatus) {
continue; 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());
}
} }

View File

@ -53,11 +53,11 @@ public class ConnectionsEndpointMerger implements EndpointResponseMerger {
final Set<ConnectionEntity> nodeConnectionEntities = nodeResponseEntity.getConnections(); final Set<ConnectionEntity> nodeConnectionEntities = nodeResponseEntity.getConnections();
for (final ConnectionEntity nodeConnectionEntity : nodeConnectionEntities) { for (final ConnectionEntity nodeConnectionEntity : nodeConnectionEntities) {
final NodeIdentifier nodeId = nodeResponse.getNodeId(); final String nodeConnectionEntityId = nodeConnectionEntity.getId();
Map<NodeIdentifier, ConnectionEntity> innerMap = entityMap.get(nodeId); Map<NodeIdentifier, ConnectionEntity> innerMap = entityMap.get(nodeConnectionEntityId);
if (innerMap == null) { if (innerMap == null) {
innerMap = new HashMap<>(); innerMap = new HashMap<>();
entityMap.put(nodeConnectionEntity.getId(), innerMap); entityMap.put(nodeConnectionEntityId, innerMap);
} }
innerMap.put(nodeResponse.getNodeId(), nodeConnectionEntity); innerMap.put(nodeResponse.getNodeId(), nodeConnectionEntity);

View File

@ -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<ControllerConfigurationEntity> {
public static final Pattern CONTROLLER_CONFIGURATION_URI_PATTERN = Pattern.compile("/nifi-api/controller/config");
@Override
protected Class<ControllerConfigurationEntity> getEntityClass() {
return ControllerConfigurationEntity.class;
}
@Override
protected void mergeResponses(ControllerConfigurationEntity clientEntity, Map<NodeIdentifier, ControllerConfigurationEntity> entityMap, Set<NodeResponse> successfulResponses,
Set<NodeResponse> 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();
}
}

View File

@ -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 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 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}"); 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 @Override
public boolean canHandle(URI uri, String method) { public boolean canHandle(URI uri, String method) {
@ -53,6 +54,6 @@ public class ControllerServiceEndpointMerger extends AbstractSingleEntityEndpoin
protected void mergeResponses(ControllerServiceEntity clientEntity, Map<NodeIdentifier, ControllerServiceEntity> entityMap, protected void mergeResponses(ControllerServiceEntity clientEntity, Map<NodeIdentifier, ControllerServiceEntity> entityMap,
Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) { Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
ControllerServiceEntityMerger.mergeControllerServices(clientEntity, entityMap); controllerServiceEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -29,7 +29,7 @@ import org.apache.nifi.web.api.dto.NodeCountersSnapshotDTO;
import org.apache.nifi.web.api.entity.CountersEntity; import org.apache.nifi.web.api.entity.CountersEntity;
public class CountersEndpointMerger extends AbstractNodeStatusEndpoint<CountersEntity, CountersDTO> { public class CountersEndpointMerger extends AbstractNodeStatusEndpoint<CountersEntity, CountersDTO> {
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 @Override
public boolean canHandle(URI uri, String method) { public boolean canHandle(URI uri, String method) {

View File

@ -18,6 +18,8 @@
package org.apache.nifi.cluster.coordination.http.endpoints; package org.apache.nifi.cluster.coordination.http.endpoints;
import org.apache.nifi.cluster.manager.ConnectionsEntityMerger; 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.NodeResponse;
import org.apache.nifi.cluster.manager.PortsEntityMerger; import org.apache.nifi.cluster.manager.PortsEntityMerger;
import org.apache.nifi.cluster.manager.ProcessGroupsEntityMerger; 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 org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -73,11 +72,13 @@ public class FlowMerger extends AbstractSingleDTOEndpoint<ProcessGroupFlowEntity
final Set<PortEntity> clientOutputPorts = flowDto.getOutputPorts(); final Set<PortEntity> clientOutputPorts = flowDto.getOutputPorts();
final Set<RemoteProcessGroupEntity> clientRemoteProcessGroups = flowDto.getRemoteProcessGroups(); final Set<RemoteProcessGroupEntity> clientRemoteProcessGroups = flowDto.getRemoteProcessGroups();
final Set<ProcessGroupEntity> clientProcessGroups = flowDto.getProcessGroups(); final Set<ProcessGroupEntity> clientProcessGroups = flowDto.getProcessGroups();
final Set<LabelEntity> clientLabels = flowDto.getLabels();
final Set<FunnelEntity> clientFunnels = flowDto.getFunnels();
final Map<String, Map<NodeIdentifier, ConnectionEntity>> connections = new HashMap<>(); final Map<String, Map<NodeIdentifier, ConnectionEntity>> connections = new HashMap<>();
final Map<String, List<FunnelEntity>> funnels = new HashMap<>(); final Map<String, Map<NodeIdentifier, FunnelEntity>> funnels = new HashMap<>();
final Map<String, Map<NodeIdentifier, PortEntity>> inputPorts = new HashMap<>(); final Map<String, Map<NodeIdentifier, PortEntity>> inputPorts = new HashMap<>();
final Map<String, List<LabelEntity>> labels = new HashMap<>(); final Map<String, Map<NodeIdentifier, LabelEntity>> labels = new HashMap<>();
final Map<String, Map<NodeIdentifier, PortEntity>> outputPorts = new HashMap<>(); final Map<String, Map<NodeIdentifier, PortEntity>> outputPorts = new HashMap<>();
final Map<String, Map<NodeIdentifier, ProcessorEntity>> processors = new HashMap<>(); final Map<String, Map<NodeIdentifier, ProcessorEntity>> processors = new HashMap<>();
final Map<String, Map<NodeIdentifier, RemoteProcessGroupEntity>> rpgs = new HashMap<>(); final Map<String, Map<NodeIdentifier, RemoteProcessGroupEntity>> rpgs = new HashMap<>();
@ -95,7 +96,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint<ProcessGroupFlowEntity
} }
for (final FunnelEntity entity : nodeFlowDto.getFunnels()) { for (final FunnelEntity entity : nodeFlowDto.getFunnels()) {
funnels.computeIfAbsent(entity.getId(), id -> new ArrayList<>()).add(entity); funnels.computeIfAbsent(entity.getId(), id -> new HashMap<>()).computeIfAbsent(nodeIdentifier, nodeId -> entity);
} }
for (final PortEntity entity : nodeFlowDto.getInputPorts()) { for (final PortEntity entity : nodeFlowDto.getInputPorts()) {
@ -107,7 +108,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint<ProcessGroupFlowEntity
} }
for (final LabelEntity entity : nodeFlowDto.getLabels()) { for (final LabelEntity entity : nodeFlowDto.getLabels()) {
labels.computeIfAbsent(entity.getId(), id -> new ArrayList<>()).add(entity); labels.computeIfAbsent(entity.getId(), id -> new HashMap<>()).computeIfAbsent(nodeIdentifier, nodeId -> entity);
} }
for (final ProcessorEntity entity : nodeFlowDto.getProcessors()) { for (final ProcessorEntity entity : nodeFlowDto.getProcessors()) {
@ -131,11 +132,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint<ProcessGroupFlowEntity
ConnectionsEntityMerger.mergeConnections(clientConnections, connections); ConnectionsEntityMerger.mergeConnections(clientConnections, connections);
// Merge funnel statuses // Merge funnel statuses
final Set<FunnelEntity> mergedFunnels = new HashSet<>(); FunnelsEntityMerger.mergeFunnels(clientFunnels, funnels);
for (final List<FunnelEntity> funnelList : funnels.values()) {
mergedFunnels.add(mergeFunnels(funnelList));
}
flowDto.setFunnels(mergedFunnels);
// Merge input ports // Merge input ports
PortsEntityMerger.mergePorts(clientInputPorts, inputPorts); PortsEntityMerger.mergePorts(clientInputPorts, inputPorts);
@ -144,11 +141,7 @@ public class FlowMerger extends AbstractSingleDTOEndpoint<ProcessGroupFlowEntity
PortsEntityMerger.mergePorts(clientOutputPorts, outputPorts); PortsEntityMerger.mergePorts(clientOutputPorts, outputPorts);
// Merge labels // Merge labels
final Set<LabelEntity> mergedLabels = new HashSet<>(); LabelsEntityMerger.mergeLabels(clientLabels, labels);
for (final List<LabelEntity> labelList : labels.values()) {
mergedLabels.add(mergeLabels(labelList));
}
flowDto.setLabels(mergedLabels);
// Merge processors // Merge processors
ProcessorsEntityMerger.mergeProcessors(clientProcessors, processors); ProcessorsEntityMerger.mergeProcessors(clientProcessors, processors);
@ -159,12 +152,4 @@ public class FlowMerger extends AbstractSingleDTOEndpoint<ProcessGroupFlowEntity
// Merge Process Groups // Merge Process Groups
ProcessGroupsEntityMerger.mergeProcessGroups(clientProcessGroups, processGroups); ProcessGroupsEntityMerger.mergeProcessGroups(clientProcessGroups, processGroups);
} }
private FunnelEntity mergeFunnels(final List<FunnelEntity> funnels) {
return funnels.get(0);
}
private LabelEntity mergeLabels(final List<LabelEntity> labels) {
return labels.get(0);
}
} }

View File

@ -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<FunnelEntity> {
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<FunnelEntity> getEntityClass() {
return FunnelEntity.class;
}
@Override
protected void mergeResponses(FunnelEntity clientEntity, Map<NodeIdentifier, FunnelEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> 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;
}
}

View File

@ -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<NodeResponse> successfulResponses, Set<NodeResponse> 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<FunnelEntity> funnelEntities = responseEntity.getFunnels();
final Map<String, Map<NodeIdentifier, FunnelEntity>> entityMap = new HashMap<>();
for (final NodeResponse nodeResponse : successfulResponses) {
final FunnelsEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(FunnelsEntity.class);
final Set<FunnelEntity> nodeFunnelEntities = nodeResponseEntity.getFunnels();
for (final FunnelEntity nodeFunnelEntity : nodeFunnelEntities) {
final String nodeFunnelEntityId = nodeFunnelEntity.getId();
Map<NodeIdentifier, FunnelEntity> 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);
}
}

View File

@ -17,6 +17,8 @@
package org.apache.nifi.cluster.coordination.http.endpoints; 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.manager.StatusMerger;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO; 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.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class GroupStatusEndpointMerger extends AbstractNodeStatusEndpoint<ProcessGroupStatusEntity, ProcessGroupStatusDTO> { public class GroupStatusEndpointMerger extends AbstractSingleEntityEndpoint<ProcessGroupStatusEntity> implements ComponentEntityStatusMerger<ProcessGroupStatusDTO> {
public static final Pattern GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/status"); public static final Pattern GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/status");
@Override @Override
@ -42,32 +45,41 @@ public class GroupStatusEndpointMerger extends AbstractNodeStatusEndpoint<Proces
} }
@Override @Override
protected ProcessGroupStatusDTO getDto(ProcessGroupStatusEntity entity) { protected void mergeResponses(ProcessGroupStatusEntity clientEntity, Map<NodeIdentifier, ProcessGroupStatusEntity> entityMap, Set<NodeResponse> successfulResponses,
return entity.getProcessGroupStatus(); Set<NodeResponse> problematicResponses) {
} final ProcessGroupStatusDTO mergedProcessGroupStatus = clientEntity.getProcessGroupStatus();
mergedProcessGroupStatus.setNodeSnapshots(new ArrayList<>());
@Override final NodeIdentifier selectedNodeId = entityMap.entrySet().stream()
protected void mergeResponses(ProcessGroupStatusDTO clientDto, Map<NodeIdentifier, ProcessGroupStatusDTO> dtoMap, NodeIdentifier selectedNodeId) { .filter(e -> e.getValue() == clientEntity)
final ProcessGroupStatusDTO mergedProcessGroupStatus = clientDto; .map(e -> e.getKey())
mergedProcessGroupStatus.setNodeSnapshots(new ArrayList<NodeProcessGroupStatusSnapshotDTO>()); .findFirst()
.orElse(null);
final NodeProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessGroupStatusSnapshotDTO(); final NodeProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessGroupStatusSnapshotDTO();
selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); selectedNodeSnapshot.setStatusSnapshot(mergedProcessGroupStatus.getAggregateSnapshot().clone());
selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
mergedProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot); mergedProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot);
for (final Map.Entry<NodeIdentifier, ProcessGroupStatusDTO> entry : dtoMap.entrySet()) { for (final Map.Entry<NodeIdentifier, ProcessGroupStatusEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeId = entry.getKey(); final NodeIdentifier nodeId = entry.getKey();
final ProcessGroupStatusDTO nodeProcessGroupStatus = entry.getValue(); final ProcessGroupStatusEntity nodeProcessGroupStatusEntity = entry.getValue();
final ProcessGroupStatusDTO nodeProcessGroupStatus = nodeProcessGroupStatusEntity.getProcessGroupStatus();
if (nodeProcessGroupStatus == mergedProcessGroupStatus) { if (nodeProcessGroupStatus == mergedProcessGroupStatus) {
continue; 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());
}
} }

View File

@ -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<LabelEntity> {
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<LabelEntity> getEntityClass() {
return LabelEntity.class;
}
@Override
protected void mergeResponses(LabelEntity clientEntity, Map<NodeIdentifier, LabelEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> 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;
}
}

View File

@ -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<NodeResponse> successfulResponses, Set<NodeResponse> 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<LabelEntity> labelEntities = responseEntity.getLabels();
final Map<String, Map<NodeIdentifier, LabelEntity>> entityMap = new HashMap<>();
for (final NodeResponse nodeResponse : successfulResponses) {
final LabelsEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(LabelsEntity.class);
final Set<LabelEntity> nodeLabelEntities = nodeResponseEntity.getLabels();
for (final LabelEntity nodeLabelEntity : nodeLabelEntities) {
final String nodeLabelEntityId = nodeLabelEntity.getId();
Map<NodeIdentifier, LabelEntity> 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);
}
}

View File

@ -34,6 +34,7 @@ public class PortEndpointMerger extends AbstractSingleEntityEndpoint<PortEntity>
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_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}"); 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 @Override
public boolean canHandle(final URI uri, final String method) { public boolean canHandle(final URI uri, final String method) {
@ -65,11 +66,10 @@ public class PortEndpointMerger extends AbstractSingleEntityEndpoint<PortEntity>
return PortEntity.class; return PortEntity.class;
} }
@Override @Override
protected void mergeResponses(final PortEntity clientEntity, final Map<NodeIdentifier, PortEntity> entityMap, protected void mergeResponses(final PortEntity clientEntity, final Map<NodeIdentifier, PortEntity> entityMap,
final Set<NodeResponse> successfulResponses, final Set<NodeResponse> problematicResponses) { final Set<NodeResponse> successfulResponses, final Set<NodeResponse> problematicResponses) {
PortEntityMerger.mergePorts(clientEntity, entityMap); portEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -17,18 +17,21 @@
package org.apache.nifi.cluster.coordination.http.endpoints; package org.apache.nifi.cluster.coordination.http.endpoints;
import java.net.URI; import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger;
import java.util.ArrayList; import org.apache.nifi.cluster.manager.NodeResponse;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.manager.StatusMerger;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.status.NodePortStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.NodePortStatusSnapshotDTO;
import org.apache.nifi.web.api.dto.status.PortStatusDTO; import org.apache.nifi.web.api.dto.status.PortStatusDTO;
import org.apache.nifi.web.api.entity.PortStatusEntity; import org.apache.nifi.web.api.entity.PortStatusEntity;
public class PortStatusEndpointMerger extends AbstractNodeStatusEndpoint<PortStatusEntity, PortStatusDTO> { 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<PortStatusEntity> implements ComponentEntityStatusMerger<PortStatusDTO> {
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 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"); 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<PortSta
} }
@Override @Override
protected PortStatusDTO getDto(PortStatusEntity entity) { protected void mergeResponses(PortStatusEntity clientEntity, Map<NodeIdentifier, PortStatusEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
return entity.getPortStatus(); final PortStatusDTO mergedPortStatus = clientEntity.getPortStatus();
} mergedPortStatus.setNodeSnapshots(new ArrayList<>());
@Override final NodeIdentifier selectedNodeId = entityMap.entrySet().stream()
protected void mergeResponses(PortStatusDTO clientDto, Map<NodeIdentifier, PortStatusDTO> dtoMap, NodeIdentifier selectedNodeId) { .filter(e -> e.getValue() == clientEntity)
final PortStatusDTO mergedPortStatus = clientDto; .map(e -> e.getKey())
mergedPortStatus.setNodeSnapshots(new ArrayList<NodePortStatusSnapshotDTO>()); .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(); final NodePortStatusSnapshotDTO selectedNodeSnapshot = new NodePortStatusSnapshotDTO();
selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); selectedNodeSnapshot.setStatusSnapshot(mergedPortStatus.getAggregateSnapshot().clone());
selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
@ -61,15 +68,22 @@ public class PortStatusEndpointMerger extends AbstractNodeStatusEndpoint<PortSta
mergedPortStatus.getNodeSnapshots().add(selectedNodeSnapshot); mergedPortStatus.getNodeSnapshots().add(selectedNodeSnapshot);
// merge the other nodes // merge the other nodes
for (final Map.Entry<NodeIdentifier, PortStatusDTO> entry : dtoMap.entrySet()) { for (final Map.Entry<NodeIdentifier, PortStatusEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeId = entry.getKey(); final NodeIdentifier nodeId = entry.getKey();
final PortStatusDTO nodePortStatus = entry.getValue(); final PortStatusEntity nodePortStatusEntity = entry.getValue();
if (nodePortStatus == clientDto) { final PortStatusDTO nodePortStatus = nodePortStatusEntity.getPortStatus();
if (nodePortStatus == mergedPortStatus) {
continue; 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());
}
} }

View File

@ -30,10 +30,17 @@ import java.util.regex.Pattern;
public class ProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint<ProcessGroupEntity> implements EndpointResponseMerger { public class ProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint<ProcessGroupEntity> 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 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 @Override
public boolean canHandle(final URI uri, final String method) { 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 @Override
@ -43,6 +50,6 @@ public class ProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint<Pro
@Override @Override
protected void mergeResponses(ProcessGroupEntity clientEntity, Map<NodeIdentifier, ProcessGroupEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) { protected void mergeResponses(ProcessGroupEntity clientEntity, Map<NodeIdentifier, ProcessGroupEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
ProcessGroupEntityMerger.mergeProcessGroups(clientEntity, entityMap); processGroupEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -31,6 +31,7 @@ import java.util.regex.Pattern;
public class ProcessorEndpointMerger extends AbstractSingleEntityEndpoint<ProcessorEntity> implements EndpointResponseMerger { public class ProcessorEndpointMerger extends AbstractSingleEntityEndpoint<ProcessorEntity> 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 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}"); public static final Pattern PROCESSOR_URI_PATTERN = Pattern.compile("/nifi-api/processors/[a-f0-9\\-]{36}");
private final ProcessorEntityMerger processorEntityMerger = new ProcessorEntityMerger();
@Override @Override
public boolean canHandle(final URI uri, final String method) { public boolean canHandle(final URI uri, final String method) {
@ -48,11 +49,10 @@ public class ProcessorEndpointMerger extends AbstractSingleEntityEndpoint<Proces
return ProcessorEntity.class; return ProcessorEntity.class;
} }
@Override @Override
protected void mergeResponses(final ProcessorEntity clientEntity, final Map<NodeIdentifier, ProcessorEntity> entityMap, final Set<NodeResponse> successfulResponses, protected void mergeResponses(final ProcessorEntity clientEntity, final Map<NodeIdentifier, ProcessorEntity> entityMap, final Set<NodeResponse> successfulResponses,
final Set<NodeResponse> problematicResponses) { final Set<NodeResponse> problematicResponses) {
ProcessorEntityMerger.mergeProcessors(clientEntity, entityMap); processorEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -17,18 +17,21 @@
package org.apache.nifi.cluster.coordination.http.endpoints; package org.apache.nifi.cluster.coordination.http.endpoints;
import java.net.URI; import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger;
import java.util.ArrayList; import org.apache.nifi.cluster.manager.NodeResponse;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.manager.StatusMerger;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.status.NodeProcessorStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.NodeProcessorStatusSnapshotDTO;
import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
import org.apache.nifi.web.api.entity.ProcessorStatusEntity; import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
public class ProcessorStatusEndpointMerger extends AbstractNodeStatusEndpoint<ProcessorStatusEntity, ProcessorStatusDTO> { 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<ProcessorStatusEntity> implements ComponentEntityStatusMerger<ProcessorStatusDTO> {
public static final Pattern PROCESSOR_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/processors/[a-f0-9\\-]{36}/status"); public static final Pattern PROCESSOR_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/processors/[a-f0-9\\-]{36}/status");
@Override @Override
@ -42,17 +45,19 @@ public class ProcessorStatusEndpointMerger extends AbstractNodeStatusEndpoint<Pr
} }
@Override @Override
protected ProcessorStatusDTO getDto(ProcessorStatusEntity entity) { protected void mergeResponses(ProcessorStatusEntity clientEntity, Map<NodeIdentifier, ProcessorStatusEntity> entityMap, Set<NodeResponse> successfulResponses,
return entity.getProcessorStatus(); Set<NodeResponse> problematicResponses) {
} final ProcessorStatusDTO mergedProcessorStatus = clientEntity.getProcessorStatus();
mergedProcessorStatus.setNodeSnapshots(new ArrayList<>());
@Override final NodeIdentifier selectedNodeId = entityMap.entrySet().stream()
protected void mergeResponses(ProcessorStatusDTO clientDto, Map<NodeIdentifier, ProcessorStatusDTO> dtoMap, NodeIdentifier selectedNodeId) { .filter(e -> e.getValue() == clientEntity)
final ProcessorStatusDTO mergedProcessorStatus = clientDto; .map(e -> e.getKey())
mergedProcessorStatus.setNodeSnapshots(new ArrayList<NodeProcessorStatusSnapshotDTO>()); .findFirst()
.orElse(null);
final NodeProcessorStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessorStatusSnapshotDTO(); final NodeProcessorStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessorStatusSnapshotDTO();
selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); selectedNodeSnapshot.setStatusSnapshot(mergedProcessorStatus.getAggregateSnapshot().clone());
selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
@ -60,15 +65,21 @@ public class ProcessorStatusEndpointMerger extends AbstractNodeStatusEndpoint<Pr
mergedProcessorStatus.getNodeSnapshots().add(selectedNodeSnapshot); mergedProcessorStatus.getNodeSnapshots().add(selectedNodeSnapshot);
// merge the other nodes // merge the other nodes
for (final Map.Entry<NodeIdentifier, ProcessorStatusDTO> entry : dtoMap.entrySet()) { for (final Map.Entry<NodeIdentifier, ProcessorStatusEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeId = entry.getKey(); final NodeIdentifier nodeId = entry.getKey();
final ProcessorStatusDTO nodeProcessorStatus = entry.getValue(); final ProcessorStatusEntity nodeProcessorStatusEntity = entry.getValue();
if (nodeProcessorStatus == clientDto) { final ProcessorStatusDTO nodeProcessorStatus = nodeProcessorStatusEntity.getProcessorStatus();
if (nodeProcessorStatus == mergedProcessorStatus) {
continue; 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());
}
} }

View File

@ -31,6 +31,7 @@ import java.util.regex.Pattern;
public class RemoteProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint<RemoteProcessGroupEntity> implements EndpointResponseMerger { public class RemoteProcessGroupEndpointMerger extends AbstractSingleEntityEndpoint<RemoteProcessGroupEntity> 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_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}"); 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 @Override
public boolean canHandle(final URI uri, final String method) { public boolean canHandle(final URI uri, final String method) {
@ -52,6 +53,6 @@ public class RemoteProcessGroupEndpointMerger extends AbstractSingleEntityEndpoi
protected void mergeResponses(RemoteProcessGroupEntity clientEntity, Map<NodeIdentifier, RemoteProcessGroupEntity> entityMap, protected void mergeResponses(RemoteProcessGroupEntity clientEntity, Map<NodeIdentifier, RemoteProcessGroupEntity> entityMap,
Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) { Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
RemoteProcessGroupEntityMerger.mergeRemoteProcessGroups(clientEntity, entityMap); remoteProcessGroupEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -17,18 +17,21 @@
package org.apache.nifi.cluster.coordination.http.endpoints; package org.apache.nifi.cluster.coordination.http.endpoints;
import java.net.URI; import org.apache.nifi.cluster.manager.ComponentEntityStatusMerger;
import java.util.ArrayList; import org.apache.nifi.cluster.manager.NodeResponse;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.manager.StatusMerger;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.status.NodeRemoteProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.NodeRemoteProcessGroupStatusSnapshotDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
public class RemoteProcessGroupStatusEndpointMerger extends AbstractNodeStatusEndpoint<RemoteProcessGroupStatusEntity, RemoteProcessGroupStatusDTO> { 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<RemoteProcessGroupStatusEntity> implements ComponentEntityStatusMerger<RemoteProcessGroupStatusDTO> {
public static final Pattern REMOTE_PROCESS_GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/remote-process-groups/[a-f0-9\\-]{36}/status"); public static final Pattern REMOTE_PROCESS_GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/flow/remote-process-groups/[a-f0-9\\-]{36}/status");
@Override @Override
@ -42,17 +45,19 @@ public class RemoteProcessGroupStatusEndpointMerger extends AbstractNodeStatusEn
} }
@Override @Override
protected RemoteProcessGroupStatusDTO getDto(RemoteProcessGroupStatusEntity entity) { protected void mergeResponses(RemoteProcessGroupStatusEntity clientEntity, Map<NodeIdentifier, RemoteProcessGroupStatusEntity> entityMap, Set<NodeResponse> successfulResponses,
return entity.getRemoteProcessGroupStatus(); Set<NodeResponse> problematicResponses) {
} final RemoteProcessGroupStatusDTO mergedRemoteProcessGroupStatus = clientEntity.getRemoteProcessGroupStatus();
mergedRemoteProcessGroupStatus.setNodeSnapshots(new ArrayList<>());
@Override final NodeIdentifier selectedNodeId = entityMap.entrySet().stream()
protected void mergeResponses(RemoteProcessGroupStatusDTO clientDto, Map<NodeIdentifier, RemoteProcessGroupStatusDTO> dtoMap, NodeIdentifier selectedNodeId) { .filter(e -> e.getValue() == clientEntity)
final RemoteProcessGroupStatusDTO mergedRemoteProcessGroupStatus = clientDto; .map(e -> e.getKey())
mergedRemoteProcessGroupStatus.setNodeSnapshots(new ArrayList<NodeRemoteProcessGroupStatusSnapshotDTO>()); .findFirst()
.orElse(null);
final NodeRemoteProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO(); final NodeRemoteProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO();
selectedNodeSnapshot.setStatusSnapshot(clientDto.getAggregateSnapshot().clone()); selectedNodeSnapshot.setStatusSnapshot(mergedRemoteProcessGroupStatus.getAggregateSnapshot().clone());
selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress()); selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort()); selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
selectedNodeSnapshot.setNodeId(selectedNodeId.getId()); selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
@ -60,15 +65,22 @@ public class RemoteProcessGroupStatusEndpointMerger extends AbstractNodeStatusEn
mergedRemoteProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot); mergedRemoteProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot);
// merge the other nodes // merge the other nodes
for (final Map.Entry<NodeIdentifier, RemoteProcessGroupStatusDTO> entry : dtoMap.entrySet()) { for (final Map.Entry<NodeIdentifier, RemoteProcessGroupStatusEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeId = entry.getKey(); final NodeIdentifier nodeId = entry.getKey();
final RemoteProcessGroupStatusDTO nodeRemoteProcessGroupStatus = entry.getValue(); final RemoteProcessGroupStatusEntity nodeRemoteProcessGroupStatusEntity = entry.getValue();
if (nodeRemoteProcessGroupStatus == clientDto) { final RemoteProcessGroupStatusDTO nodeRemoteProcessGroupStatus = nodeRemoteProcessGroupStatusEntity.getRemoteProcessGroupStatus();
if (nodeRemoteProcessGroupStatus == mergedRemoteProcessGroupStatus) {
continue; 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());
}
} }

View File

@ -31,6 +31,7 @@ import java.util.regex.Pattern;
public class ReportingTaskEndpointMerger extends AbstractSingleEntityEndpoint<ReportingTaskEntity> implements EndpointResponseMerger { public class ReportingTaskEndpointMerger extends AbstractSingleEntityEndpoint<ReportingTaskEntity> implements EndpointResponseMerger {
public static final String REPORTING_TASKS_URI = "/nifi-api/controller/reporting-tasks"; 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}"); 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 @Override
public boolean canHandle(URI uri, String method) { public boolean canHandle(URI uri, String method) {
@ -50,6 +51,6 @@ public class ReportingTaskEndpointMerger extends AbstractSingleEntityEndpoint<R
@Override @Override
protected void mergeResponses(ReportingTaskEntity clientEntity, Map<NodeIdentifier, ReportingTaskEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) { protected void mergeResponses(ReportingTaskEntity clientEntity, Map<NodeIdentifier, ReportingTaskEntity> entityMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
ReportingTaskEntityMerger.mergeReportingTasks(clientEntity, entityMap); reportingTaskEntityMerger.merge(clientEntity, entityMap);
} }
} }

View File

@ -21,6 +21,7 @@ import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -111,10 +112,15 @@ public class StatusHistoryEndpointMerger implements EndpointResponseMerger {
StatusHistoryDTO lastStatusHistory = null; StatusHistoryDTO lastStatusHistory = null;
final List<NodeStatusSnapshotsDTO> nodeStatusSnapshots = new ArrayList<>(successfulResponses.size()); final List<NodeStatusSnapshotsDTO> nodeStatusSnapshots = new ArrayList<>(successfulResponses.size());
LinkedHashMap<String, String> noReadPermissionsComponentDetails = null;
for (final NodeResponse nodeResponse : successfulResponses) { for (final NodeResponse nodeResponse : successfulResponses) {
final StatusHistoryEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(StatusHistoryEntity.class); final StatusHistoryEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(StatusHistoryEntity.class);
final StatusHistoryDTO nodeStatus = nodeResponseEntity.getStatusHistory(); final StatusHistoryDTO nodeStatus = nodeResponseEntity.getStatusHistory();
lastStatusHistory = nodeStatus; 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 NodeIdentifier nodeId = nodeResponse.getNodeId();
final NodeStatusSnapshotsDTO nodeStatusSnapshot = new NodeStatusSnapshotsDTO(); final NodeStatusSnapshotsDTO nodeStatusSnapshot = new NodeStatusSnapshotsDTO();
@ -130,12 +136,13 @@ public class StatusHistoryEndpointMerger implements EndpointResponseMerger {
clusterStatusHistory.setGenerated(new Date()); clusterStatusHistory.setGenerated(new Date());
clusterStatusHistory.setNodeSnapshots(nodeStatusSnapshots); clusterStatusHistory.setNodeSnapshots(nodeStatusSnapshots);
if (lastStatusHistory != null) { if (lastStatusHistory != null) {
clusterStatusHistory.setComponentDetails(lastStatusHistory.getComponentDetails()); clusterStatusHistory.setComponentDetails(noReadPermissionsComponentDetails == null ? lastStatusHistory.getComponentDetails() : noReadPermissionsComponentDetails);
clusterStatusHistory.setFieldDescriptors(lastStatusHistory.getFieldDescriptors()); clusterStatusHistory.setFieldDescriptors(lastStatusHistory.getFieldDescriptors());
} }
final StatusHistoryEntity clusterEntity = new StatusHistoryEntity(); final StatusHistoryEntity clusterEntity = new StatusHistoryEntity();
clusterEntity.setStatusHistory(clusterStatusHistory); clusterEntity.setStatusHistory(clusterStatusHistory);
clusterEntity.setCanRead(noReadPermissionsComponentDetails == null);
return new NodeResponse(clientResponse, clusterEntity); return new NodeResponse(clientResponse, clusterEntity);
} }

View File

@ -19,6 +19,7 @@ package org.apache.nifi.cluster.manager;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.BulletinDTO; import org.apache.nifi.web.api.dto.BulletinDTO;
import org.apache.nifi.web.api.entity.ComponentEntity; import org.apache.nifi.web.api.entity.ComponentEntity;
import org.apache.nifi.web.api.entity.Permissible;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; 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.cluster.manager.BulletinMerger.BULLETIN_COMPARATOR;
import static org.apache.nifi.reporting.BulletinRepository.MAX_BULLETINS_PER_COMPONENT; import static org.apache.nifi.reporting.BulletinRepository.MAX_BULLETINS_PER_COMPONENT;
public class ComponentEntityMerger { public interface ComponentEntityMerger<EntityType extends ComponentEntity & Permissible> {
/** /**
* 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 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<NodeIdentifier, ? extends ComponentEntity> entityMap) { @SuppressWarnings("unchecked")
final Map<NodeIdentifier, List<BulletinDTO>> bulletinDtos = new HashMap<>(); default void merge(final EntityType clientEntity, final Map<NodeIdentifier, EntityType> entityMap) {
for (final Map.Entry<NodeIdentifier, ? extends ComponentEntity> entry : entityMap.entrySet()) { for (final Map.Entry<NodeIdentifier, EntityType> entry : entityMap.entrySet()) {
final NodeIdentifier nodeIdentifier = entry.getKey(); final EntityType entity = entry.getValue();
final ComponentEntity entity = entry.getValue(); PermissionsDtoMerger.mergePermissions(clientEntity.getPermissions(), entity.getPermissions());
// 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 if (clientEntity.getPermissions().getCanRead()) {
Collections.sort(clientEntity.getBulletins(), BULLETIN_COMPARATOR); final Map<NodeIdentifier, List<BulletinDTO>> bulletinDtos = new HashMap<>();
for (final Map.Entry<NodeIdentifier, ? extends ComponentEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeIdentifier = entry.getKey();
final ComponentEntity entity = entry.getValue();
// prune the response to only include the max number of bulletins // consider the bulletins if present and authorized
if (clientEntity.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) { if (entity.getBulletins() != null) {
clientEntity.setBulletins(clientEntity.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT)); 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<NodeIdentifier, EntityType> entityMap) {
}
} }

View File

@ -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<StatusDtoType> {
/**
* 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);
}

View File

@ -17,25 +17,29 @@
package org.apache.nifi.cluster.manager; package org.apache.nifi.cluster.manager;
import org.apache.nifi.cluster.protocol.NodeIdentifier; 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 org.apache.nifi.web.api.entity.ConnectionEntity;
import java.util.Map; import java.util.Map;
public class ConnectionEntityMerger { public class ConnectionEntityMerger implements ComponentEntityMerger<ConnectionEntity>, ComponentEntityStatusMerger<ConnectionStatusDTO> {
/** @Override
* Merges the ConnectionEntity responses. public void merge(ConnectionEntity clientEntity, Map<NodeIdentifier, ConnectionEntity> entityMap) {
* ComponentEntityMerger.super.merge(clientEntity, entityMap);
* @param clientEntity the entity being returned to the client for (Map.Entry<NodeIdentifier, ConnectionEntity> entry : entityMap.entrySet()) {
* @param entityMap all node responses
*/
public static void mergeConnections(final ConnectionEntity clientEntity, final Map<NodeIdentifier, ConnectionEntity> entityMap) {
for (final Map.Entry<NodeIdentifier, ConnectionEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeId = entry.getKey(); final NodeIdentifier nodeId = entry.getKey();
final ConnectionEntity entity = entry.getValue(); final ConnectionEntity entityStatus = entry.getValue();
if (entity != clientEntity) { if (entityStatus != clientEntity) {
StatusMerger.merge(clientEntity.getStatus(), entity.getStatus(), nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); 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());
}
} }

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class ConnectionsEntityMerger { public class ConnectionsEntityMerger {
private static final ConnectionEntityMerger connectionEntityMerger = new ConnectionEntityMerger();
/** /**
* Merges multiple ConnectionEntity responses. * Merges multiple ConnectionEntity responses.
* *
@ -32,7 +34,7 @@ public class ConnectionsEntityMerger {
*/ */
public static void mergeConnections(final Set<ConnectionEntity> connectionEntities, final Map<String, Map<NodeIdentifier, ConnectionEntity>> entityMap) { public static void mergeConnections(final Set<ConnectionEntity> connectionEntities, final Map<String, Map<NodeIdentifier, ConnectionEntity>> entityMap) {
for (final ConnectionEntity entity : connectionEntities) { for (final ConnectionEntity entity : connectionEntities) {
ConnectionEntityMerger.mergeConnections(entity, entityMap.get(entity.getId())); connectionEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -20,6 +20,7 @@ import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.web.api.dto.ControllerServiceDTO; import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO; 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.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity; import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
@ -27,15 +28,16 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class ControllerServiceEntityMerger { public class ControllerServiceEntityMerger implements ComponentEntityMerger<ControllerServiceEntity> {
/** /**
* Merges the ControllerServiceEntity responses. * Merges the ControllerServiceEntity responses.
* *
* @param clientEntity the entity being returned to the client * @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<NodeIdentifier, ControllerServiceEntity> entityMap) { @Override
public void mergeComponents(final ControllerServiceEntity clientEntity, final Map<NodeIdentifier, ControllerServiceEntity> entityMap) {
final ControllerServiceDTO clientDto = clientEntity.getComponent(); final ControllerServiceDTO clientDto = clientEntity.getComponent();
final Map<NodeIdentifier, ControllerServiceDTO> dtoMap = new HashMap<>(); final Map<NodeIdentifier, ControllerServiceDTO> dtoMap = new HashMap<>();
for (final Map.Entry<NodeIdentifier, ControllerServiceEntity> entry : entityMap.entrySet()) { for (final Map.Entry<NodeIdentifier, ControllerServiceEntity> entry : entityMap.entrySet()) {
@ -44,8 +46,6 @@ public class ControllerServiceEntityMerger {
dtoMap.put(entry.getKey(), nodeControllerServiceDto); dtoMap.put(entry.getKey(), nodeControllerServiceDto);
} }
ComponentEntityMerger.mergeComponents(clientEntity, entityMap);
mergeDtos(clientDto, dtoMap); mergeDtos(clientDto, dtoMap);
} }
@ -99,6 +99,7 @@ public class ControllerServiceEntityMerger {
final Map<String, Integer> activeThreadCounts = new HashMap<>(); final Map<String, Integer> activeThreadCounts = new HashMap<>();
final Map<String, String> states = new HashMap<>(); final Map<String, String> states = new HashMap<>();
final Map<String, PermissionsDTO> canReads = new HashMap<>();
for (final Map.Entry<NodeIdentifier, Set<ControllerServiceReferencingComponentEntity>> nodeEntry : referencingComponentMap.entrySet()) { for (final Map.Entry<NodeIdentifier, Set<ControllerServiceReferencingComponentEntity>> nodeEntry : referencingComponentMap.entrySet()) {
final Set<ControllerServiceReferencingComponentEntity> nodeReferencingComponents = nodeEntry.getValue(); final Set<ControllerServiceReferencingComponentEntity> nodeReferencingComponents = nodeEntry.getValue();
@ -126,6 +127,17 @@ public class ControllerServiceEntityMerger {
states.put(nodeReferencingComponent.getId(), ControllerServiceState.ENABLING.name()); 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 // go through each referencing components
if (referencingComponents != null) { if (referencingComponents != null) {
for (final ControllerServiceReferencingComponentEntity referencingComponent : referencingComponents) { for (final ControllerServiceReferencingComponentEntity referencingComponent : referencingComponents) {
final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId()); final PermissionsDTO permissions = canReads.get(referencingComponent.getId());
if (activeThreadCount != null) { if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) {
referencingComponent.getComponent().setActiveThreadCount(activeThreadCount); final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId());
} if (activeThreadCount != null) {
referencingComponent.getComponent().setActiveThreadCount(activeThreadCount);
}
final String state = states.get(referencingComponent.getId()); final String state = states.get(referencingComponent.getId());
if (state != null) { if (state != null) {
referencingComponent.getComponent().setState(state); referencingComponent.getComponent().setState(state);
}
} else {
referencingComponent.setPermissions(permissions);
referencingComponent.setComponent(null);
} }
} }
} }

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class ControllerServicesEntityMerger { public class ControllerServicesEntityMerger {
private static final ControllerServiceEntityMerger controllerServiceEntityMerger = new ControllerServiceEntityMerger();
/** /**
* Merges multiple ControllerServiceEntity responses. * Merges multiple ControllerServiceEntity responses.
* *
@ -32,7 +34,7 @@ public class ControllerServicesEntityMerger {
*/ */
public static void mergeControllerServices(final Set<ControllerServiceEntity> controllerServiceEntities, final Map<String, Map<NodeIdentifier, ControllerServiceEntity>> entityMap) { public static void mergeControllerServices(final Set<ControllerServiceEntity> controllerServiceEntities, final Map<String, Map<NodeIdentifier, ControllerServiceEntity>> entityMap) {
for (final ControllerServiceEntity entity : controllerServiceEntities) { for (final ControllerServiceEntity entity : controllerServiceEntities) {
ControllerServiceEntityMerger.mergeControllerServices(entity, entityMap.get(entity.getId())); controllerServiceEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -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<FunnelEntity> {
// No specific merging needs to be done beyond what the ComponentEntityMerger does by default
}

View File

@ -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<FunnelEntity> funnelEntities, final Map<String, Map<NodeIdentifier, FunnelEntity>> entityMap) {
for (final FunnelEntity entity : funnelEntities) {
funnelEntityMerger.merge(entity, entityMap.get(entity.getId()));
}
}
}

View File

@ -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<LabelEntity> {
// No specific merging needs to be done beyond what the ComponentEntityMerger does by default
}

View File

@ -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<LabelEntity> labelEntities, final Map<String, Map<NodeIdentifier, LabelEntity>> entityMap) {
for (final LabelEntity entity : labelEntities) {
labelEntityMerger.merge(entity, entityMap.get(entity.getId()));
}
}
}

View File

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

View File

@ -18,13 +18,26 @@ package org.apache.nifi.cluster.manager;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.PortDTO; 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 org.apache.nifi.web.api.entity.PortEntity;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class PortEntityMerger { public class PortEntityMerger implements ComponentEntityMerger<PortEntity>, ComponentEntityStatusMerger<PortStatusDTO> {
@Override
public void merge(PortEntity clientEntity, Map<NodeIdentifier, PortEntity> entityMap) {
ComponentEntityMerger.super.merge(clientEntity, entityMap);
for (Map.Entry<NodeIdentifier, PortEntity> 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. * Merges the PortEntity responses.
@ -32,7 +45,8 @@ public class PortEntityMerger {
* @param clientEntity the entity being returned to the client * @param clientEntity the entity being returned to the client
* @param entityMap all node responses * @param entityMap all node responses
*/ */
public static void mergePorts(final PortEntity clientEntity, final Map<NodeIdentifier, PortEntity> entityMap) { @Override
public void mergeComponents(PortEntity clientEntity, Map<NodeIdentifier, PortEntity> entityMap) {
final PortDTO clientDto = clientEntity.getComponent(); final PortDTO clientDto = clientEntity.getComponent();
final Map<NodeIdentifier, PortDTO> dtoMap = new HashMap<>(); final Map<NodeIdentifier, PortDTO> dtoMap = new HashMap<>();
for (final Map.Entry<NodeIdentifier, PortEntity> entry : entityMap.entrySet()) { for (final Map.Entry<NodeIdentifier, PortEntity> entry : entityMap.entrySet()) {
@ -41,19 +55,16 @@ public class PortEntityMerger {
dtoMap.put(entry.getKey(), nodePortDto); dtoMap.put(entry.getKey(), nodePortDto);
} }
for (final Map.Entry<NodeIdentifier, PortEntity> 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); 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<NodeIdentifier, PortDTO> dtoMap) { private static void mergeDtos(final PortDTO clientDto, final Map<NodeIdentifier, PortDTO> dtoMap) {
// if unauthorized for the client dto, simple return // if unauthorized for the client dto, simple return
if (clientDto == null) { if (clientDto == null) {

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class PortsEntityMerger { public class PortsEntityMerger {
private static final PortEntityMerger portEntityMerger = new PortEntityMerger();
/** /**
* Merges multiple PortEntity responses. * Merges multiple PortEntity responses.
* *
@ -32,7 +34,7 @@ public class PortsEntityMerger {
*/ */
public static void mergePorts(final Set<PortEntity> portEntities, final Map<String, Map<NodeIdentifier, PortEntity>> entityMap) { public static void mergePorts(final Set<PortEntity> portEntities, final Map<String, Map<NodeIdentifier, PortEntity>> entityMap) {
for (final PortEntity entity : portEntities) { for (final PortEntity entity : portEntities) {
PortEntityMerger.mergePorts(entity, entityMap.get(entity.getId())); portEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -17,27 +17,28 @@
package org.apache.nifi.cluster.manager; package org.apache.nifi.cluster.manager;
import org.apache.nifi.cluster.protocol.NodeIdentifier; 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 org.apache.nifi.web.api.entity.ProcessGroupEntity;
import java.util.Map; import java.util.Map;
public class ProcessGroupEntityMerger { public class ProcessGroupEntityMerger implements ComponentEntityMerger<ProcessGroupEntity>, ComponentEntityStatusMerger<ProcessGroupStatusDTO> {
/** @Override
* Merges the ProcessorGroupEntity responses. public void merge(ProcessGroupEntity clientEntity, Map<NodeIdentifier, ProcessGroupEntity> entityMap) {
* ComponentEntityMerger.super.merge(clientEntity, entityMap);
* @param clientEntity the entity being returned to the client for (Map.Entry<NodeIdentifier, ProcessGroupEntity> entry : entityMap.entrySet()) {
* @param entityMap all node responses final ProcessGroupEntity entityStatus = entry.getValue();
*/ if (entityStatus != clientEntity) {
public static void mergeProcessGroups(final ProcessGroupEntity clientEntity, final Map<NodeIdentifier, ProcessGroupEntity> entityMap) { mergeStatus(clientEntity.getStatus(), clientEntity.getPermissions().getCanRead(), entry.getValue().getStatus(), entry.getValue().getPermissions().getCanRead(), entry.getKey());
for (final Map.Entry<NodeIdentifier, ProcessGroupEntity> 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());
} }
} }
}
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());
} }
} }

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class ProcessGroupsEntityMerger { public class ProcessGroupsEntityMerger {
private static final ProcessGroupEntityMerger processGroupEntityMerger = new ProcessGroupEntityMerger();
/** /**
* Merges multiple ProcessGroupEntity responses. * Merges multiple ProcessGroupEntity responses.
* *
@ -32,7 +34,7 @@ public class ProcessGroupsEntityMerger {
*/ */
public static void mergeProcessGroups(final Set<ProcessGroupEntity> processGroupEntities, final Map<String, Map<NodeIdentifier, ProcessGroupEntity>> entityMap) { public static void mergeProcessGroups(final Set<ProcessGroupEntity> processGroupEntities, final Map<String, Map<NodeIdentifier, ProcessGroupEntity>> entityMap) {
for (final ProcessGroupEntity entity : processGroupEntities) { for (final ProcessGroupEntity entity : processGroupEntities) {
ProcessGroupEntityMerger.mergeProcessGroups(entity, entityMap.get(entity.getId())); processGroupEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -18,13 +18,25 @@ package org.apache.nifi.cluster.manager;
import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.api.dto.ProcessorDTO; 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 org.apache.nifi.web.api.entity.ProcessorEntity;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class ProcessorEntityMerger { public class ProcessorEntityMerger implements ComponentEntityMerger<ProcessorEntity>, ComponentEntityStatusMerger<ProcessorStatusDTO> {
@Override
public void merge(ProcessorEntity clientEntity, Map<NodeIdentifier, ProcessorEntity> entityMap) {
ComponentEntityMerger.super.merge(clientEntity, entityMap);
for (Map.Entry<NodeIdentifier, ProcessorEntity> 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. * Merges the ProcessorEntity responses.
@ -32,7 +44,7 @@ public class ProcessorEntityMerger {
* @param clientEntity the entity being returned to the client * @param clientEntity the entity being returned to the client
* @param entityMap all node responses * @param entityMap all node responses
*/ */
public static void mergeProcessors(final ProcessorEntity clientEntity, final Map<NodeIdentifier, ProcessorEntity> entityMap) { public void mergeComponents(final ProcessorEntity clientEntity, final Map<NodeIdentifier, ProcessorEntity> entityMap) {
final ProcessorDTO clientDto = clientEntity.getComponent(); final ProcessorDTO clientDto = clientEntity.getComponent();
final Map<NodeIdentifier, ProcessorDTO> dtoMap = new HashMap<>(); final Map<NodeIdentifier, ProcessorDTO> dtoMap = new HashMap<>();
for (final Map.Entry<NodeIdentifier, ProcessorEntity> entry : entityMap.entrySet()) { for (final Map.Entry<NodeIdentifier, ProcessorEntity> entry : entityMap.entrySet()) {
@ -41,19 +53,16 @@ public class ProcessorEntityMerger {
dtoMap.put(entry.getKey(), nodeProcDto); dtoMap.put(entry.getKey(), nodeProcDto);
} }
for (final Map.Entry<NodeIdentifier, ProcessorEntity> 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); 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<NodeIdentifier, ProcessorDTO> dtoMap) { private static void mergeDtos(final ProcessorDTO clientDto, final Map<NodeIdentifier, ProcessorDTO> dtoMap) {
// if unauthorized for the client dto, simple return // if unauthorized for the client dto, simple return
if (clientDto == null) { if (clientDto == null) {

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class ProcessorsEntityMerger { public class ProcessorsEntityMerger {
private static final ProcessorEntityMerger processorEntityMerger = new ProcessorEntityMerger();
/** /**
* Merges multiple ProcessorEntity responses. * Merges multiple ProcessorEntity responses.
* *
@ -32,7 +34,7 @@ public class ProcessorsEntityMerger {
*/ */
public static void mergeProcessors(final Set<ProcessorEntity> processorEntities, final Map<String, Map<NodeIdentifier, ProcessorEntity>> entityMap) { public static void mergeProcessors(final Set<ProcessorEntity> processorEntities, final Map<String, Map<NodeIdentifier, ProcessorEntity>> entityMap) {
for (final ProcessorEntity entity : processorEntities) { for (final ProcessorEntity entity : processorEntities) {
ProcessorEntityMerger.mergeProcessors(entity, entityMap.get(entity.getId())); processorEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -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.RemoteProcessGroupContentsDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; 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 org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
import java.util.HashMap; import java.util.HashMap;
@ -27,7 +28,18 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class RemoteProcessGroupEntityMerger { public class RemoteProcessGroupEntityMerger implements ComponentEntityMerger<RemoteProcessGroupEntity>, ComponentEntityStatusMerger<RemoteProcessGroupStatusDTO> {
@Override
public void merge(RemoteProcessGroupEntity clientEntity, Map<NodeIdentifier, RemoteProcessGroupEntity> entityMap) {
ComponentEntityMerger.super.merge(clientEntity, entityMap);
for (Map.Entry<NodeIdentifier, RemoteProcessGroupEntity> 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. * Merges the RemoteProcessGroupEntity responses.
@ -35,7 +47,7 @@ public class RemoteProcessGroupEntityMerger {
* @param clientEntity the entity being returned to the client * @param clientEntity the entity being returned to the client
* @param entityMap all node responses * @param entityMap all node responses
*/ */
public static void mergeRemoteProcessGroups(final RemoteProcessGroupEntity clientEntity, final Map<NodeIdentifier, RemoteProcessGroupEntity> entityMap) { public void mergeComponents(final RemoteProcessGroupEntity clientEntity, final Map<NodeIdentifier, RemoteProcessGroupEntity> entityMap) {
final RemoteProcessGroupDTO clientDto = clientEntity.getComponent(); final RemoteProcessGroupDTO clientDto = clientEntity.getComponent();
final Map<NodeIdentifier, RemoteProcessGroupDTO> dtoMap = new HashMap<>(); final Map<NodeIdentifier, RemoteProcessGroupDTO> dtoMap = new HashMap<>();
for (final Map.Entry<NodeIdentifier, RemoteProcessGroupEntity> entry : entityMap.entrySet()) { for (final Map.Entry<NodeIdentifier, RemoteProcessGroupEntity> entry : entityMap.entrySet()) {
@ -44,19 +56,16 @@ public class RemoteProcessGroupEntityMerger {
dtoMap.put(entry.getKey(), nodeProcDto); dtoMap.put(entry.getKey(), nodeProcDto);
} }
for (final Map.Entry<NodeIdentifier, RemoteProcessGroupEntity> 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); 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<NodeIdentifier, RemoteProcessGroupDTO> dtoMap) { private static void mergeDtos(final RemoteProcessGroupDTO clientDto, final Map<NodeIdentifier, RemoteProcessGroupDTO> dtoMap) {
// if unauthorized for the client dto, simple return // if unauthorized for the client dto, simple return
if (clientDto == null) { if (clientDto == null) {

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class RemoteProcessGroupsEntityMerger { public class RemoteProcessGroupsEntityMerger {
private static final RemoteProcessGroupEntityMerger remoteProcessGroupEntityMerger = new RemoteProcessGroupEntityMerger();
/** /**
* Merges multiple RemoteProcessGroupEntity responses. * Merges multiple RemoteProcessGroupEntity responses.
* *
@ -32,7 +34,7 @@ public class RemoteProcessGroupsEntityMerger {
*/ */
public static void mergeRemoteProcessGroups(final Set<RemoteProcessGroupEntity> remoteProcessGroupEntities, final Map<String, Map<NodeIdentifier, RemoteProcessGroupEntity>> entityMap) { public static void mergeRemoteProcessGroups(final Set<RemoteProcessGroupEntity> remoteProcessGroupEntities, final Map<String, Map<NodeIdentifier, RemoteProcessGroupEntity>> entityMap) {
for (final RemoteProcessGroupEntity entity : remoteProcessGroupEntities) { for (final RemoteProcessGroupEntity entity : remoteProcessGroupEntities) {
RemoteProcessGroupEntityMerger.mergeRemoteProcessGroups(entity, entityMap.get(entity.getId())); remoteProcessGroupEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -24,7 +24,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class ReportingTaskEntityMerger { public class ReportingTaskEntityMerger implements ComponentEntityMerger<ReportingTaskEntity> {
/** /**
* Merges the ReportingTaskEntity responses. * Merges the ReportingTaskEntity responses.
@ -32,7 +32,7 @@ public class ReportingTaskEntityMerger {
* @param clientEntity the entity being returned to the client * @param clientEntity the entity being returned to the client
* @param entityMap all node responses * @param entityMap all node responses
*/ */
public static void mergeReportingTasks(final ReportingTaskEntity clientEntity, final Map<NodeIdentifier, ReportingTaskEntity> entityMap) { public void mergeComponents(final ReportingTaskEntity clientEntity, final Map<NodeIdentifier, ReportingTaskEntity> entityMap) {
final ReportingTaskDTO clientDto = clientEntity.getComponent(); final ReportingTaskDTO clientDto = clientEntity.getComponent();
final Map<NodeIdentifier, ReportingTaskDTO> dtoMap = new HashMap<>(); final Map<NodeIdentifier, ReportingTaskDTO> dtoMap = new HashMap<>();
for (final Map.Entry<NodeIdentifier, ReportingTaskEntity> entry : entityMap.entrySet()) { for (final Map.Entry<NodeIdentifier, ReportingTaskEntity> entry : entityMap.entrySet()) {
@ -41,8 +41,6 @@ public class ReportingTaskEntityMerger {
dtoMap.put(entry.getKey(), nodeReportingTaskDto); dtoMap.put(entry.getKey(), nodeReportingTaskDto);
} }
ComponentEntityMerger.mergeComponents(clientEntity, entityMap);
mergeDtos(clientDto, dtoMap); mergeDtos(clientDto, dtoMap);
} }

View File

@ -24,6 +24,8 @@ import java.util.Set;
public class ReportingTasksEntityMerger { public class ReportingTasksEntityMerger {
private static final ReportingTaskEntityMerger reportingTaskEntityMerger = new ReportingTaskEntityMerger();
/** /**
* Merges multiple ReportingTaskEntity responses. * Merges multiple ReportingTaskEntity responses.
* *
@ -32,7 +34,7 @@ public class ReportingTasksEntityMerger {
*/ */
public static void mergeReportingTasks(final Set<ReportingTaskEntity> reportingTaskEntities, final Map<String, Map<NodeIdentifier, ReportingTaskEntity>> entityMap) { public static void mergeReportingTasks(final Set<ReportingTaskEntity> reportingTaskEntities, final Map<String, Map<NodeIdentifier, ReportingTaskEntity>> entityMap) {
for (final ReportingTaskEntity entity : reportingTaskEntities) { for (final ReportingTaskEntity entity : reportingTaskEntities) {
ReportingTaskEntityMerger.mergeReportingTasks(entity, entityMap.get(entity.getId())); reportingTaskEntityMerger.merge(entity, entityMap.get(entity.getId()));
} }
} }
} }

View File

@ -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.ProcessorStatusSnapshotDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; 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.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.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -72,8 +77,14 @@ public class StatusMerger {
target.setQueued(prettyPrint(target.getFlowFilesQueued(), target.getBytesQueued())); 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) { public static void merge(final ProcessGroupStatusDTO target, final boolean targetReadablePermission, final ProcessGroupStatusDTO toMerge, final boolean toMergeReadablePermission,
merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); 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) { if (target.getNodeSnapshots() != null) {
final NodeProcessGroupStatusSnapshotDTO nodeSnapshot = new NodeProcessGroupStatusSnapshotDTO(); 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) { if (target == null || toMerge == null) {
return; 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.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());
target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn()); target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
@ -117,13 +142,13 @@ public class StatusMerger {
// connection status // connection status
// sort by id // sort by id
final Map<String, ConnectionStatusSnapshotDTO> mergedConnectionMap = new HashMap<>(); final Map<String, ConnectionStatusSnapshotEntity> mergedConnectionMap = new HashMap<>();
for (final ConnectionStatusSnapshotDTO status : replaceNull(target.getConnectionStatusSnapshots())) { for (final ConnectionStatusSnapshotEntity status : replaceNull(target.getConnectionStatusSnapshots())) {
mergedConnectionMap.put(status.getId(), status); mergedConnectionMap.put(status.getId(), status);
} }
for (final ConnectionStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getConnectionStatusSnapshots())) { for (final ConnectionStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getConnectionStatusSnapshots())) {
ConnectionStatusSnapshotDTO merged = mergedConnectionMap.get(statusToMerge.getId()); ConnectionStatusSnapshotEntity merged = mergedConnectionMap.get(statusToMerge.getId());
if (merged == null) { if (merged == null) {
mergedConnectionMap.put(statusToMerge.getId(), statusToMerge.clone()); mergedConnectionMap.put(statusToMerge.getId(), statusToMerge.clone());
continue; continue;
@ -134,13 +159,13 @@ public class StatusMerger {
target.setConnectionStatusSnapshots(mergedConnectionMap.values()); target.setConnectionStatusSnapshots(mergedConnectionMap.values());
// processor status // processor status
final Map<String, ProcessorStatusSnapshotDTO> mergedProcessorMap = new HashMap<>(); final Map<String, ProcessorStatusSnapshotEntity> mergedProcessorMap = new HashMap<>();
for (final ProcessorStatusSnapshotDTO status : replaceNull(target.getProcessorStatusSnapshots())) { for (final ProcessorStatusSnapshotEntity status : replaceNull(target.getProcessorStatusSnapshots())) {
mergedProcessorMap.put(status.getId(), status); mergedProcessorMap.put(status.getId(), status);
} }
for (final ProcessorStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getProcessorStatusSnapshots())) { for (final ProcessorStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getProcessorStatusSnapshots())) {
ProcessorStatusSnapshotDTO merged = mergedProcessorMap.get(statusToMerge.getId()); ProcessorStatusSnapshotEntity merged = mergedProcessorMap.get(statusToMerge.getId());
if (merged == null) { if (merged == null) {
mergedProcessorMap.put(statusToMerge.getId(), statusToMerge.clone()); mergedProcessorMap.put(statusToMerge.getId(), statusToMerge.clone());
continue; continue;
@ -152,13 +177,13 @@ public class StatusMerger {
// input ports // input ports
final Map<String, PortStatusSnapshotDTO> mergedInputPortMap = new HashMap<>(); final Map<String, PortStatusSnapshotEntity> mergedInputPortMap = new HashMap<>();
for (final PortStatusSnapshotDTO status : replaceNull(target.getInputPortStatusSnapshots())) { for (final PortStatusSnapshotEntity status : replaceNull(target.getInputPortStatusSnapshots())) {
mergedInputPortMap.put(status.getId(), status); mergedInputPortMap.put(status.getId(), status);
} }
for (final PortStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getInputPortStatusSnapshots())) { for (final PortStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getInputPortStatusSnapshots())) {
PortStatusSnapshotDTO merged = mergedInputPortMap.get(statusToMerge.getId()); PortStatusSnapshotEntity merged = mergedInputPortMap.get(statusToMerge.getId());
if (merged == null) { if (merged == null) {
mergedInputPortMap.put(statusToMerge.getId(), statusToMerge.clone()); mergedInputPortMap.put(statusToMerge.getId(), statusToMerge.clone());
continue; continue;
@ -169,13 +194,13 @@ public class StatusMerger {
target.setInputPortStatusSnapshots(mergedInputPortMap.values()); target.setInputPortStatusSnapshots(mergedInputPortMap.values());
// output ports // output ports
final Map<String, PortStatusSnapshotDTO> mergedOutputPortMap = new HashMap<>(); final Map<String, PortStatusSnapshotEntity> mergedOutputPortMap = new HashMap<>();
for (final PortStatusSnapshotDTO status : replaceNull(target.getOutputPortStatusSnapshots())) { for (final PortStatusSnapshotEntity status : replaceNull(target.getOutputPortStatusSnapshots())) {
mergedOutputPortMap.put(status.getId(), status); mergedOutputPortMap.put(status.getId(), status);
} }
for (final PortStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getOutputPortStatusSnapshots())) { for (final PortStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getOutputPortStatusSnapshots())) {
PortStatusSnapshotDTO merged = mergedOutputPortMap.get(statusToMerge.getId()); PortStatusSnapshotEntity merged = mergedOutputPortMap.get(statusToMerge.getId());
if (merged == null) { if (merged == null) {
mergedOutputPortMap.put(statusToMerge.getId(), statusToMerge.clone()); mergedOutputPortMap.put(statusToMerge.getId(), statusToMerge.clone());
continue; continue;
@ -186,13 +211,13 @@ public class StatusMerger {
target.setOutputPortStatusSnapshots(mergedOutputPortMap.values()); target.setOutputPortStatusSnapshots(mergedOutputPortMap.values());
// child groups // child groups
final Map<String, ProcessGroupStatusSnapshotDTO> mergedGroupMap = new HashMap<>(); final Map<String, ProcessGroupStatusSnapshotEntity> mergedGroupMap = new HashMap<>();
for (final ProcessGroupStatusSnapshotDTO status : replaceNull(target.getProcessGroupStatusSnapshots())) { for (final ProcessGroupStatusSnapshotEntity status : replaceNull(target.getProcessGroupStatusSnapshots())) {
mergedGroupMap.put(status.getId(), status); mergedGroupMap.put(status.getId(), status);
} }
for (final ProcessGroupStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getProcessGroupStatusSnapshots())) { for (final ProcessGroupStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getProcessGroupStatusSnapshots())) {
ProcessGroupStatusSnapshotDTO merged = mergedGroupMap.get(statusToMerge.getId()); ProcessGroupStatusSnapshotEntity merged = mergedGroupMap.get(statusToMerge.getId());
if (merged == null) { if (merged == null) {
mergedGroupMap.put(statusToMerge.getId(), statusToMerge.clone()); mergedGroupMap.put(statusToMerge.getId(), statusToMerge.clone());
continue; continue;
@ -203,13 +228,13 @@ public class StatusMerger {
target.setOutputPortStatusSnapshots(mergedOutputPortMap.values()); target.setOutputPortStatusSnapshots(mergedOutputPortMap.values());
// remote groups // remote groups
final Map<String, RemoteProcessGroupStatusSnapshotDTO> mergedRemoteGroupMap = new HashMap<>(); final Map<String, RemoteProcessGroupStatusSnapshotEntity> mergedRemoteGroupMap = new HashMap<>();
for (final RemoteProcessGroupStatusSnapshotDTO status : replaceNull(target.getRemoteProcessGroupStatusSnapshots())) { for (final RemoteProcessGroupStatusSnapshotEntity status : replaceNull(target.getRemoteProcessGroupStatusSnapshots())) {
mergedRemoteGroupMap.put(status.getId(), status); mergedRemoteGroupMap.put(status.getId(), status);
} }
for (final RemoteProcessGroupStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getRemoteProcessGroupStatusSnapshots())) { for (final RemoteProcessGroupStatusSnapshotEntity statusToMerge : replaceNull(toMerge.getRemoteProcessGroupStatusSnapshots())) {
RemoteProcessGroupStatusSnapshotDTO merged = mergedRemoteGroupMap.get(statusToMerge.getId()); RemoteProcessGroupStatusSnapshotEntity merged = mergedRemoteGroupMap.get(statusToMerge.getId());
if (merged == null) { if (merged == null) {
mergedRemoteGroupMap.put(statusToMerge.getId(), statusToMerge.clone()); mergedRemoteGroupMap.put(statusToMerge.getId(), statusToMerge.clone());
continue; continue;
@ -221,7 +246,7 @@ public class StatusMerger {
} }
private static <T> Collection<T> replaceNull(final Collection<T> collection) { private static <T> Collection<T> replaceNull(final Collection<T> collection) {
return (collection == null) ? Collections.<T> emptyList() : collection; return (collection == null) ? Collections.<T>emptyList() : collection;
} }
@ -230,7 +255,7 @@ public class StatusMerger {
* {@link ProcessGroupStatusSnapshotDTO#setInput(String)} will be called with the pretty-printed form of the * {@link ProcessGroupStatusSnapshotDTO#setInput(String)} will be called with the pretty-printed form of the
* FlowFile counts and sizes retrieved via {@link ProcessGroupStatusSnapshotDTO#getFlowFilesIn()} and * FlowFile counts and sizes retrieved via {@link ProcessGroupStatusSnapshotDTO#getFlowFilesIn()} and
* {@link ProcessGroupStatusSnapshotDTO#getBytesIn()}. * {@link ProcessGroupStatusSnapshotDTO#getBytesIn()}.
* * <p>
* This logic is performed here, rather than in the DTO itself because the DTO needs to be kept purely * 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 * getters & setters - otherwise the automatic marshalling and unmarshalling to/from JSON becomes very
* complicated. * complicated.
@ -250,8 +275,16 @@ public class StatusMerger {
target.setSent(prettyPrint(target.getFlowFilesSent(), target.getBytesSent())); 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) { public static void merge(final RemoteProcessGroupStatusDTO target, final boolean targetReadablePermission, final RemoteProcessGroupStatusDTO toMerge,
merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); 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) { if (target.getNodeSnapshots() != null) {
final NodeRemoteProcessGroupStatusSnapshotDTO nodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO(); 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) { public static void merge(final PortStatusDTO target, final boolean targetReadablePermission, final PortStatusDTO toMerge, final boolean toMergeReadablePermission, final String nodeId,
merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); 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) { if (target.getNodeSnapshots() != null) {
final NodePortStatusSnapshotDTO nodeSnapshot = new NodePortStatusSnapshotDTO(); 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) { public static void merge(final ConnectionStatusDTO target, final boolean targetReadablePermission, final ConnectionStatusDTO toMerge, final boolean toMergeReadablePermission,
merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); 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) { if (target.getNodeSnapshots() != null) {
final NodeConnectionStatusSnapshotDTO nodeSnapshot = new NodeConnectionStatusSnapshotDTO(); 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) { public static void merge(final ProcessorStatusDTO target, final boolean targetReadablePermission, final ProcessorStatusDTO toMerge, final boolean toMergeReadablePermission,
merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot()); 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) { if (target.getNodeSnapshots() != null) {
final NodeProcessorStatusSnapshotDTO nodeSnapshot = new NodeProcessorStatusSnapshotDTO(); 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) { if (target == null || toMerge == null) {
return; 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 // 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 // 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 // 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)); target.setTasksDuration(FormatUtils.formatHoursMinutesSeconds(target.getTasksDurationNanos(), TimeUnit.NANOSECONDS));
} }
public static void merge(final ConnectionStatusSnapshotEntity target, ConnectionStatusSnapshotEntity toMerge) {
public static void merge(final ConnectionStatusSnapshotDTO target, final ConnectionStatusSnapshotDTO toMerge) {
if (target == null || toMerge == null) { if (target == null || toMerge == null) {
return; 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.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn()); target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());
target.setFlowFilesOut(target.getFlowFilesOut() + toMerge.getFlowFilesOut()); 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(); final String transmittingValue = TransmissionStatus.Transmitting.name();
if (transmittingValue.equals(target.getTransmissionStatus()) || transmittingValue.equals(toMerge.getTransmissionStatus())) { if (transmittingValue.equals(target.getTransmissionStatus()) || transmittingValue.equals(toMerge.getTransmissionStatus())) {
target.setTransmissionStatus(transmittingValue); target.setTransmissionStatus(transmittingValue);
@ -391,12 +503,25 @@ public class StatusMerger {
} }
public static void merge(final PortStatusSnapshotEntity target, PortStatusSnapshotEntity toMerge) {
public static void merge(final PortStatusSnapshotDTO target, final PortStatusSnapshotDTO toMerge) {
if (target == null || toMerge == null) { if (target == null || toMerge == null) {
return; 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.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount());
target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn()); target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn()); target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());

View File

@ -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<ClientResponse, Map<String, Integer>> 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<ClientResponse, Object> 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))
}
}

View File

@ -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<ClientResponse, Object> 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: []))
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)')
}
}

View File

@ -17,12 +17,12 @@
package org.apache.nifi.controller.status.history; 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.RemoteProcessGroupStatus;
import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter; import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter;
import java.util.List;
import java.util.concurrent.TimeUnit;
public enum RemoteProcessGroupStatusDescriptor { public enum RemoteProcessGroupStatusDescriptor {
SENT_BYTES(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentBytes", SENT_BYTES(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentBytes",
"Bytes Sent (5 mins)", "Bytes Sent (5 mins)",

View File

@ -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.ProvenanceOptionsDTO;
import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO; 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.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.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.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.ConnectionEntity; 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.ControllerBulletinsEntity;
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity; 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.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.PortEntity; 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.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; 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.ProcessorEntity;
import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; 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.ReportingTaskEntity;
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity; import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
import org.apache.nifi.web.api.entity.SnippetEntity; 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.TemplateEntity;
import org.apache.nifi.web.api.entity.UserEntity; import org.apache.nifi.web.api.entity.UserEntity;
import org.apache.nifi.web.api.entity.UserGroupEntity; import org.apache.nifi.web.api.entity.UserGroupEntity;
@ -290,7 +290,7 @@ public interface NiFiServiceFacade {
* @param groupId group * @param groupId group
* @return The process group status * @return The process group status
*/ */
ProcessGroupStatusDTO getProcessGroupStatus(String groupId); ProcessGroupStatusEntity getProcessGroupStatus(String groupId, boolean recursive);
/** /**
* Gets the process group status history. * Gets the process group status history.
@ -298,7 +298,7 @@ public interface NiFiServiceFacade {
* @param groupId id * @param groupId id
* @return history * @return history
*/ */
StatusHistoryDTO getProcessGroupStatusHistory(String groupId); StatusHistoryEntity getProcessGroupStatusHistory(String groupId);
/** /**
* Returns the controller status. * Returns the controller status.
@ -455,7 +455,7 @@ public interface NiFiServiceFacade {
* @param id id * @param id id
* @return status * @return status
*/ */
ProcessorStatusDTO getProcessorStatus(String id); ProcessorStatusEntity getProcessorStatus(String id);
/** /**
* Gets the processor status history. * Gets the processor status history.
@ -463,7 +463,7 @@ public interface NiFiServiceFacade {
* @param id id * @param id id
* @return history * @return history
*/ */
StatusHistoryDTO getProcessorStatusHistory(String id); StatusHistoryEntity getProcessorStatusHistory(String id);
/** /**
* Get the descriptor for the specified property of the specified processor. * Get the descriptor for the specified property of the specified processor.
@ -540,7 +540,7 @@ public interface NiFiServiceFacade {
* @param connectionId connection * @param connectionId connection
* @return status * @return status
*/ */
ConnectionStatusDTO getConnectionStatus(String connectionId); ConnectionStatusEntity getConnectionStatus(String connectionId);
/** /**
* Gets the status history of the specified connection. * Gets the status history of the specified connection.
@ -548,7 +548,7 @@ public interface NiFiServiceFacade {
* @param connectionId connection * @param connectionId connection
* @return history * @return history
*/ */
StatusHistoryDTO getConnectionStatusHistory(String connectionId); StatusHistoryEntity getConnectionStatusHistory(String connectionId);
/** /**
* Creates a new Relationship target. * Creates a new Relationship target.
@ -708,7 +708,7 @@ public interface NiFiServiceFacade {
* @param inputPortId input port * @param inputPortId input port
* @return status * @return status
*/ */
PortStatusDTO getInputPortStatus(String inputPortId); PortStatusEntity getInputPortStatus(String inputPortId);
/** /**
* Determines if the input port could be updated. * Determines if the input port could be updated.
@ -777,7 +777,7 @@ public interface NiFiServiceFacade {
* @param outputPortId output port * @param outputPortId output port
* @return status * @return status
*/ */
PortStatusDTO getOutputPortStatus(String outputPortId); PortStatusEntity getOutputPortStatus(String outputPortId);
/** /**
* Determines if the output port could be updated. * Determines if the output port could be updated.
@ -937,7 +937,7 @@ public interface NiFiServiceFacade {
* @param id remote process group * @param id remote process group
* @return status * @return status
*/ */
RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(String id); RemoteProcessGroupStatusEntity getRemoteProcessGroupStatus(String id);
/** /**
* Gets the remote process group status history. * Gets the remote process group status history.
@ -945,7 +945,7 @@ public interface NiFiServiceFacade {
* @param id The id of the remote process group * @param id The id of the remote process group
* @return history * @return history
*/ */
StatusHistoryDTO getRemoteProcessGroupStatusHistory(String id); StatusHistoryEntity getRemoteProcessGroupStatusHistory(String id);
/** /**
* Verifies the specified remote process group can be updated. * Verifies the specified remote process group can be updated.

View File

@ -1,3 +1,4 @@
/*
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * 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.search.SearchResultsDTO;
import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; 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.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.PortStatusDTO;
import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; 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.ProcessorStatusDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
import org.apache.nifi.web.api.entity.AccessPolicyEntity; import org.apache.nifi.web.api.entity.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
import org.apache.nifi.web.api.entity.ConnectionEntity; 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.ControllerBulletinsEntity;
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity; 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.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.PortEntity; 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.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; 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.ProcessorEntity;
import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; 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.ReportingTaskEntity;
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity; import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
import org.apache.nifi.web.api.entity.SnippetEntity; 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.TemplateEntity;
import org.apache.nifi.web.api.entity.TenantEntity; import org.apache.nifi.web.api.entity.TenantEntity;
import org.apache.nifi.web.api.entity.UserEntity; import org.apache.nifi.web.api.entity.UserEntity;
@ -850,6 +859,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override @Override
public ConnectionEntity deleteConnection(final Revision revision, final String connectionId) { public ConnectionEntity deleteConnection(final Revision revision, final String connectionId) {
final Connection connection = connectionDAO.getConnection(connectionId); final Connection connection = connectionDAO.getConnection(connectionId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection);
final ConnectionDTO snapshot = deleteComponent( final ConnectionDTO snapshot = deleteComponent(
revision, revision,
connection.getResource(), connection.getResource(),
@ -857,7 +867,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
false, // no policies to remove false, // no policies to remove
dtoFactory.createConnectionDto(connection)); dtoFactory.createConnectionDto(connection));
return entityFactory.createConnectionEntity(snapshot, null, null, null); return entityFactory.createConnectionEntity(snapshot, null, permissions, null);
} }
@Override @Override
@ -884,6 +894,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override @Override
public ProcessorEntity deleteProcessor(final Revision revision, final String processorId) { public ProcessorEntity deleteProcessor(final Revision revision, final String processorId) {
final ProcessorNode processor = processorDAO.getProcessor(processorId); final ProcessorNode processor = processorDAO.getProcessor(processorId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor);
final ProcessorDTO snapshot = deleteComponent( final ProcessorDTO snapshot = deleteComponent(
revision, revision,
processor.getResource(), processor.getResource(),
@ -891,12 +902,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createProcessorDto(processor)); dtoFactory.createProcessorDto(processor));
return entityFactory.createProcessorEntity(snapshot, null, null, null, null); return entityFactory.createProcessorEntity(snapshot, null, permissions, null, null);
} }
@Override @Override
public LabelEntity deleteLabel(final Revision revision, final String labelId) { public LabelEntity deleteLabel(final Revision revision, final String labelId) {
final Label label = labelDAO.getLabel(labelId); final Label label = labelDAO.getLabel(labelId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label);
final LabelDTO snapshot = deleteComponent( final LabelDTO snapshot = deleteComponent(
revision, revision,
label.getResource(), label.getResource(),
@ -904,12 +916,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createLabelDto(label)); dtoFactory.createLabelDto(label));
return entityFactory.createLabelEntity(snapshot, null, null); return entityFactory.createLabelEntity(snapshot, null, permissions);
} }
@Override @Override
public UserEntity deleteUser(final Revision revision, final String userId) { public UserEntity deleteUser(final Revision revision, final String userId) {
final User user = userDAO.getUser(userId); final User user = userDAO.getUser(userId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
final Set<TenantEntity> userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream() final Set<TenantEntity> userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream()
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null; .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
final Set<AccessPolicySummaryEntity> policyEntities = user != null ? userGroupDAO.getAccessPoliciesForUser(userId).stream() final Set<AccessPolicySummaryEntity> policyEntities = user != null ? userGroupDAO.getAccessPoliciesForUser(userId).stream()
@ -933,12 +946,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
false, // no user specific policies to remove false, // no user specific policies to remove
dtoFactory.createUserDto(user, userGroups, policyEntities)); dtoFactory.createUserDto(user, userGroups, policyEntities));
return entityFactory.createUserEntity(snapshot, null, null); return entityFactory.createUserEntity(snapshot, null, permissions);
} }
@Override @Override
public UserGroupEntity deleteUserGroup(final Revision revision, final String userGroupId) { public UserGroupEntity deleteUserGroup(final Revision revision, final String userGroupId) {
final Group userGroup = userGroupDAO.getUserGroup(userGroupId); final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
final Set<TenantEntity> users = userGroup != null ? userGroup.getUsers().stream() final Set<TenantEntity> users = userGroup != null ? userGroup.getUsers().stream()
.map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : .map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) :
null; null;
@ -961,12 +975,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
false, // no user group specific policies to remove false, // no user group specific policies to remove
dtoFactory.createUserGroupDto(userGroup, users)); dtoFactory.createUserGroupDto(userGroup, users));
return entityFactory.createUserGroupEntity(snapshot, null, null); return entityFactory.createUserGroupEntity(snapshot, null, permissions);
} }
@Override @Override
public AccessPolicyEntity deleteAccessPolicy(final Revision revision, final String accessPolicyId) { public AccessPolicyEntity deleteAccessPolicy(final Revision revision, final String accessPolicyId) {
final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId); final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyId));
final Set<TenantEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null; final Set<TenantEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null; final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
final AccessPolicyDTO snapshot = deleteComponent( final AccessPolicyDTO snapshot = deleteComponent(
@ -987,12 +1002,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, dtoFactory.createAccessPolicyDto(accessPolicy, userGroups,
users)); users));
return entityFactory.createAccessPolicyEntity(snapshot, null, null); return entityFactory.createAccessPolicyEntity(snapshot, null, permissions);
} }
@Override @Override
public FunnelEntity deleteFunnel(final Revision revision, final String funnelId) { public FunnelEntity deleteFunnel(final Revision revision, final String funnelId) {
final Funnel funnel = funnelDAO.getFunnel(funnelId); final Funnel funnel = funnelDAO.getFunnel(funnelId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel);
final FunnelDTO snapshot = deleteComponent( final FunnelDTO snapshot = deleteComponent(
revision, revision,
funnel.getResource(), funnel.getResource(),
@ -1000,7 +1016,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createFunnelDto(funnel)); 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 @Override
public PortEntity deleteInputPort(final Revision revision, final String inputPortId) { public PortEntity deleteInputPort(final Revision revision, final String inputPortId) {
final Port port = inputPortDAO.getPort(inputPortId); final Port port = inputPortDAO.getPort(inputPortId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port);
final PortDTO snapshot = deleteComponent( final PortDTO snapshot = deleteComponent(
revision, revision,
port.getResource(), port.getResource(),
@ -1138,12 +1155,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createPortDto(port)); dtoFactory.createPortDto(port));
return entityFactory.createPortEntity(snapshot, null, null, null, null); return entityFactory.createPortEntity(snapshot, null, permissions, null, null);
} }
@Override @Override
public PortEntity deleteOutputPort(final Revision revision, final String outputPortId) { public PortEntity deleteOutputPort(final Revision revision, final String outputPortId) {
final Port port = outputPortDAO.getPort(outputPortId); final Port port = outputPortDAO.getPort(outputPortId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port);
final PortDTO snapshot = deleteComponent( final PortDTO snapshot = deleteComponent(
revision, revision,
port.getResource(), port.getResource(),
@ -1151,12 +1169,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createPortDto(port)); dtoFactory.createPortDto(port));
return entityFactory.createPortEntity(snapshot, null, null, null, null); return entityFactory.createPortEntity(snapshot, null, permissions, null, null);
} }
@Override @Override
public ProcessGroupEntity deleteProcessGroup(final Revision revision, final String groupId) { public ProcessGroupEntity deleteProcessGroup(final Revision revision, final String groupId) {
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(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 // grab the resources in the snippet so we can delete the policies afterwards
final Set<Resource> groupResources = new HashSet<>(); final Set<Resource> groupResources = new HashSet<>();
@ -1180,12 +1199,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// delete all applicable component policies // delete all applicable component policies
groupResources.forEach(groupResource -> cleanUpPolicies(groupResource)); groupResources.forEach(groupResource -> cleanUpPolicies(groupResource));
return entityFactory.createProcessGroupEntity(snapshot, null, null, null, null); return entityFactory.createProcessGroupEntity(snapshot, null, permissions, null, null);
} }
@Override @Override
public RemoteProcessGroupEntity deleteRemoteProcessGroup(final Revision revision, final String remoteProcessGroupId) { public RemoteProcessGroupEntity deleteRemoteProcessGroup(final Revision revision, final String remoteProcessGroupId) {
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId); final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup);
final RemoteProcessGroupDTO snapshot = deleteComponent( final RemoteProcessGroupDTO snapshot = deleteComponent(
revision, revision,
remoteProcessGroup.getResource(), remoteProcessGroup.getResource(),
@ -1193,7 +1213,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup)); dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup));
return entityFactory.createRemoteProcessGroupEntity(snapshot, null, null, null, null); return entityFactory.createRemoteProcessGroupEntity(snapshot, null, permissions, null, null);
} }
@Override @Override
@ -1846,6 +1866,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override @Override
public ControllerServiceEntity deleteControllerService(final Revision revision, final String controllerServiceId) { public ControllerServiceEntity deleteControllerService(final Revision revision, final String controllerServiceId) {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId); final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService);
final ControllerServiceDTO snapshot = deleteComponent( final ControllerServiceDTO snapshot = deleteComponent(
revision, revision,
controllerService.getResource(), controllerService.getResource(),
@ -1853,7 +1874,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createControllerServiceDto(controllerService)); 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 @Override
public ReportingTaskEntity deleteReportingTask(final Revision revision, final String reportingTaskId) { public ReportingTaskEntity deleteReportingTask(final Revision revision, final String reportingTaskId) {
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId); final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask);
final ReportingTaskDTO snapshot = deleteComponent( final ReportingTaskDTO snapshot = deleteComponent(
revision, revision,
reportingTask.getResource(), reportingTask.getResource(),
@ -1907,7 +1929,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
true, true,
dtoFactory.createReportingTaskDto(reportingTask)); dtoFactory.createReportingTaskDto(reportingTask));
return entityFactory.createReportingTaskEntity(snapshot, null, null, null); return entityFactory.createReportingTaskEntity(snapshot, null, permissions, null);
} }
@Override @Override
@ -2001,8 +2023,33 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public ProcessGroupStatusDTO getProcessGroupStatus(final String groupId) { public ProcessGroupStatusEntity getProcessGroupStatus(final String groupId, final boolean recursive) {
return dtoFactory.createProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(groupId)); 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 @Override
@ -2103,13 +2150,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public ConnectionStatusDTO getConnectionStatus(final String connectionId) { public ConnectionStatusEntity getConnectionStatus(final String connectionId) {
return dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(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 @Override
public StatusHistoryDTO getConnectionStatusHistory(final String connectionId) { public StatusHistoryEntity getConnectionStatusHistory(final String connectionId) {
return controllerFacade.getConnectionStatusHistory(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) { private ProcessorEntity createProcessorEntity(final ProcessorNode processor) {
@ -2198,13 +2251,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public ProcessorStatusDTO getProcessorStatus(final String id) { public ProcessorStatusEntity getProcessorStatus(final String id) {
return dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(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 @Override
public StatusHistoryDTO getProcessorStatusHistory(final String id) { public StatusHistoryEntity getProcessorStatusHistory(final String id) {
return controllerFacade.getProcessorStatusHistory(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) { private boolean authorizeBulletin(final Bulletin bulletin) {
@ -2696,8 +2755,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public PortStatusDTO getInputPortStatus(final String inputPortId) { public PortStatusEntity getInputPortStatus(final String inputPortId) {
return dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(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 @Override
@ -2707,8 +2769,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public PortStatusDTO getOutputPortStatus(final String outputPortId) { public PortStatusEntity getOutputPortStatus(final String outputPortId) {
return dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(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 @Override
@ -2718,13 +2783,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(final String id) { public RemoteProcessGroupStatusEntity getRemoteProcessGroupStatus(final String id) {
return dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(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 @Override
public StatusHistoryDTO getRemoteProcessGroupStatusHistory(final String id) { public StatusHistoryEntity getRemoteProcessGroupStatusHistory(final String id) {
return controllerFacade.getRemoteProcessGroupStatusHistory(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 @Override
@ -2870,8 +2941,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
@Override @Override
public StatusHistoryDTO getProcessGroupStatusHistory(final String groupId) { public StatusHistoryEntity getProcessGroupStatusHistory(final String groupId) {
return controllerFacade.getProcessGroupStatusHistory(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) { private boolean authorizeAction(final Action action) {

View File

@ -47,6 +47,7 @@ import org.apache.nifi.controller.reporting.ReportingTaskProvider;
import org.apache.nifi.registry.VariableRegistry; import org.apache.nifi.registry.VariableRegistry;
import org.apache.nifi.controller.service.ControllerServiceProvider; import org.apache.nifi.controller.service.ControllerServiceProvider;
import org.apache.nifi.util.NiFiProperties; 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.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.ProcessorConfigDTO; import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.ProcessorDTO;
@ -476,11 +477,11 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
for(String key : processorConfig.getDescriptors().keySet()){ for(String key : processorConfig.getDescriptors().keySet()){
PropertyDescriptorDTO descriptor = processorConfig.getDescriptors().get(key); PropertyDescriptorDTO descriptor = processorConfig.getDescriptors().get(key);
List<PropertyDescriptorDTO.AllowableValueDTO> allowableValuesDTO = descriptor.getAllowableValues(); List<AllowableValueDTO> allowableValuesDTO = descriptor.getAllowableValues();
Map<String,String> allowableValues = new HashMap<>(); Map<String,String> allowableValues = new HashMap<>();
if(allowableValuesDTO != null) { if(allowableValuesDTO != null) {
for (PropertyDescriptorDTO.AllowableValueDTO value : allowableValuesDTO) { for (AllowableValueDTO value : allowableValuesDTO) {
allowableValues.put(value.getValue(), value.getDisplayName()); allowableValues.put(value.getValue(), value.getDisplayName());
} }
} }

View File

@ -184,7 +184,7 @@ public class ControllerResource extends ApplicationResource {
required = true required = true
) final ControllerConfigurationEntity configEntity) { ) final ControllerConfigurationEntity configEntity) {
if (configEntity == null || configEntity.getControllerConfiguration() == null) { if (configEntity == null || configEntity.getComponent() == null) {
throw new IllegalArgumentException("Controller configuration must be specified"); throw new IllegalArgumentException("Controller configuration must be specified");
} }
@ -205,7 +205,7 @@ public class ControllerResource extends ApplicationResource {
}, },
null, null,
() -> { () -> {
final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getControllerConfiguration()); final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getComponent());
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
); );

View File

@ -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.flow.ProcessGroupFlowDTO;
import org.apache.nifi.web.api.dto.search.NodeSearchResultDTO; 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.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.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.AboutEntity;
import org.apache.nifi.web.api.entity.ActionEntity; import org.apache.nifi.web.api.entity.ActionEntity;
import org.apache.nifi.web.api.entity.BannerEntity; import org.apache.nifi.web.api.entity.BannerEntity;
@ -465,6 +457,10 @@ public class FlowResource extends ApplicationResource {
authorizeFlow(); authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// get all the controller services // get all the controller services
final Set<ControllerServiceEntity> controllerServices = serviceFacade.getControllerServices(groupId); final Set<ControllerServiceEntity> controllerServices = serviceFacade.getControllerServices(groupId);
controllerServiceResource.populateRemainingControllerServiceEntitiesContent(controllerServices); controllerServiceResource.populateRemainingControllerServiceEntitiesContent(controllerServices);
@ -1273,13 +1269,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified processor status // get the specified processor status
final ProcessorStatusDTO processorStatus = serviceFacade.getProcessorStatus(id); final ProcessorStatusEntity entity = serviceFacade.getProcessorStatus(id);
// generate the response entity
final ProcessorStatusEntity entity = new ProcessorStatusEntity();
entity.setProcessorStatus(processorStatus);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1352,13 +1342,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified input port status // get the specified input port status
final PortStatusDTO portStatus = serviceFacade.getInputPortStatus(id); final PortStatusEntity entity = serviceFacade.getInputPortStatus(id);
// generate the response entity
final PortStatusEntity entity = new PortStatusEntity();
entity.setPortStatus(portStatus);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1431,13 +1415,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified output port status // get the specified output port status
final PortStatusDTO portStatus = serviceFacade.getOutputPortStatus(id); final PortStatusEntity entity = serviceFacade.getOutputPortStatus(id);
// generate the response entity
final PortStatusEntity entity = new PortStatusEntity();
entity.setPortStatus(portStatus);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1510,13 +1488,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified remote process group status // get the specified remote process group status
final RemoteProcessGroupStatusDTO remoteProcessGroupStatus = serviceFacade.getRemoteProcessGroupStatus(id); final RemoteProcessGroupStatusEntity entity = serviceFacade.getRemoteProcessGroupStatus(id);
// generate the response entity
final RemoteProcessGroupStatusEntity entity = new RemoteProcessGroupStatusEntity();
entity.setRemoteProcessGroupStatus(remoteProcessGroupStatus);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1597,37 +1569,10 @@ public class FlowResource extends ApplicationResource {
} }
// get the status // get the status
final ProcessGroupStatusDTO statusReport = serviceFacade.getProcessGroupStatus(groupId); final ProcessGroupStatusEntity entity = serviceFacade.getProcessGroupStatus(groupId, recursive);
// 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
return clusterContext(generateOkResponse(entity)).build(); 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. * Retrieves the specified connection status.
* *
@ -1697,13 +1642,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified connection status // get the specified connection status
final ConnectionStatusDTO connectionStatus = serviceFacade.getConnectionStatus(id); final ConnectionStatusEntity entity = serviceFacade.getConnectionStatus(id);
// generate the response entity
final ConnectionStatusEntity entity = new ConnectionStatusEntity();
entity.setConnectionStatus(connectionStatus);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1753,13 +1692,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified processor status history // get the specified processor status history
final StatusHistoryDTO processorStatusHistory = serviceFacade.getProcessorStatusHistory(id); final StatusHistoryEntity entity = serviceFacade.getProcessorStatusHistory(id);
// generate the response entity
final StatusHistoryEntity entity = new StatusHistoryEntity();
entity.setStatusHistory(processorStatusHistory);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1805,13 +1738,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified processor status history // get the specified processor status history
final StatusHistoryDTO processGroupStatusHistory = serviceFacade.getProcessGroupStatusHistory(groupId); final StatusHistoryEntity entity = serviceFacade.getProcessGroupStatusHistory(groupId);
// generate the response entity
final StatusHistoryEntity entity = new StatusHistoryEntity();
entity.setStatusHistory(processGroupStatusHistory);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1857,13 +1784,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified processor status history // get the specified processor status history
final StatusHistoryDTO remoteProcessGroupStatusHistory = serviceFacade.getRemoteProcessGroupStatusHistory(id); final StatusHistoryEntity entity = serviceFacade.getRemoteProcessGroupStatusHistory(id);
// generate the response entity
final StatusHistoryEntity entity = new StatusHistoryEntity();
entity.setStatusHistory(remoteProcessGroupStatusHistory);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -1909,13 +1830,7 @@ public class FlowResource extends ApplicationResource {
} }
// get the specified processor status history // get the specified processor status history
final StatusHistoryDTO connectionStatusHistory = serviceFacade.getConnectionStatusHistory(id); final StatusHistoryEntity entity = serviceFacade.getConnectionStatusHistory(id);
// generate the response entity
final StatusHistoryEntity entity = new StatusHistoryEntity();
entity.setStatusHistory(connectionStatusHistory);
// generate the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }

View File

@ -110,7 +110,6 @@ import org.apache.nifi.util.FormatUtils;
import org.apache.nifi.util.StringUtils; import org.apache.nifi.util.StringUtils;
import org.apache.nifi.web.FlowModification; import org.apache.nifi.web.FlowModification;
import org.apache.nifi.web.Revision; 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.ActionDTO;
import org.apache.nifi.web.api.dto.action.HistoryDTO; import org.apache.nifi.web.api.dto.action.HistoryDTO;
import org.apache.nifi.web.api.dto.action.component.details.ComponentDetailsDTO; 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.RemoteProcessGroupStatusDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; 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.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.api.entity.TenantEntity;
import org.apache.nifi.web.controller.ControllerFacade; import org.apache.nifi.web.controller.ControllerFacade;
import org.apache.nifi.web.revision.RevisionManager; import org.apache.nifi.web.revision.RevisionManager;
@ -900,73 +904,86 @@ public final class DtoFactory {
return processGroupStatusDto; return processGroupStatusDto;
} }
public ProcessGroupStatusDTO createProcessGroupStatusDto(final ProcessGroupStatus processGroupStatus) { public ProcessGroupStatusDTO createProcessGroupStatusDto(final ProcessGroup processGroup, final ProcessGroupStatus processGroupStatus) {
final ProcessGroupStatusDTO processGroupStatusDto = createConciseProcessGroupStatusDto(processGroupStatus); final ProcessGroupStatusDTO processGroupStatusDto = createConciseProcessGroupStatusDto(processGroupStatus);
final ProcessGroupStatusSnapshotDTO snapshot = processGroupStatusDto.getAggregateSnapshot(); final ProcessGroupStatusSnapshotDTO snapshot = processGroupStatusDto.getAggregateSnapshot();
// processor status // processor status
final Collection<ProcessorStatusSnapshotDTO> processorStatDtoCollection = new ArrayList<>(); final Collection<ProcessorStatusSnapshotEntity> processorStatusSnapshotEntities = new ArrayList<>();
snapshot.setProcessorStatusSnapshots(processorStatDtoCollection); snapshot.setProcessorStatusSnapshots(processorStatusSnapshotEntities);
final Collection<ProcessorStatus> processorStatusCollection = processGroupStatus.getProcessorStatus(); final Collection<ProcessorStatus> processorStatusCollection = processGroupStatus.getProcessorStatus();
if (processorStatusCollection != null) { if (processorStatusCollection != null) {
for (final ProcessorStatus processorStatus : processorStatusCollection) { for (final ProcessorStatus processorStatus : processorStatusCollection) {
final ProcessorStatusDTO processorStatusDto = createProcessorStatusDto(processorStatus); 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 // connection status
final Collection<ConnectionStatusSnapshotDTO> connectionStatusDtoCollection = new ArrayList<>(); final Collection<ConnectionStatusSnapshotEntity> connectionStatusDtoCollection = new ArrayList<>();
snapshot.setConnectionStatusSnapshots(connectionStatusDtoCollection); snapshot.setConnectionStatusSnapshots(connectionStatusDtoCollection);
final Collection<ConnectionStatus> connectionStatusCollection = processGroupStatus.getConnectionStatus(); final Collection<ConnectionStatus> connectionStatusCollection = processGroupStatus.getConnectionStatus();
if (connectionStatusCollection != null) { if (connectionStatusCollection != null) {
for (final ConnectionStatus connectionStatus : connectionStatusCollection) { for (final ConnectionStatus connectionStatus : connectionStatusCollection) {
final ConnectionStatusDTO connectionStatusDto = createConnectionStatusDto(connectionStatus); 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 // local child process groups
final Collection<ProcessGroupStatusSnapshotDTO> childProcessGroupStatusDtoCollection = new ArrayList<>(); final Collection<ProcessGroupStatusSnapshotEntity> childProcessGroupStatusDtoCollection = new ArrayList<>();
snapshot.setProcessGroupStatusSnapshots(childProcessGroupStatusDtoCollection); snapshot.setProcessGroupStatusSnapshots(childProcessGroupStatusDtoCollection);
final Collection<ProcessGroupStatus> childProcessGroupStatusCollection = processGroupStatus.getProcessGroupStatus(); final Collection<ProcessGroupStatus> childProcessGroupStatusCollection = processGroupStatus.getProcessGroupStatus();
if (childProcessGroupStatusCollection != null) { if (childProcessGroupStatusCollection != null) {
for (final ProcessGroupStatus childProcessGroupStatus : childProcessGroupStatusCollection) { for (final ProcessGroupStatus childProcessGroupStatus : childProcessGroupStatusCollection) {
final ProcessGroupStatusDTO childProcessGroupStatusDto = createProcessGroupStatusDto(childProcessGroupStatus); final ProcessGroupStatusDTO childProcessGroupStatusDto = createProcessGroupStatusDto(processGroup, childProcessGroupStatus);
childProcessGroupStatusDtoCollection.add(childProcessGroupStatusDto.getAggregateSnapshot()); final ProcessGroup childProcessGroup = processGroup.findProcessGroup(childProcessGroupStatusDto.getId());
final PermissionsDTO childProcessGroupPermissions = createPermissionsDto(childProcessGroup);
childProcessGroupStatusDtoCollection.add(entityFactory.createProcessGroupStatusSnapshotEntity(childProcessGroupStatusDto.getAggregateSnapshot(), childProcessGroupPermissions));
} }
} }
// remote child process groups // remote child process groups
final Collection<RemoteProcessGroupStatusSnapshotDTO> childRemoteProcessGroupStatusDtoCollection = new ArrayList<>(); final Collection<RemoteProcessGroupStatusSnapshotEntity> childRemoteProcessGroupStatusDtoCollection = new ArrayList<>();
snapshot.setRemoteProcessGroupStatusSnapshots(childRemoteProcessGroupStatusDtoCollection); snapshot.setRemoteProcessGroupStatusSnapshots(childRemoteProcessGroupStatusDtoCollection);
final Collection<RemoteProcessGroupStatus> childRemoteProcessGroupStatusCollection = processGroupStatus.getRemoteProcessGroupStatus(); final Collection<RemoteProcessGroupStatus> childRemoteProcessGroupStatusCollection = processGroupStatus.getRemoteProcessGroupStatus();
if (childRemoteProcessGroupStatusCollection != null) { if (childRemoteProcessGroupStatusCollection != null) {
for (final RemoteProcessGroupStatus childRemoteProcessGroupStatus : childRemoteProcessGroupStatusCollection) { for (final RemoteProcessGroupStatus childRemoteProcessGroupStatus : childRemoteProcessGroupStatusCollection) {
final RemoteProcessGroupStatusDTO childRemoteProcessGroupStatusDto = createRemoteProcessGroupStatusDto(childRemoteProcessGroupStatus); 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 // input ports
final Collection<PortStatusSnapshotDTO> inputPortStatusDtoCollection = new ArrayList<>(); final Collection<PortStatusSnapshotEntity> inputPortStatusDtoCollection = new ArrayList<>();
snapshot.setInputPortStatusSnapshots(inputPortStatusDtoCollection); snapshot.setInputPortStatusSnapshots(inputPortStatusDtoCollection);
final Collection<PortStatus> inputPortStatusCollection = processGroupStatus.getInputPortStatus(); final Collection<PortStatus> inputPortStatusCollection = processGroupStatus.getInputPortStatus();
if (inputPortStatusCollection != null) { if (inputPortStatusCollection != null) {
for (final PortStatus portStatus : inputPortStatusCollection) { for (final PortStatus portStatus : inputPortStatusCollection) {
final PortStatusDTO portStatusDto = createPortStatusDto(portStatus); 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 // output ports
final Collection<PortStatusSnapshotDTO> outputPortStatusDtoCollection = new ArrayList<>(); final Collection<PortStatusSnapshotEntity> outputPortStatusDtoCollection = new ArrayList<>();
snapshot.setOutputPortStatusSnapshots(outputPortStatusDtoCollection); snapshot.setOutputPortStatusSnapshots(outputPortStatusDtoCollection);
final Collection<PortStatus> outputPortStatusCollection = processGroupStatus.getOutputPortStatus(); final Collection<PortStatus> outputPortStatusCollection = processGroupStatus.getOutputPortStatus();
if (outputPortStatusCollection != null) { if (outputPortStatusCollection != null) {
for (final PortStatus portStatus : outputPortStatusCollection) { for (final PortStatus portStatus : outputPortStatusCollection) {
final PortStatusDTO portStatusDto = createPortStatusDto(portStatus); 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));
} }
} }

View File

@ -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.FlowBreadcrumbDTO;
import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO; 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.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.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.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.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.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.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
import org.apache.nifi.web.api.entity.ConnectionEntity; 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.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity; import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity; 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.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.PortEntity; 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.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; 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.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.RemoteProcessGroupEntity;
import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; 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.ReportingTaskEntity;
import org.apache.nifi.web.api.entity.SnippetEntity; 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.TenantEntity;
import org.apache.nifi.web.api.entity.UserEntity; import org.apache.nifi.web.api.entity.UserEntity;
import org.apache.nifi.web.api.entity.UserGroupEntity; import org.apache.nifi.web.api.entity.UserGroupEntity;
@ -49,20 +66,105 @@ import java.util.List;
public final class EntityFactory { 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) { 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(); final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
entity.setRevision(revision); entity.setRevision(revision);
entity.setCurrentTime(new Date()); entity.setCurrentTime(new Date());
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setControllerConfiguration(dto); entity.setComponent(dto);
} }
} }
return entity; return entity;
} }
public ProcessGroupFlowEntity createProcessGroupFlowEntity(final ProcessGroupFlowDTO dto, final PermissionsDTO permissions) { 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(); final ProcessGroupFlowEntity entity = new ProcessGroupFlowEntity();
entity.setProcessGroupFlow(dto); entity.setProcessGroupFlow(dto);
entity.setPermissions(permissions); entity.setPermissions(permissions);
@ -72,6 +174,9 @@ public final class EntityFactory {
public ProcessorEntity createProcessorEntity(final ProcessorDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, public ProcessorEntity createProcessorEntity(final ProcessorDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final ProcessorStatusDTO status, final List<BulletinDTO> bulletins) { final ProcessorStatusDTO status, final List<BulletinDTO> bulletins) {
if (permissions == null || permissions.getCanRead() == null) {
throw new IllegalStateException(NO_PERMISSIONS_MESSAGE);
}
final ProcessorEntity entity = new ProcessorEntity(); final ProcessorEntity entity = new ProcessorEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
@ -80,7 +185,7 @@ public final class EntityFactory {
entity.setId(dto.getId()); entity.setId(dto.getId());
entity.setInputRequirement(dto.getInputRequirement()); entity.setInputRequirement(dto.getInputRequirement());
entity.setPosition(dto.getPosition()); entity.setPosition(dto.getPosition());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
entity.setBulletins(bulletins); 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<BulletinDTO> bulletins) { public PortEntity createPortEntity(final PortDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final PortStatusDTO status, final List<BulletinDTO> bulletins) {
if (permissions == null || permissions.getCanRead() == null) {
throw new IllegalStateException(NO_PERMISSIONS_MESSAGE);
}
final PortEntity entity = new PortEntity(); final PortEntity entity = new PortEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
@ -97,7 +205,7 @@ public final class EntityFactory {
entity.setId(dto.getId()); entity.setId(dto.getId());
entity.setPosition(dto.getPosition()); entity.setPosition(dto.getPosition());
entity.setPortType(dto.getType()); entity.setPortType(dto.getType());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
entity.setBulletins(bulletins); entity.setBulletins(bulletins);
} }
@ -108,6 +216,9 @@ public final class EntityFactory {
public ProcessGroupEntity createProcessGroupEntity(final ProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, public ProcessGroupEntity createProcessGroupEntity(final ProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final ProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) { final ProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) {
if (permissions == null || permissions.getCanRead() == null) {
throw new IllegalStateException(NO_PERMISSIONS_MESSAGE);
}
final ProcessGroupEntity entity = new ProcessGroupEntity(); final ProcessGroupEntity entity = new ProcessGroupEntity();
entity.setRevision(revision); entity.setRevision(revision);
entity.setCurrentTime(new Date()); entity.setCurrentTime(new Date());
@ -133,6 +244,9 @@ public final class EntityFactory {
} }
public LabelEntity createLabelEntity(final LabelDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final LabelEntity entity = new LabelEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
@ -145,7 +259,7 @@ public final class EntityFactory {
dimensions.setWidth(dto.getWidth()); dimensions.setWidth(dto.getWidth());
entity.setDimensions(dimensions); entity.setDimensions(dimensions);
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -153,13 +267,16 @@ public final class EntityFactory {
} }
public UserEntity createUserEntity(final UserDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final UserEntity entity = new UserEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -167,13 +284,16 @@ public final class EntityFactory {
} }
public TenantEntity createTenantEntity(final TenantDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final TenantEntity entity = new TenantEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -181,13 +301,16 @@ public final class EntityFactory {
} }
public AccessPolicySummaryEntity createAccessPolicySummaryEntity(final AccessPolicySummaryDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final AccessPolicySummaryEntity entity = new AccessPolicySummaryEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -195,13 +318,16 @@ public final class EntityFactory {
} }
public UserGroupEntity createUserGroupEntity(final UserGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final UserGroupEntity entity = new UserGroupEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -209,6 +335,9 @@ public final class EntityFactory {
} }
public AccessPolicyEntity createAccessPolicyEntity(final AccessPolicyDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final AccessPolicyEntity entity = new AccessPolicyEntity();
entity.setRevision(revision); entity.setRevision(revision);
entity.setGenerated(new Date()); entity.setGenerated(new Date());
@ -216,7 +345,7 @@ public final class EntityFactory {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -224,13 +353,16 @@ public final class EntityFactory {
} }
public FunnelEntity createFunnelEntity(final FunnelDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final FunnelEntity entity = new FunnelEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
entity.setPosition(dto.getPosition()); entity.setPosition(dto.getPosition());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); 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) { 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(); final ConnectionEntity entity = new ConnectionEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
@ -254,7 +389,7 @@ public final class EntityFactory {
entity.setDestinationId(dto.getDestination().getId()); entity.setDestinationId(dto.getDestination().getId());
entity.setDestinationGroupId(dto.getDestination().getGroupId()); entity.setDestinationGroupId(dto.getDestination().getGroupId());
entity.setDestinationType(dto.getDestination().getType()); entity.setDestinationType(dto.getDestination().getType());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -264,6 +399,9 @@ public final class EntityFactory {
public RemoteProcessGroupEntity createRemoteProcessGroupEntity(final RemoteProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, public RemoteProcessGroupEntity createRemoteProcessGroupEntity(final RemoteProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final RemoteProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) { final RemoteProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) {
if (permissions == null || permissions.getCanRead() == null) {
throw new IllegalStateException(NO_PERMISSIONS_MESSAGE);
}
final RemoteProcessGroupEntity entity = new RemoteProcessGroupEntity(); final RemoteProcessGroupEntity entity = new RemoteProcessGroupEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
@ -273,7 +411,7 @@ public final class EntityFactory {
entity.setPosition(dto.getPosition()); entity.setPosition(dto.getPosition());
entity.setInputPortCount(dto.getInputPortCount()); entity.setInputPortCount(dto.getInputPortCount());
entity.setOutputPortCount(dto.getOutputPortCount()); entity.setOutputPortCount(dto.getOutputPortCount());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
entity.setBulletins(bulletins); entity.setBulletins(bulletins);
} }
@ -282,12 +420,15 @@ public final class EntityFactory {
} }
public RemoteProcessGroupPortEntity createRemoteProcessGroupPortEntity(final RemoteProcessGroupPortDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setRemoteProcessGroupPort(dto); 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<BulletinDTO> bulletins) { public ReportingTaskEntity createReportingTaskEntity(final ReportingTaskDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final List<BulletinDTO> bulletins) {
if (permissions == null || permissions.getCanRead() == null) {
throw new IllegalStateException(NO_PERMISSIONS_MESSAGE);
}
final ReportingTaskEntity entity = new ReportingTaskEntity(); final ReportingTaskEntity entity = new ReportingTaskEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
entity.setBulletins(bulletins); 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<BulletinDTO> bulletins) { public ControllerServiceEntity createControllerServiceEntity(final ControllerServiceDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final List<BulletinDTO> bulletins) {
if (permissions == null || permissions.getCanRead() == null) {
throw new IllegalStateException(NO_PERMISSIONS_MESSAGE);
}
final ControllerServiceEntity entity = new ControllerServiceEntity(); final ControllerServiceEntity entity = new ControllerServiceEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
entity.setPosition(dto.getPosition()); entity.setPosition(dto.getPosition());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
entity.setBulletins(bulletins); entity.setBulletins(bulletins);
} }
@ -334,12 +481,15 @@ public final class EntityFactory {
public ControllerServiceReferencingComponentEntity createControllerServiceReferencingComponentEntity( public ControllerServiceReferencingComponentEntity createControllerServiceReferencingComponentEntity(
final ControllerServiceReferencingComponentDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) { 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(); final ControllerServiceReferencingComponentEntity entity = new ControllerServiceReferencingComponentEntity();
entity.setRevision(revision); entity.setRevision(revision);
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setComponent(dto); entity.setComponent(dto);
} }
} }
@ -348,11 +498,14 @@ public final class EntityFactory {
} }
public FlowBreadcrumbEntity createFlowBreadcrumbEntity(final FlowBreadcrumbDTO dto, final PermissionsDTO permissions) { 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(); final FlowBreadcrumbEntity entity = new FlowBreadcrumbEntity();
if (dto != null) { if (dto != null) {
entity.setPermissions(permissions); entity.setPermissions(permissions);
entity.setId(dto.getId()); entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) { if (permissions.getCanRead()) {
entity.setBreadcrumb(dto); entity.setBreadcrumb(dto);
} }
} }

Some files were not shown because too many files have changed in this diff Show More