Search in sources :

Example 41 with Connection

use of org.apache.nifi.connectable.Connection in project nifi by apache.

the class RepositoryContext method isRelationshipAvailabilitySatisfied.

/**
 * A Relationship is said to be Available if and only if all Connections for that Relationship are either self-loops or have non-full queues.
 *
 * @param requiredNumber minimum number of relationships that must have availability
 * @return Checks if at least <code>requiredNumber</code> of Relationationships are "available." If so, returns <code>true</code>, otherwise returns <code>false</code>
 */
public boolean isRelationshipAvailabilitySatisfied(final int requiredNumber) {
    int unavailable = 0;
    final Collection<Relationship> allRelationships = connectable.getRelationships();
    final int numRelationships = allRelationships.size();
    // the maximum number of Relationships that can be unavailable and still return true.
    final int maxUnavailable = numRelationships - requiredNumber;
    for (final Relationship relationship : allRelationships) {
        final Collection<Connection> connections = connectable.getConnections(relationship);
        if (connections != null && !connections.isEmpty()) {
            boolean available = true;
            for (final Connection connection : connections) {
                // consider self-loops available
                if (connection.getSource() == connection.getDestination()) {
                    continue;
                }
                if (connection.getFlowFileQueue().isFull()) {
                    available = false;
                    break;
                }
            }
            if (!available) {
                unavailable++;
                if (unavailable > maxUnavailable) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : Relationship(org.apache.nifi.processor.Relationship) Connection(org.apache.nifi.connectable.Connection)

Example 42 with Connection

use of org.apache.nifi.connectable.Connection in project nifi by apache.

the class StandardProcessSession method get.

@Override
public FlowFile get() {
    verifyTaskActive();
    final List<Connection> connections = context.getPollableConnections();
    final int numConnections = connections.size();
    for (int numAttempts = 0; numAttempts < numConnections; numAttempts++) {
        final Connection conn = connections.get(context.getNextIncomingConnectionIndex() % numConnections);
        final Set<FlowFileRecord> expired = new HashSet<>();
        final FlowFileRecord flowFile = conn.poll(expired);
        removeExpired(expired, conn);
        if (flowFile != null) {
            registerDequeuedRecord(flowFile, conn);
            return flowFile;
        }
    }
    return null;
}
Also used : Connection(org.apache.nifi.connectable.Connection) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 43 with Connection

use of org.apache.nifi.connectable.Connection in project nifi by apache.

the class StandardProcessSession method migrate.

private void migrate(final StandardProcessSession newOwner, Collection<FlowFile> flowFiles) {
    // We don't call validateRecordState() here because we want to allow migration of FlowFiles that have already been marked as removed or transferred, etc.
    flowFiles = flowFiles.stream().map(this::getMostRecent).collect(Collectors.toList());
    for (final FlowFile flowFile : flowFiles) {
        if (openInputStreams.containsKey(flowFile)) {
            throw new IllegalStateException(flowFile + " cannot be migrated to a new Process Session because this session currently " + "has an open InputStream for the FlowFile, created by calling ProcessSession.read(FlowFile)");
        }
        if (openOutputStreams.containsKey(flowFile)) {
            throw new IllegalStateException(flowFile + " cannot be migrated to a new Process Session because this session currently " + "has an open OutputStream for the FlowFile, created by calling ProcessSession.write(FlowFile)");
        }
        if (readRecursionSet.containsKey(flowFile)) {
            throw new IllegalStateException(flowFile + " already in use for an active callback or InputStream created by ProcessSession.read(FlowFile) has not been closed");
        }
        if (writeRecursionSet.contains(flowFile)) {
            throw new IllegalStateException(flowFile + " already in use for an active callback or OutputStream created by ProcessSession.write(FlowFile) has not been closed");
        }
        final StandardRepositoryRecord record = records.get(flowFile);
        if (record == null) {
            throw new FlowFileHandlingException(flowFile + " is not known in this session (" + toString() + ")");
        }
    }
    // If we have a FORK event for one of the given FlowFiles, then all children must also be migrated. Otherwise, we
    // could have a case where we have FlowFile A transferred and eventually exiting the flow and later the 'newOwner'
    // ProcessSession is committed, claiming to have created FlowFiles from the parent, which is no longer even in
    // the flow. This would be very confusing when looking at the provenance for the FlowFile, so it is best to avoid this.
    final Set<String> flowFileIds = flowFiles.stream().map(ff -> ff.getAttribute(CoreAttributes.UUID.key())).collect(Collectors.toSet());
    for (final Map.Entry<FlowFile, ProvenanceEventBuilder> entry : forkEventBuilders.entrySet()) {
        final FlowFile eventFlowFile = entry.getKey();
        if (flowFiles.contains(eventFlowFile)) {
            final ProvenanceEventBuilder eventBuilder = entry.getValue();
            for (final String childId : eventBuilder.getChildFlowFileIds()) {
                if (!flowFileIds.contains(childId)) {
                    throw new IllegalStateException("Cannot migrate " + eventFlowFile + " to a new session because it was forked to create " + eventBuilder.getChildFlowFileIds().size() + " children and not all children are being migrated. If any FlowFile is forked, all of its children must also be migrated at the same time as the forked FlowFile");
                }
            }
        }
    }
    // event builder for the new owner of the FlowFile and remove the child from our fork event builder.
    for (final Map.Entry<FlowFile, ProvenanceEventBuilder> entry : forkEventBuilders.entrySet()) {
        final FlowFile eventFlowFile = entry.getKey();
        final ProvenanceEventBuilder eventBuilder = entry.getValue();
        final Set<String> childrenIds = new HashSet<>(eventBuilder.getChildFlowFileIds());
        ProvenanceEventBuilder copy = null;
        for (final FlowFile flowFile : flowFiles) {
            final String flowFileId = flowFile.getAttribute(CoreAttributes.UUID.key());
            if (childrenIds.contains(flowFileId)) {
                eventBuilder.removeChildFlowFile(flowFile);
                if (copy == null) {
                    copy = eventBuilder.copy();
                    copy.getChildFlowFileIds().clear();
                }
                copy.addChildFlowFile(flowFileId);
            }
        }
        if (copy != null) {
            newOwner.forkEventBuilders.put(eventFlowFile, copy);
        }
    }
    newOwner.processingStartTime = Math.min(newOwner.processingStartTime, processingStartTime);
    for (final FlowFile flowFile : flowFiles) {
        final FlowFileRecord flowFileRecord = (FlowFileRecord) flowFile;
        final StandardRepositoryRecord repoRecord = this.records.remove(flowFile);
        newOwner.records.put(flowFileRecord, repoRecord);
        // Adjust the counts for Connections for each FlowFile that was pulled from a Connection.
        // We do not have to worry about accounting for 'input counts' on connections because those
        // are incremented only during a checkpoint, and anything that's been checkpointed has
        // also been committed above.
        final FlowFileQueue inputQueue = repoRecord.getOriginalQueue();
        if (inputQueue != null) {
            final String connectionId = inputQueue.getIdentifier();
            incrementConnectionOutputCounts(connectionId, -1, -repoRecord.getOriginal().getSize());
            newOwner.incrementConnectionOutputCounts(connectionId, 1, repoRecord.getOriginal().getSize());
            unacknowledgedFlowFiles.get(inputQueue).remove(flowFile);
            newOwner.unacknowledgedFlowFiles.computeIfAbsent(inputQueue, queue -> new HashSet<>()).add(flowFileRecord);
            flowFilesIn--;
            contentSizeIn -= flowFile.getSize();
            newOwner.flowFilesIn++;
            newOwner.contentSizeIn += flowFile.getSize();
        }
        final String flowFileId = flowFile.getAttribute(CoreAttributes.UUID.key());
        if (removedFlowFiles.remove(flowFileId)) {
            newOwner.removedFlowFiles.add(flowFileId);
            newOwner.removedCount++;
            newOwner.removedBytes += flowFile.getSize();
            removedCount--;
            removedBytes -= flowFile.getSize();
        }
        if (createdFlowFiles.remove(flowFileId)) {
            newOwner.createdFlowFiles.add(flowFileId);
        }
        if (repoRecord.getTransferRelationship() != null) {
            flowFilesOut--;
            contentSizeOut -= flowFile.getSize();
            newOwner.flowFilesOut++;
            newOwner.contentSizeOut += flowFile.getSize();
        }
        final List<ProvenanceEventRecord> events = generatedProvenanceEvents.remove(flowFile);
        if (events != null) {
            newOwner.generatedProvenanceEvents.put(flowFile, events);
        }
        final ContentClaim currentClaim = repoRecord.getCurrentClaim();
        if (currentClaim != null) {
            final ByteCountingOutputStream appendableStream = appendableStreams.remove(currentClaim);
            if (appendableStream != null) {
                newOwner.appendableStreams.put(currentClaim, appendableStream);
            }
        }
        final Path toDelete = deleteOnCommit.remove(flowFile);
        if (toDelete != null) {
            newOwner.deleteOnCommit.put(flowFile, toDelete);
        }
    }
    provenanceReporter.migrate(newOwner.provenanceReporter, flowFileIds);
}
Also used : OutputStreamCallback(org.apache.nifi.processor.io.OutputStreamCallback) FlowFileFilter(org.apache.nifi.processor.FlowFileFilter) TerminatedTaskException(org.apache.nifi.processor.exception.TerminatedTaskException) LoggerFactory(org.slf4j.LoggerFactory) QueueSize(org.apache.nifi.controller.queue.QueueSize) ByteCountingOutputStream(org.apache.nifi.stream.io.ByteCountingOutputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) DisableOnCloseOutputStream(org.apache.nifi.controller.repository.io.DisableOnCloseOutputStream) TaskTerminationInputStream(org.apache.nifi.controller.repository.io.TaskTerminationInputStream) Map(java.util.Map) Connectable(org.apache.nifi.connectable.Connectable) Connection(org.apache.nifi.connectable.Connection) Path(java.nio.file.Path) InputStreamCallback(org.apache.nifi.processor.io.InputStreamCallback) ByteCountingInputStream(org.apache.nifi.stream.io.ByteCountingInputStream) FlowFileAccessException(org.apache.nifi.processor.exception.FlowFileAccessException) FlowFile(org.apache.nifi.flowfile.FlowFile) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) UUID(java.util.UUID) EOFException(java.io.EOFException) Collectors(java.util.stream.Collectors) MissingFlowFileException(org.apache.nifi.processor.exception.MissingFlowFileException) StandardProvenanceEventRecord(org.apache.nifi.provenance.StandardProvenanceEventRecord) Objects(java.util.Objects) TaskTermination(org.apache.nifi.controller.lifecycle.TaskTermination) List(java.util.List) ProvenanceEventBuilder(org.apache.nifi.provenance.ProvenanceEventBuilder) Pattern(java.util.regex.Pattern) StandardFlowFileEvent(org.apache.nifi.controller.repository.metrics.StandardFlowFileEvent) StreamCallback(org.apache.nifi.processor.io.StreamCallback) ContentClaim(org.apache.nifi.controller.repository.claim.ContentClaim) ProcessorNode(org.apache.nifi.controller.ProcessorNode) FlowFileAccessInputStream(org.apache.nifi.controller.repository.io.FlowFileAccessInputStream) HashMap(java.util.HashMap) ProvenanceEventRepository(org.apache.nifi.provenance.ProvenanceEventRepository) FlowFileHandlingException(org.apache.nifi.processor.exception.FlowFileHandlingException) ProcessException(org.apache.nifi.processor.exception.ProcessException) BufferedOutputStream(java.io.BufferedOutputStream) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ProvenanceReporter(org.apache.nifi.provenance.ProvenanceReporter) Relationship(org.apache.nifi.processor.Relationship) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) ProvenanceEventRecord(org.apache.nifi.provenance.ProvenanceEventRecord) ContentClaimWriteCache(org.apache.nifi.controller.repository.claim.ContentClaimWriteCache) FlowFileAccessOutputStream(org.apache.nifi.controller.repository.io.FlowFileAccessOutputStream) NoSuchElementException(java.util.NoSuchElementException) LimitedInputStream(org.apache.nifi.controller.repository.io.LimitedInputStream) LinkedHashSet(java.util.LinkedHashSet) OutputStream(java.io.OutputStream) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Files(java.nio.file.Files) ProvenanceEventType(org.apache.nifi.provenance.ProvenanceEventType) IOException(java.io.IOException) ProcessSession(org.apache.nifi.processor.ProcessSession) TaskTerminationOutputStream(org.apache.nifi.controller.repository.io.TaskTerminationOutputStream) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) StreamUtils(org.apache.nifi.stream.io.StreamUtils) Closeable(java.io.Closeable) CoreAttributes(org.apache.nifi.flowfile.attributes.CoreAttributes) Collections(java.util.Collections) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) DisableOnCloseInputStream(org.apache.nifi.controller.repository.io.DisableOnCloseInputStream) InputStream(java.io.InputStream) Path(java.nio.file.Path) FlowFile(org.apache.nifi.flowfile.FlowFile) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) ByteCountingOutputStream(org.apache.nifi.stream.io.ByteCountingOutputStream) ContentClaim(org.apache.nifi.controller.repository.claim.ContentClaim) StandardProvenanceEventRecord(org.apache.nifi.provenance.StandardProvenanceEventRecord) ProvenanceEventRecord(org.apache.nifi.provenance.ProvenanceEventRecord) FlowFileHandlingException(org.apache.nifi.processor.exception.FlowFileHandlingException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ProvenanceEventBuilder(org.apache.nifi.provenance.ProvenanceEventBuilder) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 44 with Connection

use of org.apache.nifi.connectable.Connection in project nifi by apache.

the class ExpireFlowFiles method expireFlowFiles.

private void expireFlowFiles(final Connectable connectable) {
    // determine if the incoming connections for this Connectable have Expiration configured.
    boolean expirationConfigured = false;
    for (final Connection incomingConn : connectable.getIncomingConnections()) {
        if (FormatUtils.getTimeDuration(incomingConn.getFlowFileQueue().getFlowFileExpiration(), TimeUnit.MILLISECONDS) > 0) {
            expirationConfigured = true;
            break;
        }
    }
    // If expiration is not configured... don't bother running through the FlowFileQueue
    if (!expirationConfigured) {
        return;
    }
    final StandardProcessSession session = createSession(connectable);
    session.expireFlowFiles();
    session.commit();
}
Also used : Connection(org.apache.nifi.connectable.Connection) StandardProcessSession(org.apache.nifi.controller.repository.StandardProcessSession)

Example 45 with Connection

use of org.apache.nifi.connectable.Connection in project nifi by apache.

the class FlowController method initializeFlow.

public void initializeFlow() throws IOException {
    writeLock.lock();
    try {
        // get all connections/queues and recover from swap files.
        final List<Connection> connections = getGroup(getRootGroupId()).findAllConnections();
        long maxIdFromSwapFiles = -1L;
        if (flowFileRepository.isVolatile()) {
            for (final Connection connection : connections) {
                final FlowFileQueue queue = connection.getFlowFileQueue();
                queue.purgeSwapFiles();
            }
        } else {
            for (final Connection connection : connections) {
                final FlowFileQueue queue = connection.getFlowFileQueue();
                final SwapSummary swapSummary = queue.recoverSwappedFlowFiles();
                if (swapSummary != null) {
                    final Long maxFlowFileId = swapSummary.getMaxFlowFileId();
                    if (maxFlowFileId != null && maxFlowFileId > maxIdFromSwapFiles) {
                        maxIdFromSwapFiles = maxFlowFileId;
                    }
                    for (final ResourceClaim resourceClaim : swapSummary.getResourceClaims()) {
                        resourceClaimManager.incrementClaimantCount(resourceClaim);
                    }
                }
            }
        }
        flowFileRepository.loadFlowFiles(this, maxIdFromSwapFiles + 1);
        // Begin expiring FlowFiles that are old
        final RepositoryContextFactory contextFactory = new RepositoryContextFactory(contentRepository, flowFileRepository, flowFileEventRepository, counterRepositoryRef.get(), provenanceRepository);
        processScheduler.scheduleFrameworkTask(new ExpireFlowFiles(this, contextFactory), "Expire FlowFiles", 30L, 30L, TimeUnit.SECONDS);
        // now that we've loaded the FlowFiles, this has restored our ContentClaims' states, so we can tell the
        // ContentRepository to purge superfluous files
        contentRepository.cleanup();
        for (final RemoteSiteListener listener : externalSiteListeners) {
            listener.start();
        }
        notifyComponentsConfigurationRestored();
        timerDrivenEngineRef.get().scheduleWithFixedDelay(new Runnable() {

            @Override
            public void run() {
                try {
                    updateRemoteProcessGroups();
                } catch (final Throwable t) {
                    LOG.warn("Unable to update Remote Process Groups due to " + t);
                    if (LOG.isDebugEnabled()) {
                        LOG.warn("", t);
                    }
                }
            }
        }, 0L, 30L, TimeUnit.SECONDS);
        timerDrivenEngineRef.get().scheduleWithFixedDelay(new Runnable() {

            @Override
            public void run() {
                final ProcessGroup rootGroup = getRootGroup();
                final List<ProcessGroup> allGroups = rootGroup.findAllProcessGroups();
                allGroups.add(rootGroup);
                for (final ProcessGroup group : allGroups) {
                    try {
                        group.synchronizeWithFlowRegistry(flowRegistryClient);
                    } catch (final Exception e) {
                        LOG.error("Failed to synchronize {} with Flow Registry", group, e);
                    }
                }
            }
        }, 5, 60, TimeUnit.SECONDS);
        initialized.set(true);
    } finally {
        writeLock.unlock();
    }
}
Also used : Connection(org.apache.nifi.connectable.Connection) VersionedConnection(org.apache.nifi.registry.flow.VersionedConnection) StandardConnection(org.apache.nifi.connectable.StandardConnection) SwapSummary(org.apache.nifi.controller.repository.SwapSummary) ExpireFlowFiles(org.apache.nifi.controller.tasks.ExpireFlowFiles) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) ConfigException(org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException) IOException(java.io.IOException) ProcessorInstantiationException(org.apache.nifi.controller.exception.ProcessorInstantiationException) ComponentLifeCycleException(org.apache.nifi.controller.exception.ComponentLifeCycleException) UnknownServiceAddressException(org.apache.nifi.cluster.protocol.UnknownServiceAddressException) FlowSerializationException(org.apache.nifi.controller.serialization.FlowSerializationException) ResourceNotFoundException(org.apache.nifi.web.ResourceNotFoundException) InitializationException(org.apache.nifi.reporting.InitializationException) ReportingTaskInstantiationException(org.apache.nifi.controller.reporting.ReportingTaskInstantiationException) CommunicationsException(org.apache.nifi.controller.exception.CommunicationsException) FlowSynchronizationException(org.apache.nifi.controller.serialization.FlowSynchronizationException) ControllerServiceInstantiationException(org.apache.nifi.controller.exception.ControllerServiceInstantiationException) SocketRemoteSiteListener(org.apache.nifi.remote.SocketRemoteSiteListener) RemoteSiteListener(org.apache.nifi.remote.RemoteSiteListener) HttpRemoteSiteListener(org.apache.nifi.remote.HttpRemoteSiteListener) RepositoryContextFactory(org.apache.nifi.controller.scheduling.RepositoryContextFactory) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) StandardProcessGroup(org.apache.nifi.groups.StandardProcessGroup) RemoteProcessGroup(org.apache.nifi.groups.RemoteProcessGroup) ProcessGroup(org.apache.nifi.groups.ProcessGroup) StandardRemoteProcessGroup(org.apache.nifi.remote.StandardRemoteProcessGroup) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

Connection (org.apache.nifi.connectable.Connection)95 ArrayList (java.util.ArrayList)35 HashSet (java.util.HashSet)35 VersionedConnection (org.apache.nifi.registry.flow.VersionedConnection)30 FlowFileQueue (org.apache.nifi.controller.queue.FlowFileQueue)28 Connectable (org.apache.nifi.connectable.Connectable)27 ProcessGroup (org.apache.nifi.groups.ProcessGroup)26 Relationship (org.apache.nifi.processor.Relationship)23 Port (org.apache.nifi.connectable.Port)21 RemoteProcessGroup (org.apache.nifi.groups.RemoteProcessGroup)21 ProcessorNode (org.apache.nifi.controller.ProcessorNode)19 RootGroupPort (org.apache.nifi.remote.RootGroupPort)19 LinkedHashSet (java.util.LinkedHashSet)18 Set (java.util.Set)17 RemoteGroupPort (org.apache.nifi.remote.RemoteGroupPort)17 Funnel (org.apache.nifi.connectable.Funnel)16 HashMap (java.util.HashMap)15 VersionedProcessGroup (org.apache.nifi.registry.flow.VersionedProcessGroup)15 IOException (java.io.IOException)14 Map (java.util.Map)14