WIP on proxy pulse map
This commit is contained in:
+1
-1
@@ -322,7 +322,7 @@ async fn gen_timebin(
|
|||||||
channel_path: &Path,
|
channel_path: &Path,
|
||||||
config: &ChannelConfig,
|
config: &ChannelConfig,
|
||||||
split: u32,
|
split: u32,
|
||||||
node: &Node,
|
_node: &Node,
|
||||||
ensemble: &Ensemble,
|
ensemble: &Ensemble,
|
||||||
gen_var: &GenVar,
|
gen_var: &GenVar,
|
||||||
) -> Result<GenTimebinRes, Error> {
|
) -> Result<GenTimebinRes, Error> {
|
||||||
|
|||||||
@@ -106,6 +106,15 @@ where
|
|||||||
|
|
||||||
impl<F> UnwindSafe for Cont<F> {}
|
impl<F> UnwindSafe for Cont<F> {}
|
||||||
|
|
||||||
|
pub fn response_err<T>(status: StatusCode, msg: T) -> Result<Response<Body>, Error>
|
||||||
|
where
|
||||||
|
T: AsRef<str>,
|
||||||
|
{
|
||||||
|
let msg = format!("Error:\n\n{}\n\nDocumentation:\nhttps://data-api.psi.ch/api/1/documentation/\nhttps://data-api.psi.ch/api/4/documentation/", msg.as_ref());
|
||||||
|
let ret = response(status).body(Body::from(msg))?;
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! static_http {
|
macro_rules! static_http {
|
||||||
($path:expr, $tgt:expr, $tgtex:expr, $ctype:expr) => {
|
($path:expr, $tgt:expr, $tgtex:expr, $ctype:expr) => {
|
||||||
if $path == concat!("/api/4/documentation/", $tgt) {
|
if $path == concat!("/api/4/documentation/", $tgt) {
|
||||||
|
|||||||
+67
-1
@@ -9,6 +9,7 @@ use futures_util::pin_mut;
|
|||||||
use http::{Method, StatusCode};
|
use http::{Method, StatusCode};
|
||||||
use hyper::service::{make_service_fn, service_fn};
|
use hyper::service::{make_service_fn, service_fn};
|
||||||
use hyper::{Body, Request, Response, Server};
|
use hyper::{Body, Request, Response, Server};
|
||||||
|
use hyper_tls::HttpsConnector;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use netpod::log::*;
|
use netpod::log::*;
|
||||||
use netpod::{
|
use netpod::{
|
||||||
@@ -70,6 +71,8 @@ async fn proxy_http_service_try(req: Request<Body>, proxy_config: &ProxyConfig)
|
|||||||
Err(Error::with_msg("todo"))
|
Err(Error::with_msg("todo"))
|
||||||
} else if path == "/api/1/query" {
|
} else if path == "/api/1/query" {
|
||||||
Ok(proxy_api1_single_backend_query(req, proxy_config).await?)
|
Ok(proxy_api1_single_backend_query(req, proxy_config).await?)
|
||||||
|
} else if path.starts_with("/api/1/map/pulse/") {
|
||||||
|
Ok(proxy_api1_map_pulse(req, proxy_config).await?)
|
||||||
} else if path.starts_with("/api/1/gather/") {
|
} else if path.starts_with("/api/1/gather/") {
|
||||||
Ok(gather_json_2_v1(req, "/api/1/gather/", proxy_config).await?)
|
Ok(gather_json_2_v1(req, "/api/1/gather/", proxy_config).await?)
|
||||||
} else if path == "/api/4/backends" {
|
} else if path == "/api/4/backends" {
|
||||||
@@ -112,7 +115,7 @@ async fn proxy_http_service_try(req: Request<Body>, proxy_config: &ProxyConfig)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(response(StatusCode::NOT_FOUND).body(Body::from(format!(
|
Ok(response(StatusCode::NOT_FOUND).body(Body::from(format!(
|
||||||
"Sorry, not found: {:?} {:?} {:?}",
|
"Sorry, proxy can not find: {:?} {:?} {:?}",
|
||||||
req.method(),
|
req.method(),
|
||||||
req.uri().path(),
|
req.uri().path(),
|
||||||
req.uri().query(),
|
req.uri().query(),
|
||||||
@@ -298,6 +301,69 @@ pub async fn channel_search(req: Request<Body>, proxy_config: &ProxyConfig) -> R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn proxy_api1_map_pulse(req: Request<Body>, proxy_config: &ProxyConfig) -> Result<Response<Body>, Error> {
|
||||||
|
let s2 = format!("http://dummy/{}", req.uri());
|
||||||
|
info!("s2: {:?}", s2);
|
||||||
|
let url = Url::parse(&s2)?;
|
||||||
|
let mut backend = None;
|
||||||
|
for (k, v) in url.query_pairs() {
|
||||||
|
if k == "backend" {
|
||||||
|
backend = Some(v.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let backend = if let Some(backend) = backend {
|
||||||
|
backend
|
||||||
|
} else {
|
||||||
|
return Ok(super::response_err(
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
"Required parameter `backend` not specified.",
|
||||||
|
)?);
|
||||||
|
};
|
||||||
|
let pulseid = if let Some(k) = url.path_segments() {
|
||||||
|
if let Some(k) = k.rev().next() {
|
||||||
|
if let Ok(k) = k.to_string().parse::<u64>() {
|
||||||
|
k
|
||||||
|
} else {
|
||||||
|
return Ok(super::response_err(
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
"Can not parse parameter `pulseid`.",
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(super::response_err(
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
"Can not parse parameter `pulseid`.",
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(super::response_err(
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
"Required parameter `pulseid` not specified.",
|
||||||
|
)?);
|
||||||
|
};
|
||||||
|
if backend == "sf-databuffer" {
|
||||||
|
if proxy_config.search_hosts.len() == 1 {
|
||||||
|
let url = format!("http://sf-daqbuf-21:8380/api/1/map/pulse/{}", pulseid);
|
||||||
|
let req = Request::builder().method(Method::GET).uri(url).body(Body::empty())?;
|
||||||
|
let res = hyper::Client::new().request(req).await?;
|
||||||
|
let ret = response(StatusCode::OK).body(res.into_body())?;
|
||||||
|
Ok(ret)
|
||||||
|
} else {
|
||||||
|
let url = format!("https://sf-data-api.psi.ch/api/1/map/pulse/{}", pulseid);
|
||||||
|
let req = Request::builder().method(Method::GET).uri(url).body(Body::empty())?;
|
||||||
|
let https = HttpsConnector::new();
|
||||||
|
let res = hyper::Client::builder().build(https).request(req).await?;
|
||||||
|
let ret = response(StatusCode::OK).body(res.into_body())?;
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(super::response_err(
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
format!("backend \"{}\" not supported for this action", backend),
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn proxy_api1_single_backend_query(
|
pub async fn proxy_api1_single_backend_query(
|
||||||
_req: Request<Body>,
|
_req: Request<Body>,
|
||||||
_proxy_config: &ProxyConfig,
|
_proxy_config: &ProxyConfig,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::time::Instant;
|
||||||
use std::{io::SeekFrom, path::PathBuf};
|
use std::{io::SeekFrom, path::PathBuf};
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
@@ -326,6 +327,7 @@ async fn update_task(do_abort: Arc<AtomicUsize>, node_config: NodeConfigCached)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
info!("Start update task");
|
info!("Start update task");
|
||||||
|
let ts1 = Instant::now();
|
||||||
match IndexFullHttpFunction::index(&node_config).await {
|
match IndexFullHttpFunction::index(&node_config).await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -333,7 +335,9 @@ async fn update_task(do_abort: Arc<AtomicUsize>, node_config: NodeConfigCached)
|
|||||||
tokio::time::sleep(Duration::from_millis(5000)).await;
|
tokio::time::sleep(Duration::from_millis(5000)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("Done update task");
|
let ts2 = Instant::now();
|
||||||
|
let dt = ts2.duration_since(ts1).as_secs_f64() * 1e3;
|
||||||
|
info!("Done update task {:.0} ms", dt);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ Currently available backends:
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href="#channel-search-names">Channel search, with return of channel names</a></li>
|
<li><a href="#channel-search-names">Channel search, with return of channel names</a></li>
|
||||||
<li><a href="#channel-search-configs">Channel search, with return of channel configurations</a></li>
|
<li><a href="#channel-search-configs">Channel search, with return of channel configurations</a></li>
|
||||||
|
<li><a href="#map-pulse">Map pulse-id to timestamp (for SwissFEL)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
@@ -148,6 +149,19 @@ QUERY='{ "regex": "LSCP9:CH0", "backends": ["sf-databuffer"] }'
|
|||||||
curl -H 'Content-Type: application/json' -H 'Accept: application/json' -d "$QUERY" https://data-api.psi.ch/api/1/channels/config
|
curl -H 'Content-Type: application/json' -H 'Accept: application/json' -d "$QUERY" https://data-api.psi.ch/api/1/channels/config
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<a id="map-pulse"></a>
|
||||||
|
<h2>Map pulse-id to timestamp (SwissFEL)</h2>
|
||||||
|
<p><strong>Method:</strong> GET</p>
|
||||||
|
<p><strong>URL:</strong> https://data-api.psi.ch/api/1/map/pulse/PULSEID</p>
|
||||||
|
<p><strong>Result body example:</strong></p>
|
||||||
|
<pre>1677392847564</pre>
|
||||||
|
<h4>CURL example:</h4>
|
||||||
|
<pre>
|
||||||
|
curl -H 'Content-Type: application/json' -H 'Accept: application/json' https://data-api.psi.ch/api/1/map/pulse/7461843
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
<h2>Feedback and comments</h2>
|
<h2>Feedback and comments</h2>
|
||||||
<p>Feedback is very much appreciated:</p>
|
<p>Feedback is very much appreciated:</p>
|
||||||
<p>dominik.werder@psi.ch</p>
|
<p>dominik.werder@psi.ch</p>
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
<h1>Databuffer API 4 Documentation</h1>
|
<h1>Databuffer API 4 Documentation</h1>
|
||||||
|
|
||||||
<p>Documented here is the databuffer http api 4. The "original" unversioned api is documented at
|
<p>Documented here is the databuffer http api 4. The "original" unversioned api is documented at
|
||||||
<a href="https://git.psi.ch/sf_daq/ch.psi.daq.databuffer/blob/master/ch.psi.daq.queryrest/Readme.md">this location</a>.</p>
|
<a href="https://git.psi.ch/sf_daq/ch.psi.daq.databuffer/blob/master/ch.psi.daq.queryrest/Readme.md">this location</a>.</p>
|
||||||
|
<p>API version 1:
|
||||||
|
<a href="https://data-api.psi.ch/api/1/documentation/">https://data-api.psi.ch/api/1/documentation/</a></p>
|
||||||
<p>In order to keep the api surface as small as possible in comparison to api 0, we add functionality on demand,
|
<p>In order to keep the api surface as small as possible in comparison to api 0, we add functionality on demand,
|
||||||
so please feel free to create some Jira ticket!</p>
|
so please feel free to create some Jira ticket!</p>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user