Skip to content

Commit 52e5b72

Browse files
committed
add list_namespaces
1 parent 81b4a9b commit 52e5b72

File tree

3 files changed

+66
-16
lines changed

3 files changed

+66
-16
lines changed

crates/catalog/s3tables/src/catalog.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,34 @@ use std::collections::HashMap;
22

33
use anyhow::anyhow;
44
use async_trait::async_trait;
5-
use aws_config::BehaviorVersion;
65
use iceberg::table::Table;
76
use iceberg::{
87
Catalog, Error, ErrorKind, Namespace, NamespaceIdent, Result, TableCommit, TableCreation,
98
TableIdent,
109
};
1110

11+
use crate::utils::create_sdk_config;
12+
13+
#[derive(Debug)]
14+
pub struct S3TablesCatalogConfig {
15+
table_bucket_arn: String,
16+
properties: HashMap<String, String>,
17+
}
18+
1219
/// S3Tables catalog implementation.
1320
#[derive(Debug)]
1421
pub struct S3TablesCatalog {
15-
table_bucket_arn: String,
16-
client: aws_sdk_s3tables::Client,
22+
config: S3TablesCatalogConfig,
23+
s3tables_client: aws_sdk_s3tables::Client,
1724
}
1825

1926
impl S3TablesCatalog {
20-
pub async fn new(table_bucket_arn: String) -> Self {
21-
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;
22-
let client = aws_sdk_s3tables::Client::new(&config);
27+
pub async fn new(config: S3TablesCatalogConfig) -> Self {
28+
let aws_config = create_sdk_config(&config.properties).await;
29+
let s3tables_client = aws_sdk_s3tables::Client::new(&aws_config);
2330
Self {
24-
table_bucket_arn,
25-
client,
31+
config,
32+
s3tables_client,
2633
}
2734
}
2835
}
@@ -34,21 +41,16 @@ impl Catalog for S3TablesCatalog {
3441
parent: Option<&NamespaceIdent>,
3542
) -> Result<Vec<NamespaceIdent>> {
3643
let mut req = self
37-
.client
44+
.s3tables_client
3845
.list_namespaces()
39-
.table_bucket_arn(self.table_bucket_arn.clone());
46+
.table_bucket_arn(self.config.table_bucket_arn.clone());
4047
if let Some(parent) = parent {
4148
req = req.prefix(parent.to_url_string());
4249
}
4350
let resp = req.send().await.map_err(from_aws_sdk_error)?;
4451
let mut result = Vec::new();
4552
for ns in resp.namespaces() {
46-
let ns_names = ns.namespace();
47-
result.extend(
48-
ns_names
49-
.into_iter()
50-
.map(|name| NamespaceIdent::new(name.to_string())),
51-
);
53+
result.push(NamespaceIdent::from_vec(ns.namespace().to_vec())?);
5254
}
5355
Ok(result)
5456
}

crates/catalog/s3tables/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@
2020
#![deny(missing_docs)]
2121

2222
mod catalog;
23+
mod utils;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::collections::HashMap;
2+
3+
use aws_config::{BehaviorVersion, Region, SdkConfig};
4+
use aws_sdk_s3tables::config::Credentials;
5+
6+
/// Property aws profile name
7+
pub const AWS_PROFILE_NAME: &str = "profile_name";
8+
/// Property aws region
9+
pub const AWS_REGION_NAME: &str = "region_name";
10+
/// Property aws access key
11+
pub const AWS_ACCESS_KEY_ID: &str = "aws_access_key_id";
12+
/// Property aws secret access key
13+
pub const AWS_SECRET_ACCESS_KEY: &str = "aws_secret_access_key";
14+
/// Property aws session token
15+
pub const AWS_SESSION_TOKEN: &str = "aws_session_token";
16+
17+
/// Creates an aws sdk configuration based on
18+
/// provided properties and an optional endpoint URL.
19+
pub(crate) async fn create_sdk_config(properties: &HashMap<String, String>) -> SdkConfig {
20+
let mut config = aws_config::defaults(BehaviorVersion::latest());
21+
22+
if properties.is_empty() {
23+
return config.load().await;
24+
}
25+
26+
if let (Some(access_key), Some(secret_key)) = (
27+
properties.get(AWS_ACCESS_KEY_ID),
28+
properties.get(AWS_SECRET_ACCESS_KEY),
29+
) {
30+
let session_token = properties.get(AWS_SESSION_TOKEN).cloned();
31+
let credentials_provider =
32+
Credentials::new(access_key, secret_key, session_token, None, "properties");
33+
34+
config = config.credentials_provider(credentials_provider)
35+
};
36+
37+
if let Some(profile_name) = properties.get(AWS_PROFILE_NAME) {
38+
config = config.profile_name(profile_name);
39+
}
40+
41+
if let Some(region_name) = properties.get(AWS_REGION_NAME) {
42+
let region = Region::new(region_name.clone());
43+
config = config.region(region);
44+
}
45+
46+
config.load().await
47+
}

0 commit comments

Comments
 (0)