diff --git a/src/Tree.sln b/src/Tree.sln index 26e44a875bcc6fc9951ae211feaf4f53ca1fbb34..27542b14eef80691fa5ea1e0e8f6aa90d64b0129 100644 --- a/src/Tree.sln +++ b/src/Tree.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28803.156 diff --git a/src/Tree/App.config b/src/Tree/App.config index 123c4219c25d27fdbf7634753a6dfb3441f66727..20153e8bb3f89ce37e61a2706c333add291e8062 100644 --- a/src/Tree/App.config +++ b/src/Tree/App.config @@ -149,7 +149,7 @@ </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-1.26.0.0" newVersion="1.26.0.0" /> + <bindingRedirect oldVersion="0.0.0.0-1.27.0.0" newVersion="1.27.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" /> @@ -205,7 +205,7 @@ </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Coscine.Database.T4" publicKeyToken="84b4c404a0696261" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-1.26.0.0" newVersion="1.26.0.0" /> + <bindingRedirect oldVersion="0.0.0.0-1.27.0.0" newVersion="1.27.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> diff --git a/src/Tree/Controllers/TreeController.cs b/src/Tree/Controllers/TreeController.cs index 3775519fd6ae753707fd5c9c5aa0311244fa89bb..71f74886ae41b44a9bd0c47ac0cbdeb62c6a7820 100644 --- a/src/Tree/Controllers/TreeController.cs +++ b/src/Tree/Controllers/TreeController.cs @@ -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)) diff --git a/src/Tree/Program.cs b/src/Tree/Program.cs index 4e62cb67a975129085ad641d4ad86f9d3492c9db..9f4c22ca9f7390cd4d5fda216a9ffeece503f083 100644 --- a/src/Tree/Program.cs +++ b/src/Tree/Program.cs @@ -3,8 +3,14 @@ using Coscine.Configuration; namespace Coscine.Api.Tree { + /// <summary> + /// Standard Program Class + /// </summary> public class Program : AbstractProgram<ConsulConfiguration> { + /// <summary> + /// standard main body + /// </summary> public static void Main() { System.Net.ServicePointManager.DefaultConnectionLimit = int.MaxValue; diff --git a/src/Tree/Startup.cs b/src/Tree/Startup.cs index c9a0b798a44dcb84480f82600faf86edabacb35f..38f4352c2b3044d7513c733bb6beede7fc0bb713 100644 --- a/src/Tree/Startup.cs +++ b/src/Tree/Startup.cs @@ -5,13 +5,22 @@ using System; namespace Coscine.Api.Tree { + /// <summary> + /// standard startup class + /// </summary> public class Startup : AbstractStartup { + /// <summary> + /// standard startup constructor + /// </summary> public Startup() { } - + /// <summary> + /// Configures custom service extension + /// </summary> + /// <param name="services">Services</param> public override void ConfigureServicesExtension(IServiceCollection services) { base.ConfigureServicesExtension(services); diff --git a/src/Tree/Tree.csproj b/src/Tree/Tree.csproj index d25b9bf3fea971ed9788791b86675ba107ec9a32..5d3b7b847a6ef763123d28ce3501e2c4a1277f09 100644 --- a/src/Tree/Tree.csproj +++ b/src/Tree/Tree.csproj @@ -26,7 +26,7 @@ </NuGetPackageImportStamp> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> + <PlatformTarget>x64</PlatformTarget> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> @@ -34,49 +34,60 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <DocumentationFile>bin\Debug\Coscine.Api.Tree.xml</DocumentationFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> + <PlatformTarget>x64</PlatformTarget> <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <DocumentationFile>bin\Release\Coscine.Api.Tree.xml</DocumentationFile> </PropertyGroup> <ItemGroup> <Reference Include="Consul, Version=0.7.2.6, Culture=neutral, PublicKeyToken=20a6ad9a81df1d95, processorArchitecture=MSIL"> <HintPath>..\packages\Consul.0.7.2.6\lib\net45\Consul.dll</HintPath> </Reference> - <Reference Include="Coscine.ApiCommons, Version=1.10.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.ApiCommons.1.10.0\lib\net461\Coscine.ApiCommons.dll</HintPath> + <Reference Include="Coscine.ApiCommons, Version=1.11.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.ApiCommons.1.11.0\lib\net461\Coscine.ApiCommons.dll</HintPath> </Reference> <Reference Include="Coscine.Configuration, Version=1.5.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.Configuration.1.5.0\lib\net461\Coscine.Configuration.dll</HintPath> </Reference> - <Reference Include="Coscine.Database, Version=1.26.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.Database.1.26.0\lib\net461\Coscine.Database.dll</HintPath> + <Reference Include="Coscine.Database, Version=1.27.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Database.1.27.0\lib\net461\Coscine.Database.dll</HintPath> </Reference> - <Reference Include="Coscine.Database.T4, Version=1.26.0.0, Culture=neutral, PublicKeyToken=84b4c404a0696261, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.Database.1.26.0\lib\net461\Coscine.Database.T4.dll</HintPath> + <Reference Include="Coscine.Database.T4, Version=1.27.0.0, Culture=neutral, PublicKeyToken=84b4c404a0696261, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Database.1.27.0\lib\net461\Coscine.Database.T4.dll</HintPath> </Reference> - <Reference Include="Coscine.JwtHandler, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.JwtHandler.1.1.0\lib\net461\Coscine.JwtHandler.dll</HintPath> + <Reference Include="Coscine.JwtHandler, Version=1.2.0.0, Culture=neutral, PublicKeyToken=aaacf41df3a6253c, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.JwtHandler.1.2.0\lib\net461\Coscine.JwtHandler.dll</HintPath> </Reference> <Reference Include="Coscine.Logging, Version=1.2.0.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.Logging.1.2.0\lib\net461\Coscine.Logging.dll</HintPath> </Reference> - <Reference Include="Coscine.Metadata, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.Metadata.1.4.0\lib\net461\Coscine.Metadata.dll</HintPath> + <Reference Include="Coscine.Metadata, Version=1.5.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Metadata.1.5.0\lib\net461\Coscine.Metadata.dll</HintPath> + </Reference> + <Reference Include="Coscine.ResourceConfiguration, Version=1.3.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.ResourceConfiguration.1.3.0\lib\net461\Coscine.ResourceConfiguration.dll</HintPath> + </Reference> + <Reference Include="Coscine.ResourceLoader, Version=1.2.0.0, Culture=neutral, processorArchitecture=AMD64"> + <HintPath>..\packages\Coscine.ResourceLoader.1.2.0\lib\net461\Coscine.ResourceLoader.dll</HintPath> + </Reference> + <Reference Include="Coscine.ResourceTypeBase, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.ResourceTypeBase.1.4.0\lib\net461\Coscine.ResourceTypeBase.dll</HintPath> </Reference> <Reference Include="Coscine.WaterbutlerHelper, Version=1.2.1.0, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.WaterbutlerHelper.1.2.1\lib\net461\Coscine.WaterbutlerHelper.dll</HintPath> </Reference> - <Reference Include="dotNetRDF, Version=2.5.1.0, Culture=neutral, PublicKeyToken=6055ffe4c97cc780, processorArchitecture=MSIL"> - <HintPath>..\packages\dotNetRDF.2.5.1\lib\net40\dotNetRDF.dll</HintPath> + <Reference Include="dotNetRDF, Version=2.6.0.0, Culture=neutral, PublicKeyToken=6055ffe4c97cc780, processorArchitecture=MSIL"> + <HintPath>..\packages\dotNetRDF.2.6.0\lib\net40\dotNetRDF.dll</HintPath> </Reference> - <Reference Include="dotNetRDF.Data.Virtuoso, Version=2.5.1.0, Culture=neutral, PublicKeyToken=6055ffe4c97cc780, processorArchitecture=MSIL"> - <HintPath>..\packages\dotNetRDF.Data.Virtuoso.2.5.1\lib\net40\dotNetRDF.Data.Virtuoso.dll</HintPath> + <Reference Include="dotNetRDF.Data.Virtuoso, Version=2.6.0.0, Culture=neutral, PublicKeyToken=6055ffe4c97cc780, processorArchitecture=MSIL"> + <HintPath>..\packages\dotNetRDF.Data.Virtuoso.2.6.0\lib\net40\dotNetRDF.Data.Virtuoso.dll</HintPath> </Reference> <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath> @@ -84,8 +95,8 @@ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath> </Reference> - <Reference Include="HtmlAgilityPack, Version=1.11.17.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL"> - <HintPath>..\packages\HtmlAgilityPack.1.11.17\lib\Net45\HtmlAgilityPack.dll</HintPath> + <Reference Include="HtmlAgilityPack, Version=1.11.24.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL"> + <HintPath>..\packages\HtmlAgilityPack.1.11.24\lib\Net45\HtmlAgilityPack.dll</HintPath> </Reference> <Reference Include="linq2db, Version=3.1.1.0, Culture=neutral, PublicKeyToken=e41013125f9e410a, processorArchitecture=MSIL"> <HintPath>..\packages\linq2db.3.1.1\lib\net46\linq2db.dll</HintPath> diff --git a/src/Tree/packages.config b/src/Tree/packages.config index b2d9a401338bed3cae7d550202a73d39acacec09..5cb7fddecdda4bba26eabe31e768648b51835b53 100644 --- a/src/Tree/packages.config +++ b/src/Tree/packages.config @@ -1,17 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> <packages> <package id="Consul" version="0.7.2.6" targetFramework="net461" /> - <package id="Coscine.ApiCommons" version="1.10.0" targetFramework="net461" /> + <package id="Coscine.ApiCommons" version="1.11.0" targetFramework="net461" /> <package id="Coscine.Configuration" version="1.5.0" targetFramework="net461" /> - <package id="Coscine.Database" version="1.26.0" targetFramework="net461" /> - <package id="Coscine.JwtHandler" version="1.1.0" targetFramework="net461" /> + <package id="Coscine.Database" version="1.27.0" targetFramework="net461" /> + <package id="Coscine.JwtHandler" version="1.2.0" targetFramework="net461" /> <package id="Coscine.Logging" version="1.2.0" targetFramework="net461" /> - <package id="Coscine.Metadata" version="1.4.0" targetFramework="net461" /> + <package id="Coscine.Metadata" version="1.5.0" targetFramework="net461" /> + <package id="Coscine.ResourceConfiguration" version="1.3.0" targetFramework="net461" /> + <package id="Coscine.ResourceLoader" version="1.2.0" targetFramework="net461" /> + <package id="Coscine.ResourceTypeBase" version="1.4.0" targetFramework="net461" /> <package id="Coscine.WaterbutlerHelper" version="1.2.1" targetFramework="net461" /> - <package id="dotNetRDF" version="2.5.1" targetFramework="net461" /> - <package id="dotNetRDF.Data.Virtuoso" version="2.5.1" targetFramework="net461" /> + <package id="dotNetRDF" version="2.6.0" targetFramework="net461" /> + <package id="dotNetRDF.Data.Virtuoso" version="2.6.0" targetFramework="net461" /> <package id="EntityFramework" version="6.4.4" targetFramework="net461" /> - <package id="HtmlAgilityPack" version="1.11.17" targetFramework="net461" /> + <package id="HtmlAgilityPack" version="1.11.24" targetFramework="net461" /> <package id="linq2db" version="3.1.1" targetFramework="net461" /> <package id="linq2db.SqlServer" version="2.6.4" targetFramework="net461" /> <package id="linq2db.t4models" version="2.6.4" targetFramework="net461" />