pub mod graphql_schema;
pub mod rest_api;
pub mod grpc_service;
pub mod websocket_streaming;
pub mod kafka_integration;
pub mod openapi_spec;
use crate::error::Result;
use crate::model::{Dataset, Graph, Triple, Quad};
use std::sync::Arc;
use tokio::sync::RwLock;
pub struct ApiService {
dataset: Arc<RwLock<Dataset>>,
graphql_schema: graphql_schema::GraphQLSchemaGenerator,
rest_api: rest_api::RestApiHandler,
grpc_service: grpc_service::GrpcService,
websocket_streaming: websocket_streaming::WebSocketManager,
kafka_integration: kafka_integration::KafkaIntegration,
}
impl ApiService {
pub fn new(dataset: Arc<RwLock<Dataset>>) -> Result<Self> {
Ok(Self {
graphql_schema: graphql_schema::GraphQLSchemaGenerator::new(dataset.clone())?,
rest_api: rest_api::RestApiHandler::new(dataset.clone())?,
grpc_service: grpc_service::GrpcService::new(dataset.clone())?,
websocket_streaming: websocket_streaming::WebSocketManager::new(dataset.clone())?,
kafka_integration: kafka_integration::KafkaIntegration::new(dataset.clone())?,
dataset,
})
}
pub async fn start(&self) -> Result<()> {
self.graphql_schema.initialize().await?;
self.rest_api.start_server().await?;
self.grpc_service.start_server().await?;
self.websocket_streaming.initialize().await?;
self.kafka_integration.connect().await?;
Ok(())
}
pub async fn stop(&self) -> Result<()> {
self.kafka_integration.disconnect().await?;
self.websocket_streaming.shutdown().await?;
self.grpc_service.stop_server().await?;
self.rest_api.stop_server().await?;
Ok(())
}
pub async fn health_check(&self) -> ApiServiceHealth {
ApiServiceHealth {
graphql_status: self.graphql_schema.health_check().await,
rest_api_status: self.rest_api.health_check().await,
grpc_status: self.grpc_service.health_check().await,
websocket_status: self.websocket_streaming.health_check().await,
kafka_status: self.kafka_integration.health_check().await,
}
}
}
#[derive(Debug, Clone)]
pub struct ApiServiceHealth {
pub graphql_status: ServiceStatus,
pub rest_api_status: ServiceStatus,
pub grpc_status: ServiceStatus,
pub websocket_status: ServiceStatus,
pub kafka_status: ServiceStatus,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ServiceStatus {
Healthy,
Degraded(String),
Unhealthy(String),
}
impl ApiServiceHealth {
pub fn is_healthy(&self) -> bool {
matches!(self.graphql_status, ServiceStatus::Healthy) &&
matches!(self.rest_api_status, ServiceStatus::Healthy) &&
matches!(self.grpc_status, ServiceStatus::Healthy) &&
matches!(self.websocket_status, ServiceStatus::Healthy) &&
matches!(self.kafka_status, ServiceStatus::Healthy)
}
}
#[derive(Debug, Clone)]
pub struct ApiConfig {
pub graphql_config: graphql_schema::GraphQLConfig,
pub rest_config: rest_api::RestConfig,
pub grpc_config: grpc_service::GrpcConfig,
pub websocket_config: websocket_streaming::WebSocketConfig,
pub kafka_config: kafka_integration::KafkaConfig,
}
impl Default for ApiConfig {
fn default() -> Self {
Self {
graphql_config: graphql_schema::GraphQLConfig::default(),
rest_config: rest_api::RestConfig::default(),
grpc_config: grpc_service::GrpcConfig::default(),
websocket_config: websocket_streaming::WebSocketConfig::default(),
kafka_config: kafka_integration::KafkaConfig::default(),
}
}
}