Skip to content

Commit 93d3da3

Browse files
committed
Can now lookup lon/lat using two different services.
1 parent e32b53f commit 93d3da3

File tree

16 files changed

+480
-88
lines changed

16 files changed

+480
-88
lines changed

src/Server/Coderr.Server.Abstractions/Config/ConfigurationCategoryExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public static void AssignProperties(this IConfigurationSection section, IDiction
2323
foreach (var kvp in settings)
2424
{
2525
var property = type.GetProperty(kvp.Key);
26+
if (property == null)
27+
continue;
28+
2629
var propertyType = property.PropertyType;
2730
if (propertyType == typeof(Uri))
2831
{

src/Server/Coderr.Server.Domain/Modules/ErrorOrigins/ErrorOrigin.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Data;
32
using System.Diagnostics.CodeAnalysis;
43

54
namespace Coderr.Server.Domain.Modules.ErrorOrigins
@@ -9,6 +8,9 @@ namespace Coderr.Server.Domain.Modules.ErrorOrigins
98
/// </summary>
109
public class ErrorOrigin
1110
{
11+
public const double EmptyLatitude = 91;
12+
public const double EmptyLongitude = 181;
13+
1214
/// <summary>
1315
/// Creates a new instance of <see cref="ErrorOrigin" />.
1416
/// </summary>
@@ -25,6 +27,19 @@ public ErrorOrigin(string ipAddress, double longitude, double latitude)
2527
Latitude = latitude;
2628
}
2729

30+
public ErrorOrigin(string ipAddress)
31+
{
32+
IpAddress = ipAddress ?? throw new ArgumentNullException(nameof(ipAddress));
33+
Longitude = EmptyLongitude;
34+
Latitude = EmptyLatitude;
35+
}
36+
37+
/// <summary>
38+
/// For the mapper.
39+
/// </summary>
40+
protected ErrorOrigin()
41+
{
42+
}
2843

2944
/// <summary>
3045
/// City reported by the lookup service.
@@ -42,17 +57,29 @@ public ErrorOrigin(string ipAddress, double longitude, double latitude)
4257
/// </summary>
4358
public string CountryName { get; set; }
4459

60+
public int Id { get; set; }
61+
4562
/// <summary>
4663
/// IP address that we received the report from
4764
/// </summary>
4865
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ip")]
4966
public string IpAddress { get; private set; }
5067

5168
/// <summary>Longitude that the IP lookup service returned.</summary>
52-
public double Latitude { get; private set; }
69+
/// <remarks>
70+
/// 91 if not specified
71+
/// </remarks>
72+
public double Latitude { get; set; }
5373

54-
/// <summary>Latitude that the IP lookup service returned.</summary>
55-
public double Longitude { get; private set; }
74+
/// <summary>
75+
/// Latitude that the IP lookup service returned.
76+
/// </summary>
77+
/// <remarks>
78+
/// <para>
79+
/// 181 if not specified.
80+
/// </para>
81+
/// </remarks>
82+
public double Longitude { get; set; }
5683

5784
/// <summary>
5885
/// TODO: WTF IS THIS?!

src/Server/Coderr.Server.ReportAnalyzer/Boot/Bootstrapper.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ namespace Coderr.Server.ReportAnalyzer.Boot
1212
{
1313
public class Bootstrapper : IAppModule
1414
{
15-
private readonly ReportAnalyzerModuleStarter _reportAnalyzerReportAnalyzerModuleStarter;
15+
private readonly ReportAnalyzerModuleStarter _reportAnalyzerModuleStarter;
1616
private ServiceProvider _serviceProvider;
1717

1818
public Bootstrapper()
1919
{
20-
_reportAnalyzerReportAnalyzerModuleStarter = new ReportAnalyzerModuleStarter();
20+
_reportAnalyzerModuleStarter = new ReportAnalyzerModuleStarter();
2121
}
2222

2323
public void Configure(ConfigurationContext context)
@@ -32,7 +32,7 @@ public void Configure(ConfigurationContext context)
3232
Services = serviceCollection
3333
};
3434
var ignoredModules = context.Configuration.GetSection("DisabledModules:ReportAnalyzer");
35-
_reportAnalyzerReportAnalyzerModuleStarter.Configure(ourContext, new ServerConfigSectionWrapper(ignoredModules));
35+
_reportAnalyzerModuleStarter.Configure(ourContext, new ServerConfigSectionWrapper(ignoredModules));
3636

3737
RegisterConfigurationStores(ourContext);
3838
ourContext.Services.AddScoped<IPrincipalAccessor, MessagingPrincipalWrapper>();
@@ -56,13 +56,13 @@ public void Start(StartContext context)
5656
{
5757
ServiceProvider = _serviceProvider
5858
};
59-
_reportAnalyzerReportAnalyzerModuleStarter.Start(ourStartContext);
59+
_reportAnalyzerModuleStarter.Start(ourStartContext);
6060
}
6161

6262

6363
public void Stop()
6464
{
65-
_reportAnalyzerReportAnalyzerModuleStarter.Stop();
65+
_reportAnalyzerModuleStarter.Stop();
6666
}
6767

6868
private IServiceProvider GetServiceProvider()

src/Server/Coderr.Server.ReportAnalyzer/Boot/Starters/ReportQueueModule.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,6 @@ private QueueListener ConfigureQueueListener(ConfigurationContext context, strin
119119
listener.ScopeCreated += (sender, args) =>
120120
{
121121
args.Scope.ResolveDependency<IPrincipalAccessor>().First().Principal = args.Principal;
122-
123-
_logger.Debug(
124-
$"[{inboundQueueName}] Running {args.Message.Body}, Credentials: {args.Principal.ToFriendlyString()}");
125122
};
126123
listener.ScopeClosing += (sender, args) =>
127124
{
@@ -160,6 +157,7 @@ private void DiagnosticLog(LogLevel level, string queueNameOrMessageName, string
160157

161158
private void HaveRun(Task obj)
162159
{
160+
_logger.Info("Stop completed for a listener in the ReportQueueModule. " + obj);
163161
}
164162

165163
private IMessageInvoker MessageInvokerFactory(IHandlerScope arg)

src/Server/Coderr.Server.ReportAnalyzer/ErrorOrigins/Handlers/OriginsConfiguration.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
using System.Collections.Generic;
22
using Coderr.Server.Abstractions.Config;
3-
using Coderr.Server.Infrastructure.Configuration;
43

54
namespace Coderr.Server.ReportAnalyzer.ErrorOrigins.Handlers
65
{
76
public class OriginsConfiguration : IConfigurationSection
87
{
8+
/// <summary>
9+
/// API key for ipstack
10+
/// </summary>
911
public string ApiKey { get; set; }
1012

13+
/// <summary>
14+
/// API key for LocationIQ.com
15+
/// </summary>
16+
public string LocationIqApiKey { get; set; }
17+
18+
/// <summary>
19+
/// API key for mapquest.com
20+
/// </summary>
21+
public string MapQuestApiKey { get; set; }
22+
1123
string IConfigurationSection.SectionName { get; } = "Origins";
1224

1325
IDictionary<string, string> IConfigurationSection.ToDictionary()
1426
{
1527
return this.ToConfigDictionary();
1628
}
1729

30+
1831
void IConfigurationSection.Load(IDictionary<string, string> settings)
1932
{
2033
this.AssignProperties(settings);
Lines changed: 22 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
using System;
22
using System.Globalization;
3-
using System.IO;
4-
using System.Net;
53
using System.Threading.Tasks;
4+
using Coderr.Server.Abstractions.Config;
65
using Coderr.Server.Domain.Modules.ErrorOrigins;
6+
using Coderr.Server.ReportAnalyzer.Abstractions.ErrorReports;
77
using Coderr.Server.ReportAnalyzer.Abstractions.Incidents;
88
using DotNetCqs;
99
using log4net;
10-
using Newtonsoft.Json.Linq;
11-
using Coderr.Server.Abstractions.Config;
12-
using Coderr.Server.ReportAnalyzer;
13-
using Coderr.Server.ReportAnalyzer.Abstractions.ErrorReports;
1410

1511
namespace Coderr.Server.ReportAnalyzer.ErrorOrigins.Handlers
1612
{
@@ -21,14 +17,15 @@ public class StorePositionFromNewReport : IMessageHandler<ReportAddedToIncident>
2117
{
2218
private readonly ILog _logger = LogManager.GetLogger(typeof(StorePositionFromNewReport));
2319
private readonly IErrorOriginRepository _repository;
24-
private IConfiguration<OriginsConfiguration> _originConfiguration;
20+
private readonly IConfiguration<OriginsConfiguration> _originConfiguration;
2521

2622
/// <summary>
2723
/// Creates a new instance of <see cref="StorePositionFromNewReport" />.
2824
/// </summary>
2925
/// <param name="repository">repos</param>
3026
/// <exception cref="ArgumentNullException">repository</exception>
31-
public StorePositionFromNewReport(IErrorOriginRepository repository, IConfiguration<OriginsConfiguration> originConfiguration)
27+
public StorePositionFromNewReport(IErrorOriginRepository repository,
28+
IConfiguration<OriginsConfiguration> originConfiguration)
3229
{
3330
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
3431
_originConfiguration = originConfiguration;
@@ -43,16 +40,23 @@ public StorePositionFromNewReport(IErrorOriginRepository repository, IConfigurat
4340
/// </returns>
4441
public async Task HandleAsync(IMessageContext context, ReportAddedToIncident e)
4542
{
43+
// Random swedish IP for testing purposes
44+
if (e.Report.RemoteAddress == "::1" || e.Report.RemoteAddress == "127.0.0.1")
45+
e.Report.RemoteAddress = "94.254.57.227";
46+
47+
var numberStyles = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;
4648
var collection = e.Report.GetCoderrCollection();
4749
if (collection != null)
4850
{
4951
var latitude = 0d;
5052
var longitude = 0d;
5153
var gotLat = collection.Properties.TryGetValue("Longitude", out var longitudeStr)
52-
&& double.TryParse(longitudeStr, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out longitude);
54+
&& double.TryParse(longitudeStr, numberStyles,
55+
CultureInfo.InvariantCulture, out longitude);
5356

5457
var gotLong = collection.Properties.TryGetValue("Latitude", out var latitudeStr)
55-
&& double.TryParse(latitudeStr, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out latitude);
58+
&& double.TryParse(latitudeStr, numberStyles,
59+
CultureInfo.InvariantCulture, out latitude);
5660
if (gotLat && latitude > 0 && gotLong && longitude > 0)
5761
{
5862
var errorOrigin2 = new ErrorOrigin(e.Report.RemoteAddress, longitude, latitude);
@@ -65,66 +69,24 @@ public async Task HandleAsync(IMessageContext context, ReportAddedToIncident e)
6569
var latitude1 = e.Report.FindCollectionProperty("ReportLatitude");
6670
var longitude1 = e.Report.FindCollectionProperty("ReportLongitude");
6771
if (longitude1 != null
68-
&& double.TryParse(latitude1, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var latitude2)
72+
&& double.TryParse(latitude1, numberStyles, CultureInfo.InvariantCulture,
73+
out var latitude2)
6974
&& latitude1 != null
70-
&& double.TryParse(longitude1, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var longitude2))
75+
&& double.TryParse(longitude1, numberStyles, CultureInfo.InvariantCulture,
76+
out var longitude2))
7177
{
7278
var errorOrigin2 = new ErrorOrigin(e.Report.RemoteAddress, longitude2, latitude2);
7379
await _repository.CreateAsync(errorOrigin2, e.Incident.ApplicationId, e.Incident.Id, e.Report.Id);
7480
return;
7581
}
7682

7783

78-
if (string.IsNullOrEmpty(e.Report.RemoteAddress) || string.IsNullOrEmpty(_originConfiguration.Value?.ApiKey))
79-
{
80-
return;
81-
}
82-
83-
84-
// Random swedish IP for testing purposes
85-
if (e.Report.RemoteAddress == "::1" || e.Report.RemoteAddress == "127.0.0.1")
86-
e.Report.RemoteAddress = "94.254.57.227";
84+
if (string.IsNullOrEmpty(e.Report.RemoteAddress) ||
85+
string.IsNullOrEmpty(_originConfiguration.Value?.ApiKey)) return;
8786

88-
var errorOrigin = await LookupIpAddress(e);
89-
await _repository.CreateAsync(errorOrigin, e.Incident.ApplicationId, e.Incident.Id, e.Report.Id);
90-
}
91-
92-
private async Task<ErrorOrigin> LookupIpAddress(ReportAddedToIncident e)
93-
{
94-
var url = $"http://api.ipstack.com/{e.Report.RemoteAddress}?access_key={_originConfiguration.Value.ApiKey}";
95-
var request = WebRequest.CreateHttp(url);
96-
var json = "";
97-
ErrorOrigin errorOrigin;
98-
try
99-
{
100-
var response = await request.GetResponseAsync();
101-
var stream = response.GetResponseStream();
102-
var reader = new StreamReader(stream);
103-
json = await reader.ReadToEndAsync();
104-
var jsonObj = JObject.Parse(json);
105-
106-
/* /*{"ip":"94.254.21.175","country_code":"SE","country_name":"Sweden","region_code":"10","region_name":"Dalarnas Lan","city":"Falun","zipcode":"",
107-
* "latitude":60.6,"longitude":15.6333,
108-
* "metro_code":"","areacode":""}*/
109-
110-
var lat = double.Parse(jsonObj["latitude"].Value<string>(), CultureInfo.InvariantCulture);
111-
var lon = double.Parse(jsonObj["longitude"].Value<string>(), CultureInfo.InvariantCulture);
112-
errorOrigin = new ErrorOrigin(e.Report.RemoteAddress, lon, lat)
113-
{
114-
City = jsonObj["city"].ToString(),
115-
CountryCode = jsonObj["country_code"].ToString(),
116-
CountryName = jsonObj["country_name"].ToString(),
117-
RegionCode = jsonObj["region_code"].ToString(),
118-
RegionName = jsonObj["region_name"].ToString(),
119-
ZipCode = jsonObj["zip"].ToString()
120-
};
121-
}
122-
catch (Exception exception)
123-
{
124-
throw new InvalidOperationException($"Failed to call lookupService or parse the JSON: {json}.", exception);
125-
}
12687

127-
return errorOrigin;
88+
var origin = new ErrorOrigin(e.Report.RemoteAddress);
89+
await _repository.CreateAsync(origin, e.Incident.ApplicationId, e.Incident.Id, e.Report.Id);
12890
}
12991
}
13092
}

src/Server/Coderr.Server.ReportAnalyzer/ErrorOrigins/IErrorOriginRepository.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Threading.Tasks;
34
using Coderr.Server.Domain.Modules.ErrorOrigins;
45

@@ -22,6 +23,9 @@ public interface IErrorOriginRepository
2223
/// <returns>task</returns>
2324
/// <exception cref="ArgumentNullException">origin</exception>
2425
Task CreateAsync(ErrorOrigin entity, int applicationId, int incidentId, int reportId);
25-
26+
27+
Task<IList<ErrorOrigin>> GetPendingOrigins();
28+
29+
Task Update(ErrorOrigin entity);
2630
}
2731
}

0 commit comments

Comments
 (0)