use super::load_operations_from_downstream_services::load_operations_from_downstream_services;
use crate::{
dtos::ServiceWrapper,
openapi::ApiDoc,
openapi_processor::{
load_operations_from_downstream_services::ServiceOpenApiSchema,
load_paths_from_spec,
},
};
use chrono::Local;
use myc_core::domain::{
dtos::health_check_info::HealthStatus, entities::ServiceRead,
};
use myc_mem_db::repositories::MemDbAppModule;
use mycelium_base::{
entities::FetchManyResponseKind,
utils::errors::{execution_err, MappedErrors},
};
use mycelium_openapi::OpenApiSchema;
use shaku::HasComponent;
use std::{collections::HashMap, sync::Arc};
use tracing::Instrument;
use utoipa::OpenApi;
const MYCELIUM_SERVICE_NAME: &str = "mag";
#[tracing::instrument(name = "initialize_tools_registry", skip_all)]
pub(crate) async fn initialize_tools_registry(
app_modules: Arc<MemDbAppModule>,
) -> Result<ServiceOpenApiSchema, MappedErrors> {
let span = tracing::Span::current();
let mut service_operations = ServiceOpenApiSchema {
operations: Vec::new(),
docs: HashMap::new(),
};
let service_read_repo: &dyn ServiceRead = app_modules.resolve_ref();
let services = match service_read_repo
.list_services(None, None, None)
.instrument(span.clone())
.await?
{
FetchManyResponseKind::Found(services) => services,
_ => vec![],
};
let downstream_operations =
load_operations_from_downstream_services(services, app_modules.clone())
.instrument(span)
.await?;
service_operations
.operations
.extend(downstream_operations.operations);
service_operations.docs.extend(downstream_operations.docs);
let mycelium_openapi_schema =
ApiDoc::openapi().to_pretty_json().map_err(|e| {
execution_err(format!(
"Failed to convert mycelium operations to json: {e}"
))
})?;
let mycelium_docs =
OpenApiSchema::load_doc_from_string(&mycelium_openapi_schema)?;
let service_wrapper = ServiceWrapper {
name: MYCELIUM_SERVICE_NAME.to_string(),
health_status: HealthStatus::Healthy {
checked_at: Local::now(),
},
capabilities: Some(
vec!["identify-federation", "tenant", "account-management"]
.iter()
.map(|s| s.to_string())
.collect(),
),
description: Some("Mycelium API Gateway".to_string()),
};
let mycelium_operations = load_paths_from_spec(
mycelium_docs.clone(),
service_wrapper,
app_modules,
true,
)
.await?;
service_operations.operations.extend(mycelium_operations);
service_operations
.docs
.insert(MYCELIUM_SERVICE_NAME.to_string(), mycelium_docs);
Ok(service_operations)
}