Skip to content

Commit

Permalink
Delete all input and output files on submission delete
Browse files Browse the repository at this point in the history
  • Loading branch information
evanjt committed Nov 4, 2024
1 parent 06570b5 commit 876b6c8
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 26 deletions.
8 changes: 4 additions & 4 deletions src/external/s3/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use serde::Serialize;
use utoipa::ToSchema;

#[derive(ToSchema, Serialize, FromQueryResult, Debug)]
pub struct OutputObject {
key: String,
last_modified: DateTime<Utc>,
size_bytes: i64,
pub(crate) struct OutputObject {
pub(super) key: String,
pub(super) last_modified: DateTime<Utc>,
pub(super) size_bytes: i64,
}

impl From<aws_sdk_s3::types::Object> for OutputObject {
Expand Down
24 changes: 19 additions & 5 deletions src/external/s3/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use aws_config::BehaviorVersion;
use aws_sdk_s3::config::Credentials;
use aws_sdk_s3::{config::Region, Client as S3Client};
use std::sync::Arc;
use uuid::Uuid;

pub async fn get_client(config: &Config) -> Arc<S3Client> {
let region = Region::new("us-east-1");
Expand All @@ -25,12 +24,12 @@ pub async fn get_client(config: &Config) -> Arc<S3Client> {
Arc::new(S3Client::new(&shared_config))
}

pub async fn get_outputs_from_id(
client: Arc<S3Client>,
id: Uuid,
pub async fn get_outputs_from_submission(
client: &Arc<S3Client>,
obj: &crate::submissions::db::Model,
) -> Result<Vec<super::models::OutputObject>, Box<dyn std::error::Error>> {
let config = crate::config::Config::from_env();
let prefix = format!("{}/outputs/{}/", config.s3_prefix, id);
let prefix = format!("{}/outputs/{}/", config.s3_prefix, obj.id);
let mut outputs: Vec<super::models::OutputObject> = vec![];
let list = client
.list_objects()
Expand All @@ -47,3 +46,18 @@ pub async fn get_outputs_from_id(

Ok(outputs)
}

pub async fn delete_output_object(
client: &Arc<S3Client>,
object: super::models::OutputObject,
) -> Result<(), Box<dyn std::error::Error>> {
let config = crate::config::Config::from_env();
client
.delete_object()
.bucket(config.s3_bucket)
.key(object.key)
.send()
.await?;

Ok(())
}
5 changes: 2 additions & 3 deletions src/submissions/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl From<super::db::Model> for Submission {
impl
From<(
super::db::Model,
Option<Vec<crate::uploads::db::Model>>,
Vec<crate::uploads::db::Model>,
// Vec<super::run_status::db::Model>,
Vec<crate::external::k8s::models::PodName>,
Vec<crate::external::s3::models::OutputObject>,
Expand All @@ -49,7 +49,7 @@ impl
fn from(
model_tuple: (
super::db::Model,
Option<Vec<crate::uploads::db::Model>>,
Vec<crate::uploads::db::Model>,
// Vec<super::run_status::db::Model>,
Vec<crate::external::k8s::models::PodName>,
Vec<crate::external::s3::models::OutputObject>,
Expand Down Expand Up @@ -80,7 +80,6 @@ impl
created_on: submission.created_on,
last_updated: submission.last_updated,
associations: uploads
.unwrap_or_default()
.into_iter()
.map(|association| association.into())
.collect(),
Expand Down
20 changes: 20 additions & 0 deletions src/submissions/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,23 @@

// Ok(())
// }

use crate::uploads::db;
use anyhow::{anyhow, Error, Result};
use sea_orm::{DatabaseConnection, ModelTrait};

pub(super) async fn get_input_objects(
submission_obj: super::db::Model,
db: &DatabaseConnection,
) -> Result<Vec<db::Model>, Error> {
// Get the related objects to the submission according to the association
match submission_obj
.find_related(crate::uploads::db::Entity)
.all(db)
.await
{
// Return all or none. If any fail, return an error
Ok(uploads) => Ok(uploads),
Err(_) => Err(anyhow!("Failed to fetch uploads")),
}
}
41 changes: 27 additions & 14 deletions src/submissions/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,12 @@ pub async fn get_one(
Ok(obj) => obj.unwrap(),
_ => return Err((StatusCode::NOT_FOUND, Json("Not Found".to_string()))),
};
let outputs = crate::external::s3::services::get_outputs_from_id(s3, obj.id)
let outputs = crate::external::s3::services::get_outputs_from_submission(&s3, &obj)
.await
.unwrap();
let uploads = super::services::get_input_objects(obj.clone(), &db)
.await
.unwrap();
let uploads = match obj.find_related(crate::uploads::db::Entity).all(&db).await {
// Return all or none. If any fail, return an error
Ok(uploads) => Some(uploads),
Err(_) => {
return Err((
StatusCode::INTERNAL_SERVER_ERROR,
Json("Server error".to_string()),
))
}
};

// let status: Vec<super::run_status::db::Model> = obj
// .find_related(super::run_status::db::Entity)
Expand Down Expand Up @@ -235,7 +228,7 @@ pub async fn update_one(
responses((status = NO_CONTENT))
)]
pub async fn delete_one(
State((db, _s3)): State<(DatabaseConnection, Arc<S3Client>)>,
State((db, s3)): State<(DatabaseConnection, Arc<S3Client>)>,
Path(id): Path<Uuid>,
) -> StatusCode {
let obj = super::db::Entity::find_by_id(id)
Expand All @@ -244,6 +237,28 @@ pub async fn delete_one(
.unwrap()
.expect("Failed to find object");

// Delete all input objects
let uploads = super::services::get_input_objects(obj.clone(), &db)
.await
.expect("Failed to fetch input objects");

for upload in uploads {
crate::uploads::services::delete_object(&db, &s3, upload.id)
.await
.expect("Failed to delete input object");
}

// Delete all outputs
let outputs = crate::external::s3::services::get_outputs_from_submission(&s3, &obj)
.await
.expect("Failed to fetch output objects");

for output in outputs {
crate::external::s3::services::delete_output_object(&s3, output)
.await
.expect("Failed to delete output object");
}

let res: DeleteResult = obj.delete(&db).await.expect("Failed to delete object");

if res.rows_affected == 0 {
Expand Down Expand Up @@ -406,8 +421,6 @@ pub async fn download_file(
config.s3_prefix, claims.submission_id, claims.filename
);

println!("Key: {}", key);
println!("Token data: {:?}", claims);
let object = s3
.get_object()
.bucket(config.s3_bucket)
Expand Down

0 comments on commit 876b6c8

Please sign in to comment.