@oneuptime/common 11.6.1 → 11.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. package/Models/AnalyticsModels/Index.ts +4 -0
  2. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  3. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  4. package/Models/AnalyticsModels/SloHistory.ts +243 -0
  5. package/Models/DatabaseModels/Index.ts +20 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  8. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  9. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  10. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  11. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  13. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  14. package/Models/DatabaseModels/ServiceLevelObjective.ts +1115 -0
  15. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  16. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  17. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.ts +30 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  25. package/Server/Services/AnalyticsDatabaseService.ts +25 -9
  26. package/Server/Services/Index.ts +24 -0
  27. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  28. package/Server/Services/MetricService.ts +21 -2
  29. package/Server/Services/MonitorService.ts +22 -0
  30. package/Server/Services/NetworkDeviceService.ts +438 -2
  31. package/Server/Services/NetworkEndpointService.ts +414 -0
  32. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  33. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  34. package/Server/Services/NetworkSiteService.ts +1254 -0
  35. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  36. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  37. package/Server/Services/ProjectService.ts +122 -2
  38. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  39. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  40. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  41. package/Server/Services/ServiceLevelObjectiveService.ts +685 -0
  42. package/Server/Services/SloHistoryService.ts +101 -0
  43. package/Server/Services/UserNotificationSettingService.ts +37 -0
  44. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  45. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  46. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  47. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
  48. package/Server/Utils/Memory.ts +9 -1
  49. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  50. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  51. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  52. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  53. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  54. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  55. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  56. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  57. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  58. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  59. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  60. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  61. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  62. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  63. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  64. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  65. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  66. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  67. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  68. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  69. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  70. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  72. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
  73. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  74. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  75. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  76. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  77. package/Tests/Server/Utils/Memory.test.ts +213 -0
  78. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  79. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  80. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  81. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  82. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  83. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  84. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  85. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  86. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  87. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  88. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  89. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  90. package/Tests/Server/Utils/Stream.test.ts +87 -0
  91. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  92. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  93. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  94. package/Tests/Types/Email.test.ts +198 -0
  95. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  96. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  97. package/Tests/Types/Monitor/MonitorCriteria.test.ts +155 -0
  98. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +465 -0
  99. package/Tests/Types/Monitor/MonitorStep.test.ts +183 -0
  100. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  101. package/Tests/Types/Monitor/MonitorSteps.test.ts +183 -0
  102. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  103. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  104. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  105. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  106. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  107. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  108. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  109. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  110. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  111. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  112. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  113. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  114. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  115. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  116. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  117. package/Tests/Utils/Base64.test.ts +51 -0
  118. package/Tests/Utils/Boolean.test.ts +76 -0
  119. package/Tests/Utils/Crypto.test.ts +48 -0
  120. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  121. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  122. package/Tests/Utils/Enum.test.ts +54 -0
  123. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  124. package/Tests/Utils/Memory.test.ts +44 -0
  125. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  126. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  127. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  128. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  129. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  130. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  131. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  132. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  133. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  134. package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +124 -0
  135. package/Tests/Utils/Slo/SloDuration.test.ts +148 -0
  136. package/Tests/Utils/Slo/SloHealth.test.ts +334 -0
  137. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  138. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  139. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  140. package/Tests/Utils/TechStack.test.ts +50 -0
  141. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  142. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  143. package/Types/BaseDatabase/EqualTo.ts +9 -1
  144. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  145. package/Types/BaseDatabase/NotEqual.ts +9 -1
  146. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  147. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  148. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  149. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  150. package/Types/Email/EmailTemplateType.ts +2 -0
  151. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  152. package/Types/Monitor/CriteriaFilter.ts +9 -0
  153. package/Types/Monitor/MonitorStep.ts +5 -8
  154. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  155. package/Types/Monitor/MonitorType.ts +15 -5
  156. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  157. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  158. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  159. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  160. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  161. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  162. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  163. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  164. package/Types/Permission.ts +449 -0
  165. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  166. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  167. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  168. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  169. package/Types/Telemetry/ServiceType.ts +1 -0
  170. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  171. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  172. package/UI/Components/List/List.tsx +8 -0
  173. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  174. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  175. package/UI/Components/Navbar/NavBar.tsx +16 -2
  176. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  177. package/UI/Utils/Navigation.ts +10 -0
  178. package/UI/Utils/TableFilterUrlState.ts +204 -17
  179. package/UI/Utils/TableViewUrlState.ts +165 -0
  180. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  181. package/Utils/Dashboard/Components/Index.ts +7 -0
  182. package/Utils/IpCanonicalUtil.ts +134 -0
  183. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  184. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  185. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  186. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  187. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  188. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  189. package/Utils/Slo/SloBurnRateRuleState.ts +91 -0
  190. package/Utils/Slo/SloDuration.ts +165 -0
  191. package/Utils/Slo/SloEvaluation.ts +22 -0
  192. package/Utils/Slo/SloHealth.ts +302 -0
  193. package/Utils/Slo/SloStatusColor.ts +54 -0
  194. package/Utils/Slo/SloUtil.ts +637 -0
  195. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  196. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  197. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  198. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  199. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  200. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  201. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  202. package/build/dist/Models/AnalyticsModels/SloHistory.js +218 -0
  203. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  204. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  205. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  207. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  209. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  211. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  212. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  213. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  214. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  215. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  216. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  217. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  218. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  219. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  220. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  221. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  222. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1134 -0
  223. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  224. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  225. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  226. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  227. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  228. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  229. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js +21 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js.map +1 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  244. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
  245. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  246. package/build/dist/Server/Services/Index.js +24 -0
  247. package/build/dist/Server/Services/Index.js.map +1 -1
  248. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  249. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  250. package/build/dist/Server/Services/MetricService.js +21 -3
  251. package/build/dist/Server/Services/MetricService.js.map +1 -1
  252. package/build/dist/Server/Services/MonitorService.js +19 -0
  253. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  254. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  255. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  256. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  257. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  258. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  259. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  260. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  261. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  262. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  263. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  264. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  265. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  266. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  267. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  268. package/build/dist/Server/Services/ProjectService.js +98 -2
  269. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  270. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  271. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  272. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  273. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  274. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  275. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  276. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +588 -0
  277. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  278. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  279. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  280. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  281. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  282. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  283. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  284. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  285. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  286. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  287. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  288. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
  289. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  290. package/build/dist/Server/Utils/Memory.js +9 -1
  291. package/build/dist/Server/Utils/Memory.js.map +1 -1
  292. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  293. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  294. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  295. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  296. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  297. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  298. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  299. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  300. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  301. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  302. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  303. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  304. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  305. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  306. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  307. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  308. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  309. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  310. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  311. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  312. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  313. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  314. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  315. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  316. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  317. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  318. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  319. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  320. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  321. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  322. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  323. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  324. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  325. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  326. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  327. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  328. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  329. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  330. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  331. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  332. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  333. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  334. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  335. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  336. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  337. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  338. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  339. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  340. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  341. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  342. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  343. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  344. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  345. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  346. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  347. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  348. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  349. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  350. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  351. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  352. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  353. package/build/dist/Types/Permission.js +409 -0
  354. package/build/dist/Types/Permission.js.map +1 -1
  355. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  356. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  357. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  358. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  359. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  360. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  361. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  362. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  363. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  364. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  365. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  366. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  367. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  368. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  369. package/build/dist/UI/Components/List/List.js +1 -1
  370. package/build/dist/UI/Components/List/List.js.map +1 -1
  371. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  372. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  373. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  374. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  375. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  376. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  377. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  378. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  379. package/build/dist/UI/Utils/Navigation.js +9 -0
  380. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  381. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  382. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  383. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  384. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  385. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  386. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  387. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  388. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  389. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  390. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  391. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  392. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  393. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  394. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  395. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  396. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  397. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  398. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  399. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  400. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  401. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  402. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  403. package/build/dist/Utils/Slo/SloBurnRateRuleState.js +35 -0
  404. package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -0
  405. package/build/dist/Utils/Slo/SloDuration.js +87 -0
  406. package/build/dist/Utils/Slo/SloDuration.js.map +1 -0
  407. package/build/dist/Utils/Slo/SloEvaluation.js +21 -0
  408. package/build/dist/Utils/Slo/SloEvaluation.js.map +1 -0
  409. package/build/dist/Utils/Slo/SloHealth.js +179 -0
  410. package/build/dist/Utils/Slo/SloHealth.js.map +1 -0
  411. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  412. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  413. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  414. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  415. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  416. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  417. package/package.json +2 -2
  418. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  419. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  420. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -0,0 +1,496 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
2
+ import SnmpInterfaceRateUtil from "../../../../Server/Utils/Monitor/SnmpInterfaceRateUtil";
3
+ import { JSONObject } from "../../../../Types/JSON";
4
+ import OneUptimeDate from "../../../../Types/Date";
5
+ import SnmpInterface from "../../../../Types/Monitor/SnmpMonitor/SnmpInterface";
6
+ import SnmpMonitorResponse from "../../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
7
+
8
+ /*
9
+ * SnmpInterfaceRateUtil turns two consecutive walks' cumulative IF-MIB
10
+ * counters into per-interface rates. Probes stay stateless: the previous
11
+ * walk arrives as NetworkDevice.lastWalkLog — a JSON blob of
12
+ * `{ snmpResponse, monitoredAt }` — and the current side of the delta is
13
+ * server time, so these tests pin the exact rate arithmetic under a mocked
14
+ * clock, plus every guard that must leave the response untouched (first
15
+ * walk, empty walks, unparseable or future timestamps, counter wraps).
16
+ */
17
+
18
+ const NOW: Date = new Date("2026-07-16T12:01:00.000Z");
19
+ const SIXTY_SECONDS_AGO: string = "2026-07-16T12:00:00.000Z";
20
+
21
+ function buildResponse(
22
+ interfaces: Array<SnmpInterface> | undefined,
23
+ ): SnmpMonitorResponse {
24
+ return {
25
+ isOnline: true,
26
+ responseTimeInMs: 12,
27
+ failureCause: "",
28
+ oidResponses: [],
29
+ ...(interfaces !== undefined ? { interfaces: interfaces } : {}),
30
+ };
31
+ }
32
+
33
+ function currentInterface(overrides?: Partial<SnmpInterface>): SnmpInterface {
34
+ return {
35
+ interfaceIndex: 1,
36
+ name: "GigabitEthernet0/1",
37
+ isOperationallyUp: true,
38
+ isAdministrativelyUp: true,
39
+ ...overrides,
40
+ };
41
+ }
42
+
43
+ function previousWalkLog(options?: {
44
+ interfaces?: Array<JSONObject> | undefined;
45
+ monitoredAt?: string | undefined;
46
+ omitInterfaces?: boolean;
47
+ }): JSONObject {
48
+ return {
49
+ snmpResponse: {
50
+ isOnline: true,
51
+ ...(options?.omitInterfaces
52
+ ? {}
53
+ : {
54
+ interfaces: options?.interfaces ?? [
55
+ { interfaceIndex: 1, inOctets: 0, outOctets: 0 },
56
+ ],
57
+ }),
58
+ },
59
+ monitoredAt: options?.monitoredAt ?? SIXTY_SECONDS_AGO,
60
+ };
61
+ }
62
+
63
+ beforeEach(() => {
64
+ jest.spyOn(OneUptimeDate, "getCurrentDate").mockReturnValue(NOW);
65
+ });
66
+
67
+ afterEach(() => {
68
+ jest.restoreAllMocks();
69
+ });
70
+
71
+ describe("SnmpInterfaceRateUtil.attachInterfaceRates — no-op guards", () => {
72
+ test("does nothing when there is no snmpResponse", () => {
73
+ // Must simply not throw — there is nothing to attach rates to.
74
+ expect(() => {
75
+ SnmpInterfaceRateUtil.attachInterfaceRates({
76
+ snmpResponse: undefined,
77
+ previousWalkLog: previousWalkLog(),
78
+ });
79
+ }).not.toThrow();
80
+ });
81
+
82
+ test("does nothing when the current walk has no interfaces array", () => {
83
+ const response: SnmpMonitorResponse = buildResponse(undefined);
84
+
85
+ SnmpInterfaceRateUtil.attachInterfaceRates({
86
+ snmpResponse: response,
87
+ previousWalkLog: previousWalkLog(),
88
+ });
89
+
90
+ expect(response.interfaces).toBeUndefined();
91
+ });
92
+
93
+ test("does nothing when the current walk's interfaces array is empty", () => {
94
+ const response: SnmpMonitorResponse = buildResponse([]);
95
+
96
+ SnmpInterfaceRateUtil.attachInterfaceRates({
97
+ snmpResponse: response,
98
+ previousWalkLog: previousWalkLog(),
99
+ });
100
+
101
+ expect(response.interfaces).toEqual([]);
102
+ });
103
+
104
+ test("a device's first walk (no previousWalkLog) attaches no rates", () => {
105
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
106
+ const response: SnmpMonitorResponse = buildResponse([iface]);
107
+
108
+ SnmpInterfaceRateUtil.attachInterfaceRates({
109
+ snmpResponse: response,
110
+ previousWalkLog: undefined,
111
+ });
112
+
113
+ expect(iface.inBitsPerSecond).toBeUndefined();
114
+ expect(iface.outBitsPerSecond).toBeUndefined();
115
+ expect(iface.utilizationPercent).toBeUndefined();
116
+ expect(iface.errorsPerSecond).toBeUndefined();
117
+ });
118
+
119
+ test("a previous walk with no interfaces key attaches no rates", () => {
120
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
121
+ const response: SnmpMonitorResponse = buildResponse([iface]);
122
+
123
+ SnmpInterfaceRateUtil.attachInterfaceRates({
124
+ snmpResponse: response,
125
+ previousWalkLog: previousWalkLog({ omitInterfaces: true }),
126
+ });
127
+
128
+ expect(iface.inBitsPerSecond).toBeUndefined();
129
+ });
130
+
131
+ test("a previous walk with an empty interfaces array attaches no rates", () => {
132
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
133
+ const response: SnmpMonitorResponse = buildResponse([iface]);
134
+
135
+ SnmpInterfaceRateUtil.attachInterfaceRates({
136
+ snmpResponse: response,
137
+ previousWalkLog: previousWalkLog({ interfaces: [] }),
138
+ });
139
+
140
+ expect(iface.inBitsPerSecond).toBeUndefined();
141
+ });
142
+
143
+ test("a previous walk log without monitoredAt attaches no rates", () => {
144
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
145
+ const response: SnmpMonitorResponse = buildResponse([iface]);
146
+
147
+ SnmpInterfaceRateUtil.attachInterfaceRates({
148
+ snmpResponse: response,
149
+ previousWalkLog: {
150
+ snmpResponse: {
151
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
152
+ },
153
+ },
154
+ });
155
+
156
+ expect(iface.inBitsPerSecond).toBeUndefined();
157
+ });
158
+
159
+ test("an unparseable monitoredAt attaches no rates", () => {
160
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
161
+ const response: SnmpMonitorResponse = buildResponse([iface]);
162
+
163
+ SnmpInterfaceRateUtil.attachInterfaceRates({
164
+ snmpResponse: response,
165
+ previousWalkLog: previousWalkLog({ monitoredAt: "not-a-timestamp" }),
166
+ });
167
+
168
+ expect(iface.inBitsPerSecond).toBeUndefined();
169
+ });
170
+
171
+ test.each([
172
+ // Clock skew: the stored walk claims to be from the future.
173
+ ["a future monitoredAt", "2026-07-16T12:02:00.000Z"],
174
+ // Same instant: elapsed is exactly zero — division must not happen.
175
+ ["a monitoredAt equal to now", "2026-07-16T12:01:00.000Z"],
176
+ ])("%s (elapsed <= 0) attaches no rates", (_label: string, when: string) => {
177
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
178
+ const response: SnmpMonitorResponse = buildResponse([iface]);
179
+
180
+ SnmpInterfaceRateUtil.attachInterfaceRates({
181
+ snmpResponse: response,
182
+ previousWalkLog: previousWalkLog({ monitoredAt: when }),
183
+ });
184
+
185
+ expect(iface.inBitsPerSecond).toBeUndefined();
186
+ expect(iface.utilizationPercent).toBeUndefined();
187
+ });
188
+ });
189
+
190
+ describe("SnmpInterfaceRateUtil.attachInterfaceRates — rate arithmetic", () => {
191
+ test("in/out bits per second are the octet deltas over the elapsed window", () => {
192
+ const iface: SnmpInterface = currentInterface({
193
+ inOctets: 750,
194
+ outOctets: 3000,
195
+ });
196
+ const response: SnmpMonitorResponse = buildResponse([iface]);
197
+
198
+ SnmpInterfaceRateUtil.attachInterfaceRates({
199
+ snmpResponse: response,
200
+ previousWalkLog: previousWalkLog({
201
+ interfaces: [{ interfaceIndex: 1, inOctets: 0, outOctets: 1500 }],
202
+ }),
203
+ });
204
+
205
+ // (750 - 0) octets * 8 bits / 60 s = 100 bps.
206
+ expect(iface.inBitsPerSecond).toBe(100);
207
+ // (3000 - 1500) octets * 8 bits / 60 s = 200 bps.
208
+ expect(iface.outBitsPerSecond).toBe(200);
209
+ });
210
+
211
+ test("rates are rounded to two decimal places", () => {
212
+ const iface: SnmpInterface = currentInterface({ inOctets: 1000 });
213
+ const response: SnmpMonitorResponse = buildResponse([iface]);
214
+
215
+ SnmpInterfaceRateUtil.attachInterfaceRates({
216
+ snmpResponse: response,
217
+ previousWalkLog: previousWalkLog({
218
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
219
+ }),
220
+ });
221
+
222
+ // 1000 * 8 / 60 = 133.333… → 133.33.
223
+ expect(iface.inBitsPerSecond).toBe(133.33);
224
+ });
225
+
226
+ test("errorsPerSecond sums both directions over the elapsed window", () => {
227
+ const iface: SnmpInterface = currentInterface({
228
+ inErrors: 30,
229
+ outErrors: 45,
230
+ });
231
+ const response: SnmpMonitorResponse = buildResponse([iface]);
232
+
233
+ SnmpInterfaceRateUtil.attachInterfaceRates({
234
+ snmpResponse: response,
235
+ previousWalkLog: previousWalkLog({
236
+ interfaces: [{ interfaceIndex: 1, inErrors: 0, outErrors: 15 }],
237
+ }),
238
+ });
239
+
240
+ // ((30 - 0) + (45 - 15)) / 60 s = 1 error per second.
241
+ expect(iface.errorsPerSecond).toBe(1);
242
+ });
243
+
244
+ test("errorsPerSecond is computed even when only one direction has a delta", () => {
245
+ const iface: SnmpInterface = currentInterface({ inErrors: 6 });
246
+ const response: SnmpMonitorResponse = buildResponse([iface]);
247
+
248
+ SnmpInterfaceRateUtil.attachInterfaceRates({
249
+ snmpResponse: response,
250
+ previousWalkLog: previousWalkLog({
251
+ interfaces: [{ interfaceIndex: 1, inErrors: 0 }],
252
+ }),
253
+ });
254
+
255
+ // 6 / 60 s = 0.1 errors per second; the missing direction counts as 0.
256
+ expect(iface.errorsPerSecond).toBe(0.1);
257
+ });
258
+
259
+ test("no error counters on either side leaves errorsPerSecond unset", () => {
260
+ const iface: SnmpInterface = currentInterface({ inOctets: 750 });
261
+ const response: SnmpMonitorResponse = buildResponse([iface]);
262
+
263
+ SnmpInterfaceRateUtil.attachInterfaceRates({
264
+ snmpResponse: response,
265
+ previousWalkLog: previousWalkLog({
266
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
267
+ }),
268
+ });
269
+
270
+ expect(iface.errorsPerSecond).toBeUndefined();
271
+ });
272
+
273
+ test("a previous counter that is not a number yields no rate", () => {
274
+ const iface: SnmpInterface = currentInterface({ inOctets: 750 });
275
+ const response: SnmpMonitorResponse = buildResponse([iface]);
276
+
277
+ SnmpInterfaceRateUtil.attachInterfaceRates({
278
+ snmpResponse: response,
279
+ previousWalkLog: previousWalkLog({
280
+ interfaces: [{ interfaceIndex: 1, inOctets: "0" }],
281
+ }),
282
+ });
283
+
284
+ expect(iface.inBitsPerSecond).toBeUndefined();
285
+ });
286
+ });
287
+
288
+ describe("SnmpInterfaceRateUtil.attachInterfaceRates — counter wraps", () => {
289
+ test("a negative octet delta (wrap or reboot) leaves that direction's rate unset", () => {
290
+ const iface: SnmpInterface = currentInterface({
291
+ // Wrapped: went backwards relative to the previous walk.
292
+ inOctets: 100,
293
+ // Healthy direction on the same interface keeps its rate.
294
+ outOctets: 3000,
295
+ });
296
+ const response: SnmpMonitorResponse = buildResponse([iface]);
297
+
298
+ SnmpInterfaceRateUtil.attachInterfaceRates({
299
+ snmpResponse: response,
300
+ previousWalkLog: previousWalkLog({
301
+ interfaces: [
302
+ { interfaceIndex: 1, inOctets: 4000000000, outOctets: 1500 },
303
+ ],
304
+ }),
305
+ });
306
+
307
+ expect(iface.inBitsPerSecond).toBeUndefined();
308
+ expect(iface.outBitsPerSecond).toBe(200);
309
+ });
310
+
311
+ test("a negative error delta leaves errorsPerSecond unset when both directions wrapped", () => {
312
+ const iface: SnmpInterface = currentInterface({
313
+ inErrors: 1,
314
+ outErrors: 1,
315
+ });
316
+ const response: SnmpMonitorResponse = buildResponse([iface]);
317
+
318
+ SnmpInterfaceRateUtil.attachInterfaceRates({
319
+ snmpResponse: response,
320
+ previousWalkLog: previousWalkLog({
321
+ interfaces: [{ interfaceIndex: 1, inErrors: 500, outErrors: 500 }],
322
+ }),
323
+ });
324
+
325
+ expect(iface.errorsPerSecond).toBeUndefined();
326
+ });
327
+
328
+ test("a zero delta is a valid rate of 0, not a wrap", () => {
329
+ const iface: SnmpInterface = currentInterface({ inOctets: 750 });
330
+ const response: SnmpMonitorResponse = buildResponse([iface]);
331
+
332
+ SnmpInterfaceRateUtil.attachInterfaceRates({
333
+ snmpResponse: response,
334
+ previousWalkLog: previousWalkLog({
335
+ interfaces: [{ interfaceIndex: 1, inOctets: 750 }],
336
+ }),
337
+ });
338
+
339
+ expect(iface.inBitsPerSecond).toBe(0);
340
+ });
341
+ });
342
+
343
+ describe("SnmpInterfaceRateUtil.attachInterfaceRates — utilization", () => {
344
+ test("utilizationPercent comes from the busiest direction against the link speed", () => {
345
+ const iface: SnmpInterface = currentInterface({
346
+ inOctets: 750,
347
+ outOctets: 1500,
348
+ speedInBitsPerSecond: 1000,
349
+ });
350
+ const response: SnmpMonitorResponse = buildResponse([iface]);
351
+
352
+ SnmpInterfaceRateUtil.attachInterfaceRates({
353
+ snmpResponse: response,
354
+ previousWalkLog: previousWalkLog({
355
+ interfaces: [{ interfaceIndex: 1, inOctets: 0, outOctets: 0 }],
356
+ }),
357
+ });
358
+
359
+ expect(iface.inBitsPerSecond).toBe(100);
360
+ expect(iface.outBitsPerSecond).toBe(200);
361
+ // Busiest direction is out at 200 bps of a 1000 bps link → 20%.
362
+ expect(iface.utilizationPercent).toBe(20);
363
+ });
364
+
365
+ test("utilization is computed when only one direction has a rate", () => {
366
+ const iface: SnmpInterface = currentInterface({
367
+ inOctets: 750,
368
+ speedInBitsPerSecond: 1000,
369
+ });
370
+ const response: SnmpMonitorResponse = buildResponse([iface]);
371
+
372
+ SnmpInterfaceRateUtil.attachInterfaceRates({
373
+ snmpResponse: response,
374
+ previousWalkLog: previousWalkLog({
375
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
376
+ }),
377
+ });
378
+
379
+ expect(iface.utilizationPercent).toBe(10);
380
+ });
381
+
382
+ test("no link speed means no utilization even when rates exist", () => {
383
+ const iface: SnmpInterface = currentInterface({ inOctets: 750 });
384
+ const response: SnmpMonitorResponse = buildResponse([iface]);
385
+
386
+ SnmpInterfaceRateUtil.attachInterfaceRates({
387
+ snmpResponse: response,
388
+ previousWalkLog: previousWalkLog({
389
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
390
+ }),
391
+ });
392
+
393
+ expect(iface.inBitsPerSecond).toBe(100);
394
+ expect(iface.utilizationPercent).toBeUndefined();
395
+ });
396
+
397
+ test("a zero link speed never divides", () => {
398
+ const iface: SnmpInterface = currentInterface({
399
+ inOctets: 750,
400
+ speedInBitsPerSecond: 0,
401
+ });
402
+ const response: SnmpMonitorResponse = buildResponse([iface]);
403
+
404
+ SnmpInterfaceRateUtil.attachInterfaceRates({
405
+ snmpResponse: response,
406
+ previousWalkLog: previousWalkLog({
407
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
408
+ }),
409
+ });
410
+
411
+ expect(iface.utilizationPercent).toBeUndefined();
412
+ });
413
+
414
+ test("no utilization when both directions wrapped", () => {
415
+ const iface: SnmpInterface = currentInterface({
416
+ inOctets: 1,
417
+ outOctets: 1,
418
+ speedInBitsPerSecond: 1000,
419
+ });
420
+ const response: SnmpMonitorResponse = buildResponse([iface]);
421
+
422
+ SnmpInterfaceRateUtil.attachInterfaceRates({
423
+ snmpResponse: response,
424
+ previousWalkLog: previousWalkLog({
425
+ interfaces: [{ interfaceIndex: 1, inOctets: 999, outOctets: 999 }],
426
+ }),
427
+ });
428
+
429
+ expect(iface.inBitsPerSecond).toBeUndefined();
430
+ expect(iface.outBitsPerSecond).toBeUndefined();
431
+ expect(iface.utilizationPercent).toBeUndefined();
432
+ });
433
+ });
434
+
435
+ describe("SnmpInterfaceRateUtil.attachInterfaceRates — interface matching", () => {
436
+ test("an interface only present in the current walk is skipped", () => {
437
+ const newIface: SnmpInterface = currentInterface({
438
+ interfaceIndex: 9,
439
+ inOctets: 750,
440
+ speedInBitsPerSecond: 1000,
441
+ });
442
+ const knownIface: SnmpInterface = currentInterface({
443
+ interfaceIndex: 1,
444
+ inOctets: 750,
445
+ });
446
+ const response: SnmpMonitorResponse = buildResponse([newIface, knownIface]);
447
+
448
+ SnmpInterfaceRateUtil.attachInterfaceRates({
449
+ snmpResponse: response,
450
+ previousWalkLog: previousWalkLog({
451
+ interfaces: [{ interfaceIndex: 1, inOctets: 0 }],
452
+ }),
453
+ });
454
+
455
+ // Index 9 has no previous counters — nothing to delta against.
456
+ expect(newIface.inBitsPerSecond).toBeUndefined();
457
+ expect(newIface.utilizationPercent).toBeUndefined();
458
+ // Index 1 still gets its rate; a new port never blocks the others.
459
+ expect(knownIface.inBitsPerSecond).toBe(100);
460
+ });
461
+
462
+ test("previous interfaces without a numeric interfaceIndex are ignored", () => {
463
+ const iface: SnmpInterface = currentInterface({ inOctets: 750 });
464
+ const response: SnmpMonitorResponse = buildResponse([iface]);
465
+
466
+ SnmpInterfaceRateUtil.attachInterfaceRates({
467
+ snmpResponse: response,
468
+ previousWalkLog: previousWalkLog({
469
+ interfaces: [{ interfaceIndex: "1", inOctets: 0 }],
470
+ }),
471
+ });
472
+
473
+ expect(iface.inBitsPerSecond).toBeUndefined();
474
+ });
475
+
476
+ test("interfaces are matched by interfaceIndex, not array position", () => {
477
+ const iface: SnmpInterface = currentInterface({
478
+ interfaceIndex: 2,
479
+ inOctets: 750,
480
+ });
481
+ const response: SnmpMonitorResponse = buildResponse([iface]);
482
+
483
+ SnmpInterfaceRateUtil.attachInterfaceRates({
484
+ snmpResponse: response,
485
+ previousWalkLog: previousWalkLog({
486
+ interfaces: [
487
+ // Different order and an unrelated port first.
488
+ { interfaceIndex: 7, inOctets: 999999 },
489
+ { interfaceIndex: 2, inOctets: 0 },
490
+ ],
491
+ }),
492
+ });
493
+
494
+ expect(iface.inBitsPerSecond).toBe(100);
495
+ });
496
+ });
@@ -0,0 +1,175 @@
1
+ import MonitorCriteriaDataExtractor from "../../../Server/Utils/Monitor/MonitorCriteriaDataExtractor";
2
+ import DataToProcess from "../../../Server/Utils/Monitor/DataToProcess";
3
+ import AggregatedResult from "../../../Types/BaseDatabase/AggregatedResult";
4
+ import { CriteriaFilter } from "../../../Types/Monitor/CriteriaFilter";
5
+ import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
6
+ import MonitorStep from "../../../Types/Monitor/MonitorStep";
7
+ import ObjectID from "../../../Types/ObjectID";
8
+ import { describe, expect, test } from "@jest/globals";
9
+
10
+ /*
11
+ * MonitorCriteriaDataExtractor discriminates the DataToProcess union into a
12
+ * concrete monitor-response shape using presence checks on marker fields
13
+ * (hostname, logCount, spanCount, ...). If one of those markers changes, the
14
+ * whole criteria-evaluation pipeline silently starts feeding the wrong
15
+ * evaluator. These tests lock the discrimination + the numeric extraction in
16
+ * extractMetricValues.
17
+ */
18
+
19
+ const projectId: ObjectID = new ObjectID("project");
20
+ const monitorId: ObjectID = new ObjectID("monitor");
21
+
22
+ function metricResponse(
23
+ metricResult: Array<AggregatedResult>,
24
+ ): MetricMonitorResponse {
25
+ return {
26
+ projectId,
27
+ monitorId,
28
+ metricResult,
29
+ metricViewConfig: { queryConfigs: [], formulaConfigs: [] },
30
+ };
31
+ }
32
+
33
+ describe("MonitorCriteriaDataExtractor discriminators", () => {
34
+ test("getServerMonitorResponse matches on hostname", () => {
35
+ const server: DataToProcess = {
36
+ hostname: "host-1",
37
+ } as unknown as DataToProcess;
38
+
39
+ expect(MonitorCriteriaDataExtractor.getServerMonitorResponse(server)).toBe(
40
+ server,
41
+ );
42
+ expect(
43
+ MonitorCriteriaDataExtractor.getServerMonitorResponse({
44
+ logCount: 0,
45
+ } as unknown as DataToProcess),
46
+ ).toBeNull();
47
+ });
48
+
49
+ test("getProbeMonitorResponse matches on monitorStepId", () => {
50
+ const probe: DataToProcess = {
51
+ monitorStepId: new ObjectID("step"),
52
+ } as unknown as DataToProcess;
53
+
54
+ expect(MonitorCriteriaDataExtractor.getProbeMonitorResponse(probe)).toBe(
55
+ probe,
56
+ );
57
+ expect(
58
+ MonitorCriteriaDataExtractor.getProbeMonitorResponse(
59
+ {} as unknown as DataToProcess,
60
+ ),
61
+ ).toBeNull();
62
+ });
63
+
64
+ test("getLogMonitorResponse matches when logCount is defined (even 0)", () => {
65
+ const log: DataToProcess = {
66
+ logCount: 0,
67
+ } as unknown as DataToProcess;
68
+
69
+ expect(MonitorCriteriaDataExtractor.getLogMonitorResponse(log)).toBe(log);
70
+ });
71
+
72
+ test("getTraceMonitorResponse matches when spanCount is defined", () => {
73
+ const trace: DataToProcess = {
74
+ spanCount: 5,
75
+ } as unknown as DataToProcess;
76
+
77
+ expect(MonitorCriteriaDataExtractor.getTraceMonitorResponse(trace)).toBe(
78
+ trace,
79
+ );
80
+ expect(
81
+ MonitorCriteriaDataExtractor.getTraceMonitorResponse({
82
+ hostname: "x",
83
+ } as unknown as DataToProcess),
84
+ ).toBeNull();
85
+ });
86
+
87
+ test("getExceptionMonitorResponse matches when exceptionCount is defined", () => {
88
+ const exception: DataToProcess = {
89
+ exceptionCount: 3,
90
+ } as unknown as DataToProcess;
91
+
92
+ expect(
93
+ MonitorCriteriaDataExtractor.getExceptionMonitorResponse(exception),
94
+ ).toBe(exception);
95
+ });
96
+
97
+ test("getIncomingMonitorRequest matches when incomingRequestReceivedAt is defined", () => {
98
+ const incoming: DataToProcess = {
99
+ incomingRequestReceivedAt: new Date(),
100
+ } as unknown as DataToProcess;
101
+
102
+ expect(
103
+ MonitorCriteriaDataExtractor.getIncomingMonitorRequest(incoming),
104
+ ).toBe(incoming);
105
+ });
106
+
107
+ test("getMetricMonitorResponse matches when metricResult is defined", () => {
108
+ const metric: DataToProcess = metricResponse([]) as DataToProcess;
109
+ expect(MonitorCriteriaDataExtractor.getMetricMonitorResponse(metric)).toBe(
110
+ metric,
111
+ );
112
+ });
113
+
114
+ test("nested probe extractors return empty/null when not a probe", () => {
115
+ const notProbe: DataToProcess = {
116
+ hostname: "x",
117
+ } as unknown as DataToProcess;
118
+
119
+ expect(
120
+ MonitorCriteriaDataExtractor.getSyntheticMonitorResponses(notProbe),
121
+ ).toEqual([]);
122
+ expect(MonitorCriteriaDataExtractor.getSslResponse(notProbe)).toBeNull();
123
+ expect(
124
+ MonitorCriteriaDataExtractor.getCustomCodeMonitorResponse(notProbe),
125
+ ).toBeNull();
126
+ });
127
+ });
128
+
129
+ describe("MonitorCriteriaDataExtractor.extractMetricValues", () => {
130
+ const emptyFilter: CriteriaFilter = {} as CriteriaFilter;
131
+
132
+ test("returns null when the data is not a metric response", () => {
133
+ const result: { alias: string | null; values: Array<number> } | null =
134
+ MonitorCriteriaDataExtractor.extractMetricValues({
135
+ criteriaFilter: emptyFilter,
136
+ dataToProcess: { hostname: "x" } as unknown as DataToProcess,
137
+ monitorStep: new MonitorStep(),
138
+ });
139
+
140
+ expect(result).toBeNull();
141
+ });
142
+
143
+ test("returns empty values when the metric result set is empty", () => {
144
+ const result: { alias: string | null; values: Array<number> } | null =
145
+ MonitorCriteriaDataExtractor.extractMetricValues({
146
+ criteriaFilter: {
147
+ metricMonitorOptions: { metricAlias: "cpu" },
148
+ } as CriteriaFilter,
149
+ dataToProcess: metricResponse([]) as DataToProcess,
150
+ monitorStep: new MonitorStep(),
151
+ });
152
+
153
+ expect(result).toEqual({ alias: "cpu", values: [] });
154
+ });
155
+
156
+ test("extracts numeric values from the first result and drops NaN", () => {
157
+ const aggregated: AggregatedResult = {
158
+ data: [
159
+ { timestamp: new Date(), value: 10 },
160
+ { timestamp: new Date(), value: NaN },
161
+ { timestamp: new Date(), value: 20 },
162
+ ],
163
+ };
164
+
165
+ const result: { alias: string | null; values: Array<number> } | null =
166
+ MonitorCriteriaDataExtractor.extractMetricValues({
167
+ criteriaFilter: emptyFilter,
168
+ dataToProcess: metricResponse([aggregated]) as DataToProcess,
169
+ monitorStep: new MonitorStep(),
170
+ });
171
+
172
+ expect(result).not.toBeNull();
173
+ expect(result!.values).toEqual([10, 20]);
174
+ });
175
+ });