refactor: rename ImageStorage → ObjectStorage
Some checks failed
CI / Check / Test (push) Failing after 46s
Some checks failed
CI / Check / Test (push) Failing after 46s
This commit is contained in:
@@ -4,20 +4,20 @@ use async_trait::async_trait;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
events::DomainEvent,
|
||||
ports::{EventHandler, ImageRefCommand, ImageStorage},
|
||||
ports::{EventHandler, ImageRefCommand, ObjectStorage},
|
||||
};
|
||||
|
||||
use crate::Format;
|
||||
|
||||
pub struct ImageConversionHandler {
|
||||
storage: Arc<dyn ImageStorage>,
|
||||
storage: Arc<dyn ObjectStorage>,
|
||||
image_ref: Arc<dyn ImageRefCommand>,
|
||||
format: Format,
|
||||
}
|
||||
|
||||
impl ImageConversionHandler {
|
||||
pub fn new(
|
||||
storage: Arc<dyn ImageStorage>,
|
||||
storage: Arc<dyn ObjectStorage>,
|
||||
image_ref: Arc<dyn ImageRefCommand>,
|
||||
format: Format,
|
||||
) -> Self {
|
||||
|
||||
@@ -7,14 +7,14 @@ pub use config::{ConversionConfig, Format};
|
||||
pub use handler::ImageConversionHandler;
|
||||
|
||||
use domain::ports::{
|
||||
EventHandler, EventPublisher, ImageRefCommand, ImageRefQuery, ImageStorage, PeriodicJob,
|
||||
EventHandler, EventPublisher, ImageRefCommand, ImageRefQuery, ObjectStorage, PeriodicJob,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
type ConversionPair = (Arc<dyn EventHandler>, Arc<dyn PeriodicJob>);
|
||||
|
||||
pub fn build(
|
||||
image_storage: Arc<dyn ImageStorage>,
|
||||
object_storage: Arc<dyn ObjectStorage>,
|
||||
image_ref_command: Arc<dyn ImageRefCommand>,
|
||||
image_ref_query: Arc<dyn ImageRefQuery>,
|
||||
event_publisher: Arc<dyn EventPublisher>,
|
||||
@@ -27,7 +27,7 @@ pub fn build(
|
||||
let format = config.format;
|
||||
|
||||
let handler = Arc::new(ImageConversionHandler::new(
|
||||
Arc::clone(&image_storage),
|
||||
Arc::clone(&object_storage),
|
||||
image_ref_command,
|
||||
format,
|
||||
)) as Arc<dyn EventHandler>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::*;
|
||||
use image_storage::ImageStorageAdapter;
|
||||
use object_storage::ObjectStorageAdapter;
|
||||
use object_store::memory::InMemory;
|
||||
use std::sync::Mutex;
|
||||
|
||||
@@ -27,8 +27,8 @@ impl ImageRefCommand for MockImageRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn in_memory_storage() -> Arc<ImageStorageAdapter> {
|
||||
Arc::new(ImageStorageAdapter::new(Arc::new(InMemory::new())))
|
||||
fn in_memory_storage() -> Arc<ObjectStorageAdapter> {
|
||||
Arc::new(ObjectStorageAdapter::new(Arc::new(InMemory::new())))
|
||||
}
|
||||
|
||||
fn tiny_jpeg() -> Vec<u8> {
|
||||
@@ -44,7 +44,7 @@ async fn ignores_non_image_stored_events() {
|
||||
let storage = in_memory_storage();
|
||||
let image_ref = MockImageRef::new();
|
||||
let handler = ImageConversionHandler::new(
|
||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
||||
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||
Format::Avif,
|
||||
);
|
||||
@@ -68,7 +68,7 @@ async fn skips_already_converted_avif_key() {
|
||||
.unwrap();
|
||||
let image_ref = MockImageRef::new();
|
||||
let handler = ImageConversionHandler::new(
|
||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
||||
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||
Format::Avif,
|
||||
);
|
||||
@@ -92,7 +92,7 @@ async fn skips_already_converted_webp_key() {
|
||||
.unwrap();
|
||||
let image_ref = MockImageRef::new();
|
||||
let handler = ImageConversionHandler::new(
|
||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
||||
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||
Format::Webp,
|
||||
);
|
||||
@@ -113,7 +113,7 @@ async fn converts_jpeg_to_avif_and_swaps_key() {
|
||||
storage.store("avatars/u1", &tiny_jpeg()).await.unwrap();
|
||||
let image_ref = MockImageRef::new();
|
||||
let handler = ImageConversionHandler::new(
|
||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
||||
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||
Format::Avif,
|
||||
);
|
||||
@@ -139,7 +139,7 @@ async fn converts_jpeg_to_webp_and_swaps_key() {
|
||||
storage.store("avatars/u1", &tiny_jpeg()).await.unwrap();
|
||||
let image_ref = MockImageRef::new();
|
||||
let handler = ImageConversionHandler::new(
|
||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
||||
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||
Format::Webp,
|
||||
);
|
||||
|
||||
@@ -5,17 +5,17 @@ use async_trait::async_trait;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
events::DomainEvent,
|
||||
ports::{EventHandler, ImageStorage},
|
||||
ports::{EventHandler, ObjectStorage},
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use object_store::{ObjectStore, path::Path};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct ImageStorageAdapter {
|
||||
pub struct ObjectStorageAdapter {
|
||||
store: Arc<dyn ObjectStore>,
|
||||
}
|
||||
|
||||
impl ImageStorageAdapter {
|
||||
impl ObjectStorageAdapter {
|
||||
pub fn new(store: Arc<dyn ObjectStore>) -> Self {
|
||||
Self { store }
|
||||
}
|
||||
@@ -26,7 +26,7 @@ impl ImageStorageAdapter {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ImageStorage for ImageStorageAdapter {
|
||||
impl ObjectStorage for ObjectStorageAdapter {
|
||||
async fn store(&self, key: &str, image_bytes: &[u8]) -> Result<String, DomainError> {
|
||||
let path = Path::from(key);
|
||||
self.store
|
||||
@@ -78,12 +78,12 @@ impl ImageStorage for ImageStorageAdapter {
|
||||
}
|
||||
|
||||
pub struct ImageCleanupHandler {
|
||||
image_storage: Arc<dyn ImageStorage>,
|
||||
object_storage: Arc<dyn ObjectStorage>,
|
||||
}
|
||||
|
||||
impl ImageCleanupHandler {
|
||||
pub fn new(image_storage: Arc<dyn ImageStorage>) -> Self {
|
||||
Self { image_storage }
|
||||
pub fn new(object_storage: Arc<dyn ObjectStorage>) -> Self {
|
||||
Self { object_storage }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,15 +97,15 @@ impl EventHandler for ImageCleanupHandler {
|
||||
let Some(path) = poster_path else {
|
||||
return Ok(());
|
||||
};
|
||||
if let Err(e) = self.image_storage.delete(path.value()).await {
|
||||
if let Err(e) = self.object_storage.delete(path.value()).await {
|
||||
tracing::warn!("image cleanup failed for {}: {e}", path.value());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create() -> anyhow::Result<Arc<dyn ImageStorage>> {
|
||||
Ok(Arc::new(ImageStorageAdapter::from_config(
|
||||
pub fn create() -> anyhow::Result<Arc<dyn ObjectStorage>> {
|
||||
Ok(Arc::new(ObjectStorageAdapter::from_config(
|
||||
StorageConfig::from_env()?,
|
||||
)))
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::*;
|
||||
use object_store::memory::InMemory;
|
||||
|
||||
fn adapter() -> ImageStorageAdapter {
|
||||
ImageStorageAdapter::new(Arc::new(InMemory::new()))
|
||||
fn adapter() -> ObjectStorageAdapter {
|
||||
ObjectStorageAdapter::new(Arc::new(InMemory::new()))
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -46,7 +46,7 @@ async fn cleanup_handler_deletes_on_movie_deleted() {
|
||||
let inner = Arc::new(adapter());
|
||||
inner.store("some-uuid", b"img").await.unwrap();
|
||||
let path = PosterPath::new("some-uuid".to_string()).unwrap();
|
||||
let handler = ImageCleanupHandler::new(Arc::clone(&inner) as Arc<dyn ImageStorage>);
|
||||
let handler = ImageCleanupHandler::new(Arc::clone(&inner) as Arc<dyn ObjectStorage>);
|
||||
handler
|
||||
.handle(&DomainEvent::MovieDeleted {
|
||||
movie_id: MovieId::from_uuid(uuid::Uuid::new_v4()),
|
||||
|
||||
@@ -5,7 +5,7 @@ use domain::{
|
||||
errors::DomainError,
|
||||
events::DomainEvent,
|
||||
ports::{
|
||||
EventHandler, EventPublisher, ImageStorage, MetadataClient, MovieRepository,
|
||||
EventHandler, EventPublisher, ObjectStorage, MetadataClient, MovieRepository,
|
||||
PosterFetcherClient,
|
||||
},
|
||||
value_objects::{ExternalMetadataId, MovieId, PosterPath},
|
||||
@@ -15,7 +15,7 @@ pub struct PosterSyncHandler {
|
||||
movie_repository: Arc<dyn MovieRepository>,
|
||||
metadata_client: Arc<dyn MetadataClient>,
|
||||
poster_fetcher: Arc<dyn PosterFetcherClient>,
|
||||
image_storage: Arc<dyn ImageStorage>,
|
||||
object_storage: Arc<dyn ObjectStorage>,
|
||||
event_publisher: Arc<dyn EventPublisher>,
|
||||
max_retries: u32,
|
||||
}
|
||||
@@ -25,7 +25,7 @@ impl PosterSyncHandler {
|
||||
movie_repository: Arc<dyn MovieRepository>,
|
||||
metadata_client: Arc<dyn MetadataClient>,
|
||||
poster_fetcher: Arc<dyn PosterFetcherClient>,
|
||||
image_storage: Arc<dyn ImageStorage>,
|
||||
object_storage: Arc<dyn ObjectStorage>,
|
||||
event_publisher: Arc<dyn EventPublisher>,
|
||||
max_retries: u32,
|
||||
) -> Self {
|
||||
@@ -33,7 +33,7 @@ impl PosterSyncHandler {
|
||||
movie_repository,
|
||||
metadata_client,
|
||||
poster_fetcher,
|
||||
image_storage,
|
||||
object_storage,
|
||||
event_publisher,
|
||||
max_retries,
|
||||
}
|
||||
@@ -67,7 +67,7 @@ impl PosterSyncHandler {
|
||||
|
||||
let image_bytes = self.poster_fetcher.fetch_poster_bytes(&poster_url).await?;
|
||||
let stored_path = self
|
||||
.image_storage
|
||||
.object_storage
|
||||
.store(&movie_id.value().to_string(), &image_bytes)
|
||||
.await?;
|
||||
if let Err(e) = self
|
||||
|
||||
@@ -8,7 +8,7 @@ use domain::{
|
||||
events::DomainEvent,
|
||||
models::{CastMember, CrewMember, Genre, Keyword, MovieProfile},
|
||||
ports::{
|
||||
EventHandler, ImageStorage, MovieEnrichmentClient, MovieProfileRepository, MovieRepository,
|
||||
EventHandler, ObjectStorage, MovieEnrichmentClient, MovieProfileRepository, MovieRepository,
|
||||
PersonCommand, SearchCommand,
|
||||
},
|
||||
value_objects::MovieId,
|
||||
@@ -229,7 +229,7 @@ pub struct EnrichmentHandler {
|
||||
pub profile_repo: Arc<dyn MovieProfileRepository>,
|
||||
pub person_command: Arc<dyn PersonCommand>,
|
||||
pub search_command: Arc<dyn SearchCommand>,
|
||||
pub image_storage: Arc<dyn ImageStorage>,
|
||||
pub object_storage: Arc<dyn ObjectStorage>,
|
||||
http: reqwest::Client,
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ impl EnrichmentHandler {
|
||||
profile_repo: Arc<dyn MovieProfileRepository>,
|
||||
person_command: Arc<dyn PersonCommand>,
|
||||
search_command: Arc<dyn SearchCommand>,
|
||||
image_storage: Arc<dyn ImageStorage>,
|
||||
object_storage: Arc<dyn ObjectStorage>,
|
||||
) -> Self {
|
||||
Self {
|
||||
enrichment_client,
|
||||
@@ -248,7 +248,7 @@ impl EnrichmentHandler {
|
||||
profile_repo,
|
||||
person_command,
|
||||
search_command,
|
||||
image_storage,
|
||||
object_storage,
|
||||
http: reqwest::Client::new(),
|
||||
}
|
||||
}
|
||||
@@ -259,14 +259,14 @@ impl EnrichmentHandler {
|
||||
continue;
|
||||
};
|
||||
let key = format!("cast{path}");
|
||||
if self.image_storage.get(&key).await.is_ok() {
|
||||
if self.object_storage.get(&key).await.is_ok() {
|
||||
continue;
|
||||
}
|
||||
let url = format!("https://image.tmdb.org/t/p/w185{path}");
|
||||
match self.http.get(&url).send().await {
|
||||
Ok(resp) if resp.status().is_success() => {
|
||||
if let Ok(bytes) = resp.bytes().await
|
||||
&& let Err(e) = self.image_storage.store(&key, &bytes).await
|
||||
&& let Err(e) = self.object_storage.store(&key, &bytes).await
|
||||
{
|
||||
tracing::debug!("cast photo store failed for {path}: {e}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user