@@ -14,7 +14,6 @@ use super::{
1414 db_metadata, CombinedState , DesiredMode , ExistingMode , FlowSetupState , FlowSetupStatusCheck ,
1515 ObjectSetupStatusCheck , ObjectStatus , ResourceIdentifier , ResourceSetupStatusCheck ,
1616 SetupChangeType , StateChange , TargetResourceSetupStatusCheck , TargetSetupState ,
17- TargetSetupStateCommon ,
1817} ;
1918use super :: { AllSetupState , AllSetupStatusCheck } ;
2019use crate :: execution:: db_tracking_setup;
@@ -166,9 +165,8 @@ fn to_object_status<A, B>(existing: Option<A>, desired: Option<B>) -> Result<Obj
166165
167166#[ derive( Debug , Default ) ]
168167struct GroupedResourceStates {
169- desired_common : Option < TargetSetupStateCommon > ,
170- desired : Option < serde_json:: Value > ,
171- existing : CombinedState < serde_json:: Value > ,
168+ desired : Option < TargetSetupState > ,
169+ existing : CombinedState < TargetSetupState > ,
172170}
173171
174172fn group_resource_states < ' a > (
@@ -181,8 +179,7 @@ fn group_resource_states<'a>(
181179 (
182180 key,
183181 GroupedResourceStates {
184- desired_common : Some ( state. common . clone ( ) ) ,
185- desired : Some ( state. state . clone ( ) ) ,
182+ desired : Some ( state. clone ( ) ) ,
186183 existing : CombinedState :: default ( ) ,
187184 } ,
188185 )
@@ -199,14 +196,13 @@ fn group_resource_states<'a>(
199196 }
200197 let entry = entry. or_default ( ) ;
201198 if let Some ( current) = & state. current {
202- entry. existing . current = Some ( current. state . clone ( ) ) ;
199+ entry. existing . current = Some ( current. clone ( ) ) ;
203200 }
204201 for s in state. staging . iter ( ) {
205202 match s {
206- StateChange :: Upsert ( v) => entry
207- . existing
208- . staging
209- . push ( StateChange :: Upsert ( v. state . clone ( ) ) ) ,
203+ StateChange :: Upsert ( v) => {
204+ entry. existing . staging . push ( StateChange :: Upsert ( v. clone ( ) ) )
205+ }
210206 StateChange :: Delete => entry. existing . staging . push ( StateChange :: Delete ) ,
211207 }
212208 }
@@ -247,41 +243,72 @@ pub fn check_flow_setup_status(
247243 . collect ( ) ,
248244 ) ;
249245
250- let target_resources = {
251- let grouped_target_resources = group_resource_states (
252- desired_state. iter ( ) . flat_map ( |d| d. targets . iter ( ) ) ,
253- existing_state. iter ( ) . flat_map ( |e| e. targets . iter ( ) ) ,
254- ) ?;
255- let registry = executor_factory_registry ( ) ;
256- grouped_target_resources
257- . into_iter ( )
258- . map ( |( resource_id, v) | -> Result < _ > {
259- let factory = registry. get ( & resource_id. target_kind ) . ok_or_else ( || {
260- anyhow:: anyhow!(
261- "Target resource type not found: {}" ,
262- resource_id. target_kind
263- )
264- } ) ?;
265- let status_check = match factory {
266- ExecutorFactory :: ExportTarget ( factory) => {
267- factory. check_setup_status ( & resource_id. key , v. desired , v. existing ) ?
246+ let mut target_setup_state_updates = Vec :: new ( ) ;
247+ let mut target_resources = Vec :: new ( ) ;
248+
249+ let grouped_target_resources = group_resource_states (
250+ desired_state. iter ( ) . flat_map ( |d| d. targets . iter ( ) ) ,
251+ existing_state. iter ( ) . flat_map ( |e| e. targets . iter ( ) ) ,
252+ ) ?;
253+ let registry = executor_factory_registry ( ) ;
254+ for ( resource_id, v) in grouped_target_resources. into_iter ( ) {
255+ let factory = registry. get ( & resource_id. target_kind ) . ok_or_else ( || {
256+ anyhow:: anyhow!(
257+ "Target resource type not found: {}" ,
258+ resource_id. target_kind
259+ )
260+ } ) ?;
261+ target_setup_state_updates. push ( ( resource_id. clone ( ) , v. desired . clone ( ) ) ) ;
262+ let ( desired_state, desired_common) = match v. desired {
263+ Some ( desired) => (
264+ ( !desired. common . setup_by_user ) . then_some ( desired. state ) ,
265+ Some ( desired. common ) ,
266+ ) ,
267+ None => ( None , None ) ,
268+ } ;
269+ let existing_without_setup_by_user = CombinedState {
270+ current : v
271+ . existing
272+ . current
273+ . and_then ( |s| s. state_unless_setup_by_user ( ) ) ,
274+ staging : v
275+ . existing
276+ . staging
277+ . into_iter ( )
278+ . filter_map ( |s| match s {
279+ StateChange :: Upsert ( s) => {
280+ s. state_unless_setup_by_user ( ) . map ( StateChange :: Upsert )
268281 }
269- _ => bail ! ( "Unexpected factory type for {}" , resource_id. target_kind) ,
270- } ;
271- Ok ( TargetResourceSetupStatusCheck {
272- target_kind : resource_id. target_kind . clone ( ) ,
273- common : v. desired_common ,
274- status_check,
282+ StateChange :: Delete => Some ( StateChange :: Delete ) ,
275283 } )
276- } )
277- . collect :: < Result < Vec < _ > > > ( ) ?
278- } ;
284+ . collect ( ) ,
285+ } ;
286+ let never_setup_by_sys = desired_state. is_none ( )
287+ && existing_without_setup_by_user. current . is_none ( )
288+ && existing_without_setup_by_user. staging . is_empty ( ) ;
289+ if !never_setup_by_sys {
290+ let status_check = match factory {
291+ ExecutorFactory :: ExportTarget ( factory) => factory. check_setup_status (
292+ & resource_id. key ,
293+ desired_state,
294+ existing_without_setup_by_user,
295+ ) ?,
296+ _ => bail ! ( "Unexpected factory type for {}" , resource_id. target_kind) ,
297+ } ;
298+ target_resources. push ( TargetResourceSetupStatusCheck {
299+ target_kind : resource_id. target_kind . clone ( ) ,
300+ common : desired_common,
301+ status_check,
302+ } ) ;
303+ }
304+ }
279305 Ok ( FlowSetupStatusCheck {
280306 status : to_object_status ( existing_state, desired_state) ?,
281307 seen_flow_metadata_version : existing_state. and_then ( |s| s. seen_flow_metadata_version ) ,
282308 metadata_change,
283309 tracking_table : tracking_table_change,
284310 target_resources,
311+ target_setup_state_updates,
285312 } )
286313}
287314
@@ -392,25 +419,15 @@ pub async fn apply_changes(
392419 . transpose ( ) ?,
393420 ) ;
394421 }
395- for target_resource in & flow_status. target_resources {
422+ for ( resource_id , state_update ) in & flow_status. target_setup_state_updates {
396423 state_updates. insert (
397424 db_metadata:: ResourceTypeKey :: new (
398- MetadataRecordType :: Target ( target_resource . target_kind . clone ( ) ) . to_string ( ) ,
399- target_resource . status_check . key ( ) . clone ( ) ,
425+ MetadataRecordType :: Target ( resource_id . target_kind . clone ( ) ) . to_string ( ) ,
426+ resource_id . key . clone ( ) ,
400427 ) ,
401- target_resource
402- . common
428+ state_update
403429 . as_ref ( )
404- . map ( |c| {
405- serde_json:: to_value ( TargetSetupState {
406- common : c. clone ( ) ,
407- state : target_resource
408- . status_check
409- . desired_state ( )
410- . cloned ( )
411- . unwrap_or_default ( ) ,
412- } )
413- } )
430+ . map ( serde_json:: to_value)
414431 . transpose ( ) ?,
415432 ) ;
416433 }
0 commit comments