1use crate::codec::*;
2use crate::coreobj::CoreObjectType;
3use crate::DecAppId;
4use chrono::{DateTime, Local};
5use cyfs_base::*;
6use serde::Serialize;
7use std::collections::HashMap;
8
9#[derive(Clone, Debug, ProtobufTransform, Serialize)]
11#[cyfs_protobuf_type(crate::codec::protos::AddApp)]
12pub struct AddApp {
13 pub app_owner_id: Option<ObjectId>,
14}
15
16#[derive(Clone, Debug, ProtobufTransform, Serialize)]
17#[cyfs_protobuf_type(crate::codec::protos::InstallApp)]
18pub struct InstallApp {
19 pub ver: String,
20 pub run_after_install: bool,
21}
22#[derive(Clone, Debug, ProtobufEncode, ProtobufDecode, ProtobufTransformType, Serialize)]
23#[cyfs_protobuf_type(crate::codec::protos::ModifyAppPermission)]
24pub struct ModifyAppPermission {
25 pub permission: HashMap<String, bool>,
26}
27
28impl ProtobufTransform<protos::ModifyAppPermission> for ModifyAppPermission {
29 fn transform(value: protos::ModifyAppPermission) -> BuckyResult<Self> {
30 let mut permission = HashMap::new();
31 for item in &value.permission {
32 permission.insert(item.key.clone(), item.value);
33 }
34 Ok(Self { permission })
35 }
36}
37
38impl ProtobufTransform<&ModifyAppPermission> for protos::ModifyAppPermission {
39 fn transform(value: &ModifyAppPermission) -> BuckyResult<Self> {
40 let mut permission = vec![];
41 let tree_map: std::collections::BTreeMap<String, bool> =
42 value.permission.clone().into_iter().collect();
43 for (key, value) in tree_map {
44 permission.push(protos::StringBoolMapItem { key, value })
45 }
46 Ok(Self { permission })
47 }
48}
49
50#[derive(Copy, Clone, Debug, ProtobufEncode, ProtobufDecode, ProtobufTransformType, Serialize)]
51#[cyfs_protobuf_type(crate::codec::protos::AppQuota)]
52pub struct AppQuota {
53 pub mem: i64,
54 pub disk_space: i64,
55 pub cpu: i64,
56}
57
58impl ProtobufTransform<protos::AppQuota> for AppQuota {
59 fn transform(value: protos::AppQuota) -> BuckyResult<Self> {
60 Ok(Self {
61 mem: value.mem.parse::<i64>()?,
62 disk_space: value.disk_space.parse::<i64>()?,
63 cpu: value.cpu.parse::<i64>()?,
64 })
65 }
66}
67
68impl ProtobufTransform<&AppQuota> for protos::AppQuota {
69 fn transform(value: &AppQuota) -> BuckyResult<Self> {
70 Ok(Self {
71 mem: value.mem.to_string(),
72 disk_space: value.disk_space.to_string(),
73 cpu: value.cpu.to_string(),
74 })
75 }
76}
77
78#[derive(Clone, Debug, ProtobufTransformType, Serialize)]
79#[cyfs_protobuf_type(crate::codec::protos::CmdCode)]
80pub enum CmdCode {
81 Add(AddApp),
82 Remove,
83 Install(InstallApp),
84 Uninstall,
85 Start,
86 Stop,
87 SetPermission(ModifyAppPermission),
88 SetQuota(AppQuota),
89 SetAutoUpdate(bool),
90 Unknown,
91}
92
93impl ProtobufTransform<protos::CmdCode> for CmdCode {
112 fn transform(value: protos::CmdCode) -> BuckyResult<Self> {
113 let ret = match value.code {
114 0 => Self::Add(ProtobufTransform::transform(value.add_app.unwrap())?),
115 1 => Self::Remove,
116 2 => Self::Install(ProtobufTransform::transform(value.install_app.unwrap())?),
117 3 => Self::Uninstall,
118 4 => Self::Start,
119 5 => Self::Stop,
120 6 => Self::SetPermission(ProtobufTransform::transform(value.app_permission.unwrap())?),
121 7 => Self::SetQuota(ProtobufTransform::transform(value.app_quota.unwrap())?),
122 8 => Self::SetAutoUpdate(value.auto_update.unwrap()),
123 v @ _ => {
124 warn!("unknown app cmd code: {}", v);
125 Self::Unknown
126 }
127 };
128
129 Ok(ret)
130 }
131}
132
133impl ProtobufTransform<&CmdCode> for protos::CmdCode {
134 fn transform(value: &CmdCode) -> BuckyResult<Self> {
135 let mut ret = Self {
136 code: -1,
137 add_app: None,
138 install_app: None,
139 app_permission: None,
140 app_quota: None,
141 auto_update: None,
142 };
143 match value {
144 CmdCode::Add(v) => {
145 ret.code = 0;
146 ret.add_app = Some(ProtobufTransform::transform(v)?);
147 }
148 CmdCode::Remove => {
149 ret.code = 1;
150 }
151 CmdCode::Install(v) => {
152 ret.code = 2;
153 ret.install_app = Some(ProtobufTransform::transform(v)?);
154 }
155 CmdCode::Uninstall => {
156 ret.code = 3;
157 }
158 CmdCode::Start => {
159 ret.code = 4;
160 }
161 CmdCode::Stop => {
162 ret.code = 5;
163 }
164 CmdCode::SetPermission(v) => {
165 ret.code = 6;
166 ret.app_permission = Some(ProtobufTransform::transform(v)?);
167 }
168 CmdCode::SetQuota(v) => {
169 ret.code = 7;
170 ret.app_quota = Some(ProtobufTransform::transform(v)?);
171 }
172 CmdCode::SetAutoUpdate(v) => {
173 ret.code = 8;
174 ret.auto_update = Some(*v);
175 }
176 _ => {
177 ret.code = -1;
178 }
179 }
180 Ok(ret)
181 }
182}
183
184#[derive(Clone, ProtobufEncode, ProtobufDecode, ProtobufTransform, Serialize)]
185#[cyfs_protobuf_type(crate::codec::protos::AppCmdDesc)]
186pub struct AppCmdDesc {
187 pub app_id: DecAppId,
188 pub cmd_code: CmdCode,
189}
190
191impl DescContent for AppCmdDesc {
192 fn obj_type() -> u16 {
193 CoreObjectType::AppCmd as u16
194 }
195
196 fn format(&self) -> u8 {
197 OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
198 }
199
200 type OwnerType = Option<ObjectId>;
201 type AreaType = SubDescNone;
202 type AuthorType = SubDescNone;
203 type PublicKeyType = SubDescNone;
204}
205
206#[derive(Clone, Default, ProtobufEmptyEncode, ProtobufEmptyDecode, Serialize)]
207pub struct AppCmdBody {}
208
209impl BodyContent for AppCmdBody {
210 fn format(&self) -> u8 {
211 OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
212 }
213}
214
215type AppCmdType = NamedObjType<AppCmdDesc, AppCmdBody>;
216type AppCmdBuilder = NamedObjectBuilder<AppCmdDesc, AppCmdBody>;
217
218pub type AppCmdId = NamedObjectId<AppCmdType>;
219pub type AppCmd = NamedObjectBase<AppCmdType>;
220
221pub trait AppCmdObj {
222 fn app_id(&self) -> &DecAppId;
223 fn cmd(&self) -> &CmdCode;
224
225 fn add(owner: ObjectId, id: DecAppId, app_owner: Option<ObjectId>) -> Self;
226 fn remove(owner: ObjectId, id: DecAppId) -> Self;
227 fn install(owner: ObjectId, id: DecAppId, version: &str, run_after_install: bool) -> Self;
228 fn uninstall(owner: ObjectId, id: DecAppId) -> Self;
229 fn start(owner: ObjectId, id: DecAppId) -> Self;
230 fn stop(owner: ObjectId, id: DecAppId) -> Self;
231 fn set_permission(owner: ObjectId, id: DecAppId, permission: ModifyAppPermission) -> Self;
233 fn set_quota(owner: ObjectId, id: DecAppId, quota: AppQuota) -> Self;
235 fn set_auto_update(owner: ObjectId, id: DecAppId, auto_update: bool) -> Self;
236
237 fn output(&self) -> String;
238}
239
240struct AppCmdHelper {}
241
242impl AppCmdHelper {
243 fn create(owner: ObjectId, app_id: DecAppId, cmd_code: CmdCode) -> AppCmd {
244 let desc = AppCmdDesc { app_id, cmd_code };
245
246 AppCmdBuilder::new(desc, AppCmdBody {})
247 .owner(owner)
248 .option_create_time(None)
249 .build()
250 }
251}
252
253impl AppCmdObj for AppCmd {
254 fn app_id(&self) -> &DecAppId {
255 &self.desc().content().app_id
256 }
257
258 fn cmd(&self) -> &CmdCode {
259 &self.desc().content().cmd_code
260 }
261
262 fn add(owner: ObjectId, id: DecAppId, app_owner: Option<ObjectId>) -> Self {
263 let cmd = CmdCode::Add(AddApp {
264 app_owner_id: app_owner,
265 });
266 AppCmdHelper::create(owner, id, cmd)
267 }
268
269 fn remove(owner: ObjectId, id: DecAppId) -> Self {
270 AppCmdHelper::create(owner, id, CmdCode::Remove)
271 }
272
273 fn install(owner: ObjectId, id: DecAppId, version: &str, run_after_install: bool) -> Self {
274 let cmd = CmdCode::Install(InstallApp {
275 ver: version.to_owned(),
276 run_after_install,
277 });
278
279 AppCmdHelper::create(owner, id, cmd)
280 }
281
282 fn uninstall(owner: ObjectId, id: DecAppId) -> Self {
283 AppCmdHelper::create(owner, id, CmdCode::Uninstall)
284 }
285
286 fn start(owner: ObjectId, id: DecAppId) -> Self {
287 AppCmdHelper::create(owner, id, CmdCode::Start)
288 }
289
290 fn stop(owner: ObjectId, id: DecAppId) -> Self {
291 AppCmdHelper::create(owner, id, CmdCode::Stop)
292 }
293
294 fn set_permission(owner: ObjectId, id: DecAppId, permission: ModifyAppPermission) -> Self {
295 AppCmdHelper::create(owner, id, CmdCode::SetPermission(permission))
296 }
297
298 fn set_quota(owner: ObjectId, id: DecAppId, quota: AppQuota) -> Self {
299 AppCmdHelper::create(owner, id, CmdCode::SetQuota(quota))
300 }
301
302 fn set_auto_update(owner: ObjectId, id: DecAppId, auto_update: bool) -> Self {
303 AppCmdHelper::create(owner, id, CmdCode::SetAutoUpdate(auto_update))
304 }
305
306 fn output(&self) -> String {
307 let app_id = self.app_id();
308 let cmd_code = self.cmd();
309 let create_time = bucky_time_to_system_time(self.desc().create_time());
310 let create_time: DateTime<Local> = create_time.into();
311 format!(
312 "[AppCmd] appid:{}, cmd: {:?}, create time:{}",
313 app_id,
314 cmd_code,
315 create_time.format("[%Y-%m-%d %H:%M:%S.%3f]")
316 )
317 }
318}