Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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