Skip to main content

reduct_base/msg/
server_api.rs

1// Copyright 2021-2026 ReductSoftware UG
2// Licensed under the Apache License, Version 2.0
3
4use crate::msg::bucket_api::{BucketInfo, BucketSettings};
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use std::fmt::{Display, Formatter};
8
9/// License information
10///
11#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
12pub struct License {
13    /// Licensee usually is the company name
14    pub licensee: String,
15    /// Invoice number
16    pub invoice: String,
17    /// Expiry date
18    pub expiry_date: DateTime<Utc>,
19    /// Plan name
20    pub plan: String,
21    /// Number of devices (0 for unlimited)
22    pub device_number: u32,
23    /// Disk quota in TB (0 for unlimited)
24    pub disk_quota: i32,
25    /// Fingerprint
26    #[serde(default)]
27    pub fingerprint: String,
28}
29
30impl Display for License {
31    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32        write!(
33            f,
34            "\n\tLicensee: {}\n\tInvoice: {}\n\tExpiry Date: {}\n\tPlan: {}\n\tNumber of Devices: {}\n\tDisk Quota: {} TB,\n\tFingerprint: {}",
35            self.licensee, self.invoice, self.expiry_date, self.plan, self.device_number, self.disk_quota, self.fingerprint
36        )
37    }
38}
39
40/// Information about a ReductSoftware UG instance
41#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
42pub struct ServerInfo {
43    /// Version of ReductSoftware UG instance
44    pub version: String,
45    /// Effective instance name resolved from the runtime configuration
46    #[serde(default)]
47    pub instance_name: String,
48    /// Effective instance role (`STANDALONE`, `PRIMARY`, `SECONDARY`, or `REPLICA`)
49    #[serde(default)]
50    pub instance_role: String,
51    /// Number of buckets
52    pub bucket_count: u64,
53    /// Disk usage in bytes
54    pub usage: u64,
55    /// Uptime in seconds
56    pub uptime: u64,
57    /// Oldest record in instance
58    pub oldest_record: u64,
59    /// Latest record in instance
60    pub latest_record: u64,
61    /// Default settings
62    pub defaults: Defaults,
63    /// License information if it is `None`, then the instance uses Apache-2.0
64    pub license: Option<License>,
65}
66
67/// Default settings
68#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
69pub struct Defaults {
70    pub bucket: BucketSettings,
71}
72
73/// BucketLists
74#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
75pub struct BucketInfoList {
76    pub buckets: Vec<BucketInfo>,
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn server_info_deserializes_without_instance_identity() {
85        let mut value = serde_json::to_value(ServerInfo {
86            instance_name: "edge-a".to_string(),
87            instance_role: "PRIMARY".to_string(),
88            ..ServerInfo::default()
89        })
90        .unwrap();
91        let object = value.as_object_mut().unwrap();
92        object.remove("instance_name");
93        object.remove("instance_role");
94
95        let info: ServerInfo = serde_json::from_value(value).unwrap();
96        assert_eq!(info.instance_name, "");
97        assert_eq!(info.instance_role, "");
98    }
99}