Refactor code structure for improved readability and maintainability

This commit is contained in:
Torsten Brendgen
2026-05-16 16:45:28 +02:00
parent 14f856fdb3
commit 96a3e98109
426 changed files with 29236 additions and 114 deletions

View File

@@ -5,12 +5,14 @@ using Microsoft.SelfService.Portal.Core.API.Dto.Deployment.Get;
using Microsoft.SelfService.Portal.Core.API.Dto.Deployment.Edit;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Events.Interfaces;
using System.Reflection;
using System.Collections;
using System.Dynamic;
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
namespace Microsoft.SelfService.Portal.Core.API.Controllers
{
@@ -19,12 +21,21 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
public class DeploymentController : Controller
{
private readonly IDeploymentInterface _deploymentInterface;
private readonly IQueueJobService _queueJobService;
private readonly DataContext _context;
private readonly IMapper _mapper;
private readonly IEventHandlerInterface _eventHandlerInterface;
public DeploymentController(IDeploymentInterface deploymentInterface, IMapper mapper, IEventHandlerInterface eventHandlerInterface)
public DeploymentController(
IDeploymentInterface deploymentInterface,
IQueueJobService queueJobService,
DataContext context,
IMapper mapper,
IEventHandlerInterface eventHandlerInterface)
{
_deploymentInterface = deploymentInterface;
_queueJobService = queueJobService;
_context = context;
_mapper = mapper;
_eventHandlerInterface = eventHandlerInterface;
}
@@ -81,6 +92,163 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
return Ok(deploymentMap.Id);
}
[HttpPost("Request")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
public IActionResult AddDeploymentRequest([FromBody] AddDeploymentRequestDto request)
{
if (request == null)
return BadRequest(ModelState);
if (request.VirtualMachineIds == null || request.VirtualMachineIds.Count == 0)
{
ModelState.AddModelError("", "At least one VirtualMachine must be selected.");
return BadRequest(ModelState);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
try
{
var queueJobId = _queueJobService.EnqueueDeploymentRequest(
request.DeploymentGroupId,
request.VirtualMachineIds,
request.JsonData);
return Ok(queueJobId);
}
catch (InvalidOperationException ex)
{
ModelState.AddModelError("", ex.Message);
return BadRequest(ModelState);
}
}
[HttpGet("QueueJobs")]
[ProducesResponseType(200, Type = typeof(IEnumerable<GetQueueJobDto>))]
public IActionResult GetQueueJobs()
{
var queueJobs = _context.QueueJobs
.AsNoTracking()
.Include(job => job.Targets)
.Include(job => job.Steps)
.OrderByDescending(job => job.Created)
.Select(job => new GetQueueJobDto
{
Id = job.Id,
Type = job.Type,
Status = job.Status,
Attempts = job.Attempts,
MaxAttempts = job.MaxAttempts,
Started = job.Started,
Finished = job.Finished,
ErrorMessage = job.ErrorMessage,
TargetCount = job.Targets.Count,
SucceededTargetCount = job.Targets.Count(target => target.Status == QueueJobStatus.Succeeded),
FailedTargetCount = job.Targets.Count(target => target.Status == QueueJobStatus.Failed)
})
.ToList();
return Ok(queueJobs);
}
[HttpGet("QueueJobs/{Id}")]
[ProducesResponseType(200, Type = typeof(GetQueueJobDetailsDto))]
[ProducesResponseType(404)]
public IActionResult GetQueueJobById(Guid Id)
{
var queueJob = _context.QueueJobs
.AsNoTracking()
.Include(job => job.Targets)
.Include(job => job.Steps)
.FirstOrDefault(job => job.Id == Id);
if (queueJob == null)
return NotFound();
var details = new GetQueueJobDetailsDto
{
Id = queueJob.Id,
Type = queueJob.Type,
Status = queueJob.Status,
PayloadJson = queueJob.PayloadJson,
Attempts = queueJob.Attempts,
MaxAttempts = queueJob.MaxAttempts,
Started = queueJob.Started,
Finished = queueJob.Finished,
ErrorMessage = queueJob.ErrorMessage,
MetadataJson = queueJob.MetadataJson,
RuleSnapshotJson = queueJob.RuleSnapshotJson,
Created = queueJob.Created,
CreatedBy = queueJob.CreatedBy,
Modified = queueJob.Modified,
ModifiedBy = queueJob.ModifiedBy,
Targets = queueJob.Targets.Select(target => new GetQueueJobTargetDto
{
Id = target.Id,
VirtualMachineId = target.VirtualMachineId,
DeploymentGroupId = target.DeploymentGroupId,
TemplateId = target.TemplateId,
Status = target.Status,
Attempts = target.Attempts,
ErrorMessage = target.ErrorMessage
}).ToList(),
Steps = queueJob.Steps
.OrderBy(step => step.SortOrder)
.Select(step => new GetQueueJobStepDto
{
Id = step.Id,
DependsOnQueueJobStepId = step.DependsOnQueueJobStepId,
SortOrder = step.SortOrder,
Name = step.Name,
StepType = step.StepType,
Status = step.Status,
MetadataJson = step.MetadataJson,
ApprovedAt = step.ApprovedAt,
ApprovedBy = step.ApprovedBy,
ApprovalComment = step.ApprovalComment
}).ToList()
};
return Ok(details);
}
[HttpPost("QueueJobs/{Id}/Retry")]
[ProducesResponseType(204)]
[ProducesResponseType(404)]
public IActionResult RetryQueueJob(Guid Id)
{
if (!_queueJobService.RetryQueueJob(Id))
return NotFound();
return NoContent();
}
[HttpPost("QueueJobs/Steps/{stepId}/Approve")]
[ProducesResponseType(204)]
[ProducesResponseType(404)]
public IActionResult ApproveQueueJobStep(Guid stepId, [FromBody] QueueJobStepApprovalDto? payload)
{
var approvedBy = payload?.ApprovedBy ?? User?.Identity?.Name ?? "System";
if (!_queueJobService.ApproveQueueJobStep(stepId, approvedBy, payload?.Comment))
return NotFound();
return NoContent();
}
[HttpPost("QueueJobs/Steps/{stepId}/Reject")]
[ProducesResponseType(204)]
[ProducesResponseType(404)]
public IActionResult RejectQueueJobStep(Guid stepId, [FromBody] QueueJobStepApprovalDto? payload)
{
var approvedBy = payload?.ApprovedBy ?? User?.Identity?.Name ?? "System";
if (!_queueJobService.RejectQueueJobStep(stepId, approvedBy, payload?.Comment))
return NotFound();
return NoContent();
}
[HttpDelete("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]

View File

@@ -65,7 +65,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
var deploymentgroupMap = _mapper.Map<DeploymentGroupModel>(deploymentgroup);
if (!_deploymentgroupInterface.AddDeploymentGroupById(deploymentgroupMap))
if (!_deploymentgroupInterface.AddDeploymentGroupById(deploymentgroupMap, deploymentgroup.VirtualMachineIds))
{
ModelState.AddModelError("", "Something went wrong while saving");
return StatusCode(500, ModelState);

View File

@@ -139,7 +139,8 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
if (!_environmentInterface.CheckEnvironmentById(Id))
return NotFound();
var environment = _mapper.Map<GetEnvironmentDomainDto>(_environmentInterface.GetLinkedDomainsByEnvironmentId(Id));
var environment = GetEnvironmentDomainDto.FromModel(
_environmentInterface.GetLinkedDomainsByEnvironmentId(Id));
if (!ModelState.IsValid)
return BadRequest(ModelState);

View File

@@ -1,8 +1,9 @@
using AutoMapper;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.SelfService.Portal.Core.API.Dto.Service.Add;
using Microsoft.SelfService.Portal.Core.API.Dto.Service.Edit;
using Microsoft.SelfService.Portal.Core.API.Dto.Service.Get;
using Microsoft.SelfService.Portal.Core.API.Events;
using Microsoft.SelfService.Portal.Core.API.Events.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Dto.Service.RoleDefinition;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
@@ -32,20 +33,210 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
return Ok(services);
}
[HttpGet("{Id}")]
[ProducesResponseType(200, Type = typeof(ServiceModel))]
[ProducesResponseType(404)]
public IActionResult GetServiceById(Guid Id)
{
if(!_serviceInterface.CheckServiceById(Id))
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
var service = _mapper.Map<GetServiceDetailsDto>(_serviceInterface.GetServiceById(Id));
if(!ModelState.IsValid)
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(service);
}
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
public IActionResult AddServiceById([FromBody] AddServiceDto service)
{
if (service == null)
return BadRequest(ModelState);
if (_serviceInterface.CheckServiceByName(service.Name))
{
ModelState.AddModelError("", "Service already exists");
return StatusCode(422, ModelState);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
var serviceMap = _mapper.Map<ServiceModel>(service);
if (!_serviceInterface.AddServiceById(serviceMap))
{
ModelState.AddModelError("", "Something went wrong while saving");
return StatusCode(500, ModelState);
}
return Ok(serviceMap.Id);
}
[HttpPut("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult EditServiceById(Guid Id, [FromBody] EditServiceDto service)
{
if (service == null)
return BadRequest(ModelState);
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var serviceMap = _mapper.Map<ServiceModel>(service);
serviceMap.Id = Id;
if (!_serviceInterface.EditServiceById(serviceMap))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpDelete("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult DeleteServiceById(Guid Id)
{
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var service = _serviceInterface.GetServiceById(Id);
if (!_serviceInterface.DeleteServiceById(service))
{
ModelState.AddModelError("", "Something went wrong while deleting");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpGet("{Id}/RoleDefinitions")]
[ProducesResponseType(200, Type = typeof(IEnumerable<ServiceRoleDefinitionModel>))]
[ProducesResponseType(404)]
public IActionResult GetRoleDefinitionsByServiceId(Guid Id)
{
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
var roleDefinitions = _serviceInterface.GetRoleDefinitionsByServiceId(Id);
return Ok(roleDefinitions);
}
[HttpPost("{Id}/RoleDefinitions")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult AddRoleDefinition(Guid Id, [FromBody] AddServiceRoleDefinitionDto roleDefinition)
{
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
if (roleDefinition == null)
return BadRequest(ModelState);
var service = _serviceInterface.GetServiceById(Id);
if (service.IsCloudService)
return BadRequest("Role definitions are not supported for cloud services.");
if (_serviceInterface.CheckRoleDefinitionKey(Id, roleDefinition.Key))
return Conflict("Role key already exists for this service.");
var roleDefinitionModel = new ServiceRoleDefinitionModel
{
ServiceId = Id,
Key = roleDefinition.Key,
Name = roleDefinition.Name,
Description = roleDefinition.Description
};
if (!_serviceInterface.AddRoleDefinition(roleDefinitionModel))
{
ModelState.AddModelError("", "Something went wrong while saving role definition");
return StatusCode(500, ModelState);
}
return Ok(roleDefinitionModel.Id);
}
[HttpPut("{Id}/RoleDefinitions/{RoleDefinitionId}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult EditRoleDefinition(Guid Id, Guid RoleDefinitionId, [FromBody] EditServiceRoleDefinitionDto roleDefinition)
{
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
if (!_serviceInterface.CheckRoleDefinitionById(RoleDefinitionId))
return NotFound();
if (roleDefinition == null)
return BadRequest(ModelState);
var service = _serviceInterface.GetServiceById(Id);
if (service.IsCloudService)
return BadRequest("Role definitions are not supported for cloud services.");
if (_serviceInterface.CheckRoleDefinitionKey(Id, roleDefinition.Key, RoleDefinitionId))
return Conflict("Role key already exists for this service.");
var roleDefinitionModel = _serviceInterface.GetRoleDefinitionById(RoleDefinitionId);
if (roleDefinitionModel.ServiceId != Id)
return BadRequest("Role definition does not belong to this service.");
roleDefinitionModel.Key = roleDefinition.Key;
roleDefinitionModel.Name = roleDefinition.Name;
roleDefinitionModel.Description = roleDefinition.Description;
if (!_serviceInterface.EditRoleDefinition(roleDefinitionModel))
{
ModelState.AddModelError("", "Something went wrong while updating role definition");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpDelete("{Id}/RoleDefinitions/{RoleDefinitionId}")]
[ProducesResponseType(204)]
[ProducesResponseType(404)]
public IActionResult DeleteRoleDefinition(Guid Id, Guid RoleDefinitionId)
{
if (!_serviceInterface.CheckServiceById(Id))
return NotFound();
if (!_serviceInterface.CheckRoleDefinitionById(RoleDefinitionId))
return NotFound();
var roleDefinitionModel = _serviceInterface.GetRoleDefinitionById(RoleDefinitionId);
if (roleDefinitionModel.ServiceId != Id)
return BadRequest("Role definition does not belong to this service.");
if (!_serviceInterface.DeleteRoleDefinition(roleDefinitionModel))
{
ModelState.AddModelError("", "Something went wrong while deleting role definition");
return StatusCode(500, ModelState);
}
return NoContent();
}
}
}

View File

@@ -0,0 +1,130 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateCategory.Add;
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateCategory.Edit;
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateCategory.Get;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TemplateCategoryController : Controller
{
private readonly IMapper _mapper;
private readonly ITemplateCategoryInterface _templateCategoryInterface;
public TemplateCategoryController(IMapper mapper, ITemplateCategoryInterface templateCategoryInterface)
{
_mapper = mapper;
_templateCategoryInterface = templateCategoryInterface;
}
[HttpGet]
[ProducesResponseType(200, Type = typeof(IEnumerable<TemplateCategoryModel>))]
public IActionResult GetTemplateCategories()
{
var templateCategories = _mapper.Map<List<GetTemplateCategoryDto>>(_templateCategoryInterface.GetTemplateCategories());
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(templateCategories);
}
[HttpGet("{Id}")]
[ProducesResponseType(200, Type = typeof(TemplateCategoryModel))]
[ProducesResponseType(404)]
public IActionResult GetTemplateCategoryById(Guid Id)
{
if (!_templateCategoryInterface.CheckTemplateCategoryById(Id))
return NotFound();
var templateCategory = _mapper.Map<GetTemplateCategoryDetailsDto>(_templateCategoryInterface.GetTemplateCategoryById(Id));
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(templateCategory);
}
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
public IActionResult AddTemplateCategoryById([FromBody] AddTemplateCategoryDto templateCategory)
{
if (templateCategory == null)
return BadRequest(ModelState);
if (_templateCategoryInterface.CheckTemplateCategoryByName(templateCategory.Name))
{
ModelState.AddModelError("", "TemplateCategory already exists");
return StatusCode(422, ModelState);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
var templateCategoryMap = _mapper.Map<TemplateCategoryModel>(templateCategory);
if (!_templateCategoryInterface.AddTemplateCategoryById(templateCategoryMap))
{
ModelState.AddModelError("", "Something went wrong while saving");
return StatusCode(500, ModelState);
}
return Ok(templateCategoryMap.Id);
}
[HttpPut("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult EditTemplateCategoryById(Guid Id, [FromBody] EditTemplateCategoryDto templateCategory)
{
if (templateCategory == null)
return BadRequest(ModelState);
if (!_templateCategoryInterface.CheckTemplateCategoryById(Id))
return NotFound();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var templateCategoryMap = _mapper.Map<TemplateCategoryModel>(templateCategory);
templateCategoryMap.Id = Id;
if (!_templateCategoryInterface.EditTemplateCategoryById(templateCategoryMap))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpDelete("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult DeleteTemplateCategoryById(Guid Id)
{
if (!_templateCategoryInterface.CheckTemplateCategoryById(Id))
return NotFound();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var templateCategory = _templateCategoryInterface.GetTemplateCategoryById(Id);
if (!_templateCategoryInterface.DeleteTemplateCategoryById(templateCategory))
{
ModelState.AddModelError("", "Something went wrong while deleting");
return StatusCode(500, ModelState);
}
return NoContent();
}
}
}

View File

@@ -1,10 +1,10 @@
using AutoMapper;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.SelfService.Portal.Core.API.Dto.Service.Get;
using Microsoft.SelfService.Portal.Core.API.Dto.Template.Add;
using Microsoft.SelfService.Portal.Core.API.Dto.Template.Edit;
using Microsoft.SelfService.Portal.Core.API.Dto.Template.Get;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
using System.Reflection;
namespace Microsoft.SelfService.Portal.Core.API.Controllers
{
@@ -13,11 +13,16 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
public class TemplateController : Controller
{
private readonly ITemplateInterface _templateInterface;
private readonly IQueueJobService _queueJobService;
private readonly IMapper _mapper;
public TemplateController(ITemplateInterface templateInterface, IMapper mapper)
public TemplateController(
ITemplateInterface templateInterface,
IQueueJobService queueJobService,
IMapper mapper)
{
_templateInterface = templateInterface;
_queueJobService = queueJobService;
_mapper = mapper;
}
@@ -35,6 +40,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
[HttpGet("{Id}")]
[ProducesResponseType(200, Type = typeof(TemplateModel))]
[ProducesResponseType(404)]
public IActionResult GetTemplateById(Guid Id)
{
if (!_templateInterface.CheckTemplateById(Id))
@@ -47,5 +53,90 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
return Ok(template);
}
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
public IActionResult AddTemplateById([FromBody] AddTemplateDto template)
{
if (template == null)
return BadRequest(ModelState);
if (_templateInterface.CheckTemplateByName(template.Name))
{
ModelState.AddModelError("", "Template already exists");
return StatusCode(422, ModelState);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
var templateMap = _mapper.Map<TemplateModel>(template);
if (!_templateInterface.AddTemplateById(templateMap))
{
ModelState.AddModelError("", "Something went wrong while saving");
return StatusCode(500, ModelState);
}
return Ok(templateMap.Id);
}
[HttpPut("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult EditTemplateById(Guid Id, [FromBody] EditTemplateDto template)
{
if (template == null)
return BadRequest(ModelState);
if (!_templateInterface.CheckTemplateById(Id))
return NotFound();
var existingTemplate = _templateInterface.GetTemplateById(Id);
if (!ModelState.IsValid)
return BadRequest(ModelState);
var templateMap = _mapper.Map<TemplateModel>(template);
templateMap.Id = Id;
if (!_templateInterface.EditTemplateById(templateMap))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
if (!string.Equals(existingTemplate.JSONData, template.JSONData, StringComparison.Ordinal))
{
_queueJobService.EnqueueTemplateJsonChanged(Id, existingTemplate.JSONData, template.JSONData);
}
return NoContent();
}
[HttpDelete("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult DeleteTemplateById(Guid Id)
{
if (!_templateInterface.CheckTemplateById(Id))
return NotFound();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var template = _templateInterface.GetTemplateById(Id);
if (!_templateInterface.DeleteTemplateById(template))
{
ModelState.AddModelError("", "Something went wrong while deleting");
return StatusCode(500, ModelState);
}
return NoContent();
}
}
}

View File

@@ -1,5 +1,7 @@
using AutoMapper;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.SelfService.Portal.Core.API.Dto.VirtualMachine.Add;
using Microsoft.SelfService.Portal.Core.API.Dto.VirtualMachine.Edit;
using Microsoft.SelfService.Portal.Core.API.Dto.VirtualMachine.Get;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
@@ -9,13 +11,15 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
[Route("api/[controller]")]
[ApiController]
public class VirtualMachineController : Controller
{
{
private readonly IVirtualMachineInterface _virtualmachineInterface;
private readonly IDomainInterface _domainInterface;
private readonly IMapper _mapper;
public VirtualMachineController(IVirtualMachineInterface virtualmachineInterface, IMapper mapper)
public VirtualMachineController(IVirtualMachineInterface virtualmachineInterface, IDomainInterface domainInterface, IMapper mapper)
{
_virtualmachineInterface = virtualmachineInterface;
_domainInterface = domainInterface;
_mapper = mapper;
}
@@ -23,12 +27,12 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
[ProducesResponseType(200, Type = typeof(IEnumerable<VirtualMachineModel>))]
public IActionResult GetVirtualMachines()
{
var virtualmachines = _mapper.Map<List<GetVirtualMachineDto>>(_virtualmachineInterface.GetVirtualMachines());
var virtualMachines = _mapper.Map<List<GetVirtualMachineDto>>(_virtualmachineInterface.GetVirtualMachines());
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(virtualmachines);
return Ok(virtualMachines);
}
[HttpGet("{Id}")]
@@ -36,16 +40,161 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
[ProducesResponseType(400)]
public IActionResult GetVirtualMachineById(Guid Id)
{
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
return NotFound();
var virtualMachine = _mapper.Map<GetVirtualMachineDetailsDto>(_virtualmachineInterface.GetVirtualMachineById(Id));
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(virtualMachine);
}
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
public IActionResult AddVirtualMachineById([FromBody] AddVirtualMachineDto virtualMachine)
{
if (virtualMachine == null)
return BadRequest(ModelState);
if (_virtualmachineInterface.CheckVirtualMachineByName(virtualMachine.Name))
{
ModelState.AddModelError("", "VirtualMachine already exists");
return StatusCode(422, ModelState);
}
if (virtualMachine.DomainID.HasValue && !_domainInterface.CheckDomainById(virtualMachine.DomainID.Value))
{
ModelState.AddModelError("", "Domain does not exist");
return BadRequest(ModelState);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
var virtualMachineMap = _mapper.Map<VirtualMachineModel>(virtualMachine);
if (!_virtualmachineInterface.AddVirtualMachineById(virtualMachineMap))
{
ModelState.AddModelError("", "Something went wrong while saving");
return StatusCode(500, ModelState);
}
return Ok(virtualMachineMap.Id);
}
[HttpPut("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult EditVirtualMachineById(Guid Id, [FromBody] EditVirtualMachineDto virtualMachine)
{
if (virtualMachine == null)
return BadRequest(ModelState);
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
return NotFound();
var virtualmachines = _mapper.Map<GetVirtualMachineDetailsDto>(_virtualmachineInterface.GetVirtualMachineById(Id));
if(!ModelState.IsValid)
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(virtualmachines);
var existingVirtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
if (existingVirtualMachine == null)
return NotFound();
existingVirtualMachine.Name = virtualMachine.Name;
existingVirtualMachine.ExternalId = virtualMachine.ExternalId;
existingVirtualMachine.MetadataJson = virtualMachine.MetadataJson;
if (!_virtualmachineInterface.EditVirtualMachineById(existingVirtualMachine))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpPost("{Id}/Domain/{domainId}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(409)]
public IActionResult LinkVirtualMachineToDomain(Guid Id, Guid domainId)
{
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
return NotFound();
if (!_domainInterface.CheckDomainById(domainId))
return NotFound();
var existingVirtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
if (existingVirtualMachine == null)
return NotFound();
if (existingVirtualMachine.DomainID.HasValue)
return Conflict("VirtualMachine is already linked to a domain. Unlink it first.");
existingVirtualMachine.DomainID = domainId;
if (!_virtualmachineInterface.EditVirtualMachineById(existingVirtualMachine))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpDelete("{Id}/Domain")]
[ProducesResponseType(204)]
[ProducesResponseType(404)]
public IActionResult UnlinkVirtualMachineFromDomain(Guid Id)
{
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
return NotFound();
var existingVirtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
if (existingVirtualMachine == null)
return NotFound();
if (!existingVirtualMachine.DomainID.HasValue)
return NoContent();
existingVirtualMachine.DomainID = null;
if (!_virtualmachineInterface.EditVirtualMachineById(existingVirtualMachine))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
return NoContent();
}
[HttpDelete("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult DeleteVirtualMachineById(Guid Id)
{
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
return NotFound();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var virtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
if (!_virtualmachineInterface.DeleteVirtualMachineById(virtualMachine))
{
ModelState.AddModelError("", "Something went wrong while deleting");
return StatusCode(500, ModelState);
}
return NoContent();
}
}
}