ic_backup/model/application_ingress/request/
mod.rs1use super::{ApplicationIngressError, ApplicationIngressPayload};
4use crate::model::attempt_journal::ObservationReservation;
5use crate::model::{
6 attempt_journal::{AttemptAuthorityRecord, AttemptJournalRecord},
7 operation_plan::OperationPlanRecord,
8};
9
10#[derive(Debug)]
15pub struct ApplicationMutationRequest<'a> {
16 plan: &'a OperationPlanRecord,
17 payload: &'a ApplicationIngressPayload,
18 authority: AttemptAuthorityRecord,
19 mutation_attempt: u32,
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 mutation_attempt = journal
34 .pending_mutation()
35 .ok_or(ApplicationIngressError::NoPendingMutation)?;
36 let request = Self {
37 plan,
38 payload,
39 authority,
40 mutation_attempt,
41 };
42 request.validate_journal(journal)?;
43 Ok(request)
44 }
45 #[must_use]
47 pub const fn plan(&self) -> &OperationPlanRecord {
48 self.plan
49 }
50 #[must_use]
52 pub const fn payload(&self) -> &ApplicationIngressPayload {
53 self.payload
54 }
55 #[must_use]
57 pub const fn authority(&self) -> &AttemptAuthorityRecord {
58 &self.authority
59 }
60 #[must_use]
62 pub const fn mutation_attempt(&self) -> u32 {
63 self.mutation_attempt
64 }
65 pub fn validate_journal(
69 &self,
70 journal: &AttemptJournalRecord,
71 ) -> Result<(), ApplicationIngressError> {
72 journal.validate_pending_mutation(
73 &self.authority,
74 self.mutation_attempt,
75 ApplicationIngressError::AuthorityMismatch,
76 ApplicationIngressError::MutationMismatch,
77 ApplicationIngressError::ObservationPending,
78 )
79 }
80}
81
82#[derive(Debug)]
87pub struct ApplicationObservationRequest<'a> {
88 plan: &'a OperationPlanRecord,
89 payload: &'a ApplicationIngressPayload,
90 reservation: ObservationReservation,
91}
92impl<'a> ApplicationObservationRequest<'a> {
93 pub fn new(
97 plan: &'a OperationPlanRecord,
98 sequence: u64,
99 journal: &AttemptJournalRecord,
100 payload: &'a ApplicationIngressPayload,
101 ) -> Result<Self, ApplicationIngressError> {
102 let authority = authority(plan, sequence, journal)?;
103 payload.validate_observation_binding(authority.binding())?;
104 let reservation = ObservationReservation::new(authority, journal, payload.digest())
105 .map_err(crate::model::ic_observation::IcObservationRequestError::from)?;
106 Ok(Self {
107 plan,
108 payload,
109 reservation,
110 })
111 }
112 #[must_use]
114 pub const fn plan(&self) -> &OperationPlanRecord {
115 self.plan
116 }
117 #[must_use]
119 pub const fn payload(&self) -> &ApplicationIngressPayload {
120 self.payload
121 }
122 #[must_use]
124 pub const fn authority(&self) -> &AttemptAuthorityRecord {
125 &self.reservation.authority
126 }
127 #[must_use]
129 pub const fn mutation_attempt(&self) -> u32 {
130 self.reservation.mutation_attempt
131 }
132 #[must_use]
134 pub const fn observation_attempt(&self) -> u32 {
135 self.reservation.observation_attempt
136 }
137 pub fn validate_journal(
141 &self,
142 journal: &AttemptJournalRecord,
143 ) -> Result<(), ApplicationIngressError> {
144 self.reservation
145 .validate(journal)
146 .map_err(crate::model::ic_observation::IcObservationRequestError::from)?;
147 Ok(())
148 }
149}
150
151fn authority(
152 plan: &OperationPlanRecord,
153 sequence: u64,
154 journal: &AttemptJournalRecord,
155) -> Result<AttemptAuthorityRecord, ApplicationIngressError> {
156 let authority = plan.attempt_authority(sequence)?;
157 if journal.authority() != &authority {
158 return Err(ApplicationIngressError::AuthorityMismatch);
159 }
160 Ok(authority)
161}