فهرست منبع

Added clone usecases

Tim Jones 2 ماه پیش
والد
کامیت
686d799722

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 168 - 848
Commands.md


+ 13 - 0
RackPeek.Domain/Helpers/DeepClone.cs

@@ -0,0 +1,13 @@
+namespace RackPeek.Domain.Helpers;
+
+using System.Text.Json;
+
+public static class Clone
+{
+    public static T DeepClone<T>(T obj)
+    {
+        var json = JsonSerializer.Serialize(obj);
+        return JsonSerializer.Deserialize<T>(json)!;
+    }
+
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/Desktops/CloneDesktopUsecase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Desktops;
+
+public class CloneDesktopUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Firewall;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/Firewalls/CloneFirewallUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Firewalls;
+
+public class CloneFirewallUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Firewall;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/Laptops/CloneLaptopUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Laptops;
+
+public class CloneLaptopUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Laptop;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/Routers/CloneRouterUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Routers;
+
+public class CloneRouterUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Router;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/Servers/CloneServerUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Servers;
+
+public class CloneServerUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Server;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/Switches/CloneSwitchUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Switches;
+
+public class CloneSwitchUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Switch;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 31 - 0
RackPeek.Domain/Resources/Hardware/UpsUnits/CloneUpsUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.UpsUnits;
+
+public class CloneUpsUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as Ups;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 2 - 18
RackPeek.Domain/Resources/Services/CloneSystemUseCase.cs

@@ -22,24 +22,8 @@ public class CloneServiceUseCase(IServiceRepository repository, IResourceReposit
             throw new NotFoundException($"Resource '{originalName}' not found.");
         }
 
-        Network? clonedNetwork = null;
-        if (original.Network != null)
-        {
-            clonedNetwork = new Network()
-            {
-                Ip = original.Network.Ip,
-                Port = original.Network.Port,
-                Protocol = original.Network.Protocol,
-                Url = original.Network.Url,
-            };
-        }
-        
-        var clone = new Service()
-        {
-            Name = cloneName,
-            Network = clonedNetwork,
-            RunsOn = original.RunsOn,
-        };
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
         
         await repository.AddAsync(clone);
     }

+ 2 - 21
RackPeek.Domain/Resources/SystemResources/UseCases/CloneSystemUseCase.cs

@@ -23,28 +23,9 @@ public class CloneSystemUseCase(ISystemRepository repository, IResourceRepositor
         {
             throw new NotFoundException($"Resource '{originalName}' not found.");
         }
-
-        List<Drive>? clonedDrives = null;
-        if (original.Drives != null)
-        {
-            clonedDrives = original
-                .Drives
-                .Select(drive => new Drive() { Size = drive.Size, Type = drive.Type })
-                .ToList();
-        }
-        
-        var clone = new SystemResource()
-        {
-            Name = cloneName,
-            Cores = original.Cores,
-            Kind = original.Kind,
-            Os = original.Os,
-            Ram = original.Ram,
-            Type = original.Type,
-            Drives = clonedDrives,
-            RunsOn = original.RunsOn,
-        };
         
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
         await repository.AddAsync(clone);
     }
 }

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است