1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
3
4
- use crate :: discovery:: discovery_trait:: { DiscoveryFilter , DiscoveryKind , ResourceDiscovery } ;
4
+ use crate :: discovery:: {
5
+ command_discovery_cache:: {
6
+ get_adapted_resource, get_adapted_resources, get_adapters, get_extensions, get_resource, get_resources, resources_is_empty,
7
+ adapters_is_empty, extensions_is_empty, extend_adapted_resources, extend_adapters, extend_extensions, extend_resources
8
+ } ,
9
+ discovery_trait:: { DiscoveryFilter , DiscoveryKind , ResourceDiscovery }
10
+ } ;
5
11
use crate :: dscresources:: dscresource:: { Capability , DscResource , ImplementedAs } ;
6
12
use crate :: dscresources:: resource_manifest:: { import_manifest, validate_semver, Kind , ResourceManifest , SchemaKind } ;
7
13
use crate :: dscresources:: command_resource:: invoke_command;
@@ -36,13 +42,9 @@ pub enum ImportedManifest {
36
42
Extension ( DscExtension ) ,
37
43
}
38
44
45
+
39
46
#[ derive( Clone ) ]
40
47
pub struct CommandDiscovery {
41
- // use BTreeMap so that the results are sorted by the typename, the Vec is sorted by version
42
- adapters : BTreeMap < String , Vec < DscResource > > ,
43
- resources : BTreeMap < String , Vec < DscResource > > ,
44
- extensions : BTreeMap < String , DscExtension > ,
45
- adapted_resources : BTreeMap < String , Vec < DscResource > > ,
46
48
progress_format : ProgressFormat ,
47
49
}
48
50
@@ -72,17 +74,13 @@ impl CommandDiscovery {
72
74
#[ must_use]
73
75
pub fn new ( progress_format : ProgressFormat ) -> CommandDiscovery {
74
76
CommandDiscovery {
75
- adapters : BTreeMap :: new ( ) ,
76
- resources : BTreeMap :: new ( ) ,
77
- extensions : BTreeMap :: new ( ) ,
78
- adapted_resources : BTreeMap :: new ( ) ,
79
77
progress_format,
80
78
}
81
79
}
82
80
83
81
#[ must_use]
84
- pub fn get_extensions ( & self ) -> & BTreeMap < String , DscExtension > {
85
- & self . extensions
82
+ pub fn get_extensions ( & self ) -> BTreeMap < String , DscExtension > {
83
+ get_extensions ( )
86
84
}
87
85
88
86
fn get_resource_path_setting ( ) -> Result < ResourcePathSetting , DscError >
@@ -307,7 +305,7 @@ impl ResourceDiscovery for CommandDiscovery {
307
305
match kind {
308
306
DiscoveryKind :: Resource => {
309
307
// Now we need to call discover extensions and add those resource to the list of resources
310
- for extension in self . extensions . values ( ) {
308
+ for extension in get_extensions ( ) . values ( ) {
311
309
if extension. capabilities . contains ( & ExtensionCapability :: Discover ) {
312
310
debug ! ( "{}" , t!( "discovery.commandDiscovery.callingExtension" , extension = extension. type_name) ) ;
313
311
let discovered_resources = extension. discover ( ) ?;
@@ -320,26 +318,27 @@ impl ResourceDiscovery for CommandDiscovery {
320
318
}
321
319
}
322
320
}
323
- self . adapters = adapters ;
324
- self . resources = resources ;
321
+ extend_adapters ( adapters) ;
322
+ extend_resources ( resources) ;
325
323
} ,
326
324
DiscoveryKind :: Extension => {
327
- self . extensions = extensions ;
325
+ extend_extensions ( extensions) ;
328
326
}
329
327
}
330
328
331
329
Ok ( ( ) )
332
330
}
333
331
334
332
fn discover_adapted_resources ( & mut self , name_filter : & str , adapter_filter : & str ) -> Result < ( ) , DscError > {
335
- if self . resources . is_empty ( ) && self . adapters . is_empty ( ) {
333
+ if resources_is_empty ( ) && adapters_is_empty ( ) {
336
334
self . discover ( & DiscoveryKind :: Resource , "*" ) ?;
337
335
}
338
336
339
- if self . adapters . is_empty ( ) {
337
+ if adapters_is_empty ( ) {
340
338
return Ok ( ( ) ) ;
341
339
}
342
340
341
+ let adapters = get_adapters ( ) ;
343
342
let regex_str = convert_wildcard_to_regex ( adapter_filter) ;
344
343
debug ! ( "Using regex {regex_str} as filter for adapter name" ) ;
345
344
let mut regex_builder = RegexBuilder :: new ( & regex_str) ;
@@ -356,13 +355,13 @@ impl ResourceDiscovery for CommandDiscovery {
356
355
return Err ( DscError :: Operation ( "Could not build Regex filter for resource name" . to_string ( ) ) ) ;
357
356
} ;
358
357
359
- let mut progress = ProgressBar :: new ( self . adapters . len ( ) as u64 , self . progress_format ) ?;
358
+ let mut progress = ProgressBar :: new ( adapters. len ( ) as u64 , self . progress_format ) ?;
360
359
progress. write_activity ( "Searching for adapted resources" ) ;
361
360
362
361
let mut adapted_resources = BTreeMap :: < String , Vec < DscResource > > :: new ( ) ;
363
362
364
363
let mut found_adapter: bool = false ;
365
- for ( adapter_name, adapters) in & self . adapters {
364
+ for ( adapter_name, adapters) in & adapters {
366
365
for adapter in adapters {
367
366
progress. write_increment ( 1 ) ;
368
367
@@ -431,7 +430,7 @@ impl ResourceDiscovery for CommandDiscovery {
431
430
return Err ( DscError :: AdapterNotFound ( adapter_filter. to_string ( ) ) ) ;
432
431
}
433
432
434
- self . adapted_resources = adapted_resources ;
433
+ extend_adapted_resources ( adapted_resources) ;
435
434
436
435
Ok ( ( ) )
437
436
}
@@ -441,26 +440,27 @@ impl ResourceDiscovery for CommandDiscovery {
441
440
if * kind == DiscoveryKind :: Resource {
442
441
if adapter_name_filter. is_empty ( ) {
443
442
self . discover ( kind, type_name_filter) ?;
444
- for ( resource_name, resources_vec) in & self . resources {
443
+ for ( resource_name, resources_vec) in & get_resources ( ) {
445
444
resources. insert ( resource_name. clone ( ) , resources_vec. iter ( ) . map ( |r| ImportedManifest :: Resource ( r. clone ( ) ) ) . collect ( ) ) ;
446
445
}
447
- for ( adapter_name, adapter_vec) in & self . adapters {
446
+ for ( adapter_name, adapter_vec) in & get_adapters ( ) {
448
447
resources. insert ( adapter_name. clone ( ) , adapter_vec. iter ( ) . map ( |r| ImportedManifest :: Resource ( r. clone ( ) ) ) . collect ( ) ) ;
449
448
}
450
449
} else {
451
450
self . discover ( kind, "*" ) ?;
452
451
self . discover_adapted_resources ( type_name_filter, adapter_name_filter) ?;
453
452
454
453
// add/update found adapted resources to the lookup_table
455
- add_resources_to_lookup_table ( & self . adapted_resources ) ;
454
+ let adapted_resources = get_adapted_resources ( ) ;
455
+ add_resources_to_lookup_table ( & adapted_resources) ;
456
456
457
- for ( adapted_name, adapted_vec) in & self . adapted_resources {
457
+ for ( adapted_name, adapted_vec) in & adapted_resources {
458
458
resources. insert ( adapted_name. clone ( ) , adapted_vec. iter ( ) . map ( |r| ImportedManifest :: Resource ( r. clone ( ) ) ) . collect ( ) ) ;
459
459
}
460
460
}
461
461
} else {
462
462
self . discover ( kind, type_name_filter) ?;
463
- for ( extension_name, extension) in & self . extensions {
463
+ for ( extension_name, extension) in & get_extensions ( ) {
464
464
resources. insert ( extension_name. clone ( ) , vec ! [ ImportedManifest :: Extension ( extension. clone( ) ) ] ) ;
465
465
}
466
466
}
@@ -470,16 +470,18 @@ impl ResourceDiscovery for CommandDiscovery {
470
470
471
471
fn find_resources ( & mut self , required_resource_types : & [ DiscoveryFilter ] ) -> Result < BTreeMap < String , Vec < DscResource > > , DscError > {
472
472
debug ! ( "{}" , t!( "discovery.commandDiscovery.searchingForResources" , resources = required_resource_types : { : ?} ) ) ;
473
- self . discover ( & DiscoveryKind :: Resource , "*" ) ?;
473
+ if resources_is_empty ( ) {
474
+ self . discover ( & DiscoveryKind :: Resource , "*" ) ?;
475
+ }
474
476
let mut found_resources = BTreeMap :: < String , Vec < DscResource > > :: new ( ) ;
475
477
let mut required_resources = HashMap :: < DiscoveryFilter , bool > :: new ( ) ;
476
478
for filter in required_resource_types {
477
479
required_resources. insert ( filter. clone ( ) , false ) ;
478
480
}
479
481
480
482
for filter in required_resource_types {
481
- if let Some ( resources) = self . resources . get ( filter. resource_type ( ) ) {
482
- filter_resources ( & mut found_resources, & mut required_resources, resources, filter) ;
483
+ if let Some ( resources) = get_resource ( filter. resource_type ( ) ) {
484
+ filter_resources ( & mut found_resources, & mut required_resources, & resources, filter) ;
483
485
}
484
486
if required_resources. values ( ) . all ( |& v| v) {
485
487
break ;
@@ -492,12 +494,12 @@ impl ResourceDiscovery for CommandDiscovery {
492
494
}
493
495
494
496
// now go through the adapters, this is for implicit adapters so version can't be specified so use latest version
495
- for adapter_name in self . adapters . clone ( ) . keys ( ) {
497
+ for adapter_name in get_adapters ( ) . keys ( ) {
496
498
self . discover_adapted_resources ( "*" , adapter_name) ?;
497
- add_resources_to_lookup_table ( & self . adapted_resources ) ;
499
+ add_resources_to_lookup_table ( & get_adapted_resources ( ) ) ;
498
500
for filter in required_resource_types {
499
- if let Some ( adapted_resources) = self . adapted_resources . get ( filter. resource_type ( ) ) {
500
- filter_resources ( & mut found_resources, & mut required_resources, adapted_resources, filter) ;
501
+ if let Some ( adapted_resources) = get_adapted_resource ( filter. resource_type ( ) ) {
502
+ filter_resources ( & mut found_resources, & mut required_resources, & adapted_resources, filter) ;
501
503
}
502
504
if required_resources. values ( ) . all ( |& v| v) {
503
505
break ;
@@ -512,10 +514,10 @@ impl ResourceDiscovery for CommandDiscovery {
512
514
}
513
515
514
516
fn get_extensions ( & mut self ) -> Result < BTreeMap < String , DscExtension > , DscError > {
515
- if self . extensions . is_empty ( ) {
517
+ if extensions_is_empty ( ) {
516
518
self . discover ( & DiscoveryKind :: Extension , "*" ) ?;
517
519
}
518
- Ok ( self . extensions . clone ( ) )
520
+ Ok ( get_extensions ( ) )
519
521
}
520
522
}
521
523
0 commit comments