package com.thinkbiganalytics.nifi.rest.support;
/*-
* #%L
* thinkbig-nifi-rest-common-util
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* Licensed 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.
* #L%
*/
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Utiltiy class to get connection information out of the NiFi {@link ConnectionDTO} objects
*/
public class NifiConnectionUtil {
/**
* Return all processorIds marked as sources from a set of connections
*
* @param connections a set of connection objects
* @return a list of processor ids that are source processors
*/
public static List<String> getInputProcessorIds(Collection<ConnectionDTO> connections) {
List<String> processorIds = new ArrayList<>();
SourcesAndDestinations connectionItems = new SourcesAndDestinations(connections);
//find all sources that are not in a destination
for (String source : connectionItems.getSourceConnections()) {
if (!connectionItems.getDestinationConnections().contains(source)) {
processorIds.add(source);
}
}
return processorIds;
}
/**
* Return a list of input port ids from a set of connections
*
* @param connections a set of connection objects
* @return a list of the port ids
*/
public static List<String> getInputPortIds(Collection<ConnectionDTO> connections) {
List<String> inputPortIds = new ArrayList<>();
if (connections != null) {
for (ConnectionDTO connectionDTO : connections) {
if (connectionDTO.getSource().getType().equals(NifiConstants.NIFI_PORT_TYPE.INPUT_PORT.name())) {
inputPortIds.add(connectionDTO.getSource().getId());
}
}
}
return inputPortIds;
}
/**
* Return a list of processor ids that dont have any additional connections coming out of them
*
* @param connections a set of connection objects
* @return a list of ending processor ids
*/
public static List<String> getEndingProcessorIds(Collection<ConnectionDTO> connections) {
List<String> processorIds = new ArrayList<>();
SourcesAndDestinations connectionItems = new SourcesAndDestinations(connections);
//find all destinations that are not in a source
for (String dest : connectionItems.getDestinationConnections()) {
if (!connectionItems.getSourceConnections().contains(dest)) {
processorIds.add(dest);
}
}
return processorIds;
}
/**
* Return a list of connection objects whose source group id matches the {@code sourceProcessGroupId}
*
* @param connections a collection of connection objects
* @param sourceProcessGroupId a groupid to match against the connection.source.groupId field
* @return a list of connections that have their source under the same {@code sourceProcessGroupId}
*/
public static List<ConnectionDTO> findConnectionsMatchingSourceGroupId(Collection<ConnectionDTO> connections, final String sourceProcessGroupId) {
return Lists.newArrayList(Iterables.filter(connections, new Predicate<ConnectionDTO>() {
@Override
public boolean apply(ConnectionDTO connectionDTO) {
return connectionDTO.getSource().getGroupId().equals(sourceProcessGroupId);
}
}));
}
/**
* Return a list of connection objects whose destination group id matches the {@code destProcessGroupId}
*
* @param connections a collection of connection objects
* @param destProcessGroupId a groupid to match against the connection.destination.groupId field
* @return a list of connections that have their destinations under the same {@code destProcessGroupId}
*/
public static List<ConnectionDTO> findConnectionsMatchingDestinationGroupId(Collection<ConnectionDTO> connections, final String destProcessGroupId) {
return Lists.newArrayList(Iterables.filter(connections, new Predicate<ConnectionDTO>() {
@Override
public boolean apply(ConnectionDTO connectionDTO) {
return connectionDTO.getDestination().getGroupId().equals(destProcessGroupId);
}
}));
}
/**
* Return a list of connections that have a destination id matching the supplied {@code destId}
*
* @param connections a collection of connection objects
* @param destId a id to match against each connection.destination.id
* @return a list of connections that contain the {code destId}
*/
public static List<ConnectionDTO> findConnectionsMatchingDestinationId(Collection<ConnectionDTO> connections, final String destId) {
return Lists.newArrayList(Iterables.filter(connections, new Predicate<ConnectionDTO>() {
@Override
public boolean apply(ConnectionDTO connectionDTO) {
return connectionDTO.getDestination().getId().equals(destId);
}
}));
}
/**
* Return a list of connections that have a destination id matching the supplied {@code sourceId}
*
* @param connections a collection of connection objects
* @param sourceId a id to match against each connection.source.id
* @return a list of connections that contain the {code sourceId}
*/
public static List<ConnectionDTO> findConnectionsMatchingSourceId(Collection<ConnectionDTO> connections, final String sourceId) {
return Lists.newArrayList(Iterables.filter(connections, new Predicate<ConnectionDTO>() {
@Override
public boolean apply(ConnectionDTO connectionDTO) {
return connectionDTO.getSource().getId().equals(sourceId);
}
}));
}
/**
* Return a connection that has both the supplied source and destination id
*
* @param connections a collection of connection objects
* @param sourceId a sourceId to match
* @param destId a destination id to match
* @return a connection that has both the source and destination id
*/
public static ConnectionDTO findConnection(Collection<ConnectionDTO> connections, final String sourceId, final String destId) {
ConnectionDTO connection = null;
connection = Iterables.tryFind(connections, new Predicate<ConnectionDTO>() {
@Override
public boolean apply(ConnectionDTO connectionDTO) {
return connectionDTO.getSource().getId().equals(sourceId) && connectionDTO.getDestination()
.getId().equalsIgnoreCase(destId);
}
}).orNull();
return connection;
}
/**
* Return a input or output port dto matching a give name
*
* @param ports a collection of port objects
* @param name a name to match
* @return the first port dto matching the supplied name
*/
public static PortDTO findPortMatchingName(Collection<PortDTO> ports, final String name) {
return Iterables.tryFind(ports, new Predicate<PortDTO>() {
@Override
public boolean apply(PortDTO portDTO) {
return portDTO.getName().equalsIgnoreCase(name);
}
}).orNull();
}
/**
* Recursively return all the connection objects under a given process group.
* Recursively call any child process groups under the initial group and gather all their connections as well
*
* @param group that group to look under
* @return a set of connections under the supplied group and all the children
*/
public static Set<ConnectionDTO> getAllConnections(ProcessGroupDTO group) {
Set<ConnectionDTO> connections = new HashSet<>();
if (group != null) {
connections.addAll(group.getContents().getConnections());
if (group.getContents().getProcessGroups() != null) {
for (ProcessGroupDTO groupDTO : group.getContents().getProcessGroups()) {
connections.addAll(getAllConnections(groupDTO));
}
}
}
return connections;
}
/**
* Class marking information about a connection
*/
private static class SourcesAndDestinations {
private List<String> destinationConnections = new ArrayList<>();
private List<String> sourceConnections = new ArrayList<>();
private List<String> selfReferencingConnections = new ArrayList<>();
public SourcesAndDestinations(Collection<ConnectionDTO> connections) {
if (connections != null) {
for (ConnectionDTO connection : connections) {
sourceConnections.add(connection.getSource().getId());
if (!connection.getSource().getId().equalsIgnoreCase(connection.getDestination().getId())) {
destinationConnections.add(connection.getDestination().getId());
}
}
}
}
public List<String> getSelfReferencingConnections() {
return selfReferencingConnections;
}
public List<String> getDestinationConnections() {
return destinationConnections;
}
public List<String> getSourceConnections() {
return sourceConnections;
}
}
}