Skip to content
Snippets Groups Projects
Commit 0f81b509 authored by Petar Hristov's avatar Petar Hristov :speech_balloon:
Browse files

Merge branch 'Issue/2184-kpiGeneratorProject' into 'dev'

Update: KPI generator for Project

See merge request !7
parents 146eaa71 926e9168
Branches
Tags
2 merge requests!9Fix: Try/Catch,!7Update: KPI generator for Project
Pipeline #825460 passed
using KPIGenerator.Utils; using Coscine.Database.DataModel;
using Coscine.Database.Models;
using Coscine.Database.ReturnObjects;
using Coscine.ResourceTypes;
using KPIGenerator.Utils;
using Newtonsoft.Json;
using static KPIGenerator.Utils.CommandLineOptions; using static KPIGenerator.Utils.CommandLineOptions;
namespace KPIGenerator.Reportings.Project; namespace KPIGenerator.Reportings.Project;
public class ProjectReporting : Reporting<ProjectReportingOptions> public class ProjectReporting : Reporting<ProjectReportingOptions>
{ {
private readonly ProjectModel _projectModel;
private readonly ResourceModel _resourceModel;
private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectQuotaModel _projectQuotaModel;
private readonly ResourceTypeModel _resourceTypeModel;
public ProjectReporting(ProjectReportingOptions options) : base(options) public ProjectReporting(ProjectReportingOptions options) : base(options)
{ {
ReportingFileName = "projects.json"; ReportingFileName = "projects.json";
_projectModel = new ProjectModel();
_projectRoleModel = new ProjectRoleModel();
_projectQuotaModel = new ProjectQuotaModel();
_resourceModel = new ResourceModel();
_resourceTypeModel = new ResourceTypeModel();
} }
public override IEnumerable<ReportingFileObject> GenerateReporting() public override IEnumerable<ReportingFileObject> GenerateReporting()
{ {
/* var projects = _projectModel.GetAllWhere(r => r.Deleted.Equals(true) || r.Deleted.Equals(false));
* 1. Collect the reporting for the whole database -- General/{ReportingReportingFileName} var reportingFiles = new List<ReportingFileObject>();
* 2. Append to the list the same information per organization as folders -- Organizations/{OrgRorId}/{ReportingReportingFileName} var returnObjects = Generate(projects);
* --> See envisioned folder structure.
*/ //General File
throw new NotImplementedException(); reportingFiles.Add(new ReportingFileObject
{
Path = GetReportingPathGeneral(ReportingFileName),
Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjects, Formatting.Indented)),
});
// Per Organization
reportingFiles.AddRange(GeneratePerOrganization(returnObjects));
return reportingFiles;
}
private List<ReturnObject> Generate(IEnumerable<Coscine.Database.DataModel.Project> projects)
{
var returnObjects = new List<ReturnObject>();
foreach (var project in projects)
{
var projectReturnObject = _projectModel.CreateReturnObjectFromDatabaseObject(project);
var projectReportEntry = new ReturnObject
{
Id = projectReturnObject.Id,
DateCreated = projectReturnObject.DateCreated,
Organizations = GetOrganizations(projectReturnObject),
Disciplines = projectReturnObject.Disciplines.ToList(),
Deleted = projectReturnObject.Deleted,
ProjectVisibilityId = projectReturnObject.Visibility.Id,
GrantId = projectReturnObject.GrantId,
Users = _projectRoleModel.GetAllWhere(x => x.ProjectId == projectReturnObject.Id).Count(),
ResourceTypeQuota = GetResourceTypeQuota(projectReturnObject.Id)
};
returnObjects.Add(projectReportEntry);
}
return returnObjects;
}
private IEnumerable<ReportingFileObject> GeneratePerOrganization(List<ReturnObject> returnObjects)
{
var reportingFilesPerOrganization = new List<ReportingFileObject>();
var organizationsFromProjects = returnObjects.SelectMany(ro => ro.Organizations).DistinctBy(o => o.RorUrl);
foreach (var entry in organizationsFromProjects)
{
var organization = Organizations.Find(o => o.Equals(entry));
if (organization is null)
{
organization = _otherOrganization;
Console.WriteLine($"WARNING!: Organization \"{entry.RorUrl}\" could not be correctly identified. Will use \"{_otherOrganization.RorUrl}\".");
}
var returnObjectsForOrganization = returnObjects.Where(ro => ro.Organizations.Select(o => o.RorUrl).Any(e => e.Equals(entry.RorUrl)));
reportingFilesPerOrganization.Add(new ReportingFileObject
{
Path = GetReportingPathOrganization(organization.RorUrl.Replace("https://ror.org/", "").ToLower(), ReportingFileName),
Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjectsForOrganization, Formatting.Indented))
});
}
return reportingFilesPerOrganization;
}
private List<ResourceTypeQuotaReturnObject> GetResourceTypeQuota(Guid projectId)
{
var result = new List<ResourceTypeQuotaReturnObject>();
var types = ResourceTypeFactory.Instance.GetResourceTypes();
var resourceTypes = _resourceTypeModel.GetAllWhere(x => types.Any(t => x.SpecificType.Equals(t)));
var quotas = _projectQuotaModel.GetAllWhere(x => x.ProjectId == projectId);
var resourceQuotas = quotas.Where(x => resourceTypes.Any(e => x.ResourceTypeId.Equals(e.Id)));
result.AddRange(resourceQuotas.Select(x => CreateQuotaReturnObject(x, projectId)).ToList());
return result;
}
private ResourceTypeQuotaReturnObject CreateQuotaReturnObject(ProjectQuota projectQuota, Guid projectId)
{
return new ResourceTypeQuotaReturnObject
{
ResourceType = _resourceTypeModel.GetById(projectQuota.ResourceTypeId).SpecificType,
Allocated = new QuotaDimObject()
{
Value = projectQuota.Quota,
Unit = QuotaUnit.GibiBYTE,
},
Maximum = new QuotaDimObject()
{
Value = projectQuota.MaxQuota,
Unit = QuotaUnit.GibiBYTE,
},
TotalReserved = new QuotaDimObject()
{
Value = CalculateAllocatedForAll(_resourceTypeModel.GetById(projectQuota.ResourceTypeId), projectId),
Unit = QuotaUnit.GibiBYTE,
},
TotalUsed = new QuotaDimObject()
{
Value = CalculateUsedForAll(_resourceTypeModel.GetById(projectQuota.ResourceTypeId), projectId),
Unit = QuotaUnit.BYTE,
},
};
}
private int CalculateUsedForAll(ResourceType resourceType, Guid projectId)
{
var resources = _resourceModel.GetAllWhere((resource) =>
(from projectResource in resource.ProjectResources
where projectResource.ProjectId == projectId
select projectResource).Any() &&
resource.TypeId == resourceType.Id);
var used = resources.Sum(resource =>
{
// Linked has no quota.
var rt = ResourceTypeFactory.Instance.GetResourceType(resource);
if (rt.GetResourceTypeInformation().Result.IsQuotaAvailable)
{
return rt.GetResourceQuotaUsed(resource.Id.ToString(), _resourceModel.GetResourceTypeOptions(resource.Id)).Result;
}
else
{
return 0;
}
}
);
return (int)used;
}
private int CalculateAllocatedForAll(ResourceType resourceType, Guid projectId)
{
var resources = _resourceModel.GetAllWhere((resource) =>
(from projectResource in resource.ProjectResources
where projectResource.ProjectId == projectId
select projectResource).Any() &&
resource.TypeId == resourceType.Id);
var allocated = resources.Sum(resource =>
{
// Linked has no quota.
var rt = ResourceTypeFactory.Instance.GetResourceType(resource);
if (rt.GetResourceTypeInformation().Result.IsQuotaAvailable)
{
return rt.GetResourceQuotaAvailable(resource.Id.ToString(), _resourceModel.GetResourceTypeOptions(resource.Id)).Result;
}
else
{
return 0;
}
});
return (int)allocated;
}
private List<Organization> GetOrganizations(ProjectObject project)
{
var result = new List<Organization>();
foreach (var entry in project.Organizations)
{
result.Add(FetchOrganizationByRor(entry.Url));
}
return result;
} }
} }
\ No newline at end of file
namespace KPIGenerator.Reportings.Project; using Coscine.Database.ReturnObjects;
using KPIGenerator.Utils;
namespace KPIGenerator.Reportings.Project;
/// <summary> /// <summary>
/// Object containing the JSON structure for the reporting /// Object containing the JSON structure for the reporting
/// </summary> /// </summary>
public class ReturnObject public class ReturnObject
{ {
public Guid Id { get; set; }
public DateTime? DateCreated { get; set; } = null;
public List<Organization>? Organizations { get; set; } = new();
public List<DisciplineObject> Disciplines { get; set; } = new();
public bool Deleted { get; set; }
public Guid ProjectVisibilityId { get; set; }
public string? GrantId { get; set; }
public int? Users { get; set; } = null;
public List<ResourceTypeQuotaReturnObject> ResourceTypeQuota { get; set; } = new();
}
public class ResourceTypeQuotaReturnObject
{
public string ResourceType
{
get;
set;
} = null!;
public QuotaDimObject TotalUsed
{
get;
set;
} = null!;
public QuotaDimObject TotalReserved
{
get;
set;
} = null!;
public QuotaDimObject Allocated
{
get;
set;
} = null!;
public QuotaDimObject Maximum
{
get;
set;
} = null!;
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment