Skip to content

Commit 501cfe4

Browse files
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-JavaScriptProvider into zhiyuanliang/select-snapshot
2 parents 1f41e0d + 92d6531 commit 501cfe4

File tree

12 files changed

+76
-42
lines changed

12 files changed

+76
-42
lines changed

.eslintrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
"@typescript-eslint"
3434
],
3535
"rules": {
36+
"keyword-spacing": [
37+
"error",
38+
{
39+
"before": true,
40+
"after": true
41+
}
42+
],
3643
"quotes": [
3744
"error",
3845
"double",

package-lock.json

Lines changed: 4 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@azure/app-configuration-provider",
3-
"version": "2.0.0-preview.1",
3+
"version": "2.0.0",
44
"description": "The JavaScript configuration provider for Azure App Configuration",
55
"main": "dist/index.js",
66
"module": "./dist-esm/index.js",

rollup.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import dts from "rollup-plugin-dts";
44

55
export default [
66
{
7-
external: ["@azure/app-configuration", "@azure/keyvault-secrets", "@azure/core-rest-pipeline", "crypto", "dns/promises"],
7+
external: ["@azure/app-configuration", "@azure/keyvault-secrets", "@azure/core-rest-pipeline", "crypto", "dns/promises", "@microsoft/feature-management"],
88
input: "src/index.ts",
99
output: [
1010
{

src/AzureAppConfigurationImpl.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
CONDITIONS_KEY_NAME,
4646
CLIENT_FILTERS_KEY_NAME
4747
} from "./featureManagement/constants.js";
48+
import { FM_PACKAGE_NAME } from "./requestTracing/constants.js";
4849
import { AzureKeyVaultKeyValueAdapter } from "./keyvault/AzureKeyVaultKeyValueAdapter.js";
4950
import { RefreshTimer } from "./refresh/RefreshTimer.js";
5051
import {
@@ -84,6 +85,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
8485
#isInitialLoadCompleted: boolean = false;
8586
#isFailoverRequest: boolean = false;
8687
#featureFlagTracing: FeatureFlagTracingOptions | undefined;
88+
#fmVersion: string | undefined;
8789

8890
// Refresh
8991
#refreshInProgress: boolean = false;
@@ -203,7 +205,8 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
203205
initialLoadCompleted: this.#isInitialLoadCompleted,
204206
replicaCount: this.#clientManager.getReplicaCount(),
205207
isFailoverRequest: this.#isFailoverRequest,
206-
featureFlagTracing: this.#featureFlagTracing
208+
featureFlagTracing: this.#featureFlagTracing,
209+
fmVersion: this.#fmVersion
207210
};
208211
}
209212

@@ -245,6 +248,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
245248
* Loads the configuration store for the first time.
246249
*/
247250
async load() {
251+
await this.#inspectFmPackage();
248252
await this.#loadSelectedAndWatchedKeyValues();
249253
if (this.#featureFlagEnabled) {
250254
await this.#loadFeatureFlags();
@@ -335,6 +339,21 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
335339
return new Disposable(remove);
336340
}
337341

342+
/**
343+
* Inspects the feature management package version.
344+
*/
345+
async #inspectFmPackage() {
346+
if (this.#requestTracingEnabled && !this.#fmVersion) {
347+
try {
348+
// get feature management package version
349+
const fmPackage = await import(FM_PACKAGE_NAME);
350+
this.#fmVersion = fmPackage?.VERSION;
351+
} catch (error) {
352+
// ignore the error
353+
}
354+
}
355+
}
356+
338357
async #refreshTasks(): Promise<void> {
339358
const refreshTasks: Promise<boolean>[] = [];
340359
if (this.#refreshEnabled) {
@@ -972,14 +991,13 @@ function getValidKeyValueSelectors(selectors?: SettingSelector[]): SettingSelect
972991

973992
function getValidFeatureFlagSelectors(selectors?: SettingSelector[]): SettingSelector[] {
974993
if (selectors === undefined || selectors.length === 0) {
975-
// selectors must be explicitly provided.
976-
throw new Error("Feature flag selectors must be provided.");
977-
} else {
978-
selectors.forEach(selector => {
979-
selector.keyFilter = `${featureFlagPrefix}${selector.keyFilter}`;
980-
});
981-
return getValidSettingSelectors(selectors);
994+
// Default selector: key: *, label: \0
995+
return [{ keyFilter: `${featureFlagPrefix}${KeyFilter.Any}`, labelFilter: LabelFilter.Null }];
982996
}
997+
selectors.forEach(selector => {
998+
selector.keyFilter = `${featureFlagPrefix}${selector.keyFilter}`;
999+
});
1000+
return getValidSettingSelectors(selectors);
9831001
}
9841002

9851003
function isFailoverableError(error: any): boolean {

src/ConfigurationClientManager.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,13 @@ export class ConfigurationClientManager {
8585
this.#isFailoverable = false;
8686
return;
8787
}
88+
if (this.#dns) {
89+
return;
90+
}
8891

8992
try {
9093
this.#dns = await import("dns/promises");
91-
}catch (error) {
94+
} catch (error) {
9295
this.#isFailoverable = false;
9396
console.warn("Failed to load the dns module:", error.message);
9497
return;
@@ -140,13 +143,16 @@ export class ConfigurationClientManager {
140143

141144
async #discoverFallbackClients(host: string) {
142145
let result;
146+
let timeout;
143147
try {
144148
result = await Promise.race([
145-
new Promise((_, reject) => setTimeout(() => reject(new Error("SRV record query timed out.")), SRV_QUERY_TIMEOUT)),
149+
new Promise((_, reject) => timeout = setTimeout(() => reject(new Error("SRV record query timed out.")), SRV_QUERY_TIMEOUT)),
146150
this.#querySrvTargetHost(host)
147151
]);
148152
} catch (error) {
149153
throw new Error(`Failed to build fallback clients, ${error.message}`);
154+
} finally {
155+
clearTimeout(timeout);
150156
}
151157

152158
const srvTargetHosts = shuffleList(result) as string[];

src/featureManagement/FeatureFlagOptions.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ import { SettingSelector } from "../types.js";
1010
export interface FeatureFlagOptions {
1111
/**
1212
* Specifies whether feature flags will be loaded from Azure App Configuration.
13-
1413
*/
1514
enabled: boolean;
1615

1716
/**
18-
* Specifies the selectors used to filter feature flags.
17+
* Specifies what feature flags to include in the configuration provider.
1918
*
2019
* @remarks
2120
* keyFilter of selector will be prefixed with "appconfig.featureflag/" when request is sent.
22-
* If no selectors are specified then no feature flags will be retrieved.
21+
* If no selectors are specified then all feature flags with no label will be included.
2322
*/
2423
selectors?: SettingSelector[];
2524

src/requestTracing/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ export const FAILOVER_REQUEST_TAG = "Failover";
5555
export const FEATURES_KEY = "Features";
5656
export const LOAD_BALANCE_CONFIGURED_TAG = "LB";
5757

58+
// Feature management package
59+
export const FM_PACKAGE_NAME = "@microsoft/feature-management";
60+
export const FM_VERSION_KEY = "FMJsVer";
61+
5862
// Feature flag usage tracing
5963
export const FEATURE_FILTER_TYPE_KEY = "Filter";
6064
export const CUSTOM_FILTER_KEY = "CSTM";

src/requestTracing/utils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import {
2828
REPLICA_COUNT_KEY,
2929
FAILOVER_REQUEST_TAG,
3030
FEATURES_KEY,
31-
LOAD_BALANCE_CONFIGURED_TAG
31+
LOAD_BALANCE_CONFIGURED_TAG,
32+
FM_VERSION_KEY
3233
} from "./constants";
3334

3435
export interface RequestTracingOptions {
@@ -38,6 +39,7 @@ export interface RequestTracingOptions {
3839
replicaCount: number;
3940
isFailoverRequest: boolean;
4041
featureFlagTracing: FeatureFlagTracingOptions | undefined;
42+
fmVersion: string | undefined;
4143
}
4244

4345
// Utils
@@ -135,6 +137,9 @@ function createCorrelationContextHeader(requestTracingOptions: RequestTracingOpt
135137
if (requestTracingOptions.replicaCount > 0) {
136138
keyValues.set(REPLICA_COUNT_KEY, requestTracingOptions.replicaCount.toString());
137139
}
140+
if (requestTracingOptions.fmVersion) {
141+
keyValues.set(FM_VERSION_KEY, requestTracingOptions.fmVersion);
142+
}
138143

139144
// Compact tags: Features=LB+...
140145
if (appConfigOptions?.loadBalancingEnabled) {

src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4-
export const VERSION = "2.0.0-preview.1";
4+
export const VERSION = "2.0.0";

0 commit comments

Comments
 (0)