diff --git a/build/Common.props b/build/Common.props index 38ce3348319..1c52c393218 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,7 +35,6 @@ [2.1.1,6.0) [3.3.3] [17.4.1] - [3.1.0,) [3.1.0,) $(MicrosoftExtensionsDependencyInjectionPkgVer) [2.1.0,) diff --git a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj index 2526d6422a4..1323e95a51a 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj +++ b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj @@ -23,6 +23,7 @@ + diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj index a40f0c284b2..3b7a52aa896 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj @@ -38,6 +38,7 @@ + diff --git a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj index 4644969ac19..a9eb8158e6a 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj +++ b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj @@ -18,6 +18,7 @@ + diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index ffe9ed6be04..73e50fafa03 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Removed dependency on Microsoft.Extensions.Configuration.EnvironmentVariables + ([#4092](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4092)) + ## 1.4.0-rc.2 Released 2023-Jan-09 diff --git a/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs b/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs new file mode 100644 index 00000000000..f25b1f1a5c4 --- /dev/null +++ b/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs @@ -0,0 +1,122 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Extensions.Configuration.EnvironmentVariables +{ + /// + /// An environment variable based . + /// + internal sealed class EnvironmentVariablesConfigurationProvider : ConfigurationProvider + { + private const string MySqlServerPrefix = "MYSQLCONNSTR_"; + private const string SqlAzureServerPrefix = "SQLAZURECONNSTR_"; + private const string SqlServerPrefix = "SQLCONNSTR_"; + private const string CustomConnectionStringPrefix = "CUSTOMCONNSTR_"; + + private readonly string _prefix; + private readonly string _normalizedPrefix; + + /// + /// Initializes a new instance. + /// + public EnvironmentVariablesConfigurationProvider() + { + _prefix = string.Empty; + _normalizedPrefix = string.Empty; + } + + /// + /// Initializes a new instance with the specified prefix. + /// + /// A prefix used to filter the environment variables. + public EnvironmentVariablesConfigurationProvider(string? prefix) + { + _prefix = prefix ?? string.Empty; + _normalizedPrefix = Normalize(_prefix); + } + + /// + /// Loads the environment variables. + /// + public override void Load() => + Load(Environment.GetEnvironmentVariables()); + + /// + /// Generates a string representing this provider name and relevant details. + /// + /// The configuration name. + public override string ToString() + => $"{GetType().Name} Prefix: '{_prefix}'"; + + internal void Load(IDictionary envVariables) + { + var data = new Dictionary(StringComparer.OrdinalIgnoreCase); + + IDictionaryEnumerator e = envVariables.GetEnumerator(); + try + { + while (e.MoveNext()) + { + string key = (string)e.Entry.Key; + string? value = (string?)e.Entry.Value; + + if (key.StartsWith(MySqlServerPrefix, StringComparison.OrdinalIgnoreCase)) + { + HandleMatchedConnectionStringPrefix(data, MySqlServerPrefix, "MySql.Data.MySqlClient", key, value); + } + else if (key.StartsWith(SqlAzureServerPrefix, StringComparison.OrdinalIgnoreCase)) + { + HandleMatchedConnectionStringPrefix(data, SqlAzureServerPrefix, "System.Data.SqlClient", key, value); + } + else if (key.StartsWith(SqlServerPrefix, StringComparison.OrdinalIgnoreCase)) + { + HandleMatchedConnectionStringPrefix(data, SqlServerPrefix, "System.Data.SqlClient", key, value); + } + else if (key.StartsWith(CustomConnectionStringPrefix, StringComparison.OrdinalIgnoreCase)) + { + HandleMatchedConnectionStringPrefix(data, CustomConnectionStringPrefix, null, key, value); + } + else + { + AddIfNormalizedKeyMatchesPrefix(data, Normalize(key), value); + } + } + } + finally + { + (e as IDisposable)?.Dispose(); + } + + Data = data; + } + + private void HandleMatchedConnectionStringPrefix(Dictionary data, string connectionStringPrefix, string? provider, string fullKey, string? value) + { + string normalizedKeyWithoutConnectionStringPrefix = Normalize(fullKey.Substring(connectionStringPrefix.Length)); + + // Add the key-value pair for connection string, and optionally provider name + AddIfNormalizedKeyMatchesPrefix(data, $"ConnectionStrings:{normalizedKeyWithoutConnectionStringPrefix}", value); + if (provider != null) + { + AddIfNormalizedKeyMatchesPrefix(data, $"ConnectionStrings:{normalizedKeyWithoutConnectionStringPrefix}_ProviderName", provider); + } + } + + private void AddIfNormalizedKeyMatchesPrefix(Dictionary data, string normalizedKey, string? value) + { + if (normalizedKey.StartsWith(_normalizedPrefix, StringComparison.OrdinalIgnoreCase)) + { + data[normalizedKey.Substring(_normalizedPrefix.Length)] = value; + } + } + + private static string Normalize(string key) => key.Replace("__", ConfigurationPath.KeyDelimiter); + } +} diff --git a/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs b/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs new file mode 100644 index 00000000000..2785b217475 --- /dev/null +++ b/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs @@ -0,0 +1,29 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +namespace Microsoft.Extensions.Configuration.EnvironmentVariables +{ + /// + /// Represents environment variables as an . + /// + internal sealed class EnvironmentVariablesConfigurationSource : IConfigurationSource + { + /// + /// A prefix used to filter environment variables. + /// + public string? Prefix { get; set; } + + /// + /// Builds the for this source. + /// + /// The . + /// A + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + return new EnvironmentVariablesConfigurationProvider(Prefix); + } + } +} diff --git a/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesExtensions.cs b/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesExtensions.cs new file mode 100644 index 00000000000..5b97e90ce77 --- /dev/null +++ b/src/OpenTelemetry/Internal/EnvironmentVariables/EnvironmentVariablesExtensions.cs @@ -0,0 +1,52 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using Microsoft.Extensions.Configuration.EnvironmentVariables; + +namespace Microsoft.Extensions.Configuration +{ + /// + /// Extension methods for registering with . + /// + internal static class EnvironmentVariablesExtensions + { + /// + /// Adds an that reads configuration values from environment variables. + /// + /// The to add to. + /// The . + public static IConfigurationBuilder AddEnvironmentVariables(this IConfigurationBuilder configurationBuilder) + { + configurationBuilder.Add(new EnvironmentVariablesConfigurationSource()); + return configurationBuilder; + } + + /// + /// Adds an that reads configuration values from environment variables + /// with a specified prefix. + /// + /// The to add to. + /// The prefix that environment variable names must start with. The prefix will be removed from the environment variable names. + /// The . + public static IConfigurationBuilder AddEnvironmentVariables( + this IConfigurationBuilder configurationBuilder, + string? prefix) + { + configurationBuilder.Add(new EnvironmentVariablesConfigurationSource { Prefix = prefix }); + return configurationBuilder; + } + + /// + /// Adds an that reads configuration values from environment variables. + /// + /// The to add to. + /// Configures the source. + /// The . + public static IConfigurationBuilder AddEnvironmentVariables(this IConfigurationBuilder builder, Action? configureSource) + => builder.Add(configureSource); + } +} diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj index 3e5a2273fe8..ddc2af154fc 100644 --- a/src/OpenTelemetry/OpenTelemetry.csproj +++ b/src/OpenTelemetry/OpenTelemetry.csproj @@ -20,7 +20,6 @@ -