ic_backup/model/application_ingress/request/
mod.rs1use super::{ApplicationIngressError, ApplicationIngressPayload};
4use crate::model::attempt_journal::MutationReservation;
5use crate::model::attempt_journal::ObservationReservation;
6use crate::model::{
7 attempt_journal::{AttemptAuthorityRecord, AttemptJournalRecord},
8 operation_plan::OperationPlanRecord,
9};
10
11#[derive(Debug)]
16pub struct ApplicationMutationRequest<'a> {
17 plan: &'a OperationPlanRecord,
18 payload: &'a ApplicationIngressPayload,
19 reservation: MutationReservation,
20}
21impl<'a> ApplicationMutationRequest<'a> {
22 pub fn new(
26 plan: &'a OperationPlanRecord,
27 sequence: u64,
28 journal: &AttemptJournalRecord,
29 payload: &'a ApplicationIngressPayload,
30 ) -> Result<Self, ApplicationIngressError> {
31 let authority = authority(plan, sequence, journal)?;
32 payload.validate_mutation_binding(authority.binding())?;
33 let reservation = MutationReservation::new(
34 authority,
35 journal,
36 ApplicationIngressError::NoPendingMutation,
37 ApplicationIngressError::AuthorityMismatch,
38 ApplicationIngressError::MutationMismatch,
39 ApplicationIngressError::ObservationPending,
40 )?;
41 Ok(Self {
42 plan,
43 payload,
44 reservation,
45 })
46 }
47 #[must_use]
49 pub const fn plan(&self) -> &OperationPlanRecord {
50 self.plan
51 }
52 #[must_use]
54 pub const fn payload(&self) -> &ApplicationIngressPayload {
55 self.payload
56 }
57 #[must_use]
59 pub const fn authority(&self) -> &AttemptAuthorityRecord {
60 &self.reservation.authority
61 }
62 #[must_use]
64 pub const fn mutation_attempt(&self) -> u32 {
65 self.reservation.mutation_attempt
66 }
67 pub fn validate_journal(
71 &self,
72 journal: &AttemptJournalRecord,
73 ) -> Result<(), ApplicationIngressError> {
74 self.reservation.validate(
75 journal,
76 ApplicationIngressError::AuthorityMismatch,
77 ApplicationIngressError::MutationMismatch,
78 ApplicationIngressError::ObservationPending,
79 )
80 }
81}
82
83#[derive(Debug)]
88pub struct ApplicationObservationRequest<'a> {
89 plan: &'a OperationPlanRecord,
90 payload: &'a ApplicationIngressPayload,
91 reservation: ObservationReservation,
92}
93impl<'a> ApplicationObservationRequest<'a> {
94 pub fn new(
98 plan: &'a OperationPlanRecord,
99 sequence: u64,
100 journal: &AttemptJournalRecord,
101 payload: &'a ApplicationIngressPayload,
102 ) -> Result<Self, ApplicationIngressError> {
103 let authority = authority(plan, sequence, journal)?;
104 payload.validate_observation_binding(authority.binding())?;
105 let reservation = ObservationReservation::new(authority, journal, payload.digest())
106 .map_err(crate::model::ic_observation::IcObservationRequestError::from)?;
107 Ok(Self {
108 plan,
109 payload,
110 reservation,
111 })
112 }
113 #[must_use]
115 pub const fn plan(&self) -> &OperationPlanRecord {
116 self.plan
117 }
118 #[must_use]
120 pub const fn payload(&self) -> &ApplicationIngressPayload {
121 self.payload
122 }
123 #[must_use]
125 pub const fn authority(&self) -> &AttemptAuthorityRecord {
126 &self.reservation.authority
127 }
128 #[must_use]
130 pub const fn mutation_attempt(&self) -> u32 {
131 self.reservation.mutation_attempt
132 }
133 #[must_use]
135 pub const fn observation_attempt(&self) -> u32 {
136 self.reservation.observation_attempt
137 }
138 pub fn validate_journal(
142 &self,
143 journal: &AttemptJournalRecord,
144 ) -> Result<(), ApplicationIngressError> {
145 self.reservation
146 .validate(journal)
147 .map_err(crate::model::ic_observation::IcObservationRequestError::from)?;
148 Ok(())
149 }
150}
151
152fn authority(
153 plan: &OperationPlanRecord,
154 sequence: u64,
155 journal: &AttemptJournalRecord,
156) -> Result<AttemptAuthorityRecord, ApplicationIngressError> {
157 let authority = plan.attempt_authority(sequence)?;
158 if journal.authority() != &authority {
159 return Err(ApplicationIngressError::AuthorityMismatch);
160 }
161 Ok(authority)
162}