11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT license.
33
4- import { AppConfigurationClient , ConfigurationSetting , ConfigurationSettingId , GetConfigurationSettingOptions , GetConfigurationSettingResponse , ListConfigurationSettingsOptions , featureFlagPrefix , isFeatureFlag } from "@azure/app-configuration" ;
4+ import { AppConfigurationClient , ConfigurationSetting , ConfigurationSettingId , GetConfigurationSettingOptions , GetConfigurationSettingResponse , ListConfigurationSettingsOptions , featureFlagPrefix , isFeatureFlag , isSecretReference } from "@azure/app-configuration" ;
55import { isRestError } from "@azure/core-rest-pipeline" ;
66import { AzureAppConfiguration , ConfigurationObjectConstructionOptions } from "./AzureAppConfiguration.js" ;
77import { AzureAppConfigurationOptions } from "./AzureAppConfigurationOptions.js" ;
@@ -83,6 +83,9 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
8383 #ffRefreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS ;
8484 #ffRefreshTimer: RefreshTimer ;
8585
86+ // Key Vault references
87+ #resolveSecretInParallel: boolean = false ;
88+
8689 /**
8790 * Selectors of key-values obtained from @see AzureAppConfigurationOptions.selectors
8891 */
@@ -163,6 +166,10 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
163166 }
164167 }
165168
169+ if ( options ?. keyVaultOptions ?. parallelSecretResolutionEnabled ) {
170+ this . #resolveSecretInParallel = options . keyVaultOptions . parallelSecretResolutionEnabled ;
171+ }
172+
166173 this . #adapters. push ( new AzureKeyVaultKeyValueAdapter ( options ?. keyVaultOptions ) ) ;
167174 this . #adapters. push ( new JsonKeyValueAdapter ( ) ) ;
168175 }
@@ -484,7 +491,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
484491 */
485492 async #loadSelectedAndWatchedKeyValues( ) {
486493 const keyValues : [ key : string , value : unknown ] [ ] = [ ] ;
487- const loadedSettings = await this . #loadConfigurationSettings( ) ;
494+ const loadedSettings : ConfigurationSetting [ ] = await this . #loadConfigurationSettings( ) ;
488495 if ( this . #refreshEnabled && ! this . #watchAll) {
489496 await this . #updateWatchedKeyValuesEtag( loadedSettings ) ;
490497 }
@@ -494,11 +501,25 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
494501 this . #aiConfigurationTracing. reset ( ) ;
495502 }
496503
497- // adapt configuration settings to key-values
504+ const secretResolutionPromises : Promise < void > [ ] = [ ] ;
498505 for ( const setting of loadedSettings ) {
506+ if ( this . #resolveSecretInParallel && isSecretReference ( setting ) ) {
507+ // secret references are resolved asynchronously to improve performance
508+ const secretResolutionPromise = this . #processKeyValue( setting )
509+ . then ( ( [ key , value ] ) => {
510+ keyValues . push ( [ key , value ] ) ;
511+ } ) ;
512+ secretResolutionPromises . push ( secretResolutionPromise ) ;
513+ continue ;
514+ }
515+ // adapt configuration settings to key-values
499516 const [ key , value ] = await this . #processKeyValue( setting ) ;
500517 keyValues . push ( [ key , value ] ) ;
501518 }
519+ if ( secretResolutionPromises . length > 0 ) {
520+ // wait for all secret resolution promises to be resolved
521+ await Promise . all ( secretResolutionPromises ) ;
522+ }
502523
503524 this . #clearLoadedKeyValues( ) ; // clear existing key-values in case of configuration setting deletion
504525 for ( const [ k , v ] of keyValues ) {
@@ -543,7 +564,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
543564 */
544565 async #loadFeatureFlags( ) {
545566 const loadFeatureFlag = true ;
546- const featureFlagSettings = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
567+ const featureFlagSettings : ConfigurationSetting [ ] = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
547568
548569 if ( this . #requestTracingEnabled && this . #featureFlagTracing !== undefined ) {
549570 // Reset old feature flag tracing in order to track the information present in the current response from server.
0 commit comments