/* * 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.groups; import org.apache.nifi.authorization.resource.ComponentAuthorizable; import org.apache.nifi.connectable.Connectable; import org.apache.nifi.connectable.Connection; import org.apache.nifi.connectable.Funnel; import org.apache.nifi.connectable.Port; import org.apache.nifi.connectable.Positionable; import org.apache.nifi.controller.ProcessorNode; import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.Snippet; import org.apache.nifi.controller.Template; import org.apache.nifi.controller.label.Label; import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.Processor; import org.apache.nifi.remote.RemoteGroupPort; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Predicate; /** * <p> * ProcessGroup objects are containers for processing entities, such as * {@link Processor}s, {@link Port}s, and other {@link ProcessGroup}s. * </p> * * <p> * MUST BE THREAD-SAFE</p> */ public interface ProcessGroup extends ComponentAuthorizable, Positionable { /** * Predicate for filtering schedulable Processors. */ Predicate<ProcessorNode> SCHEDULABLE_PROCESSORS = node -> !node.isRunning() && !ScheduledState.DISABLED.equals(node.getScheduledState()) && node.isValid(); /** * Predicate for filtering unschedulable Processors. */ Predicate<ProcessorNode> UNSCHEDULABLE_PROCESSORS = node -> node.isRunning(); /** * Predicate for filtering schedulable Ports */ Predicate<Port> SCHEDULABLE_PORTS = port -> !port.isRunning() && !ScheduledState.DISABLED.equals(port.getScheduledState()) && port.isValid(); /** * Predicate for filtering schedulable Ports */ Predicate<Port> UNSCHEDULABLE_PORTS = port -> ScheduledState.RUNNING.equals(port.getScheduledState()); /** * @return a reference to this ProcessGroup's parent. This will be * <tt>null</tt> if and only if this is the root group. */ ProcessGroup getParent(); /** * Updates the ProcessGroup to point to a new parent * * @param group new parent group */ void setParent(ProcessGroup group); /** * @return the ID of the ProcessGroup */ String getIdentifier(); /** * @return the name of the ProcessGroup */ String getName(); /** * Updates the name of this ProcessGroup. * * @param name new name */ void setName(String name); /** * @return the user-set comments about this ProcessGroup, or * <code>null</code> if no comments have been set */ String getComments(); /** * Updates the comments for this ProcessGroup * * @param comments new comments */ void setComments(String comments); /** * @return the counts for this ProcessGroup */ ProcessGroupCounts getCounts(); /** * Starts all Processors, Local Ports, and Funnels that are directly within * this group and any child ProcessGroups, except for those that are * disabled. */ void startProcessing(); /** * Stops all Processors, Local Ports, and Funnels that are directly within * this group and child ProcessGroups, except for those that are disabled. */ void stopProcessing(); /** * Enables the given Processor * * @param processor the processor to start * @throws IllegalStateException if the processor is not valid, or is * already running */ void enableProcessor(ProcessorNode processor); /** * Enables the given Input Port * * @param port to enable */ void enableInputPort(Port port); /** * Enables the given Output Port * * @param port to enable */ void enableOutputPort(Port port); /** * Starts the given Processor * * @param processor the processor to start * @throws IllegalStateException if the processor is not valid, or is * already running */ void startProcessor(ProcessorNode processor); /** * Starts the given Input Port * * @param port to start */ void startInputPort(Port port); /** * Starts the given Output Port * * @param port to start */ void startOutputPort(Port port); /** * Starts the given Funnel * * @param funnel to start */ void startFunnel(Funnel funnel); /** * Stops the given Processor * * @param processor to stop */ void stopProcessor(ProcessorNode processor); /** * Stops the given Port * * @param port to stop */ void stopInputPort(Port port); /** * Stops the given Port * * @param port to stop */ void stopOutputPort(Port port); /** * Disables the given Processor * * @param processor the processor to start * @throws IllegalStateException if the processor is not valid, or is * already running */ void disableProcessor(ProcessorNode processor); /** * Disables the given Input Port * * @param port to disable */ void disableInputPort(Port port); /** * Disables the given Output Port * * @param port to disable */ void disableOutputPort(Port port); /** * Indicates that the Flow is being shutdown; allows cleanup of resources * associated with processors, etc. */ void shutdown(); /** * @return a boolean indicating whether or not this ProcessGroup is the root * group */ boolean isRootGroup(); /** * Adds a {@link Port} to be used for transferring {@link FlowFile}s from * external sources to {@link Processor}s and other {@link Port}s within * this ProcessGroup. * * @param port to add */ void addInputPort(Port port); /** * Removes a {@link Port} from this ProcessGroup's list of Input Ports. * * @param port the Port to remove * @throws NullPointerException if <code>port</code> is null * @throws IllegalStateException if port is not an Input Port for this * ProcessGroup */ void removeInputPort(Port port); /** * @return the {@link Set} of all {@link Port}s that are used by this * ProcessGroup as Input Ports. */ Set<Port> getInputPorts(); /** * @param id the ID of the input port * @return the input port with the given ID, or <code>null</code> if it does * not exist. */ Port getInputPort(String id); /** * Adds a {@link Port} to be used for transferring {@link FlowFile}s to * external sources. * * @param port the Port to add */ void addOutputPort(Port port); /** * Removes a {@link Port} from this ProcessGroup's list of Output Ports. * * @param port the Port to remove * @throws NullPointerException if <code>port</code> is null * @throws IllegalStateException if port is not an Input Port for this * ProcessGroup */ void removeOutputPort(Port port); /** * @param id the ID of the output port * @return the output port with the given ID, or <code>null</code> if it * does not exist. */ Port getOutputPort(String id); /** * @return the {@link Set} of all {@link Port}s that are used by this * ProcessGroup as Output Ports. */ Set<Port> getOutputPorts(); /** * Adds a reference to a ProgressGroup as a child of this. * * @param group to add */ void addProcessGroup(ProcessGroup group); /** * Returns the ProcessGroup whose parent is <code>this</code> and whose id * is given * * @param id identifier of group to get * @return child group */ ProcessGroup getProcessGroup(String id); /** * @return a {@link Set} of all Process Group References that are contained * within this. */ Set<ProcessGroup> getProcessGroups(); /** * @param group the group to remove * @throws NullPointerException if <code>group</code> is null * @throws IllegalStateException if group is not member of this * ProcessGroup, or the given ProcessGroup is not empty (i.e., it contains * at least one Processor, ProcessGroup, Input Port, Output Port, or Label). */ void removeProcessGroup(ProcessGroup group); /** * Adds the already constructed processor instance to this group * * @param processor the processor to add */ void addProcessor(ProcessorNode processor); /** * Removes the given processor from this group, destroying the Processor. * The Processor is removed from the ProcessorRegistry, and any method in * the Processor that is annotated with the * {@link org.apache.nifi.processor.annotation.OnRemoved OnRemoved} annotation will be * invoked. All outgoing connections will also be destroyed * * @param processor the Processor to remove * @throws NullPointerException if <code>processor</code> is null * @throws IllegalStateException if <code>processor</code> is not a member * of this ProcessGroup, is currently running, or has any incoming * connections. */ void removeProcessor(ProcessorNode processor); /** * @return a {@link Collection} of all FlowFileProcessors that are contained * within this. */ Set<ProcessorNode> getProcessors(); /** * Returns the FlowFileProcessor with the given ID. * * @param id the ID of the processor to retrieve * @return the processor with the given ID * @throws NullPointerException if <code>id</code> is null. */ ProcessorNode getProcessor(String id); /** * @param id the ID of the Connectable * @return the <code>Connectable</code> with the given ID, or * <code>null</code> if the <code>Connectable</code> is not a member of the * group */ Connectable getConnectable(String id); /** * Adds the given connection to this ProcessGroup. This method also notifies * the Source and Destination of the Connection that the Connection has been * established. * * @param connection to add * @throws NullPointerException if the connection is null * @throws IllegalStateException if the source or destination of the * connection is not a member of this ProcessGroup or if a connection * already exists in this ProcessGroup with the same ID */ void addConnection(Connection connection); /** * Removes the connection from this ProcessGroup. * * @param connection to remove * @throws IllegalStateException if <code>connection</code> is not contained * within this. */ void removeConnection(Connection connection); /** * Inherits a Connection from another ProcessGroup; this does not perform * any validation but simply notifies the ProcessGroup that it is now the * owner of the given Connection. This is used in place of the * {@link #addConnection(Connection)} method when moving Connections from * one group to another because addConnection notifies both the Source and * Destination of the Connection that the Connection has been established; * this method does not notify either, as both the Source and Destination * should already be aware of the Connection. * * @param connection to inherit */ void inheritConnection(Connection connection); /** * @param id identifier of connection * @return the Connection with the given ID, or <code>null</code> if the * connection does not exist. */ Connection getConnection(String id); /** * @return the {@link Set} of all {@link Connection}s contained within this */ Set<Connection> getConnections(); /** * @param id of the Connection * @return the Connection with the given ID, if it exists as a child or * descendant of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ Connection findConnection(String id); /** * @return a List of all Connections contains within this ProcessGroup and * any child ProcessGroups */ List<Connection> findAllConnections(); /** * @param id of the Funnel * @return the Funnel with the given ID, if it exists as a child or * descendant of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ Funnel findFunnel(String id); /** * @param id of the Controller Service * @return the Controller Service with the given ID, if it exists as a child or * descendant of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ ControllerServiceNode findControllerService(String id); /** * @return a List of all Controller Services contained within this ProcessGroup and any child Process Groups */ Set<ControllerServiceNode> findAllControllerServices(); /** * Adds the given RemoteProcessGroup to this ProcessGroup * * @param remoteGroup group to add * * @throws NullPointerException if the given argument is null */ void addRemoteProcessGroup(RemoteProcessGroup remoteGroup); /** * Removes the given RemoteProcessGroup from this ProcessGroup * * @param remoteGroup group to remove * @throws NullPointerException if the argument is null * @throws IllegalStateException if the given argument does not belong to * this ProcessGroup */ void removeRemoteProcessGroup(RemoteProcessGroup remoteGroup); /** * @param id identifier of group to find * @return the RemoteProcessGroup that is the child of this ProcessGroup and * has the given ID. If no RemoteProcessGroup can be found with the given * ID, returns <code>null</code> */ RemoteProcessGroup getRemoteProcessGroup(String id); /** * @return a set of all RemoteProcessGroups that belong to this * ProcessGroup. If no RemoteProcessGroup's have been added to this * ProcessGroup, will return an empty Set */ Set<RemoteProcessGroup> getRemoteProcessGroups(); /** * Adds the given Label to this ProcessGroup * * @param label the label to add * * @throws NullPointerException if the argument is null */ void addLabel(Label label); /** * Removes the given Label from this ProcessGroup * * @param label the label to remove * @throws NullPointerException if the argument is null * @throws IllegalStateException if the given argument does not belong to * this ProcessGroup */ void removeLabel(Label label); /** * @return a set of all Labels that belong to this ProcessGroup. If no * Labels belong to this ProcessGroup, returns an empty Set */ Set<Label> getLabels(); /** * @param id of the label * @return the Label that belongs to this ProcessGroup and has the given id. * If no Label can be found with this ID, returns <code>null</code> */ Label getLabel(String id); /** * @param id of the group * @return the Process Group with the given ID, if it exists as a child of * this ProcessGroup, or is this ProcessGroup. This performs a recursive * search of all ProcessGroups and descendant ProcessGroups */ ProcessGroup findProcessGroup(String id); /** * @return a List of all ProcessGroups that are children or descendants of this * ProcessGroup. This performs a recursive search of all descendant * ProcessGroups */ List<ProcessGroup> findAllProcessGroups(); /** * @param id of the group * @return the RemoteProcessGroup with the given ID, if it exists as a child * or descendant of this ProcessGroup. This performs a recursive search of * all ProcessGroups and descendant ProcessGroups */ RemoteProcessGroup findRemoteProcessGroup(String id); /** * @return a List of all Remote Process Groups that are children or * descendants of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ List<RemoteProcessGroup> findAllRemoteProcessGroups(); /** * @param id of the processor node * @return the Processor with the given ID, if it exists as a child or * descendant of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ ProcessorNode findProcessor(String id); /** * @return a List of all Processors that are children or descendants of this * ProcessGroup. This performs a recursive search of all descendant * ProcessGroups */ List<ProcessorNode> findAllProcessors(); /** * @param id of the Label * @return the Label with the given ID, if it exists as a child or * descendant of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ Label findLabel(String id); /** * @return a List of all Labels that are children or descendants of this * ProcessGroup. This performsn a recursive search of all descendant * ProcessGroups */ List<Label> findAllLabels(); /** * @param id of the port * @return the input port with the given ID, if it exists; otherwise returns * null. This performs a recursive search of all Input Ports and descendant * ProcessGroups */ Port findInputPort(String id); /** * @return a List of all InputPorts that are children or descendants of this * ProcessGroup. This performs a recursive search of all descendant * ProcessGroups */ List<Port> findAllInputPorts(); /** * @param name of port * @return the input port with the given name, if it exists; otherwise * returns null */ Port getInputPortByName(String name); /** * @param id of the port * @return the output port with the given ID, if it exists; otherwise * returns null. This performs a recursive search of all Output Ports and * descendant ProcessGroups */ Port findOutputPort(String id); /** * @return a List of all OutputPorts that are children or descendants of this * ProcessGroup. This performs a recursive search of all descendant * ProcessGroups */ List<Port> findAllOutputPorts(); /** * @param name of the port * @return the output port with the given name, if it exists; otherwise * returns null */ Port getOutputPortByName(String name); /** * Adds the given funnel to this ProcessGroup and starts it. While other * components do not automatically start, the funnel does by default because * it is intended to be more of a notional component that users are unable * to explicitly start and stop. However, there is an override available in * {@link #addFunnel(Funnel, boolean)} because we may need to avoid starting * the funnel on restart until the flow is completely initialized. * * @param funnel to add */ void addFunnel(Funnel funnel); /** * Adds the given funnel to this ProcessGroup and optionally starts the * funnel. * * @param funnel to add * @param autoStart true if should auto start */ void addFunnel(Funnel funnel, boolean autoStart); /** * @return a Set of all Funnels that belong to this ProcessGroup */ Set<Funnel> getFunnels(); /** * @param id of the funnel * @return the funnel with the given identifier */ Funnel getFunnel(String id); /** * Removes the given funnel from this ProcessGroup * * @param funnel to remove * * @throws IllegalStateException if the funnel is not a member of this * ProcessGroup or has incoming or outgoing connections */ void removeFunnel(Funnel funnel); /** * @return a List of all Funnel that are children or descendants of this * ProcessGroup. This performs a recursive search of all descendant * ProcessGroups */ List<Funnel> findAllFunnels(); /** * Adds the given Controller Service to this group * * @param service the service to add */ void addControllerService(ControllerServiceNode service); /** * Returns the controller service with the given id * * @param id the id of the controller service * @return the controller service with the given id, or <code>null</code> if no service exists with that id */ ControllerServiceNode getControllerService(String id); /** * Returns a Set of all Controller Services that are available in this Process Group * * @param recursive if <code>true</code>, returns the Controller Services available to the parent Process Group, its parents, etc. * @return a Set of all Controller Services that are available in this Process Group */ Set<ControllerServiceNode> getControllerServices(boolean recursive); /** * Removes the given Controller Service from this group * * @param service the service to remove */ void removeControllerService(ControllerServiceNode service); /** * @return <code>true</code> if this ProcessGroup has no Processors, Labels, * Connections, ProcessGroups, RemoteProcessGroupReferences, or Ports. * Otherwise, returns <code>false</code>. */ boolean isEmpty(); /** * Removes all of the components whose ID's are specified within the given * {@link Snippet} from this ProcessGroup. * * @param snippet to remove * * @throws NullPointerException if argument is null * @throws IllegalStateException if any ID in the snippet refers to a * component that is not within this ProcessGroup */ void remove(final Snippet snippet); /** * @param identifier of connectable * @return the Connectable with the given ID, if it exists; otherwise * returns null. This performs a recursive search of all ProcessGroups' * input ports, output ports, funnels, processors */ Connectable findLocalConnectable(String identifier); /** * @param identifier of remote group port * @return the RemoteGroupPort with the given ID, if it exists; otherwise * returns null. */ RemoteGroupPort findRemoteGroupPort(String identifier); /** * @return a Set of all {@link org.apache.nifi.connectable.Positionable}s contained within this * {@link ProcessGroup} and any child {@link ProcessGroup}s */ Set<Positionable> findAllPositionables(); /** * Moves all of the components whose ID's are specified within the given * {@link Snippet} from this ProcessGroup into the given destination * ProcessGroup * * @param snippet to move * @param destination where to move * @throws NullPointerException if either argument is null * @throws IllegalStateException if any ID in the snippet refers to a * component that is not within this ProcessGroup */ void move(final Snippet snippet, final ProcessGroup destination); /** * Verifies a template with the specified name can be created. * * @param name name of the template */ void verifyCanAddTemplate(String name); void verifyCanDelete(); /** * Ensures that the ProcessGroup is eligible to be deleted. * * @param ignorePortConnections if true, the Connections that are currently connected to Ports * will be ignored. Otherwise, the ProcessGroup is not eligible for deletion if its input ports * or output ports have any connections * * @throws IllegalStateException if the ProcessGroup is not eligible for deletion */ void verifyCanDelete(boolean ignorePortConnections); void verifyCanStart(Connectable connectable); void verifyCanStart(); void verifyCanStop(Connectable connectable); void verifyCanStop(); /** * Ensures that deleting the given snippet is a valid operation at this * point in time, depending on the state of this ProcessGroup * * @param snippet to delete * * @throws IllegalStateException if deleting the Snippet is not valid at * this time */ void verifyCanDelete(Snippet snippet); /** * Ensure that moving the given snippet to the given new group is a valid * operation at this point in time, depending on the state of both * ProcessGroups * * @param snippet to move * @param newProcessGroup new location * * @throws IllegalStateException if the move is not valid at this time */ void verifyCanMove(Snippet snippet, ProcessGroup newProcessGroup); /** * Adds the given template to this Process Group * * @param template the template to add */ void addTemplate(Template template); /** * Removes the given template from the Process Group * * @param template the template to remove */ void removeTemplate(Template template); /** * Returns the template with the given ID * * @param id the ID of the template * @return the template with the given ID or <code>null</code> if no template * exists in this Process Group with the given ID */ Template getTemplate(String id); /** * @param id of the template * @return the Template with the given ID, if it exists as a child or * descendant of this ProcessGroup. This performs a recursive search of all * descendant ProcessGroups */ Template findTemplate(String id); /** * @return a Set of all Templates that belong to this Process Group */ Set<Template> getTemplates(); /** * @return a Set of all Templates that belong to this Process Group and any descendant Process Groups */ Set<Template> findAllTemplates(); }