ggershinsky commented on code in PR #5544: URL: https://github.com/apache/iceberg/pull/5544#discussion_r1590856537
########## core/src/main/java/org/apache/iceberg/BaseMetastoreTableOperations.java: ########## @@ -146,21 +172,92 @@ protected void disableRefresh() { } protected String writeNewMetadataIfRequired(boolean newTable, TableMetadata metadata) { + return writeNewMetadataFileIfRequired(newTable, metadata).location(); + } + + protected MetadataFile writeNewMetadataFileIfRequired(boolean newTable, TableMetadata metadata) { return newTable && metadata.metadataFileLocation() != null - ? metadata.metadataFileLocation() - : writeNewMetadata(metadata, currentVersion() + 1); + ? new MetadataFile(metadata.metadataFileLocation(), null, -1L) + : writeNewMetadataFile(metadata, currentVersion() + 1); } protected String writeNewMetadata(TableMetadata metadata, int newVersion) { + return writeNewMetadataFile(metadata, newVersion).location(); + } + + protected MetadataFile writeNewMetadataFile(TableMetadata metadata, int newVersion) { String newTableMetadataFilePath = newTableMetadataFilePath(metadata, newVersion); - OutputFile newMetadataLocation = io().newOutputFile(newTableMetadataFilePath); + + if (encryptionKeyId == null) { + encryptionKeyId = metadata.property(TableProperties.ENCRYPTION_TABLE_KEY, null); + } + + OutputFile newMetadataFile; + String wrappedMetadataKey; + + if (encryptionKeyId != null) { + + if (encryptionDekLength < 0) { + String encryptionDekLenProp = + metadata.property(TableProperties.ENCRYPTION_DEK_LENGTH, null); + encryptionDekLength = + (encryptionDekLenProp == null) + ? TableProperties.ENCRYPTION_DEK_LENGTH_DEFAULT + : Integer.valueOf(encryptionDekLenProp); + } + + FileIO io = io(); + Preconditions.checkArgument( + io instanceof EncryptingFileIO, + "Cannot encrypt table metadata because the fileIO (%s) does not " + + "implement EncryptingFileIO", + io.getClass()); + EncryptingFileIO encryptingIO = (EncryptingFileIO) io(); + EncryptedOutputFile newEncryptedMetadataFile = + encryptingIO.newEncryptingOutputFile(newTableMetadataFilePath); + + if (newEncryptedMetadataFile.keyMetadata() == null + || newEncryptedMetadataFile.keyMetadata().buffer() == null) { + throw new IllegalStateException("Null key metadata in encrypted table"); + } + + newMetadataFile = newEncryptedMetadataFile.encryptingOutputFile(); + EncryptionManager encryptionManager = encryptingIO.encryptionManager(); + + Preconditions.checkArgument( + encryptionManager instanceof StandardEncryptionManager, + "Cannot encrypt table metadata because the encryption manager (%s) does not " + + "implement StandardEncryptionManager", + encryptionManager.getClass()); + NativeEncryptionKeyMetadata keyMetadata = + (NativeEncryptionKeyMetadata) newEncryptedMetadataFile.keyMetadata(); + ByteBuffer metadataEncryptionKey = keyMetadata.encryptionKey(); + // Wrap (encrypt) metadata file key + ByteBuffer wrappedEncryptionKey = + ((StandardEncryptionManager) encryptionManager).wrapKey(metadataEncryptionKey); + + ByteBuffer metadataAADPrefix = keyMetadata.aadPrefix(); + wrappedMetadataKey = + Base64.getEncoder() + .encodeToString( + EncryptionUtil.createKeyMetadata(wrappedEncryptionKey, metadataAADPrefix) + .buffer() + .array()); Review Comment: move this logic into a util class (eg EncryptionUtil or TableMetadataParser), so it can be re-used by other catalogs. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org For additional commands, e-mail: issues-h...@iceberg.apache.org