Skip to content

Support tag filter #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Aug 7, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1f41e0d
support snapshot
zhiyuanliang-ms Dec 19, 2024
a331e98
add testcase
zhiyuanliang-ms Dec 20, 2024
1105531
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Dec 20, 2024
7d98b58
add testcase
zhiyuanliang-ms Dec 20, 2024
9bffa88
fix lint
zhiyuanliang-ms Dec 20, 2024
28c2d0e
update
zhiyuanliang-ms Dec 24, 2024
92d6531
Merge pull request #162 from Azure/merge-main-to-preview
zhiyuanliang-ms Feb 12, 2025
501cfe4
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Feb 12, 2025
2a09f46
Merge branch 'zhiyuanliang/select-snapshot' of https://github.com/Azu…
zhiyuanliang-ms Feb 12, 2025
fed19f8
Merge branch 'main' into zhiyuanliang/select-snapshot
zhiyuanliang-ms Feb 20, 2025
071215e
Merge branch 'main' into zhiyuanliang/select-snapshot
zhiyuanliang-ms Apr 2, 2025
160f30a
Merge branch 'main' into zhiyuanliang/select-snapshot
zhiyuanliang-ms Apr 23, 2025
53544af
wip
zhiyuanliang-ms Apr 23, 2025
64f7604
wip
zhiyuanliang-ms Apr 23, 2025
5fc57b0
support tag filter
zhiyuanliang-ms Apr 23, 2025
1f5d9d8
add test
zhiyuanliang-ms Apr 23, 2025
994c10e
update test
zhiyuanliang-ms Apr 23, 2025
5b89cb6
Merge branch 'zhiyuanliang/select-snapshot' of https://github.com/Azu…
zhiyuanliang-ms Apr 23, 2025
bda172e
Merge branch 'main' of https://github.com/Azure/AppConfiguration-Java…
zhiyuanliang-ms Apr 29, 2025
cad828a
update testcase
zhiyuanliang-ms Apr 29, 2025
00421f9
Merge branch 'zhiyuanliang/select-snapshot' of https://github.com/Azu…
zhiyuanliang-ms Apr 29, 2025
667f721
Merge branch 'main' of https://github.com/Azure/AppConfiguration-Java…
zhiyuanliang-ms May 13, 2025
11b5325
Merge branch 'zhiyuanliang/select-snapshot' of https://github.com/Azu…
zhiyuanliang-ms May 13, 2025
ca3c113
update
zhiyuanliang-ms May 19, 2025
855e909
add more testcases
zhiyuanliang-ms May 19, 2025
030d72d
update
zhiyuanliang-ms May 19, 2025
381d833
Merge branch 'main' of https://github.com/Azure/AppConfiguration-Java…
zhiyuanliang-ms May 19, 2025
c0d611c
Merge branch 'zhiyuanliang/select-snapshot' of https://github.com/Azu…
zhiyuanliang-ms May 19, 2025
b985509
Merge branch 'main' of https://github.com/Azure/AppConfiguration-Java…
zhiyuanliang-ms May 22, 2025
7a246d9
fix lint
zhiyuanliang-ms May 22, 2025
58ff6c3
update testcase
zhiyuanliang-ms May 22, 2025
1809619
Merge branch 'main' of https://github.com/Azure/AppConfiguration-Java…
zhiyuanliang-ms Aug 1, 2025
fe98b43
update
zhiyuanliang-ms Aug 1, 2025
b373d1e
add more testcases
zhiyuanliang-ms Aug 4, 2025
4bfc623
Merge branch 'main' of https://github.com/Azure/AppConfiguration-Java…
zhiyuanliang-ms Aug 4, 2025
505c542
correct null tag test
zhiyuanliang-ms Aug 5, 2025
1433789
Merge branch 'main' into zhiyuanliang/tag-filter
zhiyuanliang-ms Aug 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update
  • Loading branch information
zhiyuanliang-ms committed May 19, 2025
commit 030d72d382c831c66dea03aa8d6e93e2b15ccdc8
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"dev": "rollup --config --watch",
"lint": "eslint src/ test/",
"fix-lint": "eslint src/ test/ --fix",
"test": "mocha out/test/featureFlag.test.{js,cjs,mjs} --parallel"
"test": "mocha out/test/*.test.{js,cjs,mjs} --parallel"
},
"repository": {
"type": "git",
Expand Down
28 changes: 25 additions & 3 deletions src/AzureAppConfigurationImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ListConfigurationSettingsOptions,
featureFlagPrefix,
isFeatureFlag,
isSecretReference,
GetSnapshotOptions,
GetSnapshotResponse,
KnownSnapshotComposition
Expand Down Expand Up @@ -102,6 +103,9 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
#ffRefreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS;
#ffRefreshTimer: RefreshTimer;

// Key Vault references
#resolveSecretsInParallel: boolean = false;

/**
* Selectors of key-values obtained from @see AzureAppConfigurationOptions.selectors
*/
Expand Down Expand Up @@ -182,6 +186,10 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
}
}

if (options?.keyVaultOptions?.parallelSecretResolutionEnabled) {
this.#resolveSecretsInParallel = options.keyVaultOptions.parallelSecretResolutionEnabled;
}

this.#adapters.push(new AzureKeyVaultKeyValueAdapter(options?.keyVaultOptions));
this.#adapters.push(new JsonKeyValueAdapter());
}
Expand Down Expand Up @@ -526,7 +534,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
*/
async #loadSelectedAndWatchedKeyValues() {
const keyValues: [key: string, value: unknown][] = [];
const loadedSettings = await this.#loadConfigurationSettings();
const loadedSettings: ConfigurationSetting[] = await this.#loadConfigurationSettings();
if (this.#refreshEnabled && !this.#watchAll) {
await this.#updateWatchedKeyValuesEtag(loadedSettings);
}
Expand All @@ -536,11 +544,25 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
this.#aiConfigurationTracing.reset();
}

// adapt configuration settings to key-values
const secretResolutionPromises: Promise<void>[] = [];
for (const setting of loadedSettings) {
if (this.#resolveSecretsInParallel && isSecretReference(setting)) {
// secret references are resolved asynchronously to improve performance
const secretResolutionPromise = this.#processKeyValue(setting)
.then(([key, value]) => {
keyValues.push([key, value]);
});
secretResolutionPromises.push(secretResolutionPromise);
continue;
}
// adapt configuration settings to key-values
const [key, value] = await this.#processKeyValue(setting);
keyValues.push([key, value]);
}
if (secretResolutionPromises.length > 0) {
// wait for all secret resolution promises to be resolved
await Promise.all(secretResolutionPromises);
}

this.#clearLoadedKeyValues(); // clear existing key-values in case of configuration setting deletion
for (const [k, v] of keyValues) {
Expand Down Expand Up @@ -585,7 +607,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
*/
async #loadFeatureFlags() {
const loadFeatureFlag = true;
const featureFlagSettings = await this.#loadConfigurationSettings(loadFeatureFlag);
const featureFlagSettings: ConfigurationSetting[] = await this.#loadConfigurationSettings(loadFeatureFlag);

if (this.#requestTracingEnabled && this.#featureFlagTracing !== undefined) {
// Reset old feature flag tracing in order to track the information present in the current response from server.
Expand Down
8 changes: 8 additions & 0 deletions src/keyvault/KeyVaultOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,12 @@ export interface KeyVaultOptions {
* @returns The secret value.
*/
secretResolver?: (keyVaultReference: URL) => string | Promise<string>;

/**
* Specifies whether to resolve the secret value in parallel.
*
* @remarks
* If not specified, the default value is false.
*/
parallelSecretResolutionEnabled?: boolean;
}
12 changes: 12 additions & 0 deletions test/keyvault.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,16 @@ describe("key vault reference", function () {
expect(settings.get("TestKey")).eq("SecretValue");
expect(settings.get("TestKey2")).eq("SecretValue2");
});

it("should resolve key vault reference in parallel", async () => {
const settings = await load(createMockedConnectionString(), {
keyVaultOptions: {
credential: createMockedTokenCredential(),
parallelSecretResolutionEnabled: true
}
});
expect(settings).not.undefined;
expect(settings.get("TestKey")).eq("SecretValue");
expect(settings.get("TestKeyFixedVersion")).eq("OldSecretValue");
});
});
4 changes: 2 additions & 2 deletions test/load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe("load", function () {
const connectionString = createMockedConnectionString();
return expect(load(connectionString, {
selectors: [{
labelFilter: "\0"
labelFilter: "\0"
}]
})).eventually.rejectedWith("Key filter cannot be null or empty.");
});
Expand All @@ -136,7 +136,7 @@ describe("load", function () {
return expect(load(connectionString, {
selectors: [{
snapshotName: "Test",
labelFilter: "\0"
labelFilter: "\0"
}]
})).eventually.rejectedWith("Key or label filter should not be used for a snapshot.");
});
Expand Down