From 8618bcb6eca2441433c47513858d4741e1ce7c11 Mon Sep 17 00:00:00 2001 From: Super User Date: Mon, 9 Jun 2025 23:24:34 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=B0=81=E8=A3=85CreateDevice=20CreateProf?= =?UTF-8?q?ile=20CreateProfileForApplication=20CreateProfileForDataType=20?= =?UTF-8?q?CreateStrategy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers/datamgr/route.rs | 243 +++++++++++++++++++++++++++- 1 file changed, 240 insertions(+), 3 deletions(-) diff --git a/src/cores/handlers/datamgr/route.rs b/src/cores/handlers/datamgr/route.rs index 02e617c..e23e72b 100644 --- a/src/cores/handlers/datamgr/route.rs +++ b/src/cores/handlers/datamgr/route.rs @@ -944,7 +944,7 @@ pub async fn subscribe_handler( } } - Ok(serde_json::json!("Subscribe Ok")) + Ok(json!("Subscribe Ok")) } // 获取消息处理函数 @@ -1206,7 +1206,11 @@ pub struct CallbackContext { static RESPONSE_MAP: Lazy>>>> = Lazy::new(|| Arc::new(Mutex::new(HashMap::new()))); -pub async fn request_handler(_: Arc, _request_context: RequestContext, server_request: ServerRequest) -> ServerResponse { +pub async fn request_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest +) -> ServerResponse { let bad_request = |body_str| { ServerRawResponse::bad_request() .body(Vec::from(body_str)) @@ -1301,7 +1305,11 @@ pub async fn request_handler(_: Arc, _request_context: RequestContext, } -pub async fn reply_handler(_: Arc, _request_context: RequestContext, server_request: ServerRequest) -> ServerResponse { +pub async fn reply_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest +) -> ServerResponse { let headers = server_request.headers; let body = server_request.body.as_ref().unwrap().as_slice(); @@ -1344,3 +1352,232 @@ pub async fn reply_handler(_: Arc, _request_context: RequestContext, s } } } + +pub async fn create_device_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_name = get_cstring("x-cloud-name")?; + let cloud_description = get_cstring("x-cloud-description")?; + let cloud_device_file = get_cstring("x-cloud-device-file")?; + let cloud_directory = get_cstring("x-cloud-directory")?; + + unsafe { + let ret = datamgr_api::CreateDevice( + DATA_PLUGIN_MANAGER, + cloud_name.as_ptr(), + cloud_description.as_ptr(), + cloud_device_file.as_ptr(), + cloud_directory.as_ptr(), + ); + if ret == 1 { + Ok(json!("CreateDevice success")) + } else { + Err(internal_error("CreateDevice failed")) + } + } +} + +pub async fn create_profile_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_strategy_name = get_cstring("x-cloud-strategy")?; + + let header_cloud_application = match headers.get("x-cloud-application") { + Some(value) => Some(value.to_string()), + None => None, + }; + + + let header_cloud_data_type = match headers.get("x-cloud-data-type") { + Some(value) => Some(value.to_string()), + None => None, + }; + + unsafe { + match (header_cloud_application.as_ref(), header_cloud_data_type.as_ref()) { + (Some(app), Some(dtype)) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud application")), + }; + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud data type")), + }; + let ret = datamgr_api::CreateProfile( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_data_type.as_ptr(), + cloud_strategy_name.as_ptr(), + ); + if ret == 1 { + Ok(json!("CreateProfile success")) + } else { + Err(ServerError::internal_error("CreateProfile failed")) + } + } + + (Some(app), None) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud application")), + }; + let ret = datamgr_api::CreateProfileForApplication( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_strategy_name.as_ptr(), + ); + if ret == 1 { + Ok(json!("CreateProfileForApplication success")) + } else { + Err(ServerError::internal_error("CreateProfileForApplication failed")) + } + } + + (None, Some(dtype)) => { + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud data type")), + }; + let ret = datamgr_api::CreateProfileForDataType( + DATA_PLUGIN_MANAGER, + cloud_data_type.as_ptr(), + cloud_strategy_name.as_ptr(), + ); + if ret == 1 { + Ok(json!("CreateProfileForDataType success")) + } else { + Err(internal_error("CreateProfileForDataType failed")) + } + } + + (None, None) => { + Err(internal_error("Missing required headers: cloud_application or cloud_data_type")) + } + } + } +} + +pub async fn create_strategy_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_name = get_cstring("x-cloud-name")?; + let cloud_description = get_cstring("x-cloud-description")?; + let ecc = get_cstring("x-cloud-error-correcting-algorithm")?; + let icc = get_cstring("x-cloud-integrity-check-algorithm")?; + + let life_time = match headers.get("x-cloud-life-time-in-second") { + Some(val) => match val.parse::() { + Ok(v) => v, + Err(_) => return Err(internal_error("Invalid x-cloud-life-time-in-second")), + }, + None => return Err(internal_error("Missing x-cloud-life-time-in-second header")), + }; + + let header_cloud_locations = match headers.get("x-cloud-locations") { + Some(value) => value.to_string(), + None => return Err(internal_error("Missing x-cloud-locations header")), + }; + + // 解析 x-cloud-locations + let mut device_names = Vec::new(); + let mut relative_paths = Vec::new(); + + for entry in header_cloud_locations.split(';') { + let mut device_name: Option = None; + let mut relative_path: Option = None; + + for pair in entry.split(',') { + let mut kv = pair.splitn(2, '='); + let key = kv.next().unwrap_or("").trim(); + let value = kv.next().unwrap_or("").trim(); + + match key { + "deviceName" => device_name = Some(value.to_string()), + "relativePath" => relative_path = Some(value.to_string()), + _ => {} + } + } + + match (device_name, relative_path) { + (Some(dn), Some(rp)) => { + device_names.push(CString::new(dn).map_err(|_| internal_error("Invalid deviceName"))?); + relative_paths.push(CString::new(rp).map_err(|_| internal_error("Invalid relativePath"))?); + } + _ => return Err(internal_error("Malformed x-cloud-locations entry")), + } + } + + let location_count = device_names.len() as i32; + if location_count == 0 { + return Err(internal_error("No valid locations found")); + } + + let device_name_ptrs: Vec<*const c_char> = device_names.iter().map(|s| s.as_ptr()).collect(); + let relative_path_ptrs: Vec<*const c_char> = relative_paths.iter().map(|s| s.as_ptr()).collect(); + + unsafe { + let ret = datamgr_api::CreateStrategy( + DATA_PLUGIN_MANAGER, + cloud_name.as_ptr(), + cloud_description.as_ptr(), + location_count, + device_name_ptrs.as_ptr() as *mut *const c_char, + relative_path_ptrs.as_ptr() as *mut *const c_char, + ecc.as_ptr(), + icc.as_ptr(), + life_time, + ); + + if ret == 1 { + Ok(json!("CreateStrategy success")) + } else { + Err(internal_error("CreateStrategy failed")) + } + } +} \ No newline at end of file -- Gitee From 206a9a0918d12c69a85be50f2e39be5f213d6619 Mon Sep 17 00:00:00 2001 From: Super User Date: Tue, 10 Jun 2025 11:47:32 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=B0=81=E8=A3=85=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers/datamgr/route.rs | 601 +++++++++++++++++++++++++++- 1 file changed, 596 insertions(+), 5 deletions(-) diff --git a/src/cores/handlers/datamgr/route.rs b/src/cores/handlers/datamgr/route.rs index e23e72b..666c782 100644 --- a/src/cores/handlers/datamgr/route.rs +++ b/src/cores/handlers/datamgr/route.rs @@ -1410,14 +1410,13 @@ pub async fn create_profile_handler( } }; - let cloud_strategy_name = get_cstring("x-cloud-strategy")?; + let cloud_strategy = get_cstring("x-cloud-strategy")?; let header_cloud_application = match headers.get("x-cloud-application") { Some(value) => Some(value.to_string()), None => None, }; - let header_cloud_data_type = match headers.get("x-cloud-data-type") { Some(value) => Some(value.to_string()), None => None, @@ -1438,7 +1437,7 @@ pub async fn create_profile_handler( DATA_PLUGIN_MANAGER, cloud_application.as_ptr(), cloud_data_type.as_ptr(), - cloud_strategy_name.as_ptr(), + cloud_strategy.as_ptr(), ); if ret == 1 { Ok(json!("CreateProfile success")) @@ -1455,7 +1454,7 @@ pub async fn create_profile_handler( let ret = datamgr_api::CreateProfileForApplication( DATA_PLUGIN_MANAGER, cloud_application.as_ptr(), - cloud_strategy_name.as_ptr(), + cloud_strategy.as_ptr(), ); if ret == 1 { Ok(json!("CreateProfileForApplication success")) @@ -1472,7 +1471,7 @@ pub async fn create_profile_handler( let ret = datamgr_api::CreateProfileForDataType( DATA_PLUGIN_MANAGER, cloud_data_type.as_ptr(), - cloud_strategy_name.as_ptr(), + cloud_strategy.as_ptr(), ); if ret == 1 { Ok(json!("CreateProfileForDataType success")) @@ -1580,4 +1579,596 @@ pub async fn create_strategy_handler( Err(internal_error("CreateStrategy failed")) } } +} + +pub async fn find_profile_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_application = get_cstring("x-cloud-application")?; + let cloud_data_type = get_cstring("x-cloud-data-type")?; + + unsafe { + let ret = datamgr_api::FindProfile( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_data_type.as_ptr(), + ); + if ret.is_null() { + Err(ServerError::not_found("Profile not found")) + + } else { + Ok(json!("FindProfile success")) + } + } +} + +pub async fn get_all_devices_handler( + _: Arc, + _request_context: RequestContext, + _server_request: ServerRequest, +) -> ServerResult { + + unsafe { + let ret = datamgr_api::GetAllDevices( + DATA_PLUGIN_MANAGER, + ); + if ret.is_null() { + Err(ServerError::not_found("Devices not found")) + + } else { + Ok(json!("GetAllDevices success")) + } + } +} + +pub async fn get_device_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + // 获取 cloud-name header + let header_cloud_name = headers.get("x-cloud-name").map(|v| v.to_string()); + + unsafe { + match header_cloud_name { + None => { + let ret = datamgr_api::GetAllDevices( + DATA_PLUGIN_MANAGER + ); + + if ret.is_null() { + Err(ServerError::not_found("No devices found")) + } else { + Ok(json!("Get Device List success")) + } + } + Some(ref name) if name == "default" => { + let ret = datamgr_api::GetDefaultDevice( + DATA_PLUGIN_MANAGER + ); + + if ret.is_null() { + Err(ServerError::not_found("Default device not found")) + } else { + Ok(json!("Get Default Device success")) + } + } + Some(name) => { + let c_name = CString::new(name) + .map_err(|_| ServerError::internal_error("Invalid cloud name"))?; + + let ret = datamgr_api::GetDeviceByName( + DATA_PLUGIN_MANAGER, + c_name.as_ptr() + ); + + if ret.is_null() { + Err(ServerError::not_found("Device not found")) + } else { + Ok(json!("Get Device By Name success")) + } + } + } + } +} + +pub async fn get_strategy_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + // 获取 cloud-name header + let header_cloud_name = headers.get("x-cloud-name").map(|v| v.to_string()); + + unsafe { + match header_cloud_name { + None => { + let ret = datamgr_api::GetAllStrategies( + DATA_PLUGIN_MANAGER + ); + + if ret.is_null() { + Err(ServerError::not_found("No Strategy found")) + } else { + Ok(json!("Get Strategy List success")) + } + } + Some(ref name) if name == "default" => { + let ret = datamgr_api::GetDefaultStrategy( + DATA_PLUGIN_MANAGER + ); + + if ret.is_null() { + Err(ServerError::not_found("Default Strategy not found")) + } else { + Ok(json!("Get Default Strategy success")) + } + } + Some(name) => { + let c_name = CString::new(name) + .map_err(|_| ServerError::internal_error("Invalid cloud name"))?; + + let ret = datamgr_api::GetStrategyByName( + DATA_PLUGIN_MANAGER, + c_name.as_ptr() + ); + + if ret.is_null() { + Err(ServerError::not_found("Strategy not found")) + } else { + Ok(json!("Get Strategy By Name success")) + } + } + } + } +} + +pub async fn get_profile_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let header_cloud_application = match headers.get("x-cloud-application") { + Some(value) => Some(value.to_string()), + None => None, + }; + + let header_cloud_data_type = match headers.get("x-cloud-data-type") { + Some(value) => Some(value.to_string()), + None => None, + }; + + unsafe { + let ret = match (header_cloud_application.as_ref(), header_cloud_data_type.as_ref()) { + (Some(app), Some(dtype)) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud application")), + }; + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud data type")), + }; + datamgr_api::GetProfile( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_data_type.as_ptr(), + ) + } + + (Some(app), None) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud application")), + }; + datamgr_api::GetProfileForApplication( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + ) + } + + (None, Some(dtype)) => { + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud data type")), + }; + datamgr_api::GetProfileForDataType( + DATA_PLUGIN_MANAGER, + cloud_data_type.as_ptr(), + ) + } + + (None, None) => { + return Err(ServerError::internal_error("Missing required headers: cloud_application or cloud_data_type")) + } + }; + + if ret.is_null() { + Err(ServerError::not_found("Profile not found")) + + } else { + Ok(json!("GetProfile success")) + } + } +} + +pub async fn remove_device_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_name = get_cstring("x-cloud-name")?; + + unsafe { + let ret = datamgr_api::RemoveDevice( + DATA_PLUGIN_MANAGER, + cloud_name.as_ptr(), + ); + + if ret == 1 { + Ok(json!("Remove Device success")) + } else { + + Err(ServerError::internal_error("Remove Device failed")) + } + } +} + +pub async fn remove_strategy_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_name = get_cstring("x-cloud-name")?; + + unsafe { + let ret = datamgr_api::RemoveStrategy( + DATA_PLUGIN_MANAGER, + cloud_name.as_ptr(), + ); + + if ret == 1 { + Ok(json!("Remove Strategy success")) + } else { + + Err(ServerError::internal_error("Remove Strategy failed")) + } + } +} + +pub async fn remove_profile_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let header_cloud_application = match headers.get("x-cloud-application") { + Some(value) => Some(value.to_string()), + None => None, + }; + + let header_cloud_data_type = match headers.get("x-cloud-data-type") { + Some(value) => Some(value.to_string()), + None => None, + }; + + unsafe { + let ret = match (header_cloud_application.as_ref(), header_cloud_data_type.as_ref()) { + (Some(app), Some(dtype)) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud application")), + }; + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud data type")), + }; + datamgr_api::RemoveProfile( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_data_type.as_ptr(), + ) + } + + (Some(app), None) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud application")), + }; + datamgr_api::RemoveProfileForApplication( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + ) + } + + (None, Some(dtype)) => { + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(ServerError::internal_error("Invalid cloud data type")), + }; + datamgr_api::RemoveProfileForDataType( + DATA_PLUGIN_MANAGER, + cloud_data_type.as_ptr(), + ) + } + + (None, None) => { + return Err(ServerError::internal_error("Missing required headers: cloud_application or cloud_data_type")) + } + }; + + if ret == 1 { + Ok(json!("Remove Profile success")) + } else { + + Err(ServerError::internal_error("Remove Profile failed")) + } + } +} + +pub async fn update_device_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_name = get_cstring("x-cloud-name")?; + let cloud_description = get_cstring("x-cloud-new-description")?; + let cloud_device_file = get_cstring("x-cloud-new-device-file")?; + let cloud_directory = get_cstring("x-cloud-new-directory")?; + + unsafe { + let ret = datamgr_api::UpdateDevice( + DATA_PLUGIN_MANAGER, + cloud_name.as_ptr(), + cloud_description.as_ptr(), + cloud_device_file.as_ptr(), + cloud_directory.as_ptr(), + ); + if ret == 1 { + Ok(json!("Update Device success")) + } else { + Err(internal_error("Update Device failed")) + } + } +} + +pub async fn update_strategy_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_name = get_cstring("x-cloud-name")?; + let cloud_description = get_cstring("x-cloud-new-description")?; + let ecc = get_cstring("x-cloud-new-error-correcting-algorithm")?; + let icc = get_cstring("x-cloud-new-integrity-check-algorithm")?; + + let life_time = match headers.get("x-cloud-new-life-time-in-second") { + Some(val) => match val.parse::() { + Ok(v) => v, + Err(_) => return Err(internal_error("Invalid x-cloud-new-life-time-in-second")), + }, + None => return Err(internal_error("Missing x-cloud-new-life-time-in-second header")), + }; + + let header_cloud_locations = match headers.get("x-cloud-new-locations") { + Some(value) => value.to_string(), + None => return Err(internal_error("Missing x-cloud-new-locations header")), + }; + + // 解析 x-cloud-new-locations + let mut device_names = Vec::new(); + let mut relative_paths = Vec::new(); + + for entry in header_cloud_locations.split(';') { + let mut device_name: Option = None; + let mut relative_path: Option = None; + + for pair in entry.split(',') { + let mut kv = pair.splitn(2, '='); + let key = kv.next().unwrap_or("").trim(); + let value = kv.next().unwrap_or("").trim(); + + match key { + "deviceName" => device_name = Some(value.to_string()), + "relativePath" => relative_path = Some(value.to_string()), + _ => {} + } + } + + match (device_name, relative_path) { + (Some(dn), Some(rp)) => { + device_names.push(CString::new(dn).map_err(|_| internal_error("Invalid deviceName"))?); + relative_paths.push(CString::new(rp).map_err(|_| internal_error("Invalid relativePath"))?); + } + _ => return Err(internal_error("Malformed x-cloud-locations entry")), + } + } + + let location_count = device_names.len() as i32; + if location_count == 0 { + return Err(internal_error("No valid locations found")); + } + + let device_name_ptrs: Vec<*const c_char> = device_names.iter().map(|s| s.as_ptr()).collect(); + let relative_path_ptrs: Vec<*const c_char> = relative_paths.iter().map(|s| s.as_ptr()).collect(); + + unsafe { + let ret = datamgr_api::UpdateStrategy( + DATA_PLUGIN_MANAGER, + cloud_name.as_ptr(), + cloud_description.as_ptr(), + location_count, + device_name_ptrs.as_ptr() as *mut *const c_char, + relative_path_ptrs.as_ptr() as *mut *const c_char, + ecc.as_ptr(), + icc.as_ptr(), + life_time, + ); + + if ret == 1 { + Ok(json!("Update Strategy success")) + } else { + Err(internal_error("Update Strategy failed")) + } + } +} + +pub async fn update_profile_handler( + _: Arc, + _request_context: RequestContext, + server_request: ServerRequest, +) -> ServerResult { + let headers = server_request.headers; + + let internal_error = |msg: &str| -> ServerError { + ServerError::internal_error(msg) + }; + + let get_cstring = |key: &str| { + match headers.get(key) { + Some(val) => CString::new(val.to_string()).map_err(|_| internal_error(&format!("Invalid {}", key))), + None => Err(internal_error(&format!("Missing {} header", key))), + } + }; + + let cloud_strategy = get_cstring("x-cloud-new-strategy")?; + + let header_cloud_application = match headers.get("x-cloud-new-application") { + Some(value) => Some(value.to_string()), + None => None, + }; + + let header_cloud_data_type = match headers.get("x-cloud-new-data-type") { + Some(value) => Some(value.to_string()), + None => None, + }; + + unsafe { + let ret = match (header_cloud_application.as_ref(), header_cloud_data_type.as_ref()) { + (Some(app), Some(dtype)) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud new application")), + }; + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud new data type")), + }; + datamgr_api::UpdateProfile( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_data_type.as_ptr(), + cloud_strategy.as_ptr(), + ) + } + + (Some(app), None) => { + let cloud_application = match CString::new(app.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud new application")), + }; + datamgr_api::UpdateProfileForApplication( + DATA_PLUGIN_MANAGER, + cloud_application.as_ptr(), + cloud_strategy.as_ptr(), + ) + } + + (None, Some(dtype)) => { + let cloud_data_type = match CString::new(dtype.as_str()) { + Ok(cstr) => cstr, + Err(_) => return Err(internal_error("Invalid cloud new data type")), + }; + datamgr_api::UpdateProfileForDataType( + DATA_PLUGIN_MANAGER, + cloud_data_type.as_ptr(), + cloud_strategy.as_ptr(), + ) + } + + (None, None) => { + return Err(internal_error("Missing required headers: cloud_application or cloud_data_type")) + } + }; + + if ret == 1 { + Ok(json!("Update Profile success")) + } else { + Err(ServerError::internal_error("Update Profile failed")) + } + } } \ No newline at end of file -- Gitee From 4a60178a9446675691defdce2da0f1ec86c0cb04 Mon Sep 17 00:00:00 2001 From: Super User Date: Tue, 10 Jun 2025 23:45:44 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=83=A8=E5=88=86handler?= =?UTF-8?q?=E5=AF=B9=E8=BF=94=E5=9B=9E=E5=80=BC=E7=9A=84=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers/datamgr/route.rs | 211 ++++++++++++++++++++-------- 1 file changed, 151 insertions(+), 60 deletions(-) diff --git a/src/cores/handlers/datamgr/route.rs b/src/cores/handlers/datamgr/route.rs index 666c782..3a319cc 100644 --- a/src/cores/handlers/datamgr/route.rs +++ b/src/cores/handlers/datamgr/route.rs @@ -16,6 +16,7 @@ use std::time::Duration; use tokio::sync::oneshot; use tokio::time::Instant; use uuid::Uuid; +use crate::cores::handlers::datamgr::datamgr_api::{Device, DeviceList, Strategy, StrategyList}; pub static mut DATA_PLUGIN_MANAGER: *mut std::os::raw::c_void = null_mut(); @@ -1385,9 +1386,9 @@ pub async fn create_device_handler( cloud_directory.as_ptr(), ); if ret == 1 { - Ok(json!("CreateDevice success")) + Ok(json!("Create device success")) } else { - Err(internal_error("CreateDevice failed")) + Err(internal_error("Create device failed")) } } } @@ -1440,9 +1441,9 @@ pub async fn create_profile_handler( cloud_strategy.as_ptr(), ); if ret == 1 { - Ok(json!("CreateProfile success")) + Ok(json!("Create profile success")) } else { - Err(ServerError::internal_error("CreateProfile failed")) + Err(ServerError::internal_error("Create profile failed")) } } @@ -1457,9 +1458,9 @@ pub async fn create_profile_handler( cloud_strategy.as_ptr(), ); if ret == 1 { - Ok(json!("CreateProfileForApplication success")) + Ok(json!("Create profile for application success")) } else { - Err(ServerError::internal_error("CreateProfileForApplication failed")) + Err(ServerError::internal_error("Create profile for application failed")) } } @@ -1474,9 +1475,9 @@ pub async fn create_profile_handler( cloud_strategy.as_ptr(), ); if ret == 1 { - Ok(json!("CreateProfileForDataType success")) + Ok(json!("Create profile for data type success")) } else { - Err(internal_error("CreateProfileForDataType failed")) + Err(internal_error("Create profile for data type failed")) } } @@ -1574,9 +1575,9 @@ pub async fn create_strategy_handler( ); if ret == 1 { - Ok(json!("CreateStrategy success")) + Ok(json!("Create strategy success")) } else { - Err(internal_error("CreateStrategy failed")) + Err(internal_error("Create strategy failed")) } } } @@ -1612,28 +1613,57 @@ pub async fn find_profile_handler( Err(ServerError::not_found("Profile not found")) } else { - Ok(json!("FindProfile success")) + let c_str: &CStr = CStr::from_ptr(ret); + + match c_str.to_str() { + Ok(profile_str) => { + Ok(json!(profile_str)) + }, + Err(_) => Err(internal_error("Failed to convert C string")), + } } } } -pub async fn get_all_devices_handler( - _: Arc, - _request_context: RequestContext, - _server_request: ServerRequest, -) -> ServerResult { +unsafe fn device_to_json(device_ptr: *mut Device) -> Option { + if device_ptr.is_null() { + return None; + } - unsafe { - let ret = datamgr_api::GetAllDevices( - DATA_PLUGIN_MANAGER, - ); - if ret.is_null() { - Err(ServerError::not_found("Devices not found")) + let device = *device_ptr; + let cstr_to_string = |ptr: *mut c_char| { + if ptr.is_null() { + None } else { - Ok(json!("GetAllDevices success")) + CStr::from_ptr(ptr).to_str().ok().map(|s| s.to_string()) } + }; + + Some(json!({ + "name": cstr_to_string(device.name), + "description": cstr_to_string(device.description), + "deviceFile": cstr_to_string(device.deviceFile), + "directory": cstr_to_string(device.directory), + })) +} + +unsafe fn device_list_to_json(list_ptr: *mut DeviceList) -> Option { + if list_ptr.is_null() { + return None; } + + let list = *list_ptr; + let mut devices_json = Vec::with_capacity(list.count as usize); + + for i in 0..list.count { + let device_ptr = *list.devices.add(i as usize); + if let Some(device_json) = device_to_json(device_ptr) { + devices_json.push(device_json); + } + } + + Some(json!(devices_json)) } pub async fn get_device_handler( @@ -1653,10 +1683,9 @@ pub async fn get_device_handler( DATA_PLUGIN_MANAGER ); - if ret.is_null() { - Err(ServerError::not_found("No devices found")) - } else { - Ok(json!("Get Device List success")) + match device_list_to_json(ret) { + Some(json) => Ok(json), + None => Err(ServerError::not_found("No devices found")), } } Some(ref name) if name == "default" => { @@ -1664,10 +1693,9 @@ pub async fn get_device_handler( DATA_PLUGIN_MANAGER ); - if ret.is_null() { - Err(ServerError::not_found("Default device not found")) - } else { - Ok(json!("Get Default Device success")) + match device_to_json(ret) { + Some(json) => Ok(json), + None => Err(ServerError::not_found("Default device not found")), } } Some(name) => { @@ -1679,16 +1707,75 @@ pub async fn get_device_handler( c_name.as_ptr() ); - if ret.is_null() { - Err(ServerError::not_found("Device not found")) - } else { - Ok(json!("Get Device By Name success")) + match device_to_json(ret) { + Some(json) => Ok(json), + None => Err(ServerError::not_found("Device not found")), } } } } } +unsafe fn strategy_to_json(ptr: *mut Strategy) -> Option { + if ptr.is_null() { + return None; + } + + let strategy = *ptr; + + let cstr_to_string = |s: *mut c_char| { + if s.is_null() { + None + } else { + CStr::from_ptr(s).to_str().ok().map(|s| s.to_string()) + } + }; + + let mut device_names = Vec::new(); + let mut relative_paths = Vec::new(); + + for i in 0..strategy.locationCount { + let dev_name_ptr = *strategy.locationDeviceNames.add(i as usize); + let rel_path_ptr = *strategy.locationRelativePaths.add(i as usize); + + let dev_name = cstr_to_string(dev_name_ptr).unwrap_or_default(); + let rel_path = cstr_to_string(rel_path_ptr).unwrap_or_default(); + + device_names.push(dev_name); + relative_paths.push(rel_path); + } + + Some(json!({ + "name": cstr_to_string(strategy.name), + "description": cstr_to_string(strategy.description), + "locationCount": strategy.locationCount, + "locationDeviceNames": device_names, + "locationRelativePaths": relative_paths, + "errorCorrectingAlgorithm": cstr_to_string(strategy.errorCorrectingAlgorithm), + "integrityCheckAlgorithm": cstr_to_string(strategy.integrityCheckAlgorithm), + "lifeTimeInSecond": strategy.lifeTimeInSecond, + })) +} + +unsafe fn strategy_list_to_json(list_ptr: *mut StrategyList) -> Option { + if list_ptr.is_null() { + return None; + } + + let list = *list_ptr; + let mut strategies_json = Vec::with_capacity(list.count as usize); + + for i in 0..list.count { + let strategy_ptr = *list.strategies.add(i as usize); + if let Some(json) = strategy_to_json(strategy_ptr) { + strategies_json.push(json); + } + } + + Some(json!(strategies_json)) +} + + pub async fn get_strategy_handler( _: Arc, _request_context: RequestContext, @@ -1706,10 +1793,9 @@ pub async fn get_strategy_handler( DATA_PLUGIN_MANAGER ); - if ret.is_null() { - Err(ServerError::not_found("No Strategy found")) - } else { - Ok(json!("Get Strategy List success")) + match strategy_list_to_json(ret) { + Some(json) => Ok(json), + None => Err(ServerError::not_found("No strategy found")), } } Some(ref name) if name == "default" => { @@ -1717,10 +1803,9 @@ pub async fn get_strategy_handler( DATA_PLUGIN_MANAGER ); - if ret.is_null() { - Err(ServerError::not_found("Default Strategy not found")) - } else { - Ok(json!("Get Default Strategy success")) + match strategy_to_json(ret) { + Some(json) => Ok(json), + None => Err(ServerError::not_found("Default strategy not found")), } } Some(name) => { @@ -1732,10 +1817,9 @@ pub async fn get_strategy_handler( c_name.as_ptr() ); - if ret.is_null() { - Err(ServerError::not_found("Strategy not found")) - } else { - Ok(json!("Get Strategy By Name success")) + match strategy_to_json(ret) { + Some(json) => Ok(json), + None => Err(ServerError::not_found("Strategy not found")), } } } @@ -1808,7 +1892,14 @@ pub async fn get_profile_handler( Err(ServerError::not_found("Profile not found")) } else { - Ok(json!("GetProfile success")) + let c_str: &CStr = CStr::from_ptr(ret); + + match c_str.to_str() { + Ok(profile_str) => { + Ok(json!(profile_str)) + }, + Err(_) => Err(ServerError::internal_error("Failed to convert C string")), + } } } } @@ -1840,10 +1931,10 @@ pub async fn remove_device_handler( ); if ret == 1 { - Ok(json!("Remove Device success")) + Ok(json!("Remove device success")) } else { - Err(ServerError::internal_error("Remove Device failed")) + Err(ServerError::internal_error("Remove device failed")) } } } @@ -1875,10 +1966,10 @@ pub async fn remove_strategy_handler( ); if ret == 1 { - Ok(json!("Remove Strategy success")) + Ok(json!("Remove strategy success")) } else { - Err(ServerError::internal_error("Remove Strategy failed")) + Err(ServerError::internal_error("Remove strategy failed")) } } } @@ -1946,10 +2037,10 @@ pub async fn remove_profile_handler( }; if ret == 1 { - Ok(json!("Remove Profile success")) + Ok(json!("Remove profile success")) } else { - Err(ServerError::internal_error("Remove Profile failed")) + Err(ServerError::internal_error("Remove profile failed")) } } } @@ -1986,9 +2077,9 @@ pub async fn update_device_handler( cloud_directory.as_ptr(), ); if ret == 1 { - Ok(json!("Update Device success")) + Ok(json!("Update device success")) } else { - Err(internal_error("Update Device failed")) + Err(internal_error("Update device failed")) } } } @@ -2080,9 +2171,9 @@ pub async fn update_strategy_handler( ); if ret == 1 { - Ok(json!("Update Strategy success")) + Ok(json!("Update strategy success")) } else { - Err(internal_error("Update Strategy failed")) + Err(internal_error("Update strategy failed")) } } } @@ -2166,9 +2257,9 @@ pub async fn update_profile_handler( }; if ret == 1 { - Ok(json!("Update Profile success")) + Ok(json!("Update profile success")) } else { - Err(ServerError::internal_error("Update Profile failed")) + Err(ServerError::internal_error("Update profile failed")) } } } \ No newline at end of file -- Gitee From 9fd1ed31d10c728be4a3f49a461148b8ccd43177 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 11 Jun 2025 10:38:48 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=AE=8C=E5=96=84handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers/datamgr/route.rs | 38 +++++-- src/cores/router.rs | 91 +++++++++++++++ src/cores/servers/actix_web/mod.rs | 167 ++++++++++++++++++++++++++-- 3 files changed, 277 insertions(+), 19 deletions(-) diff --git a/src/cores/handlers/datamgr/route.rs b/src/cores/handlers/datamgr/route.rs index 3a319cc..311fbb6 100644 --- a/src/cores/handlers/datamgr/route.rs +++ b/src/cores/handlers/datamgr/route.rs @@ -16,7 +16,7 @@ use std::time::Duration; use tokio::sync::oneshot; use tokio::time::Instant; use uuid::Uuid; -use crate::cores::handlers::datamgr::datamgr_api::{Device, DeviceList, Strategy, StrategyList}; +use crate::cores::handlers::datamgr::datamgr_api::{Device, DeviceList, FreeDevice, FreeDeviceList, FreeStrategy, FreeStrategyList, FreeString, Strategy, StrategyList}; pub static mut DATA_PLUGIN_MANAGER: *mut std::os::raw::c_void = null_mut(); @@ -1053,7 +1053,7 @@ pub async fn message_handler( } let remaining = timeout_duration - elapsed; - let (mut new_system, timeout_result) = + let (new_system, timeout_result) = condvar.wait_timeout(queue_system, remaining).unwrap(); queue_system = new_system; @@ -1615,6 +1615,8 @@ pub async fn find_profile_handler( } else { let c_str: &CStr = CStr::from_ptr(ret); + FreeString(ret); + match c_str.to_str() { Ok(profile_str) => { Ok(json!(profile_str)) @@ -1684,7 +1686,10 @@ pub async fn get_device_handler( ); match device_list_to_json(ret) { - Some(json) => Ok(json), + Some(json) => { + FreeDeviceList(ret); + Ok(json) + }, None => Err(ServerError::not_found("No devices found")), } } @@ -1694,7 +1699,10 @@ pub async fn get_device_handler( ); match device_to_json(ret) { - Some(json) => Ok(json), + Some(json) => { + FreeDevice(ret); + Ok(json) + }, None => Err(ServerError::not_found("Default device not found")), } } @@ -1708,7 +1716,10 @@ pub async fn get_device_handler( ); match device_to_json(ret) { - Some(json) => Ok(json), + Some(json) => { + FreeDevice(ret); + Ok(json) + }, None => Err(ServerError::not_found("Device not found")), } } @@ -1794,7 +1805,10 @@ pub async fn get_strategy_handler( ); match strategy_list_to_json(ret) { - Some(json) => Ok(json), + Some(json) => { + FreeStrategyList(ret); + Ok(json) + }, None => Err(ServerError::not_found("No strategy found")), } } @@ -1804,7 +1818,10 @@ pub async fn get_strategy_handler( ); match strategy_to_json(ret) { - Some(json) => Ok(json), + Some(json) => { + FreeStrategy(ret); + Ok(json) + }, None => Err(ServerError::not_found("Default strategy not found")), } } @@ -1818,7 +1835,10 @@ pub async fn get_strategy_handler( ); match strategy_to_json(ret) { - Some(json) => Ok(json), + Some(json) => { + FreeStrategy(ret); + Ok(json) + }, None => Err(ServerError::not_found("Strategy not found")), } } @@ -1894,6 +1914,8 @@ pub async fn get_profile_handler( } else { let c_str: &CStr = CStr::from_ptr(ret); + FreeString(ret); + match c_str.to_str() { Ok(profile_str) => { Ok(json!(profile_str)) diff --git a/src/cores/router.rs b/src/cores/router.rs index d67908b..c5e4075 100644 --- a/src/cores/router.rs +++ b/src/cores/router.rs @@ -78,6 +78,19 @@ pub enum RouterKey { DataMgrMessage, DataMgrRequest, DataMgrReply, + DataMgrCreateDevice, + DataMgrCreateProfile, + DataMgrCreateStrategy, + DataMgrFindProfile, + DataMgrGetDevice, + DataMgrGetProfile, + DataMgrGetStrategy, + DataMgrRemoveDevice, + DataMgrRemoveProfile, + DataMgrRemoveStrategy, + DataMgrUpdateDevice, + DataMgrUpdateProfile, + DataMgrUpdateStrategy, // Consensus Service Router Key ConsensusRequests, @@ -496,6 +509,84 @@ impl Router { RouterKey::DataMgrReply, handlers::datamgr::reply_handler ); + + add_route!( + router, + RouterKey::DataMgrCreateDevice, + handlers::datamgr::create_device_handler + ); + + add_route!( + router, + RouterKey::DataMgrCreateProfile, + handlers::datamgr::create_profile_handler + ); + + add_route!( + router, + RouterKey::DataMgrCreateStrategy, + handlers::datamgr::create_strategy_handler + ); + + add_route!( + router, + RouterKey::DataMgrFindProfile, + handlers::datamgr::find_profile_handler + ); + + add_route!( + router, + RouterKey::DataMgrGetDevice, + handlers::datamgr::get_device_handler + ); + + add_route!( + router, + RouterKey::DataMgrGetProfile, + handlers::datamgr::get_profile_handler + ); + + add_route!( + router, + RouterKey::DataMgrGetStrategy, + handlers::datamgr::get_strategy_handler + ); + + add_route!( + router, + RouterKey::DataMgrRemoveDevice, + handlers::datamgr::remove_device_handler + ); + + add_route!( + router, + RouterKey::DataMgrRemoveProfile, + handlers::datamgr::remove_profile_handler + ); + + add_route!( + router, + RouterKey::DataMgrRemoveStrategy, + handlers::datamgr::remove_strategy_handler + ); + + add_route!( + router, + RouterKey::DataMgrUpdateDevice, + handlers::datamgr::update_device_handler + ); + + add_route!( + router, + RouterKey::DataMgrUpdateProfile, + handlers::datamgr::update_profile_handler + ); + + add_route!( + router, + RouterKey::DataMgrUpdateStrategy, + handlers::datamgr::update_strategy_handler + ); } // consensus service routers diff --git a/src/cores/servers/actix_web/mod.rs b/src/cores/servers/actix_web/mod.rs index e051f2c..ef240da 100644 --- a/src/cores/servers/actix_web/mod.rs +++ b/src/cores/servers/actix_web/mod.rs @@ -919,6 +919,19 @@ pub mod datamgr { app.service(message); app.service(request); app.service(reply); + app.service(create_device); + app.service(create_profile); + app.service(create_strategy); + app.service(find_profile); + app.service(get_device); + app.service(get_profile); + app.service(get_strategy); + app.service(remove_device); + app.service(remove_profile); + app.service(remove_strategy); + app.service(update_device); + app.service(update_profile); + app.service(update_strategy); } #[derive(Serialize, Deserialize, Apiv2Schema)] @@ -931,17 +944,6 @@ pub mod datamgr { pub uuid: String, } - /*define_json_response_method!( - body_required - upload_data, - post, - "/{data_type}", - DataTypePath, - (), - RouterKey::DataMgrUploadData, - "DataMgr" - );*/ - define_raw_response_method!( upload_data, post, @@ -1144,6 +1146,149 @@ pub mod datamgr { RouterKey::DataMgrReply, "DataMgr" ); + + define_json_response_method!( + body_unrequired + create_device, + post, + "/Device", + (), + (), + RouterKey::DataMgrCreateDevice, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + create_profile, + post, + "/Profile", + (), + (), + RouterKey::DataMgrCreateProfile, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + create_strategy, + post, + "/Strategy", + (), + (), + RouterKey::DataMgrCreateStrategy, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + find_profile, + get, + "/Profile/Find", + (), + (), + RouterKey::DataMgrFindProfile, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + get_device, + get, + "/Device", + (), + (), + RouterKey::DataMgrGetDevice, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + get_profile, + get, + "/Profile", + (), + (), + RouterKey::DataMgrGetProfile, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + get_strategy, + get, + "/Strategy", + (), + (), + RouterKey::DataMgrGetStrategy, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + remove_device, + delete, + "/Device", + (), + (), + RouterKey::DataMgrRemoveDevice, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + remove_profile, + delete, + "/Profile", + (), + (), + RouterKey::DataMgrRemoveProfile, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + remove_strategy, + delete, + "/Strategy", + (), + (), + RouterKey::DataMgrRemoveStrategy, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + update_device, + put, + "/Device", + (), + (), + RouterKey::DataMgrUpdateDevice, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + update_profile, + put, + "/Profile", + (), + (), + RouterKey::DataMgrUpdateProfile, + "DataMgr" + ); + + define_json_response_method!( + body_unrequired + update_strategy, + put, + "/Strategy", + (), + (), + RouterKey::DataMgrUpdateStrategy, + "DataMgr" + ); } pub mod consensus { -- Gitee