Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a168104
WIP change constants to microsoft version, edit properties in fmkvada…
amerjusupovic Apr 5, 2024
92e5014
index feature flags within new microsoft section feature_flags
amerjusupovic Apr 8, 2024
d701f5b
fix all tests, use reset state
amerjusupovic Apr 8, 2024
29510c3
add warning log for old feature management libraries with new provide…
amerjusupovic Apr 11, 2024
7104361
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-D…
amerjusupovic May 8, 2024
7313d1a
WIP adding deserialization changes, updating for variants/telemetry
amerjusupovic May 8, 2024
51b4524
WIP adding exceptions for incorrect types within arrays, allocation p…
amerjusupovic May 8, 2024
4613c73
WIP allocations mostly done
amerjusupovic May 8, 2024
1452121
update remaining properties, fix tests
amerjusupovic May 16, 2024
3978016
improve metadata error message
amerjusupovic May 16, 2024
f07fb76
update tests, add variant and telemetry testing
amerjusupovic May 29, 2024
900a8e6
remove alwayson
amerjusupovic May 30, 2024
3346b64
fix warning version check
amerjusupovic May 30, 2024
c6465d2
Add tests for invalid cases
amerjusupovic May 30, 2024
1db6823
test boolean allows string
amerjusupovic May 31, 2024
7502ec6
fix tests
amerjusupovic May 31, 2024
b8a2b15
remove unused using
amerjusupovic May 31, 2024
95f1cce
add tests from original main PR for json parsing
amerjusupovic May 31, 2024
4826959
revisions
amerjusupovic Jun 3, 2024
a345921
run dotnet format on tests file
amerjusupovic Jun 10, 2024
63dc59c
Update src/Microsoft.Extensions.Configuration.AzureAppConfiguration/C…
amerjusupovic Jun 11, 2024
aaf5764
some PR comment revisions
amerjusupovic Jun 11, 2024
3e67315
make from and to nullable in percentile to check if any values were set
amerjusupovic Jun 12, 2024
19d144b
Update src/Microsoft.Extensions.Configuration.AzureAppConfiguration/C…
amerjusupovic Jun 18, 2024
1fe22a5
Update src/Microsoft.Extensions.Configuration.AzureAppConfiguration/C…
amerjusupovic Jun 18, 2024
798a63d
PR comment revisions
amerjusupovic Jun 18, 2024
1ac4033
combine if statements
amerjusupovic Jun 18, 2024
461e993
change feature flag index state method
amerjusupovic Jun 19, 2024
e2bc751
use on configuration refresh and updated as adapter events
amerjusupovic Jun 19, 2024
0fabebb
change method names
amerjusupovic Jun 20, 2024
cd19b2d
removed unused methods
amerjusupovic Jun 20, 2024
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 @@ -388,7 +388,7 @@ await CallWithRequestTracing(
// Invalidate the cached Key Vault secret (if any) for this ConfigurationSetting
foreach (IKeyValueAdapter adapter in _options.Adapters)
{
adapter.InvalidateCache(change.Current);
adapter.OnChangeDetected(change.Current);
}
}
}
Expand All @@ -399,7 +399,7 @@ await CallWithRequestTracing(
// Invalidate all the cached KeyVault secrets
foreach (IKeyValueAdapter adapter in _options.Adapters)
{
adapter.InvalidateCache();
adapter.OnChangeDetected();
}

// Update the next refresh time for all refresh registered settings and feature flags
Expand Down Expand Up @@ -734,7 +734,7 @@ await ExecuteWithFailOverPolicyAsync(
// Invalidate all the cached KeyVault secrets
foreach (IKeyValueAdapter adapter in _options.Adapters)
{
adapter.InvalidateCache();
adapter.OnChangeDetected();
}

Dictionary<string, ConfigurationSetting> mappedData = await MapConfigurationSettings(data).ConfigureAwait(false);
Expand Down Expand Up @@ -913,6 +913,11 @@ private void SetData(IDictionary<string, string> data)
// Set the application data for the configuration provider
Data = data;

foreach (IKeyValueAdapter adapter in _options.Adapters)
{
adapter.OnConfigUpdated();
}

// Notify that the configuration has been updated
OnReload();
}
Expand Down Expand Up @@ -1206,11 +1211,21 @@ private void EnsureFeatureManagementVersionInspected()
{
if (!_isFeatureManagementVersionInspected)
{
const string FeatureManagementMinimumVersion = "3.2.0";

_isFeatureManagementVersionInspected = true;

if (_requestTracingEnabled && _requestTracingOptions != null)
{
_requestTracingOptions.FeatureManagementVersion = TracingUtils.GetAssemblyVersion(RequestTracingConstants.FeatureManagementAssemblyName);
string featureManagementVersion = TracingUtils.GetAssemblyVersion(RequestTracingConstants.FeatureManagementAssemblyName);

// If the version is less than 3.2.0, log the schema version warning
if (featureManagementVersion != null && Version.Parse(featureManagementVersion) < Version.Parse(FeatureManagementMinimumVersion))
{
_logger.LogWarning(LogHelper.BuildFeatureManagementMicrosoftSchemaVersionWarningMessage());
}

_requestTracingOptions.FeatureManagementVersion = featureManagementVersion;

_requestTracingOptions.FeatureManagementAspNetCoreVersion = TracingUtils.GetAssemblyVersion(RequestTracingConstants.FeatureManagementAspNetCoreAssemblyName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public bool CanProcess(ConfigurationSetting setting)
return string.Equals(contentType, KeyVaultConstants.ContentType);
}

public void InvalidateCache(ConfigurationSetting setting = null)
public void OnChangeDetected(ConfigurationSetting setting = null)
{
if (setting == null)
{
Expand All @@ -98,6 +98,11 @@ public void InvalidateCache(ConfigurationSetting setting = null)
}
}

public void OnConfigUpdated()
{
return;
}

public bool NeedsRefresh()
{
return _secretProvider.ShouldRefreshKeyVaultSecrets();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ internal class ErrorMessages
{
public const string RefreshIntervalTooShort = "The refresh interval cannot be less than {0} milliseconds.";
public const string SecretRefreshIntervalTooShort = "The secret refresh interval cannot be less than {0} milliseconds.";
public const string FeatureFlagInvalidJsonProperty = "Invalid property '{0}' for feature flag. Key: '{1}'. Found type: '{2}'. Expected type: '{3}'.";
public const string FeatureFlagInvalidFormat = "Invalid json format for feature flag. Key: '{0}'.";
public const string InvalidKeyVaultReference = "Invalid Key Vault reference.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ internal class LoggingConstants
public const string RefreshSkippedNoClientAvailable = "Refresh skipped because no endpoint is accessible.";
public const string RefreshFailedToGetSettingsFromEndpoint = "Failed to get configuration settings from endpoint";
public const string FailingOverToEndpoint = "Failing over to endpoint";
public const string FeatureManagementMicrosoftSchemaVersionWarning = "Your application may be using an older version of " +
"Microsoft.FeatureManagement library that isn't compatible with Microsoft.Extensions.Configuration.AzureAppConfiguration. Please update " +
"the Microsoft.FeatureManagement package to version 3.2.0 or later.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
// Licensed under the MIT license.
//
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement
{
internal class ClientFilter
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("parameters")]
public JsonElement Parameters { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,21 @@
// Licensed under the MIT license.
//
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement
{
internal class FeatureAllocation
{
[JsonPropertyName("default_when_disabled")]
public string DefaultWhenDisabled { get; set; }

[JsonPropertyName("default_when_enabled")]
public string DefaultWhenEnabled { get; set; }

[JsonPropertyName("user")]
public IEnumerable<FeatureUserAllocation> User { get; set; }

[JsonPropertyName("group")]
public IEnumerable<FeatureGroupAllocation> Group { get; set; }

[JsonPropertyName("percentile")]
public IEnumerable<FeaturePercentileAllocation> Percentile { get; set; }

[JsonPropertyName("seed")]
public string Seed { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
// Licensed under the MIT license.
//
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement
{
internal class FeatureConditions
{
[JsonPropertyName("client_filters")]
public List<ClientFilter> ClientFilters { get; set; } = new List<ClientFilter>();

[JsonPropertyName("requirement_type")]
public string RequirementType { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,21 @@
// Licensed under the MIT license.
//
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement
{
internal class FeatureFlag
{
[JsonPropertyName("id")]
public string Id { get; set; }

[JsonPropertyName("enabled")]
public bool Enabled { get; set; }

[JsonPropertyName("conditions")]
public FeatureConditions Conditions { get; set; }

[JsonPropertyName("variants")]
public IEnumerable<FeatureVariant> Variants { get; set; }

[JsonPropertyName("allocation")]
public FeatureAllocation Allocation { get; set; }

[JsonPropertyName("telemetry")]
public FeatureTelemetry Telemetry { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
// Licensed under the MIT license.
//
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement
{
internal class FeatureGroupAllocation
{
[JsonPropertyName("variant")]
public string Variant { get; set; }

[JsonPropertyName("groups")]
public IEnumerable<string> Groups { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,48 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//

namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement
{
internal class FeatureManagementConstants
{
public const string FeatureFlagMarker = ".appconfig.featureflag/";
public const string ContentType = "application/vnd.microsoft.appconfig.ff+json";
public const string SectionName = "FeatureManagement";
public const string EnabledFor = "EnabledFor";
public const string Variants = "Variants";
public const string Allocation = "Allocation";
public const string User = "User";
public const string Group = "Group";
public const string Percentile = "Percentile";
public const string Telemetry = "Telemetry";
public const string Enabled = "Enabled";
public const string Metadata = "Metadata";
public const string RequirementType = "RequirementType";
public const string Name = "Name";
public const string Parameters = "Parameters";
public const string Variant = "Variant";
public const string ConfigurationValue = "ConfigurationValue";
public const string ConfigurationReference = "ConfigurationReference";
public const string StatusOverride = "StatusOverride";
public const string DefaultWhenDisabled = "DefaultWhenDisabled";
public const string DefaultWhenEnabled = "DefaultWhenEnabled";
public const string Users = "Users";
public const string Groups = "Groups";
public const string From = "From";
public const string To = "To";
public const string Seed = "Seed";

// Feature management section keys
public const string FeatureManagementSectionName = "feature_management";
public const string FeatureFlagsSectionName = "feature_flags";

// Feature flag properties
public const string Id = "id";
public const string Enabled = "enabled";
public const string Conditions = "conditions";
public const string ClientFilters = "client_filters";
public const string Variants = "variants";
public const string Allocation = "allocation";
public const string UserAllocation = "user";
public const string GroupAllocation = "group";
public const string PercentileAllocation = "percentile";
public const string Telemetry = "telemetry";
public const string Metadata = "metadata";
public const string RequirementType = "requirement_type";
public const string Name = "name";
public const string Parameters = "parameters";
public const string Variant = "variant";
public const string ConfigurationValue = "configuration_value";
public const string ConfigurationReference = "configuration_reference";
public const string StatusOverride = "status_override";
public const string DefaultWhenDisabled = "default_when_disabled";
public const string DefaultWhenEnabled = "default_when_enabled";
public const string Users = "users";
public const string Groups = "groups";
public const string From = "from";
public const string To = "to";
public const string Seed = "seed";

// Telemetry metadata keys
public const string ETag = "ETag";
public const string FeatureFlagId = "FeatureFlagId";
public const string FeatureFlagReference = "FeatureFlagReference";
public const string Status = "Status";
public const string AlwaysOnFilter = "AlwaysOn";
public const string Conditional = "Conditional";
public const string Disabled = "Disabled";
}
}
Loading