Search in sources :

Example 6 with StandardContentClaim

use of org.apache.nifi.controller.repository.claim.StandardContentClaim in project nifi by apache.

the class TestStandardProcessSession method testContentNotFoundExceptionThrownWhenUnableToReadDataOffsetTooLarge.

@Test
public void testContentNotFoundExceptionThrownWhenUnableToReadDataOffsetTooLarge() {
    final FlowFileRecord flowFileRecord = new StandardFlowFileRecord.Builder().addAttribute("uuid", "12345678-1234-1234-1234-123456789012").entryDate(System.currentTimeMillis()).contentClaim(new StandardContentClaim(resourceClaimManager.newResourceClaim("x", "x", "0", true, false), 0L)).build();
    flowFileQueue.put(flowFileRecord);
    FlowFile ff1 = session.get();
    ff1 = session.write(ff1, new OutputStreamCallback() {

        @Override
        public void process(OutputStream out) throws IOException {
        }
    });
    session.transfer(ff1);
    session.commit();
    final FlowFileRecord flowFileRecord2 = new StandardFlowFileRecord.Builder().addAttribute("uuid", "12345678-1234-1234-1234-123456789012").entryDate(System.currentTimeMillis()).contentClaim(new StandardContentClaim(resourceClaimManager.newResourceClaim("x", "x", "0", true, false), 0L)).contentClaimOffset(1000L).size(1L).build();
    flowFileQueue.put(flowFileRecord2);
    // attempt to read the data.
    try {
        session.get();
        final FlowFile ff2 = session.get();
        session.read(ff2, new InputStreamCallback() {

            @Override
            public void process(InputStream in) throws IOException {
            }
        });
        Assert.fail("Expected MissingFlowFileException");
    } catch (final MissingFlowFileException mffe) {
    }
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) MockFlowFile(org.apache.nifi.util.MockFlowFile) StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) FilterOutputStream(java.io.FilterOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) InputStreamCallback(org.apache.nifi.processor.io.InputStreamCallback) OutputStreamCallback(org.apache.nifi.processor.io.OutputStreamCallback) IOException(java.io.IOException) MissingFlowFileException(org.apache.nifi.processor.exception.MissingFlowFileException) Test(org.junit.Test)

Example 7 with StandardContentClaim

use of org.apache.nifi.controller.repository.claim.StandardContentClaim in project nifi by apache.

the class FlowController method getReplayFailureReason.

private String getReplayFailureReason(final ProvenanceEventRecord event) {
    // Check that the event is a valid type.
    final ProvenanceEventType type = event.getEventType();
    if (type == ProvenanceEventType.JOIN) {
        return "Cannot replay events that are created from multiple parents";
    }
    // Make sure event has the Content Claim info
    final Long contentSize = event.getPreviousFileSize();
    final String contentClaimId = event.getPreviousContentClaimIdentifier();
    final String contentClaimSection = event.getPreviousContentClaimSection();
    final String contentClaimContainer = event.getPreviousContentClaimContainer();
    if (contentSize == null || contentClaimId == null || contentClaimSection == null || contentClaimContainer == null) {
        return "Cannot replay data from Provenance Event because the event does not contain the required Content Claim";
    }
    try {
        final ResourceClaim resourceClaim = resourceClaimManager.newResourceClaim(contentClaimContainer, contentClaimSection, contentClaimId, false, false);
        final ContentClaim contentClaim = new StandardContentClaim(resourceClaim, event.getPreviousContentClaimOffset());
        if (!contentRepository.isAccessible(contentClaim)) {
            return "Content is no longer available in Content Repository";
        }
    } catch (final IOException ioe) {
        return "Failed to determine whether or not content was available in Content Repository due to " + ioe.toString();
    }
    // Make sure that the source queue exists
    if (event.getSourceQueueIdentifier() == null) {
        return "Cannot replay data from Provenance Event because the event does not specify the Source FlowFile Queue";
    }
    final List<Connection> connections = getGroup(getRootGroupId()).findAllConnections();
    FlowFileQueue queue = null;
    for (final Connection connection : connections) {
        if (event.getSourceQueueIdentifier().equals(connection.getIdentifier())) {
            queue = connection.getFlowFileQueue();
            break;
        }
    }
    if (queue == null) {
        return "Cannot replay data from Provenance Event because the Source FlowFile Queue with ID " + event.getSourceQueueIdentifier() + " no longer exists";
    }
    return null;
}
Also used : StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) ContentClaim(org.apache.nifi.controller.repository.claim.ContentClaim) StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) Connection(org.apache.nifi.connectable.Connection) VersionedConnection(org.apache.nifi.registry.flow.VersionedConnection) StandardConnection(org.apache.nifi.connectable.StandardConnection) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) IOException(java.io.IOException) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) ProvenanceEventType(org.apache.nifi.provenance.ProvenanceEventType)

Example 8 with StandardContentClaim

use of org.apache.nifi.controller.repository.claim.StandardContentClaim in project nifi by apache.

the class FlowController method replayFlowFile.

public ProvenanceEventRecord replayFlowFile(final ProvenanceEventRecord event, final NiFiUser user) throws IOException {
    if (event == null) {
        throw new NullPointerException();
    }
    // Check that the event is a valid type.
    final ProvenanceEventType type = event.getEventType();
    if (type == ProvenanceEventType.JOIN) {
        throw new IllegalArgumentException("Cannot replay events that are created from multiple parents");
    }
    // Make sure event has the Content Claim info
    final Long contentSize = event.getPreviousFileSize();
    final String contentClaimId = event.getPreviousContentClaimIdentifier();
    final String contentClaimSection = event.getPreviousContentClaimSection();
    final String contentClaimContainer = event.getPreviousContentClaimContainer();
    if (contentSize == null || contentClaimId == null || contentClaimSection == null || contentClaimContainer == null) {
        throw new IllegalArgumentException("Cannot replay data from Provenance Event because the event does not contain the required Content Claim");
    }
    // Make sure that the source queue exists
    if (event.getSourceQueueIdentifier() == null) {
        throw new IllegalArgumentException("Cannot replay data from Provenance Event because the event does not specify the Source FlowFile Queue");
    }
    final List<Connection> connections = getGroup(getRootGroupId()).findAllConnections();
    FlowFileQueue queue = null;
    for (final Connection connection : connections) {
        if (event.getSourceQueueIdentifier().equals(connection.getIdentifier())) {
            queue = connection.getFlowFileQueue();
            break;
        }
    }
    if (queue == null) {
        throw new IllegalStateException("Cannot replay data from Provenance Event because the Source FlowFile Queue with ID " + event.getSourceQueueIdentifier() + " no longer exists");
    }
    // Create the ContentClaim. To do so, we first need the appropriate Resource Claim. Because we don't know whether or
    // not the Resource Claim is still active, we first call ResourceClaimManager.getResourceClaim. If this returns
    // null, then we know that the Resource Claim is no longer active and can just create a new one that is not writable.
    // It's critical though that we first call getResourceClaim because otherwise, if the Resource Claim is active and we
    // create a new one that is not writable, we could end up archiving or destroying the Resource Claim while it's still
    // being written to by the Content Repository. This is important only because we are creating a FlowFile with this Resource
    // Claim. If, for instance, we are simply creating the claim to request its content, as in #getContentAvailability, etc.
    // then this is not necessary.
    ResourceClaim resourceClaim = resourceClaimManager.getResourceClaim(event.getPreviousContentClaimContainer(), event.getPreviousContentClaimSection(), event.getPreviousContentClaimIdentifier());
    if (resourceClaim == null) {
        resourceClaim = resourceClaimManager.newResourceClaim(event.getPreviousContentClaimContainer(), event.getPreviousContentClaimSection(), event.getPreviousContentClaimIdentifier(), false, false);
    }
    // Increment Claimant Count, since we will now be referencing the Content Claim
    resourceClaimManager.incrementClaimantCount(resourceClaim);
    final long claimOffset = event.getPreviousContentClaimOffset() == null ? 0L : event.getPreviousContentClaimOffset().longValue();
    final StandardContentClaim contentClaim = new StandardContentClaim(resourceClaim, claimOffset);
    contentClaim.setLength(event.getPreviousFileSize() == null ? -1L : event.getPreviousFileSize());
    if (!contentRepository.isAccessible(contentClaim)) {
        resourceClaimManager.decrementClaimantCount(resourceClaim);
        throw new IllegalStateException("Cannot replay data from Provenance Event because the data is no longer available in the Content Repository");
    }
    final String parentUUID = event.getFlowFileUuid();
    final String newFlowFileUUID = UUID.randomUUID().toString();
    // We need to create a new FlowFile by populating it with information from the
    // Provenance Event. Particularly of note here is that we are setting the FlowFile's
    // contentClaimOffset to 0. This is done for backward compatibility reasons. ContentClaim
    // used to not have a concept of an offset, and the offset was tied only to the FlowFile. This
    // was later refactored, so that the offset was part of the ContentClaim. If we set the offset
    // in both places, we'll end up skipping over that many bytes twice instead of once (once to get
    // to the beginning of the Content Claim and again to get to the offset within that Content Claim).
    // To avoid this, we just always set the offset in the Content Claim itself and set the
    // FlowFileRecord's contentClaimOffset to 0.
    final FlowFileRecord flowFileRecord = new StandardFlowFileRecord.Builder().addAttributes(event.getPreviousAttributes()).contentClaim(contentClaim).contentClaimOffset(// use 0 because we used the content claim offset in the Content Claim itself
    0L).entryDate(System.currentTimeMillis()).id(flowFileRepository.getNextFlowFileSequence()).lineageStart(event.getLineageStartDate(), 0L).size(contentSize.longValue()).addAttribute("flowfile.replay", "true").addAttribute("flowfile.replay.timestamp", String.valueOf(new Date())).addAttribute(CoreAttributes.UUID.key(), newFlowFileUUID).removeAttributes(CoreAttributes.DISCARD_REASON.key(), CoreAttributes.ALTERNATE_IDENTIFIER.key()).build();
    // Register a Provenance Event to indicate that we replayed the data.
    final ProvenanceEventRecord replayEvent = new StandardProvenanceEventRecord.Builder().setEventType(ProvenanceEventType.REPLAY).addChildUuid(newFlowFileUUID).addParentUuid(parentUUID).setFlowFileUUID(parentUUID).setAttributes(Collections.emptyMap(), flowFileRecord.getAttributes()).setCurrentContentClaim(event.getContentClaimContainer(), event.getContentClaimSection(), event.getContentClaimIdentifier(), event.getContentClaimOffset(), event.getFileSize()).setDetails("Replay requested by " + user.getIdentity()).setEventTime(System.currentTimeMillis()).setFlowFileEntryDate(System.currentTimeMillis()).setLineageStartDate(event.getLineageStartDate()).setComponentType(event.getComponentType()).setComponentId(event.getComponentId()).build();
    provenanceRepository.registerEvent(replayEvent);
    // Update the FlowFile Repository to indicate that we have added the FlowFile to the flow
    final StandardRepositoryRecord record = new StandardRepositoryRecord(queue);
    record.setWorking(flowFileRecord);
    record.setDestination(queue);
    flowFileRepository.updateRepository(Collections.singleton(record));
    // Enqueue the data
    queue.put(flowFileRecord);
    return replayEvent;
}
Also used : Connection(org.apache.nifi.connectable.Connection) VersionedConnection(org.apache.nifi.registry.flow.VersionedConnection) StandardConnection(org.apache.nifi.connectable.StandardConnection) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) Date(java.util.Date) StandardProvenanceEventRecord(org.apache.nifi.provenance.StandardProvenanceEventRecord) StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) StandardRepositoryRecord(org.apache.nifi.controller.repository.StandardRepositoryRecord) StandardProvenanceEventRecord(org.apache.nifi.provenance.StandardProvenanceEventRecord) ProvenanceEventRecord(org.apache.nifi.provenance.ProvenanceEventRecord) ResourceClaim(org.apache.nifi.controller.repository.claim.ResourceClaim) FlowFileRecord(org.apache.nifi.controller.repository.FlowFileRecord) StandardFlowFileRecord(org.apache.nifi.controller.repository.StandardFlowFileRecord) ProvenanceEventType(org.apache.nifi.provenance.ProvenanceEventType)

Example 9 with StandardContentClaim

use of org.apache.nifi.controller.repository.claim.StandardContentClaim in project nifi by apache.

the class TestFileSystemRepository method testSizeWithNoContent.

@Test(expected = ContentNotFoundException.class)
public void testSizeWithNoContent() throws IOException {
    final ContentClaim claim = new StandardContentClaim(new StandardResourceClaim(claimManager, "container1", "section 1", "1", false), 0L);
    assertEquals(0L, repository.size(claim));
}
Also used : ContentClaim(org.apache.nifi.controller.repository.claim.ContentClaim) StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) StandardResourceClaim(org.apache.nifi.controller.repository.claim.StandardResourceClaim) Test(org.junit.Test)

Example 10 with StandardContentClaim

use of org.apache.nifi.controller.repository.claim.StandardContentClaim in project nifi by apache.

the class TestStandardProcessSession method testRollbackAfterCheckpoint.

@Test
public void testRollbackAfterCheckpoint() {
    final FlowFileRecord flowFileRecord = new StandardFlowFileRecord.Builder().addAttribute("uuid", "12345678-1234-1234-1234-123456789012").entryDate(System.currentTimeMillis()).contentClaim(new StandardContentClaim(resourceClaimManager.newResourceClaim("x", "x", "0", true, false), 0L)).contentClaimOffset(0L).size(0L).build();
    flowFileQueue.put(flowFileRecord);
    final FlowFile originalFlowFile = session.get();
    assertTrue(flowFileQueue.isActiveQueueEmpty());
    assertEquals(1, flowFileQueue.getUnacknowledgedQueueSize().getObjectCount());
    final FlowFile modified = session.write(originalFlowFile, new OutputStreamCallback() {

        @Override
        public void process(OutputStream out) throws IOException {
            out.write("Hello".getBytes());
        }
    });
    session.transfer(modified);
    session.checkpoint();
    assertTrue(flowFileQueue.isActiveQueueEmpty());
    session.rollback();
    assertTrue(flowFileQueue.isActiveQueueEmpty());
    assertEquals(0, flowFileQueue.size().getObjectCount());
    assertEquals(0, flowFileQueue.getUnacknowledgedQueueSize().getObjectCount());
    session.rollback();
    flowFileQueue.put(flowFileRecord);
    assertFalse(flowFileQueue.isActiveQueueEmpty());
    final FlowFile originalRound2 = session.get();
    assertTrue(flowFileQueue.isActiveQueueEmpty());
    assertEquals(1, flowFileQueue.getUnacknowledgedQueueSize().getObjectCount());
    final FlowFile modifiedRound2 = session.write(originalRound2, new OutputStreamCallback() {

        @Override
        public void process(OutputStream out) throws IOException {
            out.write("Hello".getBytes());
        }
    });
    session.transfer(modifiedRound2);
    session.checkpoint();
    assertTrue(flowFileQueue.isActiveQueueEmpty());
    assertEquals(1, flowFileQueue.getUnacknowledgedQueueSize().getObjectCount());
    session.commit();
    // FlowFile transferred back to queue
    assertEquals(1, flowFileQueue.size().getObjectCount());
    assertEquals(0, flowFileQueue.getUnacknowledgedQueueSize().getObjectCount());
    assertFalse(flowFileQueue.isActiveQueueEmpty());
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) MockFlowFile(org.apache.nifi.util.MockFlowFile) StandardContentClaim(org.apache.nifi.controller.repository.claim.StandardContentClaim) FilterOutputStream(java.io.FilterOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) OutputStreamCallback(org.apache.nifi.processor.io.OutputStreamCallback) IOException(java.io.IOException) Test(org.junit.Test)

Aggregations

StandardContentClaim (org.apache.nifi.controller.repository.claim.StandardContentClaim)20 IOException (java.io.IOException)11 ResourceClaim (org.apache.nifi.controller.repository.claim.ResourceClaim)11 Test (org.junit.Test)10 FileOutputStream (java.io.FileOutputStream)7 OutputStream (java.io.OutputStream)7 ContentClaim (org.apache.nifi.controller.repository.claim.ContentClaim)7 ByteArrayInputStream (java.io.ByteArrayInputStream)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6 InputStream (java.io.InputStream)6 FlowFile (org.apache.nifi.flowfile.FlowFile)6 MockFlowFile (org.apache.nifi.util.MockFlowFile)6 FilterOutputStream (java.io.FilterOutputStream)5 OutputStreamCallback (org.apache.nifi.processor.io.OutputStreamCallback)5 FileInputStream (java.io.FileInputStream)4 MissingFlowFileException (org.apache.nifi.processor.exception.MissingFlowFileException)4 InputStreamCallback (org.apache.nifi.processor.io.InputStreamCallback)4 Connection (org.apache.nifi.connectable.Connection)3 FlowFileQueue (org.apache.nifi.controller.queue.FlowFileQueue)3 EOFException (java.io.EOFException)2