Metrics bug fixes

This commit is contained in:
Timothy Baldridge 2020-01-09 19:06:11 -07:00
parent ad5c8b83e6
commit 94b01a0454
12 changed files with 111 additions and 94 deletions

View File

@ -4,10 +4,11 @@ using Wabbajack.BuildServer.Models;
namespace Wabbajack.BuildServer.Controllers
{
[ApiController]
public abstract class AControllerBase<T> : ControllerBase
{
protected readonly ILogger<T> Logger;
protected readonly DBContext Db;
protected readonly ILogger<T> Logger;
protected AControllerBase(ILogger<T> logger, DBContext db)
{

View File

@ -1,12 +1,8 @@
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Threading.Tasks;
using System.Threading.Tasks;
using GraphQL;
using GraphQL.Language.AST;
using GraphQL.Types;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Wabbajack.BuildServer.GraphQL;
using Wabbajack.BuildServer.Models;
@ -24,12 +20,8 @@ namespace Wabbajack.BuildServer.Controllers
public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
{
var inputs = query.Variables.ToInputs();
var schema = new Schema
{
Query = new Query(Db),
Mutation = new Mutation(Db)
};
var schema = new Schema {Query = new Query(Db), Mutation = new Mutation(Db)};
var result = await new DocumentExecuter().ExecuteAsync(_ =>
{
_.Schema = schema;
@ -37,14 +29,13 @@ namespace Wabbajack.BuildServer.Controllers
_.OperationName = query.OperationName;
_.Inputs = inputs;
});
if(result.Errors?.Count > 0)
if (result.Errors?.Count > 0)
{
return BadRequest();
}
return Ok(result);
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Wabbajack.BuildServer.Models;
using Wabbajack.Common;
namespace Wabbajack.BuildServer.Controllers
{
[Route("/heartbeat")]
public class Heartbeat : AControllerBase<Heartbeat>
{
static Heartbeat()
{
_startTime = DateTime.Now;
}
private static DateTime _startTime;
public Heartbeat(ILogger<Heartbeat> logger, DBContext db) : base(logger, db)
{
}
[HttpGet]
public async Task<TimeSpan> GetHeartbeat()
{
return DateTime.Now - _startTime;
}
}
}

View File

@ -22,7 +22,7 @@ namespace Wabbajack.BuildServer.Controllers
[Route("{xxHashAsBase64}")]
public async Task<IndexedVirtualFile> GetFile(string xxHashAsBase64)
{
var id = xxHashAsBase64;//.FromHex().ToBase64();
var id = xxHashAsBase64.FromHex().ToBase64();
var query = new[]
{
new BsonDocument("$match",
@ -47,16 +47,18 @@ namespace Wabbajack.BuildServer.Controllers
if (t == null)
return null;
Dictionary<string, TreeResult> indexed_children= new Dictionary<string, TreeResult>();
if (t.IsArchive)
Dictionary<string, TreeResult> indexed_children = new Dictionary<string, TreeResult>();
if (t.IsArchive)
indexed_children = t.ChildFiles.ToDictionary(t => t.Hash);
var file = new IndexedVirtualFile
{
Name = Name,
Size = t.Size,
Hash = t.Hash,
Children = t.IsArchive ? t.Children.Select(child => Convert(indexed_children[child.Hash], child.Name)).ToList() : new List<IndexedVirtualFile>()
Hash = t.Hash,
Children = t.IsArchive
? t.Children.Select(child => Convert(indexed_children[child.Hash], child.Name)).ToList()
: new List<IndexedVirtualFile>()
};
return file;
}
@ -68,7 +70,5 @@ namespace Wabbajack.BuildServer.Controllers
{
public List<TreeResult> ChildFiles { get; set; }
}
}
}

View File

@ -26,6 +26,5 @@ namespace Wabbajack.BuildServer.Controllers
.OrderByDescending(j => j.Priority)
.ToListAsync();
}
}
}

View File

@ -11,13 +11,12 @@ namespace Wabbajack.BuildServer.Controllers
{
[ApiController]
[Route("/lists")]
public class ListValidation : AControllerBase<ListValidation>
{
public ListValidation(ILogger<ListValidation> logger, DBContext db) : base(logger, db)
{
}
[HttpGet]
[Route("status.json")]
public async Task<IList<ModlistSummary>> HandleGetLists()

View File

@ -1,35 +0,0 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Wabbajack.BuildServer.Models;
using Wabbajack.Common;
namespace Wabbajack.BuildServer.Controllers
{
[Route("/metrics")]
public class Metrics : AControllerBase<Metrics>
{
[HttpGet]
[Route("{Action}/Value")]
public async Task<string> NewMetric(string Action, string Value)
{
var date = DateTime.UtcNow;
await Log(date, Action, Value, Request.Headers[Consts.MetricsKeyHeader].FirstOrDefault());
return date.ToString();
}
public Metrics(ILogger<Metrics> logger, DBContext db) : base(logger, db)
{
}
internal async Task Log(DateTime timestamp, string action, string subject, string metricsKey = null)
{
var msg = new[] {string.Join("\t", new[]{timestamp.ToString(), metricsKey, action, subject})};
Utils.Log(msg.First());
await Db.Metrics.InsertOneAsync(new Metric {Timestamp = timestamp, Action = action, Subject = subject, MetricsKey = metricsKey});
}
}
}

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Wabbajack.BuildServer.Models;
using Wabbajack.Common;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack.BuildServer.Controllers
{
[ApiController]
[Route("/metrics")]
public class MetricsController : AControllerBase<MetricsController>
{
public MetricsController(ILogger<MetricsController> logger, DBContext db) : base(logger, db)
{
}
[HttpGet]
[Route("{Subject}/{Value}")]
public async Task<Result> LogMetricAsync(string Subject, string Value)
{
var date = DateTime.UtcNow;
await Log(date, Subject, Value, Request.Headers[Consts.MetricsKeyHeader].FirstOrDefault());
return new Result { Timestamp = date};
}
private async Task Log(DateTime timestamp, string action, string subject, string metricsKey = null)
{
Logger.Log(LogLevel.Information, $"Log - {timestamp} {action} {subject} {metricsKey}");
await Db.Metrics.InsertOneAsync(new Metric
{
Timestamp = timestamp, Action = action, Subject = subject, MetricsKey = metricsKey
});
}
public class Result
{
public DateTime Timestamp { get; set; }
}
}
}

View File

@ -13,14 +13,13 @@ namespace Wabbajack.BuildServer.Controllers
[Route("/v1/games/")]
public class NexusCache : AControllerBase<NexusCache>
{
public NexusCache(ILogger<NexusCache> logger, DBContext db) : base(logger, db)
{
}
/// <summary>
/// Looks up the mod details for a given Gamename/ModId pair. If the entry is not found in the cache it will
/// be requested from the server (using the caller's Nexus API key if provided).
/// Looks up the mod details for a given Gamename/ModId pair. If the entry is not found in the cache it will
/// be requested from the server (using the caller's Nexus API key if provided).
/// </summary>
/// <param name="db"></param>
/// <param name="GameName">The Nexus game name</param>
@ -38,13 +37,7 @@ namespace Wabbajack.BuildServer.Controllers
var api = await NexusApiClient.Get(Request.Headers["apikey"].FirstOrDefault());
var path = $"/v1/games/{GameName}/mods/{ModId}.json";
var body = await api.Get<ModInfo>(path);
result = new NexusCacheData<ModInfo>
{
Data = body,
Path = path,
Game = GameName,
ModId = ModId
};
result = new NexusCacheData<ModInfo> {Data = body, Path = path, Game = GameName, ModId = ModId};
try
{
await Db.NexusModInfos.InsertOneAsync(result);
@ -74,10 +67,7 @@ namespace Wabbajack.BuildServer.Controllers
var body = await api.Get<NexusApiClient.GetModFilesResponse>(path);
result = new NexusCacheData<NexusApiClient.GetModFilesResponse>
{
Data = body,
Path = path,
Game = GameName,
ModId = ModId
Data = body, Path = path, Game = GameName, ModId = ModId
};
try
{
@ -85,7 +75,6 @@ namespace Wabbajack.BuildServer.Controllers
}
catch (MongoWriteException)
{
}
method = "NOT_CACHED";
@ -96,10 +85,11 @@ namespace Wabbajack.BuildServer.Controllers
}
[HttpGet]
[Route("{GameName}/mods/{ModId}/files/{FileId}.json")]
[Route("{GameName}/mods/{ModId}/files/{FileId}.json")]
public async Task<object> GetFileInfo(string GameName, string ModId, string FileId)
{
var result = await Db.NexusFileInfos.FindOneAsync(info => info.Game == GameName && info.ModId == ModId && info.FileId == FileId);
var result = await Db.NexusFileInfos.FindOneAsync(info =>
info.Game == GameName && info.ModId == ModId && info.FileId == FileId);
string method = "CACHED";
if (result == null)
@ -109,9 +99,9 @@ namespace Wabbajack.BuildServer.Controllers
var body = await api.Get<NexusFileInfo>(path);
result = new NexusCacheData<NexusFileInfo>
{
Data = body,
Path = path,
Game = GameName,
Data = body,
Path = path,
Game = GameName,
ModId = ModId,
FileId = FileId
};
@ -121,7 +111,6 @@ namespace Wabbajack.BuildServer.Controllers
}
catch (MongoWriteException)
{
}
method = "NOT_CACHED";
@ -130,7 +119,5 @@ namespace Wabbajack.BuildServer.Controllers
Response.Headers.Add("x-cache-method", method);
return result.Data;
}
}
}

View File

@ -15,12 +15,12 @@ namespace Wabbajack.BuildServer
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("http://*:5000", "https://*:5001");
webBuilder.UseUrls("http://*:5000");
webBuilder.UseStartup<Startup>();
});
}

View File

@ -22,6 +22,7 @@ using Swashbuckle.AspNetCore.Swagger;
using Wabbajack.BuildServer.Controllers;
using Wabbajack.BuildServer.Models;
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
using Wabbajack.BuildServer.Controllers;
using Microsoft.Extensions.FileProviders;
using Directory = System.IO.Directory;
@ -44,15 +45,15 @@ namespace Wabbajack.BuildServer
{
c.SwaggerDoc("v1", new OpenApiInfo {Title = "Wabbajack Build API", Version = "v1"});
});
services.AddSingleton<DBContext>();
services.AddSingleton<JobManager>();
services.AddSingleton<AppSettings>();
services.AddControllers(o =>
services.AddMvc();
services.AddControllers()
.AddNewtonsoftJson(o =>
{
}).AddNewtonsoftJson(o =>
{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

View File

@ -2,11 +2,8 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Exe</OutputType>
<UserSecretsId>aspnet-Wabbajack.BuildServer-6E798B30-DB04-4436-BE65-F043AF37B314</UserSecretsId>
<WebProject_DirectoryAccessLevelKey>0</WebProject_DirectoryAccessLevelKey>
<PublishTrimmed>true</PublishTrimmed>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU;x64</Platforms>