Search in sources :

Example 1 with EncryptionWithColumnKey

use of org.apache.parquet.format.EncryptionWithColumnKey in project parquet-mr by apache.

the class ParquetMetadataConverter method fromParquetMetadata.

public ParquetMetadata fromParquetMetadata(FileMetaData parquetMetadata, InternalFileDecryptor fileDecryptor, boolean encryptedFooter) throws IOException {
    MessageType messageType = fromParquetSchema(parquetMetadata.getSchema(), parquetMetadata.getColumn_orders());
    List<BlockMetaData> blocks = new ArrayList<BlockMetaData>();
    List<RowGroup> row_groups = parquetMetadata.getRow_groups();
    if (row_groups != null) {
        for (RowGroup rowGroup : row_groups) {
            BlockMetaData blockMetaData = new BlockMetaData();
            blockMetaData.setRowCount(rowGroup.getNum_rows());
            blockMetaData.setTotalByteSize(rowGroup.getTotal_byte_size());
            // not set in legacy files
            if (rowGroup.isSetOrdinal()) {
                blockMetaData.setOrdinal(rowGroup.getOrdinal());
            }
            List<ColumnChunk> columns = rowGroup.getColumns();
            String filePath = columns.get(0).getFile_path();
            int columnOrdinal = -1;
            for (ColumnChunk columnChunk : columns) {
                columnOrdinal++;
                if ((filePath == null && columnChunk.getFile_path() != null) || (filePath != null && !filePath.equals(columnChunk.getFile_path()))) {
                    throw new ParquetDecodingException("all column chunks of the same row group must be in the same file for now");
                }
                ColumnMetaData metaData = columnChunk.meta_data;
                ColumnCryptoMetaData cryptoMetaData = columnChunk.getCrypto_metadata();
                ColumnChunkMetaData column = null;
                ColumnPath columnPath = null;
                boolean encryptedMetadata = false;
                if (null == cryptoMetaData) {
                    // Plaintext column
                    columnPath = getPath(metaData);
                    if (null != fileDecryptor && !fileDecryptor.plaintextFile()) {
                        // mark this column as plaintext in encrypted file decryptor
                        fileDecryptor.setColumnCryptoMetadata(columnPath, false, false, (byte[]) null, columnOrdinal);
                    }
                } else {
                    // Encrypted column
                    boolean encryptedWithFooterKey = cryptoMetaData.isSetENCRYPTION_WITH_FOOTER_KEY();
                    if (encryptedWithFooterKey) {
                        // Column encrypted with footer key
                        if (!encryptedFooter) {
                            throw new ParquetCryptoRuntimeException("Column encrypted with footer key in file with plaintext footer");
                        }
                        if (null == metaData) {
                            throw new ParquetCryptoRuntimeException("ColumnMetaData not set in Encryption with Footer key");
                        }
                        if (null == fileDecryptor) {
                            throw new ParquetCryptoRuntimeException("Column encrypted with footer key: No keys available");
                        }
                        columnPath = getPath(metaData);
                        fileDecryptor.setColumnCryptoMetadata(columnPath, true, true, (byte[]) null, columnOrdinal);
                    } else {
                        // Column encrypted with column key
                        // setColumnCryptoMetadata triggers KMS interaction, hence delayed until this column is projected
                        encryptedMetadata = true;
                    }
                }
                String createdBy = parquetMetadata.getCreated_by();
                if (!encryptedMetadata) {
                    // unencrypted column, or encrypted with footer key
                    column = buildColumnChunkMetaData(metaData, columnPath, messageType.getType(columnPath.toArray()).asPrimitiveType(), createdBy);
                    column.setRowGroupOrdinal(rowGroup.getOrdinal());
                    if (metaData.isSetBloom_filter_offset()) {
                        column.setBloomFilterOffset(metaData.getBloom_filter_offset());
                    }
                } else {
                    // column encrypted with column key
                    // Metadata will be decrypted later, if this column is accessed
                    EncryptionWithColumnKey columnKeyStruct = cryptoMetaData.getENCRYPTION_WITH_COLUMN_KEY();
                    List<String> pathList = columnKeyStruct.getPath_in_schema();
                    byte[] columnKeyMetadata = columnKeyStruct.getKey_metadata();
                    columnPath = ColumnPath.get(pathList.toArray(new String[pathList.size()]));
                    byte[] encryptedMetadataBuffer = columnChunk.getEncrypted_column_metadata();
                    column = ColumnChunkMetaData.getWithEncryptedMetadata(this, columnPath, messageType.getType(columnPath.toArray()).asPrimitiveType(), encryptedMetadataBuffer, columnKeyMetadata, fileDecryptor, rowGroup.getOrdinal(), columnOrdinal, createdBy);
                }
                column.setColumnIndexReference(toColumnIndexReference(columnChunk));
                column.setOffsetIndexReference(toOffsetIndexReference(columnChunk));
                // TODO
                // index_page_offset
                // key_value_metadata
                blockMetaData.addColumn(column);
            }
            blockMetaData.setPath(filePath);
            blocks.add(blockMetaData);
        }
    }
    Map<String, String> keyValueMetaData = new HashMap<String, String>();
    List<KeyValue> key_value_metadata = parquetMetadata.getKey_value_metadata();
    if (key_value_metadata != null) {
        for (KeyValue keyValue : key_value_metadata) {
            keyValueMetaData.put(keyValue.key, keyValue.value);
        }
    }
    return new ParquetMetadata(new org.apache.parquet.hadoop.metadata.FileMetaData(messageType, keyValueMetaData, parquetMetadata.getCreated_by(), fileDecryptor), blocks);
}
Also used : BlockMetaData(org.apache.parquet.hadoop.metadata.BlockMetaData) ParquetDecodingException(org.apache.parquet.io.ParquetDecodingException) KeyValue(org.apache.parquet.format.KeyValue) ColumnChunkMetaData(org.apache.parquet.hadoop.metadata.ColumnChunkMetaData) ParquetCryptoRuntimeException(org.apache.parquet.crypto.ParquetCryptoRuntimeException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ParquetMetadata(org.apache.parquet.hadoop.metadata.ParquetMetadata) RowGroup(org.apache.parquet.format.RowGroup) ArrayList(java.util.ArrayList) ColumnChunk(org.apache.parquet.format.ColumnChunk) Util.writeColumnMetaData(org.apache.parquet.format.Util.writeColumnMetaData) ColumnMetaData(org.apache.parquet.format.ColumnMetaData) MessageType(org.apache.parquet.schema.MessageType) ColumnCryptoMetaData(org.apache.parquet.format.ColumnCryptoMetaData) EncryptionWithColumnKey(org.apache.parquet.format.EncryptionWithColumnKey) ColumnPath(org.apache.parquet.hadoop.metadata.ColumnPath)

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ParquetCryptoRuntimeException (org.apache.parquet.crypto.ParquetCryptoRuntimeException)1 ColumnChunk (org.apache.parquet.format.ColumnChunk)1 ColumnCryptoMetaData (org.apache.parquet.format.ColumnCryptoMetaData)1 ColumnMetaData (org.apache.parquet.format.ColumnMetaData)1 EncryptionWithColumnKey (org.apache.parquet.format.EncryptionWithColumnKey)1 KeyValue (org.apache.parquet.format.KeyValue)1 RowGroup (org.apache.parquet.format.RowGroup)1 Util.writeColumnMetaData (org.apache.parquet.format.Util.writeColumnMetaData)1 BlockMetaData (org.apache.parquet.hadoop.metadata.BlockMetaData)1 ColumnChunkMetaData (org.apache.parquet.hadoop.metadata.ColumnChunkMetaData)1 ColumnPath (org.apache.parquet.hadoop.metadata.ColumnPath)1 ParquetMetadata (org.apache.parquet.hadoop.metadata.ParquetMetadata)1 ParquetDecodingException (org.apache.parquet.io.ParquetDecodingException)1 MessageType (org.apache.parquet.schema.MessageType)1