Skip to content

Commit

Permalink
backport support for CNB, including test fixes from #1087
Browse files Browse the repository at this point in the history
Also match styling and namespaces found in 3.2
  • Loading branch information
TimHess committed Dec 22, 2022
1 parent 984ea35 commit 38b62ab
Show file tree
Hide file tree
Showing 65 changed files with 3,302 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/Configuration/Configuration.sln
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Connector.Connecto
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Logging.Abstractions", "..\Logging\src\Abstractions\Steeltoe.Extensions.Logging.Abstractions.csproj", "{C86FB6E5-3024-4028-9BC0-602AEBA65E5B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding", "src\Kubernetes.ServiceBinding\Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding.csproj", "{40901586-F39F-4959-89D5-61FFC17854CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding.Test", "test\Kubernetes.ServiceBinding.Test\Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding.Test.csproj", "{73119C3B-D54A-4930-AACE-CD2156B7CCF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -282,6 +286,14 @@ Global
{C86FB6E5-3024-4028-9BC0-602AEBA65E5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C86FB6E5-3024-4028-9BC0-602AEBA65E5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C86FB6E5-3024-4028-9BC0-602AEBA65E5B}.Release|Any CPU.Build.0 = Release|Any CPU
{40901586-F39F-4959-89D5-61FFC17854CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40901586-F39F-4959-89D5-61FFC17854CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40901586-F39F-4959-89D5-61FFC17854CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40901586-F39F-4959-89D5-61FFC17854CE}.Release|Any CPU.Build.0 = Release|Any CPU
{73119C3B-D54A-4930-AACE-CD2156B7CCF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73119C3B-D54A-4930-AACE-CD2156B7CCF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73119C3B-D54A-4930-AACE-CD2156B7CCF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73119C3B-D54A-4930-AACE-CD2156B7CCF5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -329,6 +341,8 @@ Global
{3A265CB8-530E-4FC8-931D-01DE4E7F3F61} = {DA72FD0C-6B60-455A-9A07-7CA9D9064402}
{36F12A1C-00C2-4049-8A0C-7595C6185F01} = {DA72FD0C-6B60-455A-9A07-7CA9D9064402}
{C86FB6E5-3024-4028-9BC0-602AEBA65E5B} = {DA72FD0C-6B60-455A-9A07-7CA9D9064402}
{40901586-F39F-4959-89D5-61FFC17854CE} = {8C0E6601-CC7E-4A02-91B1-1E2BF93DBF9E}
{73119C3B-D54A-4930-AACE-CD2156B7CCF5} = {17EC73D7-89DD-4A26-BC01-F34900140409}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FF622C8D-0862-46BD-806B-1624BEC226E5}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Steeltoe.Extensions.Configuration;

internal static class ConfigurationDictionaryExtensions
{
public static IEnumerable<string> Filter(this IDictionary<string, string> configData, string keyPrefix, string keySuffix, string keyValue)
{
var results = new List<string>();

foreach (KeyValuePair<string, string> pair in configData)
{
if (pair.Key.StartsWith(keyPrefix, StringComparison.OrdinalIgnoreCase) && pair.Key.EndsWith(keySuffix, StringComparison.OrdinalIgnoreCase) &&
pair.Value == keyValue)
{
results.Add(ConfigurationPath.GetParentPath(pair.Key));
}
}

return results;
}

public static IEnumerable<string> Filter(this IDictionary<string, string> configData, string keyPrefix)
{
return
from pair in configData where pair.Key.StartsWith(keyPrefix, StringComparison.OrdinalIgnoreCase) select ConfigurationPath.GetParentPath(pair.Key);
}

public static void ForEach(this IEnumerable<string> keys, Action<string> mapping)
{
foreach (string key in keys)
{
mapping(key);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using Microsoft.Extensions.Configuration;
using System.Collections.Generic;

namespace Steeltoe.Extensions.Configuration;

internal abstract class ConfigurationDictionaryMapper
{
public string BindingKey { get; }

public string ToPrefix { get; }

public IDictionary<string, string> ConfigData { get; }

protected ConfigurationDictionaryMapper(IDictionary<string, string> configData, string bindingKey, params string[] toPrefix)
{
ConfigData = configData;
BindingKey = !string.IsNullOrEmpty(bindingKey) ? bindingKey + ConfigurationPath.KeyDelimiter : string.Empty;

if (toPrefix.Length > 0)
{
ToPrefix = string.Join(ConfigurationPath.KeyDelimiter, toPrefix) + ConfigurationPath.KeyDelimiter;
}
}

public void MapFromTo(string existingKey, string newKey)
{
if (ConfigData.TryGetValue(BindingKey + existingKey, out string value))
{
if (ToPrefix != null)
{
ConfigData[ToPrefix + newKey] = value;
}
else
{
ConfigData[newKey] = value;
}
}
}

public void MapFromTo(string existingKey, params string[] newKeyPath)
{
if (ConfigData.TryGetValue(BindingKey + existingKey, out string value))
{
string newKey = string.Join(ConfigurationPath.KeyDelimiter, newKeyPath);

if (ToPrefix != null)
{
ConfigData[ToPrefix + newKey] = value;
}
else
{
ConfigData[newKey] = value;
}
}
}

public void AddKeyValue(string newKey, string value)
{
ConfigData.Add(ToPrefix + newKey, value);
}

public string Get(string key)
{
return Get(key, null);
}

public string Get(string key, string defaultValue)
{
_ = ConfigData.TryGetValue(BindingKey + key, out string result);
return result ?? defaultValue;
}
}
12 changes: 12 additions & 0 deletions src/Configuration/src/Abstractions/IConfigurationPostProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;

namespace Steeltoe.Extensions.Configuration;

internal interface IConfigurationPostProcessor
{
void PostProcessConfiguration(PostProcessorConfigurationProvider provider, IDictionary<string, string> configData);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using Microsoft.Extensions.Configuration;

namespace Steeltoe.Extensions.Configuration;

internal abstract class PostProcessorConfigurationProvider : ConfigurationProvider
{
public PostProcessorConfigurationSource Source { get; }

protected PostProcessorConfigurationProvider(PostProcessorConfigurationSource source)
{
Source = source;
}

protected virtual void PostProcessConfiguration()
{
foreach (IConfigurationPostProcessor processor in Source.RegisteredProcessors)
{
processor.PostProcessConfiguration(this, Data);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;

namespace Steeltoe.Extensions.Configuration;

internal abstract class PostProcessorConfigurationSource
{
public IList<IConfigurationPostProcessor> RegisteredProcessors { get; }

public IConfigurationRoot ParentConfiguration { get; set; }

protected PostProcessorConfigurationSource()
{
RegisteredProcessors = new List<IConfigurationPostProcessor>();
}

public void RegisterPostProcessor(IConfigurationPostProcessor processor)
{
if (processor == null)
{
throw new ArgumentNullException(nameof(processor));
}

RegisteredProcessors.Add(processor);
}
}
8 changes: 8 additions & 0 deletions src/Configuration/src/Abstractions/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding")]
[assembly: InternalsVisibleTo("Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding.Test")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using Microsoft.Extensions.Configuration;
using System;

namespace Steeltoe.Extensions.Configuration.Kubernetes.ServiceBinding;

/// <summary>
/// Extension methods for registering Kubernetes <see cref="ServiceBindingConfigurationProvider" /> with <see cref="IConfigurationBuilder" />.
/// </summary>
public static class ConfigurationBuilderExtensions
{
/// <summary>
/// Adds configuration using files from the directory path specified by the environment variable "SERVICE_BINDING_ROOT". File name and directory paths
/// are used as the key, and the file contents are used as the values.
/// </summary>
/// <param name="builder">
/// The <see cref="IConfigurationBuilder" /> to add to.
/// </param>
/// <returns>
/// The <see cref="IConfigurationBuilder" />.
/// </returns>
public static IConfigurationBuilder AddKubernetesServiceBindings(this IConfigurationBuilder builder)
{
var source = new ServiceBindingConfigurationSource();
return RegisterPostProcessors(builder, source);
}

/// <summary>
/// Adds configuration using files from the directory path specified by the environment variable "SERVICE_BINDING_ROOT". File name and directory paths
/// are used as the key, and the file contents are used as the values.
/// </summary>
/// <param name="builder">
/// The <see cref="IConfigurationBuilder" /> to add to.
/// </param>
/// <param name="optional">
/// Whether the directory path is optional.
/// </param>
/// ///
/// <returns>
/// The <see cref="IConfigurationBuilder" />.
/// </returns>
public static IConfigurationBuilder AddKubernetesServiceBindings(this IConfigurationBuilder builder, bool optional)
{
var source = new ServiceBindingConfigurationSource
{
Optional = optional
};

return RegisterPostProcessors(builder, source);
}

/// <summary>
/// Adds configuration using files from the directory path specified by the environment variable "SERVICE_BINDING_ROOT". File name and directory paths
/// are used as the key, and the file contents are used as the values.
/// </summary>
/// <param name="builder">
/// The <see cref="IConfigurationBuilder" /> to add to.
/// </param>
/// <param name="optional">
/// Whether the directory path is optional.
/// </param>
/// ///
/// <param name="reloadOnChange">
/// Whether the configuration should be reloaded if the files are changed, added or removed.
/// </param>
/// <returns>
/// The <see cref="IConfigurationBuilder" />.
/// </returns>
public static IConfigurationBuilder AddKubernetesServiceBindings(this IConfigurationBuilder builder, bool optional, bool reloadOnChange)
{
var source = new ServiceBindingConfigurationSource
{
Optional = optional,
ReloadOnChange = reloadOnChange
};

return RegisterPostProcessors(builder, source);
}

/// <summary>
/// Adds configuration using files from the directory path specified by the environment variable "SERVICE_BINDING_ROOT". File name and directory paths
/// are used as the key, and the file contents are used as the values.
/// </summary>
/// <param name="builder">
/// The <see cref="IConfigurationBuilder" /> to add to.
/// </param>
/// <param name="optional">
/// Whether the directory path is optional.
/// </param>
/// ///
/// <param name="reloadOnChange">
/// Whether the configuration should be reloaded if the files are changed, added or removed.
/// </param>
/// <param name="ignoreKeyPredicate">
/// A predicate which is called before adding a key to the configuration. If it returns false, the key will be ignored.
/// </param>
/// <returns>
/// The <see cref="IConfigurationBuilder" />.
/// </returns>
public static IConfigurationBuilder AddKubernetesServiceBindings(this IConfigurationBuilder builder, bool optional, bool reloadOnChange, Predicate<string> ignoreKeyPredicate)
{
var source = new ServiceBindingConfigurationSource
{
Optional = optional,
ReloadOnChange = reloadOnChange,
IgnoreKeyPredicate = ignoreKeyPredicate
};

return RegisterPostProcessors(builder, source);
}

private static IConfigurationBuilder RegisterPostProcessors(IConfigurationBuilder builder, ServiceBindingConfigurationSource source)
{
source.RegisterPostProcessor(new ArtemisPostProcessor());
source.RegisterPostProcessor(new CassandraPostProcessor());
source.RegisterPostProcessor(new ConfigServerPostProcessor());
source.RegisterPostProcessor(new CouchbasePostProcessor());
source.RegisterPostProcessor(new DB2PostProcessor());
source.RegisterPostProcessor(new ElasticSearchPostProcessor());
source.RegisterPostProcessor(new EurekaPostProcessor());
source.RegisterPostProcessor(new KafkaPostProcessor());
source.RegisterPostProcessor(new LdapPostProcessor());
source.RegisterPostProcessor(new MongoDbPostProcessor());
source.RegisterPostProcessor(new MySqlPostProcessor());
source.RegisterPostProcessor(new Neo4JPostProcessor());
source.RegisterPostProcessor(new OraclePostProcessor());
source.RegisterPostProcessor(new PostgreSqlPostProcessor());
source.RegisterPostProcessor(new RabbitMQPostProcessor());
source.RegisterPostProcessor(new RedisPostProcessor());
source.RegisterPostProcessor(new SapHanaPostProcessor());
source.RegisterPostProcessor(new SpringSecurityOAuth2PostProcessor());
source.RegisterPostProcessor(new SqlServerPostProcessor());
source.RegisterPostProcessor(new VaultPostProcessor());
source.RegisterPostProcessor(new WavefrontPostProcessor());

// Legacy Connector Post Processors
source.RegisterPostProcessor(new RabbitMQLegacyConnectorPostProcessor());
source.RegisterPostProcessor(new MySqlLegacyConnectorPostProcessor());
source.RegisterPostProcessor(new PostgreSqlLegacyConnectorPostProcessor());
builder.Add(source);
return builder;
}
}
Loading

0 comments on commit 38b62ab

Please sign in to comment.