Skip to content
Snippets Groups Projects

New: added analytics logger (coscine/issues#2001)

Merged L. Ellenbeck requested to merge Issue/2001-extendAnalyticsLogger into dev
1 file
+ 63
32
Compare changes
  • Side-by-side
  • Inline
@@ -6,14 +6,15 @@ using Coscine.ApiCommons;
using Coscine.Configuration;
using Coscine.Database.DataModel;
using Coscine.Database.Models;
using Coscine.Logging;
using Coscine.Metadata;
using Coscine.ResourceLoader;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
namespace Coscine.Api.Admin.Controllers
{
/// <summary>
@@ -22,7 +23,7 @@ namespace Coscine.Api.Admin.Controllers
[Authorize]
public class AdminController : Controller
{
private readonly RdfStoreConnector _rdfStoreConnector = new RdfStoreConnector(Program.Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
private readonly RdfStoreConnector _rdfStoreConnector = new(Program.Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
private readonly Authenticator _authenticator;
private readonly IConfiguration _configuration;
private readonly string _graphUrl;
@@ -33,16 +34,17 @@ namespace Coscine.Api.Admin.Controllers
private readonly string _adminRole;
private readonly ResourceModel _resourceModel;
private readonly ProjectModel _projectModel;
private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectQuotaModel _projectQuotaModel;
private readonly ResourceTypeModel _resourceTypeModel;
private readonly Emitter _emitter;
private readonly float _oneGb = 1024 * 1024 * 1024;
private readonly CoscineLogger _coscineLogger;
/// <summary>
/// Default Constructor.
/// </summary>
public AdminController()
public AdminController(ILogger<AdminController> logger)
{
_authenticator = new Authenticator(this, Program.Configuration);
_configuration = Program.Configuration;
@@ -54,16 +56,17 @@ namespace Coscine.Api.Admin.Controllers
_adminRole = "supportAdmin";
_resourceModel = new ResourceModel();
_projectModel = new ProjectModel();
_projectRoleModel = new ProjectRoleModel();
_projectQuotaModel = new ProjectQuotaModel();
_resourceTypeModel = new ResourceTypeModel();
_emitter = new Emitter(Program.Configuration);
_coscineLogger = new CoscineLogger(logger);
}
/// <summary>
/// Check if the user has a specific role.
/// </summary>
/// <param name="userId">Id (guid) if the user.</param>
/// <param name="userId">Id (GUID) if the user.</param>
/// <param name="role">The role of the user.</param>
/// <returns>True if user has the role and false if not.</returns>
private bool HasRole(string userId, string role)
@@ -82,18 +85,13 @@ namespace Coscine.Api.Admin.Controllers
// Get the role based on the blank node and compare it to the requested role
var roleTriples = graph.GetTriplesWithSubjectPredicate(userSubject, graph.CreateUriNode(new Uri(_roleUrl)));
if (roleTriples?.FirstOrDefault()?.Object.ToString() != $"{_roleUrlPrefix}{role}")
{
return false;
}
return true;
return (roleTriples?.FirstOrDefault()?.Object.ToString()) == _roleUrlPrefix + role;
}
/// <summary>
/// Sum up allocated quota for all resources of a given resource type within a project.
/// </summary>
/// <param name="resourceType">The used resourcetype.</param>
/// <param name="resourceType">The used resource type.</param>
/// <param name="projectId">The used project.</param>
/// <returns>Allocated quota of the given resource type in the project.</returns>
private int CalculateAllocatedForAll(ResourceType resourceType, Guid projectId)
@@ -112,7 +110,7 @@ namespace Coscine.Api.Admin.Controllers
/// <summary>
/// Sum up used quota for all resources of a given resource type within a project.
/// </summary>
/// <param name="resourceType">The used resourcetype.</param>
/// <param name="resourceType">The used resource type.</param>
/// <param name="projectId">The used project.</param>
/// <returns>Used quota of the given resource type in the project.</returns>
private int CalculateUsedForAll(ResourceType resourceType, Guid projectId)
@@ -124,15 +122,15 @@ namespace Coscine.Api.Admin.Controllers
where projectResource.ProjectId == projectId
select projectResource).Any() &&
resource.TypeId == resourceType.Id);
var used= Math.Ceiling(resources.Sum(y => resourceTypeDefinition.GetResourceQuotaUsed(y.Id.ToString(), _resourceModel.GetResourceTypeOptions(y.Id)).Result / _oneGb));
var used = Math.Ceiling(resources.Sum(y => resourceTypeDefinition.GetResourceQuotaUsed(y.Id.ToString(), _resourceModel.GetResourceTypeOptions(y.Id)).Result / _oneGb));
return (int)used;
}
/// <summary>
/// Find the project related to the the projectString(Guid or slug)
/// Find the project related to the projectString(GUID or slug)
/// </summary>
/// <param name="projectString">Either the id (guid) of the project or the slug.</param>
/// <returns>Json list of all quotas.</returns>
/// <param name="projectString">Either the id (GUID) of the project or the slug.</param>
/// <returns>JSON list of all quotas.</returns>
[HttpGet("[controller]/{projectString}")]
public ActionResult<ProjectObject> GetProject(string projectString)
{
@@ -147,12 +145,13 @@ namespace Coscine.Api.Admin.Controllers
if (Guid.TryParse(projectString, out Guid guid))
{
project = _projectModel.GetById(guid);
} else
}
else
{
project = _projectModel.GetBySlug(projectString);
}
if(project == null)
if (project == null)
{
return NotFound("Project was not found.");
}
@@ -164,12 +163,13 @@ namespace Coscine.Api.Admin.Controllers
GUID = project.Id,
Name = project.ProjectName,
ShortName = project.DisplayName,
Quotas = quotas.Select(x => new ProjectQuotaObject {
Quotas = quotas.Select(x => new ProjectQuotaObject
{
QuotaId = x.RelationId,
ResourceType = _resourceTypeModel.GetById(x.ResourceTypeId).DisplayName,
ResourceType = _resourceTypeModel.GetById(x.ResourceTypeId).DisplayName,
Quota = x.Quota,
MaxQuota = x.MaxQuota,
Used = CalculateUsedForAll(_resourceTypeModel.GetById(x.ResourceTypeId), project.Id),
Used = CalculateUsedForAll(_resourceTypeModel.GetById(x.ResourceTypeId), project.Id),
Allocated = CalculateAllocatedForAll(_resourceTypeModel.GetById(x.ResourceTypeId), project.Id)
}).ToList(),
};
@@ -178,21 +178,21 @@ namespace Coscine.Api.Admin.Controllers
/// <summary>
/// Update the project quota
/// </summary>
/// <param name="updateQuotaParameter">Json object for updatin quota.</param>
/// <returns>NoContent (204) ond success.</returns>
/// <param name="updateQuotaParameter">JSON object for updating quota.</param>
/// <returns>NoContent (204) on success.</returns>
[HttpPost("[controller]/")]
public IActionResult UpdateQuota([FromBody]UpdateQuotaParameterObject updateQuotaParameter)
public IActionResult UpdateQuota([FromBody] UpdateQuotaParameterObject updateQuotaParameter)
{
var user = _authenticator.GetUserId();
if (!HasRole(user, _adminRole))
var user = _authenticator.GetUser();
if (!HasRole(user.Id.ToString(), _adminRole))
{
return Unauthorized($@"User has not the role: ""{_adminRole}"".");
}
var projectQuotaModel = new ProjectQuotaModel();
var projectQuota = projectQuotaModel.GetById(updateQuotaParameter.QuotaId);
if(projectQuota == null)
if (projectQuota == null)
{
return NotFound("Quota was not found.");
}
@@ -201,9 +201,40 @@ namespace Coscine.Api.Admin.Controllers
projectQuota.Quota = projectQuota.MaxQuota;
projectQuotaModel.Update(projectQuota);
_emitter.EmitQuotaChanged(new AdminEventArgs (Program.Configuration) { ProjectId = projectQuota.ProjectId });
_emitter.EmitQuotaChanged(new AdminEventArgs(Program.Configuration) { ProjectId = projectQuota.ProjectId });
if (Request.Query != null && Request.Query["noanalyticslog"] != "true")
{
var project = _projectModel.GetById(projectQuota.ProjectId);
LogAnalyticsAdminProjectQuotaChange(project, user);
}
return NoContent();
}
private void LogAnalyticsAdminProjectQuotaChange(Project project, User user)
{
var quotas = _projectQuotaModel.GetAllWhere(x => x.ProjectId == project.Id);
var quotaObjects = quotas.Select(x => new ProjectQuotaObject
{
QuotaId = x.RelationId,
ResourceType = _resourceTypeModel.GetById(x.ResourceTypeId).DisplayName,
Quota = x.Quota,
MaxQuota = x.MaxQuota,
Used = x.Quota,
Allocated = CalculateAllocatedForAll(_resourceTypeModel.GetById(x.ResourceTypeId), project.Id)
}).ToList();
_coscineLogger.AnalyticsLog(
new AnalyticsLogObject
{
Type = "Action",
Operation = "Admin Project Quota Change",
RoleId = _projectRoleModel.GetGetUserRoleForProject(project.Id, user.Id).ToString(),
UserId = user.Id.ToString(),
ProjectId = project.Id.ToString(),
QuotaSize = quotaObjects.ConvertAll(x => $"{x.ResourceType}: {x.Allocated}/{x.Used}")
});
}
}
}
}
\ No newline at end of file
Loading