Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2fc665d
allow unused cache-control options without error
aaronburtle Jun 20, 2025
50e54aa
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Jun 25, 2025
455ff18
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Jun 26, 2025
e0574bf
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Jul 11, 2025
033eeb0
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Jul 23, 2025
c7ad08f
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Aug 27, 2025
049b23e
...
aaronburtle Sep 11, 2025
cfdc2b5
extend variable replacment and include AKV
aaronburtle Sep 11, 2025
5eb9f0e
change some logic for first pass var replacement
aaronburtle Sep 13, 2025
bbcc159
fix old bools being used
aaronburtle Sep 17, 2025
f6f92bd
more bool replacements
aaronburtle Sep 18, 2025
0dd7ad6
refactor out bools
aaronburtle Sep 18, 2025
802eb53
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Sep 26, 2025
4e71c25
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Oct 9, 2025
ac4356e
addressing comments
aaronburtle Oct 21, 2025
c3dabe3
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Oct 21, 2025
6e77297
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Oct 30, 2025
3254af5
update names
aaronburtle Oct 30, 2025
b28cd6b
cleanup with fix
aaronburtle Oct 30, 2025
5e79339
cleanup
aaronburtle Oct 30, 2025
fa6582b
format, cleanup
aaronburtle Oct 31, 2025
b761333
Update src/Config/RuntimeConfigLoader.cs
aaronburtle Oct 31, 2025
9411180
Update src/Config/DeserializationVariableReplacementSettings.cs
aaronburtle Oct 31, 2025
890e2c6
Update src/Config/Converters/DatasourceHealthOptionsConvertorFactory.cs
aaronburtle Oct 31, 2025
9af3a4c
Update src/Config/Converters/DatasourceHealthOptionsConvertorFactory.cs
aaronburtle Oct 31, 2025
11318c6
Update src/Config/Converters/EntityCacheOptionsConverterFactory.cs
aaronburtle Oct 31, 2025
b9ef8f9
Update src/Config/Converters/EntityCacheOptionsConverterFactory.cs
aaronburtle Oct 31, 2025
3b1d682
Update src/Config/Converters/StringJsonConverterFactory.cs
aaronburtle Oct 31, 2025
15abe47
Update src/Config/Converters/McpRuntimeOptionsConverterFactory.cs
aaronburtle Oct 31, 2025
da9d974
Update src/Config/Converters/RuntimeHealthOptionsConvertorFactory.cs
aaronburtle Oct 31, 2025
3bde74c
Update src/Config/Converters/RuntimeHealthOptionsConvertorFactory.cs
aaronburtle Oct 31, 2025
025cbc3
format
aaronburtle Oct 31, 2025
1c6f020
remove last vestigates of replaceEnvVar
aaronburtle Oct 31, 2025
9a14dc3
format
aaronburtle Oct 31, 2025
4f38f92
format
aaronburtle Oct 31, 2025
4742669
using ordering
aaronburtle Oct 31, 2025
6b73688
Merge branch 'main' of github.com:Azure/data-api-builder
aaronburtle Oct 31, 2025
97fdc69
Merge branch 'main' into dev/aaronburtle/AKVReplacement
aaronburtle Oct 31, 2025
10855d0
removed unused null check
aaronburtle Nov 4, 2025
a172a16
address comments
aaronburtle Nov 5, 2025
8b8d2de
default to false
aaronburtle Nov 5, 2025
3e0f78b
Merge branch 'main' into dev/aaronburtle/AKVReplacement
aaronburtle Nov 5, 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
56 changes: 28 additions & 28 deletions src/Cli.Tests/ConfigureOptionsTests.cs

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/Cli.Tests/EndToEndTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ public void TestInitializingRestAndGraphQLGlobalSettings()
string[] args = { "init", "-c", TEST_RUNTIME_CONFIG_FILE, "--connection-string", SAMPLE_TEST_CONN_STRING, "--database-type", "mssql", "--rest.path", "/rest-api", "--rest.enabled", "false", "--graphql.path", "/graphql-api" };
Program.Execute(args, _cliLogger!, _fileSystem!, _runtimeConfigLoader!);

DeserializationVariableReplacementSettings replacementSettings = new(azureKeyVaultOptions: null, doReplaceEnvVar: true, doReplaceAkvVar: true);
Assert.IsTrue(_runtimeConfigLoader!.TryLoadConfig(
TEST_RUNTIME_CONFIG_FILE,
out RuntimeConfig? runtimeConfig,
replaceEnvVar: true));
replacementSettings: replacementSettings));

SqlConnectionStringBuilder builder = new(runtimeConfig.DataSource.ConnectionString);
Assert.AreEqual(ProductInfo.GetDataApiBuilderUserAgent(), builder.ApplicationName);
Expand Down Expand Up @@ -195,10 +196,11 @@ public void TestEnablingMultipleCreateOperation(CliBool isMultipleCreateEnabled,

Program.Execute(args.ToArray(), _cliLogger!, _fileSystem!, _runtimeConfigLoader!);

DeserializationVariableReplacementSettings replacementSettings = new(azureKeyVaultOptions: null, doReplaceEnvVar: true, doReplaceAkvVar: true);
Assert.IsTrue(_runtimeConfigLoader!.TryLoadConfig(
TEST_RUNTIME_CONFIG_FILE,
out RuntimeConfig? runtimeConfig,
replaceEnvVar: true));
replacementSettings: replacementSettings));

Assert.IsNotNull(runtimeConfig);
Assert.AreEqual(expectedDbType, runtimeConfig.DataSource.DatabaseType);
Expand Down
8 changes: 7 additions & 1 deletion src/Cli.Tests/EnvironmentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ public class EnvironmentTests
[TestInitialize]
public void TestInitialize()
{
StringJsonConverterFactory converterFactory = new(EnvironmentVariableReplacementFailureMode.Throw);
DeserializationVariableReplacementSettings replacementSettings = new(
azureKeyVaultOptions: null,
doReplaceEnvVar: true,
doReplaceAkvVar: false,
envFailureMode: EnvironmentVariableReplacementFailureMode.Throw);

StringJsonConverterFactory converterFactory = new(replacementSettings);
_options = new()
{
PropertyNameCaseInsensitive = true
Expand Down
3 changes: 2 additions & 1 deletion src/Cli/Exporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public static bool Export(ExportOptions options, ILogger logger, FileSystemRunti
}

// Load the runtime configuration from the file
if (!loader.TryLoadConfig(runtimeConfigFile, out RuntimeConfig? runtimeConfig, replaceEnvVar: true))
DeserializationVariableReplacementSettings replacementSettings = new(azureKeyVaultOptions: null, doReplaceEnvVar: true, doReplaceAkvVar: true);
if (!loader.TryLoadConfig(runtimeConfigFile, out RuntimeConfig? runtimeConfig, replacementSettings: replacementSettings))
{
logger.LogError("Failed to read the config file: {0}.", runtimeConfigFile);
return false;
Expand Down
1 change: 1 addition & 0 deletions src/Config/Azure.DataApiBuilder.Config.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<ItemGroup>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" />
<PackageReference Include="Microsoft.IdentityModel.Protocols" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" />
Expand Down
32 changes: 16 additions & 16 deletions src/Config/Converters/AKVRetryPolicyOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace Azure.DataApiBuilder.Config.Converters;
/// </summary>
internal class AKVRetryPolicyOptionsConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
// Currently allows for Azure Key Vault and Environment Variable replacement.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
Expand All @@ -25,27 +25,27 @@ public override bool CanConvert(Type typeToConvert)
/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new AKVRetryPolicyOptionsConverter(_replaceEnvVar);
return new AKVRetryPolicyOptionsConverter(_replacementSettings);
}

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AKVRetryPolicyOptionsConverterFactory(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal AKVRetryPolicyOptionsConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

private class AKVRetryPolicyOptionsConverter : JsonConverter<AKVRetryPolicyOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
// Currently allows for Azure Key Vault and Environment Variable replacement.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public AKVRetryPolicyOptionsConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
public AKVRetryPolicyOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

/// <summary>
Expand Down Expand Up @@ -82,7 +82,7 @@ public AKVRetryPolicyOptionsConverter(bool replaceEnvVar)
}
else
{
mode = EnumExtensions.Deserialize<AKVRetryPolicyMode>(reader.DeserializeString(_replaceEnvVar)!);
mode = EnumExtensions.Deserialize<AKVRetryPolicyMode>(reader.DeserializeString(_replacementSettings)!);
}

break;
Expand Down
128 changes: 128 additions & 0 deletions src/Config/Converters/AzureKeyVaultOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json;
using System.Text.Json.Serialization;
using Azure.DataApiBuilder.Config.ObjectModel;

namespace Azure.DataApiBuilder.Config.Converters;

/// <summary>
/// Converter factory for AzureKeyVaultOptions that can optionally perform variable replacement.
/// </summary>
internal class AzureKeyVaultOptionsConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replacementSettings">How to handle variable replacement during deserialization.</param>
internal AzureKeyVaultOptionsConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replacementSettings = replacementSettings;
}

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsAssignableTo(typeof(AzureKeyVaultOptions));
}

/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new AzureKeyVaultOptionsConverter(_replacementSettings);
}

private class AzureKeyVaultOptionsConverter : JsonConverter<AzureKeyVaultOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public AzureKeyVaultOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replacementSettings = replacementSettings;
}

/// <summary>
/// Reads AzureKeyVaultOptions with optional variable replacement.
/// </summary>
public override AzureKeyVaultOptions? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType is JsonTokenType.Null)
{
return null;
}

if (reader.TokenType is JsonTokenType.StartObject)
{
string? endpoint = null;
AKVRetryPolicyOptions? retryPolicy = null;

while (reader.Read())
{
if (reader.TokenType is JsonTokenType.EndObject)
{
return new AzureKeyVaultOptions(endpoint, retryPolicy);
}

string? property = reader.GetString();
reader.Read();

switch (property)
{
case "endpoint":
if (reader.TokenType is JsonTokenType.String)
{
endpoint = reader.DeserializeString(_replacementSettings);
}

break;

case "retry-policy":
if (reader.TokenType is JsonTokenType.StartObject)
{
// Uses the AKVRetryPolicyOptionsConverter to read the retry-policy object.
retryPolicy = JsonSerializer.Deserialize<AKVRetryPolicyOptions>(ref reader, options);
}

break;

default:
throw new JsonException($"Unexpected property {property}");
}
}
}

throw new JsonException("Invalid AzureKeyVaultOptions format");
}

/// <summary>
/// When writing the AzureKeyVaultOptions back to a JSON file, only write the properties
/// if they are user provided. This avoids polluting the written JSON file with properties
/// the user most likely omitted when writing the original DAB runtime config file.
/// This Write operation is only used when a RuntimeConfig object is serialized to JSON.
/// </summary>
public override void Write(Utf8JsonWriter writer, AzureKeyVaultOptions value, JsonSerializerOptions options)
{
writer.WriteStartObject();

if (value?.UserProvidedEndpoint is true)
{
writer.WritePropertyName("endpoint");
JsonSerializer.Serialize(writer, value.Endpoint, options);
}

if (value?.UserProvidedRetryPolicy is true)
{
writer.WritePropertyName("retry-policy");
JsonSerializer.Serialize(writer, value.RetryPolicy, options);
}

writer.WriteEndObject();
}
}
}
19 changes: 9 additions & 10 deletions src/Config/Converters/AzureLogAnalyticsAuthOptionsConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ namespace Azure.DataApiBuilder.Config.Converters;

internal class AzureLogAnalyticsAuthOptionsConverter : JsonConverter<AzureLogAnalyticsAuthOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public AzureLogAnalyticsAuthOptionsConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
public AzureLogAnalyticsAuthOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

/// <summary>
Expand Down Expand Up @@ -48,23 +47,23 @@ public AzureLogAnalyticsAuthOptionsConverter(bool replaceEnvVar)
case "custom-table-name":
if (reader.TokenType is not JsonTokenType.Null)
{
customTableName = reader.DeserializeString(_replaceEnvVar);
customTableName = reader.DeserializeString(_replacementSettings);
}

break;

case "dcr-immutable-id":
if (reader.TokenType is not JsonTokenType.Null)
{
dcrImmutableId = reader.DeserializeString(_replaceEnvVar);
dcrImmutableId = reader.DeserializeString(_replacementSettings);
}

break;

case "dce-endpoint":
if (reader.TokenType is not JsonTokenType.Null)
{
dceEndpoint = reader.DeserializeString(_replaceEnvVar);
dceEndpoint = reader.DeserializeString(_replacementSettings);
}

break;
Expand Down
32 changes: 15 additions & 17 deletions src/Config/Converters/AzureLogAnalyticsOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ namespace Azure.DataApiBuilder.Config.Converters;
/// </summary>
internal class AzureLogAnalyticsOptionsConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
Expand All @@ -25,27 +24,26 @@ public override bool CanConvert(Type typeToConvert)
/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new AzureLogAnalyticsOptionsConverter(_replaceEnvVar);
return new AzureLogAnalyticsOptionsConverter(_replacementSettings);
}

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AzureLogAnalyticsOptionsConverterFactory(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal AzureLogAnalyticsOptionsConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

private class AzureLogAnalyticsOptionsConverter : JsonConverter<AzureLogAnalyticsOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AzureLogAnalyticsOptionsConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal AzureLogAnalyticsOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

/// <summary>
Expand All @@ -57,7 +55,7 @@ internal AzureLogAnalyticsOptionsConverter(bool replaceEnvVar)
{
if (reader.TokenType is JsonTokenType.StartObject)
{
AzureLogAnalyticsAuthOptionsConverter authOptionsConverter = new(_replaceEnvVar);
AzureLogAnalyticsAuthOptionsConverter authOptionsConverter = new(_replacementSettings);

bool? enabled = null;
AzureLogAnalyticsAuthOptions? auth = null;
Expand Down Expand Up @@ -91,7 +89,7 @@ internal AzureLogAnalyticsOptionsConverter(bool replaceEnvVar)
case "dab-identifier":
if (reader.TokenType is not JsonTokenType.Null)
{
logType = reader.DeserializeString(_replaceEnvVar);
logType = reader.DeserializeString(_replacementSettings);
}

break;
Expand Down
Loading
Loading