openmina_node_common/service/archive/
gcp.rs

1use gcs::http::objects::upload as gcs_upload;
2use google_cloud_auth::credentials::CredentialsFile as GcpCredentialsFile;
3use google_cloud_storage as gcs;
4
5use super::Error;
6use std::env;
7
8pub(crate) struct ArchiveGCPClient {
9    client: gcs::client::Client,
10    bucket_name: String,
11}
12
13impl ArchiveGCPClient {
14    pub async fn new() -> Result<Self, Error> {
15        let get_env_var = |var: &str| -> Result<String, Error> {
16            env::var(var).map_err(|_| Error::EnvironmentVariableNotSet(var.to_string()))
17        };
18
19        let cred_file = get_env_var("GCP_CREDENTIALS_JSON")?;
20        let bucket_name = get_env_var("GCP_BUCKET_NAME")?;
21
22        let credentials = GcpCredentialsFile::new_from_file(cred_file)
23            .await
24            .map_err(|e| Error::UploadError(format!("GCP credentials error: {}", e)))?;
25
26        let config = gcs::client::ClientConfig::default()
27            .with_credentials(credentials)
28            .await
29            .map_err(|e| Error::UploadError(format!("GCP config error: {}", e)))?;
30
31        Ok(ArchiveGCPClient {
32            client: gcs::client::Client::new(config),
33            bucket_name,
34        })
35    }
36
37    pub async fn upload_block(&self, key: &str, data: &[u8]) -> Result<(), Error> {
38        let upload_type = gcs_upload::UploadType::Simple(gcs_upload::Media::new(key.to_string()));
39
40        self.client
41            .upload_object(
42                &gcs_upload::UploadObjectRequest {
43                    bucket: self.bucket_name.clone(),
44                    ..Default::default()
45                },
46                data.to_vec(),
47                &upload_type,
48            )
49            .await
50            .map_err(|e| Error::UploadError(format!("GCP upload failed: {}", e)))?;
51
52        Ok(())
53    }
54}