diff --git a/HICPlugin/DataFlowComponents/HICCohortManagerDestination.cs b/HICPlugin/DataFlowComponents/HICCohortManagerDestination.cs index 5b50641..0cfb669 100644 --- a/HICPlugin/DataFlowComponents/HICCohortManagerDestination.cs +++ b/HICPlugin/DataFlowComponents/HICCohortManagerDestination.cs @@ -129,7 +129,6 @@ public void Dispose(IDataLoadEventListener listener, Exception pipelineFailureEx cmd.CommandType = CommandType.StoredProcedure; cmd.CommandTimeout = 100000; - var cohortId = Convert.ToInt32(cmd.ExecuteScalar()); listener.OnNotify(this, diff --git a/HICPlugin/HICPlugin.csproj b/HICPlugin/HICPlugin.csproj index 81c8213..f502281 100644 --- a/HICPlugin/HICPlugin.csproj +++ b/HICPlugin/HICPlugin.csproj @@ -10,6 +10,12 @@ + + portable + + + portable + diff --git a/InterfaceToJira/RestApiClient2/JiraClient.cs b/InterfaceToJira/RestApiClient2/JiraClient.cs index da627ae..e90414a 100644 --- a/InterfaceToJira/RestApiClient2/JiraClient.cs +++ b/InterfaceToJira/RestApiClient2/JiraClient.cs @@ -39,6 +39,7 @@ public bool Execute(RestRequest request, HttpStatusCode expectedResponseCode) if (restResponse.ResponseStatus != ResponseStatus.Completed || restResponse.StatusCode.IsError() || restResponse.ErrorException != null) throw new JiraApiException( $"RestSharp response status: {restResponse.ResponseStatus} - HTTP response: {restResponse.StatusCode} - {restResponse.StatusDescription} - {restResponse.Content}", restResponse.ErrorException); + return restResponse.Data; } @@ -207,7 +208,7 @@ public List GetProjectNames() { Resource = "/rest/api/latest/project", Method = Method.Get - }, HttpStatusCode.OK).Select((Func) (project => project.key)).ToList(); + }, HttpStatusCode.OK).Select((Func)(project => project.key)).ToList(); list.Sort(); return list; } diff --git a/JiraPlugin/JIRATicketingSystem.cs b/JiraPlugin/JIRATicketingSystem.cs index 6bef6be..40e42d2 100644 --- a/JiraPlugin/JIRATicketingSystem.cs +++ b/JiraPlugin/JIRATicketingSystem.cs @@ -8,43 +8,95 @@ using HIC.Common.InterfaceToJira.JIRA.RestApiClient2.JiraModel; using Rdmp.Core.Ticketing; using Rdmp.Core.ReusableLibraryCode.Checks; - +using RestSharp; +using Microsoft.Win32; +using Rdmp.Core.Curation; namespace JiraPlugin; -public class JIRATicketingSystem : PluginTicketingSystem +public partial class JIRATicketingSystem : PluginTicketingSystem { - public static readonly Regex RegexForTickets = new(@"((? JIRAProjectAttachements { get; private set; } public string JIRAReleaseTicketStatus { get; private set; } - private static readonly string[] PermissableReleaseStatusesForJIRAReleaseTickets = new[] { "Released" }; + private void SetupIfRequired() + { + _client ??= new JiraClient(new JiraAccount(new JiraApiConfiguration + { + ServerUrl = _serverUrl, + User = _username, + Password = Credentials.GetDecryptedPassword(), + ApiUrl = _baseUrl + })); + } + + private string GetStatusOfJIRATicket(string ticket) + { + var issue = GetIssue(ticket) ?? throw new Exception($"Non existent ticket: {ticket}"); + return issue.fields.status.name; + } + + + private void GetAttachementsOfJIRATicket(string ticket) + { + var issue = GetIssue(ticket) ?? throw new Exception($"Non existent ticket: {ticket}"); + JIRAProjectAttachements = issue.fields.attachment; + } + + public override List GetAvailableStatuses() + { + try + { + SetupIfRequired(); + var statuses = _client.GetStatuses().Select(x => x.name); + return statuses.ToList(); + } + catch (Exception) + { + return []; + } + } + + private Issue GetIssue(string ticket) + { + return _client.GetIssue(ticket); + } + private readonly string _serverUrl; + private readonly string _apiVersion; + private readonly string _username; + private readonly string _baseUrl; public JIRATicketingSystem(TicketingSystemConstructorParameters parameters) : base(parameters) { - + Credentials = parameters.Credentials; + Url = parameters.Url; + _serverUrl = parameters.Url; + _username = parameters.Credentials.Username; + _apiVersion = "latest"; + _baseUrl = string.Format("{0}/rest/api/{1}/", _serverUrl, _apiVersion); } public override void Check(ICheckNotifier notifier) { if (Credentials == null) - notifier.OnCheckPerformed(new CheckEventArgs("Data Access credentials for JIRA are not set",CheckResult.Fail)); - - if (string.IsNullOrWhiteSpace(Url)) - notifier.OnCheckPerformed(new CheckEventArgs("You must put in a URL to the JIRA server e.g. https://jira-hic.cmdn.dundee.ac.uk",CheckResult.Fail)); + notifier.OnCheckPerformed(new CheckEventArgs("Data Access credentials for JIRA are not set", CheckResult.Fail)); + + if (string.IsNullOrWhiteSpace(_baseUrl)) + notifier.OnCheckPerformed(new CheckEventArgs("You must put in a URL to the JIRA server e.g. https://example.atlassian.net", CheckResult.Fail)); else - if (RegexForUrls.IsMatch(Url)) + if (RegexForUrls.IsMatch(_baseUrl)) notifier.OnCheckPerformed(new CheckEventArgs("Url matches RegexForUrls", CheckResult.Success)); else notifier.OnCheckPerformed( new CheckEventArgs( - $"Url {Url} does not match the regex RegexForUrls: {RegexForUrlsPattern}", + $"Url {_baseUrl} does not match the regex RegexForUrls: {RegexForUrlsPattern}", CheckResult.Fail)); try { @@ -68,46 +120,7 @@ public override void Check(ICheckNotifier notifier) } } - public override bool IsValidTicketName(string ticketName) - { - //also let user clear tickets :) - return string.IsNullOrWhiteSpace(ticketName) || RegexForTickets.IsMatch(ticketName); - } - - public override void NavigateToTicket(string ticketName) - { - if (string.IsNullOrWhiteSpace(ticketName)) - return; - try - { - Check(ThrowImmediatelyCheckNotifier.Quiet); - } - catch (Exception e) - { - throw new Exception("JIRATicketingSystem Checks() failed (see inner exception for details)",e); - } - - - Uri navigationUri = null; - Uri baseUri = null; - var relativePath = $"/browse/{ticketName}"; - try - { - baseUri = new Uri(Url); - navigationUri = new Uri(baseUri, relativePath); - Process.Start(navigationUri.AbsoluteUri); - } - catch (Exception e) - { - if(navigationUri != null) - throw new Exception($"Failed to navigate to {navigationUri.AbsoluteUri}", e); - - if (baseUri != null) - throw new Exception($"Failed to reach {relativePath} from {baseUri.AbsoluteUri}", e); - } - } - - public override TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket(string masterTicket, string requestTicket, string releaseTicket, out string reason, out Exception exception) + public override TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket(string masterTicket, string requestTicket, string releaseTicket, List acceptedStatuses, out string reason, out Exception exception) { exception = null; try @@ -128,7 +141,7 @@ public override TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket( return TicketingReleaseabilityEvaluation.NotReleaseable; } - if(string.IsNullOrWhiteSpace(requestTicket)) + if (string.IsNullOrWhiteSpace(requestTicket)) { reason = "Request JIRA ticket is blank"; return TicketingReleaseabilityEvaluation.NotReleaseable; @@ -153,12 +166,13 @@ public override TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket( return e.Message.Contains("Authentication Required") ? TicketingReleaseabilityEvaluation.CouldNotAuthenticateAgainstServer : TicketingReleaseabilityEvaluation.CouldNotReachTicketingServer; } + var statusStrings = acceptedStatuses.Select(s => s.Status).ToList(); //if it isn't at required status - if (!PermissableReleaseStatusesForJIRAReleaseTickets.Contains(JIRAReleaseTicketStatus)) + if (!statusStrings.Contains(JIRAReleaseTicketStatus)) { reason = - $"Status of release ticket ({JIRAReleaseTicketStatus}) was not one of the permissable release ticket statuses: {string.Join(",", PermissableReleaseStatusesForJIRAReleaseTickets)}"; + $"Status of release ticket ({JIRAReleaseTicketStatus}) was not one of the permissable release ticket statuses: {string.Join(",", statusStrings)}"; return TicketingReleaseabilityEvaluation.NotReleaseable; //it cannot be released } @@ -182,37 +196,94 @@ public override TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket( public override string GetProjectFolderName(string masterTicket) { SetupIfRequired(); - var issue = _client.GetIssue(masterTicket, new[] {"summary", "customfield_13400"}); + var issue = _client.GetIssue(masterTicket, new[] { "summary", "customfield_13400" }); return issue.fields.customfield_13400; } - private void SetupIfRequired() + public override bool IsValidTicketName(string ticketName) { - _client ??= new JiraClient(new JiraAccount(new JiraApiConfiguration - { - ServerUrl = Url, - User = Credentials.Username, - Password = Credentials.GetDecryptedPassword() - })); + //also let user clear tickets :) + return string.IsNullOrWhiteSpace(ticketName) || RegexForTickets.IsMatch(ticketName); } - private string GetStatusOfJIRATicket(string ticket) + public override void NavigateToTicket(string ticketName) { - var issue = GetIssue(ticket) ?? throw new Exception($"Non existent ticket: {ticket}"); - return issue.fields.status.name; - } + if (string.IsNullOrWhiteSpace(ticketName)) + return; + try + { + Check(ThrowImmediatelyCheckNotifier.Quiet); + } + catch (Exception e) + { + throw new Exception("JIRATicketingSystem Checks() failed (see inner exception for details)", e); + } + Uri navigationUri = null; + Uri baseUri = null; + var relativePath = $"/browse/{ticketName}"; + try + { + baseUri = new Uri(Url); + navigationUri = new Uri(baseUri, relativePath); + string browserPath = GetBrowserPath(); + if (browserPath == string.Empty) + browserPath = "iexplore"; + Process process = new() + { + StartInfo = new ProcessStartInfo(browserPath) + }; + process.StartInfo.Arguments = "\"" + navigationUri.AbsoluteUri + "\""; + process.Start(); + } + catch (Exception e) + { + if (navigationUri != null) + throw new Exception($"Failed to navigate to {navigationUri.AbsoluteUri}", e); - private void GetAttachementsOfJIRATicket(string ticket) - { - var issue = GetIssue(ticket) ?? throw new Exception($"Non existent ticket: {ticket}"); - JIRAProjectAttachements = issue.fields.attachment; + if (baseUri != null) + throw new Exception($"Failed to reach {relativePath} from {baseUri.AbsoluteUri}", e); + } } - private Issue GetIssue(string ticket) + private static string GetBrowserPath() { - return _client.GetIssue(ticket); + string browser = string.Empty; + RegistryKey key = null; + + try + { + // try location of default browser path in XP + key = Registry.ClassesRoot.OpenSubKey(@"HTTP\shell\open\command", false); + + // try location of default browser path in Vista + if (key == null) + { + key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http", false); ; + } + + if (key != null) + { + //trim off quotes + browser = key.GetValue(null).ToString().ToLower().Replace("\"", ""); + if (!browser.EndsWith("exe")) + { + //get rid of everything after the ".exe" + browser = browser.Substring(0, browser.LastIndexOf(".exe") + 4); + } + + key.Close(); + } + } + catch + { + return string.Empty; + } + + return browser; } + [GeneratedRegex(RegexForUrlsPattern, RegexOptions.Compiled)] + private static partial Regex MyRegex(); } \ No newline at end of file diff --git a/RDMP b/RDMP index 4ee56cc..949adc4 160000 --- a/RDMP +++ b/RDMP @@ -1 +1 @@ -Subproject commit 4ee56cc0cdedf81d8e3a15e269e5e7a9b0f804f9 +Subproject commit 949adc43e6cb9ba2b374f2553deb8ec463409307