ThrowIfInvalid.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System.ComponentModel.DataAnnotations;
  2. using RackPeek.Domain.Resources.SubResources;
  3. using RackPeek.Domain.Resources.SystemResources;
  4. namespace RackPeek.Domain.Helpers;
  5. public static class ThrowIfInvalid
  6. {
  7. public static void ResourceName(string name)
  8. {
  9. if (string.IsNullOrWhiteSpace(name)) throw new ValidationException("Name is required.");
  10. if (name.Length > 50) throw new ValidationException("Name is too long.");
  11. }
  12. public static void LabelKey(string key)
  13. {
  14. if (string.IsNullOrWhiteSpace(key)) throw new ValidationException("Label key is required.");
  15. if (key.Length > 50) throw new ValidationException("Label key is too long.");
  16. }
  17. public static void LabelValue(string value)
  18. {
  19. if (string.IsNullOrWhiteSpace(value)) throw new ValidationException("Label value is required.");
  20. if (value.Length > 200) throw new ValidationException("Label value is too long.");
  21. }
  22. public static void AccessPointModelName(string name)
  23. {
  24. if (string.IsNullOrWhiteSpace(name))
  25. throw new ValidationException("Model name is required.");
  26. if (name.Length > 50)
  27. throw new ValidationException("Model name is too long.");
  28. }
  29. public static void RamGb(double? value)
  30. {
  31. if (value is null) throw new ValidationException("RAM value must be specified.");
  32. if (value < 0) throw new ValidationException("RAM value must be a non negative number of gigabytes.");
  33. }
  34. public static void SystemType(string systemType)
  35. {
  36. if (string.IsNullOrWhiteSpace(systemType)) throw new ValidationException("System type is required.");
  37. var normalized = systemType.Trim().ToLowerInvariant();
  38. if (SystemResource.ValidSystemTypes.Contains(normalized)) return;
  39. var suggestions = GetSystemTypeSuggestions(normalized).ToList();
  40. var message = suggestions.Any()
  41. ? $"System type '{systemType}' is not valid. Did you mean: {string.Join(", ", suggestions)}?"
  42. : $"System type '{systemType}' is not valid. Valid System types include hypervisor, baremetal vm, container, other etc";
  43. throw new ValidationException(message);
  44. }
  45. private static IEnumerable<string> GetSystemTypeSuggestions(string input)
  46. {
  47. return SystemResource.ValidSystemTypes.Select(type => new { Type = type, Score = SimilarityScore(input, type) })
  48. .Where(x => x.Score >= 0.5)
  49. .OrderByDescending(x => x.Score)
  50. .Take(3)
  51. .Select(x => x.Type);
  52. }
  53. #region Nics
  54. public static void NicType(string nicType)
  55. {
  56. if (string.IsNullOrWhiteSpace(nicType)) throw new ValidationException("NIC type is required.");
  57. var normalized = nicType.Trim().ToLowerInvariant();
  58. if (Nic.ValidNicTypes.Contains(normalized)) return;
  59. var suggestions = GetNicTypeSuggestions(normalized).ToList();
  60. var message = suggestions.Any()
  61. ? $"NIC type '{nicType}' is not valid. Did you mean: {string.Join(", ", suggestions)}?"
  62. : $"NIC type '{nicType}' is not valid. Valid NIC types include rj45, sfp, sfp+, qsfp+ etc";
  63. throw new ValidationException(message);
  64. }
  65. private static IEnumerable<string> GetNicTypeSuggestions(string input)
  66. {
  67. return Nic.ValidNicTypes.Select(type => new { Type = type, Score = SimilarityScore(input, type) })
  68. .Where(x => x.Score >= 0.5)
  69. .OrderByDescending(x => x.Score)
  70. .Take(3)
  71. .Select(x => x.Type);
  72. }
  73. private static double SimilarityScore(string a, string b)
  74. {
  75. if (a == b) return 1.0;
  76. if (b.StartsWith(a) || a.StartsWith(b)) return 0.9;
  77. var commonChars = a.Intersect(b).Count();
  78. return (double)commonChars / Math.Max(a.Length, b.Length);
  79. }
  80. public static void NicSpeed(double speed)
  81. {
  82. if (speed < 0) throw new ValidationException("NIC speed must be a non negative number of gigabits per second.");
  83. }
  84. public static void NetworkSpeed(double speed)
  85. {
  86. if (speed < 0)
  87. throw new ValidationException(
  88. "Network speed must be a non negative number of gigabits per second.");
  89. }
  90. public static void NicPorts(int ports)
  91. {
  92. if (ports < 0) throw new ValidationException("NIC port count must be a non negative integer.");
  93. }
  94. #endregion
  95. #region Drives
  96. public static void DriveType(string driveType)
  97. {
  98. if (string.IsNullOrWhiteSpace(driveType)) throw new ValidationException("Drive type is required.");
  99. var normalized = driveType.Trim().ToLowerInvariant();
  100. if (Drive.ValidDriveTypes.Contains(normalized)) return;
  101. var suggestions = GetDriveTypeSuggestions(normalized).ToList();
  102. var message = suggestions.Any()
  103. ? $"Drive type '{driveType}' is not valid. Did you mean: {string.Join(", ", suggestions)}?"
  104. : $"Drive type '{driveType}' is not valid. Valid Drive types include nvme, ssd, hdd, sata, sas etc.";
  105. throw new ValidationException(message);
  106. }
  107. private static IEnumerable<string> GetDriveTypeSuggestions(string input)
  108. {
  109. return Drive.ValidDriveTypes.Select(type => new { Type = type, Score = SimilarityScore(input, type) })
  110. .Where(x => x.Score >= 0.5)
  111. .OrderByDescending(x => x.Score)
  112. .Take(3)
  113. .Select(x => x.Type);
  114. }
  115. public static void DriveSize(int size)
  116. {
  117. if (size < 0) throw new ValidationException("Drive size value must be a non negative number of gigabytes.");
  118. }
  119. #endregion
  120. }