Skip to content
Draft
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
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
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
30 changes: 14 additions & 16 deletions src/Config/Converters/AKVRetryPolicyOptionsConverterFactory.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 AKVRetryPolicyOptionsConverterFactory : 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 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.
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 +80,7 @@ public AKVRetryPolicyOptionsConverter(bool replaceEnvVar)
}
else
{
mode = EnumExtensions.Deserialize<AKVRetryPolicyMode>(reader.DeserializeString(_replaceEnvVar)!);
mode = EnumExtensions.Deserialize<AKVRetryPolicyMode>(reader.DeserializeString(_replacementSettings)!);
}

break;
Expand Down
113 changes: 113 additions & 0 deletions src/Config/Converters/AzureKeyVaultOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// 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="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</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.StartObject)
{
string? endpoint = null;
AKVRetryPolicyOptions? retryPolicy = null;

while (reader.Read())
{
if (reader.TokenType is JsonTokenType.EndObject)
{
return new AzureKeyVaultOptions
{
Endpoint = endpoint,
RetryPolicy = 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)
{
// Pass the replaceEnvVar setting to the retry policy converter
retryPolicy = JsonSerializer.Deserialize<AKVRetryPolicyOptions>(ref reader, options);
}

break;

default:
reader.Skip();
break;
}
}
}
else if (reader.TokenType is JsonTokenType.Null)
{
return null;
}

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

public override void Write(Utf8JsonWriter writer, AzureKeyVaultOptions value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, options);
}
}
}
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
34 changes: 16 additions & 18 deletions src/Config/Converters/DataSourceConverterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ namespace Azure.DataApiBuilder.Config.Converters;

internal class DataSourceConverterFactory : 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 @@ -22,27 +21,26 @@ public override bool CanConvert(Type typeToConvert)
/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new DataSourceConverter(_replaceEnvVar);
return new DataSourceConverter(_replacementSettings);
}

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

private class DataSourceConverter : JsonConverter<DataSource>
{
// 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 DataSourceConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
public DataSourceConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

public override DataSource? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Expand All @@ -69,11 +67,11 @@ public DataSourceConverter(bool replaceEnvVar)
switch (propertyName)
{
case "database-type":
databaseType = EnumExtensions.Deserialize<DatabaseType>(reader.DeserializeString(_replaceEnvVar)!);
databaseType = EnumExtensions.Deserialize<DatabaseType>(reader.DeserializeString(_replacementSettings)!);
break;

case "connection-string":
connectionString = reader.DeserializeString(replaceEnvVar: _replaceEnvVar)!;
connectionString = reader.DeserializeString(_replacementSettings)!;
break;

case "health":
Expand Down Expand Up @@ -106,7 +104,7 @@ public DataSourceConverter(bool replaceEnvVar)
if (reader.TokenType is JsonTokenType.String)
{
// Determine whether to resolve the environment variable or keep as-is.
string stringValue = reader.DeserializeString(replaceEnvVar: _replaceEnvVar)!;
string stringValue = reader.DeserializeString(_replacementSettings)!;

if (bool.TryParse(stringValue, out bool boolValue))
{
Expand Down
Loading
Loading