use crate::broker::protocol::ServiceDefinition;
use crate::broker::protocol_v2;
use crate::broker::server::service_def_loader::{ServiceDefinitionError, ServiceDefinitionLoader};
use std::path::{Path, PathBuf};
pub trait ServiceDefinitionSource: Sync {
fn lookup_or_reload(
&self,
service_name: &str,
) -> Result<ServiceDefinition, ServiceDefinitionError>;
}
impl ServiceDefinitionSource for ServiceDefinitionLoader {
fn lookup_or_reload(
&self,
service_name: &str,
) -> Result<ServiceDefinition, ServiceDefinitionError> {
ServiceDefinitionLoader::lookup_or_reload(self, service_name)
}
}
#[derive(Clone)]
pub struct CombinedServiceDefinitionLoader {
root: PathBuf,
}
impl CombinedServiceDefinitionLoader {
pub fn new(root: impl Into<PathBuf>) -> Self {
Self { root: root.into() }
}
pub fn root(&self) -> &Path {
&self.root
}
pub fn load(&self, service_name: &str) -> Result<ServiceDefinition, ServiceDefinitionError> {
match protocol_v2::ServiceDefinitionLoader::new(&self.root).load(service_name) {
Ok(v2) => Ok(service_definition_v2_to_v1(v2)),
Err(err) if is_missing_file(&err) => {
ServiceDefinitionLoader::new(&self.root).load(service_name)
}
Err(err) => Err(err),
}
}
pub fn reload(&self, service_name: &str) -> Result<ServiceDefinition, ServiceDefinitionError> {
self.load(service_name)
}
pub fn lookup_or_reload(
&self,
service_name: &str,
) -> Result<ServiceDefinition, ServiceDefinitionError> {
self.load(service_name)
}
}
impl ServiceDefinitionSource for CombinedServiceDefinitionLoader {
fn lookup_or_reload(
&self,
service_name: &str,
) -> Result<ServiceDefinition, ServiceDefinitionError> {
CombinedServiceDefinitionLoader::lookup_or_reload(self, service_name)
}
}
fn is_missing_file(err: &ServiceDefinitionError) -> bool {
matches!(err, ServiceDefinitionError::Io(io) if io.kind() == std::io::ErrorKind::NotFound)
}
pub fn service_definition_v2_to_v1(v2: protocol_v2::ServiceDefinition) -> ServiceDefinition {
ServiceDefinition {
service_name: v2.service_name,
binary_path: v2.binary_path,
isolation: v2.isolation,
explicit_instance: v2.explicit_instance,
per_version_binary_dir: v2.per_version_binary_dir,
min_version: v2.min_version,
version_allow_list: v2.version_allow_list,
labels: v2.labels,
}
}
#[cfg(test)]
mod tests;