Skip to content

Commit

Permalink
Implement Dynamic DataSource registration
Browse files Browse the repository at this point in the history
Signed-off-by: Bill DeRusha <[email protected]>
  • Loading branch information
bderusha committed Jun 29, 2023
1 parent b3b3189 commit 7065dce
Show file tree
Hide file tree
Showing 48 changed files with 670 additions and 611 deletions.
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"uriFormat": "%s/swagger"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_HOSTBUILDER__RELOADCONFIGONCHANGE": "false"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
<ItemGroup>
<ProjectReference
Include="..\..\..\CarbonAware.DataSources\CarbonAware.DataSources.Json\mock\CarbonAware.DataSources.Json.Mocks.csproj" />
<ProjectReference
Include="..\..\..\CarbonAware.DataSources\CarbonAware.DataSources.Registration\CarbonAware.DataSources.Registration.csproj" />
<ProjectReference
Include="..\..\..\CarbonAware.DataSources\CarbonAware.DataSources.WattTime\mock\CarbonAware.DataSources.WattTime.Mocks.csproj" />
<ProjectReference
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using CarbonAware.DataSources.Configuration;
using NUnit.Framework;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CarbonAware.DataSources.Configuration;
using NUnit.Framework;
using NUnit.Framework;
using System.Text.Json.Nodes;

namespace CarbonAware.CLI.IntegrationTests.Commands.EmissionsForecasts;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CarbonAware.DataSources.Configuration;
using NUnit.Framework;
using NUnit.Framework;
using System.Text.Json;

namespace CarbonAware.CLI.IntegrationTests.Commands.Location;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CarbonAware.DataSources.Configuration;
using CarbonAware.Interfaces;
using CarbonAware.Interfaces;
using CarbonAware.DataSources.ElectricityMaps.Mocks;
using CarbonAware.DataSources.ElectricityMapsFree.Mocks;
using CarbonAware.DataSources.Json.Mocks;
Expand All @@ -11,6 +10,15 @@

namespace CarbonAware.CLI.IntegrationTests;

public enum DataSourceType
{
None,
WattTime,
JSON,
ElectricityMaps,
ElectricityMapsFree,
}

/// <summary>
/// A base class that does all the common setup for the Integration Testing
/// Overrides WebAPI factory by switching out different configurations via _datasource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<ItemGroup>
<InternalsVisibleTo Include="CarbonAware.DataSources.ElectricityMaps.Mocks" />
<InternalsVisibleTo Include="CarbonAware.DataSources.ElectricityMaps.Tests" />
<InternalsVisibleTo Include="CarbonAware.DataSources.Registration" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using CarbonAware.Configuration;
using CarbonAware.DataSources.ElectricityMaps.Client;
using CarbonAware.DataSources.ElectricityMaps.Configuration;
using CarbonAware.DataSources.ElectricityMaps.Model;
using CarbonAware.Exceptions;
using CarbonAware.Interfaces;
using CarbonAware.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Net;

namespace CarbonAware.DataSources.ElectricityMaps;

Expand Down Expand Up @@ -40,6 +45,21 @@ public ElectricityMapsDataSource(ILogger<ElectricityMapsDataSource> logger, IEle
this._locationSource = locationSource;
}

public static IServiceCollection ConfigureDI<T>(IServiceCollection services, DataSourcesConfiguration dataSourcesConfig)
where T : IDataSource
{
var configSection = dataSourcesConfig.ConfigurationSection<T>();
AddElectricityMapsClient(services, configSection);
try
{
services.TryAddSingleton(typeof(T), typeof(ElectricityMapsDataSource));
} catch (Exception ex)
{
throw new ArgumentException($"ElectricityMapsDataSource is not a supported {typeof(T).Name} data source.", ex);
}
return services;
}

/// <inheritdoc />
public async Task<EmissionsForecast> GetCurrentCarbonIntensityForecastAsync(Location location)
{
Expand Down Expand Up @@ -176,4 +196,33 @@ private TimeSpan GetDurationFromHistoryDataPoints(IEnumerable<CarbonIntensity> d
// the absolute value of the TimeSpan between the two points.
return first.DateTime.Subtract(second.DateTime).Duration();
}

private static void AddElectricityMapsClient(IServiceCollection services, IConfigurationSection configSection)
{
services.Configure<ElectricityMapsClientConfiguration>(c =>
{
configSection.Bind(c);
});

var httpClientBuilder = services.AddHttpClient<ElectricityMapsClient>(IElectricityMapsClient.NamedClient);

var Proxy = configSection.GetSection("Proxy").Get<WebProxyConfiguration>();
if (Proxy?.UseProxy == true)
{
if (String.IsNullOrEmpty(Proxy.Url))
{
throw new ConfigurationException("Proxy Url is not configured.");
}
httpClientBuilder.ConfigurePrimaryHttpMessageHandler(() =>
new HttpClientHandler() {
Proxy = new WebProxy {
Address = new Uri(Proxy.Url),
Credentials = new NetworkCredential(Proxy.Username, Proxy.Password),
BypassProxyOnLocal = true
}
}
);
}
services.TryAddSingleton<IElectricityMapsClient, ElectricityMapsClient>();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using CarbonAware.Configuration;
using CarbonAware.DataSources.ElectricityMaps.Client;
using CarbonAware.DataSources.ElectricityMaps.Model;
using CarbonAware.Exceptions;
using CarbonAware.Interfaces;
using CarbonAware.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Moq;

Expand All @@ -23,6 +26,14 @@ class ElectricityMapsDataSourceTests
private static string _defaultLongitude => _defaultLocation.Longitude.ToString() ?? "";
private static DateTimeOffset _defaultDataStartTime = new DateTimeOffset(2022, 4, 18, 12, 32, 42, TimeSpan.FromHours(-6));

private readonly string TypeKey = $"Configurations:ElectricityMaps:Type";
private readonly string UsernameKey = $"Configurations:ElectricityMaps:Username";
private readonly string PasswordKey = $"Configurations:ElectricityMaps:Password";
private readonly string UseProxyKey = $"Configurations:ElectricityMaps:Proxy:UseProxy";
private readonly string ProxyUrlKey = $"Configurations:ElectricityMaps:Proxy:Url";
private readonly string ProxyUsernameKey = $"Configurations:ElectricityMaps:Proxy:Username";
private readonly string ProxyPasswordKey = $"Configurations:ElectricityMaps:Proxy:Password";

[SetUp]
public void Setup()
{
Expand Down Expand Up @@ -324,4 +335,79 @@ public async Task GetDurationBetweenHistoryDataPoints_WhenMultipleDataPoints_Ret
Assert.IsNotNull(second);
Assert.That(second.Duration, Is.EqualTo(expectedDuration));
}

[Test]
public void ConfigureDI_ClientProxyTest_With_Missing_ProxyURL_ThrowsException()
{
// Arrange
var inMemorySettings = new Dictionary<string, string> {
{ TypeKey, "ElectricityMaps" },
{ UsernameKey, "testUsername" },
{ PasswordKey, "testPassword123!" },
{ UseProxyKey, "true" },
};

var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();

var dataSourceConfig = new DataSourcesConfiguration()
{
EmissionsDataSource = "ElectricityMaps",
ForecastDataSource = "ElectricityMaps",
Section = configuration.GetSection("Configurations")
};

var serviceCollection = new ServiceCollection();

// Act & Assert
Assert.Throws<ConfigurationException>(() => ElectricityMapsDataSource.ConfigureDI<IEmissionsDataSource>(serviceCollection, dataSourceConfig));
Assert.Throws<ConfigurationException>(() => ElectricityMapsDataSource.ConfigureDI<IForecastDataSource>(serviceCollection, dataSourceConfig));
}

[TestCase(true, TestName = "ClientProxyTest, successful: denotes adding ElectricityMaps data sources using proxy.")]
[TestCase(false, TestName = "ClientProxyTest, successful: denotes adding ElectricityMaps data sources without using proxy.")]
public void ConfigureDI_ClientProxyTest_AddsDataSource(bool withProxyUrl)
{
// Arrange
var inMemorySettings = new Dictionary<string, string> {
{ TypeKey, "ElectricityMaps" },
{ UsernameKey, "testUsername" },
{ PasswordKey, "testPassword123!" },
{ UseProxyKey, withProxyUrl.ToString() },
};

if (withProxyUrl)
{
inMemorySettings.Add(ProxyUrlKey, "http://10.10.10.1");
inMemorySettings.Add(ProxyUsernameKey, "proxyUsername");
inMemorySettings.Add(ProxyPasswordKey, "proxyPassword");
}

var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();

var dataSourceConfig = new DataSourcesConfiguration()
{
EmissionsDataSource = "ElectricityMaps",
ForecastDataSource = "ElectricityMaps",
Section = configuration.GetSection("Configurations")
};

var serviceCollection = new ServiceCollection();
var emissionsDescriptor = new ServiceDescriptor(typeof(IEmissionsDataSource), typeof(ElectricityMapsDataSource), ServiceLifetime.Singleton);
var forecastDescriptor = new ServiceDescriptor(typeof(IForecastDataSource), typeof(ElectricityMapsDataSource), ServiceLifetime.Singleton);

Assert.That(!serviceCollection.Any(i => i.ToString() == emissionsDescriptor.ToString()));
Assert.That(!serviceCollection.Any(i => i.ToString() == forecastDescriptor.ToString()));

// Act
ElectricityMapsDataSource.ConfigureDI<IEmissionsDataSource>(serviceCollection, dataSourceConfig);
ElectricityMapsDataSource.ConfigureDI<IForecastDataSource>(serviceCollection, dataSourceConfig);

// Assert
Assert.That(serviceCollection.Any(i => i.ToString() == emissionsDescriptor.ToString()));
Assert.That(serviceCollection.Any(i => i.ToString() == forecastDescriptor.ToString()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<ItemGroup>
<InternalsVisibleTo Include="CarbonAware.CLI.IntegrationTests" />
<InternalsVisibleTo Include="CarbonAware.WebApi.IntegrationTests" />
</ItemGroup>

</Project>
Loading

0 comments on commit 7065dce

Please sign in to comment.