1use crate::dto::prelude::*;
2
3pub const RUNTIME_INTROSPECTION_SCHEMA_VERSION: u32 = 1;
4
5#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
10pub struct CanicHealthStatus {
11 pub schema_version: u32,
12 pub status: HealthStatus,
13 pub observed_at_ns: Option<u64>,
14 pub checks: Vec<RuntimeCheck>,
15}
16
17#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
22pub struct CanicReadinessStatus {
23 pub schema_version: u32,
24 pub role: Option<String>,
25 pub status: ReadinessStatus,
26 pub observed_at_ns: u64,
27 pub checks: Vec<RuntimeCheck>,
28 pub blockers: Vec<RuntimeDiagnostic>,
29 pub warnings: Vec<RuntimeDiagnostic>,
30}
31
32#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
37pub struct CanicRuntimeStatus {
38 pub schema_version: u32,
39 pub observed_at_ns: u64,
40 pub canister_id: Principal,
41 pub role: Option<String>,
42 pub root: Option<Principal>,
43 pub network: Option<String>,
44 pub build: RuntimeBuildInfo,
45 pub features: Vec<RuntimeFeatureStatus>,
46 pub topology: Option<RuntimeTopologyStatus>,
47 pub timers: Vec<CanicTimerStatus>,
48 pub state: Option<RuntimeStateSummary>,
49 pub recent_failures: Vec<RecentFailure>,
50 pub visibility: Vec<RuntimeVisibilityEntry>,
51 pub readiness: CanicReadinessStatus,
52 pub status: RuntimeStatus,
53}
54
55#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
60pub struct RuntimeBuildInfo {
61 pub package_name: String,
62 pub package_version: String,
63 pub canic_version: String,
64 pub canister_version: u64,
65}
66
67#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
72pub struct RuntimeCheck {
73 pub category: String,
74 pub code: String,
75 pub status: RuntimeCheckStatus,
76 pub subject: String,
77 pub detail: String,
78 pub next: Option<String>,
79 pub source: String,
80}
81
82#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
87pub struct RuntimeDiagnostic {
88 pub category: String,
89 pub code: String,
90 pub severity: RuntimeDiagnosticSeverity,
91 pub subject: String,
92 pub detail: String,
93 pub next: Option<String>,
94 pub source: String,
95}
96
97#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
102pub struct RuntimeFeatureStatus {
103 pub name: String,
104 pub enabled: bool,
105 pub visibility: RuntimeFieldVisibility,
106 pub source: String,
107}
108
109#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
114pub struct RuntimeTopologyStatus {
115 pub root: Option<Principal>,
116 pub parent: Option<Principal>,
117 pub subnet: Option<Principal>,
118 pub source: String,
119}
120
121#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
126pub struct CanicTimerStatus {
127 pub name: String,
128 pub subsystem: String,
129 pub status: TimerStatus,
130 pub enabled: bool,
131 pub registered: bool,
132 pub last_success_at_ns: Option<u64>,
133 pub last_failure_at_ns: Option<u64>,
134 pub next_due_at_ns: Option<u64>,
135 pub consecutive_failures: u64,
136 pub last_error_code: Option<String>,
137 pub last_error_summary: Option<String>,
138}
139
140#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
145pub struct RuntimeStateSummary {
146 pub manifest_schema_version: u32,
147 pub domains: Vec<RuntimeStateDomainSummary>,
148 pub total_stable_memory_pages: Option<u64>,
149}
150
151#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
156pub struct RuntimeStateDomainSummary {
157 pub domain: String,
158 pub version: u32,
159 pub storage: String,
160 pub memory_id: Option<u8>,
161 pub status: RuntimeStateDomainStatus,
162}
163
164#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
169pub struct RecentFailure {
170 pub occurred_at_ns: u64,
171 pub subsystem: String,
172 pub code: String,
173 pub severity: FailureSeverity,
174 pub summary: String,
175 pub correlation_id: Option<String>,
176 pub redacted: bool,
177}
178
179#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
184pub struct RuntimeVisibilityEntry {
185 pub field: String,
186 pub visibility: RuntimeFieldVisibility,
187}
188
189#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
194#[serde(rename_all = "snake_case")]
195pub enum HealthStatus {
196 #[serde(alias = "Healthy")]
197 Healthy,
198 #[serde(alias = "Degraded")]
199 Degraded,
200 #[serde(alias = "Unhealthy")]
201 Unhealthy,
202}
203
204#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
205#[serde(rename_all = "snake_case")]
206pub enum ReadinessStatus {
207 #[serde(alias = "Ready")]
208 Ready,
209 #[serde(alias = "Degraded")]
210 Degraded,
211 #[serde(alias = "NotReady")]
212 NotReady,
213 #[serde(alias = "NotEvaluated")]
214 NotEvaluated,
215}
216
217#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
218#[serde(rename_all = "snake_case")]
219pub enum RuntimeStatus {
220 #[serde(alias = "Ok")]
221 Ok,
222 #[serde(alias = "Degraded")]
223 Degraded,
224 #[serde(alias = "Failing")]
225 Failing,
226 #[serde(alias = "Unknown")]
227 Unknown,
228}
229
230#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
231#[serde(rename_all = "snake_case")]
232pub enum TimerStatus {
233 #[serde(alias = "Healthy")]
234 Healthy,
235 #[serde(alias = "Delayed")]
236 Delayed,
237 #[serde(alias = "Failing")]
238 Failing,
239 #[serde(alias = "Disabled")]
240 Disabled,
241 #[serde(alias = "NotRegistered")]
242 NotRegistered,
243 #[serde(alias = "Unknown")]
244 Unknown,
245}
246
247#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
248#[serde(rename_all = "snake_case")]
249pub enum FailureSeverity {
250 #[serde(alias = "Info")]
251 Info,
252 #[serde(alias = "Warning")]
253 Warning,
254 #[serde(alias = "Error")]
255 Error,
256 #[serde(alias = "Critical")]
257 Critical,
258}
259
260#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
261#[serde(rename_all = "snake_case")]
262pub enum RuntimeCheckStatus {
263 #[serde(alias = "Pass")]
264 Pass,
265 #[serde(alias = "Warn")]
266 Warn,
267 #[serde(alias = "Fail")]
268 Fail,
269 #[serde(alias = "NotEvaluated")]
270 NotEvaluated,
271}
272
273#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
274#[serde(rename_all = "snake_case")]
275pub enum RuntimeDiagnosticSeverity {
276 #[serde(alias = "Info")]
277 Info,
278 #[serde(alias = "Warning")]
279 Warning,
280 #[serde(alias = "Blocked")]
281 Blocked,
282 #[serde(alias = "Unsupported")]
283 Unsupported,
284}
285
286#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
287#[serde(rename_all = "snake_case")]
288pub enum RuntimeFieldVisibility {
289 #[serde(alias = "PublicSafe")]
290 PublicSafe,
291 #[serde(alias = "OperatorOnly")]
292 OperatorOnly,
293 #[serde(alias = "ControllerOnly")]
294 ControllerOnly,
295 #[serde(alias = "FeatureGated")]
296 FeatureGated,
297 #[serde(alias = "Disabled")]
298 Disabled,
299}
300
301#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
302#[serde(rename_all = "snake_case")]
303pub enum RuntimeStateDomainStatus {
304 #[serde(alias = "Ok")]
305 Ok,
306 #[serde(alias = "Warning")]
307 Warning,
308 #[serde(alias = "Failing")]
309 Failing,
310 #[serde(alias = "NotEvaluated")]
311 NotEvaluated,
312}
313
314#[cfg(test)]
315mod tests {
316 use super::*;
317 use candid::{Decode, Encode};
318 use serde::de::DeserializeOwned;
319 use std::fmt::Debug;
320
321 #[test]
322 fn runtime_enums_roundtrip_candid_with_runtime_variant_labels() {
323 assert_enum_candid_contract(HealthStatus::Unhealthy);
324 assert_enum_candid_contract(ReadinessStatus::NotEvaluated);
325 assert_enum_candid_contract(RuntimeStatus::Failing);
326 assert_enum_candid_contract(TimerStatus::NotRegistered);
327 assert_enum_candid_contract(FailureSeverity::Critical);
328 assert_enum_candid_contract(RuntimeCheckStatus::NotEvaluated);
329 assert_enum_candid_contract(RuntimeDiagnosticSeverity::Unsupported);
330 assert_enum_candid_contract(RuntimeFieldVisibility::OperatorOnly);
331 assert_enum_candid_contract(RuntimeStateDomainStatus::NotEvaluated);
332 }
333
334 fn assert_enum_candid_contract<T>(value: T)
335 where
336 T: CandidType + Clone + Debug + DeserializeOwned + Eq,
337 {
338 let bytes = Encode!(&value).expect("encode runtime enum");
339 let decoded = Decode!(&bytes, T).expect("decode runtime enum");
340
341 assert_eq!(decoded, value);
342 }
343}