Refactor code structure for improved readability and maintainability

This commit is contained in:
Torsten Brendgen
2026-07-07 23:27:57 +02:00
parent 96a3e98109
commit bbe521b38d
1632 changed files with 27313 additions and 54917 deletions
+147
View File
@@ -0,0 +1,147 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
{
public class DeploymentBatchRepository : IDeploymentBatchInterface
{
private readonly DataContext _context;
public DeploymentBatchRepository(DataContext context)
{
_context = context;
}
public ICollection<DeploymentGroupModel> GetDeploymentBatches()
{
return _context.DeploymentGroups.ToList();
}
public DeploymentGroupModel? GetDeploymentBatchById(Guid id)
{
return _context.DeploymentGroups
.Include(t => t.Template)
.ThenInclude(tc => tc.TemplateCategory)
.ThenInclude(s => s.Service)
.Include(d => d.Deployments)
.ThenInclude(vm => vm.Target)
.Include(batch => batch.TemplateSelections)
.ThenInclude(selection => selection.TemplateVersion)
.Include(batch => batch.ParameterValues)
.Include(batch => batch.TargetAssignments)
.ThenInclude(target => target.Target)
.Where(dg => dg.Id == id).FirstOrDefault();
}
public bool AddDeploymentBatchById(DeploymentGroupModel deploymentBatch, ICollection<Guid>? targetIds)
{
if (deploymentBatch.Id == Guid.Empty)
{
deploymentBatch.Id = Guid.NewGuid();
}
var template = _context.Templates
.Include(existing => existing.TemplateCategory)
.ThenInclude(existing => existing.Service)
.FirstOrDefault(existing => existing.Id == deploymentBatch.TemplateId);
if (template == null)
{
return false;
}
if (deploymentBatch.DeploymentRuleId.HasValue)
{
var ruleExists = _context.DeploymentRules.Any(existing => existing.Id == deploymentBatch.DeploymentRuleId.Value);
if (!ruleExists)
{
return false;
}
}
var isCloudService = template.TemplateCategory.Service.IsCloudService;
var selectedTargetIds = (targetIds ?? Array.Empty<Guid>())
.Distinct()
.ToList();
if (!isCloudService && selectedTargetIds.Count == 0)
{
return false;
}
if (selectedTargetIds.Count > 0)
{
var existingTargetIds = _context.Targets
.Where(existing => selectedTargetIds.Contains(existing.Id))
.Select(existing => existing.Id)
.ToHashSet();
if (existingTargetIds.Count != selectedTargetIds.Count)
{
return false;
}
}
_context.Add(deploymentBatch);
if (!SaveChanges())
{
return false;
}
if (!isCloudService)
{
foreach (var targetId in selectedTargetIds)
{
_context.Deployments.Add(new DeploymentModel
{
DeploymentGroupId = deploymentBatch.Id,
TargetId = targetId,
Status = QueueJobStatus.Pending,
JSONData = "{}"
});
}
return SaveChanges();
}
return true;
}
public bool DeleteDeploymentBatchById(DeploymentGroupModel deploymentBatch)
{
var deployments = _context.Deployments
.Where(existing => existing.DeploymentGroupId == deploymentBatch.Id)
.ToList();
if (deployments.Count > 0)
{
_context.Deployments.RemoveRange(deployments);
}
_context.Remove(deploymentBatch);
return SaveChanges();
}
public bool EditDeploymentBatchById(DeploymentGroupModel deploymentBatch)
{
_context.Update(deploymentBatch);
return SaveChanges();
}
public bool CheckDeploymentBatchById(Guid id)
{
return _context.DeploymentGroups
.Any(d => d.Id == id);
}
public bool SaveChanges()
{
var saved = _context.SaveChanges();
return saved > 0 ? true : false;
}
}
}
-123
View File
@@ -1,123 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
{
public class DeploymentGroupRepository : IDeploymentGroupInterface
{
private readonly DataContext _context;
public DeploymentGroupRepository(DataContext context)
{
_context = context;
}
public ICollection<DeploymentGroupModel> GetDeploymentGroups()
{
return _context.DeploymentGroups.ToList();
}
public DeploymentGroupModel GetDeploymentGroupById(Guid Id)
{
return _context.DeploymentGroups
.Include(t => t.Template)
.ThenInclude(tc => tc.TemplateCategory)
.ThenInclude(s => s.Service)
.Include(d => d.Deployments)
.ThenInclude(vm => vm.VirtualMachine)
.Where(dg => dg.Id == Id).FirstOrDefault();
}
public bool AddDeploymentGroupById(DeploymentGroupModel deploymentgroup, ICollection<Guid>? virtualMachineIds)
{
if (deploymentgroup.Id == Guid.Empty)
{
deploymentgroup.Id = Guid.NewGuid();
}
var template = _context.Templates
.Include(existing => existing.TemplateCategory)
.ThenInclude(existing => existing.Service)
.FirstOrDefault(existing => existing.Id == deploymentgroup.TemplateId);
if (template == null)
{
return false;
}
var isCloudService = template.TemplateCategory.Service.IsCloudService;
var selectedVirtualMachineIds = (virtualMachineIds ?? Array.Empty<Guid>())
.Distinct()
.ToList();
if (!isCloudService && selectedVirtualMachineIds.Count == 0)
{
return false;
}
if (selectedVirtualMachineIds.Count > 0)
{
var existingVirtualMachineIds = _context.VirtualMachines
.Where(existing => selectedVirtualMachineIds.Contains(existing.Id))
.Select(existing => existing.Id)
.ToHashSet();
if (existingVirtualMachineIds.Count != selectedVirtualMachineIds.Count)
{
return false;
}
}
_context.Add(deploymentgroup);
if (!SaveChanges())
{
return false;
}
if (!isCloudService)
{
foreach (var virtualMachineId in selectedVirtualMachineIds)
{
_context.Deployments.Add(new DeploymentModel
{
DeploymentGroupId = deploymentgroup.Id,
VirtualMachineId = virtualMachineId,
Status = QueueJobStatus.Pending,
JSONData = "{}"
});
}
return SaveChanges();
}
return true;
}
public bool DeleteDeploymentGroupById(DeploymentGroupModel deploymentgroup)
{
_context.Remove(deploymentgroup);
return SaveChanges();
}
public bool EditDeploymentGroupById(DeploymentGroupModel deploymentgroup)
{
_context.Update(deploymentgroup);
return SaveChanges();
}
public bool CheckDeploymentGroupById(Guid Id)
{
return _context.DeploymentGroups
.Any(d => d.Id == Id);
}
public bool SaveChanges()
{
var saved = _context.SaveChanges();
return saved > 0 ? true : false;
}
}
}
+26 -1
View File
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.JsonDocuments;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
@@ -22,7 +23,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
public DeploymentModel GetDeploymentById(Guid Id)
{
return _context.Deployments
.Include(vm => vm.VirtualMachine)
.Include(vm => vm.Target)
.Include(dg => dg.DeploymentGroup)
.ThenInclude(t => t.Template)
.Where(d => d.Id == Id).FirstOrDefault();
@@ -30,6 +31,10 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
public bool AddDeploymentById(DeploymentModel deployment)
{
deployment.JSONData = ConfigurationDocumentValidator.NormalizeAndValidate(
deployment.JSONData,
ConfigurationDocumentKind.DeploymentOverride).JsonData;
_context.Add(deployment);
return SaveChanges();
}
@@ -42,16 +47,35 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
public bool EditDeploymentById(DeploymentModel deployment)
{
deployment.JSONData = ConfigurationDocumentValidator.NormalizeAndValidate(
deployment.JSONData,
ConfigurationDocumentKind.DeploymentOverride).JsonData;
_context.Update(deployment);
return SaveChanges();
}
public DeploymentModel GetDeploymentByCompositeId(Guid deploymentGroupId, Guid targetId)
{
return _context.Deployments
.Include(vm => vm.Target)
.Include(dg => dg.DeploymentGroup)
.ThenInclude(t => t.Template)
.FirstOrDefault(d => d.DeploymentGroupId == deploymentGroupId && d.TargetId == targetId);
}
public bool CheckDeploymentById(Guid Id)
{
return _context.Deployments
.Any(d => d.Id == Id);
}
public bool CheckDeploymentByCompositeId(Guid deploymentGroupId, Guid targetId)
{
return _context.Deployments
.Any(d => d.DeploymentGroupId == deploymentGroupId && d.TargetId == targetId);
}
public bool SaveChanges()
{
var saved = _context.SaveChanges();
@@ -59,3 +83,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
}
}
}
+3 -2
View File
@@ -49,11 +49,11 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
.Where(d => d.Id == Id)
.FirstOrDefault();
}
public DomainModel GetVirtualMachinesByDomainId(Guid Id)
public DomainModel GetTargetsByDomainId(Guid Id)
{
return _context.Domains
.Where(d => d.Id == Id)
.Include(vm => vm.VirtualMachines)
.Include(vm => vm.Targets)
.FirstOrDefault();
}
@@ -86,3 +86,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
}
}
}
+2 -1
View File
@@ -52,7 +52,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
{
var environment = _context.Environments.Where(e => e.Id == Id).FirstOrDefault();
var isCloudEnvironment = environment != null
&& environment.EnvironmentType != EnvironmentTypes.OnPrem;
&& environment.HostingType != EnvironmentHostingTypes.OnPrem;
return _context.Templates
.Include(t => t.TemplateCategory)
@@ -79,3 +79,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
}
}
}
-56
View File
@@ -1,56 +0,0 @@
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
{
public class JobRepository : IJobInterface
{
private readonly DataContext _context;
public JobRepository(DataContext context)
{
_context = context;
}
public ICollection<JobModel> GetJobs()
{
return _context.Jobs.ToList();
}
bool IJobInterface.CheckJobById(Guid Id)
{
throw new NotImplementedException();
}
bool IJobInterface.CreateJobById(JobModel job)
{
throw new NotImplementedException();
}
bool IJobInterface.DeleteJobById(JobModel job)
{
throw new NotImplementedException();
}
JobModel IJobInterface.GetJobById(Guid Id)
{
throw new NotImplementedException();
}
ICollection<JobModel> IJobInterface.GetJobs()
{
throw new NotImplementedException();
}
bool IAbstractInterface.SaveChanges()
{
throw new NotImplementedException();
}
bool IJobInterface.UpdateJobById(JobModel job)
{
throw new NotImplementedException();
}
}
}
-59
View File
@@ -1,59 +0,0 @@
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
{
public class RunbookRepository : IRunbookInterface
{
private readonly DataContext _context;
public RunbookRepository(DataContext context)
{
_context = context;
}
public ICollection<RunbookModel> GetRunbooks()
{
return _context.Runbooks
.ToList();
}
public RunbookModel GetRunbookById(Guid Id)
{
return _context.Runbooks
.Where(r => r.Id == Id)
.FirstOrDefault();
}
public bool AddRunbookById(RunbookModel runbook)
{
_context.Add(runbook);
return SaveChanges();
}
public bool EditRunbookById(RunbookModel runbook)
{
_context.Update(runbook);
return SaveChanges();
}
public bool CheckRunbookById(Guid Id)
{
return _context.Runbooks
.Any(r => r.Id == Id);
}
public bool CheckRunbookByName(string Name)
{
return _context.Runbooks
.Any(r => r.Name == Name);
}
public bool SaveChanges()
{
var saved = _context.SaveChanges();
return saved > 0 ? true : false;
}
}
}
+2 -1
View File
@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
@@ -116,3 +116,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
}
}
}
@@ -5,65 +5,65 @@ using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
{
public class VirtualMachineRepository : IVirtualMachineInterface
public class TargetRepository : ITargetInterface
{
private readonly DataContext _context;
public VirtualMachineRepository(DataContext context)
public TargetRepository(DataContext context)
{
_context = context;
}
public ICollection<VirtualMachineModel> GetVirtualMachines()
public ICollection<TargetModel> GetTargets()
{
return _context.VirtualMachines
.Include(virtualMachine => virtualMachine.Domain)
return _context.Targets
.Include(target => target.Domain)
.ToList();
}
public VirtualMachineModel GetVirtualMachineById(Guid Id)
public TargetModel GetTargetById(Guid Id)
{
return _context.VirtualMachines
return _context.Targets
.Where(v => v.Id == Id)
.Include(d => d.Domain)
.ThenInclude(e => e.EnvironmentDomains)
.FirstOrDefault();
}
public bool AddVirtualMachineById(VirtualMachineModel virtualMachine)
public bool AddTargetById(TargetModel target)
{
_context.Add(virtualMachine);
_context.Add(target);
return SaveChanges();
}
public bool EditVirtualMachineById(VirtualMachineModel virtualMachine)
public bool EditTargetById(TargetModel target)
{
_context.Update(virtualMachine);
_context.Update(target);
return SaveChanges();
}
public bool DeleteVirtualMachineById(VirtualMachineModel virtualMachine)
public bool DeleteTargetById(TargetModel target)
{
_context.Remove(virtualMachine);
_context.Remove(target);
return SaveChanges();
}
public VirtualMachineModel GetVirtualMachineByName(string Name)
public TargetModel GetTargetByName(string Name)
{
return _context.VirtualMachines
return _context.Targets
.Where(v => v.Name == Name)
.FirstOrDefault();
}
public bool CheckVirtualMachineById(Guid Id)
public bool CheckTargetById(Guid Id)
{
return _context.VirtualMachines
return _context.Targets
.Any(v => v.Id == Id);
}
public bool CheckVirtualMachineByName(string Name)
public bool CheckTargetByName(string Name)
{
return _context.VirtualMachines
return _context.Targets
.Any(v => v.Name == Name);
}
@@ -74,3 +74,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
}
}
}
+2 -1
View File
@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.Models;
@@ -74,3 +74,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
}
}
}
+221 -4
View File
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.SelfService.Portal.Core.API.Context;
using Microsoft.SelfService.Portal.Core.API.Interfaces;
using Microsoft.SelfService.Portal.Core.API.JsonDocuments;
using Microsoft.SelfService.Portal.Core.API.Models;
namespace Microsoft.SelfService.Portal.Core.API.Repository
@@ -16,28 +17,113 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
public ICollection<TemplateModel> GetTemplates()
{
return _context.Templates
var templates = _context.Templates
.AsNoTracking()
.Include(template => template.TemplateVersions)
.ToList();
foreach (var template in templates)
{
ApplyPublishedVersion(template);
}
return templates;
}
public TemplateModel GetTemplateById(Guid Id)
{
return _context.Templates
var template = _context.Templates
.AsNoTracking()
.Include(t => t.TemplateVersions)
.Where(t => t.Id == Id)
.FirstOrDefault();
if (template != null)
{
ApplyPublishedVersion(template);
}
return template;
}
public bool AddTemplateById(TemplateModel template)
{
if (template.Id == Guid.Empty)
{
template.Id = Guid.NewGuid();
}
var document = ConfigurationDocumentValidator.NormalizeAndValidate(template.JSONData, ConfigurationDocumentKind.Template);
template.JSONData = document.JsonData;
var version = new TemplateVersionModel
{
Id = Guid.NewGuid(),
TemplateId = template.Id,
Version = string.IsNullOrWhiteSpace(template.Version) ? "1.0.0" : template.Version,
SchemaVersion = document.SchemaVersion,
IsPublished = true,
PublishedAt = DateTime.UtcNow,
PublishedBy = template.CreatedBy
};
version.SetJsonData(document.JsonData);
template.TemplateVersions.Add(version);
_context.Add(template);
return SaveChanges();
}
public bool EditTemplateById(TemplateModel template)
{
_context.Update(template);
var existingTemplate = _context.Templates
.Include(existing => existing.TemplateVersions)
.FirstOrDefault(existing => existing.Id == template.Id);
if (existingTemplate == null)
{
return false;
}
var document = ConfigurationDocumentValidator.NormalizeAndValidate(template.JSONData, ConfigurationDocumentKind.Template);
var jsonData = document.JsonData;
var publishedVersion = existingTemplate.TemplateVersions.FirstOrDefault(version => version.IsPublished);
var jsonChanged = publishedVersion == null || !string.Equals(publishedVersion.JsonData, jsonData, StringComparison.Ordinal);
existingTemplate.Name = template.Name;
existingTemplate.Version = template.Version;
existingTemplate.Description = template.Description;
existingTemplate.JSONData = jsonData;
existingTemplate.TemplateCategoryId = template.TemplateCategoryId;
existingTemplate.DeploymentRuleId = template.DeploymentRuleId;
existingTemplate.Modified = DateTime.UtcNow;
existingTemplate.ModifiedBy = template.ModifiedBy;
if (jsonChanged)
{
var versionName = GetUniqueVersionName(
existingTemplate.Id,
string.IsNullOrWhiteSpace(template.Version) ? DateTime.UtcNow.ToString("yyyyMMddHHmmss") : template.Version);
var version = new TemplateVersionModel
{
Id = Guid.NewGuid(),
TemplateId = existingTemplate.Id,
Version = versionName,
SchemaVersion = document.SchemaVersion,
IsPublished = true,
PublishedAt = DateTime.UtcNow,
PublishedBy = template.ModifiedBy
};
version.SetJsonData(jsonData);
foreach (var existingVersion in existingTemplate.TemplateVersions)
{
existingVersion.IsPublished = false;
}
existingTemplate.TemplateVersions.Add(version);
}
return SaveChanges();
}
@@ -67,10 +153,141 @@ namespace Microsoft.SelfService.Portal.Core.API.Repository
.Any(t => t.Name == Name);
}
public ICollection<TemplateVersionModel> GetTemplateVersions(Guid templateId)
{
return _context.TemplateVersions
.AsNoTracking()
.Where(version => version.TemplateId == templateId)
.OrderByDescending(version => version.Created)
.ToList();
}
public TemplateVersionModel? GetTemplateVersionById(Guid templateId, Guid versionId)
{
return _context.TemplateVersions
.AsNoTracking()
.FirstOrDefault(version => version.TemplateId == templateId && version.Id == versionId);
}
public TemplateVersionModel? GetPublishedTemplateVersion(Guid templateId)
{
return _context.TemplateVersions
.AsNoTracking()
.FirstOrDefault(version => version.TemplateId == templateId && version.IsPublished);
}
public bool AddTemplateVersion(Guid templateId, TemplateVersionModel version, bool publish)
{
if (!_context.Templates.Any(template => template.Id == templateId))
{
return false;
}
version.Id = version.Id == Guid.Empty ? Guid.NewGuid() : version.Id;
version.TemplateId = templateId;
version.Version = string.IsNullOrWhiteSpace(version.Version) ? "1.0.0" : version.Version;
var document = ConfigurationDocumentValidator.NormalizeAndValidate(
version.JsonData,
ConfigurationDocumentKind.Template,
version.SchemaVersion);
version.SchemaVersion = document.SchemaVersion;
version.SetJsonData(document.JsonData);
if (publish)
{
foreach (var existingVersion in _context.TemplateVersions.Where(existing => existing.TemplateId == templateId && existing.IsPublished))
{
existingVersion.IsPublished = false;
}
version.IsPublished = true;
version.PublishedAt = DateTime.UtcNow;
}
_context.TemplateVersions.Add(version);
return SaveChanges();
}
public bool PublishTemplateVersion(Guid templateId, Guid versionId, string? publishedBy)
{
var version = _context.TemplateVersions
.FirstOrDefault(existing => existing.TemplateId == templateId && existing.Id == versionId);
if (version == null)
{
return false;
}
foreach (var existingVersion in _context.TemplateVersions.Where(existing => existing.TemplateId == templateId && existing.IsPublished))
{
existingVersion.IsPublished = false;
}
version.IsPublished = true;
version.PublishedAt = DateTime.UtcNow;
version.PublishedBy = string.IsNullOrWhiteSpace(publishedBy) ? "System" : publishedBy;
var template = _context.Templates.FirstOrDefault(existing => existing.Id == templateId);
if (template != null)
{
template.Version = version.Version;
template.JSONData = version.JsonData;
template.Modified = DateTime.UtcNow;
template.ModifiedBy = version.PublishedBy;
}
return SaveChanges();
}
public bool CheckTemplateVersionById(Guid templateId, Guid versionId)
{
return _context.TemplateVersions
.Any(version => version.TemplateId == templateId && version.Id == versionId);
}
public bool CheckTemplateVersionByVersion(Guid templateId, string version)
{
return _context.TemplateVersions
.Any(existing => existing.TemplateId == templateId && existing.Version == version);
}
public bool SaveChanges()
{
var saved = _context.SaveChanges();
return saved > 0 ? true : false;
}
private static void ApplyPublishedVersion(TemplateModel template)
{
var publishedVersion = template.TemplateVersions?.FirstOrDefault(version => version.IsPublished);
if (publishedVersion == null)
{
return;
}
template.Version = publishedVersion.Version;
template.JSONData = publishedVersion.JsonData;
}
private string GetUniqueVersionName(Guid templateId, string version)
{
if (!CheckTemplateVersionByVersion(templateId, version))
{
return version;
}
var timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss");
var candidate = $"{version}-{timestamp}";
var counter = 1;
while (CheckTemplateVersionByVersion(templateId, candidate))
{
counter++;
candidate = $"{version}-{timestamp}-{counter}";
}
return candidate;
}
}
}