diff --git a/casdk-docs/docs/tutorial-extras/configuration.md b/casdk-docs/docs/tutorial-extras/configuration.md index c65aa44f2..e7a12756f 100644 --- a/casdk-docs/docs/tutorial-extras/configuration.md +++ b/casdk-docs/docs/tutorial-extras/configuration.md @@ -202,6 +202,11 @@ where the assembly `CarbonAware.WebApi.dll` is located under `data-sources/json` directory. For instance, if the application is installed under `/app`, copy the file to `/app/data-sources/json`. +Emission data in JSON is cached by default, it means original data would be handled +even if JSON is updated. +You need to set `DataSources__Configurations__JSON__CacheJsonData=false` +if you want to handle updated data. + ```sh cp /mycustomfile.json /app/data-sources/json export DataSources__Configurations=Json diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/mock/JsonDataSourceMocker.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/mock/JsonDataSourceMocker.cs index 5e09ba3de..808e3df9b 100644 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/mock/JsonDataSourceMocker.cs +++ b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/mock/JsonDataSourceMocker.cs @@ -4,7 +4,7 @@ using System.Text.Json; namespace CarbonAware.DataSources.Json.Mocks; -internal class JsonDataSourceMocker : IDataSourceMocker +public class JsonDataSourceMocker : IDataSourceMocker { public JsonDataSourceMocker() { } diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/Configuration/JsonDataSourceConfiguration.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/Configuration/JsonDataSourceConfiguration.cs index 2c69e6be8..b54a3116d 100644 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/Configuration/JsonDataSourceConfiguration.cs +++ b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/Configuration/JsonDataSourceConfiguration.cs @@ -30,11 +30,14 @@ public string DataFileLocation } } + public bool CacheJsonData { get; set; } + public JsonDataSourceConfiguration() { var assemblyPath = Assembly.GetExecutingAssembly().Location; assemblyDirectory = Path.GetDirectoryName(assemblyPath)!; DataFileLocation = DefaultDataFile; + CacheJsonData = true; } private static bool IsValidDirPath(string fileName) diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/JsonDataSource.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/JsonDataSource.cs index c62735dcb..c4943f558 100644 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/JsonDataSource.cs +++ b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/src/JsonDataSource.cs @@ -104,11 +104,11 @@ private IEnumerable FilterByLocation(IEnumerable d } using Stream stream = GetStreamFromFileLocation(); var jsonObject = await JsonSerializer.DeserializeAsync(stream); - if (_emissionsData is null || !_emissionsData.Any()) + if (_configuration.CacheJsonData && (_emissionsData is null || !_emissionsData.Any())) { _emissionsData = jsonObject?.Emissions; } - return _emissionsData; + return jsonObject?.Emissions; } private Stream GetStreamFromFileLocation() diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/CarbonAware.DataSources.Json.Tests.csproj b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/CarbonAware.DataSources.Json.Tests.csproj index 065ebeee5..c54355685 100644 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/CarbonAware.DataSources.Json.Tests.csproj +++ b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/CarbonAware.DataSources.Json.Tests.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -8,10 +8,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -23,6 +23,7 @@ + diff --git a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/JsonDataSourceTests.cs b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/JsonDataSourceTests.cs index 4e204cec3..68ea73e24 100644 --- a/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/JsonDataSourceTests.cs +++ b/src/CarbonAware.DataSources/CarbonAware.DataSources.Json/test/JsonDataSourceTests.cs @@ -9,6 +9,7 @@ using Moq.Protected; using Microsoft.Extensions.Options; using CarbonAware.DataSources.Json.Configuration; +using CarbonAware.DataSources.Json.Mocks; namespace CarbonAware.DataSources.Json.Tests; @@ -105,6 +106,56 @@ public async Task GetCarbonIntensityAsync_ReturnsEmptyEmissionData() Assert.That(!result.Any(), Is.True); } + [TestCase(true, TestName = "Test JsonDataSource with caching")] + [TestCase(false, TestName = "Test JsonDataSource without caching")] + public async Task GetCarbonIntensityAsync_CacheEmissionData(bool cache) + { + var logger = Mock.Of>(); + + var monitor = new Mock>(); + var config = new JsonDataSourceConfiguration + { + CacheJsonData = cache + }; + monitor.Setup(m => m.CurrentValue).Returns(config); + var dataSource = new JsonDataSource(logger, monitor.Object); + + JsonDataSourceMocker dsMocker = new(); + + var today = DateTimeOffset.Now; + var todayEnd = today.AddMinutes(30); + var todayLocation = new Location() { Name = "japan" }; + dsMocker.SetupDataMock(today, todayEnd, todayLocation.Name); + var result1 = await dataSource.GetCarbonIntensityAsync(todayLocation, today, todayEnd); + Assert.AreEqual(1, result1.Count()); + foreach (var r in result1) + { + Assert.AreEqual(r.Location, todayLocation.Name); + } + + var yesterday = today.AddDays(-1); + var yesterdayEnd = yesterday.AddMinutes(30); + var yesterdayLocation = new Location() { Name = "uk" }; + dsMocker.SetupDataMock(yesterday, yesterdayEnd, yesterdayLocation.Name); + if (cache) + { + var result2 = await dataSource.GetCarbonIntensityAsync(todayLocation, today, todayEnd); + Assert.AreEqual(1, result2.Count()); + foreach (var r in result2) + { + Assert.AreEqual(r.Location, todayLocation.Name); + } + } else + { + var result2 = await dataSource.GetCarbonIntensityAsync(yesterdayLocation, yesterday, yesterdayEnd); + Assert.AreEqual(1, result2.Count()); + foreach (var r in result2) + { + Assert.AreEqual(r.Location, yesterdayLocation.Name); + } + } + } + private Mock SetupMockDataSource() { var logger = Mock.Of>(); var monitor = Mock.Of>();