diff --git a/build/install-dotnet.ps1 b/build/install-dotnet.ps1 index 0c92b8b84..898b64099 100644 --- a/build/install-dotnet.ps1 +++ b/build/install-dotnet.ps1 @@ -1,6 +1,8 @@ -# Installs .NET 6 for CI/CD environment +# Installs .NET 6 and .NET 7 for CI/CD environment # see: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script#examples [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; +&([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 7.0.100 + &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 6.0.301 \ No newline at end of file diff --git a/examples/ConfigStoreDemo/ConfigStoreDemo.csproj b/examples/ConfigStoreDemo/ConfigStoreDemo.csproj index 92c5b12bb..3b11aa18d 100644 --- a/examples/ConfigStoreDemo/ConfigStoreDemo.csproj +++ b/examples/ConfigStoreDemo/ConfigStoreDemo.csproj @@ -1,7 +1,7 @@  false - net5.0 + net7.0 diff --git a/examples/ConsoleApplication/ConsoleApplication.csproj b/examples/ConsoleApplication/ConsoleApplication.csproj index a74c0292b..2bc2e9ecd 100644 --- a/examples/ConsoleApplication/ConsoleApplication.csproj +++ b/examples/ConsoleApplication/ConsoleApplication.csproj @@ -3,7 +3,7 @@ false Exe - net5.0 + net7.0 diff --git a/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj b/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj index f0b98b600..4ffc9d4e9 100644 --- a/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj +++ b/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj @@ -2,7 +2,7 @@ - netstandard2.0;netcoreapp3.1;net5.0;net6.0 + netstandard2.0;netcoreapp3.1;net5.0;net6.0;net7.0 Microsoft.Azure.AppConfiguration.AspNetCore allows developers to use Microsoft Azure App Configuration service as a configuration source in their applications. This package adds additional features for ASP.NET Core applications to the existing package Microsoft.Extensions.Configuration.AzureAppConfiguration. true false @@ -28,7 +28,7 @@ - 5.1.0 + 5.2.0 diff --git a/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj b/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj index 6f6478126..5eecfc6a8 100644 --- a/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj +++ b/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj @@ -2,7 +2,7 @@ - net5.0;net6.0 + net5.0;net6.0;net7.0 Microsoft.Azure.AppConfiguration.Functions.Worker allows developers to use the Microsoft Azure App Configuration service as a configuration source in their applications. This package adds additional features to the existing package Microsoft.Extensions.Configuration.AzureAppConfiguration for .NET Azure Functions running in an isolated process. true false @@ -24,7 +24,7 @@ - 5.1.0 + 5.2.0 diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationOptions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationOptions.cs index 11325af43..035014601 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationOptions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationOptions.cs @@ -129,7 +129,7 @@ public AzureAppConfigurationOptions Select(string keyFilter, string labelFilter throw new ArgumentNullException(nameof(keyFilter)); } - if (labelFilter == null) + if (string.IsNullOrWhiteSpace(labelFilter)) { labelFilter = LabelFilter.Null; } diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs index 271e3a4a6..d03f29239 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs @@ -316,17 +316,6 @@ await CallWithRequestTracing(async () => foreach (var loadOption in _options.KeyValueSelectors) { - if ((useDefaultQuery && LabelFilter.Null.Equals(loadOption.LabelFilter)) || - _options.KeyValueSelectors.Any(s => s != loadOption && - string.Equals(s.KeyFilter, KeyFilter.Any) && - string.Equals(s.LabelFilter, loadOption.LabelFilter))) - { - // This selection was already encapsulated by a wildcard query - // Or would select kvs obtained by a different selector - // We skip it to prevent unnecessary requests - continue; - } - var selector = new SettingSelector { KeyFilter = loadOption.KeyFilter, @@ -608,7 +597,7 @@ private async Task SetData(IDictionary data, bool { keyValuePairs = await ProcessAdapters(kvp.Value, cancellationToken).ConfigureAwait(false); } - catch (KeyVaultReferenceException) + catch (Exception e) when (e is KeyVaultReferenceException || e is FormatException) { if (!ignoreFailures) { diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs index 3fc84d833..30453dc1d 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs @@ -3,6 +3,7 @@ // using Azure; using Azure.Data.AppConfiguration; +using Azure.Security.KeyVault.Secrets; using System; using System.Collections.Generic; using System.Linq; @@ -41,7 +42,7 @@ public async Task>> ProcessKeyValue(Con } // Uri validation - if (string.IsNullOrEmpty(secretRef.Uri) || !Uri.TryCreate(secretRef.Uri, UriKind.Absolute, out Uri secretUri) || secretUri.Segments.Length < 3) + if (string.IsNullOrEmpty(secretRef.Uri) || !Uri.TryCreate(secretRef.Uri, UriKind.Absolute, out Uri secretUri) || !KeyVaultSecretIdentifier.TryCreate(secretUri, out KeyVaultSecretIdentifier secretIdentifier)) { throw CreateKeyVaultReferenceException("Invalid Key vault secret identifier", setting, null, secretRef); } @@ -50,7 +51,7 @@ public async Task>> ProcessKeyValue(Con try { - secret = await _secretProvider.GetSecretValue(secretUri, setting.Key, cancellationToken).ConfigureAwait(false); + secret = await _secretProvider.GetSecretValue(secretIdentifier, setting.Key, cancellationToken).ConfigureAwait(false); } catch (Exception e) when (e is UnauthorizedAccessException || (e.Source?.Equals(AzureIdentityAssemblyName, StringComparison.OrdinalIgnoreCase) ?? false)) { diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultSecretProvider.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultSecretProvider.cs index 731ba0db1..7f62e50ae 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultSecretProvider.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultSecretProvider.cs @@ -35,10 +35,8 @@ public AzureKeyVaultSecretProvider(AzureAppConfigurationKeyVaultOptions keyVault } } - public async Task GetSecretValue(Uri secretUri, string key, CancellationToken cancellationToken) + public async Task GetSecretValue(KeyVaultSecretIdentifier secretIdentifier, string key, CancellationToken cancellationToken) { - string secretName = secretUri?.Segments?.ElementAtOrDefault(2)?.TrimEnd('/'); - string secretVersion = secretUri?.Segments?.ElementAtOrDefault(3)?.TrimEnd('/'); string secretValue = null; if (_cachedKeyVaultSecrets.TryGetValue(key, out CachedKeyVaultSecret cachedSecret) && @@ -47,7 +45,7 @@ public async Task GetSecretValue(Uri secretUri, string key, Cancellation return cachedSecret.SecretValue; } - SecretClient client = GetSecretClient(secretUri); + SecretClient client = GetSecretClient(secretIdentifier.SourceId); if (client == null && _keyVaultOptions.SecretResolver == null) { @@ -60,12 +58,12 @@ public async Task GetSecretValue(Uri secretUri, string key, Cancellation { if (client != null) { - KeyVaultSecret secret = await client.GetSecretAsync(secretName, secretVersion, cancellationToken).ConfigureAwait(false); + KeyVaultSecret secret = await client.GetSecretAsync(secretIdentifier.Name, secretIdentifier.Version, cancellationToken).ConfigureAwait(false); secretValue = secret.Value; } else if (_keyVaultOptions.SecretResolver != null) { - secretValue = await _keyVaultOptions.SecretResolver(secretUri).ConfigureAwait(false); + secretValue = await _keyVaultOptions.SecretResolver(secretIdentifier.SourceId).ConfigureAwait(false); } cachedSecret = new CachedKeyVaultSecret(secretValue); diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs index 3f03c57ab..856a7bd65 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs @@ -54,7 +54,7 @@ public FeatureFlagOptions Select(string featureFlagFilter, string labelFilter = throw new ArgumentException(@"Feature flag filter should not end with '\*'.", nameof(featureFlagFilter)); } - if (labelFilter == null) + if (string.IsNullOrWhiteSpace(labelFilter)) { labelFilter = LabelFilter.Null; } diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj index 2ca85b15b..46b754be0 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj @@ -16,11 +16,11 @@ - + - + @@ -34,7 +34,7 @@ - 5.1.0 + 5.2.0 diff --git a/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj b/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj index 6a04aaa91..4cb1017f4 100644 --- a/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj +++ b/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1;netcoreapp3.1;net5.0;net6.0 + netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0 8.0 false true diff --git a/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj b/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj index d4f87588c..5406e9231 100644 --- a/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj +++ b/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj @@ -1,7 +1,7 @@  - net5.0;net6.0 + net5.0;net6.0;net7.0 8.0 false true diff --git a/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs b/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs index fcc8a75f1..79cc6e619 100644 --- a/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs +++ b/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs @@ -348,10 +348,13 @@ public void SkipRefreshIfCacheNotExpired() [Fact] public void PreservesDefaultQuery() { - var response = new MockResponse(200); - response.SetContent(SerializationHelpers.Serialize(new[] { _kv }, TestHelpers.SerializeBatch)); + var mockTransport = new MockTransport(req => + { + var response = new MockResponse(200); + response.SetContent(SerializationHelpers.Serialize(new[] { _kv }, TestHelpers.SerializeBatch)); + return response; + }); - var mockTransport = new MockTransport(response); var clientOptions = new ConfigurationClientOptions { Transport = mockTransport @@ -364,10 +367,11 @@ public void PreservesDefaultQuery() options.UseFeatureFlags(); }).Build(); - MockRequest request = mockTransport.SingleRequest; + bool performedDefaultQuery = mockTransport.Requests.Any(r => r.Uri.PathAndQuery.Contains("/kv/?key=%2A&label=%00")); + bool queriedFeatureFlags = mockTransport.Requests.Any(r => r.Uri.PathAndQuery.Contains(Uri.EscapeDataString(FeatureManagementConstants.FeatureFlagMarker))); - Assert.Contains("/kv/?key=%252A&label=%2500", Uri.EscapeUriString(request.Uri.PathAndQuery)); - Assert.DoesNotContain(Uri.EscapeDataString(FeatureManagementConstants.FeatureFlagMarker), request.Uri.PathAndQuery); + Assert.True(performedDefaultQuery); + Assert.True(queriedFeatureFlags); } [Fact] @@ -423,7 +427,7 @@ public void UsesEtagForFeatureFlagRefresh() Thread.Sleep(cacheExpirationTimeSpan); refresher.TryRefreshAsync().Wait(); - mockClient.Verify(c => c.GetConfigurationSettingsAsync(It.IsAny(), It.IsAny()), Times.Exactly(2)); + mockClient.Verify(c => c.GetConfigurationSettingsAsync(It.IsAny(), It.IsAny()), Times.Exactly(3)); } [Fact] diff --git a/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj b/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj index 05284d04e..badc0096f 100644 --- a/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj +++ b/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1;netcoreapp3.1;net5.0;net6.0 + netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0 8.0 false true