Skip to main content

rustfs_tls_runtime/
debug.rs

1// Copyright 2024 RustFS Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::state::TlsRuntimeStatusSnapshot;
16use serde::Serialize;
17
18#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
19pub struct TlsConsumerStatusItem {
20    pub consumer: &'static str,
21    pub generation: u64,
22    pub has_root_ca: bool,
23    pub has_mtls_identity: bool,
24}
25
26#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
27pub struct TlsDebugStatusResponse {
28    pub foundation: TlsRuntimeStatusSnapshot,
29    pub consumers: Vec<TlsConsumerStatusItem>,
30}
31
32#[derive(Debug, Clone)]
33pub struct TlsDebugStatusResponseBuilder {
34    foundation: TlsRuntimeStatusSnapshot,
35    consumers: Vec<TlsConsumerStatusItem>,
36}
37
38impl TlsDebugStatusResponse {
39    pub fn builder(foundation: TlsRuntimeStatusSnapshot) -> TlsDebugStatusResponseBuilder {
40        TlsDebugStatusResponseBuilder {
41            foundation,
42            consumers: Vec::new(),
43        }
44    }
45}
46
47impl TlsDebugStatusResponseBuilder {
48    pub fn push_consumers<I>(mut self, sources: I) -> Self
49    where
50        I: IntoIterator<Item = TlsConsumerStatusItem>,
51    {
52        self.consumers.extend(sources);
53        self
54    }
55
56    pub fn build(self) -> TlsDebugStatusResponse {
57        TlsDebugStatusResponse {
58            foundation: self.foundation,
59            consumers: self.consumers,
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::{TlsConsumerStatusItem, TlsDebugStatusResponse};
67    use crate::state::{
68        TlsRuntimeConsumerSection, TlsRuntimeOutboundSection, TlsRuntimeRuntimeSection, TlsRuntimeServerSection,
69        TlsRuntimeStatusSnapshot,
70    };
71
72    #[test]
73    fn builder_produces_structured_response() {
74        let foundation = TlsRuntimeStatusSnapshot {
75            runtime: TlsRuntimeRuntimeSection {
76                generation: 5,
77                reload_enabled: true,
78                detect_mode: "poll",
79                last_attempt_time: Some(1),
80                last_success_time: Some(2),
81                last_error: None,
82                source_path: "/tmp/tls".to_string(),
83            },
84            outbound: TlsRuntimeOutboundSection {
85                has_roots: true,
86                has_mtls_identity: false,
87            },
88            server: TlsRuntimeServerSection { has_material: true },
89            consumer: TlsRuntimeConsumerSection { stale_generation: false },
90        };
91
92        let response = TlsDebugStatusResponse::builder(foundation)
93            .push_consumers([TlsConsumerStatusItem {
94                consumer: "test_consumer",
95                generation: 7,
96                has_root_ca: true,
97                has_mtls_identity: false,
98            }])
99            .build();
100
101        let json = serde_json::to_value(response).expect("response should serialize");
102        assert!(json.get("foundation").is_some());
103        assert!(json.get("consumers").is_some());
104        assert!(json["consumers"].is_array());
105    }
106}