Skip to content

Commit fd9ae7b

Browse files
committed
Merge branch 'release/1.9.0'
2 parents 7487b29 + e540705 commit fd9ae7b

File tree

80 files changed

+5577
-420
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+5577
-420
lines changed

.github/workflows/dotnetcore.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ jobs:
99

1010
steps:
1111
- uses: actions/checkout@v1
12-
12+
- run: |
13+
git fetch --all --prune
14+
1315
- name: Setup .NET Core
1416
uses: actions/setup-dotnet@v1
1517
with:

.vscode/settings.json

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

HamnetDbAbstraction/DatabaseSpecific/CachingHamnetDbAccessor.cs

+413
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
namespace HamnetDbAbstraction
7+
{
8+
/// <summary>
9+
/// Container for a list of HamnetDB site entries.
10+
/// </summary>
11+
internal class HamnetDbSites : IHamnetDbSites
12+
{
13+
private List<IHamnetDbSite> sites;
14+
15+
/// <summary>
16+
/// Construct from a list of subnets.
17+
/// </summary>
18+
/// <param name="sites"></param>
19+
public HamnetDbSites(IEnumerable<IHamnetDbSite> sites)
20+
{
21+
if (sites == null)
22+
{
23+
throw new ArgumentNullException(nameof(sites), "The lists of sites is null");
24+
}
25+
26+
this.sites = sites as List<IHamnetDbSite> ?? sites.ToList();
27+
}
28+
29+
/// <inheritdoc />
30+
public int Count => this.sites.Count;
31+
32+
/// <inheritdoc />
33+
public IEnumerator<IHamnetDbSite> GetEnumerator()
34+
{
35+
return this.sites.GetEnumerator();
36+
}
37+
38+
/// <inheritdoc />
39+
IEnumerator IEnumerable.GetEnumerator()
40+
{
41+
return this.sites.GetEnumerator();
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
4+
namespace HamnetDbAbstraction
5+
{
6+
7+
/// <summary>
8+
/// Container for the base data of every(?) table in HamnetDB.
9+
/// </summary>
10+
[JsonObject]
11+
internal class JsonDataSetBase : IHamnetDbBaseData
12+
{
13+
/// <inheritdoc />
14+
[JsonProperty("edited", Required = Required.Default)]
15+
public DateTime Edited { get; set; } = DateTime.MinValue;
16+
17+
/// <inheritdoc />
18+
[JsonProperty("editor", Required = Required.Default)]
19+
public string Editor { get; set; } = string.Empty;
20+
21+
/// <inheritdoc />
22+
[JsonProperty("maintainer", Required = Required.Default)]
23+
public string Maintainer { get; set; } = string.Empty;
24+
25+
/// <inheritdoc />
26+
[JsonProperty("version", Required = Required.Always)]
27+
public int Version { get; set; }
28+
29+
/// <inheritdoc />
30+
[JsonProperty("rw_maint", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
31+
public bool MaintainerEditableOnly { get; set; }
32+
33+
/// <inheritdoc />
34+
[JsonProperty("deleted", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
35+
public bool Deleted { get; set; }
36+
37+
/// <inheritdoc />
38+
[JsonProperty("id", Required = Required.Always)]
39+
public int Id { get; set; }
40+
41+
/// <inheritdoc />
42+
[JsonProperty("no_check", Required = Required.Default), JsonConverter(typeof(JsonIntToBoolConverter))]
43+
public bool NoCheck { get; set; } = false;
44+
}
45+
}

HamnetDbAbstraction/DatabaseSpecific/JSON/JsonHamnetDbAccessor.cs

+64-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34
using System.Linq;
45
using System.Net;
56
using System.Net.Http;
@@ -11,10 +12,23 @@ namespace HamnetDbAbstraction
1112
/// <summary>
1213
/// Implementation of <see cref="IHamnetDbAccess" /> retrieving data via REST / JSON interface of HamnetDB.
1314
/// </summary>
14-
internal partial class JsonHamnetDbAccessor : IHamnetDbAccess
15+
internal class JsonHamnetDbAccessor : IHamnetDbAccess
1516
{
1617
private static readonly log4net.ILog log = HamnetDbAbstraction.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
1718

19+
/// <summary>
20+
/// Culture used by HamnetDB.
21+
/// </summary>
22+
private static CultureInfo HamnetDbJsonCultureInfo = CultureInfo.CreateSpecificCulture("de-DE");
23+
24+
/// <summary>
25+
/// HamnetDB is using German formattings.
26+
/// </summary>
27+
private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
28+
{
29+
Converters = { new HamnetDbDoubleConverter() }
30+
};
31+
1832
/// <summary>
1933
/// To detect redundant calls.
2034
/// </summary>
@@ -30,8 +44,9 @@ internal partial class JsonHamnetDbAccessor : IHamnetDbAccess
3044
/// </summary>
3145
/// <param name="hostsApiUrl">The URL to access the hosts of HamnetDB.</param>
3246
/// <param name="subnetsApiUrl">The URL to access the subnets of HamnetDB.</param>
33-
/// /// <param name="additionalDisposer">An additional Disposer that will be called (if not null) when this obejects gets disposed off.</param>
34-
public JsonHamnetDbAccessor(string hostsApiUrl, string subnetsApiUrl, IDisposable additionalDisposer)
47+
/// <param name="sitesApiUrl">The URL to access the sites of HamnetDB.</param>
48+
/// <param name="additionalDisposer">An additional Disposer that will be called (if not null) when this obejects gets disposed off.</param>
49+
public JsonHamnetDbAccessor(string hostsApiUrl, string subnetsApiUrl, string sitesApiUrl, IDisposable additionalDisposer)
3550
{
3651
if (string.IsNullOrWhiteSpace(hostsApiUrl))
3752
{
@@ -43,8 +58,14 @@ public JsonHamnetDbAccessor(string hostsApiUrl, string subnetsApiUrl, IDisposabl
4358
throw new ArgumentNullException(nameof(subnetsApiUrl), "The subnets API URL is null, empty or white-space-only");
4459
}
4560

61+
if (string.IsNullOrWhiteSpace(sitesApiUrl))
62+
{
63+
throw new ArgumentNullException(nameof(sitesApiUrl), "The sitesApiUrl API URL is null, empty or white-space-only");
64+
}
65+
4666
this.HostApiUrl = hostsApiUrl;
4767
this.SubnetsApiUrl = subnetsApiUrl;
68+
this.SitesApiUrl = sitesApiUrl;
4869
this.additionalDisposer = additionalDisposer;
4970
}
5071

@@ -65,6 +86,11 @@ public JsonHamnetDbAccessor(string hostsApiUrl, string subnetsApiUrl, IDisposabl
6586
/// </summary>
6687
public string SubnetsApiUrl { get; }
6788

89+
/// <summary>
90+
/// Gets the URL to access the sites of HamnetDB.
91+
/// </summary>
92+
public string SitesApiUrl { get; }
93+
6894
/// <inheritdoc />
6995
public IHamnetDbHosts QueryBgpRouters()
7096
{
@@ -131,6 +157,16 @@ public IHamnetDbSubnets QuerySubnets()
131157
return new HamnetDbSubnets(hosts);
132158
}
133159

160+
/// <inheritdoc />
161+
public IHamnetDbSites QuerySites()
162+
{
163+
var responseString = this.SendHttpRequest(new Uri(this.SitesApiUrl, UriKind.Absolute));
164+
165+
var responseData = JsonConvert.DeserializeObject<IEnumerable<JsonSiteDataSet>>(responseString, SerializerSettings);
166+
167+
return new HamnetDbSites(responseData);
168+
}
169+
134170
/// <summary>
135171
/// Correctly implement the disposable pattern.
136172
/// </summary>
@@ -189,5 +225,30 @@ private string SendHttpRequest(Uri uri)
189225
}
190226
}
191227
}
228+
229+
/// <summary>
230+
/// JsonConverter for reading the double values with German formatting as used by HamnetDB REST API.
231+
/// </summary>
232+
private class HamnetDbDoubleConverter : JsonConverter<double>
233+
{
234+
/// <inheritdoc />
235+
public override double ReadJson(JsonReader reader, Type objectType, double existingValue, bool hasExistingValue, JsonSerializer serializer)
236+
{
237+
string s = (string)reader.Value?.ToString();
238+
239+
if (!double.TryParse(s, NumberStyles.Any, HamnetDbJsonCultureInfo, out double parsedDouble))
240+
{
241+
return double.NaN;
242+
}
243+
244+
return parsedDouble;
245+
}
246+
247+
/// <inheritdoc />
248+
public override void WriteJson(JsonWriter writer, double value, JsonSerializer serializer)
249+
{
250+
writer.WriteValue(value.ToString(HamnetDbJsonCultureInfo));
251+
}
252+
}
192253
}
193254
}

HamnetDbAbstraction/DatabaseSpecific/JSON/JsonHostDataSet.cs

+1-47
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using Newtonsoft.Json;
32

43
namespace HamnetDbAbstraction
@@ -7,14 +6,8 @@ namespace HamnetDbAbstraction
76
/// Container for the host data set as received from HamnetDB.
87
/// </summary>
98
[JsonObject]
10-
internal class JsonHostDataSet
9+
internal class JsonHostDataSet : JsonDataSetBase
1110
{
12-
/// <summary>
13-
/// Gets or sets the date and time when the entry has last been edited.
14-
/// </summary>
15-
[JsonProperty("edited", Required = Required.Default)]
16-
public DateTime Edited { get; set; }
17-
1811
/// <summary>
1912
/// Gets or sets the IP address of the host.
2013
/// </summary>
@@ -57,63 +50,24 @@ internal class JsonHostDataSet
5750
[JsonProperty("mac", Required = Required.Default)]
5851
public string MacAddress { get; set; }
5952

60-
/// <summary>
61-
/// Gets or sets the last editor of this host.
62-
/// </summary>
63-
[JsonProperty("editor", Required = Required.Default)]
64-
public string Editor { get; set; }
65-
66-
/// <summary>
67-
/// Gets or sets the maintainer of this host.
68-
/// </summary>
69-
[JsonProperty("maintainer", Required = Required.Default)]
70-
public string Maintainer { get; set; }
71-
7253
/// <summary>
7354
/// Gets or sets a comma-separated list of readio parameters of this this host.
7455
/// </summary>
7556
[JsonProperty("radioparam", Required = Required.Default)]
7657
public string RadioParameters { get; set; }
7758

78-
/// <summary>
79-
/// Gets or sets the version of this data set.
80-
/// </summary>
81-
[JsonProperty("version", Required = Required.Default)]
82-
public int Version { get; set; }
83-
8459
/// <summary>
8560
/// Gets or sets a value indicating whether to monitor routing.
8661
/// </summary>
8762
[JsonProperty("routing", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
8863
public bool Routing { get; set; }
8964

90-
/// <summary>
91-
/// Gets or sets a value indicating whether this host is editable by maintainer only.
92-
/// </summary>
93-
[JsonProperty("rw_maint", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
94-
public bool MaintainerEditableOnly { get; set; }
95-
9665
/// <summary>
9766
/// Gets or sets a value indicating whether to ping this host.
9867
/// </summary>
9968
[JsonProperty("no_ping", Required = Required.Default), JsonConverter(typeof(JsonIntToBoolConverter))]
10069
public bool NoPing { get; set; }
10170

102-
/// <summary>
103-
/// Gets or sets a value indicating whether this host entry has been deleted and shall not be considered any more.
104-
/// </summary>
105-
/// <value>
106-
/// <c>1</c> means true, <c>0</c> false.
107-
/// </value>
108-
[JsonProperty("deleted", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
109-
public bool Deleted { get; set; }
110-
111-
/// <summary>
112-
/// Gets or sets the ID of this host.
113-
/// </summary>
114-
[JsonProperty("id", Required = Required.Default)]
115-
public int Id { get; set; }
116-
11771
/// <summary>
11872
/// Gets or sets a value indicating whether to monitor the RSSI.
11973
/// </summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using Newtonsoft.Json;
2+
3+
namespace HamnetDbAbstraction
4+
{
5+
/// <summary>
6+
/// Container for the site data set as received from HamnetDB.
7+
/// </summary>
8+
[JsonObject]
9+
internal class JsonSiteDataSet : JsonDataSetBase, IHamnetDbSite
10+
{
11+
/// <inheritdoc />
12+
[JsonProperty("latitude", Required = Required.Always)]
13+
public double Latitude { get; set; } = double.NaN;
14+
15+
/// <inheritdoc />
16+
[JsonProperty("longitude", Required = Required.Always)]
17+
public double Longitude { get; set; } = double.NaN;
18+
19+
/// <inheritdoc />
20+
[JsonProperty("ground_asl", Required = Required.Always)]
21+
public double GroundAboveSeaLevel { get; set; } = double.NaN;
22+
23+
/// <inheritdoc />
24+
[JsonProperty("elevation", Required = Required.Always)]
25+
public double Elevation { get; set; } = double.NaN;
26+
27+
/// <inheritdoc />
28+
[JsonProperty("callsign", Required = Required.Always)]
29+
public string Callsign { get; set; }
30+
31+
/// <inheritdoc />
32+
[JsonProperty("name", Required = Required.Default)]
33+
public string Name { get; set; }
34+
35+
/// <inheritdoc />
36+
[JsonProperty("comment", Required = Required.Default)]
37+
public string Comment { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets a value indicating whether this site has a cover (? whatever that is ?).
41+
/// </summary>
42+
[JsonProperty("hasCover", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
43+
public bool HasCover { get; set; }
44+
45+
/// <inheritdoc />
46+
[JsonProperty("inactive", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
47+
public bool Inactive { get; set; }
48+
49+
/// <summary>
50+
/// Gets or sets a value indicating whether this site is NewCover (? whatever that is ?).
51+
/// </summary>
52+
[JsonProperty("newCover", Required = Required.Always), JsonConverter(typeof(JsonIntToBoolConverter))]
53+
public bool NewCover { get; set; }
54+
55+
/// <inheritdoc />
56+
[JsonIgnore]
57+
public double Altitude => (double.IsNaN(this.GroundAboveSeaLevel) || double.IsNaN(this.Elevation))
58+
? double.NaN
59+
: this.GroundAboveSeaLevel + this.Elevation;
60+
}
61+
}

0 commit comments

Comments
 (0)