Page MenuHomePhabricator

D8971.id30633.diff
No OneTemporary

D8971.id30633.diff

diff --git a/services/reports/src/database/item.rs b/services/reports/src/database/item.rs
--- a/services/reports/src/database/item.rs
+++ b/services/reports/src/database/item.rs
@@ -213,6 +213,19 @@
) -> Result<(), BlobServiceError> {
todo!()
}
+
+ /// Fetches report content bytes
+ pub async fn fetch_bytes(
+ self,
+ blob_client: &BlobServiceClient,
+ ) -> Result<Vec<u8>, BlobServiceError> {
+ match self {
+ ReportContent::Database(data) => Ok(data),
+ ReportContent::Blob(BlobInfo { blob_hash, .. }) => {
+ todo!()
+ }
+ }
+ }
}
// DB conversions for report types
diff --git a/services/reports/src/http/handlers.rs b/services/reports/src/http/handlers.rs
--- a/services/reports/src/http/handlers.rs
+++ b/services/reports/src/http/handlers.rs
@@ -1,6 +1,8 @@
-use actix_web::{post, web, HttpResponse};
+use actix_web::{get, post, web, HttpResponse};
use serde::Deserialize;
+use super::NotFoundHandler;
+
use crate::report_types::ReportInput;
use crate::service::ReportsService;
@@ -21,7 +23,7 @@
}
}
-#[post("/reports")]
+#[post("")]
async fn post_reports(
payload: web::Json<PostReportsPayload>,
service: ReportsService,
@@ -33,3 +35,17 @@
let response = HttpResponse::Created().json(json!({ "reportIDs": ids }));
Ok(response)
}
+
+#[get("/{report_id}")]
+async fn get_single_report(
+ path: web::Path<String>,
+ service: ReportsService,
+) -> actix_web::Result<HttpResponse> {
+ let report_id = path.into_inner();
+ let report = service
+ .get_report(report_id.into())
+ .await?
+ .unwrap_or_404()?;
+ let response = HttpResponse::Ok().json(report);
+ Ok(response)
+}
diff --git a/services/reports/src/http/mod.rs b/services/reports/src/http/mod.rs
--- a/services/reports/src/http/mod.rs
+++ b/services/reports/src/http/mod.rs
@@ -1,6 +1,6 @@
use actix_web::error::{
- ErrorBadRequest, ErrorInternalServerError, ErrorServiceUnavailable,
- ErrorUnsupportedMediaType,
+ ErrorBadRequest, ErrorInternalServerError, ErrorNotFound,
+ ErrorServiceUnavailable, ErrorUnsupportedMediaType,
};
use actix_web::{web, App, HttpResponse, HttpServer, ResponseError};
use anyhow::Result;
@@ -34,7 +34,11 @@
.wrap(cors_config(CONFIG.is_dev()))
// Health endpoint for load balancers checks
.route("/health", web::get().to(HttpResponse::Ok))
- .service(handlers::post_reports)
+ .service(
+ web::scope("/reports")
+ .service(handlers::post_reports)
+ .service(handlers::get_single_report),
+ )
})
.bind(("0.0.0.0", CONFIG.http_port))?
.run()
@@ -100,3 +104,14 @@
.status_code()
}
}
+
+trait NotFoundHandler<T> {
+ /// Returns `Ok(T)` if `self` is `Some(T)`,
+ /// otherwise returns a `404 Not Found` error.
+ fn unwrap_or_404(self) -> actix_web::Result<T>;
+}
+impl<T> NotFoundHandler<T> for Option<T> {
+ fn unwrap_or_404(self) -> actix_web::Result<T> {
+ self.ok_or_else(|| ErrorNotFound("not found"))
+ }
+}
diff --git a/services/reports/src/service.rs b/services/reports/src/service.rs
--- a/services/reports/src/service.rs
+++ b/services/reports/src/service.rs
@@ -10,7 +10,7 @@
use crate::{
database::{client::DatabaseClient, item::ReportItem},
- report_types::{ReportID, ReportInput},
+ report_types::{ReportID, ReportInput, ReportOutput},
};
#[derive(Debug, Display, Error, From)]
@@ -94,6 +94,37 @@
self.db.save_reports(items).await?;
Ok(ids)
}
+
+ pub async fn get_report(
+ &self,
+ report_id: ReportID,
+ ) -> ServiceResult<Option<ReportOutput>> {
+ let Some(report_item) = self.db.get_report(&report_id).await? else {
+ return Ok(None);
+ };
+ let ReportItem {
+ user_id,
+ report_type,
+ platform,
+ creation_time,
+ content,
+ ..
+ } = report_item;
+
+ let report_data = content.fetch_bytes(&self.blob_client).await?;
+ let report_json = serde_json::from_slice(report_data.as_slice())
+ .map_err(ReportsServiceError::SerdeError)?;
+
+ let output = ReportOutput {
+ id: report_id,
+ user_id,
+ platform,
+ report_type,
+ creation_time,
+ content: report_json,
+ };
+ Ok(Some(output))
+ }
}
impl FromRequest for ReportsService {

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 10:45 AM (18 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2569081
Default Alt Text
D8971.id30633.diff (4 KB)

Event Timeline