-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Cherry Pick] Handling missing environment variables cleaner for SWA (#…
…1825) (#1834) Cherry pick #1825 to 0.9 ## Why make this change? - Fixes #1820 ## What is this change? - New test coverage for #1820 - Added a way to control error handling when env vars aren't set - default is left to throw, override to ignore ## How was this tested? - [x] Integration Tests - [ ] Unit Tests Co-authored-by: Aaron Powell <[email protected]>
- Loading branch information
1 parent
34fa935
commit b8c0c84
Showing
12 changed files
with
228 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/Config/Converters/EnvironmentVariableReplacementFailureMode.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
namespace Azure.DataApiBuilder.Config.Converters; | ||
|
||
/// <summary> | ||
/// Control how to handle environment variable replacement failures when deserializing strings in the JSON config file. | ||
/// </summary> | ||
public enum EnvironmentVariableReplacementFailureMode | ||
{ | ||
/// <summary> | ||
/// Ignore the missing environment variable and return the original value, eg: @env('schema'). | ||
/// </summary> | ||
Ignore, | ||
/// <summary> | ||
/// Throw an exception when a missing environment variable is encountered. This is the default behavior. | ||
/// </summary> | ||
Throw | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
namespace Azure.DataApiBuilder.Service.Tests.Configuration; | ||
|
||
internal static class ConfigurationEndpoints | ||
{ | ||
// TODO: Remove the old endpoint once we've updated all callers to use the new one. | ||
public const string CONFIGURATION_ENDPOINT = "/configuration"; | ||
public const string CONFIGURATION_ENDPOINT_V2 = "/configuration/v2"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
src/Service.Tests/Configuration/LoadConfigViaEndpoint.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Net.Http.Json; | ||
using System.Threading.Tasks; | ||
using Azure.DataApiBuilder.Config.ObjectModel; | ||
using Azure.DataApiBuilder.Core.Configurations; | ||
using Azure.DataApiBuilder.Service.Controllers; | ||
using Microsoft.AspNetCore.TestHost; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using static Azure.DataApiBuilder.Service.Tests.Configuration.ConfigurationEndpoints; | ||
using static Azure.DataApiBuilder.Service.Tests.Configuration.TestConfigFileReader; | ||
|
||
namespace Azure.DataApiBuilder.Service.Tests.Configuration; | ||
|
||
[TestClass] | ||
public class LoadConfigViaEndpointTests | ||
{ | ||
[TestMethod("Testing that missing environment variables won't cause runtime failure."), TestCategory(TestCategory.COSMOSDBNOSQL)] | ||
[DataRow(CONFIGURATION_ENDPOINT)] | ||
[DataRow(CONFIGURATION_ENDPOINT_V2)] | ||
public async Task CanLoadConfigWithMissingEnvironmentVariables(string configurationEndpoint) | ||
{ | ||
TestServer server = new(Program.CreateWebHostFromInMemoryUpdateableConfBuilder(Array.Empty<string>())); | ||
HttpClient httpClient = server.CreateClient(); | ||
|
||
(RuntimeConfig config, JsonContent content) = GetParameterContent(configurationEndpoint); | ||
|
||
HttpResponseMessage postResult = | ||
await httpClient.PostAsync(configurationEndpoint, content); | ||
Assert.AreEqual(HttpStatusCode.OK, postResult.StatusCode); | ||
|
||
RuntimeConfigProvider configProvider = server.Services.GetService(typeof(RuntimeConfigProvider)) as RuntimeConfigProvider; | ||
RuntimeConfig loadedConfig = configProvider.GetConfig(); | ||
|
||
Assert.AreEqual(config.Schema, loadedConfig.Schema); | ||
} | ||
|
||
[TestMethod("Testing that environment variables can be replaced at runtime not only when config is loaded."), TestCategory(TestCategory.COSMOSDBNOSQL)] | ||
[DataRow(CONFIGURATION_ENDPOINT)] | ||
[DataRow(CONFIGURATION_ENDPOINT_V2)] | ||
[Ignore("We don't want to environment variable substitution in late configuration, but test is left in for if this changes.")] | ||
public async Task CanLoadConfigWithEnvironmentVariables(string configurationEndpoint) | ||
{ | ||
Environment.SetEnvironmentVariable("schema", "schema.graphql"); | ||
TestServer server = new(Program.CreateWebHostFromInMemoryUpdateableConfBuilder(Array.Empty<string>())); | ||
HttpClient httpClient = server.CreateClient(); | ||
|
||
(RuntimeConfig config, JsonContent content) = GetParameterContent(configurationEndpoint); | ||
|
||
HttpResponseMessage postResult = | ||
await httpClient.PostAsync(configurationEndpoint, content); | ||
Assert.AreEqual(HttpStatusCode.OK, postResult.StatusCode); | ||
|
||
RuntimeConfigProvider configProvider = server.Services.GetService(typeof(RuntimeConfigProvider)) as RuntimeConfigProvider; | ||
RuntimeConfig loadedConfig = configProvider.GetConfig(); | ||
|
||
Assert.AreNotEqual(config.Schema, loadedConfig.Schema); | ||
Assert.AreEqual(Environment.GetEnvironmentVariable("schema"), loadedConfig.Schema); | ||
} | ||
|
||
[TestCleanup] | ||
public void Cleanup() | ||
{ | ||
Environment.SetEnvironmentVariable("schema", null); | ||
} | ||
|
||
private static (RuntimeConfig, JsonContent) GetParameterContent(string endpoint) | ||
{ | ||
RuntimeConfig config = ReadCosmosConfigurationFromFile() with { Schema = "@env('schema')" }; | ||
|
||
if (endpoint == CONFIGURATION_ENDPOINT) | ||
{ | ||
ConfigurationPostParameters @params = new( | ||
Configuration: config.ToJson(), | ||
Schema: @" | ||
type Entity { | ||
id: ID! | ||
name: String! | ||
} | ||
", | ||
ConnectionString: "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", | ||
AccessToken: null | ||
); | ||
|
||
return (config, JsonContent.Create(@params)); | ||
} | ||
else if (endpoint == CONFIGURATION_ENDPOINT_V2) | ||
{ | ||
ConfigurationPostParametersV2 @params = new( | ||
Configuration: config.ToJson(), | ||
ConfigurationOverrides: "{}", | ||
Schema: @" | ||
type Entity { | ||
id: ID! | ||
name: String! | ||
} | ||
", | ||
AccessToken: null | ||
); | ||
|
||
return (config, JsonContent.Create(@params)); | ||
} | ||
|
||
throw new ArgumentException($"Unknown endpoint: {endpoint}"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.IO; | ||
using Azure.DataApiBuilder.Config; | ||
using Azure.DataApiBuilder.Config.ObjectModel; | ||
using static Azure.DataApiBuilder.Config.FileSystemRuntimeConfigLoader; | ||
|
||
namespace Azure.DataApiBuilder.Service.Tests.Configuration; | ||
|
||
/// <summary> | ||
/// Provides the methods to read the configuration files from disk for tests. | ||
/// </summary> | ||
internal static class TestConfigFileReader | ||
{ | ||
public static RuntimeConfig ReadCosmosConfigurationFromFile() | ||
{ | ||
string cosmosFile = $"{CONFIGFILE_NAME}.{TestCategory.COSMOSDBNOSQL}{CONFIG_EXTENSION}"; | ||
|
||
string configurationFileContents = File.ReadAllText(cosmosFile); | ||
if (!RuntimeConfigLoader.TryParseConfig(configurationFileContents, out RuntimeConfig config)) | ||
{ | ||
throw new Exception("Failed to parse configuration file."); | ||
} | ||
|
||
// The Schema file isn't provided in the configuration file when going through the configuration endpoint so we're removing it. | ||
_ = config.DataSource.Options.Remove("Schema"); | ||
return config; | ||
} | ||
} |
Oops, something went wrong.