Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@azure/app-configuration-importer-file-source",
"author": "Microsoft Corporation",
"description": "A client library for importing/exporting key-values between configuration file sources and Azure App Configuration service",
"version": "3.0.0-preview",
"version": "3.0.0-preview.2",
"sdk-type": "client",
"keywords": [
"node",
Expand Down Expand Up @@ -33,7 +33,7 @@
},
"dependencies": {
"@azure/app-configuration": "^1.9.0",
"@azure/app-configuration-importer": "3.0.0-preview"
"@azure/app-configuration-importer": "3.0.0-preview.2"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.22.2",
Expand Down
2 changes: 1 addition & 1 deletion libraries/azure-app-configuration-importer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@azure/app-configuration-importer",
"author": "Microsoft Corporation",
"description": "A client library for importing/exporting key-values between configuration sources and Azure App Configuration service",
"version": "3.0.0-preview",
"version": "3.0.0-preview.2",
"sdk-type": "client",
"keywords": [
"node",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import { ImportMode, ChangeType } from "./enums";
import { OperationTimeoutError, ArgumentError } from "./errors";
import { AdaptiveTaskManager } from "./internal/adaptiveTaskManager";
import { ImportProgress, KeyLabelLookup, ConfigurationSettingChange } from "./models";
import { ImportProgress, ConfigurationSettingChange } from "./models";
import { isConfigSettingEqual } from "./internal/utils";
import { v4 as uuidv4 } from "uuid";
import { Constants } from "./internal/constants";
Expand Down Expand Up @@ -71,11 +71,11 @@

const settingsToWrite: SetConfigurationSettingParam<string | FeatureFlagValue | SecretReferenceValue>[] = configurationChanges
.filter(c => (c.changeType === ChangeType.Create || c.changeType === ChangeType.Update || c.changeType === ChangeType.None) && c.newValue)
.map(c => c.newValue!);

Check warning on line 74 in libraries/azure-app-configuration-importer/src/appConfigurationImporter.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion

const settingsToDelete: ConfigurationSetting[] = configurationChanges
.filter(c => c.changeType === ChangeType.Delete && c.currentValue)
.map(c => c.currentValue!);

Check warning on line 78 in libraries/azure-app-configuration-importer/src/appConfigurationImporter.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion

return await this.applyUpdatesToServer(settingsToWrite, settingsToDelete, options.timeout, customHeadersOption, options.progressCallback);
}
Expand Down Expand Up @@ -121,7 +121,22 @@
};
}

const configSettingsResult = await configSettingsSource.GetConfigurationSettings();
// Fetch source settings and target store settings in parallel.
// For ConfigurationChangesSource the target listing is skipped (changes are pre-calculated and
// FilterOptions are not supported on that source type).
const isChangesSource = configSettingsSource instanceof ConfigurationChangesSource;
const sourcePromise = configSettingsSource.GetConfigurationSettings();
const targetPromise: Promise<ConfigurationSetting[]> = isChangesSource
? Promise.resolve([])
: (async () => {
const items: ConfigurationSetting[] = [];
for await (const existing of this.configurationClient.listConfigurationSettings({...configSettingsSource.FilterOptions, ...customHeadersOption})) {
items.push(existing);
}
return items;
})();

const configSettingsResult = await sourcePromise;

// If the source returns ConfigurationChanges (e.g., ConfigurationChangesSource),
// return them directly without further processing since changes are already calculated
Expand All @@ -131,21 +146,22 @@

const configSettings = configSettingsResult as Array<SetConfigurationSettingParam<string | FeatureFlagValue | SecretReferenceValue>>;
const configurationChanges: Array<ConfigurationSettingChange> = [];
const configurationSettingToAdd: SetConfigurationSettingParam<string | FeatureFlagValue | SecretReferenceValue>[] = [];
const srcKeyLabelLookUp: KeyLabelLookup = {};

configSettings.forEach((config: SetConfigurationSettingParam<string | FeatureFlagValue | SecretReferenceValue>) => {
if (!srcKeyLabelLookUp[config.key]) {
srcKeyLabelLookUp[config.key] = {};
}
srcKeyLabelLookUp[config.key][config.label || ""] = true;
});

configurationSettingToAdd.push(...configSettings);
// Build O(1) lookup structures keyed by "key\0label" composite.
const srcMap = new Map<string, SetConfigurationSettingParam<string | FeatureFlagValue | SecretReferenceValue>>();
const toAddKeys = new Set<string>();
for (const config of configSettings) {
const composite = `${config.key}\u0000${config.label ?? ""}`;
srcMap.set(composite, config);
toAddKeys.add(composite);
}

const targetSettings = await targetPromise;

for (const existing of targetSettings) {
const composite = `${existing.key}\u0000${existing.label ?? ""}`;
const isKeyLabelPresent: boolean = srcMap.has(composite);

for await (const existing of this.configurationClient.listConfigurationSettings({...configSettingsSource.FilterOptions, ...customHeadersOption})) {
const isKeyLabelPresent: boolean = srcKeyLabelLookUp[existing.key] && srcKeyLabelLookUp[existing.key][existing.label || ""];

if (strict && !isKeyLabelPresent) {
configurationChanges.push({
changeType: ChangeType.Delete,
Expand All @@ -154,11 +170,11 @@
});
}

const incoming = configSettings.find(configSetting => configSetting.key == existing.key && configSetting.label === existing.label);
const incoming = srcMap.get(composite);

if (incoming) {
// Remove from add list since it already exists
configurationSettingToAdd.splice(configurationSettingToAdd.indexOf(incoming), 1);
toAddKeys.delete(composite);

if (!isConfigSettingEqual(incoming, existing)) {
configurationChanges.push({
Expand All @@ -177,11 +193,11 @@
}
}

for (const setting of configurationSettingToAdd) {
for (const composite of toAddKeys) {
configurationChanges.push({
changeType: ChangeType.Create,
currentValue: null,
newValue: setting
newValue: srcMap.get(composite)!

Check warning on line 200 in libraries/azure-app-configuration-importer/src/appConfigurationImporter.ts

View workflow job for this annotation

GitHub Actions / build

Forbidden non-null assertion
});
}

Expand All @@ -206,7 +222,7 @@
await this.executeTasksWithTimeout(importTaskManager, timeout, progressCallback);
}

private newAdaptiveTaskManager<T>(task: (setting: T) => Promise<any>, configurationSettings: Array<T>) {

Check warning on line 225 in libraries/azure-app-configuration-importer/src/appConfigurationImporter.ts

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
let index = 0;
return new AdaptiveTaskManager(() => {
if (index == configurationSettings.length) {
Expand Down
Loading