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

Merge branch 'Issue/1792-newMetadataStructure' into 'dev'

New: Use the new metadata structure (coscine/issues#1792)

See merge request !90
parents 6dc9ffc1 ac989893
Branches
Tags
2 merge requests!108Release: Sprint/2023 04 :robot:,!90New: Use the new metadata structure (coscine/issues#1792)
## Tree
# Tree API
The TreeApi handles the retrieving or storing metadata to a certain path.
Check out the [docs](https://coscine.rwth-aachen.de/coscine/api/Coscine.Api.Tree/swagger).
using Coscine.Api.Tree.Util;
using Coscine.ApiCommons;
using Coscine.ApiCommons.Factories;
using Coscine.Configuration;
......@@ -36,6 +35,7 @@ namespace Coscine.Api.Tree.Controllers
private readonly Authenticator _authenticator;
private readonly ResourceModel _resourceModel;
private readonly RdfStoreConnector _rdfStoreConnector;
private readonly CoscineLDPHelper _coscineLDPHelper;
private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectResourceModel _projectResourceModel;
private readonly CoscineLogger _coscineLogger;
......@@ -64,22 +64,7 @@ namespace Coscine.Api.Tree.Controllers
var path = rule[rule.IndexOf("/")..];
_blobApiLink = $"https://{host}{path}/blob/";
_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)
{
if (!path.StartsWith("/"))
{
path = "/" + path;
}
return new CustomUri($"https://hdl.handle.net/{_prefix}/{resourceId}@path={Uri.EscapeDataString(path)}");
_coscineLDPHelper = new CoscineLDPHelper(_rdfStoreConnector, _prefix);
}
/// <summary>
......@@ -159,10 +144,12 @@ namespace Coscine.Api.Tree.Controllers
var resourceTypeInformation = resourceTypeDefinition.GetResourceTypeInformation().Result;
var metadataInfos = new List<ResourceEntry>(fileInfos);
var metadataIds = _rdfStoreConnector.ListMetadata(resourceId);
// Add to metadata infos, if no "physical" file for it exists
if (!metadataInfos.Any((metadataInfo) => metadataInfo.Key == path))
{
metadataInfos.Add(new ResourceEntry(path, true, 0, GenerateId(resourceId, path).AbsoluteUri, null, DateTime.Now, DateTime.Now));
metadataInfos.Add(new ResourceEntry(path, true, 0, _coscineLDPHelper.GetId(resourceId, path, true, false, "metadata", metadataIds).AbsoluteUri, null, DateTime.Now, DateTime.Now));
}
var applicationProfileGraph = _rdfStoreConnector.GetGraph(resource.ApplicationProfile);
......@@ -173,7 +160,7 @@ namespace Coscine.Api.Tree.Controllers
int metadataCount = 0;
foreach (var info in metadataInfos)
{
var id = GenerateId(resourceId, info.Key);
var id = _coscineLDPHelper.GetId(resourceId, info.Key, true, false, "metadata", metadataIds);
if (_rdfStoreConnector.HasGraph(id.AbsoluteUri))
{
var graph = _rdfStoreConnector.GetGraph(id);
......@@ -297,9 +284,9 @@ namespace Coscine.Api.Tree.Controllers
/// <returns>If OK status code 204, otherwise status code 400 or 401</returns>
[HttpPut("[controller]/{resourceId}/{*path}")]
[ApiExplorerSettings(IgnoreApi = true)]
public IActionResult StoreMetadataForFileWithPath(string resourceId, string path)
public async Task<IActionResult> StoreMetadataForFileWithPath(string resourceId, string path)
{
return StoreMetadataForFile(resourceId, path);
return await StoreMetadataForFile(resourceId, path);
}
/// <summary>
......@@ -310,7 +297,7 @@ namespace Coscine.Api.Tree.Controllers
/// <param name="mimeType">Requested MimeType of the metadata</param>
/// <returns>If OK status code 204, otherwise status code 400 or 401</returns>
[HttpPut("[controller]/{resourceId}/")]
public IActionResult StoreMetadataForFileWithParameter(string resourceId, [FromQuery] string path = "", [FromQuery] string mimeType = "application/rdf+json")
public async Task<IActionResult> StoreMetadataForFileWithParameter(string resourceId, [FromQuery] string path = "", [FromQuery] string mimeType = "application/rdf+json")
{
// Strip the first slash, to reuse the previous implementation.
if (path.StartsWith("/"))
......@@ -318,7 +305,7 @@ namespace Coscine.Api.Tree.Controllers
path = path[1..];
}
return StoreMetadataForFile(resourceId, path, mimeType);
return await StoreMetadataForFile(resourceId, path, mimeType);
}
/// <summary>
......@@ -328,7 +315,7 @@ namespace Coscine.Api.Tree.Controllers
/// <param name="path">Path to the file</param>
/// <param name="mimeType">Requested MimeType of the metadata</param>
/// <returns>If OK status code 204, otherwise status code 400 or 401</returns>
public IActionResult StoreMetadataForFile(string resourceId, string path, string mimeType = "application/rdf+json")
public async Task<IActionResult> StoreMetadataForFile(string resourceId, string path, string mimeType = "application/rdf+json")
{
path = $"/{path}";
if (path.Contains("%2F") || path.Contains("%2f"))
......@@ -339,7 +326,7 @@ namespace Coscine.Api.Tree.Controllers
// Ducktape solution for supporting multiple mimetypes
var metadataObject = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
var graphNameUri = GenerateId(resourceId, path);
var graphNameUri = _coscineLDPHelper.GetId(resourceId, path, false, true);
JObject json;
......@@ -443,38 +430,15 @@ namespace Coscine.Api.Tree.Controllers
return BadRequest("Data has the wrong format!");
}
// store the data
if (_rdfStoreConnector.HasGraph(graphNameUri))
{
_rdfStoreConnector.ClearGraph(graphNameUri);
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
{
LogAnalyticsUpdateMd(_projectResourceModel.GetProjectForResource(resource.Id).Value, resource.Id, path, user, GetMetadataCompleteness(graph.Triples.Count, resource));
}
}
else
{
try
{
_rdfStoreConnector.CreateNamedGraph(graphNameUri);
}
#pragma warning disable RCS1075 // Avoid empty catch clause that catches System.Exception.
catch (Exception)
#pragma warning restore RCS1075 // Avoid empty catch clause that catches System.Exception.
{
// Graph creation failed because it has been created before, skip this for now
}
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
{
LogAnalyticsUploadMd(_projectResourceModel.GetProjectForResource(resource.Id).Value, resource.Id, path, user, GetMetadataCompleteness(graph.Triples.Count, resource));
}
}
// BaseUri must be set for the sparql query
graph.BaseUri = graphNameUri;
_rdfStoreConnector.AddGraph(graph);
await _rdfStoreConnector.AddMetadataAsync(graph);
return NoContent();
}
......
using System;
namespace Coscine.Api.Tree.Util
{
/// <summary>
/// Adapts the returned ToString of a Uri
/// </summary>
public class CustomUri : Uri
{
/// <summary>
/// Constructs a Custom Uri
/// </summary>
/// <param name="uri"></param>
public CustomUri(string uri) : base(uri)
{
}
/// <summary>
/// Overwrites the ToString for returning the AbsoluteUri (for dotNetRDF)
/// </summary>
/// <returns></returns>
public override string ToString()
{
return AbsoluteUri;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment