Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Fix/xxxx-activateGitlab
  • Fix/xxxx-resourceVisibility
  • Hotfix/0071-fixResourceCreate
  • Hotfix/1259-pathParameterFix
  • Hotfix/1260-fixUrl
  • Hotfix/1357-ymlFile
  • Hotfix/1370-swaggerDescription
  • Hotfix/1584-fixResourceLoader
  • Hotfix/1616-repairLinkedResources
  • Hotfix/1634-limitConsulCalls
  • Hotfix/1668-versionResourceConfigDepVersion
  • Hotfix/1681-fixLargeFileSizeQuery
  • Hotfix/1805-listingBreaks
  • Hotfix/2087-efNet6
  • Hotfix/2104-failedUpload
  • Hotfix/2141-fileUploadErrors
  • Hotfix/2233-fixMe
  • Hotfix/2254-fixContentLenghtCalculation
  • Hotfix/2296-selectedValuesNotReturned
  • Hotfix/2307-noLinkedTimeout
  • Hotfix/2313-fixModifiedDate
  • Hotfix/2365-targetClassWorks
  • Hotfix/2371-fixGitLabinRCV
  • Hotfix/2384-guestsAndLinked
  • Hotfix/2452-linkedDeletion
  • Hotfix/2459-EncodingPath
  • Hotfix/2504-formGen
  • Hotfix/64-releaseUDE
  • Issue/1741-semanticSearchActions
  • Issue/1792-newMetadataStructure
  • Issue/1804-fixedValueFix
  • Issue/1866-ExtendResourceTypeConfigurationTUDo
  • Issue/1877-ExtendResourceTypeConfigurationNRWFHs
  • Issue/1910-MigrationtoNET6.0
  • Issue/1912-uriMadness
  • Issue/1938-internalHandling
  • Issue/1940ResouceKeysForNRWAndTUDO
  • Issue/1951-quotaImplementation
  • Issue/1953-owlImports
  • Issue/2061-activateResourceTypeRdss3nrw
  • Issue/2072-wormResourceType
  • Issue/2102-gitLabResTypeRCV
  • Issue/2122-retrieveWithoutFile
  • Issue/2162-fixFolderResponse
  • Issue/2162-fixFolderResponsev2
  • Issue/2173-numericalTypes
  • Issue/2195-modifiedDate
  • Issue/2287-guestRole
  • Issue/2309-docs
  • Issue/2349-gitlabHttps
  • Issue/2462-removeTraces
  • Issue/2583-treeBug
  • Product/1100-fdsS3
  • Product/1154-resourceTypeDefinition
  • Product/1188-LoggingExtended
  • Product/1188-logginExtended
  • Product/1287-dotnet5Sharepoint
  • Product/1472-exposingUrls
  • Product/1552-correctFolders
  • Product/1555-readOnlyResources
  • Product/1629-onboardingOtherUniversities
  • Product/938-docuTreeApi
  • Sprint/2020-20
  • Sprint/2020-21
  • Sprint/2020-22
  • Sprint/2021-01
  • Sprint/2021-03
  • Sprint/2021-05
  • Sprint/2021-08
  • Sprint/2021-09
  • Sprint/2021-10
  • Sprint/2021-11
  • Sprint/2021-13
  • Sprint/2021-15
  • Sprint/2021-16
  • Sprint/2021-23
  • Sprint/2022-01
  • Test/xxxx-enablingGitLab
  • Topic/1114-docuTreeApi
  • Topic/1159-rtdApi
  • Topic/1221-LogginExtendedNew
  • Topic/1221-loggingExtended
  • Topic/1292-FdsS3
  • Topic/1335-dotnet5Apis
  • Topic/1527-exposingUrls
  • Topic/1575-CheckArchivingStatus
  • Topic/1658-correctFolders
  • Topic/1673-DisplayFoldersMetadata
  • Topic/1711-extendResourceTypeConfiguration
  • dev
  • gitkeep
  • master
  • product/1472-exposingUrls
  • v2.8.14-Hotfix2365
  • v1.1.0
  • v1.1.1
  • v1.1.2
  • v1.1.3
  • v1.2.0
  • v1.2.1
  • v2.0.0
  • v2.0.1
  • v2.1.0
  • v2.1.1
  • v2.10.0
  • v2.10.1
  • v2.10.2
  • v2.10.3
  • v2.11.0
  • v2.11.1
  • v2.11.2
  • v2.11.3
  • v2.11.4
  • v2.11.5
  • v2.2.0
  • v2.2.1
  • v2.2.2
  • v2.3.0
  • v2.3.1
  • v2.3.2
  • v2.3.3
  • v2.3.4
  • v2.4.0
  • v2.4.1
  • v2.4.2
  • v2.4.3
  • v2.4.4
  • v2.5.0
  • v2.5.1
  • v2.5.2
  • v2.5.3
  • v2.6.0
  • v2.6.1
  • v2.6.2
  • v2.6.3
  • v2.6.4
  • v2.7.0
  • v2.8.0
  • v2.8.1
  • v2.8.10
  • v2.8.11
  • v2.8.12
  • v2.8.13
  • v2.8.14
  • v2.8.15
  • v2.8.16
  • v2.8.2
  • v2.8.3
  • v2.8.4
  • v2.8.5
  • v2.8.6
  • v2.8.7
  • v2.8.8
  • v2.8.9
  • v2.9.0
  • v2.9.1
  • v2.9.2
  • v2.9.3
  • v2.9.4
159 results

Target

Select target project
  • coscine/backend/apis/treeapi
1 result
Select Git revision
  • Fix/xxxx-activateGitlab
  • Fix/xxxx-resourceVisibility
  • Hotfix/0071-fixResourceCreate
  • Hotfix/1259-pathParameterFix
  • Hotfix/1260-fixUrl
  • Hotfix/1357-ymlFile
  • Hotfix/1370-swaggerDescription
  • Hotfix/1584-fixResourceLoader
  • Hotfix/1616-repairLinkedResources
  • Hotfix/1634-limitConsulCalls
  • Hotfix/1668-versionResourceConfigDepVersion
  • Hotfix/1681-fixLargeFileSizeQuery
  • Hotfix/1805-listingBreaks
  • Hotfix/2087-efNet6
  • Hotfix/2104-failedUpload
  • Hotfix/2141-fileUploadErrors
  • Hotfix/2233-fixMe
  • Hotfix/2254-fixContentLenghtCalculation
  • Hotfix/2296-selectedValuesNotReturned
  • Hotfix/2307-noLinkedTimeout
  • Hotfix/2313-fixModifiedDate
  • Hotfix/2365-targetClassWorks
  • Hotfix/2371-fixGitLabinRCV
  • Hotfix/2384-guestsAndLinked
  • Hotfix/2452-linkedDeletion
  • Hotfix/2459-EncodingPath
  • Hotfix/2504-formGen
  • Hotfix/64-releaseUDE
  • Issue/1741-semanticSearchActions
  • Issue/1792-newMetadataStructure
  • Issue/1804-fixedValueFix
  • Issue/1866-ExtendResourceTypeConfigurationTUDo
  • Issue/1877-ExtendResourceTypeConfigurationNRWFHs
  • Issue/1910-MigrationtoNET6.0
  • Issue/1912-uriMadness
  • Issue/1938-internalHandling
  • Issue/1940ResouceKeysForNRWAndTUDO
  • Issue/1951-quotaImplementation
  • Issue/1953-owlImports
  • Issue/2061-activateResourceTypeRdss3nrw
  • Issue/2072-wormResourceType
  • Issue/2102-gitLabResTypeRCV
  • Issue/2122-retrieveWithoutFile
  • Issue/2162-fixFolderResponse
  • Issue/2162-fixFolderResponsev2
  • Issue/2173-numericalTypes
  • Issue/2195-modifiedDate
  • Issue/2287-guestRole
  • Issue/2309-docs
  • Issue/2349-gitlabHttps
  • Issue/2462-removeTraces
  • Issue/2583-treeBug
  • Product/1100-fdsS3
  • Product/1154-resourceTypeDefinition
  • Product/1188-LoggingExtended
  • Product/1188-logginExtended
  • Product/1287-dotnet5Sharepoint
  • Product/1472-exposingUrls
  • Product/1552-correctFolders
  • Product/1555-readOnlyResources
  • Product/1629-onboardingOtherUniversities
  • Product/938-docuTreeApi
  • Sprint/2020-20
  • Sprint/2020-21
  • Sprint/2020-22
  • Sprint/2021-01
  • Sprint/2021-03
  • Sprint/2021-05
  • Sprint/2021-08
  • Sprint/2021-09
  • Sprint/2021-10
  • Sprint/2021-11
  • Sprint/2021-13
  • Sprint/2021-15
  • Sprint/2021-16
  • Sprint/2021-23
  • Sprint/2022-01
  • Test/xxxx-enablingGitLab
  • Topic/1114-docuTreeApi
  • Topic/1159-rtdApi
  • Topic/1221-LogginExtendedNew
  • Topic/1221-loggingExtended
  • Topic/1292-FdsS3
  • Topic/1335-dotnet5Apis
  • Topic/1527-exposingUrls
  • Topic/1575-CheckArchivingStatus
  • Topic/1658-correctFolders
  • Topic/1673-DisplayFoldersMetadata
  • Topic/1711-extendResourceTypeConfiguration
  • dev
  • gitkeep
  • master
  • product/1472-exposingUrls
  • v2.8.14-Hotfix2365
  • v1.1.0
  • v1.1.1
  • v1.1.2
  • v1.1.3
  • v1.2.0
  • v1.2.1
  • v2.0.0
  • v2.0.1
  • v2.1.0
  • v2.1.1
  • v2.10.0
  • v2.10.1
  • v2.10.2
  • v2.10.3
  • v2.11.0
  • v2.11.1
  • v2.11.2
  • v2.11.3
  • v2.11.4
  • v2.11.5
  • v2.2.0
  • v2.2.1
  • v2.2.2
  • v2.3.0
  • v2.3.1
  • v2.3.2
  • v2.3.3
  • v2.3.4
  • v2.4.0
  • v2.4.1
  • v2.4.2
  • v2.4.3
  • v2.4.4
  • v2.5.0
  • v2.5.1
  • v2.5.2
  • v2.5.3
  • v2.6.0
  • v2.6.1
  • v2.6.2
  • v2.6.3
  • v2.6.4
  • v2.7.0
  • v2.8.0
  • v2.8.1
  • v2.8.10
  • v2.8.11
  • v2.8.12
  • v2.8.13
  • v2.8.14
  • v2.8.15
  • v2.8.16
  • v2.8.2
  • v2.8.3
  • v2.8.4
  • v2.8.5
  • v2.8.6
  • v2.8.7
  • v2.8.8
  • v2.8.9
  • v2.9.0
  • v2.9.1
  • v2.9.2
  • v2.9.3
  • v2.9.4
159 results
Show changes

Commits on Source 8

{
"version": 1,
"isRoot": true,
"tools": {
"gitversion.tool": {
"version": "5.6.6",
"commands": [
"dotnet-gitversion"
]
},
"dotnet-version-cli": {
"version": "2.1.1",
"commands": [
"dotnet-version"
]
}
}
}
\ No newline at end of file
...@@ -268,3 +268,6 @@ dist/ ...@@ -268,3 +268,6 @@ dist/
#linq2db #linq2db
src/.tools/* src/.tools/*
# Dotnet Tool Manifest
.config/*
\ No newline at end of file
...@@ -37,10 +37,10 @@ namespace Coscine.Api.Tree.Controllers ...@@ -37,10 +37,10 @@ namespace Coscine.Api.Tree.Controllers
private readonly ProjectRoleModel _projectRoleModel; private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectResourceModel _projectResourceModel; private readonly ProjectResourceModel _projectResourceModel;
private readonly CoscineLogger _coscineLogger; private readonly CoscineLogger _coscineLogger;
private readonly AnalyticsLogObject _analyticsLogObject;
private readonly string _blobApiLink; private readonly string _blobApiLink;
private readonly string _prefix; private readonly string _prefix;
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly string _shaclPropertyUrl = "http://www.w3.org/ns/shacl#property";
/// <summary> /// <summary>
/// Tree controller constructor /// Tree controller constructor
...@@ -56,11 +56,10 @@ namespace Coscine.Api.Tree.Controllers ...@@ -56,11 +56,10 @@ namespace Coscine.Api.Tree.Controllers
_projectResourceModel = new ProjectResourceModel(); _projectResourceModel = new ProjectResourceModel();
_coscineLogger = new CoscineLogger(logger); _coscineLogger = new CoscineLogger(logger);
_analyticsLogObject = new AnalyticsLogObject();
var rule = _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 host = rule["Host:".Length..rule.IndexOf(";")];
var path = rule.Substring(rule.IndexOf("/")); var path = rule[rule.IndexOf("/")..];
_blobApiLink = $"https://{host}{path}/blob/"; _blobApiLink = $"https://{host}{path}/blob/";
_prefix = _configuration.GetStringAndWait("coscine/global/epic/prefix"); _prefix = _configuration.GetStringAndWait("coscine/global/epic/prefix");
} }
...@@ -94,6 +93,11 @@ namespace Coscine.Api.Tree.Controllers ...@@ -94,6 +93,11 @@ namespace Coscine.Api.Tree.Controllers
var user = _authenticator.GetUser(); var user = _authenticator.GetUser();
var check = CheckResourceIdAndPath(resourceId, path, out Resource resource); var check = CheckResourceIdAndPath(resourceId, path, out Resource resource);
if (resource.ApplicationProfile[^1] != '/')
{
resource.ApplicationProfile += '/';
}
if (user == null || !_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member)) if (user == null || !_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
{ {
return Forbid("User has no Access to this resource."); return Forbid("User has no Access to this resource.");
...@@ -115,13 +119,14 @@ namespace Coscine.Api.Tree.Controllers ...@@ -115,13 +119,14 @@ namespace Coscine.Api.Tree.Controllers
var infos = await resourceTypeDefinition.ListEntries(resourceId, path, resourceTypeOptions); var infos = await resourceTypeDefinition.ListEntries(resourceId, path, resourceTypeOptions);
var graphs = new List<JToken>(); var graphs = new List<JToken>();
int metadataCount = 0;
foreach (var info in infos) foreach (var info in infos)
{ {
var id = GenerateId(resourceId, info.Key); var id = GenerateId(resourceId, info.Key);
if (_rdfStoreConnector.HasGraph(id.AbsoluteUri)) if (_rdfStoreConnector.HasGraph(id.AbsoluteUri))
{ {
var graph = _rdfStoreConnector.GetGraph(id); var graph = _rdfStoreConnector.GetGraph(id);
metadataCount = graph.Triples.Count;
graphs.Add(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()))); graphs.Add(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())));
} }
} }
...@@ -133,10 +138,10 @@ namespace Coscine.Api.Tree.Controllers ...@@ -133,10 +138,10 @@ namespace Coscine.Api.Tree.Controllers
{ {
var objectMetaInfo = new ObjectMetaInfo var objectMetaInfo = new ObjectMetaInfo
{ {
Name = x.Key.Substring(x.Key.LastIndexOf("/") + 1), Name = x.Key[(x.Key.LastIndexOf("/") + 1)..],
Path = x.Key, Path = x.Key,
Size = (int)x.BodyBytes, Size = (int)x.BodyBytes,
Kind = x.Key.Substring(x.Key.LastIndexOf(".") + 1), Kind = x.Key[(x.Key.LastIndexOf(".") + 1)..],
Provider = resource.Type.DisplayName Provider = resource.Type.DisplayName
}; };
var objectMetaInfoReturnObject = new ObjectMetaInfoReturnObject(objectMetaInfo, _blobApiLink, resource.Id.ToString()); var objectMetaInfoReturnObject = new ObjectMetaInfoReturnObject(objectMetaInfo, _blobApiLink, resource.Id.ToString());
...@@ -173,7 +178,11 @@ namespace Coscine.Api.Tree.Controllers ...@@ -173,7 +178,11 @@ namespace Coscine.Api.Tree.Controllers
)) ))
); );
LogAnalytics("View MD", resourceId, path, user); if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics) && path != "/")
{
LogAnalyticsViewMd(_projectResourceModel.GetProjectForResource(resource.Id).Value, resource.Id, path, user, GetMetadataCompleteness(metadataCount, resource));
}
return Json(jObject); return Json(jObject);
} }
catch catch
...@@ -213,10 +222,11 @@ namespace Coscine.Api.Tree.Controllers ...@@ -213,10 +222,11 @@ namespace Coscine.Api.Tree.Controllers
return Forbid("User is no project member!"); return Forbid("User is no project member!");
} }
if (resource.ApplicationProfile[resource.ApplicationProfile.Length - 1] != '/') if (resource.ApplicationProfile[^1] != '/')
{ {
resource.ApplicationProfile += '/'; resource.ApplicationProfile += '/';
} }
json[graphNameUri.AbsoluteUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"] = new JArray json[graphNameUri.AbsoluteUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"] = new JArray
{ {
new JObject new JObject
...@@ -282,16 +292,25 @@ namespace Coscine.Api.Tree.Controllers ...@@ -282,16 +292,25 @@ namespace Coscine.Api.Tree.Controllers
{ {
return BadRequest("Data has the wrong format!"); return BadRequest("Data has the wrong format!");
} }
// store the data // store the data
if (_rdfStoreConnector.HasGraph(graphNameUri)) if (_rdfStoreConnector.HasGraph(graphNameUri))
{ {
_rdfStoreConnector.ClearGraph(graphNameUri); _rdfStoreConnector.ClearGraph(graphNameUri);
LogAnalytics("Update MD", resourceId, path, user);
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
{
LogAnalyticsUpdateMd(_projectResourceModel.GetProjectForResource(resource.Id).Value, resource.Id, path, user, GetMetadataCompleteness(graph.Triples.Count, resource));
}
} }
else else
{ {
_rdfStoreConnector.CreateNamedGraph(graphNameUri); _rdfStoreConnector.CreateNamedGraph(graphNameUri);
LogAnalytics("Upload MD", resourceId, path, user);
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 // BaseUri must be set for the sparql query
...@@ -351,25 +370,67 @@ namespace Coscine.Api.Tree.Controllers ...@@ -351,25 +370,67 @@ namespace Coscine.Api.Tree.Controllers
return null; return null;
} }
/// <summary> private void LogAnalyticsViewMd(Guid projectId, Guid resourceId, string filename, User user, string metadataCompletness)
/// 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)) var analyticsLogObject = new AnalyticsLogObject
{
Type = "Action",
Operation = "View MD",
RoleId = _projectRoleModel.GetGetUserRoleForProject(projectId, user.Id).ToString(),
ProjectId = projectId.ToString(),
ResourceId = resourceId.ToString(),
FileId = resourceId.ToString() + "/" + HttpUtility.UrlDecode(filename)[1..],
ApplicationsProfile = _resourceModel.CreateReturnObjectFromDatabaseObject(_resourceModel.GetById(resourceId)).ApplicationProfile,
MetadataCompleteness = metadataCompletness,
};
_coscineLogger.AnalyticsLog(analyticsLogObject);
}
private void LogAnalyticsUploadMd(Guid projectId, Guid resourceId, string filename, User user, string metadataCompletness)
{
var analyticsLogObject = new AnalyticsLogObject
{ {
_analyticsLogObject.Type = "Action"; Type = "Action",
_analyticsLogObject.Operation = operation; Operation = "Upload MD",
_analyticsLogObject.FileId = resourceId + "/" + HttpUtility.UrlDecode(filename).Substring(1); RoleId = _projectRoleModel.GetGetUserRoleForProject(projectId, user.Id).ToString(),
_analyticsLogObject.ResourceId = resourceId; ProjectId = projectId.ToString(),
_analyticsLogObject.ProjectId = _projectResourceModel.GetProjectForResource(new Guid(resourceId)).ToString(); ResourceId = resourceId.ToString(),
_analyticsLogObject.RoleId = _projectRoleModel.GetGetUserRoleForProject(new Guid(_analyticsLogObject.ProjectId), user.Id).ToString(); FileId = resourceId.ToString() + "/" + HttpUtility.UrlDecode(filename)[1..],
_coscineLogger.AnalyticsLog(_analyticsLogObject); ApplicationsProfile = _resourceModel.CreateReturnObjectFromDatabaseObject(_resourceModel.GetById(resourceId)).ApplicationProfile,
MetadataCompleteness = metadataCompletness,
};
_coscineLogger.AnalyticsLog(analyticsLogObject);
} }
private void LogAnalyticsUpdateMd(Guid projectId, Guid resourceId, string filename, User user, string metadataCompletness)
{
var analyticsLogObject = new AnalyticsLogObject
{
Type = "Action",
Operation = "Update MD",
RoleId = _projectRoleModel.GetGetUserRoleForProject(projectId, user.Id).ToString(),
ProjectId = projectId.ToString(),
ResourceId = resourceId.ToString(),
FileId = resourceId.ToString() + "/" + HttpUtility.UrlDecode(filename)[1..],
ApplicationsProfile = _resourceModel.CreateReturnObjectFromDatabaseObject(_resourceModel.GetById(resourceId)).ApplicationProfile,
MetadataCompleteness = metadataCompletness,
};
_coscineLogger.AnalyticsLog(analyticsLogObject);
}
private string GetMetadataCompleteness(int metadataCount, Resource resource)
{
var shapesGraph = _rdfStoreConnector.GetGraph(resource.ApplicationProfile);
var nodeFactory = new NodeFactory();
var uriNode = (UriNode)nodeFactory.CreateUriNode(new Uri(_shaclPropertyUrl));
var total = shapesGraph.GetTriplesWithPredicate(uriNode).Count();
var present = metadataCount;
return $"{present}/{total}";
} }
} }
} }
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RootNamespace>Coscine.Api.Tree</RootNamespace> <RootNamespace>Coscine.Api.Tree</RootNamespace>
<AssemblyName>Coscine.Api.Tree</AssemblyName> <AssemblyName>Coscine.Api.Tree</AssemblyName>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<Version>2.0.1</Version> <Version>2.1.0</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<Authors>RWTH Aachen University</Authors> <Authors>RWTH Aachen University</Authors>
...@@ -17,6 +18,8 @@ ...@@ -17,6 +18,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Coscine.ApiCommons" Version="2.*-*" /> <PackageReference Include="Coscine.ApiCommons" Version="2.*-*" />
<PackageReference Include="Coscine.Database" Version="2.*-*" />
<PackageReference Include="Coscine.Logging" Version="2.*-*" />
<PackageReference Include="Coscine.Metadata" Version="2.*-*" /> <PackageReference Include="Coscine.Metadata" Version="2.*-*" />
<PackageReference Include="Coscine.ResourceLoader" Version="2.*-*" /> <PackageReference Include="Coscine.ResourceLoader" Version="2.*-*" />
<PackageReference Include="Coscine.WaterbutlerHelper" Version="2.*-*" /> <PackageReference Include="Coscine.WaterbutlerHelper" Version="2.*-*" />
......