use juiz_core::log;
use juiz_core::prelude::juiz_lock;
use juiz_core::utils::yaml_conf_load;
use std::path::Path;
use clap::Subcommand;
use juiz_core::prelude::*;
use crate::Args;
#[derive(Debug, Subcommand, Clone)]
pub(crate) enum EcSubCommands {
#[clap(arg_required_else_help = false)]
List {
#[arg(
short = 'f',
default_value = "./juiz.conf",
help = "Input system definition file path"
)]
filepath: String,
},
#[clap(arg_required_else_help = false)]
Start {
#[arg(help = "ID of Execution context")]
identifier: String,
#[arg(
short = 'f',
default_value = "./juiz.conf",
help = "Input system definition file path"
)]
filepath: String,
},
#[clap(arg_required_else_help = false)]
Stop {
#[arg(help = "ID of Execution context")]
identifier: String,
#[arg(
short = 'f',
default_value = "./juiz.conf",
help = "Input system definition file path"
)]
filepath: String,
},
}
pub(crate) fn on_execution_context(
manifest: Value,
working_dir: &Path,
subcommand: EcSubCommands,
args: Args,
) -> JuizResult<()> {
match on_ec_inner(manifest, working_dir, subcommand, args) {
Ok(_) => return Ok(()),
Err(e) => println!("Error: {e:?}"),
};
Ok(())
}
pub(crate) fn on_ec_inner(
_manifest: Value,
working_dir: &Path,
subcommand: EcSubCommands,
args: Args,
) -> JuizResult<()> {
match subcommand {
EcSubCommands::List { filepath } => {
log::trace!("ec list command is selected.");
let manifest2 = yaml_conf_load(filepath.clone())?;
let server = args.server;
let recursive = args.recursive;
System::new(manifest2)?
.set_working_dir(working_dir)
.start_http_broker(args.start_http_broker)
.setup()?
.add_systemproxy_by_id(Some(server.clone()))?
.run_and_do_once(|system| on_ec_list(system, Some(server), recursive))
}
EcSubCommands::Start {
identifier,
filepath,
} => {
log::trace!("ec start command is selected.");
let manifest2 = yaml_conf_load(filepath.clone())?;
let server = args.server;
System::new(manifest2)?
.set_working_dir(working_dir)
.start_http_broker(args.start_http_broker)
.setup()?
.add_systemproxy_by_id(Some(server.clone()))?
.run_and_do_once(|system| on_ec_start(system, server, identifier))
}
EcSubCommands::Stop {
identifier,
filepath,
} => {
log::trace!("ec stop command is selected.");
let manifest2 = yaml_conf_load(filepath.clone())?;
let server = args.server;
System::new(manifest2)?
.set_working_dir(working_dir)
.start_http_broker(args.start_http_broker)
.setup()?
.add_systemproxy_by_id(Some(server.clone()))?
.run_and_do_once(|system| on_ec_stop(system, server, identifier))
}
}
}
fn on_ec_list(system: &mut System, _server: Option<String>, recursive: bool) -> JuizResult<()> {
log::info!("on_ec_list() called");
let ec_manifests: Vec<Value> = system.ec_list(recursive)?;
let mut ids: Vec<String> = Vec::new();
for v in ec_manifests.iter() {
ids.push(v.as_str().unwrap().to_owned());
}
println!("{ids:?}");
Ok(())
}
fn on_ec_start(system: &mut System, server: String, id: String) -> JuizResult<()> {
if let Err(e) = ec_start_or_stop(system, &server, &id, true) {
println!("Error: {e:?}");
}
Ok(())
}
fn on_ec_stop(system: &mut System, server: String, id: String) -> JuizResult<()> {
if let Err(e) = ec_start_or_stop(system, &server, &id, false) {
println!("Error: {e:?}");
}
Ok(())
}
fn ec_start_or_stop(system: &mut System, server: &str, id: &str, start: bool) -> JuizResult<Value> {
let ec = {
let mut core_broker = system.core_broker().lock_mut()?;
let worker = core_broker.worker_mut();
match worker.ec_proxy_from_identifier(&id.to_owned()) {
Ok(ec) => ec,
Err(e) => match server_identifier(server, id) {
Some(remote_id) => worker.ec_proxy_from_identifier(&remote_id)?,
None => return Err(e),
},
}
};
let mut ec = juiz_lock(&ec)?;
if start {
ec.start()
} else {
ec.stop()
}
}
fn server_identifier(server: &str, id: &str) -> Option<String> {
let path = id.strip_prefix("core://core/")?;
Some(format!("{}/{path}", server.trim_end_matches('/')))
}
#[cfg(test)]
mod tests {
use super::server_identifier;
#[test]
fn server_identifier_rewrites_core_identifier() {
assert_eq!(
server_identifier(
"http://127.0.0.1:8000",
"core://core/execution_context/ec0::main_loop_ec"
),
Some("http://127.0.0.1:8000/execution_context/ec0::main_loop_ec".to_owned())
);
assert_eq!(
server_identifier(
"http://127.0.0.1:8000/",
"core://core/execution_context/ec0::main_loop_ec"
),
Some("http://127.0.0.1:8000/execution_context/ec0::main_loop_ec".to_owned())
);
}
#[test]
fn server_identifier_keeps_other_identifiers() {
assert_eq!(
server_identifier(
"http://127.0.0.1:8000",
"http://127.0.0.1:8000/execution_context/ec0::main_loop_ec"
),
None
);
}
}