#![allow(clippy::all, unused_imports, dead_code)]
use crate::{Actor, ActorBehavior, ClientBuilderExt, Message, Port};
use anyhow::{Error, Result};
use reflow_actor::{message::EncodableValue, ActorContext};
use reflow_actor_macro::actor;
use serde_json::{json, Value};
use std::collections::HashMap;
use std::time::Duration;
const BASE_URL: &str = "https://api.nasa.gov";
const ENV_KEY: &str = "NASA_API_KEY";
fn apply_auth(
config: &reflow_actor::ActorConfig,
mut builder: reqwest::RequestBuilder,
) -> Result<reqwest::RequestBuilder> {
let credential = config
.get_config_or_env(ENV_KEY)
.ok_or_else(|| anyhow::anyhow!("Missing env var: {}", ENV_KEY))?;
builder = builder.query(&[("api_key", &credential)]);
Ok(builder)
}
#[actor(
NasaReadApodActor,
inports::<100>(date, hd),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_read_apod(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/planetary/apod".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("date") {
query_pairs.push(("date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("hd") {
query_pairs.push(("hd", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /planetary/apod failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaSearchNeoActor,
inports::<100>(start_date, end_date),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_search_neo(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/neo/rest/v1/feed".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("start_date") {
query_pairs.push(("start_date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("end_date") {
query_pairs.push(("end_date", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /neo/rest/v1/feed failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaSearchAsteroidsActor,
inports::<100>(api_key, start_date, end_date, detailed),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_search_asteroids(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/neo/rest/v1/feed".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("start_date") {
query_pairs.push(("start_date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("end_date") {
query_pairs.push(("end_date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("detailed") {
query_pairs.push(("detailed", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /neo/rest/v1/feed failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaReadAsteroidActor,
inports::<100>(asteroid_id, api_key),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_read_asteroid(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/neo/rest/v1/neo/{asteroid_id}".to_string();
if let Some(val) = inputs.get("asteroid_id") {
endpoint = endpoint.replace("{{asteroid_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /neo/rest/v1/neo/{{asteroid_id}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
NasaListAsteroidsActor,
inports::<100>(api_key, page, size),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_asteroids(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/neo/rest/v1/neo/browse".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page") {
query_pairs.push(("page", super::message_to_str(val)));
}
if let Some(val) = inputs.get("size") {
query_pairs.push(("size", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /neo/rest/v1/neo/browse failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaSearchNasaImagesActor,
inports::<100>(q, center, description, keywords, location, media_type, nasa_id, photographer, title, year_start, year_end, page, page_size),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_search_nasa_images(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/search".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if let Some(val) = inputs.get("center") {
query_pairs.push(("center", super::message_to_str(val)));
}
if let Some(val) = inputs.get("description") {
query_pairs.push(("description", super::message_to_str(val)));
}
if let Some(val) = inputs.get("keywords") {
query_pairs.push(("keywords", super::message_to_str(val)));
}
if let Some(val) = inputs.get("location") {
query_pairs.push(("location", super::message_to_str(val)));
}
if let Some(val) = inputs.get("media_type") {
query_pairs.push(("media_type", super::message_to_str(val)));
}
if let Some(val) = inputs.get("nasa_id") {
query_pairs.push(("nasa_id", super::message_to_str(val)));
}
if let Some(val) = inputs.get("photographer") {
query_pairs.push(("photographer", super::message_to_str(val)));
}
if let Some(val) = inputs.get("title") {
query_pairs.push(("title", super::message_to_str(val)));
}
if let Some(val) = inputs.get("year_start") {
query_pairs.push(("year_start", super::message_to_str(val)));
}
if let Some(val) = inputs.get("year_end") {
query_pairs.push(("year_end", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page") {
query_pairs.push(("page", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page_size") {
query_pairs.push(("page_size", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /search failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaListEarthImageryActor,
inports::<100>(api_key, lat, lon, dim, date, cloud_score),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_earth_imagery(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/planetary/earth/imagery".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lat") {
query_pairs.push(("lat", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lon") {
query_pairs.push(("lon", super::message_to_str(val)));
}
if let Some(val) = inputs.get("dim") {
query_pairs.push(("dim", super::message_to_str(val)));
}
if let Some(val) = inputs.get("date") {
query_pairs.push(("date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("cloud_score") {
query_pairs.push(("cloud_score", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /planetary/earth/imagery failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaListEarthAssetsActor,
inports::<100>(api_key, lat, lon, dim, begin, end),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_earth_assets(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/planetary/earth/assets".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lat") {
query_pairs.push(("lat", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lon") {
query_pairs.push(("lon", super::message_to_str(val)));
}
if let Some(val) = inputs.get("dim") {
query_pairs.push(("dim", super::message_to_str(val)));
}
if let Some(val) = inputs.get("begin") {
query_pairs.push(("begin", super::message_to_str(val)));
}
if let Some(val) = inputs.get("end") {
query_pairs.push(("end", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /planetary/earth/assets failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaReadMarsRoverPhotosActor,
inports::<100>(rover, api_key, sol, earth_date, camera, page),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_read_mars_rover_photos(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/mars-photos/api/v1/rovers/{rover}/photos".to_string();
if let Some(val) = inputs.get("rover") {
endpoint = endpoint.replace("{{rover}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("sol") {
query_pairs.push(("sol", super::message_to_str(val)));
}
if let Some(val) = inputs.get("earth_date") {
query_pairs.push(("earth_date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("camera") {
query_pairs.push(("camera", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page") {
query_pairs.push(("page", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /mars-photos/api/v1/rovers/{{rover}}/photos failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
NasaReadMarsRoverActor,
inports::<100>(rover, api_key),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_read_mars_rover(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/mars-photos/api/v1/rovers/{rover}".to_string();
if let Some(val) = inputs.get("rover") {
endpoint = endpoint.replace("{{rover}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /mars-photos/api/v1/rovers/{{rover}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
NasaListEpicImagesActor,
inports::<100>(api_key),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_epic_images(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/EPIC/api/natural".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /EPIC/api/natural failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaListDonkiCmeActor,
inports::<100>(api_key, startDate, endDate),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_donki_cme(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/DONKI/CME".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("startDate") {
query_pairs.push(("startDate", super::message_to_str(val)));
}
if let Some(val) = inputs.get("endDate") {
query_pairs.push(("endDate", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /DONKI/CME failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaListDonkiFlrActor,
inports::<100>(api_key, startDate, endDate),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_donki_flr(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/DONKI/FLR".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("startDate") {
query_pairs.push(("startDate", super::message_to_str(val)));
}
if let Some(val) = inputs.get("endDate") {
query_pairs.push(("endDate", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /DONKI/FLR failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
NasaListDonkiGstActor,
inports::<100>(api_key, startDate, endDate),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn nasa_list_donki_gst(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/DONKI/GST".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("startDate") {
query_pairs.push(("startDate", super::message_to_str(val)));
}
if let Some(val) = inputs.get("endDate") {
query_pairs.push(("endDate", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /DONKI/GST failed: {}", e).into()),
);
}
}
Ok(output)
}