Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Coscine
backend
apis
Project
Commits
6bbe70ea
Commit
6bbe70ea
authored
Feb 04, 2021
by
Marcel Nellesen
Browse files
Merge branch 'Sprint/2021-01' into 'master'
Sprint/2021 01 See merge request
!122
parents
1799b289
cc1f3cfb
Changes
6
Pipelines
4
Hide whitespace changes
Inline
Side-by-side
src/Project/Controllers/ProjectController.cs
View file @
6bbe70ea
using
Coscine.Action
;
using
Coscine.Action.EventArgs
;
using
Coscine.Api.Project.ParameterObjects
;
using
Coscine.Api.Project.ReturnObjects
;
using
Coscine.ApiCommons
;
using
Coscine.ApiCommons.Factories
;
using
Coscine.Configuration
;
...
...
@@ -32,8 +34,12 @@ namespace Coscine.Api.Project.Controllers
private
readonly
Emitter
_emitter
;
private
readonly
ActivatedFeaturesModel
_activatedFeaturesModel
;
private
readonly
ProjectRoleModel
_projectRoleModel
;
private
readonly
ProjectQuotaModel
_projectQuotaModel
;
private
readonly
ResourceTypeModel
_resourceTypeModel
;
private
readonly
ResourceModel
_resourceModel
;
private
readonly
CoscineLogger
_coscineLogger
;
private
readonly
AnalyticsLogObject
_analyticsLogObject
;
private
readonly
int
_maxAvailable
=
100
;
/// <summary>
/// ProjectController constructor
...
...
@@ -47,6 +53,9 @@ namespace Coscine.Api.Project.Controllers
_emitter
=
new
Emitter
(
_configuration
);
_activatedFeaturesModel
=
new
ActivatedFeaturesModel
();
_projectRoleModel
=
new
ProjectRoleModel
();
_resourceTypeModel
=
new
ResourceTypeModel
();
_resourceModel
=
new
ResourceModel
();
_projectQuotaModel
=
new
ProjectQuotaModel
();
_coscineLogger
=
new
CoscineLogger
(
logger
);
_analyticsLogObject
=
new
AnalyticsLogObject
();
}
...
...
@@ -155,56 +164,231 @@ namespace Coscine.Api.Project.Controllers
}
/// <summary>
/// Retrieves the quota for the selected project
/// Retrieves the quota for the selected project
.
/// </summary>
/// <param name="
i
d">Id of the
resource
</param>
/// <returns>
Json object or Statuscode 401
</returns>
[
HttpGet
(
"[controller]/{
i
d}/quota
s
"
)]
public
ActionResult
<
IEnumerable
<
ProjectQuota
>>
Quotas
(
string
i
d
)
/// <param name="
projectI
d">Id of the
project.
</param>
/// <returns>
List of project quotas
</returns>
[
HttpGet
(
"[controller]/{
projectI
d}/quota
/-/all
"
)]
public
ActionResult
<
IEnumerable
<
ProjectQuota
>>
Quotas
(
string
projectI
d
)
{
var
user
=
_authenticator
.
GetUser
();
var
projectObject
=
ObjectFactory
<
ProjectObject
>.
DeserializeFromStream
(
Request
.
Body
);
var
guidId
=
Guid
.
Parse
(
id
);
var
project
=
_projectModel
.
GetById
(
guidId
);
if
(
_projectModel
.
HasAccess
(
user
,
project
,
UserRoles
.
Owner
))
if
(!
Guid
.
TryParse
(
projectId
,
out
Guid
projectGuid
))
{
return
BadRequest
(
$"
{
projectId
}
is not a guid."
);
}
var
project
=
_projectModel
.
GetById
(
projectGuid
);
if
(
project
==
null
)
{
ProjectQuotaModel
projectQuotaModel
=
new
ProjectQuotaModel
();
var
projectQuotas
=
projectQuotaModel
.
GetAllWhere
((
projectQuota
)
=>
projectQuota
.
ProjectId
==
guidId
&&
projectQuota
.
ResourceType
.
Enabled
==
true
)
.
Select
((
projectQuota
)
=>
projectQuotaModel
.
CreateReturnObjectFromDatabaseObject
(
projectQuota
));
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!"
);
}
var
projectQuotas
=
_projectQuotaModel
.
GetAllWhere
((
projectQuota
)
=>
projectQuota
.
ProjectId
==
projectGuid
&&
projectQuota
.
ResourceType
.
Enabled
==
true
);
ResourceModel
resourceModel
=
new
ResourceModel
();
RDSResourceTypeModel
rdsResourceTypeModel
=
new
RDSResourceTypeModel
();
var
returnList
=
new
List
<
dynamic
>();
foreach
(
var
projectQuota
in
projectQuotas
)
var
resourceTypes
=
_resourceTypeModel
.
GetAllWhere
(
x
=>
x
.
Enabled
);
return
Json
(
resourceTypes
.
Select
(
x
=>
{
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
if
(
projectQuota
.
ResourceType
.
DisplayName
==
"rds"
)
{
var
resources
=
resourceModel
.
GetAllWhere
((
resource
)
=>
resource
.
TypeId
==
projectQuota
.
ResourceType
.
Id
&&
(
from
connection
in
resource
.
ProjectResourceResourceIdIds
where
connection
.
ProjectId
==
guidId
select
connection
).
Any
());
var
size
=
resources
.
Sum
((
resource
)
=>
rdsResourceTypeModel
.
GetById
(
resource
.
ResourceTypeOptionId
.
Value
).
Size
);
returnList
.
Add
(
new
{
type
=
projectQuota
.
ResourceType
.
DisplayName
,
available
=
projectQuota
.
Quotas
,
allocated
=
size
});
}
}
return
Json
(
returnList
);
Id
=
x
.
Id
,
Name
=
x
.
DisplayName
,
Used
=
CalculateUsed
(
x
,
projectGuid
),
Allocated
=
projectQuota
==
null
?
0
:
projectQuota
.
Quota
};
}));
}
private
int
CalculateUsed
(
ResourceType
resourceType
,
Guid
projectId
)
{
var
resourceTypeDefinition
=
ResourceTypeFactory
.
CreateResourceTypeObject
(
resourceType
.
DisplayName
,
_configuration
);
var
resources
=
_resourceModel
.
GetAllWhere
((
resource
)
=>
(
from
projectResource
in
resource
.
ProjectResourceResourceIdIds
where
projectResource
.
ProjectId
==
projectId
select
projectResource
).
Any
()
&&
resource
.
TypeId
==
resourceType
.
Id
);
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!"
);
}
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>
...
...
@@ -319,10 +503,9 @@ namespace Coscine.Api.Project.Controllers
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
);
...
...
src/Project/ParameterObjects/UpdateProjectQuotaObject.cs
0 → 100644
View file @
6bbe70ea
using
System
;
namespace
Coscine.Api.Project.ParameterObjects
{
/// <summary>
/// Parameter object containing the update informations.
/// </summary>
public
class
UpdateProjectQuotaObject
{
/// <summary>
/// Id of the resourceType
/// </summary>
public
Guid
Id
{
get
;
set
;
}
/// <summary>
/// New Quota value.
/// </summary>
public
int
Allocated
{
get
;
set
;
}
}
}
src/Project/Project.csproj
View file @
6bbe70ea
...
...
@@ -543,6 +543,9 @@
<Private>
True
</Private>
</Reference>
<Reference
Include=
"System.Net"
/>
<Reference
Include=
"System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
>
<HintPath>
..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
</HintPath>
</Reference>
<Reference
Include=
"System.Net.Http.WebRequest"
/>
<Reference
Include=
"System.Numerics"
/>
<Reference
Include=
"System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
>
...
...
@@ -681,8 +684,11 @@
<Compile
Include=
"Controllers\RoleController.cs"
/>
<Compile
Include=
"Controllers\SubProjectController.cs"
/>
<Compile
Include=
"Controllers\ProjectRoleController.cs"
/>
<Compile
Include=
"ParameterObjects\UpdateProjectQuotaObject.cs"
/>
<Compile
Include=
"Program.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"ReturnObjects\MaxProjectQuota.cs"
/>
<Compile
Include=
"ReturnObjects\ProjectQuotaReturnObject.cs"
/>
<Compile
Include=
"Startup.cs"
/>
</ItemGroup>
<ItemGroup>
...
...
src/Project/ReturnObjects/MaxProjectQuota.cs
0 → 100644
View file @
6bbe70ea
using
System
;
namespace
Coscine.Api.Project.ReturnObjects
{
/// <summary>
/// Return object containing the maximum project quota.
/// </summary>
public
class
MaxProjectQuota
{
/// <summary>
/// The resource type id.
/// </summary>
public
Guid
Id
{
get
;
set
;
}
/// <summary>
/// Available amount in gb.
/// </summary>
public
int
Available
{
get
;
set
;
}
}
}
src/Project/ReturnObjects/ProjectQuotaReturnObject.cs
0 → 100644
View file @
6bbe70ea
using
System
;
namespace
Coscine.Api.Project.ReturnObjects
{
/// <summary>
/// Contains information about the quota of a project by resource type.
/// </summary>
public
class
ProjectQuotaReturnObject
{
/// <summary>
/// Id of the resoure type.
/// </summary>
public
Guid
Id
{
get
;
set
;
}
/// <summary>
/// Display name of the resource type.
/// </summary>
public
string
Name
{
get
;
set
;
}
/// <summary>
/// How much space is used by the resources (in gb).
/// </summary>
public
int
Used
{
get
;
set
;
}
/// <summary>
/// How much space is availabe to be taken by resources (in gb).
/// </summary>
public
int
Allocated
{
get
;
set
;
}
}
}
src/Project/packages.config
View file @
6bbe70ea
...
...
@@ -23,6 +23,7 @@
<
package
id
=
"linq2db.SqlServer"
version
=
"2.6.4"
targetFramework
=
"net472"
/>
<
package
id
=
"linq2db.t4models"
version
=
"2.6.4"
targetFramework
=
"net472"
/>
<
package
id
=
"LinqKit"
version
=
"1.1.17"
targetFramework
=
"net472"
/>
<
package
id
=
"Microsoft.AspNet.WebApi.Client"
version
=
"5.2.3"
targetFramework
=
"net472"
/>
<
package
id
=
"Microsoft.AspNetCore"
version
=
"2.2.0"
targetFramework
=
"net472"
/>
<
package
id
=
"Microsoft.AspNetCore.Antiforgery"
version
=
"2.2.0"
targetFramework
=
"net472"
/>
<
package
id
=
"Microsoft.AspNetCore.Authentication"
version
=
"2.2.0"
targetFramework
=
"net472"
/>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment