diff --git a/Directory.Packages.props b/Directory.Packages.props index 2eb0a64515..3fa7502b43 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,6 +10,7 @@ + diff --git a/Rdmp.Core.Tests/Datasets/HDR/HDRDatasetProviderTests.cs b/Rdmp.Core.Tests/Datasets/HDR/HDRDatasetProviderTests.cs new file mode 100644 index 0000000000..2f2cc1e1ae --- /dev/null +++ b/Rdmp.Core.Tests/Datasets/HDR/HDRDatasetProviderTests.cs @@ -0,0 +1,199 @@ +using NUnit.Framework; +using Rdmp.Core.CommandExecution; +using Rdmp.Core.Curation.Data.Datasets; +using Rdmp.Core.Curation.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Tests.Common; +using Rdmp.Core.Curation.Data.Datasets.HDR; +using JustEat.HttpClientInterception; + +namespace Rdmp.Core.Tests.Datasets.HDR +{ + class HDRDatasetProviderTests : DatabaseTests + { + private DatasetProviderConfiguration _configuration; + private HDRDatasetProvider _provider; + private Catalogue _catalogue; + private HttpClient _mockHttp; + private HttpClientInterceptorOptions options = new HttpClientInterceptorOptions { ThrowOnMissingRegistration = true }; + + [TearDown] + public void OneTimeTeardown() + { + _mockHttp.Dispose(); + } + + [OneTimeSetUp] + public void OneTimeSetup() + { + var dataAccessCredentials = new DataAccessCredentials(CatalogueRepository, "name") + { + Username = "test", + Password = "test" + }; + dataAccessCredentials.SaveToDatabase(); + + _configuration = new DatasetProviderConfiguration(CatalogueRepository, "Test Provider", typeof(HDRDatasetProvider).ToString(), "https://doesNotExist.preprod.hdruk.cloud/api", dataAccessCredentials.ID, "1234"); + + _configuration.SaveToDatabase(); + + _provider = new HDRDatasetProvider(new ThrowImmediatelyActivator(RepositoryLocator), _configuration, _mockHttp); + _catalogue = new Catalogue(CatalogueRepository, "HDR test Catalogue"); + _catalogue.SaveToDatabase(); + + } + private void SetupHttpClient(HttpRequestInterceptionBuilder builder) + { + builder.RegisterWith(options); + _mockHttp = options.CreateHttpClient(); + _provider = new HDRDatasetProvider(new ThrowImmediatelyActivator(RepositoryLocator), _configuration, _mockHttp); + } + + [Test] + public void CreateProviderTest() + { + Assert.DoesNotThrow(() => _configuration.GetProviderInstance(new ThrowImmediatelyActivator(RepositoryLocator))); + } + [Test] + public void AddExistingDatasetTest_Success() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("doesnotexist.preprod.hdruk.cloud") + .ForPath("api/v1/datasets/999") + .ForQuery("schema_model=HDRUK&schema_version=3.0.0") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + string name = "AddExistingDatasetTest_Success"; + Assert.DoesNotThrow(() => _provider.AddExistingDataset(name, url)); + var dataset = CatalogueRepository.GetAllObjects().FirstOrDefault(d => d.Name == name); + Assert.That(dataset, Is.Not.Null); + dataset.DeleteInDatabase(); + } + [Test] + public void AddExistingDatasetTest_BadRemote() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("doesnotexist.preprod.hdruk.cloud") + .ForPath("api/v1/datasets/999") + .ForQuery("schema_model=HDRUK&schema_version=3.0.0") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + string name = "HDRAddExistingDatasetTest_BadRemote"; + Assert.Throws(() => _provider.AddExistingDataset(name, url)); + var dataset = CatalogueRepository.GetAllObjects().FirstOrDefault(d => d.Name == name); + Assert.That(dataset, Is.Null); + } + + [Test] + public void AddExistingDatasetWithReturnTest_Success() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("doesnotexist.preprod.hdruk.cloud") + .ForPath("api/v1/datasets/999") + .ForQuery("schema_model=HDRUK&schema_version=3.0.0") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + string name = "AddExistingDatasetTest_Success"; + Assert.DoesNotThrow(() => _provider.AddExistingDatasetWithReturn(name, url)); + var dataset = CatalogueRepository.GetAllObjects().FirstOrDefault(d => d.Name == name); + Assert.That(dataset, Is.Not.Null); + dataset.DeleteInDatabase(); + } + [Test] + public void AddExistingDatasetWithReturnTest_BadRemote() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("doesnotexist.preprod.hdruk.cloud") + .ForPath("api/v1/datasets/999") + .ForQuery("schema_model=HDRUK&schema_version=3.0.0") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + string name = "HDRAddExistingDatasetTest_BadRemote"; + Assert.Throws(() => _provider.AddExistingDatasetWithReturn(name, url)); + var dataset = CatalogueRepository.GetAllObjects().FirstOrDefault(d => d.Name == name); + Assert.That(dataset, Is.Null); + } + + //FetchDatasetByID + [Test] + public void FetchDatasetByIDTest_Success() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("doesnotexist.preprod.hdruk.cloud") + .ForPath("api/v1/datasets/999") + .ForQuery("schema_model=HDRUK&schema_version=3.0.0") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + Assert.DoesNotThrow(() => _provider.FetchDatasetByID(int.Parse(url))); + } + [Test] + public void FetchDatasetByIDTest_BadRemote() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("doesnotexist.preprod.hdruk.cloud") + .ForPath("api/v1/datasets/999") + .ForQuery("schema_model=HDRUK&schema_version=3.0.0") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + Assert.Throws(() => _provider.FetchDatasetByID(int.Parse(url))); + } + + private object SucessResponseString = new + { + id = "22", + name = "AddExistingDatasetWithReturnTest_Success", + type = "Dataset", + url = "22", + source = "Jira", + _links = new + { + self = "https://api.atlassian.com/jsm/assets/workspace/1234/v1/object/22", + } + }; + + private object SucessCreateString = new + { + + }; + + private List SucessObjectTypesString = [new { name = "Dataset", id = 1, objectSchemaId = 4 }]; + + private List SuccessObjectTypeAttributes = [ + new {name="Name",id=2 } + ]; + + private object SucessAQLResult = new + { + values = new List() + }; + } +} diff --git a/Rdmp.Core.Tests/Rdmp.Core.Tests.csproj b/Rdmp.Core.Tests/Rdmp.Core.Tests.csproj index 4821571fde..c449d5feca 100644 --- a/Rdmp.Core.Tests/Rdmp.Core.Tests.csproj +++ b/Rdmp.Core.Tests/Rdmp.Core.Tests.csproj @@ -68,6 +68,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs b/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs index a3a572722d..e8d28acb25 100644 --- a/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs +++ b/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs @@ -33,24 +33,25 @@ public ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider(IBasicA public List GetCatalogues() { + var cataloguesToReturn = new List(); var catalogues = _activator.RepositoryLocator.CatalogueRepository.GetAllObjects().ToList(); - if (!_includeInternal) + if (_includeInternal) { - catalogues = catalogues.Where(c => !c.IsInternalDataset).ToList(); + cataloguesToReturn.AddRange(catalogues.Where(c => c.IsInternalDataset).ToList()); } - if (!_includeProjectSpecific) + if (_includeProjectSpecific) { - catalogues = catalogues.Where(c => !c.IsProjectSpecific(_activator.RepositoryLocator.DataExportRepository)).ToList(); + cataloguesToReturn.AddRange(catalogues.Where(c => c.IsProjectSpecific(_activator.RepositoryLocator.DataExportRepository)).ToList()); } - if (!_includeDeprecated) + if (_includeDeprecated) { - catalogues = catalogues.Where(c => !c.IsDeprecated).ToList(); + cataloguesToReturn.AddRange(catalogues.Where(c => c.IsDeprecated).ToList()); } - if (!_includeExtractable) + if (_includeExtractable) { - catalogues = catalogues.Where(c => !c.GetExtractabilityStatus(_activator.RepositoryLocator.DataExportRepository).IsExtractable).ToList(); + cataloguesToReturn.AddRange(catalogues.Where(c => c.GetExtractabilityStatus(_activator.RepositoryLocator.DataExportRepository).IsExtractable).ToList()); } - return catalogues; + return cataloguesToReturn.Distinct().ToList(); } diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDataset.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDataset.cs new file mode 100644 index 0000000000..d3566a0475 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDataset.cs @@ -0,0 +1,40 @@ +using Rdmp.Core.Repositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR +{ + /// + /// Mapping of HDR Dataset object to C# + /// + public class HDRDataset : PluginDataset + { + public HDRDataset() : base() { } + public HDRDataset(ICatalogueRepository catalogueRepository, string name) : base(catalogueRepository, name) + { + } + + public HDRDatasetItems.Data data { get; set; } + + public override string GetID() + { + return data.id.ToString(); + } + public override string GetRemoteID() + { + return Url.Split('?')[0].Split('/').Last(); + } + + public string GetDOI() + { + var version = data?.versions?.FirstOrDefault(); + if (version != null) { + return version.metadata?.metadata?.summary?.doiName?.ToString(); + } + return null; + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Access.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Access.cs new file mode 100644 index 0000000000..3db5439f25 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Access.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Access + { + public string deliveryLeadTime { get; set; } + public List jurisdiction { get; set; } + public string dataController { get; set; } + public string dataProcessor { get; set; } + public string accessRights { get; set; } + public string accessService { get; set; } + public string accessRequestCost { get; set; } + public object accessServiceCategory { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Accessibility.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Accessibility.cs new file mode 100644 index 0000000000..0119fec913 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Accessibility.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Accessibility + { + public Access access { get; set; } + public Usage usage { get; set; } + public FormatAndStandards formatAndStandards { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Coverage.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Coverage.cs new file mode 100644 index 0000000000..093f485f57 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Coverage.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Coverage + { + public object pathway { get; set; } + public string spatial { get; set; } + public object followUp { get; set; } + public object datasetCompleteness { get; set; } + public List materialType { get; set; } + public int typicalAgeRangeMin { get; set; } + public int typicalAgeRangeMax { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Data.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Data.cs new file mode 100644 index 0000000000..87a99665bc --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Data.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NPOI.HSSF.Util.HSSFColor; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Data + { + public int id { get; set; } + public object mongo_object_id { get; set; } + public object mongo_id { get; set; } + public object mongo_pid { get; set; } + public object datasetid { get; set; } + public string pid { get; set; } + public object source { get; set; } + public int discourse_topic_id { get; set; } + public bool is_cohort_discovery { get; set; } + public int commercial_use { get; set; } + public int state_id { get; set; } + public int uploader_id { get; set; } + public int metadataquality_id { get; set; } + public int user_id { get; set; } + public int team_id { get; set; } + public int views_count { get; set; } + public int views_prev_count { get; set; } + public int has_technical_details { get; set; } + public string created { get; set; } + public string updated { get; set; } + public string submitted { get; set; } + public object published { get; set; } + public DateTime created_at { get; set; } + public DateTime updated_at { get; set; } + public object deleted_at { get; set; } + public string create_origin { get; set; } + public string status { get; set; } + public int durs_count { get; set; } + public int publications_count { get; set; } + public int tools_count { get; set; } + public int collections_count { get; set; } + public List spatialCoverage { get; set; } + public List durs { get; set; } + public List publications { get; set; } + public List named_entities { get; set; } + public List collections { get; set; } + public List versions { get; set; } + public Team team { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/DataCustodian.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/DataCustodian.cs new file mode 100644 index 0000000000..c6932cfb94 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/DataCustodian.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class DataCustodian + { + public string name { get; set; } + public string identifier { get; set; } + public string contactPoint { get; set; } + public object logo { get; set; } + public object description { get; set; } + public object memberOf { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Documentation.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Documentation.cs new file mode 100644 index 0000000000..86a72487ce --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Documentation.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Documentation + { + public string description { get; set; } + public object associatedMedia { get; set; } + public string inPipeline { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/EnrichmentAndLinkage.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/EnrichmentAndLinkage.cs new file mode 100644 index 0000000000..268afd3bfa --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/EnrichmentAndLinkage.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class EnrichmentAndLinkage + { + public List tools { get; set; } + public List investigations { get; set; } + public List publicationAboutDataset { get; set; } + public List publicationUsingDataset { get; set; } + + [JsonIgnore] + public object derivedFrom { get; set; } + + [JsonIgnore] + public object isPartOf { get; set; } + + [JsonIgnore] + public object linkableDatasets { get; set; } + + [JsonIgnore] + public object similarToDatasets { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/FormatAndStandards.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/FormatAndStandards.cs new file mode 100644 index 0000000000..1538ff0e39 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/FormatAndStandards.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class FormatAndStandards + { + public List conformsTo { get; set; } + public List vocabularyEncodingScheme { get; set; } + public List language { get; set; } + public List format { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Metadata.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Metadata.cs new file mode 100644 index 0000000000..0efa87d688 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Metadata.cs @@ -0,0 +1,38 @@ +using MathNet.Numerics; +using Rdmp.Core.Curation.Data.Datasets.HDR.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Metadata + { + public Metadata metadata { get; set; } + public string identifier { get; set; } + + [JsonConverter(typeof(CustomDateTimeConverterThreeMilliseconds))] + public DateTime issued { get; set; } + + [JsonConverter(typeof(CustomDateTimeConverterThreeMilliseconds))] + public DateTime modified { get; set; } + public List revisions { get; set; } + public string version { get; set; } + public Summary summary { get; set; } + public Documentation documentation { get; set; } + public Coverage coverage { get; set; } + public Provenance provenance { get; set; } + public Accessibility accessibility { get; set; } + public EnrichmentAndLinkage enrichmentAndLinkage { get; set; } + public List observations { get; set; } + public StructuralMetadata structuralMetadata { get; set; } + public object demographicFrequency { get; set; } + public object omics { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/NamedEntity.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/NamedEntity.cs new file mode 100644 index 0000000000..1767847fb5 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/NamedEntity.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class NamedEntity + { + public int id { get; set; } + public string name { get; set; } + public DateTime created_at { get; set; } + public DateTime updated_at { get; set; } + public object deleted_at { get; set; } + public List dataset_version_ids { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Origin.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Origin.cs new file mode 100644 index 0000000000..5e2b7a2685 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Origin.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Origin + { + public List purpose { get; set; } + public List source { get; set; } + public List collectionSource { get; set; } + public List datasetType { get; set; } + public List datasetSubType { get; set; } + public string imageContrast { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PatchMetadata.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PatchMetadata.cs new file mode 100644 index 0000000000..1a0fe0021b --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PatchMetadata.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Used to map patch updates to HDR API + /// + public class PatchMetadata + { + + public string schemaModel { get; set; } + public string schemaVersion { get; set; } + public PatchSubMetadata metadata { get; set; } + + + public PatchMetadata() { } + public PatchMetadata(HDRDatasetItems.Metadata existingMetadata) + { + + metadata = existingMetadata.metadata != null ? new PatchSubMetadata(existingMetadata.metadata) : null; + schemaModel = "HDRUK"; + schemaVersion = "3.0.0"; + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PatchSubMetadata.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PatchSubMetadata.cs new file mode 100644 index 0000000000..4b12decf6f --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PatchSubMetadata.cs @@ -0,0 +1,54 @@ +using Rdmp.Core.Curation.Data.Datasets.HDR.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class PatchSubMetadata + { + public object observations { get; set; } + public Coverage coverage { get; set; } + public object structuralMetadata { get; set; } + public object enrichmentAndLinkage { get; set; } + public Accessibility accessibility { get; set; } + + public string identifier { get; set; } + [JsonConverter(typeof(CustomDateTimeConverterThreeMilliseconds))] + + public DateTime issued { get; set; } + [JsonConverter(typeof(CustomDateTimeConverterThreeMilliseconds))] + + public DateTime modified { get; set; } + + public Provenance provenance { get; set; } + public object documentation { get; set; } + public Summary summary { get; set; } + public List revisions { get; set; } + + public string version { get; set; } + + public PatchSubMetadata(HDRDatasetItems.Metadata existingMetadata) + { + accessibility = existingMetadata.accessibility; + observations = existingMetadata.observations; + coverage = existingMetadata.coverage; + structuralMetadata = existingMetadata.structuralMetadata; + enrichmentAndLinkage = existingMetadata.enrichmentAndLinkage; + provenance = existingMetadata.provenance; + documentation = existingMetadata.documentation; + summary = existingMetadata.summary; + identifier = existingMetadata.identifier; + issued = existingMetadata.issued; + modified = existingMetadata.modified; + revisions = existingMetadata.revisions; + version = existingMetadata.version; + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PostMetadata.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PostMetadata.cs new file mode 100644 index 0000000000..8127d09c30 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/PostMetadata.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Used to map create to HDR API + /// + public class PostMetadata + { + + public PostMetadata() { } + public string identifier = ""; + public string version = "1.0.0"; + public List revisions = new List(); + public string modified; + public string issued; + public Summary summary = new Summary(); + public Accessibility accessibility = new Accessibility(); + public List observations = new List(); + public Provenance provenance = new Provenance(); + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Provenance.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Provenance.cs new file mode 100644 index 0000000000..3916bdad1e --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Provenance.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Provenance + { + public Origin origin { get; set; } + public Temporal temporal { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Revision.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Revision.cs new file mode 100644 index 0000000000..e1483c3bbe --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Revision.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Revision + { + public string version { get; set; } + public string url { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/SpatialCoverage.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/SpatialCoverage.cs new file mode 100644 index 0000000000..de28cfb1dc --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/SpatialCoverage.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class SpatialCoverage + { + public int id { get; set; } + public DateTime created_at { get; set; } + public DateTime updated_at { get; set; } + public string region { get; set; } + public bool enabled { get; set; } + public List dataset_version_ids { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/StructuralMetadata.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/StructuralMetadata.cs new file mode 100644 index 0000000000..1d3903d808 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/StructuralMetadata.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class StructuralMetadata + { + public List tables { get; set; } + [JsonIgnore] + public object syntheticDataWebLink { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Summary.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Summary.cs new file mode 100644 index 0000000000..d6999e1142 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Summary.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Summary + { + public string @abstract { get; set; } + public string contactPoint { get; set; } + public List keywords { get; set; } + public object doiName { get; set; } + public string title { get; set; } + public DataCustodian dataCustodian { get; set; } + public int populationSize { get; set; } + public object alternateIdentifiers { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Team.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Team.cs new file mode 100644 index 0000000000..3562a8ea94 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Team.cs @@ -0,0 +1,47 @@ +using Rdmp.Core.Curation.Data.Datasets.HDR.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Team + { + public int id { get; set; } + public string pid { get; set; } + + [JsonConverter(typeof(CustomDateTimeConverter))] + public DateTime created_at { get; set; } + public DateTime updated_at { get; set; } + public object deleted_at { get; set; } + public string name { get; set; } + public bool enabled { get; set; } + public bool allows_messaging { get; set; } + public bool workflow_enabled { get; set; } + public bool access_requests_management { get; set; } + public bool uses_5_safes { get; set; } + public bool is_admin { get; set; } + public string team_logo { get; set; } + public string member_of { get; set; } + public object contact_point { get; set; } + public string application_form_updated_by { get; set; } + public string application_form_updated_on { get; set; } + public string mongo_object_id { get; set; } + public bool notification_status { get; set; } + public bool is_question_bank { get; set; } + public bool is_provider { get; set; } + public object url { get; set; } + public object introduction { get; set; } + public object dar_modal_header { get; set; } + public object dar_modal_content { get; set; } + public object dar_modal_footer { get; set; } + public bool is_dar { get; set; } + public object service { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Temporal.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Temporal.cs new file mode 100644 index 0000000000..2d5a43aaa4 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Temporal.cs @@ -0,0 +1,26 @@ +using Rdmp.Core.Curation.Data.Datasets.HDR.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Temporal + { + [JsonConverter(typeof(CustomDateTimeConverterThreeMilliseconds))] + + public DateTime? endDate { get; set; } + + [JsonConverter(typeof(CustomDateTimeConverterThreeMilliseconds))] + public DateTime startDate { get; set; } + public string timeLag { get; set; } + public string publishingFrequency { get; set; } + public object distributionReleaseDate { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Usage.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Usage.cs new file mode 100644 index 0000000000..d9d140c62f --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Usage.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Usage + { + public List dataUseLimitation { get; set; } + public object resourceCreator { get; set; } + public List dataUseRequirements { get; set; } = []; + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Version.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Version.cs new file mode 100644 index 0000000000..89c555d8ef --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetItems/Version.cs @@ -0,0 +1,26 @@ +using Org.BouncyCastle.Asn1.Cms; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems +{ + /// + /// Mapping from HDR API + /// + public class Version + { + public int id { get; set; } + public DateTime created_at { get; set; } + public DateTime updated_at { get; set; } + public object deleted_at { get; set; } + public int dataset_id { get; set; } + public Metadata metadata { get; set; } + public int version { get; set; } + public object provider_team_id { get; set; } + public object application_type { get; set; } + public List reduced_linked_dataset_versions { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetPatch.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetPatch.cs new file mode 100644 index 0000000000..c2f4569bb5 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetPatch.cs @@ -0,0 +1,103 @@ +using Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems; +using Rdmp.Core.Curation.Data.Datasets.HDR.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR +{ + /// + /// + /// + public class HDRDatasetPatch + { + public int id { get; set; } + public object mongo_object_id { get; set; } + public object mongo_id { get; set; } + public object mongo_pid { get; set; } + public object datasetid { get; set; } + public string pid { get; set; } + public object source { get; set; } + public int discourse_topic_id { get; set; } + public bool is_cohort_discovery { get; set; } + public int commercial_use { get; set; } + public int state_id { get; set; } + public int uploader_id { get; set; } + public int metadataquality_id { get; set; } + public int user_id { get; set; } + public int team_id { get; set; } + public int views_count { get; set; } + public int views_prev_count { get; set; } + public int has_technical_details { get; set; } + public string created { get; set; } + public string updated { get; set; } + public string submitted { get; set; } + public object published { get; set; } + public DateTime created_at { get; set; } + public DateTime updated_at { get; set; } + public object deleted_at { get; set; } + public string create_origin { get; set; } + public string status { get; set; } + public int durs_count { get; set; } + public int publications_count { get; set; } + public int tools_count { get; set; } + public int collections_count { get; set; } + public List spatialCoverage { get; set; } + public List durs { get; set; } + public List publications { get; set; } + public List named_entities { get; set; } + public List collections { get; set; } + public Team team { get; set; } + public PatchMetadata metadata { get; set; } + + + public HDRDatasetPatch() { } + public HDRDatasetPatch(HDRDataset existingDataset) + { + id = existingDataset.data.id; + mongo_object_id = existingDataset.data.mongo_object_id; + mongo_id = existingDataset.data.mongo_id; + mongo_pid = existingDataset.data.mongo_pid; + datasetid = existingDataset.data.datasetid; + pid = existingDataset.data.pid; + source = existingDataset.data.source; + discourse_topic_id = existingDataset.data.discourse_topic_id; + is_cohort_discovery = existingDataset.data.is_cohort_discovery; + commercial_use = existingDataset.data.commercial_use; + state_id = existingDataset.data.state_id; + uploader_id = existingDataset.data.uploader_id; + metadataquality_id = existingDataset.data.metadataquality_id; + user_id = existingDataset.data.user_id; + team_id = existingDataset.data.team_id; + views_count = existingDataset.data.views_count; + views_prev_count = existingDataset.data.views_prev_count; + has_technical_details = existingDataset.data.has_technical_details; + created = existingDataset.data.created; + updated = existingDataset.data.updated; + submitted = existingDataset.data.submitted; + published = existingDataset.data.published; + created_at = existingDataset.data.created_at; + updated_at = existingDataset.data.updated_at; + deleted_at = existingDataset.data.deleted_at; + create_origin = existingDataset.data.create_origin; + status = existingDataset.data.status; + durs_count = existingDataset.data.durs_count; + publications_count = existingDataset.data.publications_count; + tools_count = existingDataset.data.tools_count; + collections_count = existingDataset.data.collections_count; + spatialCoverage = existingDataset.data.spatialCoverage; + durs = existingDataset.data.durs; + publications = existingDataset.data.publications; + named_entities = existingDataset.data.named_entities; + collections = existingDataset.data.collections; + team = existingDataset.data.team; + metadata = new PatchMetadata(existingDataset.data.versions.First().metadata); + if (metadata.metadata.accessibility.usage.dataUseRequirements is null) + metadata.metadata.accessibility.usage.dataUseRequirements = []; + metadata.metadata.coverage.materialType = new List() { "Other" }; + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetPost.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetPost.cs new file mode 100644 index 0000000000..c30fa0cdb5 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetPost.cs @@ -0,0 +1,43 @@ +using Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR +{ + /// + /// + /// + public class HDRDatasetPost + { + + public PostMetadata metadata = new PostMetadata(); + public HDRDatasetPost(Catalogue catalogue) { + metadata.identifier = ""; + metadata.version = "1.0.0"; + metadata.revisions = new List(); + metadata.modified = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); + metadata.issued = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); + metadata.summary.title=catalogue.Name; + metadata.summary.@abstract = catalogue.ShortDescription!= null && catalogue.ShortDescription.Length>4?catalogue.ShortDescription:""; + metadata.summary.dataCustodian = new DataCustodian(); + metadata.summary.dataCustodian.identifier= "unknown"; + metadata.summary.dataCustodian.name = "name"; + metadata.summary.dataCustodian.contactPoint = "test@example.com"; + metadata.summary.populationSize = 0; + metadata.summary.contactPoint = ""; + metadata.provenance.temporal = new Temporal(); + metadata.provenance.origin = new Origin(); + metadata.provenance.temporal.timeLag = "Variable"; + metadata.provenance.temporal.startDate = DateTime.UtcNow; + metadata.provenance.temporal.publishingFrequency = "Irregular"; + metadata.provenance.origin.datasetSubType = new List(); + metadata.provenance.origin.datasetType = new List(); + metadata.accessibility.access = new Access(); + metadata.accessibility.access.accessRights = ""; + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetProvider.cs new file mode 100644 index 0000000000..b3957cc1da --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/HDRDatasetProvider.cs @@ -0,0 +1,288 @@ +using Org.BouncyCastle.Asn1.Cms; +using Rdmp.Core.CommandExecution; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Net; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Rdmp.Core.Curation.Data.Datasets.HDR.Helpers; +using Rdmp.Core.Curation.Data.Datasets.HDR.HDRDatasetItems; +using MongoDB.Bson; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR +{ + /// + /// Provider for connecting to the HDR Gateway + /// + public class HDRDatasetProvider : PluginDatasetProvider + { + private HttpClient _client; + private DatasetProviderConfiguration _configuration; + private readonly string _url; + + private readonly string _inputSchema = "HDRUK"; + private readonly string _inputVersion = "3.0.0"; + public HDRDatasetProvider(IBasicActivateItems activator, DatasetProviderConfiguration configuration, HttpClient client = null) : base(activator, configuration) + { + _client = client ?? new HttpClient(); + var credentials = Repository.GetAllObjectsWhere("ID", Configuration.DataAccessCredentials_ID).First(); + var apiKey = credentials.GetDecryptedPassword(); + _client.DefaultRequestHeaders.Add("x-application-id", credentials.Username); + _client.DefaultRequestHeaders.Add("x-client-id", apiKey); + _configuration = configuration; + _url = Configuration.Url.TrimEnd('/'); + } + public override Dataset AddExistingDatasetWithReturn(string name, string url) + { + HDRDataset hdrDataset = (HDRDataset)FetchDatasetByID(int.Parse(url)); + var datasetName = string.IsNullOrWhiteSpace(name) ? hdrDataset?.data.versions?.First().metadata.metadata.summary.title : name; + var dataset = new Dataset(Repository, datasetName) + { + Url = url, + Type = ToString(), + Provider_ID = Configuration.ID, + DigitalObjectIdentifier = hdrDataset.GetDOI(), + Folder = $"\\HDR\\{Configuration.Name}", + }; + dataset.SaveToDatabase(); + Activator.Publish(dataset); + return dataset; + } + + + public override void AddExistingDataset(string name, string url) + { + AddExistingDatasetWithReturn(name, url); + } + + private class CreateDatasetResponse + { + public int data { get; set; } + } + + public override Dataset Create(Catalogue catalogue) + { + var url = _url + $"/v1/integrations/datasets?input_schema={_inputSchema}&input_version={_inputVersion}"; + var serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true, + DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull + }; + using var stream = new MemoryStream(); + var ds = new HDRDatasetPost(catalogue); + + var jsonString = System.Text.Json.JsonSerializer.Serialize(ds, serializeOptions); + var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + var response = Task.Run(async () => await _client.PostAsync(url, httpContent)).Result; + if (response.StatusCode == HttpStatusCode.Created) + { + var content = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + var responseJson = JsonConvert.DeserializeObject(content); + var dataset = FetchDatasetByID(responseJson.data) as HDRDataset; + dataset.Url = dataset.data.id.ToString(); + UpdateUsingCatalogue(dataset, catalogue); + return dataset; + } + else + { + var content = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + throw new Exception(content); + } + + } + + public HDRDataset FetchHDRDataset(Dataset dataset) + { + var response = Task.Run(async () => await _client.GetAsync($"{dataset.Url}?schema_model={_inputSchema}&schema_version={_inputVersion}")).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + Console.WriteLine(detailsString); + HDRDataset hdrDataset = JsonConvert.DeserializeObject(detailsString); + return hdrDataset; + } + throw new Exception("Unable to fetch HDR dataset"); + } + + public override Dataset FetchDatasetByID(int id) + { + var url = _url + "/v1/datasets/" + id; + var response = Task.Run(async () => await _client.GetAsync($"{url}?schema_model={_inputSchema}&schema_version={_inputVersion}")).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + Console.WriteLine(detailsString); + HDRDataset hdrDataset = JsonConvert.DeserializeObject(detailsString); + return hdrDataset; + } + throw new Exception("Unable to fetch HDR dataset"); + } + + public override void Update(string uuid, PluginDataset datasetUpdates) + { + var serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true + }; + serializeOptions.Converters.Add(new CustomDateTimeConverter()); + serializeOptions.Converters.Add(new CustomDateTimeConverterThreeMilliseconds()); + + var options = new JsonWriterOptions + { + Indented = true + }; + + using var stream = new MemoryStream(); + var update = (HDRDataset)datasetUpdates; + var updateObj = new HDRUpdateObject() + { + metadata = new HDRDatasetPatch((HDRDataset)datasetUpdates).metadata.metadata + }; + System.Text.Json.JsonSerializer.Serialize(stream, updateObj.metadata, serializeOptions); + + var jsonString = "{\"metadata\":" + Encoding.UTF8.GetString(stream.ToArray()) + "}"; + var uri = $"{_url}/v1/integrations/datasets/{uuid}?input_schema={_inputSchema}&input_version={_inputVersion}"; + var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + var response = Task.Run(async () => await _client.PutAsync(uri, httpContent)).Result; + if (response.StatusCode != HttpStatusCode.OK) + { + var errorMessage = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + throw new Exception(errorMessage); + } + } + + private string MapDataTypeToHDRDataType(string dt) + { + switch (dt) + { + case "HealthcareAndDisease": + return "Healthcare and disease"; + case "TreatmentsAndInterventions": + return "Treatments/Interventions"; + case "MeasurementsAndTests": + return "Measurements/Tests"; + case "ImagingTypes": + return "Imaging types"; + case "ImagingAreaOfTheBody": + return "Imaging area of the body"; + case "Omics": + return "Omics"; + case "Socioeconomic": + return "Socioeconomic"; + case "Lifestyle": + return "Lifestyle"; + case "Registry": + return "Registry"; + case "EnvironmentalAndEnergy": + return "Environmental and energy"; + case "InformationAndCommunication": + return "Information and communication"; + case "Politics": + return "Politics"; + default: + return dt; + } + } + + private string AddSpacesToSentence(string text, bool preserveAcronyms) + { + if (string.IsNullOrWhiteSpace(text)) + return string.Empty; + StringBuilder newText = new StringBuilder(text.Length * 2); + newText.Append(text[0]); + for (int i = 1; i < text.Length; i++) + { + if (char.IsUpper(text[i]) && (text[i - 1] != ' ' && !char.IsUpper(text[i - 1]) || + preserveAcronyms && char.IsUpper(text[i - 1]) && + i < text.Length - 1 && !char.IsUpper(text[i + 1]))) + newText.Append(' '); + newText.Append(text[i]); + } + return newText.ToString(); + } + + private string MapDataSubTypeToHDR(string dst) + { + if (dst == "ResearchDiseaseRegistry") return "Disease registry (research)"; + return AddSpacesToSentence(dst, true); + } + + private string MapTimeLagToHDR(string tl) + { + switch (tl) + { + case "LessThanAWeek": + return "Less than 1 week"; + case "OneToTwoWeeks": + return "1-2 weeks"; + case "TwoToFourWeeks": + return "2-4 weeks"; + case "OneToTwoMonths": + return "1-2 months"; + case "TwoToSixMonths": + return "2-6 months"; + case "SixMonthsPlus": + return "More than 6 months"; + case "NotApplicable": + return "Not applicable"; + default: + return tl; + } + } + + public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) + { + var hdrDataset = (HDRDataset)FetchDatasetByID(int.Parse(dataset.Url)); + hdrDataset.data.versions.First().metadata.metadata.summary.title = catalogue.Name; + hdrDataset.data.versions.First().metadata.metadata.summary.@abstract = catalogue.ShortDescription != null && catalogue.ShortDescription.Length < 5 ? catalogue.ShortDescription.PadRight(5) : catalogue.ShortDescription; + hdrDataset.data.versions.First().metadata.metadata.summary.contactPoint = catalogue.Administrative_contact_email; + hdrDataset.data.versions.First().metadata.metadata.summary.keywords = (catalogue.Search_keywords ?? "").Split(',').Cast().Where(k => k != "").Cast().ToList(); + hdrDataset.data.versions.First().metadata.metadata.summary.doiName = catalogue.Doi; + + hdrDataset.data.versions.First().metadata.metadata.documentation.description = catalogue.Description; + hdrDataset.data.versions.First().metadata.metadata.documentation.associatedMedia = catalogue.AssociatedMedia; + + hdrDataset.data.versions.First().metadata.metadata.coverage.spatial = catalogue.Geographical_coverage; + + if (catalogue.DataType != null) + hdrDataset.data.versions.First().metadata.metadata.provenance.origin.datasetType = catalogue.DataType.Split(",").Select(MapDataTypeToHDRDataType).ToList(); + if (catalogue.DataSubType != null) + hdrDataset.data.versions.First().metadata.metadata.provenance.origin.datasetSubType = catalogue.DataSubType.Split(",").Select(MapDataSubTypeToHDR).ToList(); + hdrDataset.data.versions.First().metadata.metadata.provenance.temporal.endDate = catalogue.EndDate != null ? catalogue.EndDate.Value : null; + if (catalogue.StartDate != null) + hdrDataset.data.versions.First().metadata.metadata.provenance.temporal.startDate = catalogue.StartDate.Value; + hdrDataset.data.versions.First().metadata.metadata.provenance.temporal.timeLag = MapTimeLagToHDR(catalogue.UpdateLag.ToString()); + hdrDataset.data.versions.First().metadata.metadata.provenance.temporal.publishingFrequency = catalogue.Update_freq.ToString(); + + hdrDataset.data.versions.First().metadata.metadata.accessibility.access.jurisdiction = (catalogue.Juristiction ?? "").Split(",").Where(k => k != "").ToList(); + hdrDataset.data.versions.First().metadata.metadata.accessibility.access.dataController = catalogue.DataController; + hdrDataset.data.versions.First().metadata.metadata.accessibility.access.dataProcessor = catalogue.DataProcessor; + + hdrDataset.data.versions.First().metadata.metadata.identifier = Guid.NewGuid().ToString(); + + + Update(hdrDataset.data.id.ToString(), hdrDataset); + } + + public override string GetRemoteURL(Dataset dataset) + { + return $"{_url.Replace("api.", "web.").Replace("/api", "/en")}/dataset/{dataset.Url}"; + } + + private class HDRUpdateObject + { + public int team_id { get; set; } + public int user_id { get; set; } + public string create_origin { get; set; } + public PatchSubMetadata metadata { get; set; } + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/Helpers/CustomDateTimeConverter.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/Helpers/CustomDateTimeConverter.cs new file mode 100644 index 0000000000..5b2b294635 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/Helpers/CustomDateTimeConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.Helpers +{ + /// + /// + /// + public class CustomDateTimeConverter : JsonConverter + { + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return DateTime.Parse(reader.GetString()); + } + + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ss.000000Z", CultureInfo.InvariantCulture)); + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/HDR/Helpers/CustomDateTimeConverterThreeMilliseconds.cs b/Rdmp.Core/Curation/Data/Datasets/HDR/Helpers/CustomDateTimeConverterThreeMilliseconds.cs new file mode 100644 index 0000000000..519625f5cb --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/HDR/Helpers/CustomDateTimeConverterThreeMilliseconds.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.HDR.Helpers +{ + /// + /// + /// + public class CustomDateTimeConverterThreeMilliseconds : JsonConverter + { + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return DateTime.Parse(reader.GetString()); + } + + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ss.000Z", CultureInfo.InvariantCulture)); + } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/PluginDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/PluginDatasetProvider.cs index 32eb9970bf..d893742af3 100644 --- a/Rdmp.Core/Curation/Data/Datasets/PluginDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/PluginDatasetProvider.cs @@ -26,7 +26,6 @@ protected PluginDatasetProvider(IBasicActivateItems activator, DatasetProviderCo public abstract Dataset AddExistingDatasetWithReturn(string name, string url); - public abstract void Update(string uuid, PluginDataset datasetUpdates); public abstract void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue); diff --git a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs index 0f6940d973..56a195415e 100644 --- a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs +++ b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs @@ -65,7 +65,7 @@ private IAtomicCommand[] GetWhitespaceRightClickMenu() new ExecuteCommandAddNewRegexRedactionConfigurationUI(_activator) { OverrideCommandName="Add New Regex Redaction Configuration" - } + }, }; foreach (var provider in datasetProviders) { diff --git a/Rdmp.UI/MainFormUITabs/CatalogueUI.Designer.cs b/Rdmp.UI/MainFormUITabs/CatalogueUI.Designer.cs index ff2a867742..6a807d653c 100644 --- a/Rdmp.UI/MainFormUITabs/CatalogueUI.Designer.cs +++ b/Rdmp.UI/MainFormUITabs/CatalogueUI.Designer.cs @@ -36,98 +36,99 @@ private void InitializeComponent() cbColdStorage = new CheckBox(); cbInternal = new CheckBox(); cbDeprecated = new CheckBox(); - editableFolder = new SimpleControls.EditableLabelUI(); - editableCatalogueName = new SimpleControls.EditableLabelUI(); + editableFolder = new Rdmp.UI.SimpleControls.EditableLabelUI(); + editableCatalogueName = new Rdmp.UI.SimpleControls.EditableLabelUI(); ticketingControl1 = new TicketingControlUI(); tabControl1 = new TabControl(); tabPage1 = new TabPage(); groupBox23 = new GroupBox(); - aiAcronym = new SimpleControls.AdditionalInfomationUI(); + aiAcronym = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbAcronym = new TextBox(); groupBox16 = new GroupBox(); - aiDescription = new SimpleControls.AdditionalInfomationUI(); + aiDescription = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbDescription = new TextBox(); groupBox15 = new GroupBox(); - aiShortDescription = new SimpleControls.AdditionalInfomationUI(); + aiShortDescription = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbAbstract = new TextBox(); tabPage2 = new TabPage(); tableLayoutPanel2 = new TableLayoutPanel(); groupBox18 = new GroupBox(); - aiDatasetType = new SimpleControls.AdditionalInfomationUI(); - ddDatasetType = new SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); + aiDatasetType = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + ddDatasetType = new Rdmp.UI.SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); groupBox22 = new GroupBox(); - aiKeywords = new SimpleControls.AdditionalInfomationUI(); - ffcKeywords = new SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); + aiKeywords = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + ffcKeywords = new Rdmp.UI.SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); groupBox19 = new GroupBox(); - aiDatasetSubtype = new SimpleControls.AdditionalInfomationUI(); - ddDatasetSubtype = new SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); + aiDatasetSubtype = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + ddDatasetSubtype = new Rdmp.UI.SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); groupBox21 = new GroupBox(); - ddDataSourceSetting = new SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); - aiDataSourceSetting = new SimpleControls.AdditionalInfomationUI(); + ddDataSourceSetting = new Rdmp.UI.SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); + aiDataSourceSetting = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); groupBox20 = new GroupBox(); - ddDataSource = new SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); - aiDataSource = new SimpleControls.AdditionalInfomationUI(); - groupBox24 = new GroupBox(); - aiPurposeOfDataset = new SimpleControls.AdditionalInfomationUI(); - cbPurpose = new ComboBox(); + ddDataSource = new Rdmp.UI.SimpleControls.MultiSelectChips.DropdownOptionsChipDisplay(); + aiDataSource = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); groupBox17 = new GroupBox(); - aiResourceType = new SimpleControls.AdditionalInfomationUI(); + aiResourceType = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); cb_resourceType = new ComboBox(); + groupBox24 = new GroupBox(); + aiPurposeOfDataset = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + cbPurpose = new ComboBox(); tabPage3 = new TabPage(); groupBox14 = new GroupBox(); - aiEndDate = new SimpleControls.AdditionalInfomationUI(); + aiEndDate = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); dtpEndDate = new DateTimePicker(); btnEndDateClear = new Button(); groupBox13 = new GroupBox(); - aiStartDate = new SimpleControls.AdditionalInfomationUI(); + aiStartDate = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); dtpStart = new DateTimePicker(); btnStartDateClear = new Button(); groupBox12 = new GroupBox(); - aiGranularity = new SimpleControls.AdditionalInfomationUI(); + aiGranularity = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); cb_granularity = new ComboBox(); groupBox11 = new GroupBox(); - aiGeographicalCoverage = new SimpleControls.AdditionalInfomationUI(); + aiGeographicalCoverage = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbGeoCoverage = new TextBox(); tabPage4 = new TabPage(); groupBox10 = new GroupBox(); - aiJuristiction = new SimpleControls.AdditionalInfomationUI(); + aiJuristiction = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbJuristiction = new TextBox(); groupBox9 = new GroupBox(); - aiDataProcessor = new SimpleControls.AdditionalInfomationUI(); + aiDataProcessor = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbDataProcessor = new TextBox(); groupBox8 = new GroupBox(); - aiDataController = new SimpleControls.AdditionalInfomationUI(); + aiDataController = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbDataController = new TextBox(); groupBox7 = new GroupBox(); - aiAccessContact = new SimpleControls.AdditionalInfomationUI(); + aiAccessContact = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbAccessContact = new TextBox(); tabPage5 = new TabPage(); groupBox3 = new GroupBox(); - aiDOI = new SimpleControls.AdditionalInfomationUI(); + aiDOI = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); tbDOI = new TextBox(); tableLayoutPanel1 = new TableLayoutPanel(); groupBox2 = new GroupBox(); - aiControlledGroup = new SimpleControls.AdditionalInfomationUI(); - fftControlledVocab = new SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); + aiControlledGroup = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + fftControlledVocab = new Rdmp.UI.SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); groupBox1 = new GroupBox(); - aiPeople = new SimpleControls.AdditionalInfomationUI(); - ffcPeople = new SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); + aiPeople = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + ffcPeople = new Rdmp.UI.SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); tabPage6 = new TabPage(); - aiUpdateFrequency = new SimpleControls.AdditionalInfomationUI(); + aiUpdateFrequency = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); groupBox6 = new GroupBox(); - aiUpdateLag = new SimpleControls.AdditionalInfomationUI(); + aiUpdateLag = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); cbUpdateLag = new ComboBox(); groupBox5 = new GroupBox(); - aiInitialReleaseDate = new SimpleControls.AdditionalInfomationUI(); + aiInitialReleaseDate = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); dtpReleaseDate = new DateTimePicker(); btnReleaseDateClear = new Button(); groupBox4 = new GroupBox(); cb_updateFrequency = new ComboBox(); tabPage7 = new TabPage(); groupBox25 = new GroupBox(); - aiAssociatedMedia = new SimpleControls.AdditionalInfomationUI(); - ffAssociatedMedia = new SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); + aiAssociatedMedia = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + ffAssociatedMedia = new Rdmp.UI.SimpleControls.MultiSelectChips.FreeFormTextChipDisplay(); tabPage8 = new TabPage(); + button1 = new Button(); tableLayoutPanel3 = new TableLayoutPanel(); label6 = new Label(); label4 = new Label(); @@ -136,7 +137,6 @@ private void InitializeComponent() label2 = new Label(); label5 = new Label(); button2 = new Button(); - button1 = new Button(); ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit(); splitContainer1.Panel1.SuspendLayout(); splitContainer1.Panel2.SuspendLayout(); @@ -153,8 +153,8 @@ private void InitializeComponent() groupBox19.SuspendLayout(); groupBox21.SuspendLayout(); groupBox20.SuspendLayout(); - groupBox24.SuspendLayout(); groupBox17.SuspendLayout(); + groupBox24.SuspendLayout(); tabPage3.SuspendLayout(); groupBox14.SuspendLayout(); groupBox13.SuspendLayout(); @@ -268,7 +268,6 @@ private void InitializeComponent() tabControl1.Controls.Add(tabPage6); tabControl1.Controls.Add(tabPage7); tabControl1.Controls.Add(tabPage8); - tabControl1.Dock = DockStyle.Fill; tabControl1.Location = new System.Drawing.Point(0, 0); tabControl1.Name = "tabControl1"; @@ -555,33 +554,6 @@ private void InitializeComponent() aiDataSource.Size = new System.Drawing.Size(20, 20); aiDataSource.TabIndex = 24; // - // groupBox24 - // - groupBox24.AutoSize = true; - groupBox24.Controls.Add(aiPurposeOfDataset); - groupBox24.Controls.Add(cbPurpose); - groupBox24.Location = new System.Drawing.Point(207, 6); - groupBox24.Name = "groupBox24"; - groupBox24.Size = new System.Drawing.Size(194, 67); - groupBox24.TabIndex = 20; - groupBox24.TabStop = false; - groupBox24.Text = "Purpose of Dataset"; - // - // aiPurposeOfDataset - // - aiPurposeOfDataset.Location = new System.Drawing.Point(114, 0); - aiPurposeOfDataset.Name = "aiPurposeOfDataset"; - aiPurposeOfDataset.Size = new System.Drawing.Size(20, 20); - aiPurposeOfDataset.TabIndex = 27; - // - // cbPurpose - // - cbPurpose.FormattingEnabled = true; - cbPurpose.Location = new System.Drawing.Point(6, 22); - cbPurpose.Name = "cbPurpose"; - cbPurpose.Size = new System.Drawing.Size(182, 23); - cbPurpose.TabIndex = 1; - // // groupBox17 // groupBox17.AutoSize = true; @@ -609,6 +581,33 @@ private void InitializeComponent() cb_resourceType.Size = new System.Drawing.Size(182, 23); cb_resourceType.TabIndex = 0; // + // groupBox24 + // + groupBox24.AutoSize = true; + groupBox24.Controls.Add(aiPurposeOfDataset); + groupBox24.Controls.Add(cbPurpose); + groupBox24.Location = new System.Drawing.Point(207, 6); + groupBox24.Name = "groupBox24"; + groupBox24.Size = new System.Drawing.Size(194, 67); + groupBox24.TabIndex = 20; + groupBox24.TabStop = false; + groupBox24.Text = "Purpose of Dataset"; + // + // aiPurposeOfDataset + // + aiPurposeOfDataset.Location = new System.Drawing.Point(114, 0); + aiPurposeOfDataset.Name = "aiPurposeOfDataset"; + aiPurposeOfDataset.Size = new System.Drawing.Size(20, 20); + aiPurposeOfDataset.TabIndex = 27; + // + // cbPurpose + // + cbPurpose.FormattingEnabled = true; + cbPurpose.Location = new System.Drawing.Point(6, 22); + cbPurpose.Name = "cbPurpose"; + cbPurpose.Size = new System.Drawing.Size(182, 23); + cbPurpose.TabIndex = 1; + // // tabPage3 // tabPage3.AutoScroll = true; @@ -1126,6 +1125,16 @@ private void InitializeComponent() tabPage8.TabIndex = 7; tabPage8.Text = "Datasets"; // + // button1 + // + button1.Location = new System.Drawing.Point(163, 12); + button1.Name = "button1"; + button1.Size = new System.Drawing.Size(183, 23); + button1.TabIndex = 3; + button1.Text = "Create using External Provider"; + button1.UseVisualStyleBackColor = true; + button1.Click += button1_Click; + // // tableLayoutPanel3 // tableLayoutPanel3.AutoSize = true; @@ -1137,12 +1146,12 @@ private void InitializeComponent() tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle()); tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle()); tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle()); - tableLayoutPanel3.Controls.Add(label6, 5, 0); - tableLayoutPanel3.Controls.Add(label4, 3, 0); - tableLayoutPanel3.Controls.Add(label3, 2, 0); tableLayoutPanel3.Controls.Add(label1, 0, 0); tableLayoutPanel3.Controls.Add(label2, 1, 0); + tableLayoutPanel3.Controls.Add(label3, 2, 0); + tableLayoutPanel3.Controls.Add(label4, 3, 0); tableLayoutPanel3.Controls.Add(label5, 4, 0); + tableLayoutPanel3.Controls.Add(label6, 5, 0); tableLayoutPanel3.Location = new System.Drawing.Point(7, 41); tableLayoutPanel3.Name = "tableLayoutPanel3"; tableLayoutPanel3.RowCount = 2; @@ -1217,15 +1226,6 @@ private void InitializeComponent() button2.UseVisualStyleBackColor = true; button2.Click += button2_Click; // - // button1 - // - button1.Location = new System.Drawing.Point(163, 12); - button1.Name = "button1"; - button1.Size = new System.Drawing.Size(183, 23); - button1.TabIndex = 3; - button1.Text = "Create using External Provider"; - button1.UseVisualStyleBackColor = true; - button1.Click += button1_Click; // CatalogueUI // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -1261,8 +1261,8 @@ private void InitializeComponent() groupBox21.PerformLayout(); groupBox20.ResumeLayout(false); groupBox20.PerformLayout(); - groupBox24.ResumeLayout(false); groupBox17.ResumeLayout(false); + groupBox24.ResumeLayout(false); tabPage3.ResumeLayout(false); groupBox14.ResumeLayout(false); groupBox13.ResumeLayout(false); diff --git a/Rdmp.UI/MainFormUITabs/CatalogueUI.cs b/Rdmp.UI/MainFormUITabs/CatalogueUI.cs index 2921c0bbf9..d6093b9463 100644 --- a/Rdmp.UI/MainFormUITabs/CatalogueUI.cs +++ b/Rdmp.UI/MainFormUITabs/CatalogueUI.cs @@ -460,9 +460,9 @@ private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) case 7: tableLayoutPanel3.SuspendLayout(); var datasets = _catalogue.GetLinkedDatasets(); - while (tableLayoutPanel3.Controls.Count > 0) + while (tableLayoutPanel3.Controls.Count > 6) { - tableLayoutPanel3.Controls[0].Dispose(); + tableLayoutPanel3.Controls[7].Dispose(); } foreach (var dataset in datasets) { @@ -471,7 +471,7 @@ private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) var label = new Label(); label.Text = dataset.Name; label.AutoSize = true; - tableLayoutPanel3.Controls.Add(label, 0, tableLayoutPanel3.RowCount - 1); + tableLayoutPanel3.Controls.Add(label); var cb = new CheckBox(); cb.Checked = linkage.Autoupdate; cb.CheckedChanged += (object sender, EventArgs e) => @@ -480,11 +480,18 @@ private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) linkage.SaveToDatabase(); Publish(linkage); }; - tableLayoutPanel3.Controls.Add(cb, 1, tableLayoutPanel3.RowCount - 1); + tableLayoutPanel3.Controls.Add(cb); var btn = new Button(); btn.Text = "Update Now"; btn.Click += (object sender, EventArgs e) => UpdateDataset(dataset); - tableLayoutPanel3.Controls.Add(btn, 2, tableLayoutPanel3.RowCount - 1); + tableLayoutPanel3.Controls.Add(btn); + + var viewBtn = new Button(); + viewBtn.Text = "View"; + viewBtn.Enabled = false; + tableLayoutPanel3.Controls.Add(viewBtn); + + var btn3 = new Button(); btn3.Text = "Remove Link to Dataset"; btn3.Click += (object sender, EventArgs e) => @@ -496,11 +503,11 @@ private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) tabControl1_SelectedIndexChanged(tabControl1, null); } }; - tableLayoutPanel3.Controls.Add(btn3, 4, tableLayoutPanel3.RowCount - 1); + tableLayoutPanel3.Controls.Add(btn3); var labelType = new Label(); labelType.Text = _catalogue.CatalogueRepository.GetObjectByID((int)dataset.Provider_ID).Name; labelType.AutoSize = true; - tableLayoutPanel3.Controls.Add(labelType, 5, tableLayoutPanel3.RowCount - 1); + tableLayoutPanel3.Controls.Add(labelType); } tableLayoutPanel3.ResumeLayout(); diff --git a/Tests.Common/UnitTests.cs b/Tests.Common/UnitTests.cs index 6e3b082d47..ce9c1a8aa3 100644 --- a/Tests.Common/UnitTests.cs +++ b/Tests.Common/UnitTests.cs @@ -29,6 +29,7 @@ using Rdmp.Core.Curation.Data.Dashboarding; using Rdmp.Core.Curation.Data.DataLoad; using Rdmp.Core.Curation.Data.Datasets; +using Rdmp.Core.Curation.Data.Datasets.HDR; using Rdmp.Core.Curation.Data.Governance; using Rdmp.Core.Curation.Data.ImportExport; using Rdmp.Core.Curation.Data.Pipelines; @@ -622,6 +623,10 @@ public static T WhenIHaveA(MemoryDataExportRepository repository) where T : D { return (T)(object)new DatasetProviderConfiguration(repository.CatalogueRepository, "","","",WhenIHaveA(repository).ID,""); } + if (typeof(T) == typeof(HDRDataset)) + { + return (T)(object)new HDRDataset(repository.CatalogueRepository, "HDR Dataset"); + } if(typeof(T) == typeof(ExtractableDataSetProject)) { return (T)(object)new ExtractableDataSetProject(repository, WhenIHaveA(repository), WhenIHaveA(repository));