Search in sources :

Example 1 with SwapSummary

use of org.apache.nifi.controller.repository.SwapSummary in project nifi by apache.

the class TestSchemaSwapSerializerDeserializer method testRoundTripSerializeDeserializeFullSwapFile.

@Test
public void testRoundTripSerializeDeserializeFullSwapFile() throws IOException, InterruptedException {
    final ResourceClaimManager resourceClaimManager = new StandardResourceClaimManager();
    final List<FlowFileRecord> toSwap = new ArrayList<>(10000);
    final Map<String, String> attrs = new HashMap<>();
    long size = 0L;
    for (int i = 0; i < 10000; i++) {
        attrs.put("i", String.valueOf(i));
        final FlowFileRecord ff = new MockFlowFile(attrs, i, resourceClaimManager);
        toSwap.add(ff);
        size += i;
    }
    final FlowFileQueue flowFileQueue = Mockito.mock(FlowFileQueue.class);
    Mockito.when(flowFileQueue.getIdentifier()).thenReturn("87bb99fe-412c-49f6-a441-d1b0af4e20b4");
    final String swapLocation = "target/testRoundTrip.swap";
    final File swapFile = new File(swapLocation);
    Files.deleteIfExists(swapFile.toPath());
    final SwapSerializer serializer = new SchemaSwapSerializer();
    try (final OutputStream fos = new FileOutputStream(swapFile);
        final OutputStream out = new BufferedOutputStream(fos)) {
        serializer.serializeFlowFiles(toSwap, flowFileQueue, swapLocation, out);
    }
    final SwapContents contents;
    final SwapDeserializer deserializer = new SchemaSwapDeserializer();
    try (final FileInputStream fis = new FileInputStream(swapFile);
        final InputStream bufferedIn = new BufferedInputStream(fis);
        final DataInputStream dis = new DataInputStream(bufferedIn)) {
        contents = deserializer.deserializeFlowFiles(dis, swapLocation, flowFileQueue, resourceClaimManager);
    }
    final SwapSummary swapSummary = contents.getSummary();
    assertEquals(10000, swapSummary.getQueueSize().getObjectCount());
    assertEquals(size, swapSummary.getQueueSize().getByteCount());
    assertEquals(9999, swapSummary.getMaxFlowFileId().intValue());
    assertEquals(10000, contents.getFlowFiles().size());
    int counter = 0;
    for (final FlowFileRecord flowFile : contents.getFlowFiles()) {
        final int i = counter++;
        assertEquals(String.valueOf(i), flowFile.getAttribute("i"));
        assertEquals(i, flowFile.getSize());
    }
}
Also used : HashMap(java.util.HashMap) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) NullOutputStream(org.apache.nifi.stream.io.NullOutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) StandardResourceClaimManager(org.apache.nifi.controller.repository.claim.StandardResourceClaimManager) ResourceClaimManager(org.apache.nifi.controller.repository.claim.ResourceClaimManager) SwapSummary(org.apache.nifi.controller.repository.SwapSummary) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) BufferedInputStream(java.io.BufferedInputStream) StandardResourceClaimManager(org.apache.nifi.controller.repository.claim.StandardResourceClaimManager) SwapContents(org.apache.nifi.controller.repository.SwapContents) BufferedOutputStream(java.io.BufferedOutputStream) DataInputStream(java.io.DataInputStream) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) DataInputStream(java.io.DataInputStream) FileInputStream(java.io.FileInputStream) FileOutputStream(java.io.FileOutputStream) FlowFileRecord(org.apache.nifi.controller.repository.FlowFileRecord) File(java.io.File) Test(org.junit.Test)

Example 2 with SwapSummary

use of org.apache.nifi.controller.repository.SwapSummary in project nifi by apache.

the class StandardFlowFileQueue method recoverSwappedFlowFiles.

@Override
public SwapSummary recoverSwappedFlowFiles() {
    int swapFlowFileCount = 0;
    long swapByteCount = 0L;
    Long maxId = null;
    List<ResourceClaim> resourceClaims = new ArrayList<>();
    final long startNanos = System.nanoTime();
    writeLock.lock();
    try {
        final List<String> swapLocations;
        try {
            swapLocations = swapManager.recoverSwapLocations(this);
        } catch (final IOException ioe) {
            logger.error("Failed to determine whether or not any Swap Files exist for FlowFile Queue {}", getIdentifier());
            logger.error("", ioe);
            if (eventReporter != null) {
                eventReporter.reportEvent(Severity.ERROR, "FlowFile Swapping", "Failed to determine whether or not any Swap Files exist for FlowFile Queue " + getIdentifier() + "; see logs for more detials");
            }
            return null;
        }
        for (final String swapLocation : swapLocations) {
            try {
                final SwapSummary summary = swapManager.getSwapSummary(swapLocation);
                final QueueSize queueSize = summary.getQueueSize();
                final Long maxSwapRecordId = summary.getMaxFlowFileId();
                if (maxSwapRecordId != null) {
                    if (maxId == null || maxSwapRecordId > maxId) {
                        maxId = maxSwapRecordId;
                    }
                }
                swapFlowFileCount += queueSize.getObjectCount();
                swapByteCount += queueSize.getByteCount();
                resourceClaims.addAll(summary.getResourceClaims());
            } catch (final IOException ioe) {
                logger.error("Failed to recover FlowFiles from Swap File {}; the file appears to be corrupt", swapLocation, ioe.toString());
                logger.error("", ioe);
                if (eventReporter != null) {
                    eventReporter.reportEvent(Severity.ERROR, "FlowFile Swapping", "Failed to recover FlowFiles from Swap File " + swapLocation + "; the file appears to be corrupt. See logs for more details");
                }
            }
        }
        incrementSwapQueueSize(swapFlowFileCount, swapByteCount, swapLocations.size());
        this.swapLocations.addAll(swapLocations);
    } finally {
        writeLock.unlock("Recover Swap Files");
    }
    if (!swapLocations.isEmpty()) {
        final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
        logger.info("Recovered {} swap files for {} in {} millis", swapLocations.size(), this, millis);
    }
    return new StandardSwapSummary(new QueueSize(swapFlowFileCount, swapByteCount), maxId, resourceClaims);
}
Also used : QueueSize(org.apache.nifi.controller.queue.QueueSize) ArrayList(java.util.ArrayList) StandardSwapSummary(org.apache.nifi.controller.swap.StandardSwapSummary) SwapSummary(org.apache.nifi.controller.repository.SwapSummary) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) IOException(java.io.IOException) StandardSwapSummary(org.apache.nifi.controller.swap.StandardSwapSummary)

Example 3 with SwapSummary

use of org.apache.nifi.controller.repository.SwapSummary in project nifi by apache.

the class SchemaSwapDeserializer method getSwapSummary.

@Override
public SwapSummary getSwapSummary(final DataInputStream in, final String swapLocation, final ResourceClaimManager claimManager) throws IOException {
    final RecordSchema schema = RecordSchema.readFrom(in);
    final List<RecordField> summaryFields = schema.getField(SwapSchema.SWAP_SUMMARY).getSubFields();
    final RecordField summaryRecordField = new ComplexRecordField(SwapSchema.SWAP_SUMMARY, Repetition.EXACTLY_ONE, summaryFields);
    final RecordSchema summarySchema = new RecordSchema(Collections.singletonList(summaryRecordField));
    final Record summaryRecordParent = SchemaRecordReader.fromSchema(summarySchema).readRecord(in);
    final Record summaryRecord = (Record) summaryRecordParent.getFieldValue(SwapSchema.SWAP_SUMMARY);
    final SwapSummary swapSummary = SwapSummaryFieldMap.getSwapSummary(summaryRecord, claimManager);
    return swapSummary;
}
Also used : RecordField(org.apache.nifi.repository.schema.RecordField) ComplexRecordField(org.apache.nifi.repository.schema.ComplexRecordField) SwapSummary(org.apache.nifi.controller.repository.SwapSummary) Record(org.apache.nifi.repository.schema.Record) FlowFileRecord(org.apache.nifi.controller.repository.FlowFileRecord) ComplexRecordField(org.apache.nifi.repository.schema.ComplexRecordField) RecordSchema(org.apache.nifi.repository.schema.RecordSchema)

Example 4 with SwapSummary

use of org.apache.nifi.controller.repository.SwapSummary in project nifi by apache.

the class SchemaSwapSerializer method serializeFlowFiles.

@Override
public void serializeFlowFiles(final List<FlowFileRecord> toSwap, final FlowFileQueue queue, final String swapLocation, final OutputStream out) throws IOException {
    schema.writeTo(out);
    long contentSize = 0L;
    long maxFlowFileId = -1L;
    final List<ResourceClaim> resourceClaims = new ArrayList<>();
    for (final FlowFileRecord flowFile : toSwap) {
        contentSize += flowFile.getSize();
        if (flowFile.getId() > maxFlowFileId) {
            maxFlowFileId = flowFile.getId();
        }
        final ContentClaim contentClaim = flowFile.getContentClaim();
        if (contentClaim != null) {
            resourceClaims.add(contentClaim.getResourceClaim());
        }
    }
    final QueueSize queueSize = new QueueSize(toSwap.size(), contentSize);
    final SwapSummary swapSummary = new StandardSwapSummary(queueSize, maxFlowFileId, resourceClaims);
    final Record summaryRecord = new SwapSummaryFieldMap(swapSummary, queue.getIdentifier(), SwapSchema.SWAP_SUMMARY_SCHEMA_V1);
    final List<Record> flowFileRecords = toSwap.stream().map(flowFile -> new FlowFileRecordFieldMap(flowFile, flowFileSchema)).collect(Collectors.toList());
    // Create a simple record to hold the summary and the flowfile contents
    final RecordField summaryField = new SimpleRecordField(SwapSchema.SWAP_SUMMARY, FieldType.COMPLEX, Repetition.EXACTLY_ONE);
    final RecordField contentsField = new ComplexRecordField(SwapSchema.FLOWFILE_CONTENTS, Repetition.ZERO_OR_MORE, FlowFileSchema.FLOWFILE_SCHEMA_V2.getFields());
    final List<RecordField> fields = new ArrayList<>(2);
    fields.add(summaryField);
    fields.add(contentsField);
    final Map<RecordField, Object> swapFileMap = new LinkedHashMap<>();
    swapFileMap.put(summaryField, summaryRecord);
    swapFileMap.put(contentsField, flowFileRecords);
    final Record swapFileRecord = new FieldMapRecord(swapFileMap, new RecordSchema(fields));
    final SchemaRecordWriter writer = new SchemaRecordWriter();
    writer.writeRecord(swapFileRecord, out);
    out.flush();
}
Also used : OutputStream(java.io.OutputStream) ContentClaim(org.apache.nifi.controller.repository.claim.ContentClaim) FlowFileSchema(org.apache.nifi.controller.repository.schema.FlowFileSchema) Record(org.apache.nifi.repository.schema.Record) RecordField(org.apache.nifi.repository.schema.RecordField) ComplexRecordField(org.apache.nifi.repository.schema.ComplexRecordField) FlowFileRecord(org.apache.nifi.controller.repository.FlowFileRecord) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) QueueSize(org.apache.nifi.controller.queue.QueueSize) ArrayList(java.util.ArrayList) FieldMapRecord(org.apache.nifi.repository.schema.FieldMapRecord) RecordSchema(org.apache.nifi.repository.schema.RecordSchema) LinkedHashMap(java.util.LinkedHashMap) SwapSummary(org.apache.nifi.controller.repository.SwapSummary) FieldType(org.apache.nifi.repository.schema.FieldType) List(java.util.List) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) Map(java.util.Map) FlowFileRecordFieldMap(org.apache.nifi.controller.repository.schema.FlowFileRecordFieldMap) SimpleRecordField(org.apache.nifi.repository.schema.SimpleRecordField) Repetition(org.apache.nifi.repository.schema.Repetition) SchemaRecordWriter(org.apache.nifi.repository.schema.SchemaRecordWriter) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) FieldMapRecord(org.apache.nifi.repository.schema.FieldMapRecord) RecordField(org.apache.nifi.repository.schema.RecordField) ComplexRecordField(org.apache.nifi.repository.schema.ComplexRecordField) SimpleRecordField(org.apache.nifi.repository.schema.SimpleRecordField) ArrayList(java.util.ArrayList) SwapSummary(org.apache.nifi.controller.repository.SwapSummary) LinkedHashMap(java.util.LinkedHashMap) QueueSize(org.apache.nifi.controller.queue.QueueSize) ContentClaim(org.apache.nifi.controller.repository.claim.ContentClaim) SimpleRecordField(org.apache.nifi.repository.schema.SimpleRecordField) FlowFileRecordFieldMap(org.apache.nifi.controller.repository.schema.FlowFileRecordFieldMap) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) Record(org.apache.nifi.repository.schema.Record) FlowFileRecord(org.apache.nifi.controller.repository.FlowFileRecord) FieldMapRecord(org.apache.nifi.repository.schema.FieldMapRecord) ComplexRecordField(org.apache.nifi.repository.schema.ComplexRecordField) FlowFileRecord(org.apache.nifi.controller.repository.FlowFileRecord) RecordSchema(org.apache.nifi.repository.schema.RecordSchema) SchemaRecordWriter(org.apache.nifi.repository.schema.SchemaRecordWriter)

Example 5 with SwapSummary

use of org.apache.nifi.controller.repository.SwapSummary 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

SwapSummary (org.apache.nifi.controller.repository.SwapSummary)9 ArrayList (java.util.ArrayList)7 IOException (java.io.IOException)6 FlowFileRecord (org.apache.nifi.controller.repository.FlowFileRecord)6 ResourceClaim (org.apache.nifi.controller.repository.claim.ResourceClaim)5 List (java.util.List)4 FlowFileQueue (org.apache.nifi.controller.queue.FlowFileQueue)4 SwapContents (org.apache.nifi.controller.repository.SwapContents)4 OutputStream (java.io.OutputStream)3 QueueSize (org.apache.nifi.controller.queue.QueueSize)3 Record (org.apache.nifi.repository.schema.Record)3 RecordSchema (org.apache.nifi.repository.schema.RecordSchema)3 BufferedInputStream (java.io.BufferedInputStream)2 BufferedOutputStream (java.io.BufferedOutputStream)2 DataInputStream (java.io.DataInputStream)2 EOFException (java.io.EOFException)2 File (java.io.File)2 FileInputStream (java.io.FileInputStream)2 FileOutputStream (java.io.FileOutputStream)2 InputStream (java.io.InputStream)2