Import from ntp.exactlywww.com

This commit is contained in:
Carsten Larsen 2016-12-25 16:05:56 +01:00
parent d554d98310
commit 3b2d182284
25 changed files with 343 additions and 138 deletions

View File

@ -22,11 +22,12 @@
using System;
using Newtonsoft.Json;
using Ntp.Analyzer.Data.Log;
using Ntp.Analyzer.Objects;
using Ntp.Common.Log;
namespace Ntp.Analyzer.Data.Import
{
public sealed class ExactlyAdapter : WebAdapter
public sealed class ExactlyAdapter : TimeServerWebAdapter
{
public ExactlyAdapter(LogBase log)
: base(log)
@ -35,7 +36,7 @@ public ExactlyAdapter(LogBase log)
protected override string Provider => "ntp.exactlywww.com";
public ExactlyTimeServer ImportServer(int orgId)
public override TimeServer Import(int orgId)
{
string url = $"http://ntp.exactlywww.com/ntp/api/?id={orgId}";
string json = FetchHtml(url, orgId);

View File

@ -134,7 +134,7 @@ internal TimeServer ParseTable(string table, int orgId)
bool? poolMember = GetBool(poolMemberStr);
bool? notification = GetBool(notificationStr);
return new TimeServer(
return new CalgaryTimeServer(
orgId, stratus, country, name, address, ip6, useDns, poolMember, location,
display, org, geo, server, serviceArea, accessDetails, accessPolicy,
notification, autoKey, symKey, symUrl, contact, null, null, DateTime.Now);

View File

@ -22,11 +22,12 @@
using System;
using System.Globalization;
using Ntp.Analyzer.Data.Log;
using Ntp.Analyzer.Objects;
using Ntp.Common.Log;
namespace Ntp.Analyzer.Data.Import
{
internal sealed class TimeServerLoader : WebAdapter
internal sealed class TimeServerLoader : TimeServerWebAdapter
{
internal TimeServerLoader(LogBase log)
: base(log)
@ -38,7 +39,18 @@ internal TimeServerLoader(LogBase log)
protected override string Provider => "support.ntp.org";
public string ImportServer(int orgId)
public override TimeServer Import(int orgId)
{
string table = ImportServer(orgId);
if (table == null)
return null;
var importer = new TimeServerImporter(Log);
var server = importer.ParseTable(table, orgId);
return server;
}
private string ImportServer(int orgId)
{
string orgString = orgId.ToString(CultureInfo.InvariantCulture).PadLeft(6, '0');
string url = $"http://support.ntp.org/bin/view/Servers/PublicTimeServer{orgString}";

View File

@ -23,21 +23,37 @@
using System.IO;
using System.Net;
using Ntp.Analyzer.Data.Log;
using Ntp.Analyzer.Objects;
using Ntp.Common.Log;
namespace Ntp.Analyzer.Data.Import
{
public abstract class WebAdapter
public abstract class TimeServerWebAdapter
{
protected WebAdapter(LogBase log)
protected TimeServerWebAdapter(LogBase log)
{
Log = log;
}
private static bool enabled;
protected readonly LogBase Log;
protected abstract string Provider { get; }
public static TimeServerWebAdapter Create(LogBase log)
{
// Use the ExactlyAdapter for now
return enabled ? new ExactlyAdapter(log) : null;
}
public abstract TimeServer Import(int orgId);
public static void Initialize(bool enable)
{
enabled = enable;
}
protected string FetchHtml(string url, int orgId)
{
if (orgId >= 5000)
@ -59,6 +75,7 @@ private string Download(string url, int orgId)
try
{
var client = new WebClient();
// TODO: Set timeout
client.Headers.Add(
"user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)"

View File

@ -54,21 +54,21 @@ internal static void CreateTableError(this LogBase log, Exception e)
internal static void DeleteError(this LogBase log, string table, Exception e)
{
log.WriteLine($"Error while deleting from table {table}: {e.Message}", Severity.Warn);
log.WriteLine(e);
log.WriteLine(e, Severity.Warn);
Advice(log);
}
internal static void InsertError(this LogBase log, string table, Exception e)
{
log.WriteLine($"Error while inserting into table {table}: {e.Message}", Severity.Warn);
log.WriteLine(e);
log.WriteLine(e, Severity.Warn);
Advice(log);
}
internal static void ReadError(this LogBase log, string table, Exception e)
{
log.WriteLine($"Error while reading from table {table}: {e.Message}", Severity.Warn);
log.WriteLine(e);
log.WriteLine(e, Severity.Warn);
Advice(log);
}
@ -82,7 +82,7 @@ internal static void TableExists(this LogBase log, string table)
internal static void UpdateError(this LogBase log, string table, Exception e)
{
log.WriteLine($"Error while updating table {table}: {e.Message}", Severity.Warn);
log.WriteLine(e);
log.WriteLine(e, Severity.Warn);
Advice(log);
}
@ -105,6 +105,12 @@ internal static void TimeServerError(this LogBase log, string provider, int orgI
log.WriteLine($"Error while contacting {provider} with ID {orgId}", Severity.Warn);
}
internal static void TimeServerFetchError(this LogBase log, Exception e)
{
log.WriteLine("Failed to fetch time server data.", Severity.Warn);
log.WriteLine(e, Severity.Warn);
}
internal static void TimeServerMaxId(this LogBase log, string provider)
{
log.WriteLine($"Not contacting {provider} for ID > 10000.", Severity.Debug);
@ -123,7 +129,7 @@ internal static void TimeServerNotRecieved(this LogBase log, int orgId)
internal static void TimeServerParseError(this LogBase log, string type, Exception e)
{
log.WriteLine($"Could not parse time server {type}.", Severity.Warn);
log.WriteLine(e);
log.WriteLine(e, Severity.Warn);
}
}
}

View File

@ -87,13 +87,11 @@ FILES = \
../Shared/AssemblyInfo.cs \
Changes/Change03.cs \
DataFace.cs \
Import/ExactlySuccess.cs \
Import/ExactlyTimeServer.cs \
Import/ExactlyAdapter.cs \
Import/TimeServerImporter.cs \
Import/TimeServerLoader.cs \
Import/TimeServers.cs \
Import/WebAdapter.cs \
Import/TimeServerWebAdapter.cs \
Log/LogExtensions.cs \
Sql/DriftReadingDatabaseMapper.cs \
Sql/HostDatabaseMapper.cs \

View File

@ -30,9 +30,11 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Posix.4.0.0.0\lib\net40\Mono.Posix.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
@ -43,13 +45,11 @@
<Compile Include="..\Shared\AssemblyInfo.cs" />
<Compile Include="Changes\Change03.cs" />
<Compile Include="DataFace.cs" />
<Compile Include="Import\ExactlySuccess.cs" />
<Compile Include="Import\ExactlyTimeServer.cs" />
<Compile Include="Import\ExactlyAdapter.cs" />
<Compile Include="Import\TimeServerImporter.cs" />
<Compile Include="Import\TimeServerLoader.cs" />
<Compile Include="Import\TimeServers.cs" />
<Compile Include="Import\WebAdapter.cs" />
<Compile Include="Import\TimeServerWebAdapter.cs" />
<Compile Include="Log\LogExtensions.cs" />
<Compile Include="Sql\DriftReadingDatabaseMapper.cs" />
<Compile Include="Sql\HostDatabaseMapper.cs" />
@ -68,9 +68,6 @@
<Compile Include="Changes\Change02.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ntp.Analyzer.Objects\Ntp.Analyzer.Objects.csproj">
<Project>{02912378-E62D-4445-BA30-F56D3ABE9DA2}</Project>

View File

@ -101,25 +101,23 @@ internal TimeServerDatabaseMapper(LogBase log)
/// <param name="id">The time server identifier used on support.ntp.org.</param>
protected override TimeServer FetchExternal(int id)
{
var loader = new TimeServerLoader(Log);
var importer = new TimeServerImporter(Log);
var adapter = TimeServerWebAdapter.Create(Log);
if (adapter == null)
return null;
TimeServer server;
try
{
string table = loader.ImportServer(id);
if (table == null)
{
return null;
}
server = importer.ParseTable(table, id);
server = adapter.Import(id);
Insert(server);
AddItem(server);
}
catch (Exception e)
{
throw new ApplicationException("Failed to fetch time server data.", e);
Log.TimeServerFetchError(e);
return null;
}
return server;
@ -252,7 +250,7 @@ protected override void ReadContent()
if (ip4 != null)
IPAddress.TryParse(ip4, out address);
var server = new TimeServer(
var server = new CalgaryTimeServer(
id, stratum, countryCode, hostName, address, ip6, useDns, poolMember, location,
displayLocation, organization, coordinates, synchronization, serviceArea, accessDetails,
accessPolicy, notification, autoKeyUrl, symmetricKeyType, symmetricKeyUrl, serverContact,

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="Mono.Posix" version="4.0.0.0" targetFramework="net452" />
</packages>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
</packages>

View File

@ -0,0 +1,130 @@
//
// Copyright (c) 2013-2016 Carsten Sonne Larsen <cs@innolan.dk>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Net;
namespace Ntp.Analyzer.Objects
{
public sealed class CalgaryTimeServer : TimeServer
{
public CalgaryTimeServer(string name, IPAddress address, int orgId)
{
Name = name;
Address = address;
SetId(orgId);
}
public CalgaryTimeServer(
int id, int stratum, string country,
string name, IPAddress address, string v6Address,
bool? useDns, bool? poolMember, string location,
string displayLocation, string organization, string geo, string server,
string serviceArea, string accessDetails, string accessPolicy,
bool? notification, string autoKey, string symKey, string symUrl,
string contact, string providerPage, string providerUrl, DateTime updated)
: base(id)
{
Stratum = stratum;
Country = country;
Name = name;
Address = address;
V6Address = Scrub(v6Address);
this.useDns = useDns;
this.poolMember = poolMember;
Location = location;
DisplayLocation = displayLocation;
Organization = Scrub(organization);
Geo = Scrub(geo);
Location = location;
Server = server;
ServiceArea = serviceArea;
AccessDetails = accessDetails;
AccessPolicy = Scrub(accessPolicy);
this.notification = notification;
AutoKey = Scrub(autoKey);
SymKey = Scrub(symKey);
SymUrl = Scrub(symUrl);
Contact = contact;
ProviderPage = providerPage;
ProviderUrl = providerUrl;
Updated = updated;
}
private readonly bool? notification;
private readonly bool? poolMember;
private readonly bool? useDns;
public override int Stratum { get; }
public override string Country { get; }
public override string Name { get; }
public override IPAddress Address { get; }
public override string V6Address { get; }
public override bool ShouldUseDns => useDns ?? false;
public override bool IsPoolMember => poolMember ?? false;
public override string Location { get; }
public override string DisplayLocation { get; }
public override string Organization { get; }
public override string Geo { get; }
public override string Server { get; }
public override string ServiceArea { get; }
public override string AccessPolicy { get; }
public override string AccessDetails { get; }
public override bool ShouldNotify => notification ?? false;
public override string AutoKey { get; }
public override string SymKey { get; }
public override string SymUrl { get; }
public override string Contact { get; }
public override string ProviderPage { get; }
public override string ProviderUrl { get; }
public override DateTime Updated { get; }
private static string Scrub(string input)
{
if (input == null || input.Trim() == string.Empty)
return null;
return input.Trim();
}
}
}

View File

@ -21,7 +21,7 @@
using Newtonsoft.Json;
namespace Ntp.Analyzer.Data.Import
namespace Ntp.Analyzer.Objects
{
public class ExactlySuccess
{

View File

@ -20,11 +20,16 @@
// THE SOFTWARE.
using System;
using System.Net;
using Newtonsoft.Json;
namespace Ntp.Analyzer.Data.Import
// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Ntp.Analyzer.Objects
{
public class ExactlyTimeServer
public class ExactlyTimeServer : TimeServer
{
/// <summary>
/// A link to the server information page at support.ntp.org.
@ -38,11 +43,17 @@ public class ExactlyTimeServer
[JsonProperty("iso")]
public string Iso { get; set; }
public override string Country => Iso;
/// <summary>
/// The physical location of the server, useful in selecting upstream servers.
/// </summary>
[JsonProperty("location")]
public string Location { get; set; }
public string LocationRaw { get; set; }
public override string Location => LocationRaw;
public override string DisplayLocation => Location.Substring(0, 60);
/// <summary>
/// The organization sponsoring the operation of the server.
@ -50,24 +61,32 @@ public class ExactlyTimeServer
[JsonProperty("sponsor")]
public string Sponsor { get; set; }
public override string Organization => Sponsor;
/// <summary>
/// The region/area that the server is intended to serve. If you're outside that area,
/// you probably shouldn't be using it, unless there is a shortage of servers in your
/// area.
/// </summary>
[JsonProperty("service_area")]
public string ServiceArea { get; set; }
public string ServiceAreaRaw { get; set; }
public override string ServiceArea => ServiceAreaRaw;
[JsonProperty("access")]
public string Access { get; set; }
public override string AccessPolicy => Access;
/// <summary>
/// A 1 indicates the server operator would like to be notified, via the details in
/// contact if you are using their server. A zero means they don't care, just happy
/// to be of help.
/// </summary>
[JsonProperty("notify")]
public string Notify { get; set; }
public string NotifyRaw { get; set; }
public override bool ShouldNotify => NotifyRaw.Trim() == "1";
/// <summary>
/// A UNIX timestamp indicating the last time the server page was updated by the owner.
@ -81,6 +100,8 @@ public class ExactlyTimeServer
/// </summary>
public DateTime Modified => new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(ModifiedRaw);
public override DateTime Updated => Modified;
/// <summary>
/// The hostname to be used if usedns = 1.
/// </summary>
@ -88,6 +109,8 @@ public class ExactlyTimeServer
[JsonProperty("hostname")]
public string Hostname { get; set; }
public override string Name => Hostname;
/// <summary>
/// IP (v4) address to be used if usedns = 0.
/// </summary>
@ -95,30 +118,49 @@ public class ExactlyTimeServer
[JsonProperty("ipv4")]
public string Ipv4 { get; set; }
public override IPAddress Address
{
get
{
IPAddress ip;
return IPAddress.TryParse(Ipv4, out ip) ? ip : null;
}
}
/// <summary>
/// If available, the IP (v6) address to be used if usedns = 0.
/// </summary>
[JsonProperty("ipv6")]
public string Ipv6 { get; set; }
public override string V6Address => Ipv6;
/// <summary>
/// Indicates that downstream servers should use the hostname, not DNS.
/// </summary>
[JsonProperty("usedns")]
public string UseDns { get; set; }
public override bool ShouldUseDns => UseDns.Trim() == "1";
public override bool IsPoolMember => false;
/// <summary>
/// More information about the access granted, or notification requested.
/// </summary>
[JsonProperty("access_details")]
public string AccessDetails { get; set; }
public string AccessDetailsRaw { get; set; }
public override string AccessDetails => AccessDetailsRaw;
/// <summary>
/// If notify = 1, use this information to contact the server operator.
/// </summary>
/// <example>Brad Arlt (timekeeper@cpsc.ucalgary.ca)</example>
[JsonProperty("contact")]
public string Contact { get; set; }
public string ContactRaw { get; set; }
public override string Contact => ContactRaw;
/// <summary>
/// These are the IP addresses returned by a DNS query for IPv4 (A)
@ -154,7 +196,7 @@ public class ExactlyTimeServer
/// The numerical ID, as queried from the list at support.ntp.org.
/// </summary>
[JsonProperty("id")]
public int Id { get; set; }
public int IdRaw { get; set; }
/// <summary>
/// How many times we have successfully contacted this server.
@ -190,5 +232,21 @@ public class ExactlyTimeServer
/// Last time this server was successfully contacted.
/// </summary>
public DateTime Contacted => new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(ContactedRaw);
public override int Stratum => 0;
public override string Geo => string.Empty;
public override string Server => string.Empty;
public override string AutoKey => string.Empty;
public override string SymKey => string.Empty;
public override string SymUrl => string.Empty;
public override string ProviderPage => string.Empty;
public override string ProviderUrl => string.Empty;
}
}

View File

@ -12,6 +12,7 @@ BUILD_DIR = ../bin
NTP_ANALYZER_OBJECTS_DLL_MDB_SOURCE=../bin/Ntp.Analyzer.Objects.dll.mdb
NTP_ANALYZER_OBJECTS_DLL_MDB=$(BUILD_DIR)/Ntp.Analyzer.Objects.dll.mdb
NEWTONSOFT_DLL_SOURCE=../packages/Newtonsoft.Json.9.0.1/lib/net45/Newtonsoft.Json.dll
endif
@ -25,6 +26,7 @@ PROJECT_REFERENCES =
BUILD_DIR = ../bin
NTP_ANALYZER_OBJECTS_DLL_MDB=
NEWTONSOFT_DLL_SOURCE=../packages/Newtonsoft.Json.9.0.1/lib/net45/Newtonsoft.Json.dll
endif
@ -39,7 +41,10 @@ all: $(ASSEMBLY) $(PROGRAMFILES)
FILES = \
../Shared/AssemblyInfo.cs \
CalgaryTimeServer.cs \
DriftReading.cs \
ExactlySuccess.cs \
ExactlyTimeServer.cs \
Host.cs \
HostReading.cs \
Peer.cs \
@ -65,12 +70,15 @@ EXTRAS =
REFERENCES = System
DLL_REFERENCES =
DLL_REFERENCES = $(NEWTONSOFT_DLL)
CLEANFILES = $(PROGRAMFILES)
include $(top_srcdir)/Makefile.include
NEWTONSOFT_DLL = $(BUILD_DIR)/Newtonsoft.Json.dll
$(eval $(call emit-deploy-target,NEWTONSOFT_DLL))
$(eval $(call emit_resgen_targets))
$(build_xamlg_list): %.xaml.g.cs: %.xaml

View File

@ -30,11 +30,18 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Shared\AssemblyInfo.cs" />
<Compile Include="CalgaryTimeServer.cs" />
<Compile Include="DriftReading.cs" />
<Compile Include="ExactlySuccess.cs" />
<Compile Include="ExactlyTimeServer.cs" />
<Compile Include="Host.cs" />
<Compile Include="HostReading.cs" />
<Compile Include="Peer.cs" />
@ -53,6 +60,9 @@
<Compile Include="HostIoReading.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>

View File

@ -1,4 +1,4 @@
//
//
// Copyright (c) 2013-2016 Carsten Sonne Larsen <cs@innolan.dk>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@ -24,107 +24,61 @@
namespace Ntp.Analyzer.Objects
{
public sealed class TimeServer : PersistentObject
public abstract class TimeServer : PersistentObject
{
public TimeServer(string name, IPAddress address, int orgId)
protected TimeServer()
{
Name = name;
Address = address;
SetId(orgId);
}
public TimeServer(
int id, int stratum, string country,
string name, IPAddress address, string v6Address,
bool? useDns, bool? poolMember, string location,
string displayLocation, string organization, string geo, string server,
string serviceArea, string accessDetails, string accessPolicy,
bool? notification, string autoKey, string symKey, string symUrl,
string contact, string providerPage, string providerUrl, DateTime updated)
protected TimeServer(int id)
: base(id)
{
Stratum = stratum;
Country = country;
Name = name;
Address = address;
V6Address = Scrub(v6Address);
this.useDns = useDns;
this.poolMember = poolMember;
Location = location;
DisplayLocation = displayLocation;
Organization = Scrub(organization);
Geo = Scrub(geo);
Location = location;
Server = server;
ServiceArea = serviceArea;
AccessDetails = accessDetails;
AccessPolicy = Scrub(accessPolicy);
this.notification = notification;
AutoKey = Scrub(autoKey);
SymKey = Scrub(symKey);
SymUrl = Scrub(symUrl);
Contact = contact;
ProviderPage = providerPage;
ProviderUrl = providerUrl;
Updated = updated;
}
private readonly bool? notification;
private readonly bool? poolMember;
private readonly bool? useDns;
public abstract int Stratum { get; }
public int Stratum { get; }
public abstract string Country { get; }
public string Country { get; }
public abstract string Name { get; }
public string Name { get; }
public abstract IPAddress Address { get; }
public IPAddress Address { get; }
public abstract string V6Address { get; }
public string V6Address { get; }
public abstract bool ShouldUseDns { get; }
public bool ShouldUseDns => useDns ?? false;
public abstract bool IsPoolMember { get; }
public bool IsPoolMember => poolMember ?? false;
public abstract string Location { get; }
public string Location { get; }
public abstract string DisplayLocation { get; }
public string DisplayLocation { get; }
public abstract string Organization { get; }
public string Organization { get; }
public abstract string Geo { get; }
public string Geo { get; }
public abstract string Server { get; }
public string Server { get; }
public abstract string ServiceArea { get; }
public string ServiceArea { get; }
public abstract string AccessPolicy { get; }
public string AccessPolicy { get; }
public abstract string AccessDetails { get; }
public string AccessDetails { get; }
public abstract bool ShouldNotify { get; }
public bool ShouldNotify => notification ?? false;
public abstract string AutoKey { get; }
public string AutoKey { get; }
public abstract string SymKey { get; }
public string SymKey { get; }
public abstract string SymUrl { get; }
public string SymUrl { get; }
public abstract string Contact { get; }
public string Contact { get; }
public abstract string ProviderPage { get; }
public string ProviderPage { get; }
public abstract string ProviderUrl { get; }
public string ProviderUrl { get; }
public DateTime Updated { get; }
private static string Scrub(string input)
{
if (input == null || input.Trim() == string.Empty)
return null;
return input.Trim();
}
public abstract DateTime Updated { get; }
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
</packages>

View File

@ -221,6 +221,7 @@ private void ParseDatabaseSection(ISyntaxNode parent)
case Symbol.KeywordPass:
case Symbol.KeywordCreate:
case Symbol.KeywordUpgrade:
case Symbol.KeywordImport:
case Symbol.KeywordDatabaseName:
case Symbol.KeywordDatabaseUser:
case Symbol.KeywordDatabasePass:

View File

@ -42,7 +42,8 @@ public sealed class DatabaseConfiguration : ConfigurationNode, IDatabaseConfigur
int? protocol,
bool? ssl,
bool? initialize,
bool? upgrade
bool? upgrade,
bool? import
)
: base(configName)
{
@ -60,8 +61,11 @@ public sealed class DatabaseConfiguration : ConfigurationNode, IDatabaseConfigur
this.ssl = ssl;
this.initialize = initialize;
this.upgrade = upgrade;
this.import = import;
}
private readonly bool? import;
private readonly bool? initialize;
private readonly bool? ssl;
private readonly bool? upgrade;
@ -74,6 +78,10 @@ public sealed class DatabaseConfiguration : ConfigurationNode, IDatabaseConfigur
[NtpaSetting(Symbol.KeywordUpgrade, false)]
public bool Upgrade => upgrade ?? false;
[NtpaIndex(52)]
[NtpaSetting(Symbol.KeywordImport, true)]
public bool Import => import ?? true;
[NtpaIndex(2)]
[NtpaSetting(Symbol.KeywordConString)]
public string ConnectionString { get; }

View File

@ -51,6 +51,7 @@ protected override DatabaseConfiguration InternalCompile()
Nodes.SingleOrDefault(n => n.Symbol == Symbol.KeywordDatabasePass) as StringSettingNode;
var create = Nodes.SingleOrDefault(n => n.Symbol == Symbol.KeywordCreate) as BooleanSettingNode;
var upgrade = Nodes.SingleOrDefault(n => n.Symbol == Symbol.KeywordUpgrade) as BooleanSettingNode;
var import = Nodes.SingleOrDefault(n => n.Symbol == Symbol.KeywordImport) as BooleanSettingNode;
var provider = Nodes.Single(n => n.Symbol == Symbol.KeywordDatabaseProvider) as DatabaseProviderNode;
var conString = Nodes.SingleOrDefault(n => n.Symbol == Symbol.KeywordConString) as StringSettingNode;
var certFile = Nodes.SingleOrDefault(n => n.Symbol == Symbol.KeywordCertFile) as StringSettingNode;
@ -79,7 +80,8 @@ protected override DatabaseConfiguration InternalCompile()
protocol?.Value,
ssl?.Value,
create?.Value,
upgrade?.Value
upgrade?.Value,
import?.Value
);
}
@ -97,6 +99,7 @@ protected override void ValidateMandatories()
Symbol.KeywordUser,
Symbol.KeywordPass,
Symbol.KeywordCreate,
Symbol.KeywordImport,
Symbol.KeywordUpgrade,
Symbol.KeywordDatabaseName,
Symbol.KeywordDatabaseUser,
@ -112,7 +115,7 @@ protected override void ValidateMandatories()
CheckAllIsPresent(new List<Symbol> {Symbol.KeywordDatabaseProvider});
CheckOnlyOneIsPresent(new List<Symbol>
CheckOneIsPresent(new List<Symbol>
{
Symbol.KeywordIp,
Symbol.KeywordHost,
@ -120,19 +123,19 @@ protected override void ValidateMandatories()
Symbol.KeywordHostAddress
});
CheckOnlyOneIsPresent(new List<Symbol>
CheckOneIsPresent(new List<Symbol>
{
Symbol.KeywordName,
Symbol.KeywordDatabaseName
});
CheckOnlyOneIsPresent(new List<Symbol>
CheckOneIsPresent(new List<Symbol>
{
Symbol.KeywordUser,
Symbol.KeywordDatabaseUser
});
CheckOnlyOneIsPresent(new List<Symbol>
CheckOneIsPresent(new List<Symbol>
{
Symbol.KeywordPass,
Symbol.KeywordDatabasePass

View File

@ -127,6 +127,7 @@ private Keyword(string name, Symbol symbol, Type valueType = null)
new Keyword("Frequency", Symbol.KeywordFrequency, typeof(int)),
new Keyword("Create", Symbol.KeywordCreate, typeof(bool)),
new Keyword("Upgrade", Symbol.KeywordUpgrade, typeof(bool)),
new Keyword("Import", Symbol.KeywordImport, typeof(bool)),
new Keyword("ShowTimestamp", Symbol.KeywordShowTimestamp, typeof(bool)),
new Keyword("ShowSeverity", Symbol.KeywordShowSeverity, typeof(bool)),
new Keyword("TimeFormat", Symbol.KeywordTimeFormat, typeof(string)),

View File

@ -105,6 +105,7 @@ public enum Symbol
KeywordDatabase,
KeywordCreate,
KeywordUpgrade,
KeywordImport,
KeywordDatabaseProvider,
KeywordDatabaseProviderMySql,
KeywordDatabaseProviderPostgre,

View File

@ -283,7 +283,7 @@ REFERENCES = \
System.Drawing \
System.Runtime.Serialization
DLL_REFERENCES =
DLL_REFERENCES = $(NPLOT_DLL)
CLEANFILES = $(PROGRAMFILES)
@ -296,6 +296,7 @@ NTP_ANALYZER_DATA_DLL = $(BUILD_DIR)/Ntp.Analyzer.Data.dll
NTP_DATA_PROVIDER_DLL = $(BUILD_DIR)/Ntp.Data.Provider.dll
MYSQL_DATA_DLL = $(BUILD_DIR)/MySql.Data.dll
NPGSQL_DLL = $(BUILD_DIR)/Npgsql.dll
NPLOT_DLL = $(BUILD_DIR)/NPlot.dll
NTP_ANALYZER_IMPORT_DLL = $(BUILD_DIR)/Ntp.Analyzer.Import.dll
$(eval $(call emit-deploy-target,MYSQL_DATA_DLL))

View File

@ -30,25 +30,14 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="NPlot">
<HintPath>..\packages\NPlot.0.9.10.0\lib\net20\NPlot.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
<Choose>
<When Condition=" '$(NPlot)' == 'nuget' ">
<ItemGroup>
<Reference Include="NPlot">
<HintPath>..\packages/NPlot.0.9.10.0/lib/net20/NPlot.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<When Condition=" '$(NPlot)' != 'nuget' ">
<ItemGroup>
<Reference Include="NPlot, Version=0.9.11.0, Culture=neutral, PublicKeyToken=1d82a50c5d01c44e" />
</ItemGroup>
</When>
</Choose>
<ItemGroup>
<Compile Include="..\Shared\AssemblyInfo.cs" />
<Compile Include="Config\Attribute\NtpaIndex.cs" />

View File

@ -30,8 +30,11 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Mono.Posix.4.0.0.0\lib\net40\Mono.Posix.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Mono.Posix" />
<Reference Include="System.Core" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />