mirror of https://github.com/apache/nifi.git
NIFI-7073: This closes #4025. Route to failure when error on PutHDFS file system close
Signed-off-by: Joe Witt <joewitt@apache.org>
This commit is contained in:
parent
850869c6d2
commit
76e8c51e11
|
@ -23,7 +23,6 @@ import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.permission.FsCreateModes;
|
import org.apache.hadoop.fs.permission.FsCreateModes;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.io.compress.CompressionCodec;
|
import org.apache.hadoop.io.compress.CompressionCodec;
|
||||||
import org.apache.hadoop.ipc.RemoteException;
|
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
@ -353,7 +352,7 @@ public class PutHDFS extends AbstractHadoopProcessor {
|
||||||
if (fos != null) {
|
if (fos != null) {
|
||||||
fos.close();
|
fos.close();
|
||||||
}
|
}
|
||||||
} catch (RemoteException re) {
|
} catch (Throwable t) {
|
||||||
// when talking to remote HDFS clusters, we don't notice problems until fos.close()
|
// when talking to remote HDFS clusters, we don't notice problems until fos.close()
|
||||||
if (createdFile != null) {
|
if (createdFile != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -361,8 +360,7 @@ public class PutHDFS extends AbstractHadoopProcessor {
|
||||||
} catch (Throwable ignore) {
|
} catch (Throwable ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw re;
|
throw t;
|
||||||
} catch (Throwable ignore) {
|
|
||||||
}
|
}
|
||||||
fos = null;
|
fos = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,6 +432,33 @@ public class PutHDFSTest {
|
||||||
fileSystem.getFileStatus(new Path("target/test-classes/randombytes-1")).getPermission());
|
fileSystem.getFileStatus(new Path("target/test-classes/randombytes-1")).getPermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutFileWithCloseException() throws IOException {
|
||||||
|
mockFileSystem = new MockFileSystem(true);
|
||||||
|
String dirName = "target/testPutFileCloseException";
|
||||||
|
File file = new File(dirName);
|
||||||
|
file.mkdirs();
|
||||||
|
Path p = new Path(dirName).makeQualified(mockFileSystem.getUri(), mockFileSystem.getWorkingDirectory());
|
||||||
|
|
||||||
|
TestRunner runner = TestRunners.newTestRunner(new TestablePutHDFS(kerberosProperties, mockFileSystem));
|
||||||
|
runner.setProperty(PutHDFS.DIRECTORY, dirName);
|
||||||
|
runner.setProperty(PutHDFS.CONFLICT_RESOLUTION, "replace");
|
||||||
|
|
||||||
|
try (FileInputStream fis = new FileInputStream("src/test/resources/testdata/randombytes-1")) {
|
||||||
|
Map<String, String> attributes = new HashMap<>();
|
||||||
|
attributes.put(CoreAttributes.FILENAME.key(), "randombytes-1");
|
||||||
|
runner.enqueue(fis, attributes);
|
||||||
|
runner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MockFlowFile> failedFlowFiles = runner
|
||||||
|
.getFlowFilesForRelationship(PutHDFS.REL_FAILURE);
|
||||||
|
assertFalse(failedFlowFiles.isEmpty());
|
||||||
|
assertTrue(failedFlowFiles.get(0).isPenalized());
|
||||||
|
|
||||||
|
mockFileSystem.delete(p, true);
|
||||||
|
}
|
||||||
|
|
||||||
private class TestablePutHDFS extends PutHDFS {
|
private class TestablePutHDFS extends PutHDFS {
|
||||||
|
|
||||||
private KerberosProperties testKerberosProperties;
|
private KerberosProperties testKerberosProperties;
|
||||||
|
@ -461,6 +488,15 @@ public class PutHDFSTest {
|
||||||
|
|
||||||
private class MockFileSystem extends FileSystem {
|
private class MockFileSystem extends FileSystem {
|
||||||
private final Map<Path, FileStatus> pathToStatus = new HashMap<>();
|
private final Map<Path, FileStatus> pathToStatus = new HashMap<>();
|
||||||
|
private final boolean failOnClose;
|
||||||
|
|
||||||
|
public MockFileSystem() {
|
||||||
|
failOnClose = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MockFileSystem(boolean failOnClose) {
|
||||||
|
this.failOnClose = failOnClose;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getUri() {
|
public URI getUri() {
|
||||||
|
@ -476,7 +512,17 @@ public class PutHDFSTest {
|
||||||
public FSDataOutputStream create(final Path f, final FsPermission permission, final boolean overwrite, final int bufferSize, final short replication,
|
public FSDataOutputStream create(final Path f, final FsPermission permission, final boolean overwrite, final int bufferSize, final short replication,
|
||||||
final long blockSize, final Progressable progress) {
|
final long blockSize, final Progressable progress) {
|
||||||
pathToStatus.put(f, newFile(f, permission));
|
pathToStatus.put(f, newFile(f, permission));
|
||||||
return new FSDataOutputStream(new ByteArrayOutputStream(), new Statistics(""));
|
if(failOnClose) {
|
||||||
|
return new FSDataOutputStream(new ByteArrayOutputStream(), new Statistics("")) {
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
super.close();
|
||||||
|
throw new IOException("Fail on close");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return new FSDataOutputStream(new ByteArrayOutputStream(), new Statistics(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue