feat,fix: add `get` cli command, cli commands don't panic
parent
d3c5d182af
commit
04d54f6e43
|
@ -23,9 +23,13 @@ lazy_static! {
|
||||||
upend::common::build::PROJECT_NAME,
|
upend::common::build::PROJECT_NAME,
|
||||||
upend::common::build::PKG_VERSION
|
upend::common::build::PKG_VERSION
|
||||||
);
|
);
|
||||||
|
|
||||||
pub static ref REQWEST_CLIENT: reqwest::blocking::Client = reqwest::blocking::Client::builder()
|
pub static ref REQWEST_CLIENT: reqwest::blocking::Client = reqwest::blocking::Client::builder()
|
||||||
.user_agent(APP_USER_AGENT.as_str())
|
.user_agent(APP_USER_AGENT.as_str())
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
pub static ref REQWEST_ASYNC_CLIENT: reqwest::Client = reqwest::Client::builder()
|
||||||
|
.user_agent(APP_USER_AGENT.as_str())
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate upend;
|
extern crate upend;
|
||||||
use crate::common::{get_static_dir, REQWEST_CLIENT};
|
use crate::common::{get_static_dir, REQWEST_ASYNC_CLIENT};
|
||||||
use actix_cors::Cors;
|
use actix_cors::Cors;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::{middleware, App, HttpServer};
|
use actix_web::{middleware, App, HttpServer};
|
||||||
|
@ -63,12 +63,24 @@ enum Commands {
|
||||||
#[arg(short, long, default_value = "tsv")]
|
#[arg(short, long, default_value = "tsv")]
|
||||||
format: OutputFormat,
|
format: OutputFormat,
|
||||||
},
|
},
|
||||||
|
Get {
|
||||||
|
/// URL of the UpEnd instance to query.
|
||||||
|
#[arg(short, long, default_value = "http://localhost:8093")]
|
||||||
|
url: Url,
|
||||||
|
/// The address of the entity; prefix a filepath by `=` to insert its hash.
|
||||||
|
entity: String,
|
||||||
|
/// The attribute to get the value(s) of. Optional.
|
||||||
|
attribute: Option<String>,
|
||||||
|
/// Output format
|
||||||
|
#[arg(short, long, default_value = "tsv")]
|
||||||
|
format: OutputFormat,
|
||||||
|
},
|
||||||
/// Insert an entry into an UpEnd server instance.
|
/// Insert an entry into an UpEnd server instance.
|
||||||
Insert {
|
Insert {
|
||||||
/// URL of the UpEnd instance to query.
|
/// URL of the UpEnd instance to query.
|
||||||
#[arg(short, long)]
|
#[arg(short, long, default_value = "http://localhost:8093")]
|
||||||
url: Option<Url>,
|
url: Url,
|
||||||
/// The address of the entity; prefix a filepath by `@` to insert its hash.
|
/// The address of the entity; prefix a filepath by `=` to insert its hash.
|
||||||
entity: String,
|
entity: String,
|
||||||
/// The attribute of the entry.
|
/// The attribute of the entry.
|
||||||
attribute: String,
|
attribute: String,
|
||||||
|
@ -196,21 +208,73 @@ async fn main() -> Result<()> {
|
||||||
})
|
})
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
debug!("Final query: {}", query);
|
|
||||||
|
|
||||||
let api_url = url.join("/api/query")?;
|
let api_url = url.join("/api/query")?;
|
||||||
|
|
||||||
debug!("Querying \"{}\"", api_url);
|
debug!("Querying \"{}\": {}", api_url, query);
|
||||||
let response = REQWEST_CLIENT.post(api_url).body(query).send()?;
|
let response = REQWEST_ASYNC_CLIENT.post(api_url).body(query).send().await?;
|
||||||
|
|
||||||
response.error_for_status_ref()?;
|
response.error_for_status_ref()?;
|
||||||
|
|
||||||
match format {
|
match format {
|
||||||
OutputFormat::Json | OutputFormat::Raw => println!("{}", response.text()?),
|
OutputFormat::Json | OutputFormat::Raw => println!("{}", response.text().await?),
|
||||||
OutputFormat::Tsv => {
|
OutputFormat::Tsv => {
|
||||||
eprintln!("entity\tattribute\tvalue\ttimestamp\tprovenance");
|
eprintln!("entity\tattribute\tvalue\ttimestamp\tprovenance");
|
||||||
response
|
response
|
||||||
.json::<HashMap<String, serde_json::Value>>()?
|
.json::<HashMap<String, serde_json::Value>>().await?
|
||||||
|
.iter()
|
||||||
|
.for_each(|(_, entry)| {
|
||||||
|
println!(
|
||||||
|
"{}\t{}\t{}\t{}\t{}",
|
||||||
|
entry.get("entity").and_then(|e| e.as_str()).unwrap(),
|
||||||
|
entry.get("attribute").and_then(|a| a.as_str()).unwrap(),
|
||||||
|
entry.get("value").and_then(|v| v.get("c")).unwrap(),
|
||||||
|
entry.get("timestamp").and_then(|t| t.as_str()).unwrap(),
|
||||||
|
entry.get("provenance").and_then(|p| p.as_str()).unwrap(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Commands::Get {
|
||||||
|
url,
|
||||||
|
entity,
|
||||||
|
attribute,
|
||||||
|
format,
|
||||||
|
} => {
|
||||||
|
let api_url = url.join("/api/obj")?;
|
||||||
|
|
||||||
|
let entity = match entity {
|
||||||
|
entity if entity.starts_with('=') => hash_path(&entity[1..])?.to_string(),
|
||||||
|
entity if entity.starts_with("http") => Address::Url(entity.parse()?).to_string(),
|
||||||
|
_ => entity,
|
||||||
|
};
|
||||||
|
|
||||||
|
let query = format!(
|
||||||
|
"(matches @{} {} ?)",
|
||||||
|
entity,
|
||||||
|
attribute
|
||||||
|
.map(|a| format!("\"{a}\""))
|
||||||
|
.unwrap_or("?".to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
debug!("Querying \"{}\": {}", api_url, query);
|
||||||
|
let response = REQWEST_ASYNC_CLIENT
|
||||||
|
.get(api_url)
|
||||||
|
.body(query)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
response.error_for_status_ref()?;
|
||||||
|
|
||||||
|
match format {
|
||||||
|
OutputFormat::Json | OutputFormat::Raw => println!("{}", response.text().await?),
|
||||||
|
OutputFormat::Tsv => {
|
||||||
|
eprintln!("entity\tattribute\tvalue\ttimestamp\tprovenance");
|
||||||
|
response
|
||||||
|
.json::<HashMap<String, serde_json::Value>>()
|
||||||
|
.await?
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|(_, entry)| {
|
.for_each(|(_, entry)| {
|
||||||
println!(
|
println!(
|
||||||
|
@ -234,7 +298,6 @@ async fn main() -> Result<()> {
|
||||||
value,
|
value,
|
||||||
format: _,
|
format: _,
|
||||||
} => {
|
} => {
|
||||||
let url = url.unwrap_or("http://localhost:8093".parse().unwrap());
|
|
||||||
let api_url = url.join("/api/obj")?;
|
let api_url = url.join("/api/obj")?;
|
||||||
|
|
||||||
let entity = match entity {
|
let entity = match entity {
|
||||||
|
@ -252,15 +315,15 @@ async fn main() -> Result<()> {
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("Inserting {:?} at \"{}\"", body, api_url);
|
debug!("Inserting {:?} at \"{}\"", body, api_url);
|
||||||
let response = REQWEST_CLIENT.put(api_url).json(&body).send()?;
|
let response = REQWEST_ASYNC_CLIENT.put(api_url).json(&body).send().await?;
|
||||||
|
|
||||||
match response.error_for_status_ref() {
|
match response.error_for_status_ref() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let data: Vec<String> = response.json()?;
|
let data: Vec<String> = response.json().await?;
|
||||||
Ok(println!("{}", data[0]))
|
Ok(println!("{}", data[0]))
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("{}", response.text()?);
|
error!("{}", response.text().await?);
|
||||||
Err(err.into())
|
Err(err.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +465,10 @@ async fn main() -> Result<()> {
|
||||||
|
|
||||||
let app = App::new()
|
let app = App::new()
|
||||||
.wrap(cors)
|
.wrap(cors)
|
||||||
.wrap(middleware::DefaultHeaders::new().add(("UPEND-VERSION", upend::common::build::PKG_VERSION)))
|
.wrap(
|
||||||
|
middleware::DefaultHeaders::new()
|
||||||
|
.add(("UPEND-VERSION", upend::common::build::PKG_VERSION)),
|
||||||
|
)
|
||||||
.app_data(actix_web::web::PayloadConfig::new(4_294_967_296))
|
.app_data(actix_web::web::PayloadConfig::new(4_294_967_296))
|
||||||
.app_data(Data::new(state.clone()))
|
.app_data(Data::new(state.clone()))
|
||||||
.wrap(middleware::Logger::default().exclude("/api/jobs"))
|
.wrap(middleware::Logger::default().exclude("/api/jobs"))
|
||||||
|
|
Loading…
Reference in New Issue