Refactor YAML parsing logic and settings handling across Client and Server projects, improve request building in the client.
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace VirtualDDNSRouter.Client.Context;
|
||||||
|
|
||||||
|
[YamlStaticContext]
|
||||||
|
[YamlSerializable(typeof(Settings))]
|
||||||
|
public partial class YamlStaticContextClient : StaticContext
|
||||||
|
{
|
||||||
|
}
|
@@ -1,3 +1,4 @@
|
|||||||
|
using VirtualDDNSRouter.Client.Context;
|
||||||
using YamlDotNet.Serialization;
|
using YamlDotNet.Serialization;
|
||||||
using YamlDotNet.Serialization.NamingConventions;
|
using YamlDotNet.Serialization.NamingConventions;
|
||||||
using Settings = VirtualDDNSRouter.Client.Models.Settings;
|
using Settings = VirtualDDNSRouter.Client.Models.Settings;
|
||||||
@@ -16,7 +17,7 @@ public class Helpers
|
|||||||
var yamlContent = await File.ReadAllTextAsync(YamlFilePath).ConfigureAwait(false);
|
var yamlContent = await File.ReadAllTextAsync(YamlFilePath).ConfigureAwait(false);
|
||||||
|
|
||||||
// Build the deserializer with explicit naming convention
|
// Build the deserializer with explicit naming convention
|
||||||
var deserializer = new StaticDeserializerBuilder(new YamlStaticContext())
|
var deserializer = new StaticDeserializerBuilder(new YamlStaticContextClient())
|
||||||
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
||||||
.IgnoreUnmatchedProperties()
|
.IgnoreUnmatchedProperties()
|
||||||
.Build();
|
.Build();
|
||||||
@@ -24,16 +25,10 @@ public class Helpers
|
|||||||
// Deserialize into Settings
|
// Deserialize into Settings
|
||||||
var settings = deserializer.Deserialize<Settings>(yamlContent);
|
var settings = deserializer.Deserialize<Settings>(yamlContent);
|
||||||
|
|
||||||
if (settings is null || string.IsNullOrWhiteSpace(settings.Host) || string.IsNullOrWhiteSpace(settings.Path) ||
|
if (settings is null || string.IsNullOrWhiteSpace(settings.host) || string.IsNullOrWhiteSpace(settings.path) ||
|
||||||
string.IsNullOrWhiteSpace(settings.ApiKey))
|
string.IsNullOrWhiteSpace(settings.apiKey))
|
||||||
throw new Exception("Invalid settings file");
|
throw new Exception("Invalid settings file");
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
[YamlStaticContext]
|
|
||||||
[YamlSerializable(typeof(Settings))]
|
|
||||||
private partial class YamlStaticContext : StaticContext
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -1,10 +1,17 @@
|
|||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace VirtualDDNSRouter.Client.Models;
|
namespace VirtualDDNSRouter.Client.Models;
|
||||||
|
|
||||||
public class Settings
|
[YamlSerializable]
|
||||||
|
public record Settings
|
||||||
{
|
{
|
||||||
public string Host { get; set; } = string.Empty;
|
public string host { get; set; } = string.Empty;
|
||||||
public string Path { get; set; } = string.Empty;
|
public string path { get; set; } = string.Empty;
|
||||||
public ushort DestinationPort { get; set; } = 80;
|
public ushort destinationPort { get; set; } = 80;
|
||||||
public string ApiKey { get; set; } = string.Empty;
|
public string apiKey { get; set; } = string.Empty;
|
||||||
public ushort RefreshIntervalMinutes { get; set; } = 5;
|
public ushort refreshIntervalMinutes { get; set; } = 5;
|
||||||
|
|
||||||
|
public Settings()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
@@ -10,17 +10,34 @@ Console.CancelKeyPress += (s, e) =>
|
|||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
var timer = new PeriodicTimer(TimeSpan.FromMinutes(settings.RefreshIntervalMinutes));
|
var timer = new PeriodicTimer(TimeSpan.FromMinutes(settings.refreshIntervalMinutes));
|
||||||
|
|
||||||
var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
|
var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get,
|
var builder = new UriBuilder
|
||||||
new Uri($"{settings.Host}/setip/{settings.Path}/{settings.DestinationPort}/{settings.ApiKey}"));
|
|
||||||
while (await timer.WaitForNextTickAsync())
|
|
||||||
{
|
{
|
||||||
if (cts.IsCancellationRequested) break;
|
Scheme = "http",
|
||||||
var response = await client.SendAsync(request, cts.Token);
|
Host = settings.host,
|
||||||
if (response.IsSuccessStatusCode)
|
Path = $"setip/{settings.path}/{settings.destinationPort}/{settings.apiKey}"
|
||||||
Console.WriteLine("[INFO] IP address updated at " + DateTime.Now.ToString("HH:mm:ss"));
|
};
|
||||||
else
|
|
||||||
Console.WriteLine("[ERROR] IP address update failed at " + DateTime.Now.ToString("HH:mm:ss"));
|
var request = new HttpRequestMessage(HttpMethod.Get, builder.Uri);
|
||||||
|
|
||||||
|
Console.WriteLine("[INFO] App started. Scheduling IP address update every " + settings.refreshIntervalMinutes +
|
||||||
|
" minutes.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (await timer.WaitForNextTickAsync(cts.Token))
|
||||||
|
{
|
||||||
|
if (cts.IsCancellationRequested) break;
|
||||||
|
var response = await client.SendAsync(request, cts.Token);
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
Console.WriteLine("[INFO] IP address updated at " + DateTime.Now.ToString("HH:mm:ss"));
|
||||||
|
else
|
||||||
|
Console.WriteLine("[ERROR] IP address update failed at " + DateTime.Now.ToString("HH:mm:ss"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
Console.WriteLine("[INFO] Shutdown complete.");
|
||||||
}
|
}
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="YamlDotNet" Version="16.3.0"/>
|
<PackageReference Include="YamlDotNet" Version="16.3.0"/>
|
||||||
|
<PackageReference Include="Vecc.YamlDotNet.Analyzers.StaticGenerator" Version="16.3.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -5,6 +5,6 @@ namespace VirtualDDNSRouter.Server.Context;
|
|||||||
|
|
||||||
[YamlStaticContext]
|
[YamlStaticContext]
|
||||||
[YamlSerializable(typeof(Rule))]
|
[YamlSerializable(typeof(Rule))]
|
||||||
public partial class YamlStaticContext : StaticContext
|
public partial class YamlStaticContextServer : StaticContext
|
||||||
{
|
{
|
||||||
}
|
}
|
@@ -1,4 +1,3 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using VirtualDDNSRouter.Server.Context;
|
using VirtualDDNSRouter.Server.Context;
|
||||||
using VirtualDDNSRouter.Server.Interfaces;
|
using VirtualDDNSRouter.Server.Interfaces;
|
||||||
using VirtualDDNSRouter.Server.Models;
|
using VirtualDDNSRouter.Server.Models;
|
||||||
@@ -19,7 +18,7 @@ public class YamlParser : IYamlParser
|
|||||||
var yamlContent = await File.ReadAllTextAsync(_yamlFilePath).ConfigureAwait(false);
|
var yamlContent = await File.ReadAllTextAsync(_yamlFilePath).ConfigureAwait(false);
|
||||||
|
|
||||||
// Build the deserializer with explicit naming convention
|
// Build the deserializer with explicit naming convention
|
||||||
var deserializer = new StaticDeserializerBuilder(new YamlStaticContext())
|
var deserializer = new StaticDeserializerBuilder(new YamlStaticContextServer())
|
||||||
.WithNamingConvention(UnderscoredNamingConvention.Instance) // maps api_key -> apiKey
|
.WithNamingConvention(UnderscoredNamingConvention.Instance) // maps api_key -> apiKey
|
||||||
.IgnoreUnmatchedProperties()
|
.IgnoreUnmatchedProperties()
|
||||||
.Build();
|
.Build();
|
||||||
@@ -27,6 +26,6 @@ public class YamlParser : IYamlParser
|
|||||||
// Deserialize into a list of Rule
|
// Deserialize into a list of Rule
|
||||||
var rules = deserializer.Deserialize<List<Rule>>(yamlContent);
|
var rules = deserializer.Deserialize<List<Rule>>(yamlContent);
|
||||||
|
|
||||||
return rules ?? new List<Rule>();
|
return rules;
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user