From c4309ed3fa160492274ac6540c8d8762d14fb252 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 09:19:22 +0100 Subject: [PATCH 01/20] start of jira work --- Rdmp.Core/Curation/Data/Catalogue.cs | 7 + .../Data/Datasets/Jira/API/AQLResult.cs | 21 + .../Curation/Data/Datasets/Jira/API/Avatar.cs | 20 + .../Curation/Data/Datasets/Jira/API/Entry.cs | 25 ++ .../Datasets/Jira/API/MediaClientConfig.cs | 18 + .../Datasets/Jira/API/UpdateAttributes.cs | 14 + .../Curation/Data/Datasets/Jira/API/Value.cs | 28 ++ .../Data/Datasets/Jira/JiraDataset.cs | 33 ++ .../Jira/JiraDatasetObjects/Attribute.cs | 22 + .../Jira/JiraDatasetObjects/DefaultType.cs | 17 + .../Jira/JiraDatasetObjects/ExtendedInfo.cs | 17 + .../Datasets/Jira/JiraDatasetObjects/Icon.cs | 19 + .../Datasets/Jira/JiraDatasetObjects/Links.cs | 16 + .../ObjectAttributeValue.cs | 20 + .../Jira/JiraDatasetObjects/ObjectType.cs | 30 ++ .../JiraDatasetObjects/ObjectTypeAttribute.cs | 40 ++ .../JiraDatasetObjects/ReferenceObjectType.cs | 30 ++ .../Jira/JiraDatasetObjects/ReferenceType.cs | 23 + .../JiraDatasetObjects/ReferencedObject.cs | 27 ++ .../Data/Datasets/Jira/JiraDatasetProvider.cs | 423 ++++++++++++++++++ .../Collections/ConfigurationsCollectionUI.cs | 6 +- ...cuteCommandCreateNewJiraConfigurationUI.cs | 29 ++ .../CreateNewJiraConfigurationUI.Designer.cs | 246 ++++++++++ .../Jira/CreateNewJiraConfigurationUI.cs | 70 +++ 24 files changed, 1200 insertions(+), 1 deletion(-) create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Attribute.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/DefaultType.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ExtendedInfo.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Icon.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Links.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectAttributeValue.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectType.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceObjectType.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceType.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferencedObject.cs create mode 100644 Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs create mode 100644 Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs create mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs create mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs diff --git a/Rdmp.Core/Curation/Data/Catalogue.cs b/Rdmp.Core/Curation/Data/Catalogue.cs index 804c87f6f2..55d80be778 100644 --- a/Rdmp.Core/Curation/Data/Catalogue.cs +++ b/Rdmp.Core/Curation/Data/Catalogue.cs @@ -16,6 +16,7 @@ using Rdmp.Core.CohortCreation.Execution; using Rdmp.Core.Curation.Data.Aggregation; using Rdmp.Core.Curation.Data.DataLoad; +using Rdmp.Core.Curation.Data.Datasets; using Rdmp.Core.Curation.Data.Defaults; using Rdmp.Core.Curation.Data.ImportExport; using Rdmp.Core.Curation.Data.Serialization; @@ -1147,6 +1148,12 @@ internal Catalogue(ShareManager shareManager, ShareDefinition shareDefinition) /// public override string ToString() => Name; + + public List GetLinkedDatasets() + { + return CatalogueRepository.GetAllObjectsWhere("Catalogue_ID", this.ID).Select(l => l.Dataset).Distinct().ToList(); + } + /// /// Sorts alphabetically based on /// diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs new file mode 100644 index 0000000000..b33a651b58 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs @@ -0,0 +1,21 @@ +using Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.API +{ + public class AQLResult + { + public int startAt { get; set; } + public int maxResults { get; set; } + public int total { get; set; } + public List values { get; set; } + public List objectTypeAttributes { get; set; } + public bool hasMoreResults { get; set; } + public bool last { get; set; } + public bool isLast { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs new file mode 100644 index 0000000000..47a9db3baf --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.API +{ + public class Avatar + { + public string workspaceId { get; set; } + public string url16 { get; set; } + public string url48 { get; set; } + public string url72 { get; set; } + public string url144 { get; set; } + public string url288 { get; set; } + public string objectId { get; set; } + public MediaClientConfig mediaClientConfig { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs new file mode 100644 index 0000000000..bf66a6c388 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.API +{ + public class Entry + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string name { get; set; } + public int position { get; set; } + public DateTime created { get; set; } + public DateTime updated { get; set; } + public int objectCount { get; set; } + public string objectSchemaId { get; set; } + public bool inherited { get; set; } + public bool abstractObjectType { get; set; } + public bool parentObjectTypeInherited { get; set; } + public string description { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs new file mode 100644 index 0000000000..372bb8f370 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.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.Jira.API +{ + public class MediaClientConfig + { + public string clientId { get; set; } + public string issuer { get; set; } + public string mediaBaseUrl { get; set; } + public string mediaJwtToken { get; set; } + public string fileId { get; set; } + public int tokenLifespanInMinutes { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs new file mode 100644 index 0000000000..1c76bf5f13 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.API +{ + public class UpdateAttributes + { + public List attributes { get; set; } + + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs new file mode 100644 index 0000000000..53ac743c72 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs @@ -0,0 +1,28 @@ +using Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.API +{ + public class Value + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string label { get; set; } + public string objectKey { get; set; } + public Avatar avatar { get; set; } + public ObjectType objectType { get; set; } + public DateTime created { get; set; } + public DateTime updated { get; set; } + public bool hasAvatar { get; set; } + public long timestamp { get; set; } + public List attributes { get; set; } + public Links _links { get; set; } + public string name { get; set; } + } + +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs new file mode 100644 index 0000000000..b1eadc465c --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -0,0 +1,33 @@ +using Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects; +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.Jira +{ + class JiraDataset: PluginDataset + { + public JiraDataset() + { + } + public JiraDataset(ICatalogueRepository catalogueRepository, string name) : base(catalogueRepository, name) + { + } + + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string label { get; set; } + public string objectKey { get; set; } + public ObjectType objectType { get; set; } + public DateTime created { get; set; } + public DateTime updated { get; set; } + public List attributes { get; set; } + public ExtendedInfo extendedInfo { get; set; } + public Links _links { get; set; } + public string name { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Attribute.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Attribute.cs new file mode 100644 index 0000000000..0581cfb398 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Attribute.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.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class Attribute + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public ObjectTypeAttribute objectTypeAttribute { get; set; } + public string objectTypeAttributeId { get; set; } + public List objectAttributeValues { get; set; } + public string objectId { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/DefaultType.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/DefaultType.cs new file mode 100644 index 0000000000..f2ca93c449 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/DefaultType.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.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class DefaultType + { + public int id { get; set; } + public string name { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ExtendedInfo.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ExtendedInfo.cs new file mode 100644 index 0000000000..d3787f5c71 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ExtendedInfo.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.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class ExtendedInfo + { + public bool openIssuesExists { get; set; } + public bool attachmentsExists { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Icon.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Icon.cs new file mode 100644 index 0000000000..9b1b02d698 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Icon.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.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class Icon + { + public string id { get; set; } + public string name { get; set; } + public string url16 { get; set; } + public string url48 { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Links.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Links.cs new file mode 100644 index 0000000000..902a72b210 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/Links.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class Links + { + public string self { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectAttributeValue.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectAttributeValue.cs new file mode 100644 index 0000000000..6495cf2fc7 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectAttributeValue.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class ObjectAttributeValue + { + public object value { get; set; } + public object searchValue { get; set; } + public bool referencedType { get; set; } + public string displayValue { get; set; } + public ReferencedObject referencedObject { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectType.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectType.cs new file mode 100644 index 0000000000..452220fec7 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectType.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class ObjectType + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string name { get; set; } + public int type { get; set; } + public string description { get; set; } + public Icon icon { get; set; } + public int position { get; set; } + public DateTime created { get; set; } + public DateTime updated { get; set; } + public int objectCount { get; set; } + public string objectSchemaId { get; set; } + public bool inherited { get; set; } + public bool abstractObjectType { get; set; } + public bool parentObjectTypeInherited { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs new file mode 100644 index 0000000000..50c680a6c3 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects +{ + public class ObjectTypeAttribute + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string name { get; set; } + public bool label { get; set; } + public int type { get; set; } + public DefaultType defaultType { get; set; } + public bool editable { get; set; } + public bool system { get; set; } + public bool sortable { get; set; } + public bool summable { get; set; } + public bool indexed { get; set; } + public int minimumCardinality { get; set; } + public int maximumCardinality { get; set; } + public bool removable { get; set; } + public bool hidden { get; set; } + public bool includeChildObjectTypes { get; set; } + public bool uniqueAttribute { get; set; } + public string options { get; set; } + public int position { get; set; } + public string description { get; set; } + public ReferenceType referenceType { get; set; } + public string referenceObjectTypeId { get; set; } + public ReferenceObjectType referenceObjectType { get; set; } + public string suffix { get; set; } + public string regexValidation { get; set; } + public string qlQuery { get; set; } + public string iql { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceObjectType.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceObjectType.cs new file mode 100644 index 0000000000..09073e48a7 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceObjectType.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class ReferenceObjectType + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string name { get; set; } + public int type { get; set; } + public string description { get; set; } + public Icon icon { get; set; } + public int position { get; set; } + public DateTime created { get; set; } + public DateTime updated { get; set; } + public int objectCount { get; set; } + public string objectSchemaId { get; set; } + public bool inherited { get; set; } + public bool abstractObjectType { get; set; } + public bool parentObjectTypeInherited { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceType.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceType.cs new file mode 100644 index 0000000000..9a42836615 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferenceType.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.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class ReferenceType + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string name { get; set; } + public string description { get; set; } + public string color { get; set; } + public string url16 { get; set; } + public bool removable { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferencedObject.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferencedObject.cs new file mode 100644 index 0000000000..d147d94cbc --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ReferencedObject.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects +{ + /// + /// + /// + public class ReferencedObject + { + public string workspaceId { get; set; } + public string globalId { get; set; } + public string id { get; set; } + public string label { get; set; } + public string objectKey { get; set; } + public ObjectType objectType { get; set; } + public DateTime created { get; set; } + public DateTime updated { get; set; } + public bool hasAvatar { get; set; } + public object timestamp { get; set; } + public Links _links { get; set; } + public string name { get; set; } + } +} diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs new file mode 100644 index 0000000000..673217ba90 --- /dev/null +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -0,0 +1,423 @@ +using Newtonsoft.Json; +using Rdmp.Core.CommandExecution; +using Rdmp.Core.Curation.Data.Datasets.Jira.API; +using Rdmp.Core.DataExport.Data; +using Rdmp.Core.MapsDirectlyToDatabaseTable; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Rdmp.Core.Curation.Data.Datasets.Jira +{ + public class JiraDatasetProvider : PluginDatasetProvider + { + private readonly string _workspace; + private readonly HttpClient _client; + private readonly string API_URL = "https://api.atlassian.com/jsm/assets/workspace/"; + private readonly String DATASET = "Dataset"; + private readonly String PROJECT = "Project"; + private readonly String NAME = "Name"; + + + public JiraDatasetProvider(IBasicActivateItems activator, DatasetProviderConfiguration configuration, HttpClient httpClient = null) : base(activator, configuration) + { + _client = httpClient ?? new HttpClient(); + var credentials = Repository.GetAllObjectsWhere("ID", Configuration.DataAccessCredentials_ID).First(); + var apiKey = credentials.GetDecryptedPassword(); + var code = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{credentials.Username}:{apiKey}")); + _client.DefaultRequestHeaders.Add("Authorization", $"Basic {code}"); + + _client.DefaultRequestHeaders + .Accept + .Add(new MediaTypeWithQualityHeaderValue("application/json")); + _workspace = configuration.Organisation_ID; + } + + public override void AddExistingDataset(string name, string url) + { + AddExistingDatasetWithReturn(name, url); + } + + public override Dataset AddExistingDatasetWithReturn(string name, string url) + { + JiraDataset jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(url)); + var dataset = new Curation.Data.Datasets.Dataset(Repository, jiraDataset.name) + { + Url = jiraDataset._links.self, + Type = this.ToString(), + Provider_ID = Configuration.ID, + Folder = $"\\Jira\\{Configuration.Name}", + }; + dataset.SaveToDatabase(); + Activator.Publish(dataset); + return dataset; + } + + private class CreateAtrObj + { + public string objectTypeId; + public List Attributes; + } + + public override Dataset Create(Catalogue catalogue) + { + var url = $"{API_URL}{_workspace}/v1/object/create"; + var serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true + }; + using var stream = new MemoryStream(); + + var response = Task.Run(async () => await _client.GetAsync($"{API_URL}{_workspace}/v1/objectschema/{Configuration.Url}/objecttypes")).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + List objectSchemaTypes = JsonConvert.DeserializeObject>(detailsString); + var t = objectSchemaTypes.FirstOrDefault(e => e.name == DATASET); + string objectTypeId = t.id; + string nameAttributeId = ""; + var schema = GetSchemaAttributes(t.objectSchemaId); + var item = schema.Where(s => s.name == NAME); + if (item.Any()) + { + nameAttributeId = item.First().id; + } + else + { + throw new Exception($"{response.StatusCode}: Unable to fetch Object Types"); + } + var o = new CreateAtrObj() + { + objectTypeId = objectTypeId, + Attributes = new List() { new JiraDatasetObjects.Attribute() { + objectTypeAttributeId=nameAttributeId, + objectAttributeValues = new List(){ + new(){value=catalogue.Name} + } + } } + }; + + + System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); + var jsonString = Encoding.UTF8.GetString(stream.ToArray()); + var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + response = Task.Run(async () => await _client.PostAsync(url, httpContent)).Result; + if (response.StatusCode == HttpStatusCode.Created) + { + detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + JiraDataset jiraDataset = JsonConvert.DeserializeObject(detailsString); + jiraDataset = FetchDatasetByID(int.Parse(jiraDataset.id)) as JiraDataset; + UpdateUsingCatalogue(jiraDataset, catalogue); + return jiraDataset; + } + else + { + throw new Exception($"{response.StatusCode}: Unable to create Dataset"); + } + } + else + { + throw new Exception($"{response.StatusCode}: Unable to fetch Object Types"); + } + + } + + public override Dataset FetchDatasetByID(int id) + { + var response = Task.Run(async () => await _client.GetAsync($"{API_URL}{_workspace}/v1/object/{id}")).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + JiraDataset jiraDataset = JsonConvert.DeserializeObject(detailsString); + + return jiraDataset; + } + throw new Exception($"{response.StatusCode}: Unable to fetch Dataset by ID {id}"); + } + + public override List FetchDatasets() + { + throw new NotImplementedException(); + } + + + + + public override void Update(string uuid, PluginDataset datasetUpdates) + { + var ds = (JiraDataset)datasetUpdates; + List jiraAttributes = []; + foreach (var attribute in ds.attributes) + { + var obj = new JiraDatasetObjects.Attribute(); + obj.objectTypeAttributeId = attribute.objectTypeAttributeId; + obj.objectAttributeValues = new List(); + foreach (var v in attribute.objectAttributeValues) + { + obj.objectAttributeValues.Add(new JiraDatasetObjects.ObjectAttributeValue() + { + value = v.value + }); + } + jiraAttributes.Add(obj); + } + var serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true + }; + using var stream = new MemoryStream(); + var o = new UpdateAttributes() + { + attributes = jiraAttributes + }; + System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); + var jsonString = Encoding.UTF8.GetString(stream.ToArray()); + var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + var response = Task.Run(async () => await _client.PutAsync($"{API_URL}{_workspace}/v1/object/{uuid}", httpContent)).Result; + if (response.StatusCode != HttpStatusCode.OK) + { + throw new Exception($"{response.StatusCode}: Unable to update Dataset"); + } + } + + private static string GetObjectTypeAttributeID(JiraDataset dataset, string name) + { + try + { + var a = dataset.attributes.Select(a => a.objectTypeAttribute); + var b = a.Select(a => a.name); + var c = a.Where(l => l.name == name).ToList(); + if (c.Any()) return c.First().id; + return null; + } + catch (Exception) + { + return null; + } + } + + + private List _schemaObjects = []; + + private List GetSchemaAttributes(string objectSchemaID) + { + + if (_schemaObjects.Any()) return _schemaObjects; + + var otresponse = Task.Run(async () => await _client.GetAsync($"{API_URL}{_workspace}/v1/objectschema/{objectSchemaID}/objecttypes")).Result; + if (otresponse.StatusCode == HttpStatusCode.OK) + { + var otdetailsString = Task.Run(async () => await otresponse.Content.ReadAsStringAsync()).Result; + var _objectEntires = JsonConvert.DeserializeObject>(otdetailsString); + var o = _objectEntires.FirstOrDefault(o => o.name == DATASET); + if (o is not null) + { + var id = o.id; + var response = Task.Run(async () => await _client.GetAsync($"{API_URL}{_workspace}/v1/objecttype/{id}/attributes")).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + _schemaObjects = JsonConvert.DeserializeObject>(detailsString); + return _schemaObjects; + } + else + { + throw new Exception($"{response.StatusCode}: Unable to fetch Object Attributes for Schema {objectSchemaID}"); + } + } + throw new Exception("Unable to find Dataset object"); + } + else + { + throw new Exception($"{otresponse.StatusCode}: Unable to fetch Object Types"); + + } + + + + } + + private JiraDatasetObjects.Attribute GenerateUpdateAttribute(JiraDataset dataset, Catalogue catalogue, string name, string value) + { + var otai = GetObjectTypeAttributeID(dataset, name); + if (otai is null) + { + var schema = GetSchemaAttributes(dataset.objectType.objectSchemaId); + var item = schema.Where(s => s.name == name); + if (item.Any()) + { + otai = item.First().id; + } + } + return new JiraDatasetObjects.Attribute() + { + objectTypeAttributeId = otai, + objectAttributeValues = new List() { + new JiraDatasetObjects.ObjectAttributeValue() + { + value = value + } + } + }; + } + + + + public override void UpdateUsingCatalogue(PluginDataset dataset, Catalogue catalogue) + { + var jiraDataset = (JiraDataset)dataset; + var updateDataset = new JiraDataset(); + updateDataset.attributes = new List(); + + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Name", catalogue.Name)); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Short Description", catalogue.ShortDescription)); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Acronym", catalogue.Acronym)); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "DOI", catalogue.Doi)); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Update Frequency", ((Catalogue.UpdateFrequencies)catalogue.Update_freq).ToString())); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Initial Release Date", catalogue.DatasetReleaseDate.ToString())); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Update Lag", ((Catalogue.UpdateLagTimes)catalogue.UpdateLag).ToString())); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Is Deprecated", catalogue.IsDeprecated.ToString())); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Is Project Specific", catalogue.IsProjectSpecific(Activator.RepositoryLocator.DataExportRepository).ToString())); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "RDMP_CatalogueID", catalogue.ID.ToString())); + updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "RDMP_CatalogueDB", (catalogue.CatalogueRepository as TableRepository).GetConnection().Connection.ConnectionString)); + var tableInfos = catalogue.CatalogueItems.Select(ci => ci.ColumnInfo.TableInfo).ToList(); + var databaseTableschema = GetSchemaAttributes(jiraDataset.objectType.objectSchemaId).Where(s => s.name == "Database").First().id; + + var serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true + }; + + var jsonString = "{\r\n \"qlQuery\": \"objectType = Database\"\r\n}"; + var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + + var response = Task.Run(async () => await _client.PostAsync($"{API_URL}{_workspace}/v1/object/aql", httpContent)).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + AQLResult databases = JsonConvert.DeserializeObject(detailsString); + + var dbUpdate = new JiraDatasetObjects.Attribute(); + dbUpdate.objectId = jiraDataset.id; + dbUpdate.objectTypeAttributeId = databaseTableschema; + dbUpdate.objectAttributeValues = databases.values.Select(d => new JiraDatasetObjects.ObjectAttributeValue() { value = d.objectKey }).ToList(); + + + var dbs = new List(); + foreach (var ti in tableInfos) + { + var o = databases.values.FirstOrDefault(db => db.attributes.Any(a => a.objectAttributeValues.First().value.ToString() == ti.Database[1..^1]) && db.attributes.Any(a => a.objectAttributeValues.First().value.ToString() == ti.Server)); + if (o is not null) + { + dbs.Add(o); + } + } + dbs = dbs.Distinct().ToList(); + + + using var stream = new MemoryStream(); + System.Text.Json.JsonSerializer.Serialize(stream, dbUpdate, serializeOptions); + var dbUpdatejson = Encoding.UTF8.GetString(stream.ToArray()); + + updateDataset.attributes.Add(new JiraDatasetObjects.Attribute() + { + objectTypeAttributeId = databaseTableschema, + objectAttributeValues = dbs.Select(v => new JiraDatasetObjects.ObjectAttributeValue() { value = v.objectKey }).ToList() + }); + } + else + { + throw new Exception($"{response.StatusCode}: Unable to fetch Jira Database Object"); + } + + Update(jiraDataset.id, updateDataset); + + //update projects + var projectSpecificIDs = Activator.RepositoryLocator.DataExportRepository.GetAllObjectsWhere("Catalogue_ID", catalogue.ID).Where(eds => eds.Project_ID != null).Select(eds => eds.Project_ID); + var projectSpecifics = Activator.RepositoryLocator.DataExportRepository.GetAllObjects().Where(p => projectSpecificIDs.Contains(p.ID)); + var projectsUsedIn = Activator.RepositoryLocator.DataExportRepository.GetAllObjects().Where(p => p.ExtractionConfigurations.Any(ec => ec.GetAllExtractableDataSets().Any(eds => eds.Catalogue_ID == catalogue.ID))); + var linkedProjects = projectSpecifics.Concat(projectsUsedIn).ToList().Distinct(); + + response = Task.Run(async () => await _client.GetAsync($"{API_URL}{_workspace}/v1/objectschema/{Configuration.Url}/objecttypes")).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + var detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + List objectSchemaTypes = JsonConvert.DeserializeObject>(detailsString); + var t = objectSchemaTypes.FirstOrDefault(e => e.name == PROJECT); + + + + foreach (var project in linkedProjects) + { + var catalogues = project.GetAllProjectCatalogues();//is this all of them? + List datasets = catalogue.GetLinkedDatasets().Where(ds => ds.Provider_ID == Configuration.ID).ToList(); + + + + jsonString = $"{{\r\n \"qlQuery\": \"objectType = Project and \\\"Project ID\\\" startswith \\\"Project {project.ProjectNumber} \\\"\"\r\n}}"; + httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + response = Task.Run(async () => await _client.PostAsync($"{API_URL}{_workspace}/v1/object/aql", httpContent)).Result; + if (response.StatusCode == HttpStatusCode.OK) + { + + detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; + AQLResult projects = JsonConvert.DeserializeObject(detailsString); + var datasetID = projects.objectTypeAttributes.First(ota => ota.name == DATASET).id; + foreach (var jiraAssetProject in projects.values) + { + List jiraAttributes = []; + jiraAttributes.Add(new JiraDatasetObjects.Attribute() + { + objectTypeAttributeId = datasetID, + objectAttributeValues = datasets.Select(ds => new JiraDatasetObjects.ObjectAttributeValue() { value = ((JiraDataset)FetchDatasetByID(int.Parse(ds.Url.Split('/').Last()))).objectKey }).ToList() + + }); + serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true + }; + using var stream = new MemoryStream(); + var o = new UpdateAttributes() + { + attributes = jiraAttributes + }; + System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); + jsonString = Encoding.UTF8.GetString(stream.ToArray()); + httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + response = Task.Run(async () => await _client.PutAsync($"{API_URL}{_workspace}/v1/object/{jiraAssetProject.id}", httpContent)).Result; + if (response.StatusCode != HttpStatusCode.OK) + { + throw new Exception($"{response.StatusCode}: Unable to Link Dataset to project {jiraAssetProject.id}"); + } + } + } + else + { + throw new Exception($"{response.StatusCode}: Unable to fetch Projects"); + } + } + } + else + { + throw new Exception($"{response.StatusCode}: Unable to fetch Object types"); + } + } + + } +} diff --git a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs index c75dc69052..723249bbf8 100644 --- a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs +++ b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs @@ -30,7 +30,11 @@ private IAtomicCommand[] GetWhitespaceRightClickMenu() new ExecuteCommandAddNewRegexRedactionConfigurationUI(_activator) { OverrideCommandName="Add New Regex Redaction Configuration" - } + }, + new ExecuteCommandCreateNewJiraConfigurationUI(_activator){ + OverrideCommandName="Create New Jira Configuration", SuggestedCategory="Jira Integration" + }, + }; } diff --git a/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs b/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs new file mode 100644 index 0000000000..86b5aa19df --- /dev/null +++ b/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs @@ -0,0 +1,29 @@ +using Rdmp.Core.CommandExecution.AtomicCommands; +using Rdmp.Core.CommandExecution; +using Rdmp.UI.ItemActivation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Rdmp.UI.SimpleDialogs.Datasets.Jira; + +namespace Rdmp.UI.CommandExecution.AtomicCommands +{ + public class ExecuteCommandCreateNewJiraConfigurationUI : BasicCommandExecution, IAtomicCommand + { + private readonly IActivateItems _activator; + + public ExecuteCommandCreateNewJiraConfigurationUI(IActivateItems activator) : base(activator) + { + _activator = activator; + } + + public override void Execute() + { + base.Execute(); + var ui = new CreateNewJiraConfigurationUI(_activator); + ui.ShowDialog(); + } + } +} diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs new file mode 100644 index 0000000000..8c678618d5 --- /dev/null +++ b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs @@ -0,0 +1,246 @@ +namespace Rdmp.UI.SimpleDialogs.Datasets.Jira +{ + partial class CreateNewJiraConfigurationUI + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + label1 = new System.Windows.Forms.Label(); + label2 = new System.Windows.Forms.Label(); + label3 = new System.Windows.Forms.Label(); + label4 = new System.Windows.Forms.Label(); + tbName = new System.Windows.Forms.TextBox(); + tbUrl = new System.Windows.Forms.TextBox(); + tbOrganisationId = new System.Windows.Forms.TextBox(); + cbCredentials = new System.Windows.Forms.ComboBox(); + btnSave = new System.Windows.Forms.Button(); + cbImportCatalogues = new System.Windows.Forms.CheckBox(); + cbIncludeInternal = new System.Windows.Forms.CheckBox(); + cbImportProjectSpecific = new System.Windows.Forms.CheckBox(); + cbImportDeprecated = new System.Windows.Forms.CheckBox(); + aiImportAll = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + aiInternal = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + aiProjectSpecific = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + aiDeprecated = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(57, 76); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(104, 15); + label1.TabIndex = 0; + label1.Text = "Object Schema ID:"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(119, 37); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(42, 15); + label2.TabIndex = 1; + label2.Text = "Name:"; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(26, 116); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(135, 15); + label3.TabIndex = 2; + label3.Text = "Data Access Credentials:"; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new System.Drawing.Point(69, 152); + label4.Name = "label4"; + label4.Size = new System.Drawing.Size(92, 15); + label4.TabIndex = 3; + label4.Text = "Organisation ID:"; + // + // tbName + // + tbName.Location = new System.Drawing.Point(169, 34); + tbName.Name = "tbName"; + tbName.Size = new System.Drawing.Size(370, 23); + tbName.TabIndex = 4; + tbName.TextChanged += ValidateForm; + // + // tbUrl + // + tbUrl.Location = new System.Drawing.Point(169, 73); + tbUrl.Name = "tbUrl"; + tbUrl.Size = new System.Drawing.Size(370, 23); + tbUrl.TabIndex = 5; + tbUrl.TextChanged += ValidateForm; + // + // tbOrganisationId + // + tbOrganisationId.Location = new System.Drawing.Point(169, 149); + tbOrganisationId.Name = "tbOrganisationId"; + tbOrganisationId.Size = new System.Drawing.Size(370, 23); + tbOrganisationId.TabIndex = 6; + tbOrganisationId.TextChanged += ValidateForm; + // + // cbCredentials + // + cbCredentials.FormattingEnabled = true; + cbCredentials.Location = new System.Drawing.Point(169, 108); + cbCredentials.Name = "cbCredentials"; + cbCredentials.Size = new System.Drawing.Size(208, 23); + cbCredentials.TabIndex = 7; + cbCredentials.SelectedIndexChanged += ValidateForm; + // + // btnSave + // + btnSave.Enabled = false; + btnSave.Location = new System.Drawing.Point(464, 318); + btnSave.Name = "btnSave"; + btnSave.Size = new System.Drawing.Size(75, 23); + btnSave.TabIndex = 8; + btnSave.Text = "Save"; + btnSave.UseVisualStyleBackColor = true; + btnSave.Click += Save; + // + // cbImportCatalogues + // + cbImportCatalogues.AutoSize = true; + cbImportCatalogues.Location = new System.Drawing.Point(337, 188); + cbImportCatalogues.Name = "cbImportCatalogues"; + cbImportCatalogues.Size = new System.Drawing.Size(202, 19); + cbImportCatalogues.TabIndex = 9; + cbImportCatalogues.Text = "Import All Extractable Catalogues"; + cbImportCatalogues.UseVisualStyleBackColor = true; + // + // cbIncludeInternal + // + cbIncludeInternal.AutoSize = true; + cbIncludeInternal.Location = new System.Drawing.Point(337, 213); + cbIncludeInternal.Name = "cbIncludeInternal"; + cbIncludeInternal.Size = new System.Drawing.Size(184, 19); + cbIncludeInternal.TabIndex = 10; + cbIncludeInternal.Text = "Import All Internal Catalogues"; + cbIncludeInternal.UseVisualStyleBackColor = true; + // + // cbImportProjectSpecific + // + cbImportProjectSpecific.AutoSize = true; + cbImportProjectSpecific.Location = new System.Drawing.Point(337, 238); + cbImportProjectSpecific.Name = "cbImportProjectSpecific"; + cbImportProjectSpecific.Size = new System.Drawing.Size(225, 19); + cbImportProjectSpecific.TabIndex = 11; + cbImportProjectSpecific.Text = "Import All Project Sepcific Catalogues"; + cbImportProjectSpecific.UseVisualStyleBackColor = true; + // + // cbImportDeprecated + // + cbImportDeprecated.AutoSize = true; + cbImportDeprecated.Location = new System.Drawing.Point(337, 263); + cbImportDeprecated.Name = "cbImportDeprecated"; + cbImportDeprecated.Size = new System.Drawing.Size(204, 19); + cbImportDeprecated.TabIndex = 12; + cbImportDeprecated.Text = "Import All Deprecated Catalogues"; + cbImportDeprecated.UseVisualStyleBackColor = true; + // + // aiImportAll + // + aiImportAll.Location = new System.Drawing.Point(542, 188); + aiImportAll.Name = "aiImportAll"; + aiImportAll.Size = new System.Drawing.Size(20, 20); + aiImportAll.TabIndex = 13; + // + // aiInternal + // + aiInternal.Location = new System.Drawing.Point(521, 213); + aiInternal.Name = "aiInternal"; + aiInternal.Size = new System.Drawing.Size(20, 20); + aiInternal.TabIndex = 14; + // + // aiProjectSpecific + // + aiProjectSpecific.Location = new System.Drawing.Point(559, 237); + aiProjectSpecific.Name = "aiProjectSpecific"; + aiProjectSpecific.Size = new System.Drawing.Size(20, 20); + aiProjectSpecific.TabIndex = 15; + // + // aiDeprecated + // + aiDeprecated.Location = new System.Drawing.Point(542, 263); + aiDeprecated.Name = "aiDeprecated"; + aiDeprecated.Size = new System.Drawing.Size(20, 20); + aiDeprecated.TabIndex = 16; + // + // CreateNewJiraConfigurationUI + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(800, 450); + Controls.Add(aiDeprecated); + Controls.Add(aiProjectSpecific); + Controls.Add(aiInternal); + Controls.Add(aiImportAll); + Controls.Add(cbImportDeprecated); + Controls.Add(cbImportProjectSpecific); + Controls.Add(cbIncludeInternal); + Controls.Add(cbImportCatalogues); + Controls.Add(btnSave); + Controls.Add(cbCredentials); + Controls.Add(tbOrganisationId); + Controls.Add(tbUrl); + Controls.Add(tbName); + Controls.Add(label4); + Controls.Add(label3); + Controls.Add(label2); + Controls.Add(label1); + Name = "CreateNewJiraConfigurationUI"; + Text = "Create Pure Configuration"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox tbName; + private System.Windows.Forms.TextBox tbUrl; + private System.Windows.Forms.TextBox tbOrganisationId; + private System.Windows.Forms.ComboBox cbCredentials; + private System.Windows.Forms.Button btnSave; + private System.Windows.Forms.CheckBox cbImportCatalogues; + private System.Windows.Forms.CheckBox cbIncludeInternal; + private System.Windows.Forms.CheckBox cbImportProjectSpecific; + private System.Windows.Forms.CheckBox cbImportDeprecated; + private SimpleControls.AdditionalInfomationUI aiImportAll; + private SimpleControls.AdditionalInfomationUI aiInternal; + private SimpleControls.AdditionalInfomationUI aiProjectSpecific; + private SimpleControls.AdditionalInfomationUI aiDeprecated; + } +} \ No newline at end of file diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs new file mode 100644 index 0000000000..1a9e12fe9f --- /dev/null +++ b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs @@ -0,0 +1,70 @@ +using Rdmp.Core.Curation.Data.Datasets; +using Rdmp.Core.Curation.Data; +using Rdmp.UI.ItemActivation; +using Rdmp.UI.TestsAndSetup.ServicePropogation; +using System; +using Rdmp.Core.Curation.Data.Datasets.Jira; + +namespace Rdmp.UI.SimpleDialogs.Datasets.Jira +{ + public partial class CreateNewJiraConfigurationUI : RDMPForm + { + + private readonly IActivateItems _activator; + public CreateNewJiraConfigurationUI(IActivateItems activator) + { + InitializeComponent(); + _activator = activator; + var dataAccessCredentials = _activator.RepositoryLocator.CatalogueRepository.GetAllObjects(); + cbCredentials.Items.Clear(); + cbCredentials.Items.AddRange(dataAccessCredentials); + } + + private void DisableSave() + { + btnSave.Enabled = false; + } + + private void ValidateForm(object sender, EventArgs e) + { + + if (cbCredentials.SelectedItem is null) + { + DisableSave(); + return; + } + if (string.IsNullOrWhiteSpace(tbName.Text)) + { + DisableSave(); + return; + } + if (string.IsNullOrWhiteSpace(tbUrl.Text)) + { + DisableSave(); + return; + } + if (string.IsNullOrWhiteSpace(tbOrganisationId.Text)) + { + DisableSave(); + return; + } + btnSave.Enabled = true; + } + + private void Save(object sender, EventArgs e) + { + var config = new DatasetProviderConfiguration(_activator.RepositoryLocator.CatalogueRepository, tbName.Text, typeof(JiraDatasetProvider).ToString(), tbUrl.Text, ((DataAccessCredentials)cbCredentials.SelectedItem).ID, tbOrganisationId.Text); + config.SaveToDatabase(); + _activator.Publish(config); + + if (cbImportCatalogues.Checked || cbImportProjectSpecific.Checked || cbIncludeInternal.Checked || cbImportDeprecated.Checked) + { + var cmd = new ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider(_activator, new JiraDatasetProvider(_activator, config), cbImportCatalogues.Checked, cbIncludeInternal.Checked, cbImportProjectSpecific.Checked, cbImportDeprecated.Checked); + cmd.Execute(); + } + + Close(); + _activator.Show($"Dataset Provider '{tbName.Text}' has successfully been created"); + } + } +} From ee5e39cdaee99fa0bcc4b895cf51886360482ae1 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 09:31:13 +0100 Subject: [PATCH 02/20] update provider --- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs | 2 +- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 2 +- .../SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs index b1eadc465c..2b8218c98e 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -8,7 +8,7 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira { - class JiraDataset: PluginDataset + public class JiraDataset: PluginDataset { public JiraDataset() { diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 673217ba90..05955b60c4 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -66,7 +66,7 @@ private class CreateAtrObj public List Attributes; } - public override Dataset Create(Catalogue catalogue) + public override JiraDataset Create(Catalogue catalogue) { var url = $"{API_URL}{_workspace}/v1/object/create"; var serializeOptions = new JsonSerializerOptions diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs index 1a9e12fe9f..1df86c25ae 100644 --- a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs +++ b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs @@ -4,6 +4,7 @@ using Rdmp.UI.TestsAndSetup.ServicePropogation; using System; using Rdmp.Core.Curation.Data.Datasets.Jira; +using Rdmp.Core.CommandExecution.AtomicCommands; namespace Rdmp.UI.SimpleDialogs.Datasets.Jira { From a7cb487d379e5da0305dfee494474935a49411be Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 10:38:26 +0100 Subject: [PATCH 03/20] add show --- .../Collections/ConfigurationsCollectionUI.cs | 6 +- .../ImportExistingJiraDatasetUI.Designer.cs | 131 ++++++++++++++++++ .../Jira/ImportExistingJiraDatasetUI.cs | 76 ++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs create mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs diff --git a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs index 723249bbf8..feac48ca7d 100644 --- a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs +++ b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs @@ -33,6 +33,10 @@ private IAtomicCommand[] GetWhitespaceRightClickMenu() }, new ExecuteCommandCreateNewJiraConfigurationUI(_activator){ OverrideCommandName="Create New Jira Configuration", SuggestedCategory="Jira Integration" + }, + new ExecuteCommandImportExistingJiraDatasetUI(_activator) + { + OverrideCommandName="Import Existing Jira Dataset", SuggestedCategory="Jira Integration" }, }; @@ -50,7 +54,7 @@ public override void SetItemActivator(IActivateItems activator) tlvConfigurations.AddObject(Activator.CoreChildProvider.AllDatasetProviderConfigurationsNode); tlvConfigurations.AddObject(Activator.CoreChildProvider.AllRegexRedactionConfigurationsNode); tlvConfigurations.Refresh(); - } + } public void RefreshBus_RefreshObject(object sender, RefreshObjectEventArgs e) { diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs new file mode 100644 index 0000000000..01dcec9a99 --- /dev/null +++ b/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs @@ -0,0 +1,131 @@ +namespace Rdmp.UI.SimpleDialogs.Datasets.Jira +{ + partial class ImportExistingJiraDatasetUI + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + btnCreate = new System.Windows.Forms.Button(); + btnCancel = new System.Windows.Forms.Button(); + tbUrl = new System.Windows.Forms.TextBox(); + lblError = new System.Windows.Forms.Label(); + label2 = new System.Windows.Forms.Label(); + cbProviders = new System.Windows.Forms.ComboBox(); + label1 = new System.Windows.Forms.Label(); + SuspendLayout(); + // + // btnCreate + // + btnCreate.Location = new System.Drawing.Point(550, 108); + btnCreate.Name = "btnCreate"; + btnCreate.Size = new System.Drawing.Size(75, 23); + btnCreate.TabIndex = 14; + btnCreate.Text = "Create"; + btnCreate.UseVisualStyleBackColor = true; + btnCreate.Click += btnCreate_Click; + // + // btnCancel + // + btnCancel.Location = new System.Drawing.Point(459, 108); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new System.Drawing.Size(75, 23); + btnCancel.TabIndex = 15; + btnCancel.Text = "Cancel"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.Click += btnCancel_Click; + // + // tbUrl + // + tbUrl.Location = new System.Drawing.Point(74, 56); + tbUrl.Name = "tbUrl"; + tbUrl.Size = new System.Drawing.Size(551, 23); + tbUrl.TabIndex = 17; + // + // lblError + // + lblError.AutoSize = true; + lblError.ForeColor = System.Drawing.Color.Red; + lblError.Location = new System.Drawing.Point(23, 95); + lblError.Name = "lblError"; + lblError.Size = new System.Drawing.Size(0, 15); + lblError.TabIndex = 18; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(14, 20); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(54, 15); + label2.TabIndex = 19; + label2.Text = "Provider:"; + // + // cbProviders + // + cbProviders.FormattingEnabled = true; + cbProviders.Location = new System.Drawing.Point(74, 17); + cbProviders.Name = "cbProviders"; + cbProviders.Size = new System.Drawing.Size(345, 23); + cbProviders.TabIndex = 20; + cbProviders.SelectedIndexChanged += cbProviders_SelectedIndexChanged; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(37, 59); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(37, 15); + label1.TabIndex = 16; + label1.Text = "UUID:"; + // + // ImportExistingPureDatasetUI + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(667, 158); + Controls.Add(cbProviders); + Controls.Add(label2); + Controls.Add(lblError); + Controls.Add(tbUrl); + Controls.Add(label1); + Controls.Add(btnCancel); + Controls.Add(btnCreate); + Name = "ImportExistingPureDatasetUI"; + Text = "Import Existing HDR Dataset"; + Load += ImportExistingPureDatasetUI_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private System.Windows.Forms.Button btnCreate; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.TextBox tbUrl; + private System.Windows.Forms.Label lblError; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox cbProviders; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs new file mode 100644 index 0000000000..82f88bb601 --- /dev/null +++ b/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs @@ -0,0 +1,76 @@ +using Microsoft.Data.SqlClient; +using Rdmp.Core.Curation.Data.Datasets.Jira; +using Rdmp.Core.Curation.Data.Datasets; +using Rdmp.UI.CommandExecution.AtomicCommands; +using Rdmp.UI.ItemActivation; +using Rdmp.UI.TestsAndSetup.ServicePropogation; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Rdmp.UI.SimpleDialogs.Datasets.Jira +{ + public partial class ImportExistingJiraDatasetUI : RDMPForm + { + private readonly IActivateItems _activator; + + private readonly string[] _visibilities = { "FREE", "CAMPUS", "BACKEND", "CONFIDENTIAL" }; + + private DatasetProviderConfiguration _providerConfiguration; + private JiraDatasetProvider _datasetProvider; + + public ImportExistingJiraDatasetUI(IActivateItems activator, ExecuteCommandImportExistingJiraDatasetUI command) : base(activator) + { + _activator = activator; + InitializeComponent(); + var configs = _activator.RepositoryLocator.CatalogueRepository.GetAllObjectsWhere("Type", typeof(JiraDatasetProvider).ToString()); + cbProviders.Items.AddRange(configs); + } + + private void ImportExistingPureDatasetUI_Load(object sender, EventArgs e) + { + + } + + private void btnCancel_Click(object sender, EventArgs e) + { + Dispose(); + } + + private void btnCreate_Click(object sender, EventArgs e) + { + if (_activator.YesNo("Please confirm you wish to import this Dataset", "Import Dataset")) + { + try + { + var provider = new JiraDatasetProvider(_activator, (DatasetProviderConfiguration)cbProviders.SelectedItem); + provider.AddExistingDataset(null, tbUrl.Text); + Close(); + Dispose(); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + lblError.Text = "Unable to locate dataset. Ensure UUID is correct."; + lblError.Visible = true; + return; + } + } + } + + private void cbProviders_SelectedIndexChanged(object sender, EventArgs e) + { + if (cbProviders.SelectedItem is DatasetProviderConfiguration config) + { + _providerConfiguration = config; + _datasetProvider = new JiraDatasetProvider(_activator, _providerConfiguration); + } + } + } +} From b92532996e8a42ae9fc2c4a75ed3bfa1427fcef1 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 11:06:06 +0100 Subject: [PATCH 04/20] add working import --- ...ngCataloguesIntoExternalDatasetProvider.cs | 1 + Rdmp.Core/Curation/Data/Datasets/Dataset.cs | 2 +- .../Data/Datasets/Jira/JiraDataset.cs | 7 ++- .../Data/Datasets/Jira/JiraDatasetProvider.cs | 55 ++++++++++--------- .../Curation/Data/Datasets/PluginDataset.cs | 7 ++- ...ecuteCommandImportExistingJiraDatasetUI.cs | 28 ++++++++++ .../CreateNewJiraConfigurationUI.Designer.cs | 2 +- 7 files changed, 72 insertions(+), 30 deletions(-) create mode 100644 Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs diff --git a/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs b/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs index 538bee1153..1b8e1701b8 100644 --- a/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs +++ b/Rdmp.Core/CommandExecution/AtomicCommands/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider.cs @@ -53,6 +53,7 @@ public override void Execute() foreach (var catalogue in catalogues) { var dataset = _provider.Create(catalogue); + var ds = _provider.AddExistingDatasetWithReturn(null, dataset.GetID()); var cmd = new ExecuteCommandLinkCatalogueToDataset(_activator, catalogue, ds); cmd.Execute(); diff --git a/Rdmp.Core/Curation/Data/Datasets/Dataset.cs b/Rdmp.Core/Curation/Data/Datasets/Dataset.cs index 8c8ad8042e..a8f0e52ce1 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Dataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Dataset.cs @@ -75,7 +75,7 @@ public int? Provider_ID } public override string ToString() => Name; - public string GetID() + public virtual string GetID() { return ID.ToString(); } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs index 2b8218c98e..06b9b8a88c 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -8,7 +8,7 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira { - public class JiraDataset: PluginDataset + public class JiraDataset : PluginDataset { public JiraDataset() { @@ -17,6 +17,11 @@ public JiraDataset(ICatalogueRepository catalogueRepository, string name) : base { } + public override string GetID() + { + return id; + } + public string workspaceId { get; set; } public string globalId { get; set; } public string id { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 05955b60c4..7737af6958 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -376,34 +376,37 @@ public override void UpdateUsingCatalogue(PluginDataset dataset, Catalogue catal detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; AQLResult projects = JsonConvert.DeserializeObject(detailsString); - var datasetID = projects.objectTypeAttributes.First(ota => ota.name == DATASET).id; - foreach (var jiraAssetProject in projects.values) + if (projects.objectTypeAttributes.Any()) { - List jiraAttributes = []; - jiraAttributes.Add(new JiraDatasetObjects.Attribute() + var datasetID = projects.objectTypeAttributes.First(ota => ota.name == DATASET).id; + foreach (var jiraAssetProject in projects.values) { - objectTypeAttributeId = datasetID, - objectAttributeValues = datasets.Select(ds => new JiraDatasetObjects.ObjectAttributeValue() { value = ((JiraDataset)FetchDatasetByID(int.Parse(ds.Url.Split('/').Last()))).objectKey }).ToList() - - }); - serializeOptions = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true, - IncludeFields = true - }; - using var stream = new MemoryStream(); - var o = new UpdateAttributes() - { - attributes = jiraAttributes - }; - System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); - jsonString = Encoding.UTF8.GetString(stream.ToArray()); - httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); - response = Task.Run(async () => await _client.PutAsync($"{API_URL}{_workspace}/v1/object/{jiraAssetProject.id}", httpContent)).Result; - if (response.StatusCode != HttpStatusCode.OK) - { - throw new Exception($"{response.StatusCode}: Unable to Link Dataset to project {jiraAssetProject.id}"); + List jiraAttributes = []; + jiraAttributes.Add(new JiraDatasetObjects.Attribute() + { + objectTypeAttributeId = datasetID, + objectAttributeValues = datasets.Select(ds => new JiraDatasetObjects.ObjectAttributeValue() { value = ((JiraDataset)FetchDatasetByID(int.Parse(ds.Url.Split('/').Last()))).objectKey }).ToList() + + }); + serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true + }; + using var stream = new MemoryStream(); + var o = new UpdateAttributes() + { + attributes = jiraAttributes + }; + System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); + jsonString = Encoding.UTF8.GetString(stream.ToArray()); + httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + response = Task.Run(async () => await _client.PutAsync($"{API_URL}{_workspace}/v1/object/{jiraAssetProject.id}", httpContent)).Result; + if (response.StatusCode != HttpStatusCode.OK) + { + throw new Exception($"{response.StatusCode}: Unable to Link Dataset to project {jiraAssetProject.id}"); + } } } } diff --git a/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs b/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs index ab5877b396..3f40f81061 100644 --- a/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs @@ -7,11 +7,16 @@ namespace Rdmp.Core.Curation.Data.Datasets /// /// Base class to allow all plugin dataset types to be based off /// - public class PluginDataset : Rdmp.Core.Curation.Data.Datasets.Dataset + public class PluginDataset : Dataset { public PluginDataset(ICatalogueRepository catalogueRepository, string name) : base(catalogueRepository, name) { } public PluginDataset() { } public PluginDataset(ICatalogueRepository repository, DbDataReader r) : base(repository, r) { } + + public override string GetID() + { + return ID.ToString(); + } } } \ No newline at end of file diff --git a/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs b/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs new file mode 100644 index 0000000000..913d0b0c5e --- /dev/null +++ b/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs @@ -0,0 +1,28 @@ +using Rdmp.Core.CommandExecution.AtomicCommands; +using Rdmp.UI.ItemActivation; +using Rdmp.UI.SimpleDialogs.Datasets.Jira; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rdmp.UI.CommandExecution.AtomicCommands +{ + public class ExecuteCommandImportExistingJiraDatasetUI : ExecuteCommandCreateDataset + { + private readonly IActivateItems _activator; + + public ExecuteCommandImportExistingJiraDatasetUI(IActivateItems activator) : base( + activator, "New Dataset") + { + _activator = activator; + } + + public override void Execute() + { + var ui = new ImportExistingJiraDatasetUI(_activator, this); + ui.ShowDialog(); + } + } +} diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs index 8c678618d5..90c47d542c 100644 --- a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs +++ b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs @@ -218,7 +218,7 @@ private void InitializeComponent() Controls.Add(label2); Controls.Add(label1); Name = "CreateNewJiraConfigurationUI"; - Text = "Create Pure Configuration"; + Text = "Create Jira Configuration"; ResumeLayout(false); PerformLayout(); } From f272cea5379a51e0784c81bf0d8082c2a690e57e Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 13:20:54 +0100 Subject: [PATCH 05/20] fix build --- .../Curation/Data/Datasets/DatasetProviderConfiguration.cs | 5 +++-- Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs | 3 +++ Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs | 3 +++ Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs | 3 +++ .../Curation/Data/Datasets/Jira/API/MediaClientConfig.cs | 3 +++ .../Curation/Data/Datasets/Jira/API/UpdateAttributes.cs | 3 +++ Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs | 3 +++ Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs | 3 +++ .../Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs | 3 +++ .../Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 3 +++ Tests.Common/UnitTests.cs | 6 ++++++ 11 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/DatasetProviderConfiguration.cs b/Rdmp.Core/Curation/Data/Datasets/DatasetProviderConfiguration.cs index 5ab1142800..dd98de1225 100644 --- a/Rdmp.Core/Curation/Data/Datasets/DatasetProviderConfiguration.cs +++ b/Rdmp.Core/Curation/Data/Datasets/DatasetProviderConfiguration.cs @@ -1,4 +1,5 @@ using MongoDB.Driver; +using Rdmp.Core.CommandExecution; using Rdmp.Core.MapsDirectlyToDatabaseTable.Attributes; using Rdmp.Core.Repositories; using System; @@ -44,7 +45,7 @@ internal DatasetProviderConfiguration(ICatalogueRepository repository, DbDataRea } - public IDatasetProvider GetProviderInstance() + public IDatasetProvider GetProviderInstance(IBasicActivateItems activator) { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) @@ -52,7 +53,7 @@ public IDatasetProvider GetProviderInstance() var type = assembly.GetTypes().FirstOrDefault(t => t.FullName == Type); if (type != null) { - return (IDatasetProvider)Activator.CreateInstance(type); + return (IDatasetProvider)Activator.CreateInstance(type,activator,this); } } return null; diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs index b33a651b58..c92620a38a 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/AQLResult.cs @@ -7,6 +7,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.API { + /// + /// + /// public class AQLResult { public int startAt { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs index 47a9db3baf..a8e80ef356 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Avatar.cs @@ -6,6 +6,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.API { + /// + /// + /// public class Avatar { public string workspaceId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs index bf66a6c388..3b98ec2dfb 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Entry.cs @@ -6,6 +6,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.API { + /// + /// + /// public class Entry { public string workspaceId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs index 372bb8f370..4515c3ae90 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/MediaClientConfig.cs @@ -6,6 +6,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.API { + /// + /// + /// public class MediaClientConfig { public string clientId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs index 1c76bf5f13..1801fb9e81 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/UpdateAttributes.cs @@ -6,6 +6,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.API { + /// + /// + /// public class UpdateAttributes { public List attributes { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs index 53ac743c72..87121f9ac6 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/API/Value.cs @@ -7,6 +7,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.API { + /// + /// + /// public class Value { public string workspaceId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs index 06b9b8a88c..56c60c0cdf 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -8,6 +8,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira { + /// + /// + /// public class JiraDataset : PluginDataset { public JiraDataset() diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs index 50c680a6c3..87fea6260a 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetObjects/ObjectTypeAttribute.cs @@ -6,6 +6,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects { + /// + /// + /// public class ObjectTypeAttribute { public string workspaceId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 7737af6958..dd8bceca42 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -16,6 +16,9 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira { + /// + /// + /// public class JiraDatasetProvider : PluginDatasetProvider { private readonly string _workspace; diff --git a/Tests.Common/UnitTests.cs b/Tests.Common/UnitTests.cs index fe1613e925..6023092a12 100644 --- a/Tests.Common/UnitTests.cs +++ b/Tests.Common/UnitTests.cs @@ -29,6 +29,8 @@ using Rdmp.Core.Curation.Data.Dashboarding; using Rdmp.Core.Curation.Data.DataLoad; using Rdmp.Core.Curation.Data.Datasets; +using Rdmp.Core.Curation.Data.Datasets.Jira; +using Rdmp.Core.Curation.Data.Datasets.Jira.JiraDatasetObjects; using Rdmp.Core.Curation.Data.Governance; using Rdmp.Core.Curation.Data.ImportExport; using Rdmp.Core.Curation.Data.Pipelines; @@ -622,6 +624,10 @@ public static T WhenIHaveA(MemoryDataExportRepository repository) where T : D { return (T)(object)new DatasetProviderConfiguration(repository.CatalogueRepository, "","","",WhenIHaveA(repository).ID,""); } + if(typeof(T) == typeof(JiraDataset)) + { + return (T)(object)new JiraDataset(repository.CatalogueRepository,"Jira Dataset"); + } throw new TestCaseNotWrittenYetException(typeof(T)); } From 602f3516b2ee0f8519995f6df3bf14c740a56aac Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 14:13:56 +0100 Subject: [PATCH 06/20] add virtual url --- Rdmp.Core/Curation/Data/Datasets/Dataset.cs | 2 +- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs | 4 ++++ Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Dataset.cs b/Rdmp.Core/Curation/Data/Datasets/Dataset.cs index 9aee569f50..25cca30266 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Dataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Dataset.cs @@ -79,7 +79,7 @@ public virtual string GetID() { return ID.ToString(); } - public string GetURL() + public virtual string GetURL() { return Url.ToString(); } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs index 56c60c0cdf..c77282cd17 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -24,6 +24,10 @@ public override string GetID() { return id; } + public override string GetURL() + { + return _links.self; + } public string workspaceId { get; set; } public string globalId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs b/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs index 3f40f81061..60f1dc5f6e 100644 --- a/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/PluginDataset.cs @@ -18,5 +18,9 @@ public override string GetID() { return ID.ToString(); } + public override string GetURL() + { + return ID.ToString(); + } } } \ No newline at end of file From a0590c06194655d46bd52f3e6e47f42d748a448b Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 15:09:35 +0100 Subject: [PATCH 07/20] fix jira --- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs | 4 ++-- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs index c77282cd17..22f4eab95e 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -24,9 +24,9 @@ public override string GetID() { return id; } - public override string GetURL() + public override string GetRemoteID() { - return _links.self; + return _links.self.Split("/").Last(); } public string workspaceId { get; set; } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index dd8bceca42..8369b065f3 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -277,7 +277,7 @@ private JiraDatasetObjects.Attribute GenerateUpdateAttribute(JiraDataset dataset - public override void UpdateUsingCatalogue(PluginDataset dataset, Catalogue catalogue) + public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) { var jiraDataset = (JiraDataset)dataset; var updateDataset = new JiraDataset(); @@ -424,6 +424,5 @@ public override void UpdateUsingCatalogue(PluginDataset dataset, Catalogue catal throw new Exception($"{response.StatusCode}: Unable to fetch Object types"); } } - } } From 2244111379287ce488d0a2524a5c957e2383a4e3 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 28 Apr 2025 15:46:26 +0100 Subject: [PATCH 08/20] working update --- Rdmp.Core/Curation/Data/Datasets/IDataset.cs | 2 ++ Rdmp.Core/Curation/Data/Datasets/IDatasetProvider.cs | 1 + Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 3 ++- Rdmp.UI/MainFormUITabs/CatalogueUI.cs | 3 +-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/IDataset.cs b/Rdmp.Core/Curation/Data/Datasets/IDataset.cs index 3b73096298..a9cfcc1ce1 100644 --- a/Rdmp.Core/Curation/Data/Datasets/IDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/IDataset.cs @@ -35,6 +35,7 @@ public interface IDataset: IMapsDirectlyToDatabaseTable /// string Type { get; } + /// /// The URL to access the dataset /// @@ -42,4 +43,5 @@ public interface IDataset: IMapsDirectlyToDatabaseTable public abstract string GetID(); public abstract string GetRemoteID(); + } diff --git a/Rdmp.Core/Curation/Data/Datasets/IDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/IDatasetProvider.cs index 2b623e9bf3..186dedc762 100644 --- a/Rdmp.Core/Curation/Data/Datasets/IDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/IDatasetProvider.cs @@ -24,4 +24,5 @@ public interface IDatasetProvider Dataset Create(Catalogue catalogue); Dataset AddExistingDatasetWithReturn(string name, string url); + } \ No newline at end of file diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 8369b065f3..7aecab000a 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -279,7 +279,7 @@ private JiraDatasetObjects.Attribute GenerateUpdateAttribute(JiraDataset dataset public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) { - var jiraDataset = (JiraDataset)dataset; + var jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(dataset.Url.Split("/").Last())); var updateDataset = new JiraDataset(); updateDataset.attributes = new List(); @@ -424,5 +424,6 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) throw new Exception($"{response.StatusCode}: Unable to fetch Object types"); } } + } } diff --git a/Rdmp.UI/MainFormUITabs/CatalogueUI.cs b/Rdmp.UI/MainFormUITabs/CatalogueUI.cs index 1ea6ee63b7..04ff867703 100644 --- a/Rdmp.UI/MainFormUITabs/CatalogueUI.cs +++ b/Rdmp.UI/MainFormUITabs/CatalogueUI.cs @@ -516,8 +516,7 @@ private void UpdateDataset(Dataset dataset) { var providerConfiguration = Activator.RepositoryLocator.CatalogueRepository.GetObjectByID((int)dataset.Provider_ID); var provider = providerConfiguration.GetProviderInstance(Activator); - var ds = provider.FetchDatasetByID(int.Parse(dataset.GetRemoteID())); //todo this id may change - provider.UpdateUsingCatalogue(ds, _catalogue); + provider.UpdateUsingCatalogue(dataset, _catalogue); } private void tableLayoutPanel3_Paint(object sender, PaintEventArgs e) { From fcb4570646fe9ff870db51e0de88b59f513e4a70 Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 29 Apr 2025 08:29:51 +0100 Subject: [PATCH 09/20] fix mapping --- .../ClassFileEvaluation/ExplicitDatabaseNameChecker.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Rdmp.UI.Tests/DesignPatternTests/ClassFileEvaluation/ExplicitDatabaseNameChecker.cs b/Rdmp.UI.Tests/DesignPatternTests/ClassFileEvaluation/ExplicitDatabaseNameChecker.cs index 2585a5baf8..9dfbb7af4c 100644 --- a/Rdmp.UI.Tests/DesignPatternTests/ClassFileEvaluation/ExplicitDatabaseNameChecker.cs +++ b/Rdmp.UI.Tests/DesignPatternTests/ClassFileEvaluation/ExplicitDatabaseNameChecker.cs @@ -29,7 +29,8 @@ public static void FindProblems(List csFilesFound) "PluginPackagerProgramOptions.cs", //allowed because it's a suggestion to the user about command line arguments "DocumentationCrossExaminationTest.cs", //allowed because its basically a list of comments that are allowed despite not appearing in the codebase "ResearchDataManagementPlatformOptions.cs", //allowed because it's an Example - "AWSS3BucketReleaseDestination.cs" //allowed as it uses it as a temp file identifier + "AWSS3BucketReleaseDestination.cs", //allowed as it uses it as a temp file identifier + "JiraDatasetProvider.cs" //Jira attribute uses the prohibited string }; From b5034e78e2e13b9eecbb8b0572ffeed6bf7fcc29 Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 29 Apr 2025 09:08:36 +0100 Subject: [PATCH 10/20] fix tests --- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs index 22f4eab95e..800098cba9 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDataset.cs @@ -9,7 +9,7 @@ namespace Rdmp.Core.Curation.Data.Datasets.Jira { /// - /// + /// Mapping of Jira API Asset object to C# /// public class JiraDataset : PluginDataset { From 2cdc743399a307a8faea016782654ca17ffa5a4f Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 29 Apr 2025 14:21:48 +0100 Subject: [PATCH 11/20] tidy up --- .../Data/Datasets/Jira/JiraDatasetProvider.cs | 2 +- .../Collections/ConfigurationsCollectionUI.cs | 16 +- ...cuteCommandCreateNewJiraConfigurationUI.cs | 29 --- ...ecuteCommandImportExistingJiraDatasetUI.cs | 28 -- .../CreateNewJiraConfigurationUI.Designer.cs | 246 ------------------ .../Jira/CreateNewJiraConfigurationUI.cs | 71 ----- .../ImportExistingJiraDatasetUI.Designer.cs | 131 ---------- .../Jira/ImportExistingJiraDatasetUI.cs | 76 ------ 8 files changed, 5 insertions(+), 594 deletions(-) delete mode 100644 Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs delete mode 100644 Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs delete mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs delete mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs delete mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs delete mode 100644 Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 7aecab000a..1be0489702 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -119,7 +119,7 @@ public override JiraDataset Create(Catalogue catalogue) detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; JiraDataset jiraDataset = JsonConvert.DeserializeObject(detailsString); jiraDataset = FetchDatasetByID(int.Parse(jiraDataset.id)) as JiraDataset; - UpdateUsingCatalogue(jiraDataset, catalogue); + //UpdateUsingCatalogue(jiraDataset, catalogue); return jiraDataset; } else diff --git a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs index 1b8e72e923..2933711f68 100644 --- a/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs +++ b/Rdmp.UI/Collections/ConfigurationsCollectionUI.cs @@ -34,26 +34,18 @@ private IAtomicCommand[] GetWhitespaceRightClickMenu() new ExecuteCommandAddNewRegexRedactionConfigurationUI(_activator) { OverrideCommandName="Add New Regex Redaction Configuration" - }, - new ExecuteCommandCreateNewJiraConfigurationUI(_activator){ - OverrideCommandName="Create New Jira Configuration", SuggestedCategory="Jira Integration" - }, - new ExecuteCommandImportExistingJiraDatasetUI(_activator) - { - OverrideCommandName="Import Existing Jira Dataset", SuggestedCategory="Jira Integration" - }, - + } }; - foreach(var provider in datasetProviders) + foreach (var provider in datasetProviders) { - options = options.Append(new ExecuteCommandAddNewDatasetProviderUI(_activator,provider) + options = options.Append(new ExecuteCommandAddNewDatasetProviderUI(_activator, provider) { OverrideCommandName = $"Add New {System.Text.RegularExpressions.Regex.Replace(provider.Name, "([A-Z])", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim()}", SuggestedCategory = "Dataset Provider Configurations" }).ToArray(); options = options.Append(new ExecuteCommandAddNewDatasetUI(_activator, provider) { - OverrideCommandName = $"Add Existing {System.Text.RegularExpressions.Regex.Replace(provider.Name, "([A-Z])", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim().Replace("Provider","")}", + OverrideCommandName = $"Add Existing {System.Text.RegularExpressions.Regex.Replace(provider.Name, "([A-Z])", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim().Replace("Provider", "")}", SuggestedCategory = "Datasets" }).ToArray(); } diff --git a/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs b/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs deleted file mode 100644 index 86b5aa19df..0000000000 --- a/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandCreateNewJiraConfigurationUI.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Rdmp.Core.CommandExecution.AtomicCommands; -using Rdmp.Core.CommandExecution; -using Rdmp.UI.ItemActivation; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Rdmp.UI.SimpleDialogs.Datasets.Jira; - -namespace Rdmp.UI.CommandExecution.AtomicCommands -{ - public class ExecuteCommandCreateNewJiraConfigurationUI : BasicCommandExecution, IAtomicCommand - { - private readonly IActivateItems _activator; - - public ExecuteCommandCreateNewJiraConfigurationUI(IActivateItems activator) : base(activator) - { - _activator = activator; - } - - public override void Execute() - { - base.Execute(); - var ui = new CreateNewJiraConfigurationUI(_activator); - ui.ShowDialog(); - } - } -} diff --git a/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs b/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs deleted file mode 100644 index 913d0b0c5e..0000000000 --- a/Rdmp.UI/CommandExecution/AtomicCommands/ExecuteCommandImportExistingJiraDatasetUI.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Rdmp.Core.CommandExecution.AtomicCommands; -using Rdmp.UI.ItemActivation; -using Rdmp.UI.SimpleDialogs.Datasets.Jira; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Rdmp.UI.CommandExecution.AtomicCommands -{ - public class ExecuteCommandImportExistingJiraDatasetUI : ExecuteCommandCreateDataset - { - private readonly IActivateItems _activator; - - public ExecuteCommandImportExistingJiraDatasetUI(IActivateItems activator) : base( - activator, "New Dataset") - { - _activator = activator; - } - - public override void Execute() - { - var ui = new ImportExistingJiraDatasetUI(_activator, this); - ui.ShowDialog(); - } - } -} diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs deleted file mode 100644 index 90c47d542c..0000000000 --- a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.Designer.cs +++ /dev/null @@ -1,246 +0,0 @@ -namespace Rdmp.UI.SimpleDialogs.Datasets.Jira -{ - partial class CreateNewJiraConfigurationUI - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - label1 = new System.Windows.Forms.Label(); - label2 = new System.Windows.Forms.Label(); - label3 = new System.Windows.Forms.Label(); - label4 = new System.Windows.Forms.Label(); - tbName = new System.Windows.Forms.TextBox(); - tbUrl = new System.Windows.Forms.TextBox(); - tbOrganisationId = new System.Windows.Forms.TextBox(); - cbCredentials = new System.Windows.Forms.ComboBox(); - btnSave = new System.Windows.Forms.Button(); - cbImportCatalogues = new System.Windows.Forms.CheckBox(); - cbIncludeInternal = new System.Windows.Forms.CheckBox(); - cbImportProjectSpecific = new System.Windows.Forms.CheckBox(); - cbImportDeprecated = new System.Windows.Forms.CheckBox(); - aiImportAll = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); - aiInternal = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); - aiProjectSpecific = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); - aiDeprecated = new Rdmp.UI.SimpleControls.AdditionalInfomationUI(); - SuspendLayout(); - // - // label1 - // - label1.AutoSize = true; - label1.Location = new System.Drawing.Point(57, 76); - label1.Name = "label1"; - label1.Size = new System.Drawing.Size(104, 15); - label1.TabIndex = 0; - label1.Text = "Object Schema ID:"; - // - // label2 - // - label2.AutoSize = true; - label2.Location = new System.Drawing.Point(119, 37); - label2.Name = "label2"; - label2.Size = new System.Drawing.Size(42, 15); - label2.TabIndex = 1; - label2.Text = "Name:"; - // - // label3 - // - label3.AutoSize = true; - label3.Location = new System.Drawing.Point(26, 116); - label3.Name = "label3"; - label3.Size = new System.Drawing.Size(135, 15); - label3.TabIndex = 2; - label3.Text = "Data Access Credentials:"; - // - // label4 - // - label4.AutoSize = true; - label4.Location = new System.Drawing.Point(69, 152); - label4.Name = "label4"; - label4.Size = new System.Drawing.Size(92, 15); - label4.TabIndex = 3; - label4.Text = "Organisation ID:"; - // - // tbName - // - tbName.Location = new System.Drawing.Point(169, 34); - tbName.Name = "tbName"; - tbName.Size = new System.Drawing.Size(370, 23); - tbName.TabIndex = 4; - tbName.TextChanged += ValidateForm; - // - // tbUrl - // - tbUrl.Location = new System.Drawing.Point(169, 73); - tbUrl.Name = "tbUrl"; - tbUrl.Size = new System.Drawing.Size(370, 23); - tbUrl.TabIndex = 5; - tbUrl.TextChanged += ValidateForm; - // - // tbOrganisationId - // - tbOrganisationId.Location = new System.Drawing.Point(169, 149); - tbOrganisationId.Name = "tbOrganisationId"; - tbOrganisationId.Size = new System.Drawing.Size(370, 23); - tbOrganisationId.TabIndex = 6; - tbOrganisationId.TextChanged += ValidateForm; - // - // cbCredentials - // - cbCredentials.FormattingEnabled = true; - cbCredentials.Location = new System.Drawing.Point(169, 108); - cbCredentials.Name = "cbCredentials"; - cbCredentials.Size = new System.Drawing.Size(208, 23); - cbCredentials.TabIndex = 7; - cbCredentials.SelectedIndexChanged += ValidateForm; - // - // btnSave - // - btnSave.Enabled = false; - btnSave.Location = new System.Drawing.Point(464, 318); - btnSave.Name = "btnSave"; - btnSave.Size = new System.Drawing.Size(75, 23); - btnSave.TabIndex = 8; - btnSave.Text = "Save"; - btnSave.UseVisualStyleBackColor = true; - btnSave.Click += Save; - // - // cbImportCatalogues - // - cbImportCatalogues.AutoSize = true; - cbImportCatalogues.Location = new System.Drawing.Point(337, 188); - cbImportCatalogues.Name = "cbImportCatalogues"; - cbImportCatalogues.Size = new System.Drawing.Size(202, 19); - cbImportCatalogues.TabIndex = 9; - cbImportCatalogues.Text = "Import All Extractable Catalogues"; - cbImportCatalogues.UseVisualStyleBackColor = true; - // - // cbIncludeInternal - // - cbIncludeInternal.AutoSize = true; - cbIncludeInternal.Location = new System.Drawing.Point(337, 213); - cbIncludeInternal.Name = "cbIncludeInternal"; - cbIncludeInternal.Size = new System.Drawing.Size(184, 19); - cbIncludeInternal.TabIndex = 10; - cbIncludeInternal.Text = "Import All Internal Catalogues"; - cbIncludeInternal.UseVisualStyleBackColor = true; - // - // cbImportProjectSpecific - // - cbImportProjectSpecific.AutoSize = true; - cbImportProjectSpecific.Location = new System.Drawing.Point(337, 238); - cbImportProjectSpecific.Name = "cbImportProjectSpecific"; - cbImportProjectSpecific.Size = new System.Drawing.Size(225, 19); - cbImportProjectSpecific.TabIndex = 11; - cbImportProjectSpecific.Text = "Import All Project Sepcific Catalogues"; - cbImportProjectSpecific.UseVisualStyleBackColor = true; - // - // cbImportDeprecated - // - cbImportDeprecated.AutoSize = true; - cbImportDeprecated.Location = new System.Drawing.Point(337, 263); - cbImportDeprecated.Name = "cbImportDeprecated"; - cbImportDeprecated.Size = new System.Drawing.Size(204, 19); - cbImportDeprecated.TabIndex = 12; - cbImportDeprecated.Text = "Import All Deprecated Catalogues"; - cbImportDeprecated.UseVisualStyleBackColor = true; - // - // aiImportAll - // - aiImportAll.Location = new System.Drawing.Point(542, 188); - aiImportAll.Name = "aiImportAll"; - aiImportAll.Size = new System.Drawing.Size(20, 20); - aiImportAll.TabIndex = 13; - // - // aiInternal - // - aiInternal.Location = new System.Drawing.Point(521, 213); - aiInternal.Name = "aiInternal"; - aiInternal.Size = new System.Drawing.Size(20, 20); - aiInternal.TabIndex = 14; - // - // aiProjectSpecific - // - aiProjectSpecific.Location = new System.Drawing.Point(559, 237); - aiProjectSpecific.Name = "aiProjectSpecific"; - aiProjectSpecific.Size = new System.Drawing.Size(20, 20); - aiProjectSpecific.TabIndex = 15; - // - // aiDeprecated - // - aiDeprecated.Location = new System.Drawing.Point(542, 263); - aiDeprecated.Name = "aiDeprecated"; - aiDeprecated.Size = new System.Drawing.Size(20, 20); - aiDeprecated.TabIndex = 16; - // - // CreateNewJiraConfigurationUI - // - AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - ClientSize = new System.Drawing.Size(800, 450); - Controls.Add(aiDeprecated); - Controls.Add(aiProjectSpecific); - Controls.Add(aiInternal); - Controls.Add(aiImportAll); - Controls.Add(cbImportDeprecated); - Controls.Add(cbImportProjectSpecific); - Controls.Add(cbIncludeInternal); - Controls.Add(cbImportCatalogues); - Controls.Add(btnSave); - Controls.Add(cbCredentials); - Controls.Add(tbOrganisationId); - Controls.Add(tbUrl); - Controls.Add(tbName); - Controls.Add(label4); - Controls.Add(label3); - Controls.Add(label2); - Controls.Add(label1); - Name = "CreateNewJiraConfigurationUI"; - Text = "Create Jira Configuration"; - ResumeLayout(false); - PerformLayout(); - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.TextBox tbName; - private System.Windows.Forms.TextBox tbUrl; - private System.Windows.Forms.TextBox tbOrganisationId; - private System.Windows.Forms.ComboBox cbCredentials; - private System.Windows.Forms.Button btnSave; - private System.Windows.Forms.CheckBox cbImportCatalogues; - private System.Windows.Forms.CheckBox cbIncludeInternal; - private System.Windows.Forms.CheckBox cbImportProjectSpecific; - private System.Windows.Forms.CheckBox cbImportDeprecated; - private SimpleControls.AdditionalInfomationUI aiImportAll; - private SimpleControls.AdditionalInfomationUI aiInternal; - private SimpleControls.AdditionalInfomationUI aiProjectSpecific; - private SimpleControls.AdditionalInfomationUI aiDeprecated; - } -} \ No newline at end of file diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs deleted file mode 100644 index 1df86c25ae..0000000000 --- a/Rdmp.UI/SimpleDialogs/Datasets/Jira/CreateNewJiraConfigurationUI.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Rdmp.Core.Curation.Data.Datasets; -using Rdmp.Core.Curation.Data; -using Rdmp.UI.ItemActivation; -using Rdmp.UI.TestsAndSetup.ServicePropogation; -using System; -using Rdmp.Core.Curation.Data.Datasets.Jira; -using Rdmp.Core.CommandExecution.AtomicCommands; - -namespace Rdmp.UI.SimpleDialogs.Datasets.Jira -{ - public partial class CreateNewJiraConfigurationUI : RDMPForm - { - - private readonly IActivateItems _activator; - public CreateNewJiraConfigurationUI(IActivateItems activator) - { - InitializeComponent(); - _activator = activator; - var dataAccessCredentials = _activator.RepositoryLocator.CatalogueRepository.GetAllObjects(); - cbCredentials.Items.Clear(); - cbCredentials.Items.AddRange(dataAccessCredentials); - } - - private void DisableSave() - { - btnSave.Enabled = false; - } - - private void ValidateForm(object sender, EventArgs e) - { - - if (cbCredentials.SelectedItem is null) - { - DisableSave(); - return; - } - if (string.IsNullOrWhiteSpace(tbName.Text)) - { - DisableSave(); - return; - } - if (string.IsNullOrWhiteSpace(tbUrl.Text)) - { - DisableSave(); - return; - } - if (string.IsNullOrWhiteSpace(tbOrganisationId.Text)) - { - DisableSave(); - return; - } - btnSave.Enabled = true; - } - - private void Save(object sender, EventArgs e) - { - var config = new DatasetProviderConfiguration(_activator.RepositoryLocator.CatalogueRepository, tbName.Text, typeof(JiraDatasetProvider).ToString(), tbUrl.Text, ((DataAccessCredentials)cbCredentials.SelectedItem).ID, tbOrganisationId.Text); - config.SaveToDatabase(); - _activator.Publish(config); - - if (cbImportCatalogues.Checked || cbImportProjectSpecific.Checked || cbIncludeInternal.Checked || cbImportDeprecated.Checked) - { - var cmd = new ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider(_activator, new JiraDatasetProvider(_activator, config), cbImportCatalogues.Checked, cbIncludeInternal.Checked, cbImportProjectSpecific.Checked, cbImportDeprecated.Checked); - cmd.Execute(); - } - - Close(); - _activator.Show($"Dataset Provider '{tbName.Text}' has successfully been created"); - } - } -} diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs deleted file mode 100644 index 01dcec9a99..0000000000 --- a/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.Designer.cs +++ /dev/null @@ -1,131 +0,0 @@ -namespace Rdmp.UI.SimpleDialogs.Datasets.Jira -{ - partial class ImportExistingJiraDatasetUI - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - btnCreate = new System.Windows.Forms.Button(); - btnCancel = new System.Windows.Forms.Button(); - tbUrl = new System.Windows.Forms.TextBox(); - lblError = new System.Windows.Forms.Label(); - label2 = new System.Windows.Forms.Label(); - cbProviders = new System.Windows.Forms.ComboBox(); - label1 = new System.Windows.Forms.Label(); - SuspendLayout(); - // - // btnCreate - // - btnCreate.Location = new System.Drawing.Point(550, 108); - btnCreate.Name = "btnCreate"; - btnCreate.Size = new System.Drawing.Size(75, 23); - btnCreate.TabIndex = 14; - btnCreate.Text = "Create"; - btnCreate.UseVisualStyleBackColor = true; - btnCreate.Click += btnCreate_Click; - // - // btnCancel - // - btnCancel.Location = new System.Drawing.Point(459, 108); - btnCancel.Name = "btnCancel"; - btnCancel.Size = new System.Drawing.Size(75, 23); - btnCancel.TabIndex = 15; - btnCancel.Text = "Cancel"; - btnCancel.UseVisualStyleBackColor = true; - btnCancel.Click += btnCancel_Click; - // - // tbUrl - // - tbUrl.Location = new System.Drawing.Point(74, 56); - tbUrl.Name = "tbUrl"; - tbUrl.Size = new System.Drawing.Size(551, 23); - tbUrl.TabIndex = 17; - // - // lblError - // - lblError.AutoSize = true; - lblError.ForeColor = System.Drawing.Color.Red; - lblError.Location = new System.Drawing.Point(23, 95); - lblError.Name = "lblError"; - lblError.Size = new System.Drawing.Size(0, 15); - lblError.TabIndex = 18; - // - // label2 - // - label2.AutoSize = true; - label2.Location = new System.Drawing.Point(14, 20); - label2.Name = "label2"; - label2.Size = new System.Drawing.Size(54, 15); - label2.TabIndex = 19; - label2.Text = "Provider:"; - // - // cbProviders - // - cbProviders.FormattingEnabled = true; - cbProviders.Location = new System.Drawing.Point(74, 17); - cbProviders.Name = "cbProviders"; - cbProviders.Size = new System.Drawing.Size(345, 23); - cbProviders.TabIndex = 20; - cbProviders.SelectedIndexChanged += cbProviders_SelectedIndexChanged; - // - // label1 - // - label1.AutoSize = true; - label1.Location = new System.Drawing.Point(37, 59); - label1.Name = "label1"; - label1.Size = new System.Drawing.Size(37, 15); - label1.TabIndex = 16; - label1.Text = "UUID:"; - // - // ImportExistingPureDatasetUI - // - AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - ClientSize = new System.Drawing.Size(667, 158); - Controls.Add(cbProviders); - Controls.Add(label2); - Controls.Add(lblError); - Controls.Add(tbUrl); - Controls.Add(label1); - Controls.Add(btnCancel); - Controls.Add(btnCreate); - Name = "ImportExistingPureDatasetUI"; - Text = "Import Existing HDR Dataset"; - Load += ImportExistingPureDatasetUI_Load; - ResumeLayout(false); - PerformLayout(); - } - - #endregion - private System.Windows.Forms.Button btnCreate; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.TextBox tbUrl; - private System.Windows.Forms.Label lblError; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.ComboBox cbProviders; - private System.Windows.Forms.Label label1; - } -} \ No newline at end of file diff --git a/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs b/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs deleted file mode 100644 index 82f88bb601..0000000000 --- a/Rdmp.UI/SimpleDialogs/Datasets/Jira/ImportExistingJiraDatasetUI.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Microsoft.Data.SqlClient; -using Rdmp.Core.Curation.Data.Datasets.Jira; -using Rdmp.Core.Curation.Data.Datasets; -using Rdmp.UI.CommandExecution.AtomicCommands; -using Rdmp.UI.ItemActivation; -using Rdmp.UI.TestsAndSetup.ServicePropogation; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Rdmp.UI.SimpleDialogs.Datasets.Jira -{ - public partial class ImportExistingJiraDatasetUI : RDMPForm - { - private readonly IActivateItems _activator; - - private readonly string[] _visibilities = { "FREE", "CAMPUS", "BACKEND", "CONFIDENTIAL" }; - - private DatasetProviderConfiguration _providerConfiguration; - private JiraDatasetProvider _datasetProvider; - - public ImportExistingJiraDatasetUI(IActivateItems activator, ExecuteCommandImportExistingJiraDatasetUI command) : base(activator) - { - _activator = activator; - InitializeComponent(); - var configs = _activator.RepositoryLocator.CatalogueRepository.GetAllObjectsWhere("Type", typeof(JiraDatasetProvider).ToString()); - cbProviders.Items.AddRange(configs); - } - - private void ImportExistingPureDatasetUI_Load(object sender, EventArgs e) - { - - } - - private void btnCancel_Click(object sender, EventArgs e) - { - Dispose(); - } - - private void btnCreate_Click(object sender, EventArgs e) - { - if (_activator.YesNo("Please confirm you wish to import this Dataset", "Import Dataset")) - { - try - { - var provider = new JiraDatasetProvider(_activator, (DatasetProviderConfiguration)cbProviders.SelectedItem); - provider.AddExistingDataset(null, tbUrl.Text); - Close(); - Dispose(); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - lblError.Text = "Unable to locate dataset. Ensure UUID is correct."; - lblError.Visible = true; - return; - } - } - } - - private void cbProviders_SelectedIndexChanged(object sender, EventArgs e) - { - if (cbProviders.SelectedItem is DatasetProviderConfiguration config) - { - _providerConfiguration = config; - _datasetProvider = new JiraDatasetProvider(_activator, _providerConfiguration); - } - } - } -} From 21596f76f350000e566483dab9096281e542269d Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 29 Apr 2025 15:08:18 +0100 Subject: [PATCH 12/20] working update --- Rdmp.Core/Curation/Data/Catalogue.cs | 2 +- .../Data/Datasets/Jira/JiraDatasetProvider.cs | 39 ++++++------------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Catalogue.cs b/Rdmp.Core/Curation/Data/Catalogue.cs index 78ee80a344..5a75754ff2 100644 --- a/Rdmp.Core/Curation/Data/Catalogue.cs +++ b/Rdmp.Core/Curation/Data/Catalogue.cs @@ -1165,7 +1165,7 @@ public override void SaveToDatabase() var repositoryProvider = new UserSettingsRepositoryFinder(); var activator = new ThrowImmediatelyActivator(repositoryProvider, ThrowImmediatelyCheckNotifier.Quiet); var providerInstance = providerConfiguration.GetProviderInstance(activator); - var ds = providerInstance.FetchDatasetByID(int.Parse(dataset.Url.Split('/').Last())); + var ds = providerInstance.FetchDatasetByID(int.Parse(dataset.GetRemoteID())); providerInstance.UpdateUsingCatalogue(ds, this); } } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 1be0489702..5c4d130fbc 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -28,6 +28,13 @@ public class JiraDatasetProvider : PluginDatasetProvider private readonly String PROJECT = "Project"; private readonly String NAME = "Name"; + private readonly JsonSerializerOptions serializeOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + IncludeFields = true + }; + public JiraDatasetProvider(IBasicActivateItems activator, DatasetProviderConfiguration configuration, HttpClient httpClient = null) : base(activator, configuration) { @@ -51,7 +58,7 @@ public override void AddExistingDataset(string name, string url) public override Dataset AddExistingDatasetWithReturn(string name, string url) { JiraDataset jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(url)); - var dataset = new Curation.Data.Datasets.Dataset(Repository, jiraDataset.name) + var dataset = new Dataset(Repository, jiraDataset.name) { Url = jiraDataset._links.self, Type = this.ToString(), @@ -72,12 +79,6 @@ private class CreateAtrObj public override JiraDataset Create(Catalogue catalogue) { var url = $"{API_URL}{_workspace}/v1/object/create"; - var serializeOptions = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true, - IncludeFields = true - }; using var stream = new MemoryStream(); var response = Task.Run(async () => await _client.GetAsync($"{API_URL}{_workspace}/v1/objectschema/{Configuration.Url}/objecttypes")).Result; @@ -118,8 +119,9 @@ public override JiraDataset Create(Catalogue catalogue) { detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; JiraDataset jiraDataset = JsonConvert.DeserializeObject(detailsString); - jiraDataset = FetchDatasetByID(int.Parse(jiraDataset.id)) as JiraDataset; - //UpdateUsingCatalogue(jiraDataset, catalogue); + jiraDataset = FetchDatasetByID(int.Parse(jiraDataset.GetRemoteID())) as JiraDataset; + jiraDataset.Url = jiraDataset.GetRemoteID();//hack to force the correct id when fetching the mew dataset by ID + UpdateUsingCatalogue(jiraDataset, catalogue); return jiraDataset; } else @@ -173,12 +175,6 @@ public override void Update(string uuid, PluginDataset datasetUpdates) } jiraAttributes.Add(obj); } - var serializeOptions = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true, - IncludeFields = true - }; using var stream = new MemoryStream(); var o = new UpdateAttributes() { @@ -297,13 +293,6 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) var tableInfos = catalogue.CatalogueItems.Select(ci => ci.ColumnInfo.TableInfo).ToList(); var databaseTableschema = GetSchemaAttributes(jiraDataset.objectType.objectSchemaId).Where(s => s.name == "Database").First().id; - var serializeOptions = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true, - IncludeFields = true - }; - var jsonString = "{\r\n \"qlQuery\": \"objectType = Database\"\r\n}"; var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); @@ -391,12 +380,6 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) objectAttributeValues = datasets.Select(ds => new JiraDatasetObjects.ObjectAttributeValue() { value = ((JiraDataset)FetchDatasetByID(int.Parse(ds.Url.Split('/').Last()))).objectKey }).ToList() }); - serializeOptions = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true, - IncludeFields = true - }; using var stream = new MemoryStream(); var o = new UpdateAttributes() { From fa057ebea89811137f2085b688c19f19c0c3e7fa Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 29 Apr 2025 15:28:25 +0100 Subject: [PATCH 13/20] fix update --- Rdmp.Core/Curation/Data/Catalogue.cs | 3 +-- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Catalogue.cs b/Rdmp.Core/Curation/Data/Catalogue.cs index 5a75754ff2..a05bae570b 100644 --- a/Rdmp.Core/Curation/Data/Catalogue.cs +++ b/Rdmp.Core/Curation/Data/Catalogue.cs @@ -1165,8 +1165,7 @@ public override void SaveToDatabase() var repositoryProvider = new UserSettingsRepositoryFinder(); var activator = new ThrowImmediatelyActivator(repositoryProvider, ThrowImmediatelyCheckNotifier.Quiet); var providerInstance = providerConfiguration.GetProviderInstance(activator); - var ds = providerInstance.FetchDatasetByID(int.Parse(dataset.GetRemoteID())); - providerInstance.UpdateUsingCatalogue(ds, this); + providerInstance.UpdateUsingCatalogue(dataset, this); } } diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 5c4d130fbc..04261ff146 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -119,8 +119,6 @@ public override JiraDataset Create(Catalogue catalogue) { detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; JiraDataset jiraDataset = JsonConvert.DeserializeObject(detailsString); - jiraDataset = FetchDatasetByID(int.Parse(jiraDataset.GetRemoteID())) as JiraDataset; - jiraDataset.Url = jiraDataset.GetRemoteID();//hack to force the correct id when fetching the mew dataset by ID UpdateUsingCatalogue(jiraDataset, catalogue); return jiraDataset; } @@ -275,7 +273,7 @@ private JiraDatasetObjects.Attribute GenerateUpdateAttribute(JiraDataset dataset public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) { - var jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(dataset.Url.Split("/").Last())); + var jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(dataset.GetRemoteID())); var updateDataset = new JiraDataset(); updateDataset.attributes = new List(); From 960e84b1b3c4dcf51a4f327b8cfb5a29c3a264a7 Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 29 Apr 2025 15:32:38 +0100 Subject: [PATCH 14/20] tidy up jira --- .../Data/Datasets/Jira/JiraDatasetProvider.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 04261ff146..6f2368a736 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -275,19 +275,20 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) { var jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(dataset.GetRemoteID())); var updateDataset = new JiraDataset(); - updateDataset.attributes = new List(); - - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Name", catalogue.Name)); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Short Description", catalogue.ShortDescription)); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Acronym", catalogue.Acronym)); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "DOI", catalogue.Doi)); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Update Frequency", ((Catalogue.UpdateFrequencies)catalogue.Update_freq).ToString())); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Initial Release Date", catalogue.DatasetReleaseDate.ToString())); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Update Lag", ((Catalogue.UpdateLagTimes)catalogue.UpdateLag).ToString())); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Is Deprecated", catalogue.IsDeprecated.ToString())); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "Is Project Specific", catalogue.IsProjectSpecific(Activator.RepositoryLocator.DataExportRepository).ToString())); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "RDMP_CatalogueID", catalogue.ID.ToString())); - updateDataset.attributes.Add(GenerateUpdateAttribute(jiraDataset, catalogue, "RDMP_CatalogueDB", (catalogue.CatalogueRepository as TableRepository).GetConnection().Connection.ConnectionString)); + updateDataset.attributes = new List() { + GenerateUpdateAttribute(jiraDataset, catalogue, "Name", catalogue.Name), + GenerateUpdateAttribute(jiraDataset, catalogue, "Short Description", catalogue.ShortDescription), + GenerateUpdateAttribute(jiraDataset, catalogue, "Acronym", catalogue.Acronym), + GenerateUpdateAttribute(jiraDataset, catalogue, "DOI", catalogue.Doi), + GenerateUpdateAttribute(jiraDataset, catalogue, "Update Frequency", ((Catalogue.UpdateFrequencies)catalogue.Update_freq).ToString()), + GenerateUpdateAttribute(jiraDataset, catalogue, "Initial Release Date", catalogue.DatasetReleaseDate.ToString()), + GenerateUpdateAttribute(jiraDataset, catalogue, "Update Lag", ((Catalogue.UpdateLagTimes)catalogue.UpdateLag).ToString()), + GenerateUpdateAttribute(jiraDataset, catalogue, "Is Deprecated", catalogue.IsDeprecated.ToString()), + GenerateUpdateAttribute(jiraDataset, catalogue, "Is Project Specific", catalogue.IsProjectSpecific(Activator.RepositoryLocator.DataExportRepository).ToString()), + GenerateUpdateAttribute(jiraDataset, catalogue, "RDMP_CatalogueID", catalogue.ID.ToString()), + GenerateUpdateAttribute(jiraDataset, catalogue, "RDMP_CatalogueDB", (catalogue.CatalogueRepository as TableRepository).GetConnection().Connection.ConnectionString), + }; + var tableInfos = catalogue.CatalogueItems.Select(ci => ci.ColumnInfo.TableInfo).ToList(); var databaseTableschema = GetSchemaAttributes(jiraDataset.objectType.objectSchemaId).Where(s => s.name == "Database").First().id; From b49c2713c85b9c09ca7f536f19fe36424f895f0d Mon Sep 17 00:00:00 2001 From: James Friel Date: Wed, 30 Apr 2025 11:32:42 +0100 Subject: [PATCH 15/20] add tests --- Directory.Packages.props | 1 + .../Datasets/Jira/JiraDatasetProviderTests.cs | 334 ++++++++++++++++++ Rdmp.Core.Tests/Rdmp.Core.Tests.csproj | 1 + .../Data/Datasets/Jira/JiraDatasetProvider.cs | 16 +- 4 files changed, 342 insertions(+), 10 deletions(-) create mode 100644 Rdmp.Core.Tests/Datasets/Jira/JiraDatasetProviderTests.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 3541aa23c9..9df0d34f40 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,6 +10,7 @@ + diff --git a/Rdmp.Core.Tests/Datasets/Jira/JiraDatasetProviderTests.cs b/Rdmp.Core.Tests/Datasets/Jira/JiraDatasetProviderTests.cs new file mode 100644 index 0000000000..1b673f5c20 --- /dev/null +++ b/Rdmp.Core.Tests/Datasets/Jira/JiraDatasetProviderTests.cs @@ -0,0 +1,334 @@ +using Amazon.Runtime.Internal.Endpoints.StandardLibrary; +using JustEat.HttpClientInterception; +using NUnit.Framework; +using Org.BouncyCastle.Asn1.X509; +using Rdmp.Core.CommandExecution; +using Rdmp.Core.Curation.Data; +using Rdmp.Core.Curation.Data.Datasets; +using Rdmp.Core.Curation.Data.Datasets.Jira; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using Tests.Common; +using static System.Net.WebRequestMethods; + +namespace Rdmp.Core.Tests.Datasets.Jira; + +class JiraDatasetProviderTests : DatabaseTests +{ + + private DatasetProviderConfiguration _configuration; + private JiraDatasetProvider _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(JiraDatasetProvider).ToString(), "4", dataAccessCredentials.ID, "1234"); + + _configuration.SaveToDatabase(); + + _provider = new JiraDatasetProvider(new ThrowImmediatelyActivator(RepositoryLocator), _configuration, _mockHttp); + _catalogue = new Catalogue(CatalogueRepository, "Jira test Catalogue"); + _catalogue.SaveToDatabase(); + + } + + private void SetupHttpClient(HttpRequestInterceptionBuilder builder) + { + builder.RegisterWith(options); + _mockHttp = options.CreateHttpClient(); + _provider = new JiraDatasetProvider(new ThrowImmediatelyActivator(RepositoryLocator), _configuration, _mockHttp); + } + + [Test] + public void CreateProviderTest() + { + Assert.DoesNotThrow(() => _configuration.GetProviderInstance(new ThrowImmediatelyActivator(RepositoryLocator))); + } + + //AddExistingDataset + [Test] + public void AddExistingDatasetTest_Success() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/{url}") + .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("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/{url}") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + string name = "AddExistingDatasetTest_BadRemote"; + Assert.Throws(() => _provider.AddExistingDataset(name, url)); + var dataset = CatalogueRepository.GetAllObjects().FirstOrDefault(d => d.Name == name); + Assert.That(dataset, Is.Null); + } + //AddExistingDatasetWithReturn + [Test] + public void AddExistingDatasetWithReturnTest_Success() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/{url}") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + string name = "AddExistingDatasetWithReturnTest_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("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/{url}") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + string name = "AddExistingDatasetWithReturnTest_BadRemote"; + Assert.Throws(() => _provider.AddExistingDatasetWithReturn(name, url)); + var dataset = CatalogueRepository.GetAllObjects().FirstOrDefault(d => d.Name == name); + Assert.That(dataset, Is.Null); + } + + [Test] + public void CreateDataset_BadObjectType() + { + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/objectschema/4/objecttypes") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForPost() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/create") + .Responds() + .WithStatus(201).WithJsonContent(SucessCreateString); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests().ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/objecttype/1/attributes") + .Responds() + .WithStatus(200).WithJsonContent(SuccessObjectTypeAttributes); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/999") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + + var catalogue = new Catalogue(CatalogueRepository, "CreateDataset_Success"); + catalogue.SaveToDatabase(); + var e = Assert.Throws(() => _provider.Create(catalogue)); + Assert.That(e.Message, Is.EqualTo("BadRequest: Unable to fetch Object Types")); + } + + [Test] + public void CreateDataset_UnableToCreate() + { + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/objectschema/4/objecttypes") + .Responds() + .WithStatus(200).WithJsonContent(SucessObjectTypesString); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForPost() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/create") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests().ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/objecttype/1/attributes") + .Responds() + .WithStatus(200).WithJsonContent(SuccessObjectTypeAttributes); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/999") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + + var catalogue = new Catalogue(CatalogueRepository, "CreateDataset_Success"); + catalogue.SaveToDatabase(); + var e = Assert.Throws(() => _provider.Create(catalogue)); + Assert.That(e.Message, Is.EqualTo("BadRequest: Unable to create Dataset")); + } + + [Test] + public void CreateDataset_NoMatchingSchema() + { + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/objectschema/4/objecttypes") + .Responds() + .WithStatus(200).WithJsonContent(SucessObjectTypesString); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForPost() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/create") + .Responds() + .WithStatus(201).WithJsonContent(SucessCreateString); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests().ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/objecttype/1/attributes") + .Responds() + .WithStatus(400); + SetupHttpClient(builder); + + builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/999") + .Responds() + .WithStatus(200).WithJsonContent(SucessResponseString); + SetupHttpClient(builder); + + var catalogue = new Catalogue(CatalogueRepository, "CreateDataset_Success"); + catalogue.SaveToDatabase(); + var e = Assert.Throws(() => _provider.Create(catalogue)); + Assert.That(e.Message, Is.EqualTo("BadRequest: Unable to fetch Object Attributes for Schema 4")); + } + //FetchDatasetByID + [Test] + public void FetchDatasetByIDTest_Success() + { + var url = "999"; + var builder = new HttpRequestInterceptionBuilder() + .Requests() + .ForHttps() + .ForHost("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/{url}") + .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("api.atlassian.com/jsm/assets/workspace") + .ForPath($"/1234/v1/object/{url}") + .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/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 6f2368a736..73fe7bf8e3 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -58,7 +58,7 @@ public override void AddExistingDataset(string name, string url) public override Dataset AddExistingDatasetWithReturn(string name, string url) { JiraDataset jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(url)); - var dataset = new Dataset(Repository, jiraDataset.name) + var dataset = new Dataset(Repository, name??jiraDataset.name) { Url = jiraDataset._links.self, Type = this.ToString(), @@ -97,7 +97,7 @@ public override JiraDataset Create(Catalogue catalogue) } else { - throw new Exception($"{response.StatusCode}: Unable to fetch Object Types"); + throw new Exception($"{response.StatusCode}: No matching Schema found for {NAME}"); } var o = new CreateAtrObj() { @@ -147,14 +147,6 @@ public override Dataset FetchDatasetByID(int id) throw new Exception($"{response.StatusCode}: Unable to fetch Dataset by ID {id}"); } - public override List FetchDatasets() - { - throw new NotImplementedException(); - } - - - - public override void Update(string uuid, PluginDataset datasetUpdates) { var ds = (JiraDataset)datasetUpdates; @@ -407,5 +399,9 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) } } + public override List FetchDatasets() + { + throw new NotImplementedException(); + } } } From 0f9ede8dd6408d2968487d492ce2418f9ef213e8 Mon Sep 17 00:00:00 2001 From: James Friel Date: Wed, 30 Apr 2025 13:31:39 +0100 Subject: [PATCH 16/20] fix ovveride --- Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 73fe7bf8e3..3810221d46 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -398,10 +398,5 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) throw new Exception($"{response.StatusCode}: Unable to fetch Object types"); } } - - public override List FetchDatasets() - { - throw new NotImplementedException(); - } } } From c0a2771dec2803466030f882413182f2f206bc0f Mon Sep 17 00:00:00 2001 From: James Friel Date: Thu, 1 May 2025 09:54:41 +0100 Subject: [PATCH 17/20] fixups --- .../Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 8 +++++--- Rdmp.UI/SubComponents/CreateExternalDatasetDialog.cs | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 3810221d46..98f823896b 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -32,7 +32,8 @@ public class JiraDatasetProvider : PluginDatasetProvider { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true, - IncludeFields = true + IncludeFields = true, + DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; @@ -119,6 +120,7 @@ public override JiraDataset Create(Catalogue catalogue) { detailsString = Task.Run(async () => await response.Content.ReadAsStringAsync()).Result; JiraDataset jiraDataset = JsonConvert.DeserializeObject(detailsString); + jiraDataset.Url = jiraDataset._links.self; UpdateUsingCatalogue(jiraDataset, catalogue); return jiraDataset; } @@ -265,7 +267,7 @@ private JiraDatasetObjects.Attribute GenerateUpdateAttribute(JiraDataset dataset public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) { - var jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(dataset.GetRemoteID())); + var jiraDataset = (JiraDataset)FetchDatasetByID(int.Parse(dataset.Url.Split("/").Last())); var updateDataset = new JiraDataset(); updateDataset.attributes = new List() { GenerateUpdateAttribute(jiraDataset, catalogue, "Name", catalogue.Name), @@ -327,7 +329,7 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) throw new Exception($"{response.StatusCode}: Unable to fetch Jira Database Object"); } - Update(jiraDataset.id, updateDataset); + Update(jiraDataset.GetRemoteID(), updateDataset); //update projects var projectSpecificIDs = Activator.RepositoryLocator.DataExportRepository.GetAllObjectsWhere("Catalogue_ID", catalogue.ID).Where(eds => eds.Project_ID != null).Select(eds => eds.Project_ID); diff --git a/Rdmp.UI/SubComponents/CreateExternalDatasetDialog.cs b/Rdmp.UI/SubComponents/CreateExternalDatasetDialog.cs index 9f4f59d492..6e72520a72 100644 --- a/Rdmp.UI/SubComponents/CreateExternalDatasetDialog.cs +++ b/Rdmp.UI/SubComponents/CreateExternalDatasetDialog.cs @@ -10,6 +10,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using System.Security.Policy; namespace Rdmp.UI.SubComponents { @@ -35,10 +36,10 @@ private void button1_Click(object sender, EventArgs e) { var provider = ((DatasetProviderConfiguration)cbPovider.SelectedItem).GetProviderInstance(_activator); var dataset = provider.Create(_catalogue); - - if (!_activator.RepositoryLocator.CatalogueRepository.GetAllObjectsWhere("Dataset_ID", dataset.ID).Where(l => l.Catalogue.ID == _catalogue.ID).Any()) + var ds = provider.AddExistingDatasetWithReturn(null, dataset.GetID()); + if (!_activator.RepositoryLocator.CatalogueRepository.GetAllObjectsWhere("Dataset_ID", ds.ID).Where(l => l.Catalogue.ID == _catalogue.ID).Any()) { - var linkage = new CatalogueDatasetLinkage(_activator.RepositoryLocator.CatalogueRepository, _catalogue, dataset); + var linkage = new CatalogueDatasetLinkage(_activator.RepositoryLocator.CatalogueRepository, _catalogue, ds); linkage.SaveToDatabase(); } Close(); From 47efe8eaf25014cf9359c2b3baddae3324f8da01 Mon Sep 17 00:00:00 2001 From: James Friel Date: Tue, 6 May 2025 11:07:20 +0100 Subject: [PATCH 18/20] add url --- .../Curation/Data/Datasets/Jira/JiraDatasetProvider.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 98f823896b..579cc82162 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -263,7 +263,11 @@ private JiraDatasetObjects.Attribute GenerateUpdateAttribute(JiraDataset dataset }; } - + public override string GetRemoteURL(Dataset dataset) + { + Activator.Show("Unable to open URL for Jira Assets. Please visit your Atlassian instance to access this Dataset"); + return null; + } public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) { From 16f8a7065698d7ac94b0807606760ebbfaada944 Mon Sep 17 00:00:00 2001 From: James Friel Date: Wed, 5 Nov 2025 11:16:04 +0000 Subject: [PATCH 19/20] use new type name --- .../Data/Datasets/Jira/JiraDatasetProvider.cs | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs index 579cc82162..f00a1590f9 100644 --- a/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs +++ b/Rdmp.Core/Curation/Data/Datasets/Jira/JiraDatasetProvider.cs @@ -336,7 +336,7 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) Update(jiraDataset.GetRemoteID(), updateDataset); //update projects - var projectSpecificIDs = Activator.RepositoryLocator.DataExportRepository.GetAllObjectsWhere("Catalogue_ID", catalogue.ID).Where(eds => eds.Project_ID != null).Select(eds => eds.Project_ID); + var projectSpecificIDs = Activator.RepositoryLocator.DataExportRepository.GetAllObjectsWhere("Catalogue_ID", catalogue.ID).Where(eds => eds.Projects != null).SelectMany(eds => eds.Projects).Select(p => p.ID).Distinct(); var projectSpecifics = Activator.RepositoryLocator.DataExportRepository.GetAllObjects().Where(p => projectSpecificIDs.Contains(p.ID)); var projectsUsedIn = Activator.RepositoryLocator.DataExportRepository.GetAllObjects().Where(p => p.ExtractionConfigurations.Any(ec => ec.GetAllExtractableDataSets().Any(eds => eds.Catalogue_ID == catalogue.ID))); var linkedProjects = projectSpecifics.Concat(projectsUsedIn).ToList().Distinct(); @@ -357,7 +357,7 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) - jsonString = $"{{\r\n \"qlQuery\": \"objectType = Project and \\\"Project ID\\\" startswith \\\"Project {project.ProjectNumber} \\\"\"\r\n}}"; + jsonString = $"{{\r\n \"qlQuery\": \"objectType = \\\"Project - This should have been a CM\\\" and \\\"Project ID\\\" startswith \\\"Project {project.ProjectNumber} \\\"\"\r\n}}"; httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); response = Task.Run(async () => await _client.PostAsync($"{API_URL}{_workspace}/v1/object/aql", httpContent)).Result; if (response.StatusCode == HttpStatusCode.OK) @@ -367,28 +367,33 @@ public override void UpdateUsingCatalogue(Dataset dataset, Catalogue catalogue) AQLResult projects = JsonConvert.DeserializeObject(detailsString); if (projects.objectTypeAttributes.Any()) { - var datasetID = projects.objectTypeAttributes.First(ota => ota.name == DATASET).id; - foreach (var jiraAssetProject in projects.values) + var datasetTypeAttribute = projects.objectTypeAttributes.FirstOrDefault(ota => ota.name == DATASET); + if (datasetTypeAttribute is not null) { - List jiraAttributes = []; - jiraAttributes.Add(new JiraDatasetObjects.Attribute() - { - objectTypeAttributeId = datasetID, - objectAttributeValues = datasets.Select(ds => new JiraDatasetObjects.ObjectAttributeValue() { value = ((JiraDataset)FetchDatasetByID(int.Parse(ds.Url.Split('/').Last()))).objectKey }).ToList() + var datasetID = datasetTypeAttribute.id; - }); - using var stream = new MemoryStream(); - var o = new UpdateAttributes() - { - attributes = jiraAttributes - }; - System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); - jsonString = Encoding.UTF8.GetString(stream.ToArray()); - httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); - response = Task.Run(async () => await _client.PutAsync($"{API_URL}{_workspace}/v1/object/{jiraAssetProject.id}", httpContent)).Result; - if (response.StatusCode != HttpStatusCode.OK) + foreach (var jiraAssetProject in projects.values) { - throw new Exception($"{response.StatusCode}: Unable to Link Dataset to project {jiraAssetProject.id}"); + List jiraAttributes = []; + jiraAttributes.Add(new JiraDatasetObjects.Attribute() + { + objectTypeAttributeId = datasetID, + objectAttributeValues = datasets.Select(ds => new JiraDatasetObjects.ObjectAttributeValue() { value = ((JiraDataset)FetchDatasetByID(int.Parse(ds.Url.Split('/').Last()))).objectKey }).ToList() + + }); + using var stream = new MemoryStream(); + var o = new UpdateAttributes() + { + attributes = jiraAttributes + }; + System.Text.Json.JsonSerializer.Serialize(stream, o, serializeOptions); + jsonString = Encoding.UTF8.GetString(stream.ToArray()); + httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); + response = Task.Run(async () => await _client.PutAsync($"{API_URL}{_workspace}/v1/object/{jiraAssetProject.id}", httpContent)).Result; + if (response.StatusCode != HttpStatusCode.OK) + { + throw new Exception($"{response.StatusCode}: Unable to Link Dataset to project {jiraAssetProject.id}"); + } } } } From 78331d4ec25efd5e5f5849e6308d2f415fe83e0d Mon Sep 17 00:00:00 2001 From: James Friel Date: Thu, 6 Nov 2025 08:14:32 +0000 Subject: [PATCH 20/20] update tests --- ...ortExistingCataloguesIntoExternalDatasetProviderTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Rdmp.Core.Tests/CommandExecution/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProviderTests.cs b/Rdmp.Core.Tests/CommandExecution/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProviderTests.cs index 414a1009aa..1d5ed54bff 100644 --- a/Rdmp.Core.Tests/CommandExecution/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProviderTests.cs +++ b/Rdmp.Core.Tests/CommandExecution/ExecuteCommandImportExistingCataloguesIntoExternalDatasetProviderTests.cs @@ -21,7 +21,8 @@ public void TestImportInternalCataloguesOnly() var _cata2 = new Catalogue(GetMockActivator().RepositoryLocator.CatalogueRepository, "Dataset2"); _cata1.SaveToDatabase(); _cata2.SaveToDatabase(); - + var ext = new ExtractableDataSet(GetMockActivator().RepositoryLocator.DataExportRepository, _cata2); + ext.SaveToDatabase(); var configuration = new DatasetProviderConfiguration(GetMockActivator().RepositoryLocator.CatalogueRepository, "test", "test", "test",1,"test"); var provider = new InternalDatasetProvider(GetMockActivator(),configuration,null); var cmd = new ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider(GetMockActivator(), provider, false,true, false, false,false); @@ -52,7 +53,8 @@ public void TestImportDeprecatedCataloguesOnly() var _cata2 = new Catalogue(GetMockActivator().RepositoryLocator.CatalogueRepository, "Dataset2"); _cata1.SaveToDatabase(); _cata2.SaveToDatabase(); - + var ext = new ExtractableDataSet(GetMockActivator().RepositoryLocator.DataExportRepository, _cata2); + ext.SaveToDatabase(); var configuration = new DatasetProviderConfiguration(GetMockActivator().RepositoryLocator.CatalogueRepository, "test", "test", "test", 1, "test"); var provider = new InternalDatasetProvider(GetMockActivator(), configuration, null); var cmd = new ExecuteCommandImportExistingCataloguesIntoExternalDatasetProvider(GetMockActivator(), provider, false, false, false, true, false);