Core, Flink: Refactor InputFilesDecryptor and use EncryptingFileIO.bulkDecrypt() - #18198
gaborkaszab wants to merge 1 commit into
Conversation
|
|
||
| private Map<String, InputFile> inputFiles() { | ||
| if (lazyInputFiles == null) { | ||
| this.lazyInputFiles = encryptingIO.bulkDecrypt(referencedFiles); |
There was a problem hiding this comment.
Do we need to synchronize this?
| public InputFile getInputFile(String location) { | ||
| return decryptedInputFiles.get(location); | ||
| InputFile inputFile = inputFiles().get(location); | ||
| Preconditions.checkArgument( |
There was a problem hiding this comment.
It is a behavioural change. Seems acceptable, but I would like to make sure that we are ok with this.
| void before() { | ||
| this.dataInputFile = Mockito.mock(InputFile.class); | ||
| this.deleteInputFile = Mockito.mock(InputFile.class); | ||
| this.encryptingIO = Mockito.mock(EncryptingFileIO.class); |
There was a problem hiding this comment.
Maybe use InMemoryFileIO?
this.encryptingIO = Mockito.spy(EncryptingFileIO.combine(new InMemoryFileIO(), PlaintextEncryptionManager.instance()));
| EncryptedFiles.encryptedInput( | ||
| io.newInputFile(entry.getKey()), entry.getValue())); | ||
| this( | ||
| () -> referencedFiles(combinedTask.files()).iterator(), |
There was a problem hiding this comment.
do we need this lambda? Shall we just call referencedFiles when lazyInputFiles is initialized?
…kDecrypt()
Changes this contains:
- More generic interface with parameters:
- Iterable<FileScanTask>
- EncryptingFileIO
- Contructs InputFiles lazily when first requested
- EncryptionManager is wrapped into EncryptingFileIO input parameter
- Use EncryptingFileIO.bulkDecrypt() instead of EncryptionManager.decrypt()
- Throw if file location is not found
- Removed usage of old contructor and getInputFile(FileScanTask)
With this design, this class is generic enough to be wired into other
readers as a common implementation for creating InputFiles with bulk
decryption taken into account. Later, GenericReader and Spark's readers can
swap to use this.
One hidden improvement: Previously this class created InputFiles using
location + key metadata without the size. While this works, when it comes
to reading, it requires an extra RPC to get the size of the file.
Now, with bulkDecrypt(), the location + size + key metadata are used
together saving an extra RPC per file.
55ba635 to
4e54fc1
Compare
| .getValue() | ||
| .getMessage()) | ||
| .contains("File does not exist: "); | ||
| .contains("Failed to open input stream for file: "); |
There was a problem hiding this comment.
This is an error scenario test that verifies that reading from missing files is handled gracefully. The error text changes because we create InputFile differently: via the newInputFile variant that accepts a length.
Originally the test failed when doing an extra RPC to get the length before reading the file:
NotFoundException: File does not exist: /tmp/.../generic-appender-partition-test-...
at HadoopInputFile.lazyStat(HadoopInputFile.java:166)
at HadoopInputFile.getLength(HadoopInputFile.java:177)
at Parquet$ReadBuilder.<init>(Parquet.java:1334) <-- reads length up front
at Parquet.read(Parquet.java:1254)
at ParquetFormatModel.readBuilder(ParquetFormatModel.java:140)
at RowDataFileScanTaskReader.newIterable(RowDataFileScanTaskReader.java:108)
While now the extra RPC is gone, this fails when trying to actually open the file:
NotFoundException: Failed to open input stream for file: /tmp/.../generic-appender-partition-test-...
at HadoopInputFile.newStream(HadoopInputFile.java:187)
at EagerInputFile.newStream(EagerInputFile.java:76)
at ParquetIO$ParquetInputFile.newStream(ParquetIO.java:254)
at ParquetFileReader.<init>(ParquetFileReader.java:961)
at ReadConf.newReader(ReadConf.java:194)
I think this is acceptable. WDYT @pvary ?
Changes this contains:
With this design, this class is generic enough to be wired into other readers as a common implementation for creating InputFiles with bulk decryption taken into account. Later, GenericReader and Spark's readers can swap to use this.
One hidden improvement: Previously this class created InputFiles using location + key metadata without the size. While this works, when it comes to reading, it requires an extra RPC to get the size of the file. Now, with bulkDecrypt(), the location + size + key metadata are used together saving an extra RPC per file.