Skip to content
Snippets Groups Projects

Sprint/2021 01

Merged Marcel Nellesen requested to merge Sprint/2021-01 into master
6 files
+ 297
42
Compare changes
  • Side-by-side
  • Inline
Files
6
using Coscine.Action;
using Coscine.Action;
using Coscine.Action.EventArgs;
using Coscine.Action.EventArgs;
 
using Coscine.Api.Project.ParameterObjects;
 
using Coscine.Api.Project.ReturnObjects;
using Coscine.ApiCommons;
using Coscine.ApiCommons;
using Coscine.ApiCommons.Factories;
using Coscine.ApiCommons.Factories;
using Coscine.Configuration;
using Coscine.Configuration;
@@ -32,8 +34,12 @@ namespace Coscine.Api.Project.Controllers
@@ -32,8 +34,12 @@ namespace Coscine.Api.Project.Controllers
private readonly Emitter _emitter;
private readonly Emitter _emitter;
private readonly ActivatedFeaturesModel _activatedFeaturesModel;
private readonly ActivatedFeaturesModel _activatedFeaturesModel;
private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectRoleModel _projectRoleModel;
 
private readonly ProjectQuotaModel _projectQuotaModel;
 
private readonly ResourceTypeModel _resourceTypeModel;
 
private readonly ResourceModel _resourceModel;
private readonly CoscineLogger _coscineLogger;
private readonly CoscineLogger _coscineLogger;
private readonly AnalyticsLogObject _analyticsLogObject;
private readonly AnalyticsLogObject _analyticsLogObject;
 
private readonly int _maxAvailable = 100;
/// <summary>
/// <summary>
/// ProjectController constructor
/// ProjectController constructor
@@ -47,6 +53,9 @@ namespace Coscine.Api.Project.Controllers
@@ -47,6 +53,9 @@ namespace Coscine.Api.Project.Controllers
_emitter = new Emitter(_configuration);
_emitter = new Emitter(_configuration);
_activatedFeaturesModel = new ActivatedFeaturesModel();
_activatedFeaturesModel = new ActivatedFeaturesModel();
_projectRoleModel = new ProjectRoleModel();
_projectRoleModel = new ProjectRoleModel();
 
_resourceTypeModel = new ResourceTypeModel();
 
_resourceModel = new ResourceModel();
 
_projectQuotaModel = new ProjectQuotaModel();
_coscineLogger = new CoscineLogger(logger);
_coscineLogger = new CoscineLogger(logger);
_analyticsLogObject = new AnalyticsLogObject();
_analyticsLogObject = new AnalyticsLogObject();
}
}
@@ -155,56 +164,231 @@ namespace Coscine.Api.Project.Controllers
@@ -155,56 +164,231 @@ namespace Coscine.Api.Project.Controllers
}
}
/// <summary>
/// <summary>
/// Retrieves the quota for the selected project
/// Retrieves the quota for the selected project.
/// </summary>
/// </summary>
/// <param name="id">Id of the resource</param>
/// <param name="projectId">Id of the project.</param>
/// <returns>Json object or Statuscode 401</returns>
/// <returns>List of project quotas</returns>
[HttpGet("[controller]/{id}/quotas")]
[HttpGet("[controller]/{projectId}/quota/-/all")]
public ActionResult<IEnumerable<ProjectQuota>> Quotas(string id)
public ActionResult<IEnumerable<ProjectQuota>> Quotas(string projectId)
{
{
var user = _authenticator.GetUser();
var user = _authenticator.GetUser();
var projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body);
var guidId = Guid.Parse(id);
if (!Guid.TryParse(projectId, out Guid projectGuid))
var project = _projectModel.GetById(guidId);
{
if (_projectModel.HasAccess(user, project, UserRoles.Owner))
return BadRequest($"{projectId} is not a guid.");
 
}
 
 
var project = _projectModel.GetById(projectGuid);
 
 
if (project == null)
{
{
ProjectQuotaModel projectQuotaModel = new ProjectQuotaModel();
return NotFound($"Could not find project with id: {projectId}");
var projectQuotas =
}
projectQuotaModel.GetAllWhere((projectQuota) =>
projectQuota.ProjectId == guidId
if (!_projectModel.HasAccess(user, project, UserRoles.Owner))
&& projectQuota.ResourceType.Enabled == true)
{
.Select((projectQuota) => projectQuotaModel.CreateReturnObjectFromDatabaseObject(projectQuota));
return Unauthorized("The user is not authorized to perform a get on the selected project!");
 
}
 
var projectQuotas =
 
_projectQuotaModel.GetAllWhere((projectQuota) =>
 
projectQuota.ProjectId == projectGuid
 
&& projectQuota.ResourceType.Enabled == true);
ResourceModel resourceModel = new ResourceModel();
var resourceTypes = _resourceTypeModel.GetAllWhere(x => x.Enabled);
RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
var returnList = new List<dynamic>();
return Json(resourceTypes.Select(x =>
foreach (var projectQuota in projectQuotas)
{
 
var projectQuota = _projectQuotaModel.GetWhere((y) =>
 
y.ProjectId == projectGuid &&
 
y.ResourceTypeId == x.Id);
 
return new ProjectQuotaReturnObject
{
{
// TODO: Cleanup quota and give it to every resource, this hard coded solution seems not scalable
Id = x.Id,
if (projectQuota.ResourceType.DisplayName == "rds")
Name = x.DisplayName,
{
Used = CalculateUsed(x, projectGuid),
var resources = resourceModel.GetAllWhere((resource) =>
Allocated = projectQuota == null ? 0 : projectQuota.Quota
resource.TypeId == projectQuota.ResourceType.Id
};
&& (from connection in resource.ProjectResourceResourceIdIds
}));
where connection.ProjectId == guidId
}
select connection).Any());
private int CalculateUsed(ResourceType resourceType, Guid projectId)
var size = resources.Sum((resource) =>
{
rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value).Size);
var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resourceType.DisplayName, _configuration);
returnList.Add(new {
type = projectQuota.ResourceType.DisplayName,
var resources = _resourceModel.GetAllWhere((resource) =>
available = projectQuota.Quotas,
(from projectResource in resource.ProjectResourceResourceIdIds
allocated = size
where projectResource.ProjectId == projectId
});
select projectResource).Any() &&
}
resource.TypeId == resourceType.Id);
}
return Json(returnList);
var used = resources.Sum(y => resourceTypeDefinition.GetResourceQuotaAvailable(y.Id.ToString(), _resourceModel.GetResourceTypeOptions(y.Id)).Result);
 
return (int)used;
 
}
 
 
/// <summary>
 
/// Retrieves the quota for the selected project and resource Type.
 
/// </summary>
 
/// <param name="projectId">Id of the project</param>
 
/// <param name="resourceTypeId">Id of the resource type</param>
 
/// <returns>The project quota for the resource type.</returns>
 
[HttpGet("[controller]/{projectId}/quota/{resourceTypeId}")]
 
public ActionResult<ProjectQuotaReturnObject> Quota(string projectId, string resourceTypeId)
 
{
 
var user = _authenticator.GetUser();
 
 
if (!Guid.TryParse(projectId, out Guid projectGuid))
 
{
 
return BadRequest($"{projectId} is not a guid.");
}
}
else
 
var project = _projectModel.GetById(projectGuid);
 
 
if (project == null)
 
{
 
return NotFound($"Could not find project with id: {projectId}");
 
}
 
 
if (!_projectModel.HasAccess(user, project, UserRoles.Owner))
 
{
 
return Unauthorized("The user is not authorized to perform a get on the selected project!");
 
}
 
 
if (!Guid.TryParse(resourceTypeId, out Guid resourceTypeGuid))
 
{
 
return BadRequest($"{resourceTypeId} is not a guid.");
 
}
 
 
var resourceType = _resourceTypeModel.GetById(resourceTypeGuid);
 
 
if (resourceType == null || !resourceType.Enabled)
 
{
 
return NotFound($"Could not find resourceType with id: {resourceTypeId}");
 
}
 
 
var projectQuota =
 
_projectQuotaModel.GetWhere((x) =>
 
x.ProjectId == projectGuid &&
 
x.ResourceTypeId == resourceTypeGuid);
 
 
var projectQuotaReturnObject = new ProjectQuotaReturnObject
 
{
 
Id = resourceTypeGuid,
 
Name = resourceType.DisplayName,
 
Used = CalculateUsed(resourceType, projectGuid),
 
Allocated = projectQuota.Quota};
 
 
return Json(projectQuotaReturnObject);
 
}
 
 
/// <summary>
 
/// Get the max quota for a resource type.
 
/// </summary>
 
/// <param name="projectId">Id of the project.</param>
 
/// <param name="resourceTypeId">Id of the resource</param>
 
/// <returns>The maximum value for the quota.</returns>
 
[HttpGet("[controller]/{projectId}/quota/{resourceTypeId}/max")]
 
public ActionResult<MaxProjectQuota> GetQuotaMax(string projectId, string resourceTypeId)
 
{
 
var user = _authenticator.GetUser();
 
 
if (!Guid.TryParse(projectId, out Guid projectGuid))
 
{
 
return BadRequest($"{projectId} is not a guid.");
 
}
 
 
var project = _projectModel.GetById(projectGuid);
 
 
if (project == null)
 
{
 
return NotFound($"Could not find project with id: {projectId}");
 
}
 
 
if (!_projectModel.HasAccess(user, project, UserRoles.Owner))
 
{
 
return Unauthorized("The user is not authorized to perform a get on the selected project!");
 
}
 
 
if (!Guid.TryParse(resourceTypeId, out Guid resourceTypeGuid))
 
{
 
return BadRequest($"{resourceTypeId} is not a guid.");
 
}
 
 
var resourceType = _resourceTypeModel.GetById(resourceTypeGuid);
 
 
if (resourceType == null || !resourceType.Enabled)
 
{
 
return NotFound($"Could not find resourceType with id: {resourceTypeId}");
 
}
 
 
return Json(new MaxProjectQuota { Id = resourceTypeGuid, Available = _maxAvailable });
 
}
 
 
/// <summary>
 
/// Update the project quota.
 
/// </summary>
 
/// <param name="projectId">Id of the project.</param>
 
/// <param name="resourceTypeId">Id of the resource.</param>
 
/// <param name="updateProjectQuotaObject">Object containing the update values.</param>
 
/// <returns>NoContent (204).</returns>
 
[HttpPost("[controller]/{projectId}/quota/{resourceTypeId}")]
 
public IActionResult UpdateQuota(string projectId, string resourceTypeId, [FromBody]UpdateProjectQuotaObject updateProjectQuotaObject)
 
{
 
var user = _authenticator.GetUser();
 
 
if (!Guid.TryParse(projectId, out Guid projectGuid))
 
{
 
return BadRequest($"{projectId} is not a guid.");
 
}
 
 
var project = _projectModel.GetById(projectGuid);
 
 
if (project == null)
 
{
 
return NotFound($"Could not find project with id: {projectId}");
 
}
 
 
if (!_projectModel.HasAccess(user, project, UserRoles.Owner))
{
{
return Unauthorized("The user is not authorized to perform a get on the selected project!");
return Unauthorized("The user is not authorized to perform a get on the selected project!");
}
}
 
 
if (!Guid.TryParse(resourceTypeId, out Guid resourceTypeGuid))
 
{
 
return BadRequest($"{resourceTypeId} is not a guid.");
 
}
 
 
var resourceType = _resourceTypeModel.GetById(resourceTypeGuid);
 
 
if (resourceType == null || !resourceType.Enabled)
 
{
 
return NotFound($"Could not find resourceType with id: {resourceTypeId}");
 
}
 
 
if (updateProjectQuotaObject.Allocated < 0)
 
{
 
return BadRequest($"Allocated {updateProjectQuotaObject.Allocated}. Cannot be less than 0.");
 
}
 
 
var projectQuotaForCurrent = _projectQuotaModel.GetWhere(x => x.ProjectId == projectGuid && x.ResourceTypeId == resourceTypeGuid);
 
var used = CalculateUsed(resourceType, projectGuid);
 
 
if(used > updateProjectQuotaObject.Allocated)
 
{
 
return BadRequest($"Cannot set quota ({updateProjectQuotaObject.Allocated}) below the used value ({used}).");
 
}
 
 
var projectQuotaForAll = _projectQuotaModel.GetAllWhere(x => x.ProjectId == projectGuid).Sum(x => x.Quota);
 
 
if(projectQuotaForAll - projectQuotaForCurrent.Quota + updateProjectQuotaObject.Allocated > _maxAvailable)
 
{
 
return BadRequest($"Cannot set quota to {updateProjectQuotaObject.Allocated}. In combination with the other quotas ({projectQuotaForAll - projectQuotaForCurrent.Quota}), it would exceed the limit of {_maxAvailable}");
 
}
 
 
projectQuotaForCurrent.Quota = updateProjectQuotaObject.Allocated;
 
_projectQuotaModel.Update(projectQuotaForCurrent);
 
 
return NoContent();
}
}
/// <summary>
/// <summary>
@@ -319,10 +503,9 @@ namespace Coscine.Api.Project.Controllers
@@ -319,10 +503,9 @@ namespace Coscine.Api.Project.Controllers
projectInstituteModel.Delete(projectInstitute);
projectInstituteModel.Delete(projectInstitute);
}
}
var projectQuotaModel = new ProjectQuotaModel();
foreach (var projectQuota in _projectQuotaModel.GetAllWhere((Quota) => Quota.ProjectId == project.Id))
foreach (var projectQuota in projectQuotaModel.GetAllWhere((Quota) => Quota.ProjectId == project.Id))
{
{
projectQuotaModel.Delete(projectQuota);
_projectQuotaModel.Delete(projectQuota);
}
}
_activatedFeaturesModel.DeactivateAllFeatures(project);
_activatedFeaturesModel.DeactivateAllFeatures(project);
Loading