Skip to content

Commit

Permalink
feat(issue-156): add test skeleton for on-tracker
Browse files Browse the repository at this point in the history
Merge pull request #157 from live-dev999/live-dev999/issue156
  • Loading branch information
live-dev999 committed Jan 16, 2022
2 parents b1e5be9 + dec1c7f commit 9d7822d
Show file tree
Hide file tree
Showing 15 changed files with 528 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using O2.Tracker.DbUtility;

namespace O2.OnTracker.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IGeoIpAddressResolver _geoIpAddressResolver;

public ValuesController(IGeoIpAddressResolver geoIpAddressResolver)
{
_geoIpAddressResolver = geoIpAddressResolver;
}
// GET api/values
[HttpGet]
public ActionResult Get()
{
// var ip = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
IPAddress remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;//Request.HttpContext.Connection.RemoteIpAddress;
string result = "";
if (remoteIpAddress != null)
{
// If we got an IPV6 address, then we need to ask the network for the IPV4 address
// This usually only happens when the browser is on the same machine as the server.
if (remoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
remoteIpAddress = System.Net.Dns.GetHostEntry(remoteIpAddress).AddressList
.First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
}
result = remoteIpAddress.ToString();
}

if (result.ToString() == "127.0.0.1")
return Ok("request with localhost");
return Ok(_geoIpAddressResolver.ResolveAddress(IPAddress.Parse(result.ToString())));
// return new string[] { "value1", "value2" };
}

// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}

// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}

// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}

// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace O2.OnTracker.Api.IoC
{
public static class ServiceCollectionExtensions
{
// ReSharper disable once InconsistentNaming
public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfiguration configuration)
where TConfig : class, new()
{
if (services == null)
throw new ArgumentNullException(nameof(services));

if (configuration == null)
throw new ArgumentNullException(nameof(configuration));

var config = new TConfig();
configuration.Bind(config);
services.AddSingleton(config);
return config;
}
public static IServiceCollection AddBusiness(this IServiceCollection services)
{
// services.AddSingleton<IEmailSenderService, InMemoryEmailSenderService>();
// // Include DataLayer
// // services.AddScoped<IEmailSenderService, EmailSenderService>();
// //more business services...
//
// services.AddSingleton<IEmailSender, EmailSender>();
return services;
}

public static IServiceCollection AddRequiredMvcComponents(this IServiceCollection services)
{
// services.AddTransient<ApiExceptionFilter>();

var mvcBuilder = services.AddMvc(options =>
{
// options.Filters.Add<ApiExceptionFilter>();
});
// mvcBuilder.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//var mvcBuilder = services.AddMvcCore(options =>
//{
// options.Filters.Add<ApiExceptionFilter>();
//});
//mvcBuilder.AddJsonFormatters();

//mvcBuilder.AddAuthorization();
// mvcBuilder.AddFormatterMappings();
//mvcBuilder.AddRazorViewEngine();
//mvcBuilder.AddRazorPages();
//mvcBuilder.AddCacheTagHelper();
//mvcBuilder.AddDataAnnotations();

//mvcBuilder.AddCors();
return services;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using MaxMind.Db;
using O2.OnTracker.Api.Setup;

namespace O2.Tracker.DbUtility
{
public sealed class MaxMindLocalGeoIpAddressResolver : IGeoIpAddressResolver
{
private const string DefaultLang = "en";

private const FileAccessMode AccessMode = FileAccessMode.Memory;

// private static readonly ILog m_log = LogManager.GetLogger(typeof(MaxMindLocalGeoIpAddressResolver));

private readonly Reader m_reader;

public MaxMindLocalGeoIpAddressResolver(GeoDatabase setting)
{
// var path = geoDbSetting;
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + setting.ConnectionDb;//+ "/geoip/" + "GeoLite2-City.mmdb";
if (string.IsNullOrWhiteSpace(path))
throw new Exception("MaxMind local database path is not configured");

m_reader = new Reader(path);
// if (m_log.IsDebugEnabled)
// m_log.Debug($"{nameof(settings.MaxMindGeoIpDatabasePath)}='{path}'.");

m_reader = new Reader(path, AccessMode);
}

public GeoLocation ResolveAddress(IPAddress ip)
{
var response = m_reader.Find<GeoLocationData>(ip);
if (response == null)
return null;

var result = new GeoLocation
{
Country = response.Country?.Names[DefaultLang],
City = response.City?.Names[DefaultLang]
};
var location = response.Location;
if (location?.HasCoordinates == true)
result.Point = new Point
{
lat = location.Latitude.Value,
lon = location.Longitude.Value
};

return result;
}

private class NamedEntity
{
[Constructor]
protected NamedEntity(
IDictionary<string, string> names = null)
{
Names = names != null ? new Dictionary<string, string>(names) : new Dictionary<string, string>();
}

public IReadOnlyDictionary<string, string> Names { get; }
}

private sealed class Country : NamedEntity
{
[Constructor]
public Country(
IDictionary<string, string> names = null)
: base(names)
{
}
}

private sealed class Location
{
[Constructor]
public Location(
double? latitude = null,
double? longitude = null)
{
Latitude = latitude;
Longitude = longitude;
}

public bool HasCoordinates => Latitude.HasValue && Longitude.HasValue;

public double? Latitude { get; }

public double? Longitude { get; }
}

private sealed class GeoLocationData
{
[Constructor]
public GeoLocationData(
Country country,
NamedEntity city,
Location location)
{
Country = country;
City = city;
Location = location;
}

public Country Country { get; }
public NamedEntity City { get; }
public Location Location { get; }
}

public void Dispose()
{
m_reader.Dispose();
}
}
}


39 changes: 39 additions & 0 deletions src/Services/on-tracker/O2.OnTracker.Api/O2.OnTracker.Api.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\O2.Tracker.DbUtility\O2.Tracker.DbUtility.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="geoip\GeoLite2-City.mmdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Remove="geoip\**" />
</ItemGroup>

<ItemGroup>
<Compile Remove="geoip\**" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Remove="geoip\**" />
</ItemGroup>

<ItemGroup>
<Content Remove="geoip\**" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions src/Services/on-tracker/O2.OnTracker.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace O2.OnTracker.Api
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"profiles": {
"O2.OnTracker.Api": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"applicationUrl": "https://localhost:57549;http://localhost:43192",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
7 changes: 7 additions & 0 deletions src/Services/on-tracker/O2.OnTracker.Api/Setup/GeoDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace O2.OnTracker.Api.Setup
{
public class GeoDatabase
{
public string ConnectionDb { get; set; }
}
}
Loading

0 comments on commit 9d7822d

Please sign in to comment.