Skip to content

Commit 1daa2ec

Browse files
committed
feat(api): add batch operation for artifacts, attachments and tasks
1 parent 00adc71 commit 1daa2ec

13 files changed

Lines changed: 1286 additions & 13 deletions

File tree

.pre-commit-config.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: cargo-fmt
5+
name: cargo fmt
6+
entry: cargo fmt --all
7+
language: system
8+
types: [rust]
9+
pass_filenames: false # This makes it a lot faster
10+
11+
- id: cargo-clippy
12+
name: cargo clippy
13+
language: system
14+
types: [rust]
15+
pass_filenames: false
16+
entry: cargo clippy --workspace -- -D warnings

netmito/src/api/groups.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ pub fn groups_router(st: InfraPool) -> Router<InfraPool> {
4343
"/{group_name}/download/attachments/list",
4444
post(batch_download_attachments_by_keys),
4545
)
46+
.route(
47+
"/{group_name}/delete/attachments",
48+
post(batch_delete_attachments_by_filter),
49+
)
50+
.route(
51+
"/{group_name}/delete/attachments/list",
52+
post(batch_delete_attachments_by_keys),
53+
)
4654
.route_layer(middleware::from_fn_with_state(
4755
st.clone(),
4856
user_auth_middleware,
@@ -273,3 +281,41 @@ pub async fn batch_download_attachments_by_keys(
273281
})?;
274282
Ok(Json(resp))
275283
}
284+
285+
pub async fn batch_delete_attachments_by_filter(
286+
Extension(u): Extension<AuthUser>,
287+
State(pool): State<InfraPool>,
288+
Path(group_name): Path<String>,
289+
Json(req): Json<AttachmentsDeleteByFilterReq>,
290+
) -> Result<Json<AttachmentsDeleteByFilterResp>, ApiError> {
291+
let resp = service::s3::batch_delete_attachments_by_filter(u.id, &pool, group_name, req)
292+
.await
293+
.map_err(|e| match e {
294+
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
295+
crate::error::Error::ApiError(e) => e,
296+
_ => {
297+
tracing::error!("{}", e);
298+
ApiError::InternalServerError
299+
}
300+
})?;
301+
Ok(Json(resp))
302+
}
303+
304+
pub async fn batch_delete_attachments_by_keys(
305+
Extension(u): Extension<AuthUser>,
306+
State(pool): State<InfraPool>,
307+
Path(group_name): Path<String>,
308+
Json(req): Json<AttachmentsDeleteByKeysReq>,
309+
) -> Result<Json<AttachmentsDeleteByKeysResp>, ApiError> {
310+
let resp = service::s3::batch_delete_attachments_by_keys(u.id, &pool, group_name, req)
311+
.await
312+
.map_err(|e| match e {
313+
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
314+
crate::error::Error::ApiError(e) => e,
315+
_ => {
316+
tracing::error!("{}", e);
317+
ApiError::InternalServerError
318+
}
319+
})?;
320+
Ok(Json(resp))
321+
}

netmito/src/api/tasks.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ pub fn tasks_router(st: InfraPool) -> Router<InfraPool> {
4242
"/download/artifacts/list",
4343
post(batch_download_artifacts_by_uuids),
4444
)
45+
.route("/delete/artifacts", post(batch_delete_artifacts_by_filter))
46+
.route(
47+
"/delete/artifacts/list",
48+
post(batch_delete_artifacts_by_uuids),
49+
)
50+
.route("/submit", post(batch_submit_tasks))
4551
.route_layer(middleware::from_fn_with_state(
4652
st.clone(),
4753
user_auth_middleware,
@@ -286,3 +292,57 @@ pub async fn batch_download_artifacts_by_uuids(
286292
})?;
287293
Ok(Json(resp))
288294
}
295+
296+
pub async fn batch_delete_artifacts_by_filter(
297+
Extension(u): Extension<AuthUser>,
298+
State(pool): State<InfraPool>,
299+
Json(req): Json<ArtifactsDeleteByFilterReq>,
300+
) -> Result<Json<ArtifactsDeleteByFilterResp>, ApiError> {
301+
let resp = service::s3::batch_delete_artifacts_by_filter(u.id, &pool, req)
302+
.await
303+
.map_err(|e| match e {
304+
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
305+
crate::error::Error::ApiError(e) => e,
306+
_ => {
307+
tracing::error!("{}", e);
308+
ApiError::InternalServerError
309+
}
310+
})?;
311+
Ok(Json(resp))
312+
}
313+
314+
pub async fn batch_delete_artifacts_by_uuids(
315+
Extension(u): Extension<AuthUser>,
316+
State(pool): State<InfraPool>,
317+
Json(req): Json<ArtifactsDeleteByUuidsReq>,
318+
) -> Result<Json<ArtifactsDeleteByUuidsResp>, ApiError> {
319+
let resp = service::s3::batch_delete_artifacts_by_uuids(u.id, &pool, req)
320+
.await
321+
.map_err(|e| match e {
322+
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
323+
crate::error::Error::ApiError(e) => e,
324+
_ => {
325+
tracing::error!("{}", e);
326+
ApiError::InternalServerError
327+
}
328+
})?;
329+
Ok(Json(resp))
330+
}
331+
332+
pub async fn batch_submit_tasks(
333+
Extension(u): Extension<AuthUser>,
334+
State(pool): State<InfraPool>,
335+
Json(req): Json<TasksSubmitReq>,
336+
) -> Result<Json<TasksSubmitResp>, ApiError> {
337+
let resp = service::task::user_batch_submit_tasks(&pool, u.id, req)
338+
.await
339+
.map_err(|e| match e {
340+
crate::error::Error::AuthError(err) => ApiError::AuthError(err),
341+
crate::error::Error::ApiError(e) => e,
342+
_ => {
343+
tracing::error!("{}", e);
344+
ApiError::InternalServerError
345+
}
346+
})?;
347+
Ok(Json(resp))
348+
}

netmito/src/client/http.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,130 @@ impl MitoHttpClient {
11621162
}
11631163
}
11641164

1165+
pub async fn batch_delete_artifacts_by_filter(
1166+
&mut self,
1167+
req: ArtifactsDeleteByFilterReq,
1168+
) -> crate::error::Result<ArtifactsDeleteByFilterResp> {
1169+
self.url.set_path("tasks/delete/artifacts");
1170+
let resp = self
1171+
.http_client
1172+
.post(self.url.as_str())
1173+
.bearer_auth(&self.credential)
1174+
.json(&req)
1175+
.send()
1176+
.await
1177+
.map_err(map_reqwest_err)?;
1178+
if resp.status().is_success() {
1179+
let resp = resp
1180+
.json::<ArtifactsDeleteByFilterResp>()
1181+
.await
1182+
.map_err(RequestError::from)?;
1183+
Ok(resp)
1184+
} else {
1185+
Err(get_error_from_resp(resp).await.into())
1186+
}
1187+
}
1188+
1189+
pub async fn batch_delete_artifacts_by_list(
1190+
&mut self,
1191+
req: ArtifactsDeleteByUuidsReq,
1192+
) -> crate::error::Result<ArtifactsDeleteByUuidsResp> {
1193+
self.url.set_path("tasks/delete/artifacts/list");
1194+
let resp = self
1195+
.http_client
1196+
.post(self.url.as_str())
1197+
.bearer_auth(&self.credential)
1198+
.json(&req)
1199+
.send()
1200+
.await
1201+
.map_err(map_reqwest_err)?;
1202+
if resp.status().is_success() {
1203+
let resp = resp
1204+
.json::<ArtifactsDeleteByUuidsResp>()
1205+
.await
1206+
.map_err(RequestError::from)?;
1207+
Ok(resp)
1208+
} else {
1209+
Err(get_error_from_resp(resp).await.into())
1210+
}
1211+
}
1212+
1213+
pub async fn batch_delete_attachments_by_filter(
1214+
&mut self,
1215+
group_name: &str,
1216+
req: AttachmentsDeleteByFilterReq,
1217+
) -> crate::error::Result<AttachmentsDeleteByFilterResp> {
1218+
self.url
1219+
.set_path(&format!("groups/{group_name}/delete/attachments"));
1220+
let resp = self
1221+
.http_client
1222+
.post(self.url.as_str())
1223+
.bearer_auth(&self.credential)
1224+
.json(&req)
1225+
.send()
1226+
.await
1227+
.map_err(map_reqwest_err)?;
1228+
if resp.status().is_success() {
1229+
let resp = resp
1230+
.json::<AttachmentsDeleteByFilterResp>()
1231+
.await
1232+
.map_err(RequestError::from)?;
1233+
Ok(resp)
1234+
} else {
1235+
Err(get_error_from_resp(resp).await.into())
1236+
}
1237+
}
1238+
1239+
pub async fn batch_delete_attachments_by_list(
1240+
&mut self,
1241+
group_name: &str,
1242+
req: AttachmentsDeleteByKeysReq,
1243+
) -> crate::error::Result<AttachmentsDeleteByKeysResp> {
1244+
self.url
1245+
.set_path(&format!("groups/{group_name}/delete/attachments/list"));
1246+
let resp = self
1247+
.http_client
1248+
.post(self.url.as_str())
1249+
.bearer_auth(&self.credential)
1250+
.json(&req)
1251+
.send()
1252+
.await
1253+
.map_err(map_reqwest_err)?;
1254+
if resp.status().is_success() {
1255+
let resp = resp
1256+
.json::<AttachmentsDeleteByKeysResp>()
1257+
.await
1258+
.map_err(RequestError::from)?;
1259+
Ok(resp)
1260+
} else {
1261+
Err(get_error_from_resp(resp).await.into())
1262+
}
1263+
}
1264+
1265+
pub async fn batch_submit_tasks(
1266+
&mut self,
1267+
req: TasksSubmitReq,
1268+
) -> crate::error::Result<TasksSubmitResp> {
1269+
self.url.set_path("tasks/submit");
1270+
let resp = self
1271+
.http_client
1272+
.post(self.url.as_str())
1273+
.bearer_auth(&self.credential)
1274+
.json(&req)
1275+
.send()
1276+
.await
1277+
.map_err(map_reqwest_err)?;
1278+
if resp.status().is_success() {
1279+
let resp = resp
1280+
.json::<TasksSubmitResp>()
1281+
.await
1282+
.map_err(RequestError::from)?;
1283+
Ok(resp)
1284+
} else {
1285+
Err(get_error_from_resp(resp).await.into())
1286+
}
1287+
}
1288+
11651289
pub async fn admin_shutdown_coordinator(
11661290
&mut self,
11671291
req: ShutdownReq,

0 commit comments

Comments
 (0)