142 lines
4.0 KiB
Rust
142 lines
4.0 KiB
Rust
//! # peach-jsonrpc-server
|
|
//!
|
|
//! A JSON-RPC server which exposes an API over HTTP.
|
|
|
|
use std::env;
|
|
use std::result::Result;
|
|
|
|
use jsonrpc_core::{IoHandler, Value};
|
|
use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation, ServerBuilder};
|
|
use log::info;
|
|
use miniserde::json;
|
|
use peach_stats::stats;
|
|
|
|
mod error;
|
|
use crate::error::JsonRpcServerError;
|
|
|
|
/// Create JSON-RPC I/O handler, add RPC methods and launch HTTP server.
|
|
pub fn run() -> Result<(), JsonRpcServerError> {
|
|
info!("Starting up.");
|
|
|
|
info!("Creating JSON-RPC I/O handler.");
|
|
let mut io = IoHandler::default();
|
|
|
|
io.add_sync_method("ping", |_| Ok(Value::String("success".to_string())));
|
|
|
|
// TODO: add blocks of methods according to provided flags
|
|
|
|
/* PEACH-STATS RPC METHODS */
|
|
|
|
io.add_sync_method("cpu_stats", move |_| {
|
|
info!("Fetching CPU statistics.");
|
|
let cpu = stats::cpu_stats().map_err(JsonRpcServerError::Stats)?;
|
|
let json_cpu = json::to_string(&cpu);
|
|
|
|
Ok(Value::String(json_cpu))
|
|
});
|
|
|
|
io.add_sync_method("cpu_stats_percent", move |_| {
|
|
info!("Fetching CPU statistics as percentages.");
|
|
let cpu = stats::cpu_stats_percent().map_err(JsonRpcServerError::Stats)?;
|
|
let json_cpu = json::to_string(&cpu);
|
|
|
|
Ok(Value::String(json_cpu))
|
|
});
|
|
|
|
io.add_sync_method("disk_usage", move |_| {
|
|
info!("Fetching disk usage statistics.");
|
|
let disks = stats::disk_usage().map_err(JsonRpcServerError::Stats)?;
|
|
let json_disks = json::to_string(&disks);
|
|
|
|
Ok(Value::String(json_disks))
|
|
});
|
|
|
|
io.add_sync_method("load_average", move |_| {
|
|
info!("Fetching system load average statistics.");
|
|
let avg = stats::load_average().map_err(JsonRpcServerError::Stats)?;
|
|
let json_avg = json::to_string(&avg);
|
|
|
|
Ok(Value::String(json_avg))
|
|
});
|
|
|
|
io.add_sync_method("mem_stats", move |_| {
|
|
info!("Fetching current memory statistics.");
|
|
let mem = stats::mem_stats().map_err(JsonRpcServerError::Stats)?;
|
|
let json_mem = json::to_string(&mem);
|
|
|
|
Ok(Value::String(json_mem))
|
|
});
|
|
|
|
io.add_sync_method("uptime", move |_| {
|
|
info!("Fetching system uptime.");
|
|
let uptime = stats::uptime().map_err(JsonRpcServerError::Stats)?;
|
|
let json_uptime = json::to_string(&uptime);
|
|
|
|
Ok(Value::String(json_uptime))
|
|
});
|
|
|
|
let http_server =
|
|
env::var("PEACH_JSONRPC_SERVER").unwrap_or_else(|_| "127.0.0.1:5110".to_string());
|
|
|
|
info!("Starting JSON-RPC server on {}.", http_server);
|
|
let server = ServerBuilder::new(io)
|
|
.cors(DomainsValidation::AllowOnly(vec![
|
|
AccessControlAllowOrigin::Null,
|
|
]))
|
|
.start_http(
|
|
&http_server
|
|
.parse()
|
|
.expect("Invalid HTTP address and port combination"),
|
|
)
|
|
.expect("Unable to start RPC server");
|
|
|
|
server.wait();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
use jsonrpc_core::{Error as JsonRpcError, ErrorCode};
|
|
use jsonrpc_test as test_rpc;
|
|
|
|
#[test]
|
|
fn rpc_success() {
|
|
let rpc = {
|
|
let mut io = IoHandler::new();
|
|
io.add_sync_method("rpc_success_response", |_| {
|
|
Ok(Value::String("success".into()))
|
|
});
|
|
test_rpc::Rpc::from(io)
|
|
};
|
|
|
|
assert_eq!(rpc.request("rpc_success_response", &()), r#""success""#);
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_parse_error() {
|
|
let rpc = {
|
|
let mut io = IoHandler::new();
|
|
io.add_sync_method("rpc_parse_error", |_| {
|
|
let e = JsonRpcError {
|
|
code: ErrorCode::ParseError,
|
|
message: String::from("Parse error"),
|
|
data: None,
|
|
};
|
|
Err(JsonRpcError::from(JsonRpcServerError::MissingParameter(e)))
|
|
});
|
|
test_rpc::Rpc::from(io)
|
|
};
|
|
|
|
assert_eq!(
|
|
rpc.request("rpc_parse_error", &()),
|
|
r#"{
|
|
"code": -32700,
|
|
"message": "Parse error"
|
|
}"#
|
|
);
|
|
}
|
|
}
|