1use super::request::*;
2use super::processor::*;
3use crate::{base::*, requestor::*, SharedObjectStackDecID, UtilBuildDirFromObjectMapOutputRequest, UtilBuildDirFromObjectMapOutputResponse, UtilBuildFileOutputRequest, UtilBuildFileOutputResponse};
4use cyfs_base::*;
5
6use cyfs_core::{Zone, ZoneId};
7use http_types::{Method, Request, Response, Url};
8use std::sync::Arc;
9
10#[derive(Clone)]
11pub struct UtilRequestor {
12 dec_id: Option<SharedObjectStackDecID>,
13 requestor: HttpRequestorRef,
14 service_url: Url,
15}
16
17impl UtilRequestor {
18 pub fn new(dec_id: Option<SharedObjectStackDecID>, requestor: HttpRequestorRef) -> Self {
19 let addr = requestor.remote_addr();
20
21 let url = format!("http://{}/util/", addr);
22 let url = Url::parse(&url).unwrap();
23
24 Self {
25 dec_id,
26 requestor,
27 service_url: url,
28 }
29 }
30
31 pub fn into_processor(self) -> UtilOutputProcessorRef {
32 Arc::new(Box::new(self))
33 }
34
35 pub fn clone_processor(&self) -> UtilOutputProcessorRef {
36 self.clone().into_processor()
37 }
38
39 fn encode_common_headers(&self, com_req: &UtilRequestCommon, http_req: &mut Request) {
40 if let Some(dec_id) = &com_req.dec_id {
41 http_req.insert_header(cyfs_base::CYFS_DEC_ID, dec_id.to_string());
42 } else if let Some(dec_id) = &self.dec_id {
43 if let Some(dec_id) = dec_id.get() {
44 http_req.insert_header(cyfs_base::CYFS_DEC_ID, dec_id.to_string());
45 }
46 }
47
48 RequestorHelper::encode_opt_header_with_encoding(http_req, cyfs_base::CYFS_REQ_PATH, com_req.req_path.as_deref());
49
50 if let Some(target) = &com_req.target {
51 http_req.insert_header(cyfs_base::CYFS_TARGET, target.to_string());
52 }
53
54 http_req.insert_header(cyfs_base::CYFS_FLAGS, com_req.flags.to_string());
55 }
56
57 fn encode_get_device_request(&self, req: &UtilGetDeviceRequest) -> Request {
58 let url = self.service_url.join("device").unwrap();
59 let mut http_req = Request::new(Method::Get, url);
60 self.encode_common_headers(&req.common, &mut http_req);
61
62 http_req
63 }
64
65 async fn decode_get_device_response(
66 mut resp: Response,
67 ) -> BuckyResult<UtilGetDeviceResponse> {
68 let buf = resp.body_bytes().await.map_err(|e| {
69 let msg = format!("get_current_device failed, read body bytes error! {}", e);
70 error!("{}", msg);
71
72 BuckyError::from(msg)
73 })?;
74
75 let (device, _) = Device::raw_decode(&buf).map_err(|e| {
76 error!("decode device from resp bytes error: {}", e);
77 e
78 })?;
79
80 let device_id: DeviceId = device.desc().device_id().clone();
81
82 Ok(UtilGetDeviceResponse { device_id, device })
83 }
84
85 pub async fn get_device(
87 &self,
88 req: UtilGetDeviceRequest,
89 ) -> BuckyResult<UtilGetDeviceResponse> {
90 let http_req = self.encode_get_device_request(&req);
91
92 let mut resp = self.requestor.request(http_req).await?;
93
94 if resp.status().is_success() {
95 let resp = Self::decode_get_device_response(resp).await?;
96 info!("util get_device from non stack success: {}", resp);
97
98 Ok(resp)
99 } else {
100 let e = RequestorHelper::error_from_resp(&mut resp).await;
101 Err(e)
102 }
103 }
104
105 fn encode_get_zone_request(&self, req: UtilGetZoneRequest) -> Request {
106 let url = self.service_url.join("zone").unwrap();
107 let mut http_req = Request::new(Method::Post, url);
108 self.encode_common_headers(&req.common, &mut http_req);
109
110 RequestorHelper::encode_opt_header(&mut http_req, cyfs_base::CYFS_OBJECT_ID, &req.object_id);
111 if let Some(object_raw) = req.object_raw {
112 http_req.set_body(object_raw);
113 }
114
115 http_req
116 }
117 async fn decode_get_zone_response(
118 mut resp: Response,
119 ) -> BuckyResult<UtilGetZoneResponse> {
120 let zone: Zone = RequestorHelper::decode_raw_object_body(&mut resp).await?;
121 let zone_id: ZoneId = RequestorHelper::decode_header(&resp, cyfs_base::CYFS_ZONE_ID)?;
122
123 let device_id = RequestorHelper::decode_header(&resp, cyfs_base::CYFS_OOD_DEVICE_ID)?;
124
125 let resp = UtilGetZoneResponse {
126 zone,
127 zone_id,
128 device_id,
129 };
130
131 info!("util get_zone from non stack success: {}", resp);
132
133 Ok(resp)
134 }
135
136 pub async fn get_zone(
140 &self,
141 req: UtilGetZoneRequest,
142 ) -> BuckyResult<UtilGetZoneResponse> {
143 let http_req = self.encode_get_zone_request(req);
144
145 let mut resp = self.requestor.request(http_req).await?;
146
147 if resp.status().is_success() {
148 let resp = Self::decode_get_zone_response(resp).await?;
149
150 Ok(resp)
151 } else {
152 let e = RequestorHelper::error_from_resp(&mut resp).await;
153 Err(e)
154 }
155 }
156
157 fn encode_resolve_ood_request(&self, req: &UtilResolveOODRequest) -> Request {
158 let url = self.service_url.join("resolve_ood").unwrap();
159
160 let mut http_req = Request::new(Method::Get, url);
162 RequestorHelper::encode_header(&mut http_req, cyfs_base::CYFS_OBJECT_ID, &req.object_id);
163 RequestorHelper::encode_opt_header(&mut http_req, cyfs_base::CYFS_OWNER_ID, &req.owner_id);
164
165 self.encode_common_headers(&req.common, &mut http_req);
166
167 http_req
168 }
169
170 pub async fn resolve_ood(
171 &self,
172 req: UtilResolveOODRequest,
173 ) -> BuckyResult<UtilResolveOODResponse> {
174 let http_req = self.encode_resolve_ood_request(&req);
175 let mut resp = self.requestor.request(http_req).await?;
176
177 if resp.status().is_success() {
178 let resp = RequestorHelper::decode_json_body(&mut resp).await?;
179 Ok(resp)
180 } else {
181 let e = RequestorHelper::error_from_resp(&mut resp).await;
182 Err(e)
183 }
184 }
185
186 fn encode_get_ood_status_request(&self, req: UtilGetOODStatusRequest) -> Request {
187 let url = self.service_url.join("ood_status").unwrap();
188 let mut http_req = Request::new(Method::Get, url);
189 self.encode_common_headers(&req.common, &mut http_req);
190
191 http_req
192 }
193
194 pub async fn get_ood_status(
195 &self,
196 req: UtilGetOODStatusRequest,
197 ) -> BuckyResult<UtilGetOODStatusResponse> {
198 let http_req = self.encode_get_ood_status_request(req);
199
200 let mut resp = self.requestor.request(http_req).await?;
201
202 if resp.status().is_success() {
203 let resp = resp.body_json().await.map_err(|e| {
204 let msg = format!("parse get_ood_status resp body error! err={}", e);
205 error!("{}", msg);
206 BuckyError::new(BuckyErrorCode::InvalidData, msg)
207 })?;
208
209 Ok(resp)
210 } else {
211 let e = RequestorHelper::error_from_resp(&mut resp).await;
212 error!(
213 "util get_ood_status failed: status={}, {}",
214 resp.status(),
215 e
216 );
217
218 Err(e)
219 }
220 }
221
222 fn encode_get_noc_info_request(&self, req: UtilGetNOCInfoRequest) -> Request {
223 let url = self.service_url.join("noc_info").unwrap();
224 let mut http_req = Request::new(Method::Get, url);
225 self.encode_common_headers(&req.common, &mut http_req);
226
227 http_req
228 }
229
230 pub async fn get_noc_info(
231 &self,
232 req: UtilGetNOCInfoRequest,
233 ) -> BuckyResult<UtilGetNOCInfoResponse> {
234 let http_req = self.encode_get_noc_info_request(req);
235
236 let mut resp = self.requestor.request(http_req).await?;
237
238 if resp.status().is_success() {
239 let resp = resp.body_json().await.map_err(|e| {
240 let msg = format!("parse get_noc_stat resp body error! err={}", e);
241 error!("{}", msg);
242 BuckyError::new(BuckyErrorCode::InvalidData, msg)
243 })?;
244
245 Ok(resp)
246 } else {
247 let e = RequestorHelper::error_from_resp(&mut resp).await;
248 error!("util get_noc_stat failed: status={}, {}", resp.status(), e);
249
250 Err(e)
251 }
252 }
253
254 fn encode_get_network_access_info_request(
255 &self,
256 req: UtilGetNetworkAccessInfoRequest,
257 ) -> Request {
258 let url = self.service_url.join("network_access_info").unwrap();
259 let mut http_req = Request::new(Method::Get, url);
260 self.encode_common_headers(&req.common, &mut http_req);
261
262 http_req
263 }
264
265 pub async fn get_network_access_info(
266 &self,
267 req: UtilGetNetworkAccessInfoRequest,
268 ) -> BuckyResult<UtilGetNetworkAccessInfoResponse> {
269 let http_req = self.encode_get_network_access_info_request(req);
270
271 let mut resp = self.requestor.request(http_req).await?;
272
273 if resp.status().is_success() {
274 let resp = RequestorHelper::decode_json_body(&mut resp)
275 .await
276 .map_err(|e| {
277 let msg = format!("parse get_network_access_info resp body error! err={}", e);
278 error!("{}", msg);
279 BuckyError::new(BuckyErrorCode::InvalidData, msg)
280 })?;
281
282 Ok(resp)
283 } else {
284 let e = RequestorHelper::error_from_resp(&mut resp).await;
285 error!(
286 "util get_network_access_info failed: status={}, {}",
287 resp.status(),
288 e
289 );
290
291 Err(e)
292 }
293 }
294
295 fn encode_get_device_static_info_request(
296 &self,
297 req: UtilGetDeviceStaticInfoRequest,
298 ) -> Request {
299 let url = self.service_url.join("device_static_info").unwrap();
300 let mut http_req = Request::new(Method::Get, url);
301 self.encode_common_headers(&req.common, &mut http_req);
302
303 http_req
304 }
305
306 pub async fn get_device_static_info(
307 &self,
308 req: UtilGetDeviceStaticInfoRequest,
309 ) -> BuckyResult<UtilGetDeviceStaticInfoResponse> {
310 let http_req = self.encode_get_device_static_info_request(req);
311
312 let mut resp = self.requestor.request(http_req).await?;
313
314 if resp.status().is_success() {
315 let content = RequestorHelper::decode_json_body(&mut resp)
316 .await
317 .map_err(|e| {
318 let msg = format!("parse get_device_static_info resp body error! err={}", e);
319 error!("{}", msg);
320 BuckyError::new(BuckyErrorCode::InvalidData, msg)
321 })?;
322
323 Ok(content)
324 } else {
325 let e = RequestorHelper::error_from_resp(&mut resp).await;
326 error!(
327 "util get_device_static_info failed: status={}, {}",
328 resp.status(),
329 e
330 );
331
332 Err(e)
333 }
334 }
335
336 fn encode_get_system_info_request(&self, req: UtilGetSystemInfoRequest) -> Request {
337 let url = self.service_url.join("system_info").unwrap();
338 let mut http_req = Request::new(Method::Get, url);
339 self.encode_common_headers(&req.common, &mut http_req);
340
341 http_req
342 }
343
344 pub async fn get_system_info(
345 &self,
346 req: UtilGetSystemInfoRequest,
347 ) -> BuckyResult<UtilGetSystemInfoResponse> {
348 let http_req = self.encode_get_system_info_request(req);
349
350 let mut resp = self.requestor.request(http_req).await?;
351
352 if resp.status().is_success() {
353 let content = resp.body_json().await.map_err(|e| {
354 let msg = format!("parse get_system_info resp body error! err={}", e);
355 error!("{}", msg);
356 BuckyError::new(BuckyErrorCode::InvalidData, msg)
357 })?;
358
359 Ok(content)
360 } else {
361 let e = RequestorHelper::error_from_resp(&mut resp).await;
362 error!(
363 "util get_system_info failed: status={}, {}",
364 resp.status(),
365 e
366 );
367
368 Err(e)
369 }
370 }
371
372 fn encode_get_version_info_request(&self, req: UtilGetVersionInfoRequest) -> Request {
373 let url = self.service_url.join("version_info").unwrap();
374 let mut http_req = Request::new(Method::Get, url);
375 self.encode_common_headers(&req.common, &mut http_req);
376
377 http_req
378 }
379
380 pub async fn get_version_info(
381 &self,
382 req: UtilGetVersionInfoRequest,
383 ) -> BuckyResult<UtilGetVersionInfoResponse> {
384 let http_req = self.encode_get_version_info_request(req);
385
386 let mut resp = self.requestor.request(http_req).await?;
387
388 if resp.status().is_success() {
389 let content = RequestorHelper::decode_json_body(&mut resp)
390 .await
391 .map_err(|e| {
392 let msg = format!("parse get_version_info resp body error! err={}", e);
393 error!("{}", msg);
394 BuckyError::new(BuckyErrorCode::InvalidData, msg)
395 })?;
396
397 Ok(content)
398 } else {
399 let e = RequestorHelper::error_from_resp(&mut resp).await;
400 error!(
401 "util get_version_info failed: status={}, {}",
402 resp.status(),
403 e
404 );
405
406 Err(e)
407 }
408 }
409
410 pub async fn build_file_object(
411 &self,
412 req: UtilBuildFileOutputRequest
413 ) -> BuckyResult<UtilBuildFileOutputResponse> {
414 let url = self.service_url.join("build_file").unwrap();
415 let mut http_req = Request::new(Method::Post, url);
416 self.encode_common_headers(&req.common, &mut http_req);
417 let body = req.encode_string();
418 http_req.set_body(body);
419
420 let mut resp = self.requestor.request(http_req).await?;
421 if resp.status().is_success() {
422 let content = RequestorHelper::decode_json_body(&mut resp)
423 .await
424 .map_err(|e| {
425 let msg = format!("parse build file resp body error! err={}", e);
426 error!("{}", msg);
427 BuckyError::new(BuckyErrorCode::InvalidData, msg)
428 })?;
429
430 Ok(content)
431 } else {
432 let e = RequestorHelper::error_from_resp(&mut resp).await;
433 error!(
434 "util build_file_object failed: status={}, {}",
435 resp.status(),
436 e
437 );
438
439 Err(e)
440 }
441 }
442
443 pub async fn build_dir_from_object_map(
444 &self,
445 req: UtilBuildDirFromObjectMapOutputRequest
446 ) -> BuckyResult<UtilBuildDirFromObjectMapOutputResponse> {
447 let url = self.service_url.join("build_dir_from_object_map").unwrap();
448 let mut http_req = Request::new(Method::Post, url);
449 self.encode_common_headers(&req.common, &mut http_req);
450 let body = req.encode_string();
451 http_req.set_body(body);
452
453 let mut resp = self.requestor.request(http_req).await?;
454 if resp.status().is_success() {
455 let content = RequestorHelper::decode_json_body(&mut resp)
456 .await
457 .map_err(|e| {
458 let msg = format!("parse build dir resp body error! err={}", e);
459 error!("{}", msg);
460 BuckyError::new(BuckyErrorCode::InvalidData, msg)
461 })?;
462
463 Ok(content)
464 } else {
465 let e = RequestorHelper::error_from_resp(&mut resp).await;
466 error!(
467 "util build_dir_from_object_map failed: status={}, {}",
468 resp.status(),
469 e
470 );
471
472 Err(e)
473 }
474 }
475}
476
477#[async_trait::async_trait]
478impl UtilOutputProcessor for UtilRequestor {
479 async fn get_device(
480 &self,
481 req: UtilGetDeviceRequest,
482 ) -> BuckyResult<UtilGetDeviceResponse> {
483 Self::get_device(&self, req).await
484 }
485
486 async fn get_zone(
487 &self,
488 req: UtilGetZoneRequest,
489 ) -> BuckyResult<UtilGetZoneResponse> {
490 Self::get_zone(&self, req).await
491 }
492
493 async fn resolve_ood(
494 &self,
495 req: UtilResolveOODRequest,
496 ) -> BuckyResult<UtilResolveOODResponse> {
497 Self::resolve_ood(&self, req).await
498 }
499
500 async fn get_ood_status(
501 &self,
502 req: UtilGetOODStatusRequest,
503 ) -> BuckyResult<UtilGetOODStatusResponse> {
504 Self::get_ood_status(&self, req).await
505 }
506
507 async fn get_noc_info(
508 &self,
509 req: UtilGetNOCInfoRequest,
510 ) -> BuckyResult<UtilGetNOCInfoResponse> {
511 Self::get_noc_info(&self, req).await
512 }
513
514 async fn get_network_access_info(
515 &self,
516 req: UtilGetNetworkAccessInfoRequest,
517 ) -> BuckyResult<UtilGetNetworkAccessInfoResponse> {
518 Self::get_network_access_info(&self, req).await
519 }
520
521 async fn get_device_static_info(
522 &self,
523 req: UtilGetDeviceStaticInfoRequest,
524 ) -> BuckyResult<UtilGetDeviceStaticInfoResponse> {
525 Self::get_device_static_info(&self, req).await
526 }
527
528 async fn get_system_info(
529 &self,
530 req: UtilGetSystemInfoRequest,
531 ) -> BuckyResult<UtilGetSystemInfoResponse> {
532 Self::get_system_info(&self, req).await
533 }
534
535 async fn get_version_info(
536 &self,
537 req: UtilGetVersionInfoRequest,
538 ) -> BuckyResult<UtilGetVersionInfoResponse> {
539 Self::get_version_info(&self, req).await
540 }
541
542 async fn build_file_object(&self, req: UtilBuildFileOutputRequest) -> BuckyResult<UtilBuildFileOutputResponse> {
543 Self::build_file_object(self, req).await
544 }
545
546 async fn build_dir_from_object_map(&self, req: UtilBuildDirFromObjectMapOutputRequest)
547 -> BuckyResult<UtilBuildDirFromObjectMapOutputResponse> {
548 Self::build_dir_from_object_map(self, req).await
549 }
550}