예제 #1
0
        private IActionResult GetStatusResult(ICommandResult result)
        {
            if (result is null)
            {
                return(ErrorResult
                       .NotFound($"A status for the provided Tracking Id was not found.")
                       .ActionResult());
            }

            result.Links.TryGetValue("status", out var status);

            switch (result.RuntimeStatus)
            {
            case CommandRuntimeStatus.Completed:

                if (result.Links.TryGetValue("location", out var location))
                {
                    // return 302 (found) with location to resource
                    Response.Headers.Add("Location", location);
                    return(StatusResult
                           .Success(result.CommandId.ToString(), location, result.RuntimeStatus.ToString(), result.CustomStatus)
                           .ActionResult());
                }

                // no resource location (i.e. DELETE command) return 200 (ok)
                return(StatusResult
                       .Success(result.CommandId.ToString(), result.RuntimeStatus.ToString(), result.CustomStatus)
                       .ActionResult());

            case CommandRuntimeStatus.Running:
            case CommandRuntimeStatus.ContinuedAsNew:
            case CommandRuntimeStatus.Pending:

                // command is in an active state, return 202 (accepted) so client can poll
                return(StatusResult
                       .Accepted(result.CommandId.ToString(), status, result.RuntimeStatus.ToString(), result.CustomStatus)
                       .ActionResult());

            case CommandRuntimeStatus.Canceled:
            case CommandRuntimeStatus.Terminated:
            case CommandRuntimeStatus.Failed:

                return(StatusResult
                       .Failed(result.Errors, result.CommandId.ToString(), result.RuntimeStatus.ToString(), result.CustomStatus)
                       .ActionResult());

            default:     // TODO: this probably isn't right as a default

                if (result.Errors?.Any() ?? false)
                {
                    return(StatusResult
                           .Failed(result.Errors, result.CommandId.ToString(), result.RuntimeStatus.ToString(), result.CustomStatus)
                           .ActionResult());
                }

                return(StatusResult
                       .Ok(result.CommandId.ToString(), result.RuntimeStatus.ToString(), result.CustomStatus)
                       .ActionResult());
            }
        }
예제 #2
0
        public async Task <IActionResult> Post([FromBody] UserDefinition userDefinition)
        {
            if (userDefinition is null)
            {
                throw new ArgumentNullException(nameof(userDefinition));
            }

            var validation = new UserDefinitionValidator().Validate(userDefinition);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var teamCloudInstance = await teamCloudRepository
                                    .GetAsync()
                                    .ConfigureAwait(false);

            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound($"No TeamCloud Instance was found.")
                       .ActionResult());
            }

            var newUser = await userService
                          .GetUserAsync(userDefinition)
                          .ConfigureAwait(false);

            if (newUser is null)
            {
                return(ErrorResult
                       .NotFound($"A User with the Email '{userDefinition.Email}' could not be found.")
                       .ActionResult());
            }

            if (teamCloudInstance.Users.Contains(newUser))
            {
                return(ErrorResult
                       .Conflict($"A User with the Email '{userDefinition.Email}' already exists on this TeamCloud Instance. Please try your request again with a unique email or call PUT to update the existing User.")
                       .ActionResult());
            }

            var command = new OrchestratorTeamCloudUserCreateCommand(CurrentUser, newUser);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shouldn't happen, but we need to decide to do when it does.");
        }
예제 #3
0
        public async Task <IActionResult> Delete([FromRoute] string userNameOrId)
        {
            if (string.IsNullOrWhiteSpace(userNameOrId))
            {
                return(ErrorResult
                       .BadRequest($"The identifier '{userNameOrId}' provided in the url path is invalid.  Must be a valid email address or GUID.", ResultErrorCode.ValidationError)
                       .ActionResult());
            }

            var teamCloudInstance = await teamCloudRepository
                                    .GetAsync()
                                    .ConfigureAwait(false);

            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound($"No TeamCloud Instance was found.")
                       .ActionResult());
            }

            if (!Guid.TryParse(userNameOrId, out var userId))
            {
                var idLookup = await userService
                               .GetUserIdAsync(userNameOrId)
                               .ConfigureAwait(false);

                if (!idLookup.HasValue || idLookup.Value == Guid.Empty)
                {
                    return(ErrorResult
                           .NotFound($"A User with the email '{userNameOrId}' could not be found.")
                           .ActionResult());
                }

                userId = idLookup.Value;
            }

            var user = teamCloudInstance.Users?.FirstOrDefault(u => u.Id == userId);

            if (user is null)
            {
                return(ErrorResult
                       .NotFound($"The specified User could not be found in this TeamCloud Instance.")
                       .ActionResult());
            }

            var command = new OrchestratorTeamCloudUserDeleteCommand(CurrentUser, user);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shoudn't happen, but we need to decide to do when it does.");
        }
예제 #4
0
        public async Task <IActionResult> Put([FromBody] User user)
        {
            if (user is null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var validation = new UserValidator().Validate(user);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var teamCloudInstance = await teamCloudRepository
                                    .GetAsync()
                                    .ConfigureAwait(false);

            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound($"No TeamCloud Instance was found.")
                       .ActionResult());
            }

            var oldUser = teamCloudInstance.Users?.FirstOrDefault(u => u.Id == user.Id);

            if (oldUser is null)
            {
                return(ErrorResult
                       .NotFound($"A User with the ID '{oldUser.Id}' could not be found on this TeamCloud Instance.")
                       .ActionResult());
            }

            if (oldUser.IsAdmin() && !user.IsAdmin() && teamCloudInstance.Users.Count(u => u.IsAdmin()) == 1)
            {
                return(ErrorResult
                       .BadRequest($"The TeamCloud instance must have at least one Admin user. To change this user's role you must first add another Admin user.", ResultErrorCode.ValidationError)
                       .ActionResult());
            }

            var command = new OrchestratorTeamCloudUserUpdateCommand(CurrentUser, user);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shouldn't happen, but we need to decide to do when it does.");
        }
        public async Task <IActionResult> Put([FromBody] User user)
        {
            if (!ProjectId.HasValue)
            {
                return(ErrorResult
                       .BadRequest($"Project Id provided in the url path is invalid.  Must be a valid GUID.", ResultErrorCode.ValidationError)
                       .ActionResult());
            }

            var validation = new UserValidator().Validate(user);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var project = await projectsRepository
                          .GetAsync(ProjectId.Value)
                          .ConfigureAwait(false);

            if (project is null)
            {
                return(ErrorResult
                       .NotFound($"A Project with the ID '{ProjectId.Value}' could not be found in this TeamCloud Instance.")
                       .ActionResult());
            }

            var oldUser = project?.Users?.FirstOrDefault(u => u.Id == user.Id);

            if (oldUser is null)
            {
                return(ErrorResult
                       .NotFound($"A User with the ID '{oldUser.Id}' could not be found on this Project.")
                       .ActionResult());
            }

            var command = new OrchestratorProjectUserUpdateCommand(CurrentUser, user, ProjectId.Value);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shoudn't happen, but we need to decide to do when it does.");
        }
예제 #6
0
        public async Task <IActionResult> Put([FromBody] Provider provider)
        {
            if (provider is null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            var validation = new ProviderValidator().Validate(provider);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var teamCloudInstance = await teamCloudRepository
                                    .GetAsync()
                                    .ConfigureAwait(false);

            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound($"No TeamCloud Instance was found.")
                       .ActionResult());
            }

            var oldProvider = teamCloudInstance.Providers?.FirstOrDefault(p => p.Id == provider.Id);

            if (oldProvider is null)
            {
                return(ErrorResult
                       .NotFound($"A Provider with the ID '{provider.Id}' could not be found on this TeamCloud Instance.")
                       .ActionResult());
            }

            var command = new OrchestratorProviderUpdateCommand(CurrentUser, provider);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shoudn't happen, but we need to decide to do when it does.");
        }
예제 #7
0
        public async Task <IActionResult> Delete(string projectNameOrId)
        {
            if (string.IsNullOrWhiteSpace(projectNameOrId))
            {
                return(ErrorResult
                       .BadRequest($"The identifier '{projectNameOrId}' provided in the url path is invalid.  Must be a valid project name or GUID.", ResultErrorCode.ValidationError)
                       .ActionResult());
            }

            Project project;

            if (Guid.TryParse(projectNameOrId, out var projectId))
            {
                project = await projectsRepository
                          .GetAsync(projectId)
                          .ConfigureAwait(false);
            }
            else
            {
                project = await projectsRepository
                          .GetAsync(projectNameOrId)
                          .ConfigureAwait(false);
            }

            if (project is null)
            {
                return(ErrorResult
                       .NotFound($"A Project with the identifier '{projectNameOrId}' could not be found in this TeamCloud Instance")
                       .ActionResult());
            }

            var command = new OrchestratorProjectDeleteCommand(CurrentUser, project);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shouldn't happen, but we need to decide to do when it does.");
        }
예제 #8
0
        public async Task <IActionResult> Post([FromBody] TeamCloudConfiguration teamCloudConfiguraiton)
        {
            var validation = new TeamCloudConfigurationValidator().Validate(teamCloudConfiguraiton);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var teamCloudInstance = await teamCloudRepository
                                    .GetAsync()
                                    .ConfigureAwait(false);

            if (teamCloudInstance != null)
            {
                return(ErrorResult
                       .Conflict("A TeamCloud Instance already existis.")
                       .ActionResult());
            }

            var command = new OrchestratorTeamCloudCreateCommand(CurrentUser, teamCloudConfiguraiton);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shoudn't happen, but we need to decide to do when it does.");
        }
예제 #9
0
        public async Task <IActionResult> Delete(string providerId)
        {
            var teamCloudInstance = await teamCloudRepository
                                    .GetAsync()
                                    .ConfigureAwait(false);

            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound($"No TeamCloud Instance was found.")
                       .ActionResult());
            }

            var provider = teamCloudInstance.Providers?.FirstOrDefault(p => p.Id == providerId);

            if (provider is null)
            {
                return(ErrorResult
                       .NotFound($"A Provider with the ID '{providerId}' could not be found on this TeamCloud Instance.")
                       .ActionResult());
            }

            // TODO: Query via the database query instead of getting all
            var projectTypes = await projectTypesRepository
                               .ListAsync()
                               .ToListAsync()
                               .ConfigureAwait(false);

            if (projectTypes.Any(pt => pt.Providers.Any(pr => pr.Id == providerId)))
            {
                return(ErrorResult
                       .BadRequest("Cannot delete Providers referenced in existing ProjectType definitions", ResultErrorCode.ValidationError)
                       .ActionResult());
            }

            // TODO: Query via the database query instead of getting all
            var projects = await projectsRepository
                           .ListAsync()
                           .ToListAsync()
                           .ConfigureAwait(false);

            if (projects.Any(p => p.Type.Providers.Any(pr => pr.Id == providerId)))
            {
                if (projectTypes.Any(pt => pt.Providers.Any(pr => pr.Id == providerId)))
                {
                    return(ErrorResult
                           .BadRequest("Cannot delete Providers being used by existing Projects", ResultErrorCode.ValidationError)
                           .ActionResult());
                }
            }

            var command = new OrchestratorProviderDeleteCommand(CurrentUser, provider);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shoudn't happen, but we need to decide to do when it does.");
        }
예제 #10
0
        public async Task <IActionResult> Post([FromBody] ProjectDefinition projectDefinition)
        {
            if (projectDefinition is null)
            {
                throw new ArgumentNullException(nameof(projectDefinition));
            }

            var validation = new ProjectDefinitionValidator().Validate(projectDefinition);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var users = await ResolveUsersAsync(projectDefinition)
                        .ConfigureAwait(false);

            var nameExists = await projectsRepository
                             .NameExistsAsync(projectDefinition.Name)
                             .ConfigureAwait(false);

            if (nameExists)
            {
                return(ErrorResult
                       .Conflict($"A Project with name '{projectDefinition.Name}' already exists. Project names must be unique. Please try your request again with a unique name.")
                       .ActionResult());
            }

            var project = new Project
            {
                Id    = Guid.NewGuid(),
                Users = users,
                Name  = projectDefinition.Name,
                Tags  = projectDefinition.Tags
            };

            if (!string.IsNullOrEmpty(projectDefinition.ProjectType))
            {
                project.Type = await projectTypesRepository
                               .GetAsync(projectDefinition.ProjectType)
                               .ConfigureAwait(false);

                if (project.Type is null)
                {
                    return(ErrorResult
                           .BadRequest(new ValidationError {
                        Field = "projectType", Message = $"A Project Type with the ID '{projectDefinition.ProjectType}' could not be found in this TeamCloud Instance. Please try your request again with a valid Project Type ID for 'projectType'."
                    })
                           .ActionResult());
                }
            }
            else
            {
                project.Type = await projectTypesRepository
                               .GetDefaultAsync()
                               .ConfigureAwait(false);

                if (project.Type is null)
                {
                    return(ErrorResult
                           .BadRequest(new ValidationError {
                        Field = "projectType", Message = $"No value was provided for 'projectType' and there is no a default Project Type set for this TeamCloud Instance. Please try your request again with a valid Project Type ID for 'projectType'."
                    })
                           .ActionResult());
                }
            }

            var command = new OrchestratorProjectCreateCommand(CurrentUser, project);

            var commandResult = await orchestrator
                                .InvokeAsync(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(StatusResult
                       .Accepted(commandResult.CommandId.ToString(), statusUrl, commandResult.RuntimeStatus.ToString(), commandResult.CustomStatus)
                       .ActionResult());
            }

            throw new Exception("This shouldn't happen, but we need to decide to do when it does.");
        }