public void MapMapEqual() { var from = new IpGeo { ContinentCode = "a", CountryCode = "b", Latitude = 1, Longitude = 2, YourIp = "0.3.0.0", Timestamp = DateTimeOffset.UtcNow }; var toFrom = from.To <IpGeoTableEntity>().To <IpGeo>(); DeepAssert.Equal(from, toFrom); }
public async Task <IpGeo?> GetLocation(IPAddress ipAddress) { if (ipAddress.IsInternal()) { return(null); } var ipString = ipAddress.ToString(); var row = await ipCacheTable_.RetrieveAsync <IpGeoTableEntity>("ip", ipString); if (row == null || row.Timestamp < DateTimeOffset.UtcNow - cacheTimeout_) { try { var ipGeo = new IpGeo { YourIp = ipString }; // TODO: make use of canonical representation of ip so avoid saving it again try { var ipInfo = await ipdata_.Lookup(ipString, x => x.Latitude, x => x.Longitude, x => x.RegionCode, x => x.CountryCode, x => x.ContinentCode); ipGeo.Latitude = ipInfo.Latitude !.Value; ipGeo.Longitude = ipInfo.Longitude !.Value; ipGeo.ContinentCode = ipInfo.ContinentCode; ipGeo.CountryCode = ipInfo.CountryCode; ipGeo.ETag = row?.ETag; } catch (ApiException ex) when(ex.StatusCode == HttpStatusCode.BadRequest) { // for private ip address it gives 400 with body `{"message": "10.65.1.37 is a private IP address"}` logger_.LogWarning("Failed to get geo-location for {ipString} with {StatusCode}", ipString, ex.StatusCode); return(null); } row = await ipCacheTable_.InsertOrMergeAsync(ipGeo.To <IpGeoTableEntity>()); } catch (Exception ex) { logger_.LogCritical(ex, $"Failed to get geo-location for {ipString}"); return(null); } } return(row.To <IpGeo>()); }