use of org.apache.nifi.logging.LogLevel in project nifi by apache.
the class FetchFile method onTrigger.
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
FlowFile flowFile = session.get();
if (flowFile == null) {
return;
}
final StopWatch stopWatch = new StopWatch(true);
final String filename = context.getProperty(FILENAME).evaluateAttributeExpressions(flowFile).getValue();
final LogLevel levelFileNotFound = LogLevel.valueOf(context.getProperty(FILE_NOT_FOUND_LOG_LEVEL).getValue());
final LogLevel levelPermDenied = LogLevel.valueOf(context.getProperty(PERM_DENIED_LOG_LEVEL).getValue());
final File file = new File(filename);
// Verify that file system is reachable and file exists
Path filePath = file.toPath();
if (!Files.exists(filePath) && !Files.notExists(filePath)) {
// see https://docs.oracle.com/javase/tutorial/essential/io/check.html for more details
getLogger().log(levelFileNotFound, "Could not fetch file {} from file system for {} because the existence of the file cannot be verified; routing to failure", new Object[] { file, flowFile });
session.transfer(session.penalize(flowFile), REL_FAILURE);
return;
} else if (!Files.exists(filePath)) {
getLogger().log(levelFileNotFound, "Could not fetch file {} from file system for {} because the file does not exist; routing to not.found", new Object[] { file, flowFile });
session.getProvenanceReporter().route(flowFile, REL_NOT_FOUND);
session.transfer(session.penalize(flowFile), REL_NOT_FOUND);
return;
}
// Verify read permission on file
final String user = System.getProperty("user.name");
if (!isReadable(file)) {
getLogger().log(levelPermDenied, "Could not fetch file {} from file system for {} due to user {} not having sufficient permissions to read the file; routing to permission.denied", new Object[] { file, flowFile, user });
session.getProvenanceReporter().route(flowFile, REL_PERMISSION_DENIED);
session.transfer(session.penalize(flowFile), REL_PERMISSION_DENIED);
return;
}
// If configured to move the file and fail if unable to do so, check that the existing file does not exist and that we have write permissions
// for the parent file.
final String completionStrategy = context.getProperty(COMPLETION_STRATEGY).getValue();
final String targetDirectoryName = context.getProperty(MOVE_DESTINATION_DIR).evaluateAttributeExpressions(flowFile).getValue();
if (targetDirectoryName != null) {
final File targetDir = new File(targetDirectoryName);
if (COMPLETION_MOVE.getValue().equalsIgnoreCase(completionStrategy)) {
if (targetDir.exists() && (!isWritable(targetDir) || !isDirectory(targetDir))) {
getLogger().error("Could not fetch file {} from file system for {} because Completion Strategy is configured to move the original file to {}, " + "but that is not a directory or user {} does not have permissions to write to that directory", new Object[] { file, flowFile, targetDir, user });
session.transfer(flowFile, REL_FAILURE);
return;
}
final String conflictStrategy = context.getProperty(CONFLICT_STRATEGY).getValue();
if (CONFLICT_FAIL.getValue().equalsIgnoreCase(conflictStrategy)) {
final File targetFile = new File(targetDir, file.getName());
if (targetFile.exists()) {
getLogger().error("Could not fetch file {} from file system for {} because Completion Strategy is configured to move the original file to {}, " + "but a file with name {} already exists in that directory and the Move Conflict Strategy is configured for failure", new Object[] { file, flowFile, targetDir, file.getName() });
session.transfer(flowFile, REL_FAILURE);
return;
}
}
}
}
// import content from file system
try (final FileInputStream fis = new FileInputStream(file)) {
flowFile = session.importFrom(fis, flowFile);
} catch (final IOException ioe) {
getLogger().error("Could not fetch file {} from file system for {} due to {}; routing to failure", new Object[] { file, flowFile, ioe.toString() }, ioe);
session.transfer(session.penalize(flowFile), REL_FAILURE);
return;
}
session.getProvenanceReporter().modifyContent(flowFile, "Replaced content of FlowFile with contents of " + file.toURI(), stopWatch.getElapsed(TimeUnit.MILLISECONDS));
session.transfer(flowFile, REL_SUCCESS);
// It is critical that we commit the session before we perform the Completion Strategy. Otherwise, we could have a case where we
// ingest the file, delete/move the file, and then NiFi is restarted before the session is committed. That would result in data loss.
// As long as we commit the session right here, before we perform the Completion Strategy, we are safe.
session.commit();
// Attempt to perform the Completion Strategy action
Exception completionFailureException = null;
if (COMPLETION_DELETE.getValue().equalsIgnoreCase(completionStrategy)) {
// convert to path and use Files.delete instead of file.delete so that if we fail, we know why
try {
delete(file);
} catch (final IOException ioe) {
completionFailureException = ioe;
}
} else if (COMPLETION_MOVE.getValue().equalsIgnoreCase(completionStrategy)) {
final File targetDirectory = new File(targetDirectoryName);
final File targetFile = new File(targetDirectory, file.getName());
try {
if (targetFile.exists()) {
final String conflictStrategy = context.getProperty(CONFLICT_STRATEGY).getValue();
if (CONFLICT_KEEP_INTACT.getValue().equalsIgnoreCase(conflictStrategy)) {
// don't move, just delete the original
Files.delete(file.toPath());
} else if (CONFLICT_RENAME.getValue().equalsIgnoreCase(conflictStrategy)) {
// rename to add a random UUID but keep the file extension if it has one.
final String simpleFilename = targetFile.getName();
final String newName;
if (simpleFilename.contains(".")) {
newName = StringUtils.substringBeforeLast(simpleFilename, ".") + "-" + UUID.randomUUID().toString() + "." + StringUtils.substringAfterLast(simpleFilename, ".");
} else {
newName = simpleFilename + "-" + UUID.randomUUID().toString();
}
move(file, new File(targetDirectory, newName), false);
} else if (CONFLICT_REPLACE.getValue().equalsIgnoreCase(conflictStrategy)) {
move(file, targetFile, true);
}
} else {
move(file, targetFile, false);
}
} catch (final IOException ioe) {
completionFailureException = ioe;
}
}
// Handle completion failures
if (completionFailureException != null) {
getLogger().warn("Successfully fetched the content from {} for {} but failed to perform Completion Action due to {}; routing to success", new Object[] { file, flowFile, completionFailureException }, completionFailureException);
}
}
Aggregations