From 43357bc8c9ff9a8ccc43fb1d8bac855714963800 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Thu, 14 Mar 2019 14:26:36 +1000 Subject: [PATCH] Added `GetActiveWithSummary` and `GetAllWithSummary` to `TaskRepository` as well as `UserRepository.FindByUsername` --- ...AreaShouldNotRegress..NETCore.approved.txt | 14 +++++ ...houldNotRegress..NETFramework.approved.txt | 14 +++++ .../Model/TaskResourceCollection.cs | 14 +++++ .../Repositories/Async/BasicRepository.cs | 2 +- .../Repositories/Async/TaskRepository.cs | 34 +++++++++-- .../Repositories/Async/UserRepository.cs | 4 ++ .../Repositories/BasicRepository.cs | 2 +- .../Repositories/TaskRepository.cs | 58 +++++++++++++------ .../Repositories/UserRepository.cs | 4 ++ 9 files changed, 122 insertions(+), 24 deletions(-) create mode 100644 source/Octopus.Client/Model/TaskResourceCollection.cs diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 536bf9cf7..45c4d6385 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -4159,6 +4159,14 @@ Octopus.Client.Model Nullable StartTime { get; set; } Octopus.Client.Model.TaskState State { get; set; } } + class TaskResourceCollection + Octopus.Client.Extensibility.IResource + Octopus.Client.Model.IAuditedResource + Octopus.Client.Model.ResourceCollection + { + .ctor(IEnumerable, Octopus.Client.Extensibility.LinkCollection) + Dictionary TotalCounts { get; set; } + } abstract class TaskRestrictedTo { static System.String DeploymentTargets @@ -5961,7 +5969,9 @@ Octopus.Client.Repositories Octopus.Client.Model.TaskResource ExecuteCommunityActionTemplatesSynchronisation(String) Octopus.Client.Model.TaskResource ExecuteHealthCheck(String, Int32, Int32, String, String[], String, String, String[]) Octopus.Client.Model.TaskResource ExecuteTentacleUpgrade(String, String, String[], String, String, String[]) + Octopus.Client.Model.TaskResourceCollection GetActiveWithSummary(Int32, Int32) List GetAllActive(Int32) + Octopus.Client.Model.TaskResourceCollection GetAllWithSummary(Int32, Int32) Octopus.Client.Model.TaskDetailsResource GetDetails(Octopus.Client.Model.TaskResource, Nullable, Nullable) IReadOnlyList GetQueuedBehindTasks(Octopus.Client.Model.TaskResource) String GetRawOutputLog(Octopus.Client.Model.TaskResource) @@ -6026,6 +6036,7 @@ Octopus.Client.Repositories Octopus.Client.Model.UserResource Create(String, String, String, String) Octopus.Client.Model.ApiKeyResource CreateApiKey(Octopus.Client.Model.UserResource, String) Octopus.Client.Model.UserResource CreateServiceAccount(String, String) + Octopus.Client.Model.UserResource FindByUsername(String) List GetApiKeys(Octopus.Client.Model.UserResource) Octopus.Client.Model.UserResource GetCurrent() Octopus.Client.Model.SpaceResource[] GetSpaces(Octopus.Client.Model.UserResource) @@ -6538,7 +6549,9 @@ Octopus.Client.Repositories.Async Task ExecuteCommunityActionTemplatesSynchronisation(String) Task ExecuteHealthCheck(String, Int32, Int32, String, String[], String, String, String[]) Task ExecuteTentacleUpgrade(String, String, String[], String, String, String[]) + Task GetActiveWithSummary(Int32, Int32) Task> GetAllActive(Int32) + Task GetAllWithSummary(Int32, Int32) Task GetDetails(Octopus.Client.Model.TaskResource, Nullable, Nullable) Task> GetQueuedBehindTasks(Octopus.Client.Model.TaskResource) Task GetRawOutputLog(Octopus.Client.Model.TaskResource) @@ -6604,6 +6617,7 @@ Octopus.Client.Repositories.Async Task Create(String, String, String, String) Task CreateApiKey(Octopus.Client.Model.UserResource, String) Task CreateServiceAccount(String, String) + Task FindByUsername(String) Task> GetApiKeys(Octopus.Client.Model.UserResource) Task GetCurrent() Task GetSpaces(Octopus.Client.Model.UserResource) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 9d8b78482..4d19f092d 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -4178,6 +4178,14 @@ Octopus.Client.Model Nullable StartTime { get; set; } Octopus.Client.Model.TaskState State { get; set; } } + class TaskResourceCollection + Octopus.Client.Extensibility.IResource + Octopus.Client.Model.IAuditedResource + Octopus.Client.Model.ResourceCollection + { + .ctor(IEnumerable, Octopus.Client.Extensibility.LinkCollection) + Dictionary TotalCounts { get; set; } + } abstract class TaskRestrictedTo { static System.String DeploymentTargets @@ -5983,7 +5991,9 @@ Octopus.Client.Repositories Octopus.Client.Model.TaskResource ExecuteCommunityActionTemplatesSynchronisation(String) Octopus.Client.Model.TaskResource ExecuteHealthCheck(String, Int32, Int32, String, String[], String, String, String[]) Octopus.Client.Model.TaskResource ExecuteTentacleUpgrade(String, String, String[], String, String, String[]) + Octopus.Client.Model.TaskResourceCollection GetActiveWithSummary(Int32, Int32) List GetAllActive(Int32) + Octopus.Client.Model.TaskResourceCollection GetAllWithSummary(Int32, Int32) Octopus.Client.Model.TaskDetailsResource GetDetails(Octopus.Client.Model.TaskResource, Nullable, Nullable) IReadOnlyList GetQueuedBehindTasks(Octopus.Client.Model.TaskResource) String GetRawOutputLog(Octopus.Client.Model.TaskResource) @@ -6048,6 +6058,7 @@ Octopus.Client.Repositories Octopus.Client.Model.UserResource Create(String, String, String, String) Octopus.Client.Model.ApiKeyResource CreateApiKey(Octopus.Client.Model.UserResource, String) Octopus.Client.Model.UserResource CreateServiceAccount(String, String) + Octopus.Client.Model.UserResource FindByUsername(String) List GetApiKeys(Octopus.Client.Model.UserResource) Octopus.Client.Model.UserResource GetCurrent() Octopus.Client.Model.SpaceResource[] GetSpaces(Octopus.Client.Model.UserResource) @@ -6560,7 +6571,9 @@ Octopus.Client.Repositories.Async Task ExecuteCommunityActionTemplatesSynchronisation(String) Task ExecuteHealthCheck(String, Int32, Int32, String, String[], String, String, String[]) Task ExecuteTentacleUpgrade(String, String, String[], String, String, String[]) + Task GetActiveWithSummary(Int32, Int32) Task> GetAllActive(Int32) + Task GetAllWithSummary(Int32, Int32) Task GetDetails(Octopus.Client.Model.TaskResource, Nullable, Nullable) Task> GetQueuedBehindTasks(Octopus.Client.Model.TaskResource) Task GetRawOutputLog(Octopus.Client.Model.TaskResource) @@ -6626,6 +6639,7 @@ Octopus.Client.Repositories.Async Task Create(String, String, String, String) Task CreateApiKey(Octopus.Client.Model.UserResource, String) Task CreateServiceAccount(String, String) + Task FindByUsername(String) Task> GetApiKeys(Octopus.Client.Model.UserResource) Task GetCurrent() Task GetSpaces(Octopus.Client.Model.UserResource) diff --git a/source/Octopus.Client/Model/TaskResourceCollection.cs b/source/Octopus.Client/Model/TaskResourceCollection.cs new file mode 100644 index 000000000..3576c57f9 --- /dev/null +++ b/source/Octopus.Client/Model/TaskResourceCollection.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Octopus.Client.Extensibility; + +namespace Octopus.Client.Model +{ + public class TaskResourceCollection : ResourceCollection + { + public TaskResourceCollection(IEnumerable items, LinkCollection links) : base(items, links) + { + } + + public Dictionary TotalCounts { get; set; } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/Async/BasicRepository.cs b/source/Octopus.Client/Repositories/Async/BasicRepository.cs index 67a9165c0..62ab89774 100644 --- a/source/Octopus.Client/Repositories/Async/BasicRepository.cs +++ b/source/Octopus.Client/Repositories/Async/BasicRepository.cs @@ -176,7 +176,7 @@ protected virtual void EnrichSpaceId(TResource resource) } } - async Task ResolveLink() + protected async Task ResolveLink() { if (CollectionLinkName == null && getCollectionLinkName != null) CollectionLinkName = await getCollectionLinkName(Repository).ConfigureAwait(false); diff --git a/source/Octopus.Client/Repositories/Async/TaskRepository.cs b/source/Octopus.Client/Repositories/Async/TaskRepository.cs index 6c531d8f9..76377353e 100644 --- a/source/Octopus.Client/Repositories/Async/TaskRepository.cs +++ b/source/Octopus.Client/Repositories/Async/TaskRepository.cs @@ -20,7 +20,30 @@ public interface ITaskRepository : IPaginate, IGet, Task GetDetails(TaskResource resource, bool? includeVerboseOutput = null, int? tail = null); Task ExecuteActionTemplate(ActionTemplateResource resource, Dictionary properties, string[] machineIds = null, string[] environmentIds = null, string[] targetRoles = null, string description = null); Task ExecuteCommunityActionTemplatesSynchronisation(string description = null); + + /// + /// Gets all the active tasks (optionally limited to pageSize) + /// + /// Number of items per page, setting to less than the total items still retreives all items, but uses multiple requests reducing memory load on the server + /// Task> GetAllActive(int pageSize = int.MaxValue); + + /// + /// Returns all active tasks (optionally limited to pageSize) along with a count of all tasks in each status + /// + /// + /// + /// + Task GetActiveWithSummary(int pageSize = int.MaxValue, int skip = 0); + + /// + /// Returns all tasks (optionally limited to pageSize) along with a count of all tasks in each status + /// + /// + /// + /// + Task GetAllWithSummary(int pageSize = int.MaxValue, int skip = 0); + Task GetRawOutputLog(TaskResource resource); Task GetTaskTypes(); Task Rerun(TaskResource resource); @@ -261,13 +284,14 @@ public async Task WaitForCompletion(TaskResource[] tasks, int pollIntervalSecond } } - /// - /// - /// - /// Number of items per page, setting to less than the total items still retreives all items, but uses multiple requests reducing memory load on the server - /// public Task> GetAllActive(int pageSize = int.MaxValue) => FindAll(pathParameters: new { active = true, take = pageSize }); + public async Task GetActiveWithSummary(int pageSize = int.MaxValue, int skip = 0) + => await Client.Get(await ResolveLink(), new {active = true, take = pageSize, skip}); + + public async Task GetAllWithSummary(int pageSize = int.MaxValue, int skip = 0) + => await Client.Get(await ResolveLink(), new {take = pageSize, skip}); + public ITaskRepository UsingContext(SpaceContext spaceContext) { return new TaskRepository(Repository, spaceContext); diff --git a/source/Octopus.Client/Repositories/Async/UserRepository.cs b/source/Octopus.Client/Repositories/Async/UserRepository.cs index 74dbfd64b..80a77a828 100644 --- a/source/Octopus.Client/Repositories/Async/UserRepository.cs +++ b/source/Octopus.Client/Repositories/Async/UserRepository.cs @@ -13,6 +13,7 @@ public interface IUserRepository : IDelete, ICreate { + Task FindByUsername(string username); Task Create(string username, string displayName, string password = null, string emailAddress = null); Task CreateServiceAccount(string username, string displayName); Task Register(RegisterCommand registerCommand); @@ -40,6 +41,9 @@ public UserRepository(IOctopusAsyncRepository repository) invitations = new LegacyInvitationRepository(Repository); } + public Task FindByUsername(string username) + => FindOne(u => u.Username.Equals(username, StringComparison.CurrentCultureIgnoreCase), pathParameters: new {filter = username}); + public Task Create(string username, string displayName, string password = null, string emailAddress = null) { return Create(new UserResource diff --git a/source/Octopus.Client/Repositories/BasicRepository.cs b/source/Octopus.Client/Repositories/BasicRepository.cs index 21f8e061b..cab04814f 100644 --- a/source/Octopus.Client/Repositories/BasicRepository.cs +++ b/source/Octopus.Client/Repositories/BasicRepository.cs @@ -170,7 +170,7 @@ protected virtual void EnrichSpaceId(TResource resource) } } - string ResolveLink() + protected string ResolveLink() { if (CollectionLinkName == null && getCollectionLinkName != null) CollectionLinkName = getCollectionLinkName(Repository); diff --git a/source/Octopus.Client/Repositories/TaskRepository.cs b/source/Octopus.Client/Repositories/TaskRepository.cs index 34626cc27..23f7faf7a 100644 --- a/source/Octopus.Client/Repositories/TaskRepository.cs +++ b/source/Octopus.Client/Repositories/TaskRepository.cs @@ -19,7 +19,30 @@ public interface ITaskRepository : IPaginate, IGet, TaskResource ExecuteAdHocScript(string scriptBody, string[] machineIds = null, string[] environmentIds = null, string[] targetRoles = null, string description = null, string syntax = "PowerShell"); TaskResource ExecuteActionTemplate(ActionTemplateResource resource, Dictionary properties, string[] machineIds = null, string[] environmentIds = null, string[] targetRoles = null, string description = null); TaskResource ExecuteCommunityActionTemplatesSynchronisation(string description = null); + + /// + /// Gets all the active tasks (optionally limited to pageSize) + /// + /// Number of items per page, setting to less than the total items still retreives all items, but uses multiple requests reducing memory load on the server + /// List GetAllActive(int pageSize = Int32.MaxValue); + + /// + /// Returns all active tasks (optionally limited to pageSize) along with a count of all tasks in each status + /// + /// + /// + /// + TaskResourceCollection GetActiveWithSummary(int pageSize = int.MaxValue, int skip = 0); + + /// + /// Returns all tasks (optionally limited to pageSize) along with a count of all tasks in each status + /// + /// + /// + /// + TaskResourceCollection GetAllWithSummary(int pageSize = int.MaxValue, int skip = 0); + TaskDetailsResource GetDetails(TaskResource resource, bool? includeVerboseOutput = null, int? tail = null); string GetRawOutputLog(TaskResource resource); TaskTypeResource[] GetTaskTypes(); @@ -45,7 +68,7 @@ public TaskRepository(IOctopusRepository repository) } public TaskResource ExecuteHealthCheck( - string description = null, int timeoutAfterMinutes = 5, int machineTimeoutAfterMinutes = 1, string environmentId = null, string[] machineIds = null, + string description = null, int timeoutAfterMinutes = 5, int machineTimeoutAfterMinutes = 1, string environmentId = null, string[] machineIds = null, string restrictTo = null, string workerpoolId = null, string[] workerIds = null) { EnsureSingleSpaceContext(); @@ -140,7 +163,7 @@ public TaskResource ExecuteActionTemplate(ActionTemplateResource template, Dicti { if (string.IsNullOrEmpty(template?.Id)) throw new ArgumentException("The step template was either null, or has no ID"); - var resource = new TaskResource(){SpaceId = template.SpaceId}; + var resource = new TaskResource() {SpaceId = template.SpaceId}; resource.Name = BuiltInTasks.AdHocScript.Name; resource.Description = string.IsNullOrWhiteSpace(description) ? "Run step template: " + template.Name : description; resource.Arguments = new Dictionary @@ -191,19 +214,19 @@ public TaskTypeResource[] GetTaskTypes() public void Rerun(TaskResource resource) { EnsureTaskCanRunInTheCurrentContext(resource); - Client.Post(resource.Link("Rerun"), (TaskResource)null); + Client.Post(resource.Link("Rerun"), (TaskResource) null); } public void Cancel(TaskResource resource) { EnsureTaskCanRunInTheCurrentContext(resource); - Client.Post(resource.Link("Cancel"), (TaskResource)null); + Client.Post(resource.Link("Cancel"), (TaskResource) null); } public void ModifyState(TaskResource resource, TaskState newState, string reason) { EnsureTaskCanRunInTheCurrentContext(resource); - Client.Post(resource.Link("State"), new { state = newState, reason = reason }); + Client.Post(resource.Link("State"), new {state = newState, reason = reason}); } public IReadOnlyList GetQueuedBehindTasks(TaskResource resource) @@ -213,14 +236,14 @@ public IReadOnlyList GetQueuedBehindTasks(TaskResource resource) public void WaitForCompletion(TaskResource task, int pollIntervalSeconds = 4, int timeoutAfterMinutes = 0, Action interval = null) { - WaitForCompletion(new[] { task }, pollIntervalSeconds, timeoutAfterMinutes, interval); + WaitForCompletion(new[] {task}, pollIntervalSeconds, timeoutAfterMinutes, interval); } public void WaitForCompletion(TaskResource[] tasks, int pollIntervalSeconds = 4, int timeoutAfterMinutes = 0, Action interval = null) => WaitForCompletion(tasks, pollIntervalSeconds, TimeSpan.FromMinutes(timeoutAfterMinutes), interval); public void WaitForCompletion(TaskResource[] tasks, int pollIntervalSeconds = 4, TimeSpan? timeoutAfter = null, Action interval = null) - { + { var start = Stopwatch.StartNew(); if (tasks == null || tasks.Length == 0) return; @@ -228,9 +251,9 @@ public void WaitForCompletion(TaskResource[] tasks, int pollIntervalSeconds = 4, while (true) { var stillRunning = - (from task in tasks - let currentStatus = Client.Get(task.Link("Self"), AdditionalQueryParameters) - select currentStatus).ToArray(); + (from task in tasks + let currentStatus = Client.Get(task.Link("Self"), AdditionalQueryParameters) + select currentStatus).ToArray(); interval?.Invoke(stillRunning); @@ -246,12 +269,13 @@ public void WaitForCompletion(TaskResource[] tasks, int pollIntervalSeconds = 4, } } - /// - /// - /// - /// Number of items per page, setting to less than the total items still retreives all items, but uses multiple requests reducing memory load on the server - /// - public List GetAllActive(int pageSize = int.MaxValue) => FindAll(pathParameters: new { active = true, take = pageSize }); + public List GetAllActive(int pageSize = int.MaxValue) => FindAll(pathParameters: new {active = true, take = pageSize}); + + public TaskResourceCollection GetActiveWithSummary(int pageSize = int.MaxValue, int skip = 0) + => Client.Get(ResolveLink(), new {active = true, take = pageSize, skip}); + + public TaskResourceCollection GetAllWithSummary(int pageSize = int.MaxValue, int skip = 0) + => Client.Get(ResolveLink(), new {take = pageSize, skip}); public ITaskRepository UsingContext(SpaceContext userDefinedSpaceContext) { @@ -263,7 +287,7 @@ void EnsureTaskCanRunInTheCurrentContext(TaskResource task) if (string.IsNullOrEmpty(task.SpaceId)) return; var spaceContext = GetCurrentSpaceContext(); - + spaceContext.ApplySpaceSelection(spaces => { if (spaces.All(space => space.Id != task.SpaceId)) diff --git a/source/Octopus.Client/Repositories/UserRepository.cs b/source/Octopus.Client/Repositories/UserRepository.cs index 3b911632c..6fc43d461 100644 --- a/source/Octopus.Client/Repositories/UserRepository.cs +++ b/source/Octopus.Client/Repositories/UserRepository.cs @@ -13,6 +13,7 @@ public interface IUserRepository : IDelete, ICreate { + UserResource FindByUsername(string username); UserResource Create(string username, string displayName, string password = null, string emailAddress = null); UserResource CreateServiceAccount(string username, string displayName); UserResource Register(RegisterCommand registerCommand); @@ -40,6 +41,9 @@ public UserRepository(IOctopusRepository repository) invitations = new LegacyInvitationRepository(repository); } + public UserResource FindByUsername(string username) + => FindOne(u => u.Username.Equals(username, StringComparison.CurrentCultureIgnoreCase), pathParameters: new {filter = username}); + public UserResource Create(string username, string displayName, string password = null, string emailAddress = null) { return Create(new UserResource