@@ -26,13 +26,15 @@ use editoast_derive::EditoastError;
26
26
use serde:: Deserialize ;
27
27
use serde:: Serialize ;
28
28
use std:: collections:: HashMap ;
29
+ use std:: ops:: DerefMut as _;
29
30
use std:: sync:: Arc ;
30
31
use thiserror:: Error ;
31
32
use utoipa:: IntoParams ;
32
33
use utoipa:: ToSchema ;
33
34
34
35
use self :: edition:: edit;
35
36
use self :: edition:: split_track_section;
37
+ use super :: pagination:: PaginationStats ;
36
38
use super :: params:: List ;
37
39
use crate :: core:: infra_loading:: InfraLoadRequest ;
38
40
use crate :: core:: infra_state:: InfraStateRequest ;
@@ -44,12 +46,10 @@ use crate::infra_cache::InfraCache;
44
46
use crate :: infra_cache:: ObjectCache ;
45
47
use crate :: map;
46
48
use crate :: map:: MapLayers ;
47
- use crate :: models:: List as ModelList ;
48
- use crate :: models:: NoParams ;
49
49
use crate :: modelsv2:: prelude:: * ;
50
50
use crate :: modelsv2:: DbConnectionPool ;
51
51
use crate :: modelsv2:: Infra ;
52
- use crate :: views:: pagination:: PaginatedResponse ;
52
+ use crate :: views:: pagination:: PaginatedList as _ ;
53
53
use crate :: views:: pagination:: PaginationQueryParam ;
54
54
use crate :: RedisClient ;
55
55
use editoast_schemas:: infra:: SwitchType ;
@@ -211,40 +211,47 @@ async fn refresh(
211
211
Ok ( Json ( RefreshResponse { infra_refreshed } ) )
212
212
}
213
213
214
+ #[ derive( Serialize , ToSchema ) ]
215
+ struct InfraListResponse {
216
+ #[ serde( flatten) ]
217
+ stats : PaginationStats ,
218
+ results : Vec < InfraWithState > ,
219
+ }
220
+
214
221
/// Return a list of infras
215
222
#[ get( "" ) ]
216
223
async fn list (
217
224
db_pool : Data < DbConnectionPool > ,
218
225
core : Data < CoreClient > ,
219
226
pagination_params : Query < PaginationQueryParam > ,
220
- ) -> Result < Json < PaginatedResponse < InfraWithState > > > {
221
- let ( page , per_page ) = pagination_params
227
+ ) -> Result < Json < InfraListResponse > > {
228
+ let settings = pagination_params
222
229
. validate ( 1000 ) ?
223
230
. warn_page_size ( 100 )
224
- . unpack ( ) ;
225
- let db_pool = db_pool. into_inner ( ) ;
226
- let infras = Infra :: list ( db_pool. clone ( ) , page, per_page, NoParams ) . await ?;
227
- let infra_state = call_core_infra_state ( None , db_pool, core) . await ?;
228
- let infras_with_state: Vec < InfraWithState > = infras
229
- . results
230
- . into_iter ( )
231
- . map ( |infra| {
232
- let infra_id = infra. id ;
233
- let state = infra_state
234
- . get ( & infra_id. to_string ( ) )
235
- . unwrap_or ( & InfraStateResponse :: default ( ) )
236
- . status ;
237
- InfraWithState { infra, state }
238
- } )
239
- . collect ( ) ;
240
- let infras_with_state = PaginatedResponse :: < InfraWithState > {
241
- count : infras. count ,
242
- previous : infras. previous ,
243
- next : infras. next ,
244
- results : infras_with_state,
231
+ . into_selection_settings ( ) ;
232
+
233
+ let ( ( infras, stats) , infra_states) = {
234
+ let conn = & mut db_pool. get ( ) . await ?;
235
+ futures:: try_join!(
236
+ Infra :: list_paginated( conn, settings) ,
237
+ fetch_all_infra_states( core. as_ref( ) ) ,
238
+ ) ?
245
239
} ;
246
240
247
- Ok ( Json ( infras_with_state) )
241
+ let response = InfraListResponse {
242
+ stats,
243
+ results : infras
244
+ . into_iter ( )
245
+ . map ( |infra| {
246
+ let state = infra_states
247
+ . get ( & infra. id . to_string ( ) )
248
+ . map ( |response| response. status )
249
+ . unwrap_or_default ( ) ;
250
+ InfraWithState { infra, state }
251
+ } )
252
+ . collect ( ) ,
253
+ } ;
254
+ Ok ( Json ( response) )
248
255
}
249
256
250
257
#[ derive( Debug , Clone , Copy , Default , Deserialize , PartialEq , Eq , Serialize , ToSchema ) ]
@@ -296,11 +303,7 @@ async fn get(
296
303
let conn = & mut db_pool. get ( ) . await ?;
297
304
let infra =
298
305
Infra :: retrieve_or_fail ( conn, infra_id, || InfraApiError :: NotFound { infra_id } ) . await ?;
299
- let infra_state = call_core_infra_state ( Some ( infra_id) , db_pool. into_inner ( ) , core) . await ?;
300
- let state = infra_state
301
- . get ( & infra_id. to_string ( ) )
302
- . unwrap_or ( & InfraStateResponse :: default ( ) )
303
- . status ;
306
+ let state = fetch_infra_state ( infra. id , core. as_ref ( ) ) . await ?. status ;
304
307
Ok ( Json ( InfraWithState { infra, state } ) )
305
308
}
306
309
@@ -562,12 +565,6 @@ async fn unlock(
562
565
Ok ( HttpResponse :: NoContent ( ) . finish ( ) )
563
566
}
564
567
565
- #[ derive( Debug , Default , Deserialize ) ]
566
-
567
- pub struct StatePayload {
568
- infra : Option < i64 > ,
569
- }
570
-
571
568
/// Instructs Core to load an infra
572
569
#[ utoipa:: path(
573
570
tag = "infra" ,
@@ -595,21 +592,9 @@ async fn load(
595
592
Ok ( HttpResponse :: NoContent ( ) . finish ( ) )
596
593
}
597
594
598
- /// Builds a Core cache_status request, runs it
599
- pub async fn call_core_infra_state (
600
- infra_id : Option < i64 > ,
601
- db_pool : Arc < DbConnectionPool > ,
602
- core : Data < CoreClient > ,
603
- ) -> Result < HashMap < String , InfraStateResponse > > {
604
- if let Some ( infra_id) = infra_id {
605
- let conn = & mut db_pool. get ( ) . await ?;
606
- if !Infra :: exists ( conn, infra_id) . await ? {
607
- return Err ( InfraApiError :: NotFound { infra_id } . into ( ) ) ;
608
- }
609
- }
610
- let infra_request = InfraStateRequest { infra : infra_id } ;
611
- let response = infra_request. fetch ( core. as_ref ( ) ) . await ?;
612
- Ok ( response)
595
+ #[ derive( Debug , Default , Deserialize ) ]
596
+ pub struct StatePayload {
597
+ infra : Option < i64 > ,
613
598
}
614
599
615
600
#[ get( "/cache_status" ) ]
@@ -618,14 +603,36 @@ async fn cache_status(
618
603
db_pool : Data < DbConnectionPool > ,
619
604
core : Data < CoreClient > ,
620
605
) -> Result < Json < HashMap < String , InfraStateResponse > > > {
621
- let payload = match payload {
622
- Either :: Left ( state) => state. into_inner ( ) ,
623
- Either :: Right ( _) => Default :: default ( ) ,
624
- } ;
625
- let infra_id = payload. infra ;
626
- Ok ( Json (
627
- call_core_infra_state ( infra_id, db_pool. into_inner ( ) , core) . await ?,
628
- ) )
606
+ if let Either :: Left ( Json ( StatePayload {
607
+ infra : Some ( infra_id) ,
608
+ } ) ) = payload
609
+ {
610
+ if !Infra :: exists ( db_pool. get ( ) . await ?. deref_mut ( ) , infra_id) . await ? {
611
+ return Err ( InfraApiError :: NotFound { infra_id } . into ( ) ) ;
612
+ }
613
+ let infra_state = fetch_infra_state ( infra_id, core. as_ref ( ) ) . await ?;
614
+ Ok ( Json ( HashMap :: from ( [ ( infra_id. to_string ( ) , infra_state) ] ) ) )
615
+ } else {
616
+ Ok ( Json ( fetch_all_infra_states ( core. as_ref ( ) ) . await ?) )
617
+ }
618
+ }
619
+
620
+ /// Builds a Core cache_status request, runs it
621
+ pub async fn fetch_infra_state ( infra_id : i64 , core : & CoreClient ) -> Result < InfraStateResponse > {
622
+ Ok ( InfraStateRequest {
623
+ infra : Some ( infra_id) ,
624
+ }
625
+ . fetch ( core)
626
+ . await ?
627
+ . get ( & infra_id. to_string ( ) )
628
+ . cloned ( )
629
+ . unwrap_or_default ( ) )
630
+ }
631
+
632
+ pub async fn fetch_all_infra_states (
633
+ core : & CoreClient ,
634
+ ) -> Result < HashMap < String , InfraStateResponse > > {
635
+ InfraStateRequest :: default ( ) . fetch ( core) . await
629
636
}
630
637
631
638
#[ cfg( test) ]
0 commit comments