Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/common/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pub const EMPTY_STR: &str = "";

pub const HTTP_METHOD_GET: &str = "GET";
//pub const HTTP_METHOD_PUT:&str= "PUT";
//pub const HTTP_METHOD_POST:&str= "POST";
//pub const HTTP_METHOD_DELETE:&str= "DELETE";
pub const HTTP_METHOD_POST: &str = "POST";
// pub const HTTP_METHOD_DELETE:&str= "DELETE";
pub const HTTP_METHOD_ALL: &str = EMPTY_STR;

pub const SEQ_KEY_CONFIG: &str = "SEQ_CONFIG";
Expand Down
36 changes: 34 additions & 2 deletions src/config/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,33 @@ impl ConfigActor {
(size, info_list)
}

pub fn get_config_info_by_keys(&self, keys: &Vec<ConfigKey>) -> (usize, Vec<ConfigInfoDto>) {
let mut info_list = Vec::with_capacity(keys.len());

for key in keys.iter() {
let key: ConfigKey = ConfigKey {
tenant: key.tenant.clone(),
data_id: key.data_id.clone(),
group: key.group.clone(),
};

if let Some(value) = self.cache.get(&key) {
let info = ConfigInfoDto {
tenant: key.tenant.clone(),
group: key.group.clone(),
data_id: key.data_id.clone(),
desc: value.desc.clone(),
content: Some(value.content.clone()),
md5: Some(value.md5.clone()),
..Default::default()
};
info_list.push(info);
}
}

let size = info_list.len();
(size, info_list)
}
/*
pub(crate) fn get_history_info_page_old(
&self,
Expand Down Expand Up @@ -688,6 +715,7 @@ pub enum ConfigCmd {
InnerSetLastId(u64),
GET(ConfigKey),
QueryPageInfo(Box<ConfigQueryParam>),
QueryInfoByKeys(Box<Vec<ConfigKey>>),
QueryHistoryPageInfo(Box<ConfigHistoryParam>),
LISTENER(Vec<ListenerItem>, ListenerSenderType, i64),
Subscribe(Vec<ListenerItem>, Arc<String>),
Expand Down Expand Up @@ -815,6 +843,10 @@ impl Handler<ConfigCmd> for ConfigActor {
let (size, list) = self.get_config_info_page(config_query_param.as_ref());
return Ok(ConfigResult::ConfigInfoPage(size, list));
}
ConfigCmd::QueryInfoByKeys(config_keys) => {
let (size, list) = self.get_config_info_by_keys(config_keys.as_ref());
return Ok(ConfigResult::ConfigInfoPage(size, list));
}
ConfigCmd::QueryHistoryPageInfo(query_param) => {
let (size, list) = self.get_history_info_page(query_param.as_ref());
return Ok(ConfigResult::ConfigHistoryInfoPage(size, list));
Expand Down Expand Up @@ -876,8 +908,8 @@ impl Handler<ConfigAsyncCmd> for ConfigActor {
}
Ok(ConfigResult::NULL)
}
.into_actor(self)
.map(|r, _act, _ctx| r);
.into_actor(self)
.map(|r, _act, _ctx| r);
Comment on lines +911 to +912
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修正Actor消息处理语法错误

🔴 Blocker | 🐞 Bugs

📋 问题详情

在ConfigActor的消息处理逻辑中,.into_actor(self).map(...)的代码块缩进存在语法问题,可能导致编译失败。

💡 解决方案

修正语法错误:

+    .into_actor(self)
+    .map(|r, _act, _ctx| r);
-            .into_actor(self)
-            .map(|r, _act, _ctx| r);

确保代码块与前序代码正确缩进对齐


您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

Box::pin(fut)
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/console/api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;

use super::cluster_api::query_cluster_info;
use super::config_api::query_config_list;
use super::config_api::{download_config_by_keys, query_config_list};
use super::{
config_api::{download_config, import_config, query_history_config_page},
connection_api::query_grpc_connection,
Expand Down Expand Up @@ -171,7 +171,10 @@ pub fn console_api_config_v1(config: &mut web::ServiceConfig) {
)
.service(web::resource("/configs").route(web::get().to(query_config_list)))
.service(web::resource("/config/import").route(web::post().to(import_config)))
.service(web::resource("/config/download").route(web::get().to(download_config)))
.service(web::resource("/config/download")
.route(web::get().to(download_config))
.route(web::post().to(download_config_by_keys))
)
.service(
web::resource("/config/history").route(web::get().to(query_history_config_page)),
)
Expand Down
64 changes: 54 additions & 10 deletions src/console/config_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,21 @@ use std::sync::Arc;
use actix_multipart::form::tempfile::TempFile;
use actix_multipart::form::text::Text;
use actix_multipart::form::MultipartForm;
use actix_multipart::Multipart;
use actix_web::{http::header, web, Error, HttpMessage, HttpRequest, HttpResponse, Responder};
use zip::write::FileOptions;

use super::model::PageResult;
use crate::common::appdata::AppShareData;
use crate::config::core::{
ConfigActor, ConfigAsyncCmd, ConfigCmd, ConfigInfoDto, ConfigKey, ConfigResult,
ConfigActor, ConfigCmd, ConfigInfoDto, ConfigKey, ConfigResult,
};
use crate::config::ConfigUtils;
use crate::console::model::config_model::{
OpsConfigOptQueryListResponse, OpsConfigQueryListRequest,
};
use crate::console::model::config_model::{ConfigParams, OpsConfigOptQueryListResponse, OpsConfigQueryListRequest};
use crate::raft::cluster::model::SetConfigReq;
use crate::{now_millis, user_namespace_privilege};
use actix::prelude::Addr;
use tokio_stream::StreamExt;
use uuid::Uuid;
use zip::{ZipArchive, ZipWriter};

use super::model::config_model::OpsConfigImportInfo;
use super::model::PageResult;
use zip::ZipWriter;

pub async fn query_config_list(
req: HttpRequest,
Expand Down Expand Up @@ -231,3 +225,53 @@ pub async fn download_config(
Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
}
}

/// 按 key 导出配置
pub async fn download_config_by_keys(
request: web::Json<Vec<ConfigParams>>,
config_addr: web::Data<Addr<ConfigActor>>,
) -> impl Responder {
let params = request.into_inner();
if params.is_empty() {
return HttpResponse::BadRequest().body("keys cannot be empty");
}

let keys = params
.into_iter()
.map(|k| {
let k = k.to_key();
ConfigKey {
tenant: Arc::new(ConfigUtils::default_tenant(k.tenant.to_string())),
..k
}
})
.collect();

let cmd = ConfigCmd::QueryInfoByKeys(Box::new(keys));
match config_addr.send(cmd).await {
Ok(res) => {
let r: ConfigResult = res.unwrap();
match r {
ConfigResult::ConfigInfoPage(_, list) => {
let mut tmpfile: File = tempfile::tempfile().unwrap();
{
let write = std::io::Write::by_ref(&mut tmpfile);
let zip = ZipWriter::new(write);
zip_file(zip, list).ok();
}
Comment on lines +257 to +261
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改进错误处理避免panic

🟠 Critical | 🐞 Bugs

📋 问题详情

在download_config_by_keys函数中,tempfile::tempfile().unwrap()的错误未被处理,可能导致程序panic。此外,zip_file(zip, list).ok()会忽略压缩失败的错误,无法正确反馈错误信息。

💡 解决方案

改进错误处理:

- let mut tmpfile: File = tempfile::tempfile().unwrap();
+ let mut tmpfile = match tempfile::tempfile() {
+     Ok(f) => f,
+     Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
+ };

修改建议:
1. 使用match处理临时文件创建失败
2. 将zip_file的错误返回给客户端
3. 优化ZipWriter的生命周期管理

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

tmpfile.seek(SeekFrom::Start(0)).unwrap();
let mut buf = vec![];
tmpfile.read_to_end(&mut buf).unwrap();

let filename = format!("rnacos_config_export_{}.zip", now_millis());
HttpResponse::Ok()
.insert_header(header::ContentType::octet_stream())
.insert_header(header::ContentDisposition::attachment(filename))
.body(buf)
}
_ => HttpResponse::InternalServerError().body("config result error"),
}
}
Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
}
}
4 changes: 3 additions & 1 deletion src/user/permission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
/// 2)http请求路径,由后端拦截器控制否支持请求;
use std::{collections::HashSet, hash::Hash, sync::Arc};

use crate::common::constant::{EMPTY_STR, HTTP_METHOD_ALL, HTTP_METHOD_GET};

use crate::common::constant::{EMPTY_STR, HTTP_METHOD_ALL, HTTP_METHOD_GET, HTTP_METHOD_POST};

pub enum Resource {
WebResource(&'static str),
Expand Down Expand Up @@ -241,6 +242,7 @@ lazy_static::lazy_static! {

R::Path("/rnacos/api/console/configs",HTTP_METHOD_GET),
R::Path("/rnacos/api/console/config/download",HTTP_METHOD_GET),
R::Path("/rnacos/api/console/config/download",HTTP_METHOD_POST),
R::Path("/rnacos/api/console/config/import",HTTP_METHOD_ALL),
R::Path("/rnacos/api/console/cs/configs",HTTP_METHOD_ALL),
R::Path("/rnacos/api/console/config/history",HTTP_METHOD_GET),
Expand Down
Loading