Skip to content
Snippets Groups Projects

Sprint/2020 22

Files

@@ -21,9 +21,14 @@ using System.Web;
using VDS.RDF;
using VDS.RDF.Parsing;
using VDS.RDF.Writing;
using Coscine.ResourceLoader;
using Coscine.Configuration;
namespace Coscine.Api.Tree.Controllers
{
/// <summary>
/// This controller represents the actions which can be taken with a tree object.
/// </summary>
[Authorize]
public class TreeController : Controller
{
@@ -34,36 +39,50 @@ namespace Coscine.Api.Tree.Controllers
private readonly ProjectResourceModel _projectResourceModel;
private readonly CoscineLogger _coscineLogger;
private readonly AnalyticsLogObject _analyticsLogObject;
private readonly IDataSourceService _dataSourceService;
private readonly WaterbutlerInterface _waterbutlerInterface;
private readonly string _blobApiLink;
private readonly string _prefix;
private readonly IConfiguration _configuration;
public TreeController(ILogger<TreeController> logger, IDataSourceService dataSourceService)
/// <summary>
/// Tree controller constructor
/// </summary>
/// <param name="logger">Logger</param>
public TreeController(ILogger<TreeController> logger)
{
_authenticator = new Authenticator(this, Program.Configuration);
_configuration = Program.Configuration;
_authenticator = new Authenticator(this, _configuration);
_resourceModel = new ResourceModel();
_rdfStoreConnector = new RdfStoreConnector(Program.Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
_rdfStoreConnector = new RdfStoreConnector(_configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
_projectRoleModel = new ProjectRoleModel();
_projectResourceModel = new ProjectResourceModel();
_coscineLogger = new CoscineLogger(logger);
_analyticsLogObject = new AnalyticsLogObject();
_dataSourceService = dataSourceService;
_waterbutlerInterface = new WaterbutlerInterface(Program.Configuration, _dataSourceService);
var rule = Program.Configuration.GetStringAndWait("traefik/frontends/Coscine.Api.Blob/routes/Coscine.Api.Blob/rule");
var rule = _configuration.GetStringAndWait("traefik/frontends/Coscine.Api.Blob/routes/Coscine.Api.Blob/rule");
var host = rule.Substring("Host:".Length, rule.IndexOf(";") - "Host:".Length);
var path = rule.Substring(rule.IndexOf("/"));
_blobApiLink = $"https://{host}{path}/blob/";
_prefix = Program.Configuration.GetStringAndWait("coscine/global/epic/prefix");
_prefix = _configuration.GetStringAndWait("coscine/global/epic/prefix");
}
/// <summary>
/// Generates Id
/// </summary>
/// <param name="resourceId">Id of the resource</param>
/// <param name="path"> Path to file</param>
/// <returns> Uri </returns>
public Uri GenerateId(string resourceId, string path)
{
return new Uri($"https://hdl.handle.net/{_prefix}/{resourceId}@path={Uri.EscapeDataString(path)}");
}
/// <summary>
/// This method retrieves the metadata
/// </summary>
/// <param name="resourceId"> Id of a resource</param>
/// <param name="path">Path to the file</param>
/// <returns> JSON Object with the metadata if ok, otherwise Statuscode 400 or 401 or 404</returns>
[HttpGet("[controller]/{resourceId}/{*path}")]
public async Task<IActionResult> GetMetadata(string resourceId, string path)
{
@@ -86,66 +105,61 @@ namespace Coscine.Api.Tree.Controllers
return check;
}
var resourceTypeOptions = new Dictionary<string, string>();
if (resource.Type.DisplayName == "rds")
{
var data = new RDSResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId);
resourceTypeOptions.Add("bucketname", data.BucketName);
}
else if (resource.Type.DisplayName == "s3")
{
var data = new S3ResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId);
resourceTypeOptions.Add("accessKey", data.AccessKey);
resourceTypeOptions.Add("secretKey", data.SecretKey);
resourceTypeOptions.Add("bucketname", data.BucketName);
resourceTypeOptions.Add("resourceUrl", data.ResourceUrl);
}
else if (resource.Type.DisplayName == "gitlab")
try
{
var data = new GitlabResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId);
resourceTypeOptions.Add("token", data.Token);
resourceTypeOptions.Add("repositoryUrl", data.RepositoryUrl);
resourceTypeOptions.Add("repositoryNumber", data.RepositoryNumber.ToString());
}
var authHeader = _waterbutlerInterface.BuildAuthHeader(resource.Type.DisplayName, resourceTypeOptions);
var resourceTypeOptions = _resourceModel.GetResourceTypeOptions(resource.Id);
var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resource.Type.DisplayName, _configuration);
if (resourceTypeDefinition == null)
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
if (authHeader == null)
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
var infos = await resourceTypeDefinition.ListEntries(resourceId, path, resourceTypeOptions);
var graphs = new List<JToken>();
var provider = GetResourceTypeName(resource);
var infos = await _waterbutlerInterface.GetObjectInfoAsync(path, provider, authHeader);
foreach (var info in infos)
{
var id = GenerateId(resourceId, info.Key);
if (_rdfStoreConnector.HasGraph(id.AbsoluteUri))
{
var graph = _rdfStoreConnector.GetGraph(id);
graphs.Add(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())));
}
}
// Not found
if (infos == null)
{
return NotFound($"Found nothing in waterbutler under \"{path}\".");
var jObject = new JObject(
new JProperty("data", new JObject(
new JProperty("metadataStorage", JToken.FromObject(graphs)),
new JProperty("fileStorage", JToken.FromObject(infos.Select(x =>
{
var objectMetaInfo = new ObjectMetaInfo
{
Name = x.Key.Substring(x.Key.LastIndexOf("/") + 1),
Path = x.Key,
Size = (int)x.BodyBytes,
Kind = x.Key.Substring(x.Key.LastIndexOf(".") + 1),
Provider = resource.Type.DisplayName
};
return new ObjectMetaInfoReturnObject(objectMetaInfo, _blobApiLink, resource.Id.ToString());
})))
))
);
LogAnalytics("View MD", resourceId, path, user);
return Json(jObject);
}
var graphs = new List<JToken>();
foreach (var info in infos)
catch
{
var id = GenerateId(resourceId, info.Path);
if (_rdfStoreConnector.HasGraph(id.AbsoluteUri))
{
var graph = _rdfStoreConnector.GetGraph(id);
graphs.Add(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())));
}
return BadRequest($"Error in communication with the resource");
}
var jObject = new JObject(
new JProperty("data", new JObject(
new JProperty("metadataStorage", JToken.FromObject(graphs)),
new JProperty("fileStorage", JToken.FromObject(infos.Select( x => new ObjectMetaInfoReturnObject(x, _blobApiLink, resource.Id.ToString()))))
))
);
LogAnalytics("View MD", resourceId, path, user);
return Json(jObject);
}
/// <summary>
/// This method stores the metadata of the file
/// </summary>
/// <param name="resourceId">Id of the resource</param>
/// <param name="path">Path to the file</param>
/// <returns>If ok Statuscode 204, otherwise Statuscode 400 or 401</returns>
[HttpPut("[controller]/{resourceId}/{*path}")]
public IActionResult StoreMetadataForFile(string resourceId, string path)
{
@@ -259,7 +273,13 @@ namespace Coscine.Api.Tree.Controllers
return NoContent();
}
/// <summary>
/// Checks the resource Id and the path
/// </summary>
/// <param name="resourceId">Id of the resource</param>
/// <param name="path">Path to the file</param>
/// <param name="resource">Resource</param>
/// <returns>null, otherwise Statuscode 400 or 404 </returns>
private IActionResult CheckResourceIdAndPath(string resourceId, string path, out Resource resource)
{
resource = null;
@@ -303,18 +323,13 @@ namespace Coscine.Api.Tree.Controllers
return null;
}
private string GetResourceTypeName(Resource resource)
{
if (resource.Type.DisplayName.ToLower().Equals("s3"))
{
return "rds";
}
else
{
return resource.Type.DisplayName.ToLower();
}
}
/// <summary>
/// Log analytics
/// </summary>
/// <param name="operation">Operation</param>
/// <param name="resourceId">Resource of the id</param>
/// <param name="filename">Name of the file</param>
/// <param name="user">User object</param>
private void LogAnalytics(string operation, string resourceId, string filename, User user)
{
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
Loading