adding features
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
use std::time::Duration;
|
||||
|
||||
/// Configuración de caché
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CacheConfig {
|
||||
/// TTL para entradas de archivos en caché (ms)
|
||||
pub file_ttl_ms: u64,
|
||||
/// TTL para entradas de directorios en caché (ms)
|
||||
pub directory_ttl_ms: u64,
|
||||
/// Máximo número de entradas en caché
|
||||
pub max_entries: usize,
|
||||
}
|
||||
|
||||
impl Default for CacheConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
file_ttl_ms: 60_000, // 1 minuto
|
||||
directory_ttl_ms: 120_000, // 2 minutos
|
||||
max_entries: 10_000, // 10,000 entradas
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuración de timeouts para diferentes operaciones
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TimeoutConfig {
|
||||
@@ -160,6 +181,8 @@ impl Default for ConcurrencyConfig {
|
||||
/// Configuración global de la aplicación
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppConfig {
|
||||
/// Configuración de caché
|
||||
pub cache: CacheConfig,
|
||||
/// Configuración de timeouts
|
||||
pub timeouts: TimeoutConfig,
|
||||
/// Configuración de recursos
|
||||
@@ -171,6 +194,7 @@ pub struct AppConfig {
|
||||
impl Default for AppConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
cache: CacheConfig::default(),
|
||||
timeouts: TimeoutConfig::default(),
|
||||
resources: ResourceConfig::default(),
|
||||
concurrency: ConcurrencyConfig::default(),
|
||||
|
||||
+100
-36
@@ -1,6 +1,6 @@
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use crate::domain::services::path_service::PathService;
|
||||
use crate::infrastructure::repositories::folder_fs_repository::FolderFsRepository;
|
||||
@@ -8,20 +8,28 @@ use crate::infrastructure::repositories::file_fs_repository::FileFsRepository;
|
||||
use crate::infrastructure::services::file_system_i18n_service::FileSystemI18nService;
|
||||
use crate::infrastructure::services::id_mapping_service::IdMappingService;
|
||||
use crate::infrastructure::services::cache_manager::StorageCacheManager;
|
||||
use crate::infrastructure::services::file_metadata_cache::FileMetadataCache;
|
||||
use crate::application::services::folder_service::FolderService;
|
||||
use crate::application::services::file_service::FileService;
|
||||
use crate::application::services::i18n_application_service::I18nApplicationService;
|
||||
use crate::application::services::storage_mediator::{StorageMediator, FileSystemStorageMediator};
|
||||
use crate::application::ports::inbound::{FileUseCase, FolderUseCase, UseCaseFactory};
|
||||
use crate::application::ports::outbound::{FileStoragePort, FolderStoragePort};
|
||||
use crate::application::ports::file_ports::{FileUploadUseCase, FileRetrievalUseCase, FileManagementUseCase, FileUseCaseFactory};
|
||||
use crate::application::ports::storage_ports::{FileReadPort, FileWritePort, FilePathResolutionPort};
|
||||
use crate::infrastructure::repositories::{FileMetadataManager, FilePathResolver, FileFsReadRepository, FileFsWriteRepository};
|
||||
use crate::application::services::{FileUploadService, FileRetrievalService, FileManagementService, AppFileUseCaseFactory};
|
||||
use crate::common::errors::DomainError;
|
||||
use crate::domain::services::i18n_service::I18nService;
|
||||
use crate::common::config::AppConfig;
|
||||
use crate::domain::repositories::folder_repository::FolderRepository;
|
||||
|
||||
/// Fábrica para los diferentes componentes de la aplicación
|
||||
#[allow(dead_code)]
|
||||
pub struct AppServiceFactory {
|
||||
storage_path: PathBuf,
|
||||
locales_path: PathBuf,
|
||||
config: AppConfig,
|
||||
}
|
||||
|
||||
impl AppServiceFactory {
|
||||
@@ -31,6 +39,17 @@ impl AppServiceFactory {
|
||||
Self {
|
||||
storage_path,
|
||||
locales_path,
|
||||
config: AppConfig::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Crea una nueva fábrica de servicios con configuración personalizada
|
||||
#[allow(dead_code)]
|
||||
pub fn with_config(storage_path: PathBuf, locales_path: PathBuf, config: AppConfig) -> Self {
|
||||
Self {
|
||||
storage_path,
|
||||
locales_path,
|
||||
config,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,18 +82,18 @@ impl AppServiceFactory {
|
||||
path_service,
|
||||
cache_manager,
|
||||
id_mapping_service,
|
||||
config: self.config.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Inicializa los servicios de repositorio
|
||||
/// Inicializa los servicios de repositorio utilizando el patrón Builder mejorado
|
||||
#[allow(dead_code)]
|
||||
pub fn create_repository_services(&self, core: &CoreServices) -> RepositoryServices {
|
||||
// Storage mediator - create first because it's needed by folder repository
|
||||
// (temporarily using a placeholder for folder repository, will update later)
|
||||
let placeholder_folder_repo = Arc::new(FolderFsRepository::new_stub());
|
||||
// Storage mediator - con inicialización diferida para folder repository
|
||||
let folder_repository_holder = Arc::new(RwLock::new(None));
|
||||
|
||||
let storage_mediator = Arc::new(FileSystemStorageMediator::new(
|
||||
placeholder_folder_repo.clone(),
|
||||
let storage_mediator = Arc::new(FileSystemStorageMediator::new_with_lazy_folder(
|
||||
folder_repository_holder.clone(),
|
||||
core.path_service.clone(),
|
||||
core.id_mapping_service.clone()
|
||||
));
|
||||
@@ -87,14 +106,47 @@ impl AppServiceFactory {
|
||||
core.path_service.clone(),
|
||||
));
|
||||
|
||||
// Create a file metadata cache with default configuration
|
||||
// Actualizar el holder para el mediador una vez que el repository está creado
|
||||
if let Ok(mut holder) = folder_repository_holder.write() {
|
||||
*holder = Some(folder_repository.clone());
|
||||
}
|
||||
|
||||
// Metadata cache
|
||||
let metadata_cache = Arc::new(
|
||||
crate::infrastructure::services::file_metadata_cache::FileMetadataCache::default_with_config(
|
||||
crate::common::config::AppConfig::default()
|
||||
)
|
||||
FileMetadataCache::default_with_config(core.config.clone())
|
||||
);
|
||||
|
||||
// File repository
|
||||
// Componentes refactorizados
|
||||
let metadata_manager = Arc::new(FileMetadataManager::new(
|
||||
metadata_cache.clone(),
|
||||
core.config.clone()
|
||||
));
|
||||
|
||||
let path_resolver = Arc::new(FilePathResolver::new(
|
||||
core.path_service.clone(),
|
||||
storage_mediator.clone(),
|
||||
core.id_mapping_service.clone()
|
||||
));
|
||||
|
||||
// File repositories separados para lectura y escritura
|
||||
let file_read_repository = Arc::new(FileFsReadRepository::new(
|
||||
self.storage_path.clone(),
|
||||
metadata_manager.clone(),
|
||||
path_resolver.clone(),
|
||||
core.config.clone(),
|
||||
None // processor will be added later if needed
|
||||
));
|
||||
|
||||
let file_write_repository = Arc::new(FileFsWriteRepository::new(
|
||||
self.storage_path.clone(),
|
||||
metadata_manager.clone(),
|
||||
path_resolver.clone(),
|
||||
storage_mediator.clone(),
|
||||
core.config.clone(),
|
||||
None // processor will be added later if needed
|
||||
));
|
||||
|
||||
// Legacy file repository - mantenido por compatibilidad
|
||||
let file_repository = Arc::new(FileFsRepository::new(
|
||||
self.storage_path.clone(),
|
||||
storage_mediator.clone(),
|
||||
@@ -111,8 +163,12 @@ impl AppServiceFactory {
|
||||
RepositoryServices {
|
||||
folder_repository,
|
||||
file_repository,
|
||||
file_read_repository,
|
||||
file_write_repository,
|
||||
i18n_repository,
|
||||
storage_mediator,
|
||||
metadata_manager,
|
||||
path_resolver,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,10 +180,29 @@ impl AppServiceFactory {
|
||||
repos.folder_repository.clone()
|
||||
));
|
||||
|
||||
// Antiguo servicio único
|
||||
let file_service = Arc::new(FileService::new(
|
||||
repos.file_repository.clone()
|
||||
));
|
||||
|
||||
// Nuevos servicios refactorizados
|
||||
let file_upload_service = Arc::new(FileUploadService::new(
|
||||
repos.file_write_repository.clone()
|
||||
));
|
||||
|
||||
let file_retrieval_service = Arc::new(FileRetrievalService::new(
|
||||
repos.file_read_repository.clone()
|
||||
));
|
||||
|
||||
let file_management_service = Arc::new(FileManagementService::new(
|
||||
repos.file_write_repository.clone()
|
||||
));
|
||||
|
||||
let file_use_case_factory = Arc::new(AppFileUseCaseFactory::new(
|
||||
repos.file_read_repository.clone(),
|
||||
repos.file_write_repository.clone()
|
||||
));
|
||||
|
||||
let i18n_service = Arc::new(I18nApplicationService::new(
|
||||
repos.i18n_repository.clone()
|
||||
));
|
||||
@@ -135,6 +210,10 @@ impl AppServiceFactory {
|
||||
ApplicationServices {
|
||||
folder_service,
|
||||
file_service,
|
||||
file_upload_service,
|
||||
file_retrieval_service,
|
||||
file_management_service,
|
||||
file_use_case_factory,
|
||||
i18n_service,
|
||||
}
|
||||
}
|
||||
@@ -146,6 +225,7 @@ pub struct CoreServices {
|
||||
pub path_service: Arc<PathService>,
|
||||
pub cache_manager: Arc<StorageCacheManager>,
|
||||
pub id_mapping_service: Arc<IdMappingService>,
|
||||
pub config: AppConfig,
|
||||
}
|
||||
|
||||
/// Contenedor para servicios de repositorio
|
||||
@@ -153,8 +233,12 @@ pub struct CoreServices {
|
||||
pub struct RepositoryServices {
|
||||
pub folder_repository: Arc<dyn FolderStoragePort>,
|
||||
pub file_repository: Arc<dyn FileStoragePort>,
|
||||
pub file_read_repository: Arc<dyn FileReadPort>,
|
||||
pub file_write_repository: Arc<dyn FileWritePort>,
|
||||
pub i18n_repository: Arc<dyn I18nService>,
|
||||
pub storage_mediator: Arc<dyn StorageMediator>,
|
||||
pub metadata_manager: Arc<FileMetadataManager>,
|
||||
pub path_resolver: Arc<FilePathResolver>,
|
||||
}
|
||||
|
||||
/// Contenedor para servicios de aplicación
|
||||
@@ -162,29 +246,9 @@ pub struct RepositoryServices {
|
||||
pub struct ApplicationServices {
|
||||
pub folder_service: Arc<dyn FolderUseCase>,
|
||||
pub file_service: Arc<dyn FileUseCase>,
|
||||
pub file_upload_service: Arc<dyn FileUploadUseCase>,
|
||||
pub file_retrieval_service: Arc<dyn FileRetrievalUseCase>,
|
||||
pub file_management_service: Arc<dyn FileManagementUseCase>,
|
||||
pub file_use_case_factory: Arc<dyn FileUseCaseFactory>,
|
||||
pub i18n_service: Arc<I18nApplicationService>,
|
||||
}
|
||||
|
||||
/// Fábrica de casos de uso para la inyección de dependencias
|
||||
#[allow(dead_code)]
|
||||
pub struct AppUseCaseFactory {
|
||||
services: ApplicationServices,
|
||||
}
|
||||
|
||||
impl AppUseCaseFactory {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(services: ApplicationServices) -> Self {
|
||||
Self { services }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl UseCaseFactory for AppUseCaseFactory {
|
||||
fn create_file_use_case(&self) -> Arc<dyn FileUseCase> {
|
||||
self.services.file_service.clone()
|
||||
}
|
||||
|
||||
fn create_folder_use_case(&self) -> Arc<dyn FolderUseCase> {
|
||||
self.services.folder_service.clone()
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@ pub enum ErrorKind {
|
||||
Timeout,
|
||||
/// Error interno del sistema
|
||||
InternalError,
|
||||
/// Funcionalidad no implementada
|
||||
NotImplemented,
|
||||
}
|
||||
|
||||
impl Display for ErrorKind {
|
||||
@@ -28,6 +30,7 @@ impl Display for ErrorKind {
|
||||
ErrorKind::AccessDenied => write!(f, "Access Denied"),
|
||||
ErrorKind::Timeout => write!(f, "Timeout"),
|
||||
ErrorKind::InternalError => write!(f, "Internal Error"),
|
||||
ErrorKind::NotImplemented => write!(f, "Not Implemented"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +135,17 @@ impl DomainError {
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Crea un error de funcionalidad no implementada
|
||||
pub fn not_implemented<S: Into<String>>(entity_type: &'static str, message: S) -> Self {
|
||||
Self {
|
||||
kind: ErrorKind::NotImplemented,
|
||||
entity_type,
|
||||
entity_id: None,
|
||||
message: message.into(),
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Establece el ID de la entidad
|
||||
#[allow(dead_code)]
|
||||
|
||||
Reference in New Issue
Block a user