This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c5c34b6f Add get_config_value to AWS/Azure/GCP Builders (#4035)
6c5c34b6f is described below

commit 6c5c34b6fb3d2fa700856077b6ea2555ff5fb598
Author: r.4ntix <[email protected]>
AuthorDate: Mon Apr 10 23:13:00 2023 +0800

    Add get_config_value to AWS/Azure/GCP Builders (#4035)
    
    * minor: make struct fields of Builders(S3/Azure/GCS) to pub
    
    * minor: use `get_config_value` method instead of public fields
    
    * fix clippy error
---
 object_store/src/aws/checksum.rs |  10 +++-
 object_store/src/aws/mod.rs      | 103 +++++++++++++++++++++++++++++++++++++++
 object_store/src/azure/mod.rs    |  81 ++++++++++++++++++++++++++++++
 object_store/src/gcp/mod.rs      |  56 +++++++++++++++++++++
 4 files changed, 249 insertions(+), 1 deletion(-)

diff --git a/object_store/src/aws/checksum.rs b/object_store/src/aws/checksum.rs
index ae35f0612..c787c28a8 100644
--- a/object_store/src/aws/checksum.rs
+++ b/object_store/src/aws/checksum.rs
@@ -39,11 +39,19 @@ impl Checksum {
     }
 }
 
+impl std::fmt::Display for Checksum {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match &self {
+            Self::SHA256 => write!(f, "sha256"),
+        }
+    }
+}
+
 impl TryFrom<&String> for Checksum {
     type Error = ();
 
     fn try_from(value: &String) -> Result<Self, Self::Error> {
-        match value.as_str() {
+        match value.to_lowercase().as_str() {
             "sha256" => Ok(Self::SHA256),
             _ => Err(()),
         }
diff --git a/object_store/src/aws/mod.rs b/object_store/src/aws/mod.rs
index f88960b4b..de62360d0 100644
--- a/object_store/src/aws/mod.rs
+++ b/object_store/src/aws/mod.rs
@@ -400,20 +400,35 @@ impl CloudMultiPartUploadImpl for S3MultiPartUpload {
 /// ```
 #[derive(Debug, Default, Clone)]
 pub struct AmazonS3Builder {
+    /// Access key id
     access_key_id: Option<String>,
+    /// Secret access_key
     secret_access_key: Option<String>,
+    /// Region
     region: Option<String>,
+    /// Bucket name
     bucket_name: Option<String>,
+    /// Endpoint for communicating with AWS S3
     endpoint: Option<String>,
+    /// Token to use for requests
     token: Option<String>,
+    /// Url
     url: Option<String>,
+    /// Retry config
     retry_config: RetryConfig,
+    /// When set to true, fallback to IMDSv1
     imdsv1_fallback: bool,
+    /// When set to true, virtual hosted style request has to be used
     virtual_hosted_style_request: bool,
+    /// When set to true, unsigned payload option has to be used
     unsigned_payload: bool,
+    /// Checksum algorithm which has to be used for object integrity check 
during upload
     checksum_algorithm: Option<Checksum>,
+    /// Metadata endpoint, see 
<https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html>
     metadata_endpoint: Option<String>,
+    /// Profile name, see 
<https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html>
     profile: Option<String>,
+    /// Client options
     client_options: ClientOptions,
 }
 
@@ -751,6 +766,38 @@ impl AmazonS3Builder {
         Ok(self)
     }
 
+    /// Get config value via a [`AmazonS3ConfigKey`].
+    ///
+    /// # Example
+    /// ```
+    /// use object_store::aws::{AmazonS3Builder, AmazonS3ConfigKey};
+    ///
+    /// let builder = AmazonS3Builder::from_env()
+    ///     .with_bucket_name("foo");
+    /// let bucket_name = 
builder.get_config_value(&AmazonS3ConfigKey::Bucket).unwrap_or_default();
+    /// assert_eq!("foo", &bucket_name);
+    /// ```
+    pub fn get_config_value(&self, key: &AmazonS3ConfigKey) -> Option<String> {
+        match key {
+            AmazonS3ConfigKey::AccessKeyId => self.access_key_id.clone(),
+            AmazonS3ConfigKey::SecretAccessKey => 
self.secret_access_key.clone(),
+            AmazonS3ConfigKey::Region | AmazonS3ConfigKey::DefaultRegion => {
+                self.region.clone()
+            }
+            AmazonS3ConfigKey::Bucket => self.bucket_name.clone(),
+            AmazonS3ConfigKey::Endpoint => self.endpoint.clone(),
+            AmazonS3ConfigKey::Token => self.token.clone(),
+            AmazonS3ConfigKey::ImdsV1Fallback => 
Some(self.imdsv1_fallback.to_string()),
+            AmazonS3ConfigKey::VirtualHostedStyleRequest => {
+                Some(self.virtual_hosted_style_request.to_string())
+            }
+            AmazonS3ConfigKey::MetadataEndpoint => 
self.metadata_endpoint.clone(),
+            AmazonS3ConfigKey::Profile => self.profile.clone(),
+            AmazonS3ConfigKey::UnsignedPayload => 
Some(self.unsigned_payload.to_string()),
+            AmazonS3ConfigKey::Checksum => self.checksum_algorithm.map(|v| 
v.to_string()),
+        }
+    }
+
     /// Sets properties on this builder based on a URL
     ///
     /// This is a separate member function to allow fallible computation to
@@ -1272,6 +1319,62 @@ mod tests {
         assert!(builder.unsigned_payload);
     }
 
+    #[test]
+    fn s3_test_config_get_value() {
+        let aws_access_key_id = "object_store:fake_access_key_id".to_string();
+        let aws_secret_access_key = "object_store:fake_secret_key".to_string();
+        let aws_default_region = 
"object_store:fake_default_region".to_string();
+        let aws_endpoint = "object_store:fake_endpoint".to_string();
+        let aws_session_token = "object_store:fake_session_token".to_string();
+        let options = HashMap::from([
+            (AmazonS3ConfigKey::AccessKeyId, aws_access_key_id.clone()),
+            (
+                AmazonS3ConfigKey::SecretAccessKey,
+                aws_secret_access_key.clone(),
+            ),
+            (AmazonS3ConfigKey::DefaultRegion, aws_default_region.clone()),
+            (AmazonS3ConfigKey::Endpoint, aws_endpoint.clone()),
+            (AmazonS3ConfigKey::Token, aws_session_token.clone()),
+            (AmazonS3ConfigKey::UnsignedPayload, "true".to_string()),
+        ]);
+
+        let builder = 
AmazonS3Builder::new().try_with_options(&options).unwrap();
+        assert_eq!(
+            builder
+                .get_config_value(&AmazonS3ConfigKey::AccessKeyId)
+                .unwrap(),
+            aws_access_key_id
+        );
+        assert_eq!(
+            builder
+                .get_config_value(&AmazonS3ConfigKey::SecretAccessKey)
+                .unwrap(),
+            aws_secret_access_key
+        );
+        assert_eq!(
+            builder
+                .get_config_value(&AmazonS3ConfigKey::DefaultRegion)
+                .unwrap(),
+            aws_default_region
+        );
+        assert_eq!(
+            builder
+                .get_config_value(&AmazonS3ConfigKey::Endpoint)
+                .unwrap(),
+            aws_endpoint
+        );
+        assert_eq!(
+            builder.get_config_value(&AmazonS3ConfigKey::Token).unwrap(),
+            aws_session_token
+        );
+        assert_eq!(
+            builder
+                .get_config_value(&AmazonS3ConfigKey::UnsignedPayload)
+                .unwrap(),
+            "true"
+        );
+    }
+
     #[test]
     fn s3_test_config_fallible_options() {
         let aws_access_key_id = "object_store:fake_access_key_id".to_string();
diff --git a/object_store/src/azure/mod.rs b/object_store/src/azure/mod.rs
index c2e72f214..11350a202 100644
--- a/object_store/src/azure/mod.rs
+++ b/object_store/src/azure/mod.rs
@@ -394,24 +394,43 @@ impl CloudMultiPartUploadImpl for AzureMultiPartUpload {
 /// ```
 #[derive(Default, Clone)]
 pub struct MicrosoftAzureBuilder {
+    /// Account name
     account_name: Option<String>,
+    /// Access key
     access_key: Option<String>,
+    /// Container name
     container_name: Option<String>,
+    /// Bearer token
     bearer_token: Option<String>,
+    /// Client id
     client_id: Option<String>,
+    /// Client secret
     client_secret: Option<String>,
+    /// Tenant id
     tenant_id: Option<String>,
+    /// Query pairs for shared access signature authorization
     sas_query_pairs: Option<Vec<(String, String)>>,
+    /// Shared access signature
     sas_key: Option<String>,
+    /// Authority host
     authority_host: Option<String>,
+    /// Url
     url: Option<String>,
+    /// When set to true, azurite storage emulator has to be used
     use_emulator: bool,
+    /// Msi endpoint for acquiring managed identity token
     msi_endpoint: Option<String>,
+    /// Object id for use with managed identity authentication
     object_id: Option<String>,
+    /// Msi resource id for use with managed identity authentication
     msi_resource_id: Option<String>,
+    /// File containing token for Azure AD workload identity federation
     federated_token_file: Option<String>,
+    /// When set to true, azure cli has to be used for acquiring access token
     use_azure_cli: bool,
+    /// Retry config
     retry_config: RetryConfig,
+    /// Client options
     client_options: ClientOptions,
 }
 
@@ -747,6 +766,35 @@ impl MicrosoftAzureBuilder {
         Ok(self)
     }
 
+    /// Get config value via a [`AzureConfigKey`].
+    ///
+    /// # Example
+    /// ```
+    /// use object_store::azure::{MicrosoftAzureBuilder, AzureConfigKey};
+    ///
+    /// let builder = MicrosoftAzureBuilder::from_env()
+    ///     .with_account("foo");
+    /// let account_name = 
builder.get_config_value(&AzureConfigKey::AccountName).unwrap_or_default();
+    /// assert_eq!("foo", &account_name);
+    /// ```
+    pub fn get_config_value(&self, key: &AzureConfigKey) -> Option<String> {
+        match key {
+            AzureConfigKey::AccountName => self.account_name.clone(),
+            AzureConfigKey::AccessKey => self.access_key.clone(),
+            AzureConfigKey::ClientId => self.client_id.clone(),
+            AzureConfigKey::ClientSecret => self.client_secret.clone(),
+            AzureConfigKey::AuthorityId => self.tenant_id.clone(),
+            AzureConfigKey::SasKey => self.sas_key.clone(),
+            AzureConfigKey::Token => self.bearer_token.clone(),
+            AzureConfigKey::UseEmulator => Some(self.use_emulator.to_string()),
+            AzureConfigKey::MsiEndpoint => self.msi_endpoint.clone(),
+            AzureConfigKey::ObjectId => self.object_id.clone(),
+            AzureConfigKey::MsiResourceId => self.msi_resource_id.clone(),
+            AzureConfigKey::FederatedTokenFile => 
self.federated_token_file.clone(),
+            AzureConfigKey::UseAzureCli => 
Some(self.use_azure_cli.to_string()),
+        }
+    }
+
     /// Sets properties on this builder based on a URL
     ///
     /// This is a separate member function to allow fallible computation to
@@ -1252,6 +1300,39 @@ mod tests {
         assert_eq!(builder.bearer_token.unwrap(), azure_storage_token);
     }
 
+    #[test]
+    fn azure_test_config_get_value() {
+        let azure_client_id = "object_store:fake_access_key_id".to_string();
+        let azure_storage_account_name = 
"object_store:fake_secret_key".to_string();
+        let azure_storage_token = 
"object_store:fake_default_region".to_string();
+        let options = HashMap::from([
+            (AzureConfigKey::ClientId, azure_client_id.clone()),
+            (
+                AzureConfigKey::AccountName,
+                azure_storage_account_name.clone(),
+            ),
+            (AzureConfigKey::Token, azure_storage_token.clone()),
+        ]);
+
+        let builder = MicrosoftAzureBuilder::new()
+            .try_with_options(&options)
+            .unwrap();
+        assert_eq!(
+            builder.get_config_value(&AzureConfigKey::ClientId).unwrap(),
+            azure_client_id
+        );
+        assert_eq!(
+            builder
+                .get_config_value(&AzureConfigKey::AccountName)
+                .unwrap(),
+            azure_storage_account_name
+        );
+        assert_eq!(
+            builder.get_config_value(&AzureConfigKey::Token).unwrap(),
+            azure_storage_token
+        );
+    }
+
     #[test]
     fn azure_test_config_fallible_options() {
         let azure_client_id = "object_store:fake_access_key_id".to_string();
diff --git a/object_store/src/gcp/mod.rs b/object_store/src/gcp/mod.rs
index 5247693e6..a6cf66022 100644
--- a/object_store/src/gcp/mod.rs
+++ b/object_store/src/gcp/mod.rs
@@ -768,12 +768,19 @@ impl ObjectStore for GoogleCloudStorage {
 /// ```
 #[derive(Debug, Clone)]
 pub struct GoogleCloudStorageBuilder {
+    /// Bucket name
     bucket_name: Option<String>,
+    /// Url
     url: Option<String>,
+    /// Path to the service account file
     service_account_path: Option<String>,
+    /// The serialized service account key
     service_account_key: Option<String>,
+    /// Path to the application credentials file.
     application_credentials_path: Option<String>,
+    /// Retry config
     retry_config: RetryConfig,
+    /// Client options
     client_options: ClientOptions,
 }
 
@@ -983,6 +990,28 @@ impl GoogleCloudStorageBuilder {
         Ok(self)
     }
 
+    /// Get config value via a [`GoogleConfigKey`].
+    ///
+    /// # Example
+    /// ```
+    /// use object_store::gcp::{GoogleCloudStorageBuilder, GoogleConfigKey};
+    ///
+    /// let builder = GoogleCloudStorageBuilder::from_env()
+    ///     .with_service_account_key("foo");
+    /// let service_account_key = 
builder.get_config_value(&GoogleConfigKey::ServiceAccountKey).unwrap_or_default();
+    /// assert_eq!("foo", &service_account_key);
+    /// ```
+    pub fn get_config_value(&self, key: &GoogleConfigKey) -> Option<String> {
+        match key {
+            GoogleConfigKey::ServiceAccount => 
self.service_account_path.clone(),
+            GoogleConfigKey::ServiceAccountKey => 
self.service_account_key.clone(),
+            GoogleConfigKey::Bucket => self.bucket_name.clone(),
+            GoogleConfigKey::ApplicationCredentials => {
+                self.application_credentials_path.clone()
+            }
+        }
+    }
+
     /// Sets properties on this builder based on a URL
     ///
     /// This is a separate member function to allow fallible computation to
@@ -1452,6 +1481,33 @@ mod test {
         assert_eq!(builder.bucket_name.unwrap(), google_bucket_name.as_str());
     }
 
+    #[test]
+    fn gcs_test_config_get_value() {
+        let google_service_account = 
"object_store:fake_service_account".to_string();
+        let google_bucket_name = "object_store:fake_bucket".to_string();
+        let options = HashMap::from([
+            (
+                GoogleConfigKey::ServiceAccount,
+                google_service_account.clone(),
+            ),
+            (GoogleConfigKey::Bucket, google_bucket_name.clone()),
+        ]);
+
+        let builder = GoogleCloudStorageBuilder::new()
+            .try_with_options(&options)
+            .unwrap();
+        assert_eq!(
+            builder
+                .get_config_value(&GoogleConfigKey::ServiceAccount)
+                .unwrap(),
+            google_service_account
+        );
+        assert_eq!(
+            builder.get_config_value(&GoogleConfigKey::Bucket).unwrap(),
+            google_bucket_name
+        );
+    }
+
     #[test]
     fn gcs_test_config_fallible_options() {
         let google_service_account = 
"object_store:fake_service_account".to_string();

Reply via email to