Skip to content

Commit 01d8ea2

Browse files
author
Stephane Royer
committed
feat: Add configuration adapter and enhance sample project with new input files and settings
1 parent dc7c247 commit 01d8ea2

File tree

11 files changed

+212
-6
lines changed

11 files changed

+212
-6
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using System.Linq;
3+
using System.Text.Json.Nodes;
4+
using Microsoft.Extensions.Configuration;
5+
using Paillave.Etl.Core;
6+
7+
namespace Paillave.Etl.FromConfigurationConnectors;
8+
9+
public class ConfigurationAdapter(IConfiguration configuration, ConfigurationFileValueConnectorParser parser, Func<string, string> resolveSensitiveValues)
10+
{
11+
private const string code = "DEVITEMSOURCE";
12+
public IFileValueProvider GetFileValueProvider(string sectionName)
13+
=> CreateFileValueConnectors(sectionName, ConnectorType.Provider).GetProvider(code);
14+
public IFileValueProcessor GetFileValueProcessor(string sectionName)
15+
=> CreateFileValueConnectors(sectionName, ConnectorType.Processor).GetProcessor(code);
16+
17+
private IFileValueConnectors CreateFileValueConnectors(string sectionName, ConnectorType connectorType)
18+
{
19+
IConfigurationSection configurationSection = configuration.GetSection(sectionName);
20+
var section = configurationSection.ToJsonNode();
21+
var definition = BuildConnectorConfiguration(section, code, connectorType) ?? throw new InvalidOperationException("No configuration found for a connector");
22+
var fileValueConnectors = parser.GetConnectors(definition, resolveSensitiveValues);
23+
return fileValueConnectors;
24+
}
25+
private enum ConnectorType
26+
{
27+
Provider,
28+
Processor
29+
}
30+
private string? BuildConnectorConfiguration(JsonNode? configuration, string code, ConnectorType connectorType)
31+
{
32+
if (configuration is null)
33+
return null;
34+
35+
var obj = new JsonObject()
36+
{
37+
["src"] = new JsonObject()
38+
{
39+
["Type"] = configuration?["Type"]?.DeepClone(),
40+
["Connection"] = configuration?["Connection"]?.DeepClone()
41+
}
42+
};
43+
switch (connectorType)
44+
{
45+
case ConnectorType.Provider:
46+
obj["src"]!["Providers"] = new JsonObject()
47+
{
48+
[code] = configuration?["Provider"]?.DeepClone() ?? new JsonObject()
49+
};
50+
break;
51+
case ConnectorType.Processor:
52+
obj["src"]!["Processors"] = new JsonObject()
53+
{
54+
[code] = configuration?["Processor"]?.DeepClone() ?? new JsonObject()
55+
};
56+
break;
57+
}
58+
return obj.ToJsonString();
59+
}
60+
}
61+
public static class ConfigurationJsonExtensions
62+
{
63+
public static JsonNode? ToJsonNode(this IConfigurationSection section)
64+
{
65+
if (!section.Exists()) return null;
66+
67+
var children = section.GetChildren().ToList();
68+
if (children.Count == 0)
69+
{
70+
return section.Value is null ? JsonValue.Create((string?)null) : JsonValue.Create(section.Value);
71+
}
72+
73+
if (children.All(c => int.TryParse(c.Key, out _)))
74+
{
75+
var arr = new JsonArray();
76+
foreach (var child in children.OrderBy(c => int.Parse(c.Key)))
77+
arr.Add(child.ToJsonNode());
78+
return arr;
79+
}
80+
81+
var obj = new JsonObject();
82+
foreach (var child in children)
83+
obj[child.Key] = child.ToJsonNode();
84+
return obj;
85+
}
86+
}

src/Paillave.Etl.FromConfigurationConnectors/Paillave.Etl.FromConfigurationConnectors.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<ProjectReference Include="..\Paillave.Etl\Paillave.Etl.csproj" />
1212
</ItemGroup>
1313
<ItemGroup>
14-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" allowedVersions="13.0.1"/>
15-
<PackageReference Include="NJsonSchema" Version="11.1.0" allowedVersions="10.6.6"/>
14+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.5" />
15+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" allowedVersions="13.0.1" />
16+
<PackageReference Include="NJsonSchema" Version="11.1.0" allowedVersions="10.6.6" />
1617
</ItemGroup>
1718
</Project>

src/Paillave.Etl/Core/FileValueProviderBase.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
24
using System.Text.Json.Nodes;
35
using System.Threading;
46

@@ -14,15 +16,25 @@ namespace Paillave.Etl.Core;
1416

1517
public virtual string TypeName => this.GetType().Name;
1618

17-
public void Provide(object input, Action<IFileValue, FileReference> pushFileValue, CancellationToken cancellationToken)
19+
public void Provide(object? input, Action<IFileValue, FileReference> pushFileValue, CancellationToken cancellationToken)
1820
=> Provide(input, pushFileValue, connectionParameters, providerParameters, cancellationToken);
19-
public void Provide(object input, Action<IFileValue> pushFileValue, CancellationToken cancellationToken)
21+
public void Provide(object? input, Action<IFileValue> pushFileValue, CancellationToken cancellationToken)
2022
=> Provide(input, (fileValue, FileReference) => pushFileValue(fileValue), cancellationToken);
21-
protected abstract void Provide(object input, Action<IFileValue, FileReference> pushFileValue, TConnectionParameters connectionParameters, TProviderParameters providerParameters, CancellationToken cancellationToken);
23+
protected abstract void Provide(object? input, Action<IFileValue, FileReference> pushFileValue, TConnectionParameters connectionParameters, TProviderParameters providerParameters, CancellationToken cancellationToken);
2224
public void Test() => Test(connectionParameters, providerParameters);
2325
protected abstract void Test(TConnectionParameters connectionParameters, TProviderParameters providerParameters);
2426
public void PushValues(object input, Action<IFileValue> push, CancellationToken cancellationToken, IExecutionContext context)
2527
=> Provide(input, push, cancellationToken);
2628

2729
public abstract IFileValue Provide(JsonNode? fileSpecific);
30+
31+
public IAsyncEnumerable<FileReference> Provide(object? input = null, CancellationToken cancellationToken = default)
32+
{
33+
throw new NotImplementedException();
34+
}
35+
36+
public Stream Open(JsonNode fileSpecific)
37+
{
38+
throw new NotImplementedException();
39+
}
2840
}

src/Paillave.Etl/Core/IFileValueProvider.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
24
using System.Text.Json.Nodes;
35
using System.Threading;
46

@@ -9,7 +11,9 @@ public interface IFileValueProvider
911
string Code { get; }
1012
ProcessImpact PerformanceImpact { get; }
1113
ProcessImpact MemoryFootPrint { get; }
12-
void Provide(object input, Action<IFileValue, FileReference> pushFileValue, CancellationToken cancellationToken);
14+
void Provide(object? input, Action<IFileValue, FileReference> pushFileValue, CancellationToken cancellationToken);
1315
IFileValue Provide(JsonNode fileSpecific);
16+
// IAsyncEnumerable<FileReference> Provide(object? input = null, CancellationToken cancellationToken = default);
17+
// Stream Open(JsonNode fileSpecific);
1418
void Test();
1519
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SicavCode,SicavName,SicavType,PortfolioCode,PortfolioName
2+
S1,Sicav1,UCITS,P1,Portfolio1
3+
S2,Sicav2,AIFM,P2,Portfolio2
4+
S1,Sicav1,UCITS,P3,Portfolio3
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
PortfolioCode,SecurityCode,Isin,SecurityName,SecurityClass,Issuer,Date,Value
2+
P1,S1,ISIN1,Security1,A,,20201020,10
3+
P1,S2,ISIN2,Security2,B,,20201020,11
4+
P1,S3,,Security3,,Issuer1,20201020,12
5+
P2,S4,ISIN4,Security4,C,,20201020,20
6+
P2,S2,ISIN2,Security2,B,,20201020,21
7+
P2,S3,,Security3,,Issuer1,20201020,22
8+
P2,S2,ISIN2,Security2,B,,20201020,31
9+
P2,S3,,Security3,,Issuer1,20201020,32
10+
P3,S1,ISIN1,Security1,A,,20201020,42
11+
P3,S2,ISIN2,Security2,B,,20201020,31
12+
P3,S3,,Security3,,Issuer1,20201020,32
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
PortfolioCode,SecurityCode,Isin,SecurityName,SecurityClass,Issuer,Date,Value
2+
P1,S1,ISIN1,Security1,A,,20201021,11
3+
P1,S2,ISIN2,Security2,B,,20201021,12
4+
P1,S3,,Security3,,Issuer1,20201021,13
5+
P2,S5,ISIN5,Security5,D,,20201021,21
6+
P2,S2,ISIN2,Security2,B,,20201021,22
7+
P2,S3,,Security3,,Issuer1,20201021,33
8+
P2,S3,,Security3,,Issuer1,20201021,33
9+
P2,S2,ISIN2,Security2,B,,20201021,32
10+
P2,S3,,Security3,,Issuer1,20201021,4
11+
P3,S2,ISIN2,Security2,B,,20201021,32
12+
P3,S3,,Security3,,Issuer1,20201021,4
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Code,Date,Weight
2+
P1,"Tue 20 Oct, 2020",33
3+
P1,"Wed 21 Oct, 2020",36
4+
P2,"Tue 20 Oct, 2020",126
5+
P2,"Wed 21 Oct, 2020",145
6+
P3,"Tue 20 Oct, 2020",105
7+
P3,"Wed 21 Oct, 2020",36

src/Tutorials/Paillave.Etl.Samples/Paillave.Etl.Samples.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
<PrivateAssets>all</PrivateAssets>
2727
</PackageReference>
2828
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
29+
<PackageReference Include="Microsoft.Extensions.Configuration.KeyPerFile" Version="9.0.0" />
30+
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.0" />
31+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
32+
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="9.0.0" />
2933
</ItemGroup>
3034

3135
<PropertyGroup>

src/Tutorials/Paillave.Etl.Samples/Program2.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
using Paillave.Etl.Core;
1111
using Microsoft.Extensions.DependencyInjection;
1212
using Microsoft.EntityFrameworkCore;
13+
using Microsoft.Extensions.Configuration;
14+
using Paillave.Etl.FromConfigurationConnectors;
15+
using Paillave.Etl.Mail;
16+
using Paillave.Etl.GraphApi;
1317

1418
namespace Paillave.Etl.Samples;
1519

@@ -35,6 +39,30 @@ static async Task Main(string[] args)
3539
// /// <returns></returns>
3640
static async Task SimplyImportAsync(string[] args)
3741
{
42+
43+
44+
var configuration = ApplicationConfigurationBuilder.GetConfiguration(args);
45+
46+
47+
var configAdapter = new ConfigurationAdapter(
48+
configuration,
49+
new ConfigurationFileValueConnectorParser(
50+
new MailProviderProcessorAdapter(),
51+
new FileSystemProviderProcessorAdapter(),
52+
new GraphApiProviderProcessorAdapter()),
53+
s => s);
54+
55+
var provider = configAdapter.GetFileValueProvider("MyProvider");
56+
var processor = configAdapter.GetFileValueProcessor("MyProcessor");
57+
provider.Provide(new(), (fv, fr) =>
58+
{
59+
Console.WriteLine(fv.Name);
60+
processor.Process(fv, i => { }, default);
61+
}, default);
62+
63+
processor.Process(new InMemoryFileValue(new MemoryStream(), "TestFile.txt"), i => { }, default);
64+
65+
3866
var services = new ServiceCollection()
3967
.AddPooledDbContextFactory<DataAccess.TestDbContext>(options => options.UseSqlServer(@"Server=localhost,1433;Initial Catalog=TestEtl;Persist Security Info=False;User ID=SA;Password=<YourStrong@Passw0rd>;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=true;Connection Timeout=300;", options => options
4068
.CommandTimeout(2000)
@@ -168,4 +196,22 @@ static async Task SimplyImportAsync(string[] args)
168196
// var res = await processRunner.ExecuteAsync(args, executionOptions);
169197
// }
170198
// }
199+
}
200+
201+
public static class ApplicationConfigurationBuilder
202+
{
203+
public static IConfigurationRoot GetConfiguration(string[]? args = null) => new ConfigurationBuilder()
204+
.SetBasePath(Directory.GetCurrentDirectory())
205+
.AddJsonFile("appsettings.json", true, true)
206+
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true, true)
207+
.AddKeyPerFile("appsettings", true, true)
208+
.AddEnvironmentVariables()
209+
.AddEnvironmentVariables("SAMPLEETLNET_")
210+
.AddUserSecrets(typeof(Program).Assembly)
211+
.AddCommandLine(args ?? [], new Dictionary<string, string>
212+
{
213+
["-cnx"] = "ConnectionStrings:SqlServer",
214+
["--connectionString"] = "ConnectionStrings:SqlServer"
215+
})
216+
.Build();
171217
}

0 commit comments

Comments
 (0)