diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml index 0122f01e757..62fa274bebd 100644 --- a/.github/workflows/cpp.yml +++ b/.github/workflows/cpp.yml @@ -299,6 +299,7 @@ jobs: ARROW_BUILD_SHARED: ON ARROW_BUILD_STATIC: OFF ARROW_BUILD_TESTS: ON + ARROW_CMAKE_ARGS: -DPARQUET_BUILD_DBPS_LIBS=OFF ARROW_DATASET: ON ARROW_FLIGHT: OFF ARROW_HDFS: ON @@ -417,7 +418,9 @@ jobs: ARROW_WITH_ZSTD: ON ARROW_CMAKE_ARGS: >- -DARROW_PACKAGE_PREFIX=/${{ matrix.msystem_lower}} + -DARROW_BUILD_SHARED=ON -DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON + -DPARQUET_BUILD_DBPS_LIBS=OFF # We can't use unity build because we don't have enough memory on # GitHub Actions. # CMAKE_UNITY_BUILD: ON diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index aa9df362f11..b36963b455c 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -236,7 +236,9 @@ jobs: ARROW_WITH_ZSTD: ON ARROW_CMAKE_ARGS: >- -DARROW_PACKAGE_PREFIX=/ucrt${{ matrix.mingw-n-bits }} + -DARROW_BUILD_SHARED=ON -DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON + -DPARQUET_BUILD_DBPS_LIBS=OFF CMAKE_UNITY_BUILD: ON steps: - name: Disable Crash Dialogs @@ -349,6 +351,9 @@ jobs: ARROW_WITH_SNAPPY: ON ARROW_WITH_ZLIB: ON ARROW_WITH_ZSTD: ON + ARROW_CMAKE_ARGS: >- + -DARROW_BUILD_SHARED=ON + -DPARQUET_BUILD_DBPS_LIBS=OFF CMAKE_CXX_STANDARD: "17" CMAKE_GENERATOR: Ninja CMAKE_INSTALL_PREFIX: "${{ github.workspace }}/dist" diff --git a/cpp/src/parquet/encryption/aes_encryption.cc b/cpp/src/parquet/encryption/aes_encryption.cc index dd7eb4df3d3..72ca1fb45bf 100644 --- a/cpp/src/parquet/encryption/aes_encryption.cc +++ b/cpp/src/parquet/encryption/aes_encryption.cc @@ -30,7 +30,6 @@ #include "parquet/encryption/openssl_internal.h" #include "parquet/exception.h" -using ::arrow::util::span; using parquet::ParquetException; namespace parquet::encryption { @@ -132,11 +131,11 @@ AesCryptoContext::CipherContext AesEncryptor::MakeCipherContext() const { return ctx; } -int32_t AesEncryptor::SignedFooterEncrypt(span footer, - span key, - span aad, - span nonce, - span encrypted_footer) { +int32_t AesEncryptor::SignedFooterEncrypt(::arrow::util::span footer, + ::arrow::util::span key, + ::arrow::util::span aad, + ::arrow::util::span nonce, + ::arrow::util::span encrypted_footer) { if (static_cast(key_length_) != key.size()) { std::stringstream ss; ss << "Wrong key length " << key.size() << ". Should be " << key_length_; @@ -157,8 +156,10 @@ int32_t AesEncryptor::SignedFooterEncrypt(span footer, return GcmEncrypt(footer, key, nonce, aad, encrypted_footer); } -int32_t AesEncryptor::Encrypt(span plaintext, span key, - span aad, span ciphertext) { +int32_t AesEncryptor::Encrypt(::arrow::util::span plaintext, + ::arrow::util::span key, + ::arrow::util::span aad, + ::arrow::util::span ciphertext) { if (static_cast(key_length_) != key.size()) { std::stringstream ss; ss << "Wrong key length " << key.size() << ". Should be " << key_length_; @@ -184,9 +185,11 @@ int32_t AesEncryptor::Encrypt(span plaintext, span return CtrEncrypt(plaintext, key, nonce, ciphertext); } -int32_t AesEncryptor::GcmEncrypt(span plaintext, span key, - span nonce, span aad, - span ciphertext) { +int32_t AesEncryptor::GcmEncrypt(::arrow::util::span plaintext, + ::arrow::util::span key, + ::arrow::util::span nonce, + ::arrow::util::span aad, + ::arrow::util::span ciphertext) { int len; int32_t ciphertext_len; @@ -261,8 +264,10 @@ int32_t AesEncryptor::GcmEncrypt(span plaintext, span plaintext, span key, - span nonce, span ciphertext) { +int32_t AesEncryptor::CtrEncrypt(::arrow::util::span plaintext, + ::arrow::util::span key, + ::arrow::util::span nonce, + ::arrow::util::span ciphertext) { int len; int32_t ciphertext_len; @@ -405,8 +410,10 @@ int32_t AesDecryptor::CiphertextLength(int32_t plaintext_len) const { return plaintext_len + ciphertext_size_delta_; } -int32_t AesDecryptor::Decrypt(span ciphertext, span key, - span aad, span plaintext) { +int32_t AesDecryptor::Decrypt(::arrow::util::span ciphertext, + ::arrow::util::span key, + ::arrow::util::span aad, + ::arrow::util::span plaintext) { if (static_cast(key_length_) != key.size()) { std::stringstream ss; ss << "Wrong key length " << key.size() << ". Should be " << key_length_; @@ -444,7 +451,8 @@ AesCryptoContext::CipherContext AesDecryptor::MakeCipherContext() const { return ctx; } -int32_t AesDecryptor::GetCiphertextLength(span ciphertext) const { +int32_t AesDecryptor::GetCiphertextLength( + ::arrow::util::span ciphertext) const { if (length_buffer_length_ > 0) { // Note: length_buffer_length_ must be either 0 or kBufferSizeLength if (ciphertext.size() < static_cast(kBufferSizeLength)) { @@ -489,8 +497,10 @@ int32_t AesDecryptor::GetCiphertextLength(span ciphertext) const } } -int32_t AesDecryptor::GcmDecrypt(span ciphertext, span key, - span aad, span plaintext) { +int32_t AesDecryptor::GcmDecrypt(::arrow::util::span ciphertext, + ::arrow::util::span key, + ::arrow::util::span aad, + ::arrow::util::span plaintext) { int len; int32_t plaintext_len; @@ -562,8 +572,9 @@ int32_t AesDecryptor::GcmDecrypt(span ciphertext, span ciphertext, span key, - span plaintext) { +int32_t AesDecryptor::CtrDecrypt(::arrow::util::span ciphertext, + ::arrow::util::span key, + ::arrow::util::span plaintext) { int len; int32_t plaintext_len; diff --git a/cpp/src/parquet/encryption/encoding_properties.h b/cpp/src/parquet/encryption/encoding_properties.h index b2e68d0bd9d..51fa7d29eed 100644 --- a/cpp/src/parquet/encryption/encoding_properties.h +++ b/cpp/src/parquet/encryption/encoding_properties.h @@ -26,13 +26,14 @@ #include "parquet/column_page.h" #include "parquet/encoding.h" #include "parquet/metadata.h" +#include "parquet/platform.h" #include "parquet/types.h" namespace parquet::encryption { -class EncodingPropertiesBuilder; +class PARQUET_EXPORT EncodingPropertiesBuilder; -class EncodingProperties { +class PARQUET_EXPORT EncodingProperties { public: static std::unique_ptr MakeFromMetadata( const ColumnDescriptor* column_descriptor, @@ -121,7 +122,7 @@ class EncodingProperties { //-------------------------------- }; // class EncodingProperties -class EncodingPropertiesBuilder { +class PARQUET_EXPORT EncodingPropertiesBuilder { public: EncodingPropertiesBuilder() = default; diff --git a/cpp/src/parquet/encryption/external/dbpa_enum_utils.h b/cpp/src/parquet/encryption/external/dbpa_enum_utils.h index 7d1d8b3ac7f..0cd46e94833 100644 --- a/cpp/src/parquet/encryption/external/dbpa_enum_utils.h +++ b/cpp/src/parquet/encryption/external/dbpa_enum_utils.h @@ -23,6 +23,7 @@ #include #include "arrow/type_fwd.h" // For arrow::Compression +#include "parquet/platform.h" #include "parquet/types.h" namespace parquet::encryption::external { @@ -34,7 +35,7 @@ namespace parquet::encryption::external { * - parquet::Type and dbps::external::Type * - arrow::Compression and dbps::external::CompressionCodec */ -class DBPAEnumUtils { +class PARQUET_EXPORT DBPAEnumUtils { public: // Static maps for type conversions static const std::unordered_map diff --git a/cpp/src/parquet/encryption/external/dbpa_executor.h b/cpp/src/parquet/encryption/external/dbpa_executor.h index b913de64063..279d6dad8e5 100644 --- a/cpp/src/parquet/encryption/external/dbpa_executor.h +++ b/cpp/src/parquet/encryption/external/dbpa_executor.h @@ -25,6 +25,7 @@ #include #include +#include "parquet/platform.h" template using span = tcb::span; @@ -43,7 +44,7 @@ class DBPAExecutorTimeoutException; * DBPAExecutor - A decorator for DataBatchProtectionAgentInterface with timeout support * Original exceptions from wrapped agents are preserved and re-thrown unchanged. */ -class DBPAExecutor : public DataBatchProtectionAgentInterface { +class PARQUET_EXPORT DBPAExecutor : public DataBatchProtectionAgentInterface { public: /** * Constructor that takes ownership of the wrapped agent with configurable timeouts @@ -112,7 +113,7 @@ class DBPAExecutor : public DataBatchProtectionAgentInterface { /** * Exception thrown when a DBPA operation times out */ -class DBPAExecutorTimeoutException : public std::runtime_error { +class PARQUET_EXPORT DBPAExecutorTimeoutException : public std::runtime_error { public: explicit DBPAExecutorTimeoutException(const std::string& operation, int64_t timeout_milliseconds) diff --git a/cpp/src/parquet/encryption/external/dbpa_library_wrapper.cc b/cpp/src/parquet/encryption/external/dbpa_library_wrapper.cc index 068d77409ca..f0add7d35ef 100644 --- a/cpp/src/parquet/encryption/external/dbpa_library_wrapper.cc +++ b/cpp/src/parquet/encryption/external/dbpa_library_wrapper.cc @@ -30,7 +30,7 @@ namespace parquet::encryption::external { // Default implementation for handle closing function void DefaultSharedLibraryClosingFn(void* library_handle) { - auto status = arrow::internal::CloseDynamicLibrary(library_handle); + auto status = ::arrow::internal::CloseDynamicLibrary(library_handle); if (!status.ok()) { ARROW_LOG(WARNING) << "Error closing library: " << status.message(); } diff --git a/cpp/src/parquet/encryption/external/dbpa_library_wrapper.h b/cpp/src/parquet/encryption/external/dbpa_library_wrapper.h index a9aa930d13a..d158c835be0 100644 --- a/cpp/src/parquet/encryption/external/dbpa_library_wrapper.h +++ b/cpp/src/parquet/encryption/external/dbpa_library_wrapper.h @@ -23,6 +23,7 @@ #include #include +#include "parquet/platform.h" template using span = tcb::span; @@ -38,7 +39,7 @@ using dbps::external::Type; // Default implementation for shared library closing function // This is passed into the constructor of DBPALibraryWrapper, // and is used as the default function to close the shared library. -void DefaultSharedLibraryClosingFn(void* library_handle); +PARQUET_EXPORT void DefaultSharedLibraryClosingFn(void* library_handle); // Decorator/Wrapper class for the DataBatchProtectionAgentInterface // Its main purpose is to close the shared library when Arrow is about to destroy @@ -47,7 +48,7 @@ void DefaultSharedLibraryClosingFn(void* library_handle); // In the constructor we allow to pass a function that will be used to close the shared // library. This simplifies testing, as we can use a mock function to avoid actually // closing the shared library. -class DBPALibraryWrapper : public DataBatchProtectionAgentInterface { +class PARQUET_EXPORT DBPALibraryWrapper : public DataBatchProtectionAgentInterface { private: std::unique_ptr wrapped_agent_; void* library_handle_; diff --git a/cpp/src/parquet/encryption/external/loadable_encryptor_utils.cc b/cpp/src/parquet/encryption/external/loadable_encryptor_utils.cc index d2a3ef62619..17051b54315 100644 --- a/cpp/src/parquet/encryption/external/loadable_encryptor_utils.cc +++ b/cpp/src/parquet/encryption/external/loadable_encryptor_utils.cc @@ -39,11 +39,12 @@ typedef DataBatchProtectionAgentInterface* (*create_encryptor_t)(); std::unique_ptr LoadableEncryptorUtils::CreateInstance( void* library_handle) { - auto symbol_result = arrow::internal::GetSymbol(library_handle, "create_new_instance"); + auto symbol_result = + ::arrow::internal::GetSymbol(library_handle, "create_new_instance"); if (!symbol_result.ok()) { ARROW_LOG(ERROR) << "Cannot load symbol 'create_new_instance()': " << symbol_result.status().message(); - auto status = arrow::internal::CloseDynamicLibrary(library_handle); + auto status = ::arrow::internal::CloseDynamicLibrary(library_handle); throw std::runtime_error("Failed to load symbol 'create_new_instance()': " + symbol_result.status().message()); @@ -60,7 +61,7 @@ std::unique_ptr LoadableEncryptorUtils::Creat if (instance == nullptr) { ARROW_LOG(ERROR) << "Cannot create instance of DataBatchProtectionAgentInterface"; - auto status = arrow::internal::CloseDynamicLibrary(library_handle); + auto status = ::arrow::internal::CloseDynamicLibrary(library_handle); throw std::runtime_error( "Failed to create instance of DataBatchProtectionAgentInterface"); } @@ -77,7 +78,8 @@ LoadableEncryptorUtils::LoadFromLibrary(const std::string& library_path) { "LoadableEncryptorUtils::LoadFromLibrary: No library path provided"); } - auto library_handle_result = arrow::internal::LoadDynamicLibrary(library_path.c_str()); + auto library_handle_result = + ::arrow::internal::LoadDynamicLibrary(library_path.c_str()); if (!library_handle_result.ok()) { throw std::runtime_error("Failed to load library: " + library_handle_result.status().message()); diff --git a/cpp/src/parquet/encryption/external_dbpa_encryption.cc b/cpp/src/parquet/encryption/external_dbpa_encryption.cc index 513020f00da..3494019913a 100644 --- a/cpp/src/parquet/encryption/external_dbpa_encryption.cc +++ b/cpp/src/parquet/encryption/external_dbpa_encryption.cc @@ -435,7 +435,7 @@ ExternalDBPAEncryptorAdapter* ExternalDBPAEncryptorAdapterFactory::GetEncryptor( auto key_metadata = KeyMetadata::Parse(column_encryption_properties->key_metadata()); key_id = key_metadata.key_material().master_key_id(); - } catch (const ParquetException& e) { + } catch (const ParquetException&) { // It is possible for the key metadata to only contain the key id itself, so if // it cannot be parsed as valid JSON, send the key id as string for the ExternalDBPA // to process. @@ -663,7 +663,7 @@ std::unique_ptr ExternalDBPADecryptorAdapterFactory::GetDecr try { auto key_metadata = KeyMetadata::Parse(crypto_metadata->key_metadata()); key_id = key_metadata.key_material().master_key_id(); - } catch (const ParquetException& e) { + } catch (const ParquetException&) { // It is possible for the key metadata to only contain the key id itself, so if // it cannot be parsed as valid JSON, send the key id as string for the ExternalDBPA // to process. diff --git a/cpp/src/parquet/encryption/external_dbpa_encryption.h b/cpp/src/parquet/encryption/external_dbpa_encryption.h index 23832c6627e..9d66a721b41 100644 --- a/cpp/src/parquet/encryption/external_dbpa_encryption.h +++ b/cpp/src/parquet/encryption/external_dbpa_encryption.h @@ -28,6 +28,7 @@ #include "parquet/encryption/encoding_properties.h" #include "parquet/encryption/encryptor_interface.h" #include "parquet/metadata.h" +#include "parquet/platform.h" #include "parquet/types.h" using dbps::external::DataBatchProtectionAgentInterface; @@ -35,7 +36,7 @@ using dbps::external::DataBatchProtectionAgentInterface; namespace parquet::encryption { /// Call an external Data Batch Protection Agent (DBPA) to encrypt data. -class ExternalDBPAEncryptorAdapter : public EncryptorInterface { +class PARQUET_EXPORT ExternalDBPAEncryptorAdapter : public EncryptorInterface { public: static std::unique_ptr Make( ParquetCipher::type algorithm, std::string column_name, std::string key_id, @@ -115,7 +116,7 @@ class ExternalDBPAEncryptorAdapter : public EncryptorInterface { }; // Utilities for External DBPA adapters -class ExternalDBPAUtils { +class PARQUET_EXPORT ExternalDBPAUtils { public: // Convert Arrow KeyValueMetadata to a std::map. // Returns std::nullopt if the input is null or contains no pairs. @@ -126,6 +127,7 @@ class ExternalDBPAUtils { // Update encryptor-level metadata accumulator based on encoding attributes and // EncryptionResult-provided metadata. If no metadata is available or page_type is // unsupported/absent, function performs no-op. +PARQUET_EXPORT void UpdateEncryptorMetadata( std::map>& metadata_by_module, const EncodingProperties& encoding_properties, @@ -133,7 +135,7 @@ void UpdateEncryptorMetadata( /// Factory for ExternalDBPAEncryptorAdapter instances. The cache exists while the write /// operation is open, and is used to guarantee the lifetime of the encryptor. -class ExternalDBPAEncryptorAdapterFactory { +class PARQUET_EXPORT ExternalDBPAEncryptorAdapterFactory { public: ExternalDBPAEncryptorAdapter* GetEncryptor( ParquetCipher::type algorithm, @@ -146,7 +148,7 @@ class ExternalDBPAEncryptorAdapterFactory { /// Call an external Data Batch Protection Agent (DBPA) to decrypt data. /// connection configuration provided. -class ExternalDBPADecryptorAdapter : public DecryptorInterface { +class PARQUET_EXPORT ExternalDBPADecryptorAdapter : public DecryptorInterface { public: static std::unique_ptr Make( ParquetCipher::type algorithm, std::string column_name, std::string key_id, @@ -225,7 +227,7 @@ class ExternalDBPADecryptorAdapter : public DecryptorInterface { }; /// Factory for ExternalDBPADecryptorAdapter instances. No cache exists for decryptors. -class ExternalDBPADecryptorAdapterFactory { +class PARQUET_EXPORT ExternalDBPADecryptorAdapterFactory { public: std::unique_ptr GetDecryptor( ParquetCipher::type algorithm, const ColumnCryptoMetaData* crypto_metadata, diff --git a/cpp/src/parquet/types.h b/cpp/src/parquet/types.h index 1fd97165533..f3b1b5d7f89 100644 --- a/cpp/src/parquet/types.h +++ b/cpp/src/parquet/types.h @@ -574,6 +574,7 @@ struct ParquetCipher { /// Check whether a requested encryption algorithm is supported by the Parquet /// library. Used in the crypto factory to validate the requested encryption /// algorithm is available. +PARQUET_EXPORT bool IsParquetCipherSupported(ParquetCipher::type cipher); struct AadMetadata {