reactive_graph_net_http/behaviour/component/
http.rs1use reactive_graph_behaviour_model_api::behaviour_validator;
2use reactive_graph_behaviour_model_api::prelude::*;
3use reactive_graph_behaviour_model_impl::entity_behaviour;
4use reactive_graph_graph::prelude::*;
5use reactive_graph_reactive_model_impl::ReactiveEntity;
6use serde_json::Value;
7use serde_json::json;
8use uuid::Uuid;
9
10use log::error;
11
12use reactive_graph_net_http_model::RequestProperties::METHOD;
13use reactive_graph_net_http_model::RequestProperties::PAYLOAD;
14use reactive_graph_net_http_model::RequestProperties::REQUEST_HEADERS;
15use reactive_graph_net_http_model::ResponseProperties::RESPONSE_HEADERS;
16use reactive_graph_net_http_model::ResponseProperties::STATUS;
17use reactive_graph_net_http_model::UrlProperties::URL;
18use reactive_graph_runtime_model::ActionProperties::TRIGGER;
19use reactive_graph_std_result_model::ResultObjectProperties::RESULT;
20
21entity_behaviour!(Http, HttpFactory, HttpFsm, HttpBehaviourTransitions, HttpValidator);
22
23behaviour_validator!(
24 HttpValidator,
25 Uuid,
26 ReactiveEntity,
27 METHOD.as_ref(),
28 PAYLOAD.as_ref(),
29 REQUEST_HEADERS.as_ref(),
30 RESPONSE_HEADERS.as_ref(),
31 RESULT.as_ref(),
32 STATUS.as_ref(),
33 URL.as_ref()
34);
35
36impl BehaviourInit<Uuid, ReactiveEntity> for HttpBehaviourTransitions {
37 fn init(&self) -> Result<(), BehaviourInitializationFailed> {
38 if self.reactive_instance.as_bool(TRIGGER).unwrap_or(false) {
39 send_request(&self.reactive_instance);
40 }
41 Ok(())
42 }
43}
44
45impl BehaviourConnect<Uuid, ReactiveEntity> for HttpBehaviourTransitions {
46 fn connect(&self) -> Result<(), BehaviourConnectFailed> {
47 let reactive_instance = self.reactive_instance.clone();
48 self.property_observers.observe_with_handle(TRIGGER.as_ref(), move |trigger: &Value| {
49 if !trigger.as_bool().unwrap_or(false) {
50 return;
51 }
52 send_request(&reactive_instance);
53 });
54 Ok(())
55 }
56}
57
58impl BehaviourShutdown<Uuid, ReactiveEntity> for HttpBehaviourTransitions {}
59impl BehaviourTransitions<Uuid, ReactiveEntity> for HttpBehaviourTransitions {}
60
61fn send_request(reactive_instance: &ReactiveEntity) {
62 let Some(method) = reactive_instance.as_string(METHOD) else {
63 return;
64 };
65 let Some(url) = reactive_instance.as_string(URL) else {
66 return;
67 };
68 let Some(request_headers) = reactive_instance.as_object(REQUEST_HEADERS) else {
69 return;
70 };
71 let Some(payload) = reactive_instance.get(PAYLOAD) else {
72 return;
73 };
74 let mut request = ureq::request(method.as_str(), url.as_str());
75 for (request_header, value) in request_headers.into_iter() {
76 if let Some(value) = value.as_str() {
77 request = request.set(request_header.as_ref(), value);
78 }
79 }
80 let result = request.send_json(payload);
81 match result {
82 Ok(response) => {
83 reactive_instance.set(STATUS, json!(response.status()));
84 let mut response_headers = json!({});
85 for header_name in response.headers_names() {
86 response_headers[header_name] = json!(response.header(header_name.as_str()));
87 }
88 reactive_instance.set(RESPONSE_HEADERS, response_headers);
89 match response.into_json() {
90 Ok(result) => {
91 reactive_instance.set(RESULT, result);
92 }
93 Err(e) => error!("Failed to parse response as JSON: {}", e.to_string()),
94 }
95 }
96 Err(e) => {
97 error!("Failed to send request: {}", e.to_string());
98 }
99 }
100}