use of org.apache.nifi.processor.exception.FlowFileAccessException in project nifi by apache.
the class PutFileTransfer method onTrigger.
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
FlowFile flowFile = session.get();
if (flowFile == null) {
return;
}
final ComponentLog logger = getLogger();
final String hostname = context.getProperty(FileTransfer.HOSTNAME).evaluateAttributeExpressions(flowFile).getValue();
final int maxNumberOfFiles = context.getProperty(FileTransfer.BATCH_SIZE).asInteger();
int fileCount = 0;
try (final T transfer = getFileTransfer(context)) {
do {
final String rootPath = context.getProperty(FileTransfer.REMOTE_PATH).evaluateAttributeExpressions(flowFile).getValue();
final String workingDirPath;
if (rootPath == null) {
workingDirPath = null;
} else {
File workingDirectory = new File(rootPath);
if (!workingDirectory.getPath().startsWith("/") && !workingDirectory.getPath().startsWith("\\")) {
workingDirectory = new File(transfer.getHomeDirectory(flowFile), workingDirectory.getPath());
}
workingDirPath = workingDirectory.getPath().replace("\\", "/");
}
final boolean rejectZeroByteFiles = context.getProperty(FileTransfer.REJECT_ZERO_BYTE).asBoolean();
final ConflictResult conflictResult = identifyAndResolveConflictFile(context.getProperty(FileTransfer.CONFLICT_RESOLUTION).getValue(), transfer, workingDirPath, flowFile, rejectZeroByteFiles, logger);
if (conflictResult.isTransfer()) {
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
beforePut(flowFile, context, transfer);
final FlowFile flowFileToTransfer = flowFile;
final AtomicReference<String> fullPathRef = new AtomicReference<>(null);
session.read(flowFile, new InputStreamCallback() {
@Override
public void process(final InputStream in) throws IOException {
try (final InputStream bufferedIn = new BufferedInputStream(in)) {
if (workingDirPath != null && context.getProperty(SFTPTransfer.CREATE_DIRECTORY).asBoolean()) {
transfer.ensureDirectoryExists(flowFileToTransfer, new File(workingDirPath));
}
fullPathRef.set(transfer.put(flowFileToTransfer, workingDirPath, conflictResult.getFileName(), bufferedIn));
}
}
});
afterPut(flowFile, context, transfer);
stopWatch.stop();
final String dataRate = stopWatch.calculateDataRate(flowFile.getSize());
final long millis = stopWatch.getDuration(TimeUnit.MILLISECONDS);
logger.info("Successfully transferred {} to {} on remote host {} in {} milliseconds at a rate of {}", new Object[] { flowFile, fullPathRef.get(), hostname, millis, dataRate });
String fullPathWithSlash = fullPathRef.get();
if (!fullPathWithSlash.startsWith("/")) {
fullPathWithSlash = "/" + fullPathWithSlash;
}
final String destinationUri = transfer.getProtocolName() + "://" + hostname + fullPathWithSlash;
session.getProvenanceReporter().send(flowFile, destinationUri, millis);
}
if (conflictResult.isPenalize()) {
flowFile = session.penalize(flowFile);
}
session.transfer(flowFile, conflictResult.getRelationship());
session.commit();
} while (isScheduled() && (getRelationships().size() == context.getAvailableRelationships().size()) && (++fileCount < maxNumberOfFiles) && ((flowFile = session.get()) != null));
} catch (final IOException e) {
context.yield();
logger.error("Unable to transfer {} to remote host {} due to {}", new Object[] { flowFile, hostname, e });
flowFile = session.penalize(flowFile);
session.transfer(flowFile, REL_FAILURE);
} catch (final FlowFileAccessException e) {
context.yield();
logger.error("Unable to transfer {} to remote host {} due to {}", new Object[] { flowFile, hostname, e.getCause() });
flowFile = session.penalize(flowFile);
session.transfer(flowFile, REL_FAILURE);
} catch (final ProcessException e) {
context.yield();
logger.error("Unable to transfer {} to remote host {} due to {}: {}; routing to failure", new Object[] { flowFile, hostname, e, e.getCause() });
flowFile = session.penalize(flowFile);
session.transfer(flowFile, REL_FAILURE);
}
}
use of org.apache.nifi.processor.exception.FlowFileAccessException in project nifi by apache.
the class GetFileTransfer method onTrigger.
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
final long pollingIntervalMillis = context.getProperty(FileTransfer.POLLING_INTERVAL).asTimePeriod(TimeUnit.MILLISECONDS);
final long nextPollTime = lastPollTime.get() + pollingIntervalMillis;
BlockingQueue<FileInfo> fileQueue = fileQueueRef.get();
final ComponentLog logger = getLogger();
// do not do the listing if there are already 100 or more items in our queue
// 100 is really just a magic number that seems to work out well in practice
FileTransfer transfer = null;
if (System.currentTimeMillis() >= nextPollTime && (fileQueue == null || fileQueue.size() < 100) && listingLock.tryLock()) {
try {
transfer = getFileTransfer(context);
try {
fetchListing(context, session, transfer);
lastPollTime.set(System.currentTimeMillis());
} catch (final IOException e) {
context.yield();
try {
transfer.close();
} catch (final IOException e1) {
logger.warn("Unable to close connection due to {}", new Object[] { e1 });
}
logger.error("Unable to fetch listing from remote server due to {}", new Object[] { e });
return;
}
} finally {
listingLock.unlock();
}
}
fileQueue = fileQueueRef.get();
if (fileQueue == null || fileQueue.isEmpty()) {
// nothing to do!
context.yield();
if (transfer != null) {
try {
transfer.close();
} catch (final IOException e1) {
logger.warn("Unable to close connection due to {}", new Object[] { e1 });
}
}
return;
}
final String hostname = context.getProperty(FileTransfer.HOSTNAME).evaluateAttributeExpressions().getValue();
final boolean deleteOriginal = context.getProperty(FileTransfer.DELETE_ORIGINAL).asBoolean();
final int maxSelects = context.getProperty(FileTransfer.MAX_SELECTS).asInteger();
if (transfer == null) {
transfer = getFileTransfer(context);
}
try {
for (int i = 0; i < maxSelects && isScheduled(); i++) {
final FileInfo file;
sharableTransferLock.lock();
try {
file = fileQueue.poll();
if (file == null) {
return;
}
processing.add(file);
} finally {
sharableTransferLock.unlock();
}
File relativeFile = new File(file.getFullPathFileName());
final String parentRelativePath = (null == relativeFile.getParent()) ? "" : relativeFile.getParent();
final String parentRelativePathString = parentRelativePath + "/";
final Path absPath = relativeFile.toPath().toAbsolutePath();
final String absPathString = absPath.getParent().toString() + "/";
try {
FlowFile flowFile = session.create();
final StopWatch stopWatch = new StopWatch(false);
try (final InputStream in = transfer.getInputStream(file.getFullPathFileName())) {
stopWatch.start();
flowFile = session.importFrom(in, flowFile);
stopWatch.stop();
}
transfer.flush();
final long millis = stopWatch.getDuration(TimeUnit.MILLISECONDS);
final String dataRate = stopWatch.calculateDataRate(flowFile.getSize());
flowFile = session.putAttribute(flowFile, this.getClass().getSimpleName().toLowerCase() + ".remote.source", hostname);
flowFile = session.putAttribute(flowFile, CoreAttributes.PATH.key(), parentRelativePathString);
flowFile = session.putAttribute(flowFile, CoreAttributes.FILENAME.key(), relativeFile.getName());
flowFile = session.putAttribute(flowFile, CoreAttributes.ABSOLUTE_PATH.key(), absPathString);
Map<String, String> attributes = getAttributesFromFile(file);
if (attributes.size() > 0) {
flowFile = session.putAllAttributes(flowFile, attributes);
}
if (deleteOriginal) {
try {
transfer.deleteFile(flowFile, null, file.getFullPathFileName());
} catch (final IOException e) {
logger.error("Failed to remove remote file {} due to {}; deleting local copy", new Object[] { file.getFullPathFileName(), e });
session.remove(flowFile);
return;
}
}
session.getProvenanceReporter().receive(flowFile, transfer.getProtocolName() + "://" + hostname + "/" + file.getFullPathFileName(), millis);
session.transfer(flowFile, REL_SUCCESS);
logger.info("Successfully retrieved {} from {} in {} milliseconds at a rate of {} and transferred to success", new Object[] { flowFile, hostname, millis, dataRate });
session.commit();
} catch (final IOException e) {
context.yield();
logger.error("Unable to retrieve file {} due to {}", new Object[] { file.getFullPathFileName(), e });
try {
transfer.close();
} catch (IOException e1) {
logger.warn("Unable to close connection to remote host due to {}", new Object[] { e1 });
}
session.rollback();
return;
} catch (final FlowFileAccessException e) {
context.yield();
logger.error("Unable to retrieve file {} due to {}", new Object[] { file.getFullPathFileName(), e.getCause() }, e);
try {
transfer.close();
} catch (IOException e1) {
logger.warn("Unable to close connection to remote host due to {}", e1);
}
session.rollback();
return;
} finally {
processing.remove(file);
}
}
} finally {
try {
transfer.close();
} catch (final IOException e) {
logger.warn("Failed to close connection to {} due to {}", new Object[] { hostname, e });
}
}
}
use of org.apache.nifi.processor.exception.FlowFileAccessException in project nifi by apache.
the class MockProcessSession method exportTo.
@Override
public void exportTo(FlowFile flowFile, final OutputStream out) {
flowFile = validateState(flowFile);
if (flowFile == null || out == null) {
throw new IllegalArgumentException("arguments cannot be null");
}
if (!(flowFile instanceof MockFlowFile)) {
throw new IllegalArgumentException("Cannot export a flow file that I did not create");
}
final MockFlowFile mock = (MockFlowFile) flowFile;
try {
out.write(mock.getData());
} catch (final IOException e) {
throw new FlowFileAccessException(e.toString(), e);
}
}
use of org.apache.nifi.processor.exception.FlowFileAccessException in project nifi by apache.
the class MockProcessSession method importFrom.
@Override
public MockFlowFile importFrom(final InputStream in, FlowFile flowFile) {
flowFile = validateState(flowFile);
if (in == null || flowFile == null) {
throw new IllegalArgumentException("argument cannot be null");
}
if (!(flowFile instanceof MockFlowFile)) {
throw new IllegalArgumentException("Cannot export a flow file that I did not create");
}
final MockFlowFile mock = (MockFlowFile) flowFile;
final MockFlowFile newFlowFile = new MockFlowFile(mock.getId(), flowFile);
currentVersions.put(newFlowFile.getId(), newFlowFile);
try {
final byte[] data = readFully(in);
newFlowFile.setData(data);
return newFlowFile;
} catch (final IOException e) {
throw new FlowFileAccessException(e.toString(), e);
}
}
use of org.apache.nifi.processor.exception.FlowFileAccessException in project nifi by apache.
the class StandardProcessSession method merge.
@Override
public FlowFile merge(Collection<FlowFile> sources, FlowFile destination, final byte[] header, final byte[] footer, final byte[] demarcator) {
verifyTaskActive();
sources = validateRecordState(sources);
destination = validateRecordState(destination);
if (sources.contains(destination)) {
throw new IllegalArgumentException("Destination cannot be within sources");
}
final Collection<StandardRepositoryRecord> sourceRecords = new ArrayList<>();
for (final FlowFile source : sources) {
final StandardRepositoryRecord record = records.get(source);
sourceRecords.add(record);
try {
ensureNotAppending(record.getCurrentClaim());
claimCache.flush(record.getCurrentClaim());
} catch (final IOException e) {
throw new FlowFileAccessException("Unable to read from source " + source + " due to " + e.toString(), e);
}
}
final StandardRepositoryRecord destinationRecord = records.get(destination);
final ContentRepository contentRepo = context.getContentRepository();
final ContentClaim newClaim;
try {
newClaim = contentRepo.create(context.getConnectable().isLossTolerant());
claimLog.debug("Creating ContentClaim {} for 'merge' for {}", newClaim, destinationRecord.getCurrent());
} catch (final IOException e) {
throw new FlowFileAccessException("Unable to create ContentClaim due to " + e.toString(), e);
}
long readCount = 0L;
long writtenCount = 0L;
try {
try (final OutputStream rawOut = contentRepo.write(newClaim);
final OutputStream out = new BufferedOutputStream(rawOut)) {
if (header != null && header.length > 0) {
out.write(header);
writtenCount += header.length;
}
int objectIndex = 0;
final boolean useDemarcator = demarcator != null && demarcator.length > 0;
final int numSources = sources.size();
for (final FlowFile source : sources) {
final StandardRepositoryRecord sourceRecord = records.get(source);
final long copied = contentRepo.exportTo(sourceRecord.getCurrentClaim(), out, sourceRecord.getCurrentClaimOffset(), source.getSize());
writtenCount += copied;
readCount += copied;
// don't add demarcator after the last claim
if (useDemarcator && ++objectIndex < numSources) {
out.write(demarcator);
writtenCount += demarcator.length;
}
}
if (footer != null && footer.length > 0) {
out.write(footer);
writtenCount += footer.length;
}
} finally {
bytesWritten += writtenCount;
bytesRead += readCount;
}
} catch (final ContentNotFoundException nfe) {
destroyContent(newClaim);
handleContentNotFound(nfe, destinationRecord);
handleContentNotFound(nfe, sourceRecords);
} catch (final IOException ioe) {
destroyContent(newClaim);
throw new FlowFileAccessException("Failed to merge " + sources.size() + " into " + destination + " due to " + ioe.toString(), ioe);
} catch (final Throwable t) {
destroyContent(newClaim);
throw t;
}
removeTemporaryClaim(destinationRecord);
final FlowFileRecord newFile = new StandardFlowFileRecord.Builder().fromFlowFile(destinationRecord.getCurrent()).contentClaim(newClaim).contentClaimOffset(0L).size(writtenCount).build();
destinationRecord.setWorking(newFile);
records.put(newFile, destinationRecord);
return newFile;
}
Aggregations