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 auth: Option<RuntimeAuthStatusSummary>,
50 pub blob_storage: Option<RuntimeBlobStorageStatusSummary>,
51 pub recent_failures: Vec<RecentFailure>,
52 pub visibility: Vec<RuntimeVisibilityEntry>,
53 pub readiness: CanicReadinessStatus,
54 pub status: RuntimeStatus,
55}
56
57#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
62pub struct RuntimeBuildInfo {
63 pub package_name: String,
64 pub package_version: String,
65 pub canic_version: String,
66 pub canister_version: u64,
67}
68
69#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
74pub struct RuntimeCheck {
75 pub category: String,
76 pub code: String,
77 pub status: RuntimeCheckStatus,
78 pub subject: String,
79 pub detail: String,
80 pub next: Option<String>,
81 pub source: String,
82}
83
84#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
89pub struct RuntimeDiagnostic {
90 pub category: String,
91 pub code: String,
92 pub severity: RuntimeDiagnosticSeverity,
93 pub subject: String,
94 pub detail: String,
95 pub next: Option<String>,
96 pub source: String,
97}
98
99#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
104pub struct RuntimeFeatureStatus {
105 pub name: String,
106 pub enabled: bool,
107 pub visibility: RuntimeFieldVisibility,
108 pub source: String,
109}
110
111#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
116pub struct RuntimeTopologyStatus {
117 pub root: Option<Principal>,
118 pub parent: Option<Principal>,
119 pub subnet: Option<Principal>,
120 pub source: String,
121}
122
123#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
128pub struct CanicTimerStatus {
129 pub name: String,
130 pub subsystem: String,
131 pub status: TimerStatus,
132 pub enabled: bool,
133 pub registered: bool,
134 pub last_success_at_ns: Option<u64>,
135 pub last_failure_at_ns: Option<u64>,
136 pub next_due_at_ns: Option<u64>,
137 pub consecutive_failures: u64,
138 pub last_error_code: Option<String>,
139 pub last_error_summary: Option<String>,
140}
141
142#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
147pub struct RuntimeStateSummary {
148 pub manifest_schema_version: u32,
149 pub domains: Vec<RuntimeStateDomainSummary>,
150 pub total_stable_memory_pages: Option<u64>,
151}
152
153#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
158pub struct RuntimeStateDomainSummary {
159 pub domain: String,
160 pub version: u32,
161 pub storage: String,
162 pub memory_id: Option<u8>,
163 pub status: RuntimeStateDomainStatus,
164}
165
166#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
171pub struct RuntimeAuthStatusSummary {
172 pub auth_features: Vec<RuntimeFeatureStatus>,
173}
174
175#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
180pub struct RuntimeBlobStorageStatusSummary {
181 pub blob_storage_features: Vec<RuntimeFeatureStatus>,
182}
183
184#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
189pub struct RecentFailure {
190 pub occurred_at_ns: u64,
191 pub subsystem: String,
192 pub code: String,
193 pub severity: FailureSeverity,
194 pub summary: String,
195 pub correlation_id: Option<String>,
196 pub redacted: bool,
197}
198
199#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
204pub struct RuntimeVisibilityEntry {
205 pub field: String,
206 pub visibility: RuntimeFieldVisibility,
207}
208
209#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
214#[serde(rename_all = "snake_case")]
215pub enum HealthStatus {
216 #[serde(alias = "Healthy")]
217 Healthy,
218 #[serde(alias = "Degraded")]
219 Degraded,
220 #[serde(alias = "Unhealthy")]
221 Unhealthy,
222 #[serde(alias = "Unknown")]
223 Unknown,
224}
225
226#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
227#[serde(rename_all = "snake_case")]
228pub enum ReadinessStatus {
229 #[serde(alias = "Ready")]
230 Ready,
231 #[serde(alias = "Degraded")]
232 Degraded,
233 #[serde(alias = "NotReady")]
234 NotReady,
235 #[serde(alias = "NotEvaluated")]
236 NotEvaluated,
237}
238
239#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
240#[serde(rename_all = "snake_case")]
241pub enum RuntimeStatus {
242 #[serde(alias = "Ok")]
243 Ok,
244 #[serde(alias = "Degraded")]
245 Degraded,
246 #[serde(alias = "Failing")]
247 Failing,
248 #[serde(alias = "Unknown")]
249 Unknown,
250}
251
252#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
253#[serde(rename_all = "snake_case")]
254pub enum TimerStatus {
255 #[serde(alias = "Healthy")]
256 Healthy,
257 #[serde(alias = "Delayed")]
258 Delayed,
259 #[serde(alias = "Failing")]
260 Failing,
261 #[serde(alias = "Disabled")]
262 Disabled,
263 #[serde(alias = "NotRegistered")]
264 NotRegistered,
265 #[serde(alias = "Unknown")]
266 Unknown,
267}
268
269#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
270#[serde(rename_all = "snake_case")]
271pub enum FailureSeverity {
272 #[serde(alias = "Info")]
273 Info,
274 #[serde(alias = "Warning")]
275 Warning,
276 #[serde(alias = "Error")]
277 Error,
278 #[serde(alias = "Critical")]
279 Critical,
280}
281
282#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
283#[serde(rename_all = "snake_case")]
284pub enum RuntimeCheckStatus {
285 #[serde(alias = "Pass")]
286 Pass,
287 #[serde(alias = "Warn")]
288 Warn,
289 #[serde(alias = "Fail")]
290 Fail,
291 #[serde(alias = "NotEvaluated")]
292 NotEvaluated,
293}
294
295#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
296#[serde(rename_all = "snake_case")]
297pub enum RuntimeDiagnosticSeverity {
298 #[serde(alias = "Info")]
299 Info,
300 #[serde(alias = "Warning")]
301 Warning,
302 #[serde(alias = "Blocked")]
303 Blocked,
304 #[serde(alias = "Unsupported")]
305 Unsupported,
306}
307
308#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
309#[serde(rename_all = "snake_case")]
310pub enum RuntimeFieldVisibility {
311 #[serde(alias = "PublicSafe")]
312 PublicSafe,
313 #[serde(alias = "OperatorOnly")]
314 OperatorOnly,
315 #[serde(alias = "ControllerOnly")]
316 ControllerOnly,
317 #[serde(alias = "FeatureGated")]
318 FeatureGated,
319 #[serde(alias = "Disabled")]
320 Disabled,
321}
322
323#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
324#[serde(rename_all = "snake_case")]
325pub enum RuntimeStateDomainStatus {
326 #[serde(alias = "Ok")]
327 Ok,
328 #[serde(alias = "Warning")]
329 Warning,
330 #[serde(alias = "Failing")]
331 Failing,
332 #[serde(alias = "NotEvaluated")]
333 NotEvaluated,
334}
335
336#[cfg(test)]
337mod tests {
338 use super::*;
339 use candid::{Decode, Encode};
340 use serde::de::DeserializeOwned;
341 use std::fmt::Debug;
342
343 #[test]
344 fn runtime_enums_roundtrip_candid_with_runtime_variant_labels() {
345 assert_enum_candid_contract(HealthStatus::Unknown);
346 assert_enum_candid_contract(ReadinessStatus::NotEvaluated);
347 assert_enum_candid_contract(RuntimeStatus::Failing);
348 assert_enum_candid_contract(TimerStatus::NotRegistered);
349 assert_enum_candid_contract(FailureSeverity::Critical);
350 assert_enum_candid_contract(RuntimeCheckStatus::NotEvaluated);
351 assert_enum_candid_contract(RuntimeDiagnosticSeverity::Unsupported);
352 assert_enum_candid_contract(RuntimeFieldVisibility::OperatorOnly);
353 assert_enum_candid_contract(RuntimeStateDomainStatus::NotEvaluated);
354 }
355
356 fn assert_enum_candid_contract<T>(value: T)
357 where
358 T: CandidType + Clone + Debug + DeserializeOwned + Eq,
359 {
360 let bytes = Encode!(&value).expect("encode runtime enum");
361 let decoded = Decode!(&bytes, T).expect("decode runtime enum");
362
363 assert_eq!(decoded, value);
364 }
365}