ThrowIfInvalid.cs 5.5 KB

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