From bf3ac465bdea9fa38a2b23de2dd42ab77ede9a98 Mon Sep 17 00:00:00 2001 From: Nassim Boutekedjiret Date: Tue, 7 Jan 2025 19:25:21 +0100 Subject: [PATCH 1/2] Issue #71: Display platform tiles in the connectors directory * Updated main Mojo and producers to produce the new pages. --- pom.xml | 4 +- src/it/metricshub-connectors/pom.xml | 1 + .../main/connector/database/MySQL/MySQL.yaml | 2 +- .../connector/hardware/DiskPart/DiskPart.yaml | 2 +- .../hardware/GenBatteryNT/GenBatteryNT.yaml | 2 +- .../GenericSwitchEnclosure.yaml | 2 +- .../hardware/GenericUPS/GenericUPS.yaml | 2 +- .../connector/hardware/HyperV/HyperV.yaml | 2 +- .../connector/hardware/IpmiTool/IpmiTool.yaml | 2 +- .../LibreHardwareMonitor.yaml | 2 +- .../LinuxIPNetwork/LinuxIPNetwork.yaml | 2 +- .../LinuxIfConfigNetwork.yaml | 2 +- .../LinuxMultipath/LinuxMultipath.yaml | 2 +- .../main/connector/hardware/MIB2/MIB2.yaml | 2 +- .../hardware/MIB2Linux/MIB2Linux.yaml | 2 +- .../connector/hardware/MIB2NT/MIB2NT.yaml | 2 +- .../hardware/MIB2Switch/MIB2Switch.yaml | 2 +- .../hardware/NvidiaSmi/NvidiaSmi.yaml | 2 +- .../main/connector/hardware/Virsh/Virsh.yaml | 6 +- .../hardware/WBEMGenDiskNT/WBEMGenDiskNT.yaml | 2 +- .../hardware/WBEMGenHBA/WBEMGenHBA.yaml | 2 +- .../hardware/WBEMGenLUN/WBEMGenLUN.yaml | 2 +- .../WBEMGenNetwork/WBEMGenNetwork.yaml | 2 +- .../WinStorageSpaces/WinStorageSpaces.yaml | 2 +- .../hardware/lmsensors/lmsensors.yaml | 2 +- .../src/site/resources/css/site.css | 103 +++++++- .../images/platforms/ethernet-switch.png | Bin 0 -> 994 bytes .../resources/images/platforms/hyper-v.png | Bin 0 -> 994 bytes .../images/platforms/hypervisors.png | Bin 0 -> 994 bytes .../site/resources/images/platforms/ipmi.png | Bin 0 -> 994 bytes .../site/resources/images/platforms/kvm.png | Bin 0 -> 994 bytes .../site/resources/images/platforms/linux.png | Bin 0 -> 994 bytes .../images/platforms/microsoft-windows.png | Bin 0 -> 994 bytes .../resources/images/platforms/my-sql.png | Bin 0 -> 994 bytes .../resources/images/platforms/nvidia.png | Bin 0 -> 994 bytes .../site/resources/images/platforms/qemu.png | Bin 0 -> 994 bytes .../images/platforms/system-with-snmp.png | Bin 0 -> 994 bytes .../site/resources/images/platforms/ups.png | Bin 0 -> 994 bytes .../site/resources/images/platforms/xen.png | Bin 0 -> 994 bytes .../metricshub-connectors/src/site/site.xml | 1 + src/it/metricshub-connectors/verify.groovy | 221 ++++++++++++------ .../connector/AbstractConnectorReport.java | 6 + .../connector/ConnectorsDirectoryReport.java | 182 +++++++++++++-- .../maven/metricshub/connector/Constants.java | 20 ++ .../AbstractGroupConnectorsProducer.java | 98 ++++++++ .../producer/AbstractPageProducer.java | 23 +- .../producer/ConnectorJsonNodeReader.java | 110 +++++---- .../producer/ConnectorPageProducer.java | 69 ++++-- ...ucer.java => FullListingPageProducer.java} | 22 +- .../connector/producer/JsonNodeHelper.java | 55 +++-- .../producer/PlatformsPageProducer.java | 136 +++++++++++ .../connector/producer/SinkHelper.java | 64 ++++- .../SpecificPlatformPageProducer.java | 75 ++++++ .../connector/producer/TagPageProducer.java | 44 +--- .../producer/model/platform/Platform.java | 164 +++++-------- .../connector/producer/package-info.java | 3 +- 56 files changed, 1058 insertions(+), 393 deletions(-) create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/ethernet-switch.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/hyper-v.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/hypervisors.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/ipmi.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/kvm.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/linux.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/microsoft-windows.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/my-sql.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/nvidia.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/qemu.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/system-with-snmp.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/ups.png create mode 100644 src/it/metricshub-connectors/src/site/resources/images/platforms/xen.png create mode 100644 src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractGroupConnectorsProducer.java rename src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/{MainPageProducer.java => FullListingPageProducer.java} (87%) create mode 100644 src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/PlatformsPageProducer.java create mode 100644 src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SpecificPlatformPageProducer.java diff --git a/pom.xml b/pom.xml index 5d5040c..f6d965b 100644 --- a/pom.xml +++ b/pom.xml @@ -68,8 +68,8 @@ - - 11 + + 17 diff --git a/src/it/metricshub-connectors/pom.xml b/src/it/metricshub-connectors/pom.xml index 660879f..13ed174 100644 --- a/src/it/metricshub-connectors/pom.xml +++ b/src/it/metricshub-connectors/pom.xml @@ -5,6 +5,7 @@ org.sentrysoftware.maven metricshub-connectors + MetricsHub 1.0.00-SNAPSHOT pom diff --git a/src/it/metricshub-connectors/src/main/connector/database/MySQL/MySQL.yaml b/src/it/metricshub-connectors/src/main/connector/database/MySQL/MySQL.yaml index 3fa687a..7e15503 100644 --- a/src/it/metricshub-connectors/src/main/connector/database/MySQL/MySQL.yaml +++ b/src/it/metricshub-connectors/src/main/connector/database/MySQL/MySQL.yaml @@ -2,7 +2,7 @@ extends: - ../Database/Database connector: displayName: MySQL - platforms: Any platform running MySQL + platforms: MySQL reliesOn : MySQL Database information: Monitors performance and operational metrics for a MySQL database. detection: diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/DiskPart/DiskPart.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/DiskPart/DiskPart.yaml index c544405..47f3fc4 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/DiskPart/DiskPart.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/DiskPart/DiskPart.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Windows - DiskPart - platforms: Any system + platforms: Microsoft Windows reliesOn: The DISKPART.EXE command-line utility information: "Discovers and monitors the logical disks in a Microsoft Windows system through the DISKPART.EXE utility, notably the software RAID volumes." version: 1.0 diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/GenBatteryNT/GenBatteryNT.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/GenBatteryNT/GenBatteryNT.yaml index a90e58a..8441040 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/GenBatteryNT/GenBatteryNT.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/GenBatteryNT/GenBatteryNT.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: WMI - Battery - platforms: Any system + platforms: Microsoft Windows reliesOn: WMI version: 1.0 information: This connector provides battery monitoring for Windows computers. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/GenericSwitchEnclosure/GenericSwitchEnclosure.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/GenericSwitchEnclosure/GenericSwitchEnclosure.yaml index aa33bc2..3412274 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/GenericSwitchEnclosure/GenericSwitchEnclosure.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/GenericSwitchEnclosure/GenericSwitchEnclosure.yaml @@ -4,7 +4,7 @@ extends: - ../MIB2-header/MIB2-header connector: displayName: Generic Ethernet Switch - platforms: MIB-2 Supported Switch + platforms: Ethernet Switch reliesOn: MIB-2 SNMP version: 1.0 information: This connector provides an enclosure for Ethernet switches that do not provide one of their own. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/GenericUPS/GenericUPS.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/GenericUPS/GenericUPS.yaml index 1d040af..b654ba9 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/GenericUPS/GenericUPS.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/GenericUPS/GenericUPS.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Generic UPS - platforms: Any UPS which supports UPS-MIB (RFC1628) + platforms: UPS version: 1.0 information: This connector provides hardware monitoring of MIB-2 Standard UPS through an SNMP interface. detection: diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/HyperV/HyperV.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/HyperV/HyperV.yaml index ea3f710..780e9bc 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/HyperV/HyperV.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/HyperV/HyperV.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Hyper-V - platforms: Hyper-V Servers + platforms: Hyper-V reliesOn: PowerShell version: 1.0 information: This connector provides hardware monitoring through Hyper-V PowerShell cmdlets. The user requires Hyper-V Administrators membership. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/IpmiTool/IpmiTool.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/IpmiTool/IpmiTool.yaml index 0817ab8..3deb5f3 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/IpmiTool/IpmiTool.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/IpmiTool/IpmiTool.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: IPMI - platforms: Any system with IPMI + platforms: IPMI reliesOn: IPMI information: "Gives environmental information (temperatures, fans, etc.) on several IPMI-enabled servers in-band and out-of-band." version: 2.0 diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/LibreHardwareMonitor/LibreHardwareMonitor.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/LibreHardwareMonitor/LibreHardwareMonitor.yaml index 823d4b4..f0e02ac 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/LibreHardwareMonitor/LibreHardwareMonitor.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/LibreHardwareMonitor/LibreHardwareMonitor.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Libre Hardware Monitor - platforms: Any Windows system + platforms: Microsoft Windows reliesOn: Libre Hardware Monitor information: "This connector provides the hardware monitoring of Processors, Temperatures, Fans, Voltages, GPU, Memory Modules, Physical Disk of a computer." detection: diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIPNetwork/LinuxIPNetwork.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIPNetwork/LinuxIPNetwork.yaml index c8ec2bd..26ba4a3 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIPNetwork/LinuxIPNetwork.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIPNetwork/LinuxIPNetwork.yaml @@ -7,7 +7,7 @@ constants: COLLECT_COMMAND_LINE: "/sbin/ip -s link show dev ${attribute::id}" connector: displayName: Linux - Network (ip) - platforms: Any system + platforms: Linux reliesOn: Linux system commands (ip) version: 1.0 information: This connector provides the monitoring of active network cards on all Linux systems using ip command. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIfConfigNetwork/LinuxIfConfigNetwork.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIfConfigNetwork/LinuxIfConfigNetwork.yaml index 6d95a94..f4c57d0 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIfConfigNetwork/LinuxIfConfigNetwork.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/LinuxIfConfigNetwork/LinuxIfConfigNetwork.yaml @@ -7,7 +7,7 @@ constants: COLLECT_COMMAND_LINE: "/sbin/ifconfig -a ${attribute::id}" connector: displayName: Linux - Network (ifconfig) - platforms: Any system + platforms: Linux reliesOn: Linux system commands (ifconfig) version: 1.0 information: This connector provides the monitoring of active network cards on all Linux systems using ifconfig command. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/LinuxMultipath/LinuxMultipath.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/LinuxMultipath/LinuxMultipath.yaml index 009e3b7..d82ee18 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/LinuxMultipath/LinuxMultipath.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/LinuxMultipath/LinuxMultipath.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Linux - Multipath - platforms: Any system with multipath + platforms: Linux reliesOn: Linux multipath utility version: 1.0 information: This connector provides the monitoring of HBA cards on all Linux systems through the multipath utility. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2/MIB2.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2/MIB2.yaml index cab7063..a5df5bb 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2/MIB2.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2/MIB2.yaml @@ -4,7 +4,7 @@ extends: - ../MIB2-header/MIB2-header connector: displayName: MIB-2 Standard SNMP Agent - Network Interfaces - platforms: Any system with SNMP + platforms: System with SNMP detection: appliesTo: - Network diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Linux/MIB2Linux.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Linux/MIB2Linux.yaml index ab08c0b..b095d82 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Linux/MIB2Linux.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Linux/MIB2Linux.yaml @@ -4,7 +4,7 @@ extends: - ../MIB2-header/MIB2-header connector: displayName: MIB-2 Standard SNMP Agent - Network Interfaces - Linux - platforms: Any system with SNMP + platforms: Linux detection: appliesTo: - Linux diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2NT/MIB2NT.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2NT/MIB2NT.yaml index c7bef2a..b26aae6 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2NT/MIB2NT.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2NT/MIB2NT.yaml @@ -4,7 +4,7 @@ extends: - ../MIB2-header/MIB2-header connector: displayName: MIB-2 Standard SNMP Agent - Network Interfaces - Windows - platforms: Any system with SNMP + platforms: Microsoft Windows detection: appliesTo: - NT diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Switch/MIB2Switch.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Switch/MIB2Switch.yaml index 1ef4470..f1604ed 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Switch/MIB2Switch.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/MIB2Switch/MIB2Switch.yaml @@ -9,7 +9,7 @@ constants: _DEVICE_ID: EthernetSwitch connector: displayName: Ethernet Switch with Sensors (SNMP) - platforms: MIB-2 and Entity-Sensor-MIB Supported Switch + platforms: Ethernet Switch reliesOn: "MIB-2, Entity-Sensor-MIB, SNMP" version: 1.0 information: This connector provides an enclosure and sensors for Ethernet switches that provide it. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/NvidiaSmi/NvidiaSmi.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/NvidiaSmi/NvidiaSmi.yaml index 70e0161..f193249 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/NvidiaSmi/NvidiaSmi.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/NvidiaSmi/NvidiaSmi.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Nvidia-Smi - platforms: Any system with Nvidia GPUs + platforms: Nvidia reliesOn: NVIDIA drivers with NVIDIA-SMI support. information: Gives hardware information on most Nvidia GPUs. (Clocking) detection: diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/Virsh/Virsh.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/Virsh/Virsh.yaml index e7c0ffa..9728489 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/Virsh/Virsh.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/Virsh/Virsh.yaml @@ -3,7 +3,11 @@ extends: - ../Hardware/Hardware connector: displayName: "KVM, QEMU, Xen and Hypervisors (virsh)" - platforms: "KVM, QEMU, Xen, Hypervisors" + platforms: + - KVM + - QEMU + - Xen + - Hypervisors reliesOn: libvirt API version: 1.0 information: This connector provides VM monitoring through the virsh command. The host requires the libvirt API installed. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenDiskNT/WBEMGenDiskNT.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenDiskNT/WBEMGenDiskNT.yaml index 1115691..f26eb18 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenDiskNT/WBEMGenDiskNT.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenDiskNT/WBEMGenDiskNT.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: WMI - Disks - platforms: Any system + platforms: Microsoft Windows reliesOn: WMI version: 1.1 information: This connector provides monitoring of the S.M.A.R.T.-enabled disks that are directly handled by Windows (and WBEM through the WMI service). It tries to exclude disks that are actually logical disks exposed by some RAID controllers. diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenHBA/WBEMGenHBA.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenHBA/WBEMGenHBA.yaml index 087c037..a48dd11 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenHBA/WBEMGenHBA.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenHBA/WBEMGenHBA.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: WMI - HBA - platforms: Any system + platforms: Microsoft Windows reliesOn: WMI version: 0.9 information: This connector provides the monitoring of HBA cards on all Windows-based systems through the WMI layer (root/WMI namespace). diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenLUN/WBEMGenLUN.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenLUN/WBEMGenLUN.yaml index e3a2412..381db2b 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenLUN/WBEMGenLUN.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenLUN/WBEMGenLUN.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: WMI - LUN - platforms: Any system + platforms: Microsoft Windows reliesOn: WMI version: 0.9 information: This connector provides the monitoring of LUNs on all Windows-based systems through the WMI layer (root/WMI namespace). diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenNetwork/WBEMGenNetwork.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenNetwork/WBEMGenNetwork.yaml index 4f53feb..c3cb568 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenNetwork/WBEMGenNetwork.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/WBEMGenNetwork/WBEMGenNetwork.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: WMI - Network - platforms: Any system + platforms: Microsoft Windows reliesOn: WMI version: 1.3 information: This connector provides the monitoring of network cards on all Windows-based systems through the WMI layer (root/WMI namespace). diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/WinStorageSpaces/WinStorageSpaces.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/WinStorageSpaces/WinStorageSpaces.yaml index f9110c1..6449717 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/WinStorageSpaces/WinStorageSpaces.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/WinStorageSpaces/WinStorageSpaces.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: Windows Storage Spaces (WMI) - platforms: Any system + platforms: Microsoft Windows reliesOn: Windows Storage Spaces information: "This connector provides monitoring physical disks through Windows Storage Management's WMI provider. It supports all disk types, including disks on NVMe bus and NVDIMM. When available, temperature sensors are also discovered and monitored." detection: diff --git a/src/it/metricshub-connectors/src/main/connector/hardware/lmsensors/lmsensors.yaml b/src/it/metricshub-connectors/src/main/connector/hardware/lmsensors/lmsensors.yaml index 082b2f8..dea40b8 100644 --- a/src/it/metricshub-connectors/src/main/connector/hardware/lmsensors/lmsensors.yaml +++ b/src/it/metricshub-connectors/src/main/connector/hardware/lmsensors/lmsensors.yaml @@ -3,7 +3,7 @@ extends: - ../Hardware/Hardware connector: displayName: lm_sensors - platforms: Any system + platforms: Linux reliesOn: lm_sensors information: "Provides the monitoring environment sensors on Linux, through the sensors command." version: 1.1 diff --git a/src/it/metricshub-connectors/src/site/resources/css/site.css b/src/it/metricshub-connectors/src/site/resources/css/site.css index 631a17e..d3594c5 100644 --- a/src/it/metricshub-connectors/src/site/resources/css/site.css +++ b/src/it/metricshub-connectors/src/site/resources/css/site.css @@ -26,4 +26,105 @@ color: white; text-decoration: none; font-size: small; -} \ No newline at end of file +} + +.custom-class .platform-tile-container { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + padding: 10px; + width: 100%; +} + +.custom-class .platform-tile { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + background: rgb(237 237 237); + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + text-align: center; + padding: 20px; + transition: transform 0.3s ease, box-shadow 0.3s ease; + text-decoration: none; + color: inherit; +} + +.custom-class .platform-tile:hover { + transform: translateY(-5px); + box-shadow: 0 8px 12px rgba(0, 0, 0, 0.2); + cursor: pointer; +} + +.custom-class .platform-tile .platform-title { + font-size: 18px; + margin-bottom: 15px; + color: #333; + text-align: center; + min-height: 50px; + display: flex; + align-items: center; + justify-content: center; +} + +.custom-class .platform-tile .platform-connectors { + font-size: 14px; + margin-bottom: 15px; + color: #333; + text-align: center; + min-height: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +.custom-class .platform-tile .platform-icon { + width: 80px; + height: 80px; + background-size: cover; + background-position: center; +} + +.custom-class .platform-tile .platform-badges { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; + margin-top: 10px; + width: 100%; +} + +.custom-class .platform-tile .badge { + font-size: 10px; + border-radius: 10px; + padding: 5px 10px; + text-align: center; + white-space: nowrap; +} + +.custom-class .platform-tile div:last-child { + margin-top: auto; +} + +@media (max-width: 1200px) and (min-width: 993px) { + .custom-class .platform-tile-container { + grid-template-columns: repeat(3, 1fr); + } +} + +@media (max-width: 992px) and (min-width: 769px) { + .custom-class .platform-tile-container { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + .custom-class .platform-tile-container { + grid-template-columns: repeat(1, 1fr); + } + + .custom-class .platform-tile { + padding: 40px; + } +} diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/ethernet-switch.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/ethernet-switch.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/hyper-v.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/hyper-v.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/hypervisors.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/hypervisors.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/ipmi.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/ipmi.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/kvm.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/kvm.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/linux.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/linux.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/microsoft-windows.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/microsoft-windows.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/my-sql.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/my-sql.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/nvidia.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/nvidia.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/qemu.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/qemu.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/system-with-snmp.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/system-with-snmp.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/ups.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/ups.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/resources/images/platforms/xen.png b/src/it/metricshub-connectors/src/site/resources/images/platforms/xen.png new file mode 100644 index 0000000000000000000000000000000000000000..84a8e2c5a0432b40654f0552d4a00175633d3b4b GIT binary patch literal 994 zcmV<810DQ{P)gXpaw~L8WC{HkZQ-8emo%pz z_xyh6^rq+D`h3KQ5hF&7*ny2>&_#|$8J0#{9F4FWpv97Ds7ze&mD4yTahYR;9j6JG z1S9M;()^{ekgut!ImuCI76$4`Wbx;@WjwpE<_bV85R)ndKLfGaE&xlTYcN3D9TCsu zR~;w47Z6k1T~QN3sIZm1cttz`%EH5kQ{sFU@RE3)VRg-Q!6-fTims^3PfG@)6&OcAZ|rknzXkH zSS|alq0Zlh?7JFME4a0~>z6H6AbKqOwpRhGWxplZvE_;E>#E?<&CU%=RUqoJpL#X% z$8k~yk&-5MEmZ+W3l&QCtDdiVD*L)BXs+s50S*n7=&E4>SPIE-^I&&w-ElG|G0-!v zyap_Vvc@ZbLYr{&`^hE8iI@e%uFL}z+B7Zz?SkgUMi2pv8mB2I=e~IwmMcJZ0SO{N z?tc-o9~N;kmc=c>Bz*MXWPC*NmAwLD_aq#@FO}7I5CCDNL-h+d;#Xq@U)crV_VL^4 z13^m7p=c{D2A7+V~Pmivt59Zu|@p)-2zUJe#NQLeDQ&BT!5XvXl-vv0Up=( z7O!g#CKb{^ekl}Jj==}#AXbPuJGN+DfV3{yLV)@}%HcZ*P~?sF3aEf%Au{~WHR-o` z>jI<<26k8&l;;%@AnO1)2H)Q6tO&3UH%ggl$H|(7l$lZ21t@;axBwJ-2{*^;`aCHD zkZ-FiE})9W1*m*-w(-WZZKuECtpYeaWP~$@1$f}+&vA^PbcCKpK-hp}8Ww=1`EGbX zB0PwP%`&*MaRz``p)tCJu+$Z0ZGL@+-I())i2x&@>ch?8CblU~42dI3y& zfgtGxFzE$GNiTp&FF=!C0Fz!IM|uIgR|Lyzg0jo^1)_cx$8ujF>PL7v6jKll9K(Hq zXhDGLxFW!@+!u%jRKPLW7m)4T7ogN%WW2Z}u3sA01XwpA0N;C5_61m)?=mbvQ=t8P zQ$YCX`F(-F)9o-5KjkxH>~;P$EGe@Tul;rD9YD;GdDG;H5hF&7nD6M@UldjzDkpk` Qpa1{>07*qoM6N<$f^5sfxBvhE literal 0 HcmV?d00001 diff --git a/src/it/metricshub-connectors/src/site/site.xml b/src/it/metricshub-connectors/src/site/site.xml index 6a2d8f1..2b967ee 100644 --- a/src/it/metricshub-connectors/src/site/site.xml +++ b/src/it/metricshub-connectors/src/site/site.xml @@ -30,6 +30,7 @@ + diff --git a/src/it/metricshub-connectors/verify.groovy b/src/it/metricshub-connectors/verify.groovy index 2514e72..fbc03a9 100644 --- a/src/it/metricshub-connectors/verify.groovy +++ b/src/it/metricshub-connectors/verify.groovy @@ -5,104 +5,107 @@ assert new File(basedir, "target/site/index.html").isFile() // Site checks for the Otel version // -// Main page: metricshub-connectors-directory.html -File htmlFile = new File(basedir, "target/site/metricshub-connectors-directory.html") -assert htmlFile.exists() : "Main metricshub-connectors-directory.html page must be created" +// Main page: metricshub-connectors-full-listing.html +File htmlFile = new File(basedir, "target/site/metricshub-connectors-full-listing.html") +assert htmlFile.exists() : "Main metricshub-connectors-full-listing.html page must be created" String htmlText = htmlFile.text -assert htmlText.indexOf("MIB2Switch") > -1 : "metricshub-connectors-directory: MIB2Switch must be listed" -assert htmlText.indexOf("GenericSwitchEnclosure") > -1 : "metricshub-connectors-directory: GenericSwitchEnclosure must be listed" -assert htmlText.indexOf("GenericUPS") > -1 : "metricshub-connectors-directory: GenericUPS must be listed" -assert htmlText.indexOf("HyperV") > -1 : "metricshub-connectors-directory: HyperV must be listed" -assert htmlText.indexOf("IpmiTool") > -1 : "metricshub-connectors-directory: IpmiTool must be listed" -assert htmlText.indexOf("Virsh") > -1 : "metricshub-connectors-directory: Virsh must be listed" -assert htmlText.indexOf("LibreHardwareMonitor") > -1 : "metricshub-connectors-directory: LibreHardwareMonitor must be listed" -assert htmlText.indexOf("LinuxMultipath") > -1 : "metricshub-connectors-directory: LinuxMultipath must be listed" -assert htmlText.indexOf("LinuxIfConfigNetwork") > -1 : "metricshub-connectors-directory: LinuxIfConfigNetwork must be listed" -assert htmlText.indexOf("LinuxIPNetwork") > -1 : "metricshub-connectors-directory: LinuxIPNetwork must be listed" -assert htmlText.indexOf("lmsensors") > -1 : "metricshub-connectors-directory: lmsensors must be listed" -assert htmlText.indexOf("MIB2") > -1 : "metricshub-connectors-directory: MIB2 must be listed" -assert htmlText.indexOf("MIB2Linux") > -1 : "metricshub-connectors-directory: MIB2Linux must be listed" -assert htmlText.indexOf("MIB2NT") > -1 : "metricshub-connectors-directory: MIB2NT must be listed" -assert htmlText.indexOf("NvidiaSmi") > -1 : "metricshub-connectors-directory: NvidiaSmi must be listed" -assert htmlText.indexOf("DiskPart") > -1 : "metricshub-connectors-directory: DiskPart must be listed" -assert htmlText.indexOf("WinStorageSpaces") > -1 : "metricshub-connectors-directory: WinStorageSpaces must be listed" -assert htmlText.indexOf("GenBatteryNT") > -1 : "metricshub-connectors-directory: GenBatteryNT must be listed" -assert htmlText.indexOf("WBEMGenDiskNT") > -1 : "metricshub-connectors-directory: WBEMGenDiskNT must be listed" -assert htmlText.indexOf("WBEMGenHBA") > -1 : "metricshub-connectors-directory: WBEMGenHBA must be listed" -assert htmlText.indexOf("WBEMGenLUN") > -1 : "metricshub-connectors-directory: WBEMGenLUN must be listed" -assert htmlText.indexOf("WBEMGenNetwork") > -1 : "metricshub-connectors-directory: WBEMGenNetwork must be listed" -assert htmlText.indexOf("MySQL") > -1 : "metricshub-connectors-directory: MySQL must be listed" +assert htmlText.indexOf("MIB2Switch") > -1 : "metricshub-connectors-full-listing: MIB2Switch must be listed" +assert htmlText.indexOf("GenericSwitchEnclosure") > -1 : "metricshub-connectors-full-listing: GenericSwitchEnclosure must be listed" +assert htmlText.indexOf("GenericUPS") > -1 : "metricshub-connectors-full-listing: GenericUPS must be listed" +assert htmlText.indexOf("HyperV") > -1 : "metricshub-connectors-full-listing: HyperV must be listed" +assert htmlText.indexOf("IpmiTool") > -1 : "metricshub-connectors-full-listing: IpmiTool must be listed" +assert htmlText.indexOf("Virsh") > -1 : "metricshub-connectors-full-listing: Virsh must be listed" +assert htmlText.indexOf("LibreHardwareMonitor") > -1 : "metricshub-connectors-full-listing: LibreHardwareMonitor must be listed" +assert htmlText.indexOf("LinuxMultipath") > -1 : "metricshub-connectors-full-listing: LinuxMultipath must be listed" +assert htmlText.indexOf("LinuxIfConfigNetwork") > -1 : "metricshub-connectors-full-listing: LinuxIfConfigNetwork must be listed" +assert htmlText.indexOf("LinuxIPNetwork") > -1 : "metricshub-connectors-full-listing: LinuxIPNetwork must be listed" +assert htmlText.indexOf("lmsensors") > -1 : "metricshub-connectors-full-listing: lmsensors must be listed" +assert htmlText.indexOf("MIB2") > -1 : "metricshub-connectors-full-listing: MIB2 must be listed" +assert htmlText.indexOf("MIB2Linux") > -1 : "metricshub-connectors-full-listing: MIB2Linux must be listed" +assert htmlText.indexOf("MIB2NT") > -1 : "metricshub-connectors-full-listing: MIB2NT must be listed" +assert htmlText.indexOf("NvidiaSmi") > -1 : "metricshub-connectors-full-listing: NvidiaSmi must be listed" +assert htmlText.indexOf("DiskPart") > -1 : "metricshub-connectors-full-listing: DiskPart must be listed" +assert htmlText.indexOf("WinStorageSpaces") > -1 : "metricshub-connectors-full-listing: WinStorageSpaces must be listed" +assert htmlText.indexOf("GenBatteryNT") > -1 : "metricshub-connectors-full-listing: GenBatteryNT must be listed" +assert htmlText.indexOf("WBEMGenDiskNT") > -1 : "metricshub-connectors-full-listing: WBEMGenDiskNT must be listed" +assert htmlText.indexOf("WBEMGenHBA") > -1 : "metricshub-connectors-full-listing: WBEMGenHBA must be listed" +assert htmlText.indexOf("WBEMGenLUN") > -1 : "metricshub-connectors-full-listing: WBEMGenLUN must be listed" +assert htmlText.indexOf("WBEMGenNetwork") > -1 : "metricshub-connectors-full-listing: WBEMGenNetwork must be listed" +assert htmlText.indexOf("MySQL") > -1 : "metricshub-connectors-full-listing: MySQL must be listed" // Check generated reference files String directoryPath = 'target/site/connectors' String [] fileNamesToCheck = [ - 'diskpart.html', - 'genbatterynt.html', - 'genericswitchenclosure.html', - 'genericups.html', - 'hyperv.html', - 'ipmitool.html', - 'librehardwaremonitor.html', - 'linuxifconfignetwork.html', - 'linuxipnetwork.html', - 'linuxmultipath.html', - 'lmsensors.html', - 'mib2.html', - 'mib2linux.html', - 'mib2nt.html', - 'mib2switch.html', - 'nvidiasmi.html', - 'virsh.html', - 'wbemgendisknt.html', - 'wbemgenhba.html', - 'wbemgenlun.html', - 'wbemgennetwork.html', - 'winstoragespaces.html', - 'mysql.html' + 'diskpart.html', + 'genbatterynt.html', + 'genericswitchenclosure.html', + 'genericups.html', + 'hyperv.html', + 'ipmitool.html', + 'librehardwaremonitor.html', + 'linuxifconfignetwork.html', + 'linuxipnetwork.html', + 'linuxmultipath.html', + 'lmsensors.html', + 'mib2.html', + 'mib2linux.html', + 'mib2nt.html', + 'mib2switch.html', + 'nvidiasmi.html', + 'virsh.html', + 'wbemgendisknt.html', + 'wbemgenhba.html', + 'wbemgenlun.html', + 'wbemgennetwork.html', + 'winstoragespaces.html', + 'mysql.html' ] fileNamesToCheck.each { fileName -> - File file = new File(basedir, "$directoryPath/$fileName") + File file = new File(basedir, "$directoryPath/$fileName") - assert file.exists() : "File $fileName does not exist in the $directoryPath directory" - assert htmlText.indexOf("href=\"connectors/$fileName\"") > -1 : "metricshub-connectors-directory: href=connectors/$fileName must be listed" + assert file.exists() : "File $fileName does not exist in the $directoryPath directory" + assert htmlText.indexOf("href=\"connectors/$fileName\"") > -1 : "metricshub-connectors-full-listing: href=connectors/$fileName must be listed" } // Check generated reference files String tagsDirectoryPath = 'target/site/connectors/tags' String [] tagsFileNamesToCheck = [ - 'hardware.html', - 'nvidia.html', - 'vm.html', - 'hyper-v.html', - 'hardware.html', - 'database.html', + 'hardware.html', + 'nvidia.html', + 'vm.html', + 'hyper-v.html', + 'hardware.html', + 'database.html', ] String [] hardwareConnectors = [ - 'HyperV', - 'IpmiTool', - 'LibreHardwareMonitor', - 'NvidiaSmi', + 'HyperV', + 'IpmiTool', + 'LibreHardwareMonitor', + 'NvidiaSmi', ] tagsFileNamesToCheck.each { fileName -> - File file = new File(basedir, "$tagsDirectoryPath/$fileName") + File file = new File(basedir, "$tagsDirectoryPath/$fileName") - assert file.exists() : "File $fileName does not exist in the $tagsDirectoryPath directory" - assert htmlText.indexOf("href=\"connectors/tags/$fileName\"") > -1 : "metricshub connectors tag: href=connectors/tags/$fileName must be listed" + assert file.exists() : "File $fileName does not exist in the $tagsDirectoryPath directory" + assert htmlText.indexOf("href=\"connectors/tags/$fileName\"") > -1 : "metricshub connectors tag: href=connectors/tags/$fileName must be listed" - // Check the hardware connectors - if (fileName == 'hardware.html') { - hardwareConnectors.each { connectorId -> - assert htmlText.indexOf("$connectorId") > -1 : "metricshub connectors tag: $connectorId must be listed" - } - } + // Check the hardware connectors + if (fileName == 'hardware.html') { + hardwareConnectors.each { connectorId -> + assert htmlText.indexOf("$connectorId") > -1 : "metricshub connectors tag: $connectorId must be listed" + } + } } // IpmiTool htmlText = new File(basedir, "target/site/connectors/ipmitool.html").text +assert htmlText.indexOf("Typical platform:") > - 1 : "IPMITool: 'Typical platform:' must be present" +assert htmlText.indexOf("IPMI") > - 1 : "IPMITool: typical platform text must be present" +assert htmlText.indexOf("IPMI") > - 1 : "IPMITool: platforms/ipmi.html link text must be present" assert htmlText.indexOf("ipmi:") > -1 && htmlText.indexOf("wmi:") > -1 && htmlText.indexOf("ssh:") > -1 : "IpmiTool: Examples must list ipmi, wmi and ssh" assert htmlText =~ /metricshub.*-t management.*-c \+IpmiTool.*--ipmi/ : "IpmiTool: CLI must specify -t management -c +IpmiTool --ipmi" @@ -202,7 +205,7 @@ assert htmlText.indexOf('

Description

') > - 1 : "MIB2: assert htmlText.indexOf("This connector discovers the enclosure and Ethernet ports of a system equipped with an MIB-2 standard SNMP Agent.") > - 1 : "MIB2: Page must indicate a description" assert htmlText.indexOf('

Target

') > - 1 : "MIB2: Page must indicate 'Target' as HTML H3 element" assert htmlText.indexOf("Typical platform:") > - 1 : "MIB2: 'Typical platform:' must be present" -assert htmlText.indexOf("Any system with SNMP") > - 1 : "MIB2: typical platform text must be present" +assert htmlText.indexOf("SNMP") > - 1 : "MIB2: typical platform text must be present" assert htmlText.indexOf("Operating systems:") > - 1 : "MIB2 'Operating systems:' must be present" assert htmlText.indexOf("Network Device") > -1 : "MIB2: operating system 'Network Device' must be present" assert htmlText.indexOf("Out-Of-Band") > -1 : "MIB2: operating system 'Out-Of-Band' must be present" @@ -246,7 +249,7 @@ assert htmlText.indexOf('physical_address_type') > -1 : "MIB2: the 'physical_add // Nvidia-Smi htmlText = new File(basedir, "target/site/connectors/nvidiasmi.html").text -assert htmlText.indexOf("Any system with Nvidia GPUs") > -1 : "NvidiaSmi: Unexpected Typical platform" +assert htmlText.indexOf("Nvidia") > -1 : "NvidiaSmi: Unexpected Typical platform" assert htmlText.indexOf("Microsoft Windows, Linux") > -1 : "NvidiaSmi: Unexpected Operating Systems" assert htmlText.indexOf("NVIDIA drivers with NVIDIA-SMI support") > -1 : "NvidiaSmi: Unexpected Leverages" assert htmlText.indexOf("Command Lines") > -1 : "NvidiaSmi: Unexpected Technology and protocols" @@ -254,7 +257,7 @@ assert htmlText.indexOf("nvidia-smi") > -1 : "NvidiaSmi: Unexpected // WinStoreSpaces htmlText = new File(basedir, "target/site/connectors/winstoragespaces.html").text -assert htmlText.indexOf("Any system") > -1 : "WinStoreSpaces: Unexpected Typical platform" +assert htmlText.indexOf("Microsoft Windows") > -1 : "WinStoreSpaces: Unexpected Typical platform" assert htmlText.indexOf("Storage System, Microsoft Windows") > -1 : "WinStoreSpaces: Unexpected Operating Systems" assert htmlText.indexOf("Windows Storage Spaces") > -1 : "WinStoreSpaces: Unexpected Leverages" assert htmlText.indexOf("WMI/WinRM") > -1 : "WinStoreSpaces: Unexpected Technology and protocols" @@ -263,7 +266,7 @@ assert htmlText.indexOf("metricshub HOSTNAME -t storage -c +WinStorageSpaces --w // MySQL htmlText = new File(basedir, "target/site/connectors/mysql.html").text -assert htmlText.indexOf("Any platform running MySQL") > -1 : "MySQL: Unexpected Typical platform" +assert htmlText.indexOf("MySQL") > -1 : "MySQL: Unexpected Typical platform" assert htmlText.indexOf("Microsoft Windows, Linux") > -1 : "MySQL: Unexpected Operating Systems" assert htmlText.indexOf("MySQL Database") > -1 : "MySQL: Unexpected Leverages" assert htmlText.indexOf("SQL/JDBC") > -1 : "MySQL: Unexpected Technology and protocols" @@ -271,4 +274,70 @@ assert htmlText.indexOf("metricshub HOSTNAME -t win -c +MySQL --jdbc -u USER --j assert htmlText.indexOf("SELECT @@version_comment REGEXP 'mysql' AS is_mysql;") > -1 : "MySQL: Page must indicate the activation criterion." assert htmlText.indexOf("Expected Result:") > -1 : "MySQL: Page must indicate the Expected Result message." assert htmlText.indexOf("1") > -1 : "MySQL: Page must indicate the expected result value." -assert htmlText.indexOf('

Metrics

') > - 1 : "MySQL: Page must indicate 'Metrics' as HTML H3 element" \ No newline at end of file +assert htmlText.indexOf('

Metrics

') > - 1 : "MySQL: Page must indicate 'Metrics' as HTML H3 element" + +// Verify that the metricshub-connectors-directory.html file has been created +File directoryHtmlFile = new File(basedir, "target/site/metricshub-connectors-directory.html") +assert directoryHtmlFile.exists() : "Main metricshub-connectors-directory.html page must be created" + +// Read the file content +String directoryHtmlText = directoryHtmlFile.text + +// Define platforms to check +def platforms = [ + [name: "IPMI", link: "connectors/platforms/ipmi.html", icon: "ipmi"], + [name: "Ethernet Switch", link: "connectors/platforms/ethernet-switch.html", icon: "ethernet-switch"], + [name: "Hyper-V", link: "connectors/platforms/hyper-v.html", icon: "hyper-v"], + [name: "Hypervisors", link: "connectors/platforms/hypervisors.html", icon: "hypervisors"], + [name: "KVM", link: "connectors/platforms/kvm.html", icon: "kvm"], + [name: "Linux", link: "connectors/platforms/linux.html", icon: "linux"], + [name: "Microsoft Windows", link: "connectors/platforms/microsoft-windows.html", icon: "microsoft-windows"], + [name: "MySQL", link: "connectors/platforms/my-sql.html", icon: "my-sql"], + [name: "Nvidia", link: "connectors/platforms/nvidia.html", icon: "nvidia"], + [name: "QEMU", link: "connectors/platforms/qemu.html", icon: "qemu"], + [name: "System with SNMP", link: "connectors/platforms/system-with-snmp.html", icon: "system-with-snmp"], + [name: "UPS", link: "connectors/platforms/ups.html", icon: "ups"], + [name: "Xen", link: "connectors/platforms/xen.html", icon: "xen"] +] + +// Check each platform +platforms.each { platform -> + // Check platform title + assert directoryHtmlText.indexOf(platform.name) > -1 : "Platform '${platform.name}' must be listed in metricshub-connectors-directory.html" + + // Check platform link + assert directoryHtmlText.indexOf("href=\"${platform.link}\"") > -1 : "Platform '${platform.name}' must link to '${platform.link}'" + + // Check platform icon + assert directoryHtmlText.indexOf("src=\"images/platforms/${platform.icon}.png\"") > -1 : "Platform '${platform.name}' must have the correct icon '${platform.icon}.png'" +} + +// Additional checks classes +assert directoryHtmlText.indexOf("class=\"connectors-badge badge\"") > -1 : "connectors-badge class must be present in metricshub-connectors-directory.html" +assert directoryHtmlText.indexOf("class=\"technology-badge badge\"") > -1 : "technology-badge class must be present in metricshub-connectors-directory.html" +assert directoryHtmlText.indexOf("class=\"platform-tile-container\"") > -1 : "platform-tile-container class must be present in metricshub-connectors-directory.html" +assert directoryHtmlText.indexOf("class=\"platform-tile\"") > -1 : "platform-tile class must be present in metricshub-connectors-directory.html" +assert directoryHtmlText.indexOf("class=\"platform-title\"") > -1 : "platform-title class must be present in metricshub-connectors-directory.html" +assert directoryHtmlText.indexOf("class=\"platform-icon\"") > -1 : "platform-icon must be present in metricshub-connectors-directory.html" +assert directoryHtmlText.indexOf("alt=\"inline\"") > -1 : "alt=\"inline\" attribute must be present in metricshub-connectors-directory.html" + +// Define regex patterns to check +def regexps = [ + /class="connectors-badge badge"/, + /class="platform-tile"/, + /class="platform-title"/, + /class="platform-icon"/, + /alt="inline"/ +] + +// Get the number of platforms +def expectedCount = platforms.size() + +// Check occurrences of each regex pattern +regexps.each { pattern -> + def count = (directoryHtmlText =~ pattern).count // Count matches for the pattern + assert count == expectedCount : "Expected $expectedCount occurrences of $pattern, but found $count" +} + +def countContainer = (directoryHtmlText =~ /class="platform-tile-container"/).count +assert countContainer == 1 : "Expected 1 platform-tile-container class, but found $countContainer" diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java index 64b6d61..f7014fc 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java @@ -52,6 +52,12 @@ public abstract class AbstractConnectorReport extends AbstractMavenReport { @Parameter(defaultValue = "${project.basedir}/src/main/connector", property = "sourceDirectory", required = true) protected File sourceDirectory; + /** + * The directory where the platform icons are located. + */ + @Parameter(defaultValue = "images/platforms", property = "platformIconsDirectory", required = true) + protected String platformIconsDirectory; + protected Log logger; protected Map connectors; diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java index c251be5..42f820d 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java @@ -20,14 +20,12 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ -import static org.sentrysoftware.maven.metricshub.connector.Constants.CONNECTOR_SUBDIRECTORY_NAME; -import static org.sentrysoftware.maven.metricshub.connector.Constants.TAG_SUBDIRECTORY_NAME; - import com.fasterxml.jackson.databind.JsonNode; import java.io.File; import java.io.IOException; import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -42,17 +40,20 @@ import org.apache.maven.reporting.MavenReportException; import org.sentrysoftware.maven.metricshub.connector.producer.ConnectorJsonNodeReader; import org.sentrysoftware.maven.metricshub.connector.producer.ConnectorPageProducer; -import org.sentrysoftware.maven.metricshub.connector.producer.MainPageProducer; +import org.sentrysoftware.maven.metricshub.connector.producer.FullListingPageProducer; +import org.sentrysoftware.maven.metricshub.connector.producer.PlatformsPageProducer; import org.sentrysoftware.maven.metricshub.connector.producer.SinkHelper; +import org.sentrysoftware.maven.metricshub.connector.producer.SpecificPlatformPageProducer; import org.sentrysoftware.maven.metricshub.connector.producer.TagPageProducer; +import org.sentrysoftware.maven.metricshub.connector.producer.model.platform.Platform; /** * This Maven report goal builds an HTML Page for the Connectors Directory. * * It is invoked during the Maven site generation process.
* - * It takes the source code of the connectors as input then generates a report that describes the - * connectors in detail. + * It takes the source code of the connectors as input then generates a report that describes + * the supported platforms, tags, and connectors. *

* This plugin goal is a report goal that works in the site build lifecycle. It * simply needs to be declared in the report section of the pom.xml. @@ -75,16 +76,21 @@ public class ConnectorsDirectoryReport extends AbstractConnectorReport { /** - * Connector directory output name + * Format string for sink creation error messages. + */ + private static final String SINK_CREATION_ERROR_FORMAT = "Could not create sink for %s in %s"; + + /** + * Format string to create a subdirectory. */ - public static final String CONNECTORS_DIRECTORY_OUTPUT_NAME = "metricshub-connectors-directory"; + private static final String SUBDIRECTORY_FORMAT = "%s/%s"; @Override protected void doReport() throws MavenReportException { // Subdirectory where we're going to store the pages for each connector. - final File connectorSubdirectory = new File(outputDirectory, CONNECTOR_SUBDIRECTORY_NAME); + final File connectorSubdirectory = new File(outputDirectory, Constants.CONNECTOR_SUBDIRECTORY_NAME); if (!connectorSubdirectory.exists() && !connectorSubdirectory.mkdirs()) { - final String message = "Could not create connectorSubdirectory: " + connectorSubdirectory.getAbsolutePath(); + final String message = "Could not create connectors subdirectory: " + connectorSubdirectory.getAbsolutePath(); logger.error(message); throw new MavenReportException(message); } @@ -92,19 +98,42 @@ protected void doReport() throws MavenReportException { // Retrieve tags final Map> tags = determineTags(); - // Main page - produceMainPage(tags.keySet()); + // Name of the connector subdirectory + final String connectorDirectoryName = connectorSubdirectory.getName(); + + final List platforms = determinePlatforms(); + + // Platforms page + producePlatformsPage(platforms); + + // Subdirectory within connector subdirectory where we store the pages for each platform. + + final File platformSubdirectory = new File( + String.format(SUBDIRECTORY_FORMAT, outputDirectory, connectorDirectoryName), + Constants.PLATFORM_SUBDIRECTORY_NAME + ); + if (!platformSubdirectory.exists() && !platformSubdirectory.mkdirs()) { + final String message = "Could not create platform subdirectory: " + platformSubdirectory.getAbsolutePath(); + logger.error(message); + throw new MavenReportException(message); + } + + // Platform pages + produceSpecifcPlatformPages(platformSubdirectory, platforms); + + // Full listing page + produceFullListingPage(tags.keySet()); // Connector pages produceConnectorPages(connectorSubdirectory, buildSupersededMap()); - // Subdirectory whithin connector subdirectory where we store the pages for each tag. + // Subdirectory within connector subdirectory where we store the pages for each tag. final File tagSubdirectory = new File( - String.format("%s/%s", outputDirectory, connectorSubdirectory.getName()), - TAG_SUBDIRECTORY_NAME + String.format(SUBDIRECTORY_FORMAT, outputDirectory, connectorDirectoryName), + Constants.TAG_SUBDIRECTORY_NAME ); if (!tagSubdirectory.exists() && !tagSubdirectory.mkdirs()) { - final String message = "Could not create tagSubdirectory: " + tagSubdirectory.getAbsolutePath(); + final String message = "Could not create tag subdirectory: " + tagSubdirectory.getAbsolutePath(); logger.error(message); throw new MavenReportException(message); } @@ -149,7 +178,7 @@ private void produceConnectorPages(final File connectorSubdirectory, final Map tags) throws MavenReportException { - final Sink mainSink = getMainSink(); + private void produceFullListingPage(final Set tags) throws MavenReportException { + // Create a new sink! + final Sink sink; + try { + sink = getSinkFactory().createSink(outputDirectory, Constants.CONNECTORS_FULL_LISTING_FILE_NAME); + } catch (IOException e) { + final String message = String.format( + SINK_CREATION_ERROR_FORMAT, + Constants.CONNECTORS_FULL_LISTING_FILE_NAME, + outputDirectory + ); + logger.error(message, e); + throw new MavenReportException(message, e); + } - new MainPageProducer(logger, CONNECTOR_SUBDIRECTORY_NAME, TAG_SUBDIRECTORY_NAME) - .produce(mainSink, connectors, enterpriseConnectorIds, tags); + new FullListingPageProducer(logger, Constants.CONNECTOR_SUBDIRECTORY_NAME, Constants.TAG_SUBDIRECTORY_NAME) + .produce(sink, connectors, enterpriseConnectorIds, tags); } @Override @@ -215,7 +259,7 @@ public String getName(final Locale locale) { @Override public String getOutputName() { - return CONNECTORS_DIRECTORY_OUTPUT_NAME; + return Constants.CONNECTORS_DIRECTORY_OUTPUT_NAME; } /** @@ -247,4 +291,92 @@ private Map> determineTags() { ) ); } + + /** + * Constructs a map where each key is the kebab case representation of a platform name + * and its corresponding value is the {@link Platform} object.
+ * Then, it sorts the platforms by display name and returns them as a list, thus ensuring a consistent + * order in the generated report. + * + * @return a list of platforms sorted by display name. + */ + private List determinePlatforms() { + final Map platforms = new HashMap<>(); + for (Map.Entry connectorEntry : connectors.entrySet()) { + final JsonNode connector = connectorEntry.getValue(); + final ConnectorJsonNodeReader reader = new ConnectorJsonNodeReader(connector); + for (String platformName : reader.getPlatforms()) { + // Generate the platform ID + final String platformId = kebabCase(platformName); + + // Merge or create + final Platform platform = platforms.computeIfAbsent( + platformId, + id -> new Platform(id, platformName, "%s/%s.png".formatted(platformIconsDirectory, id)) + ); + + // Add the connector + platform.addConnector(connectorEntry.getKey(), connector); + + // Add the platform technology types + platform.addTechnologies(reader.getTechnologies()); + } + } + + return platforms.values().stream().sorted(Comparator.comparing(Platform::getDisplayName)).toList(); + } + + /** + * Converts the given text to kebab-case. + * + * @param text The string to convert. + * @return The kebab-case text. + */ + public static String kebabCase(final String text) { + return text + .replaceAll("\\s+", " ") + .replaceAll("[()]", "") + .replaceAll("([a-z0-9])([A-Z])", "$1-$2") + .replaceAll("[^a-zA-Z0-9]", "-") + .toLowerCase(); + } + + /** + * Produces the pages for each platform in the Maven report. + * + * @param platformSubdirectory The subdirectory where the platform pages will be created. + * @param platforms The list of platforms to be listed as part of the report. + * @throws MavenReportException + */ + private void produceSpecifcPlatformPages(final File platformSubdirectory, final List platforms) + throws MavenReportException { + for (Platform platform : platforms) { + // Create a new sink! + final Sink sink; + try { + sink = getSinkFactory().createSink(platformSubdirectory, SinkHelper.buildPageFilename(platform.getId())); + } catch (IOException e) { + final String message = String.format(SINK_CREATION_ERROR_FORMAT, platform.getId(), platformSubdirectory); + logger.error(message, e); + throw new MavenReportException(message, e); + } + + new SpecificPlatformPageProducer(logger) + .produce(sink, platform, Constants.CONNECTOR_SUBDIRECTORY_NAME, enterpriseConnectorIds); + } + } + + /** + * Produces the platforms page for the Maven report. + * + * @param platforms The list of platforms to be listed as part of the report. + * @throws MavenReportException + */ + private void producePlatformsPage(final List platforms) throws MavenReportException { + new PlatformsPageProducer( + logger, + SUBDIRECTORY_FORMAT.formatted(Constants.CONNECTOR_SUBDIRECTORY_NAME, Constants.PLATFORM_SUBDIRECTORY_NAME) + ) + .produce(getMainSink(), platforms); + } } diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/Constants.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/Constants.java index d80dce9..3175bdb 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/Constants.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/Constants.java @@ -47,6 +47,26 @@ public class Constants { */ public static final String TAG_SUBDIRECTORY_NAME = "tags"; + /** + * Name of the subdirectory that will contain the pages for each platform + */ + public static final String PLATFORM_SUBDIRECTORY_NAME = "platforms"; + + /** + * Connectors directory output name + */ + public static final String CONNECTORS_DIRECTORY_OUTPUT_NAME = "metricshub-connectors-directory"; + + /** + * Connectors directory output HTML file name + */ + public static final String CONNECTORS_DIRECTORY_OUTPUT_FILE_NAME = CONNECTORS_DIRECTORY_OUTPUT_NAME + ".html"; + + /** + * Connectors full list file name + */ + public static final String CONNECTORS_FULL_LISTING_FILE_NAME = "metricshub-connectors-full-listing.html"; + /** * CSS class for a medium-sized Bootstrap column with a width of 3. */ diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractGroupConnectorsProducer.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractGroupConnectorsProducer.java new file mode 100644 index 0000000..827dc61 --- /dev/null +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractGroupConnectorsProducer.java @@ -0,0 +1,98 @@ +package org.sentrysoftware.maven.metricshub.connector.producer; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * MetricsHub Connector Maven Plugin + * ჻჻჻჻჻჻ + * Copyright (C) 2023 Sentry Software + * ჻჻჻჻჻჻ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import com.fasterxml.jackson.databind.JsonNode; +import java.util.List; +import java.util.Map; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.plugin.logging.Log; +import org.sentrysoftware.maven.metricshub.connector.Constants; + +/** + * Abstract class for producing pages that group connectors. + */ +public abstract class AbstractGroupConnectorsProducer extends AbstractPageProducer { + + /** + * Constructor for the AbstractGroupConnectorsProducer. + * + * @param logger The logger used for logging. + */ + protected AbstractGroupConnectorsProducer(Log logger) { + super(logger); + } + + /** + * Builds the head and body of the page. + * + * @param sink The sink used for generating content + * @param connectorSubdirectoryName The connector subdirectory name + * @param enterpriseConnectorIds The enterprise connector identifiers + * @param title The title of the page + * @param connectors The map of connector identifiers to their corresponding JsonNodes + */ + protected void buildHeadAndBody( + final Sink sink, + final String connectorSubdirectoryName, + final List enterpriseConnectorIds, + final String title, + final Map connectors + ) { + // Create the head element of the page + buildHead(sink, title); + + sink.body(); + + // Links to the main page and full listing + ConnectorPageProducer.backLinks( + sink, + String.format("../../%s", Constants.CONNECTORS_DIRECTORY_OUTPUT_FILE_NAME), + String.format("../../%s", Constants.CONNECTORS_FULL_LISTING_FILE_NAME) + ); + + // Title + sink.section1(); + sink.sectionTitle1(); + sink.text(title); + sink.sectionTitle1_(); + + sink.paragraph(); + sink.rawText(getIntroductionText(title)); + sink.paragraph_(); + + // Table of connectors + buildConnectorsTable(sink, connectors, connectorSubdirectoryName, enterpriseConnectorIds, true); + + // Close the page + sink.section1_(); + sink.body_(); + sink.close(); + } + + /** + * Returns the introduction text for the group page. + * + * @param title The category. + * @return The introduction text. + */ + protected abstract String getIntroductionText(String title); +} diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractPageProducer.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractPageProducer.java index 558fdc4..2838812 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractPageProducer.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/AbstractPageProducer.java @@ -35,6 +35,7 @@ import org.apache.maven.plugin.logging.Log; import org.sentrysoftware.maven.metricshub.connector.producer.model.common.OsType; import org.sentrysoftware.maven.metricshub.connector.producer.model.common.TechnologyType; +import org.sentrysoftware.maven.metricshub.connector.producer.model.platform.Platform; /** * Abstract class for producing pages. @@ -79,14 +80,14 @@ private void buildTableHeaderRow(final Sink sink) { * @param connectors The map of connector identifiers to their corresponding JsonNodes. * @param connectorSubdirectoryName The connector subdirectory name. * @param enterpriseConnectorIds The enterprise connector identifiers. - * @param isTagPage Whether the page is a tag page. + * @param areWeUnderConnectors We are located under the connectors directory. */ protected void buildConnectorsTable( final Sink sink, final Map connectors, final String connectorSubdirectoryName, final List enterpriseConnectorIds, - final boolean isTagPage + final boolean areWeUnderConnectors ) { // Create the table sink.table(); @@ -116,7 +117,7 @@ protected void buildConnectorsTable( // Builds the HTML page path name corresponding to the specified connector page filename final String connectorPagePath = String.format( - isTagPage ? "../../%s/%s" : "%s/%s", + areWeUnderConnectors ? "../../%s/%s" : "%s/%s", connectorSubdirectoryName, pageFilename ); @@ -138,7 +139,7 @@ protected void buildConnectorsTable( sink.tableCell_(); sink.tableCell(); - sink.text(SinkHelper.replaceCommaWithSpace(connectorJsonNodeReader.getPlatformsOrDefault("N/A"))); + sink.text(Platform.formatPlatforms(connectorJsonNodeReader.getPlatforms())); sink.tableCell_(); sink.tableCell(); @@ -164,4 +165,18 @@ protected void buildConnectorsTable( sink.table_(); } + + /** + * Builds the head of the page. + * + * @param sink The sink used for generating content + * @param displayName The display name to be set in the title. + */ + protected void buildHead(final Sink sink, final String displayName) { + sink.head(); + sink.title(); + sink.text(displayName); + sink.title_(); + sink.head_(); + } } diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorJsonNodeReader.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorJsonNodeReader.java index 58d3e7e..29ac76d 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorJsonNodeReader.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorJsonNodeReader.java @@ -20,11 +20,6 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ -import static org.sentrysoftware.maven.metricshub.connector.producer.JsonNodeHelper.nodeToStringList; -import static org.sentrysoftware.maven.metricshub.connector.producer.JsonNodeHelper.nonNull; -import static org.sentrysoftware.maven.metricshub.connector.producer.JsonNodeHelper.nonNullTextOrDefault; -import static org.sentrysoftware.maven.metricshub.connector.producer.JsonNodeHelper.stream; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -36,6 +31,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -106,19 +102,18 @@ public String getDisplayName() { public String getInformationOrDefault(final String defaultValue) { final JsonNode information = getConnectorSection().map(node -> node.get("information")).orElse(null); - return nonNullTextOrDefault(information, defaultValue); + return JsonNodeHelper.nonNullTextOrDefault(information, defaultValue); } /** * Retrieves the platforms property of the connector, if available. * - * @param defaultValue The default value to return if the platforms property is null or represents a JSON null. - * @return The platforms property as a String, or the specified default value if not present. + * @return The platforms property as a Set, or the specified default value if not present. */ - public String getPlatformsOrDefault(final String defaultValue) { + public Set getPlatforms() { final JsonNode platforms = getConnectorSection().map(node -> node.get("platforms")).orElse(null); - return nonNullTextOrDefault(platforms, defaultValue); + return JsonNodeHelper.nodeToStringCollection(platforms, TreeSet::new); } /** @@ -128,9 +123,9 @@ public String getPlatformsOrDefault(final String defaultValue) { */ public List getSupersedes() { final JsonNode detection = getDetection(); - if (nonNull(detection)) { - final JsonNode supersedes = detection.get("supersedes"); // NOSONAR nonNull() is already called - return nodeToStringList(supersedes); + if (JsonNodeHelper.nonNull(detection)) { + final JsonNode supersedes = detection.get("supersedes"); // NOSONAR JsonNodeHelper.nonNull() is already called + return JsonNodeHelper.nodeToStringList(supersedes); } return Collections.emptyList(); } @@ -142,9 +137,9 @@ public List getSupersedes() { */ public List getAppliesTo() { final JsonNode detection = getDetection(); - if (nonNull(detection)) { - final JsonNode appliesTo = detection.get("appliesTo"); // NOSONAR nonNull() is already called - return nodeToStringList(appliesTo); + if (JsonNodeHelper.nonNull(detection)) { + final JsonNode appliesTo = detection.get("appliesTo"); // NOSONAR JsonNodeHelper.nonNull() is already called + return JsonNodeHelper.nodeToStringList(appliesTo); } return Collections.emptyList(); } @@ -163,15 +158,16 @@ public String getRequiredMetricsHubVersion() { final JsonNode criteria = getDetectionCriteria(); // If criteria information is not available or is not an array, return null - if (!nonNull(criteria) || !criteria.isArray()) { // NOSONAR nonNull() is already called + if (!JsonNodeHelper.nonNull(criteria) || !criteria.isArray()) { // NOSONAR JsonNodeHelper.nonNull() is already called return null; } // Filter criteria of type "productRequirements" and extract the engine version - return stream((ArrayNode) criteria) + return JsonNodeHelper + .stream((ArrayNode) criteria) .filter(node -> { final JsonNode typeNode = getType(node); - return nonNull(typeNode) && "productrequirements".equalsIgnoreCase(typeNode.asText()); + return JsonNodeHelper.nonNull(typeNode) && "productrequirements".equalsIgnoreCase(typeNode.asText()); }) .map(node -> node.get("engineVersion")) .filter(JsonNodeHelper::nonNull) @@ -199,11 +195,11 @@ private JsonNode getDetectionCriteria() { final JsonNode detection = getDetection(); // If detection information is not available, return null - if (!nonNull(detection)) { + if (!JsonNodeHelper.nonNull(detection)) { return null; } - return detection.get("criteria"); // NOSONAR nonNull() is already called + return detection.get("criteria"); // NOSONAR JsonNodeHelper.nonNull() is already called } /** @@ -224,7 +220,7 @@ private JsonNode getDetection() { public String getReliesOnOrDefault(final String defaultValue) { final JsonNode reliesOn = getConnectorSection().map(node -> node.get("reliesOn")).orElse(null); - return nonNullTextOrDefault(reliesOn, defaultValue); + return JsonNodeHelper.nonNullTextOrDefault(reliesOn, defaultValue); } /** @@ -276,12 +272,12 @@ private void collectTechnologies(final Set technologies, final J .filter(JsonNodeHelper::nonNull) .forEach(job -> { final JsonNode sources = job.get("sources"); - if (!nonNull(sources)) { + if (!JsonNodeHelper.nonNull(sources)) { return; } sources.forEach(source -> { final JsonNode typeNode = getType(source); - if (nonNull(typeNode)) { + if (JsonNodeHelper.nonNull(typeNode)) { TechnologyType.getTechnologyType(typeNode.asText()).ifPresent(technologies::add); } }); @@ -299,7 +295,7 @@ private void collectTechnologies(final Set technologies, final J */ public List getSudoCommands() { final JsonNode sudoCommands = connector.get("sudoCommands"); - return nodeToStringList(sudoCommands); + return JsonNodeHelper.nodeToStringList(sudoCommands); } /** @@ -314,8 +310,8 @@ public List getSudoCommands() { */ public Set getConnectionTypes() { final JsonNode detection = getDetection(); - if (nonNull(detection)) { - final JsonNode connectionTypes = detection.get("connectionTypes"); // NOSONAR nonNull() is already called + if (JsonNodeHelper.nonNull(detection)) { + final JsonNode connectionTypes = detection.get("connectionTypes"); // NOSONAR JsonNodeHelper.nonNull() is already called return nodeToCaseInsensitiveSet(connectionTypes); } return Collections.emptySet(); @@ -329,7 +325,7 @@ public Set getConnectionTypes() { * or not of the expected types. */ private Set nodeToCaseInsensitiveSet(final JsonNode node) { - return nodeToStringList(node).stream().map(String::toLowerCase).collect(Collectors.toSet()); + return JsonNodeHelper.nodeToStringList(node).stream().map(String::toLowerCase).collect(Collectors.toSet()); } /** @@ -345,9 +341,9 @@ private Set nodeToCaseInsensitiveSet(final JsonNode node) { */ public boolean isAutoDetectionDisabled() { final JsonNode detection = getDetection(); - if (nonNull(detection)) { - final JsonNode disableAutoDetection = detection.get("disableAutoDetection"); // NOSONAR nonNull() is already called - if (nonNull(disableAutoDetection) && disableAutoDetection.isBoolean()) { + if (JsonNodeHelper.nonNull(detection)) { + final JsonNode disableAutoDetection = detection.get("disableAutoDetection"); // NOSONAR JsonNodeHelper.nonNull() is already called + if (JsonNodeHelper.nonNull(disableAutoDetection) && disableAutoDetection.isBoolean()) { return disableAutoDetection.asBoolean(); } } @@ -361,9 +357,9 @@ public boolean isAutoDetectionDisabled() { */ public String getOnLastResort() { final JsonNode detection = getDetection(); - if (nonNull(detection)) { - final JsonNode onLastResort = detection.get("onLastResort"); // NOSONAR nonNull() is already called - if (nonNull(onLastResort)) { + if (JsonNodeHelper.nonNull(detection)) { + final JsonNode onLastResort = detection.get("onLastResort"); // NOSONAR JsonNodeHelper.nonNull() is already called + if (JsonNodeHelper.nonNull(onLastResort)) { return onLastResort.asText(); } } @@ -378,8 +374,8 @@ public String getOnLastResort() { public List getCriteria() { final JsonNode detectionCriteria = getDetectionCriteria(); - if (nonNull(detectionCriteria) && detectionCriteria.isArray()) { // NOSONAR nonNull() is already called - return stream((ArrayNode) detectionCriteria).collect(Collectors.toList()); + if (JsonNodeHelper.nonNull(detectionCriteria) && detectionCriteria.isArray()) { // NOSONAR JsonNodeHelper.nonNull() is already called + return JsonNodeHelper.stream((ArrayNode) detectionCriteria).collect(Collectors.toList()); } return Collections.emptyList(); @@ -439,12 +435,12 @@ private void collectAttributes(final Set attributeKeys, final JsonNode.. .filter(JsonNodeHelper::nonNull) .forEach(job -> { final JsonNode mapping = getMapping(job); - if (!nonNull(mapping)) { + if (!JsonNodeHelper.nonNull(mapping)) { return; } final JsonNode attributes = mapping.get("attributes"); - if (!nonNull(attributes)) { + if (!JsonNodeHelper.nonNull(attributes)) { return; } @@ -481,12 +477,12 @@ private void collectMetrics(final Set metricKeys, final JsonNode... jobs .filter(JsonNodeHelper::nonNull) .forEach(job -> { final JsonNode mapping = getMapping(job); - if (!nonNull(mapping)) { + if (!JsonNodeHelper.nonNull(mapping)) { return; } final JsonNode metric = mapping.get("metrics"); - if (!nonNull(metric)) { + if (!JsonNodeHelper.nonNull(metric)) { return; } @@ -520,7 +516,7 @@ private String includeStatesInMetricName(final String metricName) { final JsonNode metricDefinitions = connector.get("metrics"); // No metric definitions? - if (!nonNull(metricDefinitions)) { + if (!JsonNodeHelper.nonNull(metricDefinitions)) { return name; } @@ -529,19 +525,19 @@ private String includeStatesInMetricName(final String metricName) { final JsonNode metricDefinition = metricDefinitions.get(metricNameWithoutAttributes); // No metric definition? - if (!nonNull(metricDefinition)) { + if (!JsonNodeHelper.nonNull(metricDefinition)) { return name; } final JsonNode type = getType(metricDefinition); // Check the type object. Must be non null and object defining state set - if (!nonNull(metricDefinition) || !type.isObject()) { + if (!JsonNodeHelper.nonNull(metricDefinition) || !type.isObject()) { return name; } final JsonNode stateSet = type.get("stateSet"); - final List stateSetList = nodeToStringList(stateSet); + final List stateSetList = JsonNodeHelper.nodeToStringList(stateSet); if (!stateSet.isEmpty()) { // Include the state values in the metric name Collections.sort(stateSetList); @@ -578,12 +574,12 @@ public static final String extractMetricName(final String name) { */ public boolean hasBladeMonitorJob() { final JsonNode monitors = getMonitors().orElse(null); - if (nonNull(monitors)) { - final JsonNode bladeMonitorJob = monitors.get("blade"); // NOSONAR nonNull() is already called - if (nonNull(bladeMonitorJob)) { + if (JsonNodeHelper.nonNull(monitors)) { + final JsonNode bladeMonitorJob = monitors.get("blade"); // NOSONAR JsonNodeHelper.nonNull() is already called + if (JsonNodeHelper.nonNull(bladeMonitorJob)) { final JsonNode[] bladeJobs = getMonitorJobs(bladeMonitorJob); for (JsonNode bladeJob : bladeJobs) { - if (nonNull(bladeJob) && nonNull(getMapping(bladeJob))) { + if (JsonNodeHelper.nonNull(bladeJob) && JsonNodeHelper.nonNull(getMapping(bladeJob))) { return true; } } @@ -614,8 +610,8 @@ private JsonNode getMapping(final JsonNode job) { */ public List getAndCompleteTags(final boolean isEnterprise) { JsonNode detection = getDetection(); - if (nonNull(detection)) { - final JsonNode tagsNode = detection.get("tags"); // NOSONAR nonNull() is already called + if (JsonNodeHelper.nonNull(detection)) { + final JsonNode tagsNode = detection.get("tags"); // NOSONAR JsonNodeHelper.nonNull() is already called final ArrayNode tagsArrayNode = tagsNode != null && !tagsNode.isNull() ? (ArrayNode) tagsNode : JsonNodeFactory.instance.arrayNode(); @@ -623,7 +619,7 @@ public List getAndCompleteTags(final boolean isEnterprise) { tagsArrayNode.add(isEnterprise ? "enterprise" : "community"); ((ObjectNode) detection).set("tags", tagsArrayNode); - return nodeToStringList(tagsArrayNode); + return JsonNodeHelper.nodeToStringList(tagsArrayNode); } return Collections.emptyList(); } @@ -635,8 +631,8 @@ public List getAndCompleteTags(final boolean isEnterprise) { */ public List getTags() { JsonNode detection = getDetection(); - return nonNull(detection) - ? nodeToStringList(detection.get("tags")) // NOSONAR nonNull() is already called + return JsonNodeHelper.nonNull(detection) + ? JsonNodeHelper.nodeToStringList(detection.get("tags")) // NOSONAR JsonNodeHelper.nonNull() is already called : Collections.emptyList(); } @@ -669,8 +665,8 @@ public Map getDefaultVariables() { final JsonNode variablesNode = getConnectorSection().map(node -> node.get("variables")).orElse(null); final Map defaultVariables = new HashMap<>(); - if (nonNull(variablesNode)) { - variablesNode // NOSONAR nonNull() is already called + if (JsonNodeHelper.nonNull(variablesNode)) { + variablesNode // NOSONAR JsonNodeHelper.nonNull() is already called .fields() .forEachRemaining(entry -> { final String variableName = entry.getKey(); @@ -681,8 +677,8 @@ public Map getDefaultVariables() { // Create a ConnectorDefaultVariable object and put it into the map final ConnectorDefaultVariable connectorDefaultVariable = new ConnectorDefaultVariable( - nonNullTextOrDefault(description, null), - nonNullTextOrDefault(defaultValue, null) + JsonNodeHelper.nonNullTextOrDefault(description, null), + JsonNodeHelper.nonNullTextOrDefault(defaultValue, null) ); defaultVariables.put(variableName, connectorDefaultVariable); }); diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorPageProducer.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorPageProducer.java index 2cb4a55..57d04e6 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorPageProducer.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/ConnectorPageProducer.java @@ -20,9 +20,6 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ -import static org.sentrysoftware.maven.metricshub.connector.ConnectorsDirectoryReport.CONNECTORS_DIRECTORY_OUTPUT_NAME; -import static org.sentrysoftware.maven.metricshub.connector.Constants.TAG_SUBDIRECTORY_NAME; - import com.fasterxml.jackson.databind.JsonNode; import java.text.ChoiceFormat; import java.util.ArrayList; @@ -38,6 +35,8 @@ import lombok.Builder; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.plugin.logging.Log; +import org.sentrysoftware.maven.metricshub.connector.ConnectorsDirectoryReport; +import org.sentrysoftware.maven.metricshub.connector.Constants; import org.sentrysoftware.maven.metricshub.connector.producer.model.common.ConnectorDefaultVariable; import org.sentrysoftware.maven.metricshub.connector.producer.model.common.OpenTelemetryHardwareType; import org.sentrysoftware.maven.metricshub.connector.producer.model.common.OsType; @@ -94,13 +93,12 @@ public void produce( sink.body(); - // Back to the main page - sink.paragraph(SinkHelper.setClass("small")); - sink.rawText(SinkHelper.glyphIcon("arrow-left") + " "); - sink.link(String.format("../%s.html", CONNECTORS_DIRECTORY_OUTPUT_NAME)); - sink.text("Back to the list of connectors"); - sink.link_(); - sink.paragraph_(); + // Links to the main page and full listing + backLinks( + sink, + String.format("../%s", Constants.CONNECTORS_DIRECTORY_OUTPUT_FILE_NAME), + String.format("../%s", Constants.CONNECTORS_FULL_LISTING_FILE_NAME) + ); // Big title sink.section1(); @@ -131,7 +129,7 @@ public void produce( sink.rawText( SinkHelper.bootstrapLabel( SinkHelper.hyperlinkRef( - String.format("%s/%s.html", TAG_SUBDIRECTORY_NAME, tag.toLowerCase().replace(" ", "-")), + String.format("%s/%s.html", Constants.TAG_SUBDIRECTORY_NAME, tag.toLowerCase().replace(" ", "-")), tag ), "metricshub-tag" @@ -158,14 +156,29 @@ public void produce( sink.text("Target"); sink.sectionTitle2_(); - final String platforms = connectorJsonNodeReader.getPlatformsOrDefault("N/A"); + // Typical platforms + final Set platforms = connectorJsonNodeReader.getPlatforms(); + final int platformsSize = platforms.size(); + sink.paragraph(); sink.text("Typical "); - sink.text(new ChoiceFormat("-1#platform|0 "connectors cannot be null."); Objects.requireNonNull(connectorTags, () -> "connectorTags cannot be null."); - logger.debug( - String.format("Generating the main page %s.html", ConnectorsDirectoryReport.CONNECTORS_DIRECTORY_OUTPUT_NAME) - ); + logger.debug(String.format("Generating the full-listing page %s", Constants.CONNECTORS_FULL_LISTING_FILE_NAME)); + + final String title = "${project.name} Connectors"; - mainSink.head(); - mainSink.title(); - mainSink.text("Connectors Directory"); - mainSink.title_(); - mainSink.head_(); + buildHead(mainSink, title); mainSink.body(); // Title mainSink.section1(); mainSink.sectionTitle1(); - mainSink.text("Connectors Directory"); + mainSink.text(title); mainSink.sectionTitle1_(); // Intro diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/JsonNodeHelper.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/JsonNodeHelper.java index bbfc022..e1f4e91 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/JsonNodeHelper.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/JsonNodeHelper.java @@ -22,13 +22,15 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -79,38 +81,55 @@ public static Stream stream(final ArrayNode arrayNode) { } /** - * Converts a {@link JsonNode} to a list of strings. - *

- * This method takes a {@link JsonNode} as input and converts it into a list of strings. If the input node is an array, - * the method uses {@link #convertSimpleArrayNodeToList(ArrayNode)} to perform the conversion. If the node is a single - * value node, it is converted into a singleton list containing its text representation. If the input node is null or - * not of the expected types, an empty list is returned. - *

+ * Converts a {@link JsonNode} to a {@link List} of strings. + * This method invokes {@link #nodeToStringCollection(JsonNode, Supplier)} with + * an {@link ArrayList} as the collection type. + * * @param node The {@link JsonNode} to convert to a list of strings. - * @return A {@link List} of strings representing the contents of the input node, or an empty list if the node is null - * or not of the expected types. + * @return A {@link List} of strings representing the contents of the input node, or an empty list if the node is null. */ public static List nodeToStringList(final JsonNode node) { + return nodeToStringCollection(node, ArrayList::new); + } + + /** + * Converts a {@link JsonNode} to a {@link Collection} of strings.
+ * For a string node, the string is split using a comma as a separator, trailing + * and leading spaces are removed from each element.
+ * + * @param The type of the collection. + * @param node The {@link JsonNode} to convert to a collection of strings. + * @param collectionFactory The factory for the collection to be returned. + * @return A {@link Collection} of strings representing the contents of the input node, or an empty Collection if the node is null. + */ + public static > C nodeToStringCollection( + final JsonNode node, + final Supplier collectionFactory + ) { if (nonNull(node)) { if (node.isArray()) { - return convertSimpleArrayNodeToList((ArrayNode) node); - } else if (node.isValueNode()) { - return Collections.singletonList(node.asText()); + return convertSimpleArrayNodeToCollection((ArrayNode) node, collectionFactory); } + return Stream.of(node.asText().split(",")).map(String::trim).collect(Collectors.toCollection(collectionFactory)); } - return Collections.emptyList(); + return Stream.empty().collect(Collectors.toCollection(collectionFactory)); } /** - * Converts a Jackson {@link ArrayNode} to a {@link List} of strings. + * Converts a Jackson {@link ArrayNode} to a {@link Collection} of strings. * - * @param arrayNode The {@code ArrayNode} to be converted to a list of strings. + * @param The type of the collection. + * @param arrayNode The {@code ArrayNode} to be converted to a collection of strings. + * @param collectionFactory The factory for the collection to be returned. * @return A {@code List} containing the text representations of the elements in the {@code ArrayNode}. * @throws NullPointerException if {@code arrayNode} is {@code null}. */ - public static List convertSimpleArrayNodeToList(final ArrayNode arrayNode) { - return stream(arrayNode).map(JsonNode::asText).collect(Collectors.toList()); + public static > C convertSimpleArrayNodeToCollection( + final ArrayNode arrayNode, + final Supplier collectionFactory + ) { + return stream(arrayNode).map(JsonNode::asText).collect(Collectors.toCollection(collectionFactory)); } /** diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/PlatformsPageProducer.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/PlatformsPageProducer.java new file mode 100644 index 0000000..97de5b8 --- /dev/null +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/PlatformsPageProducer.java @@ -0,0 +1,136 @@ +package org.sentrysoftware.maven.metricshub.connector.producer; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * MetricsHub Connector Maven Plugin + * ჻჻჻჻჻჻ + * Copyright (C) 2023 Sentry Software + * ჻჻჻჻჻჻ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.List; +import java.util.Objects; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.doxia.sink.SinkEventAttributes; +import org.apache.maven.plugin.logging.Log; +import org.sentrysoftware.maven.metricshub.connector.Constants; +import org.sentrysoftware.maven.metricshub.connector.producer.model.common.TechnologyType; +import org.sentrysoftware.maven.metricshub.connector.producer.model.platform.Platform; + +/** + * Utility class for producing the platforms page of the connectors directory. + */ +public class PlatformsPageProducer { + + private final Log logger; + private final String platformSubdirectory; + + /** + * Constructor for the main platforms page producer. + * + * @param logger The logger used for logging. + * @param platformSubdirectory The connector subdirectory name. + */ + public PlatformsPageProducer(final Log logger, final String platformSubdirectory) { + this.logger = logger; + this.platformSubdirectory = platformSubdirectory; + } + + /** + * Produces the main platforms page report that lists all the platforms. + * + * @param mainSink The main sink used for generating content. + * @param platforms The list of platforms to be listed as part of the report. + */ + public void produce(final Sink mainSink, final List platforms) { + Objects.requireNonNull(platformSubdirectory, () -> "platformSubdirectory cannot be null."); + Objects.requireNonNull(logger, () -> "logger cannot be null."); + Objects.requireNonNull(platforms, () -> "platforms cannot be null."); + Objects.requireNonNull(mainSink, () -> "mainSink cannot be null."); + + logger.debug( + String.format("Generating the main platforms page %s", Constants.CONNECTORS_DIRECTORY_OUTPUT_FILE_NAME) + ); + + mainSink.head(); + mainSink.title(); + mainSink.text("Connectors Directory"); + mainSink.title_(); + mainSink.head_(); + + mainSink.body(); + + // Title + mainSink.section1(); + mainSink.sectionTitle1(); + mainSink.text("Connectors Directory"); + mainSink.sectionTitle1_(); + + // Introduction + mainSink.paragraph(); + mainSink.text( + "This directory lists the platforms supported by ${project.name} ${project.version}." + + " Each platform page lists the connectors that target that platform." + ); + mainSink.paragraph_(); + + mainSink.sectionTitle2(); + mainSink.text("Platforms"); + mainSink.sectionTitle2_(); + + // Begin the tile container + mainSink.division(SinkHelper.setClass("platform-tile-container")); + + // Produce tiles for each platform + platforms.forEach(platform -> { + final String platformId = platform.getId(); + final String displayName = platform.getDisplayName(); + final String iconPath = platform.getIconPath(); + final int numberOfConnectors = platform.getConnectors().size(); + + // Create a tile for the platform + mainSink.link(platformSubdirectory + "/" + platformId + ".html", SinkHelper.setClass("platform-tile")); + + mainSink.division(SinkHelper.setClass("platform-title")); + mainSink.text(displayName); + mainSink.division_(); + + mainSink.figure(SinkHelper.setClass("platform-icon")); + // alt="inline" is used to prevent the icon from being displayed in the block element managed by the front framework + mainSink.figureGraphics(iconPath, SinkHelper.setAttribute(SinkEventAttributes.ALT, "inline")); + mainSink.figure_(); + + mainSink.division(SinkHelper.setClass("platform-badges")); + mainSink.rawText(SinkHelper.bootstrapBadge(String.valueOf(numberOfConnectors), "connectors-badge")); + platform + .getTechnologies() + .stream() + .map(TechnologyType::getDisplayName) + .forEach(technology -> mainSink.rawText(SinkHelper.bootstrapBadge(technology, "technology-badge"))); + mainSink.division_(); + + mainSink.link_(); + }); + + // Close the tile container + mainSink.division_(); + + mainSink.section1_(); + + mainSink.body_(); + + mainSink.close(); + } +} diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SinkHelper.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SinkHelper.java index 45a092f..1812197 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SinkHelper.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SinkHelper.java @@ -39,6 +39,11 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class SinkHelper { + /** + * The non-breaking space character + */ + public static final String NON_BREAKING_SPACE = " "; + /** * Use a compiled representation of a regular expression to find commas followed by non-whitespace */ @@ -51,11 +56,22 @@ public class SinkHelper { * @return the AttributeSet that can be used in any Sink element */ public static SinkEventAttributes setClass(final String className) { + return setAttribute(SinkEventAttributes.CLASS, className); + } + + /** + * Creates an AttributeSet that sets the specified attribute to the specified value + * + * @param attributeName The name of the attribute to be set + * @param value The value to be set for the attribute + * @return the AttributeSet that can be used in any Sink element + */ + public static SinkEventAttributes setAttribute(final String attributeName, final String value) { // Create a new AttributeSet final SinkEventAttributes attributes = new SinkEventAttributeSet(); - // Set the class - attributes.addAttribute(SinkEventAttributes.CLASS, className); + // Set the attribute value + attributes.addAttribute(attributeName, value); return attributes; } @@ -124,27 +140,51 @@ public static String glyphIcon(final String iconName) { /** * Create a bootstrap badge with the following content. * - * @param content text of the badge. - * @param customClassname custom class name to apply to the badge. + * @param content text of the label. + * @param customClassname custom class name to apply to the label. * @return the HTML code for this badge. */ - public static String bootstrapLabel(@NonNull final String content, String customClassname) { + public static String bootstrapLabel(@NonNull final String content, final String customClassname) { + return String.format( + " %s", + normalizeCustomClassName(customClassname), + content + ); + } + + /** + * Create a bootstrap badge with the following content. + * + * @param content text of the label. + * @param customClassname custom class name to apply to the label + * @return the HTML code for this badge. + */ + public static String bootstrapBadge(@NonNull final String content, String customClassname) { + return String.format("%s", normalizeCustomClassName(customClassname), content); + } + + /** + * Checks if the custom class name is null and returns an empty string if it is. + * Otherwise, it returns the custom class name trimmed with a trailing space. + * + * @param customClassname custom class name to apply to the label + * @return the normalized custom class name. + */ + private static String normalizeCustomClassName(String customClassname) { if (customClassname == null) { - customClassname = ""; - } else { - customClassname = customClassname.trim() + " "; + return ""; } - return String.format(" %s", customClassname, content); + return customClassname.trim() + " "; } /** * Builds the HTML page file name corresponding to the specified connector identifier. * - * @param connectorId The connector identifier. + * @param pageId The page identifier. * @return The corresponding HTML page filename. */ - public static String buildPageFilename(final String connectorId) { - return connectorId.toLowerCase() + ".html"; + public static String buildPageFilename(final String pageId) { + return pageId.toLowerCase() + ".html"; } /** diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SpecificPlatformPageProducer.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SpecificPlatformPageProducer.java new file mode 100644 index 0000000..af72ccb --- /dev/null +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/SpecificPlatformPageProducer.java @@ -0,0 +1,75 @@ +package org.sentrysoftware.maven.metricshub.connector.producer; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * MetricsHub Connector Maven Plugin + * ჻჻჻჻჻჻ + * Copyright (C) 2023 Sentry Software + * ჻჻჻჻჻჻ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import com.fasterxml.jackson.databind.JsonNode; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.plugin.logging.Log; +import org.sentrysoftware.maven.metricshub.connector.producer.model.platform.Platform; + +/** + * Utility class for producing platform page related to connectors. + */ +public class SpecificPlatformPageProducer extends AbstractGroupConnectorsProducer { + + /** + * Constructor for the tag page producer. + * + * @param logger The logger used for logging. + */ + public SpecificPlatformPageProducer(Log logger) { + super(logger); + } + + /** + * Produces the tag page report that lists all the connectors. + * + * @param sink The sink used for generating content. + * @param platform The platform to be listed as part of the report. + * @param connectorSubdirectoryName The connector subdirectory name. + * @param enterpriseConnectorIds The enterprise connector identifiers. + */ + public void produce( + final Sink sink, + final Platform platform, + final String connectorSubdirectoryName, + final List enterpriseConnectorIds + ) { + Objects.requireNonNull(platform, () -> "platform cannot be null."); + Objects.requireNonNull(sink, () -> "sink cannot be null."); + Objects.requireNonNull(logger, () -> "logger cannot be null."); + + logger.debug("Generating Platform Page: " + SinkHelper.buildPageFilename(platform.getId())); + + final String displayName = platform.getDisplayName(); + final Map connectors = platform.getConnectors(); + + buildHeadAndBody(sink, connectorSubdirectoryName, enterpriseConnectorIds, displayName, connectors); + } + + @Override + protected String getIntroductionText(final String title) { + return String.format("Discover all the available connectors related to the %s platform.", title); + } +} diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/TagPageProducer.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/TagPageProducer.java index 1f61daa..eae9649 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/TagPageProducer.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/TagPageProducer.java @@ -20,8 +20,6 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ -import static org.sentrysoftware.maven.metricshub.connector.ConnectorsDirectoryReport.CONNECTORS_DIRECTORY_OUTPUT_NAME; - import com.fasterxml.jackson.databind.JsonNode; import java.util.List; import java.util.Map; @@ -32,7 +30,7 @@ /** * Utility class for producing tag page related to connectors. */ -public class TagPageProducer extends AbstractPageProducer { +public class TagPageProducer extends AbstractGroupConnectorsProducer { private final String tagName; @@ -65,41 +63,13 @@ public void produce( Objects.requireNonNull(sink, () -> "sink cannot be null."); Objects.requireNonNull(logger, () -> "logger cannot be null."); - logger.debug("Generating " + SinkHelper.buildPageFilename(tagName)); - - // Create the head element of the page - sink.head(); - sink.title(); - sink.text(tagName); - sink.title_(); - sink.head_(); - - sink.body(); - - // Back to the main page - sink.paragraph(SinkHelper.setClass("small")); - sink.rawText(SinkHelper.glyphIcon("arrow-left") + " "); - sink.link(String.format("../../%s.html", CONNECTORS_DIRECTORY_OUTPUT_NAME)); - sink.text("Back to the list of connectors"); - sink.link_(); - sink.paragraph_(); + logger.debug("Generating Tag Page: " + SinkHelper.buildPageFilename(tagName)); - // Title - sink.section1(); - sink.sectionTitle1(); - sink.text(tagName); - sink.sectionTitle1_(); - - sink.paragraph(); - sink.rawText(String.format("This page lists the connectors associated with the %s tag.", tagName)); - sink.paragraph_(); - - // Table of connectors - buildConnectorsTable(sink, connectors, connectorSubdirectoryName, enterpriseConnectorIds, true); + buildHeadAndBody(sink, connectorSubdirectoryName, enterpriseConnectorIds, tagName, connectors); + } - // Close the page - sink.section1_(); - sink.body_(); - sink.close(); + @Override + protected String getIntroductionText(final String title) { + return String.format("Discover all the available connectors related to the %s tag.", title); } } diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/model/platform/Platform.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/model/platform/Platform.java index e6a27c0..2bc8962 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/model/platform/Platform.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/model/platform/Platform.java @@ -20,168 +20,112 @@ * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ */ +import com.fasterxml.jackson.databind.JsonNode; +import java.util.Collections; +import java.util.Comparator; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import lombok.Getter; +import org.sentrysoftware.maven.metricshub.connector.producer.SinkHelper; +import org.sentrysoftware.maven.metricshub.connector.producer.model.common.TechnologyType; /** - * Platform to MetricsHub Connector implementation - * It is made of { os ; platform ; technology }. + * MetricsHub Connector Platform implementation. */ -public class Platform implements Comparable { +public class Platform { /** - * The supported platform name (as specified by the connector `platforms` property) + * Comparator to sort the technology types by display name. */ - @Getter - private final String name; + private static final Comparator COMPARATOR = (p1, p2) -> + p1.getDisplayName().compareTo(p2.getDisplayName()); /** - * The operating system for this platform (Linux, Microsoft Windows, etc.) + * The unique identifier of the platform */ @Getter - private final String os; + private String id; /** - * The type of connection we're using to support this platform (SNMP, WBEM, SSH, etc.) + * The supported platform name (as specified by the connector `platforms` property) */ @Getter - private final String technology; + private String displayName; /** - * Connector ID to display name mapping + * The icon path of the platform */ - private final Map connectors = new LinkedHashMap<>(); + @Getter + private String iconPath; /** - * All the prerequisites for this platform + * The technology types supported by the platform */ - private final Set prerequisites = new LinkedHashSet<>(); + private Set technologies = new TreeSet<>(COMPARATOR); - private final int hashCode; + /** + * Connectors associated with this platform + */ + private Map connectors = new LinkedHashMap<>(); /** - * Constructs a new instance of the platform + * Constructor for the Platform class. * - * @param name The supported platform name (as specified by the connector `platforms` property) - * @param os The operating system for this platform (Linux, Microsoft Windows, etc.) - * @param technology The type of connection we're using to support this platform (SNMP, WBEM, SSH, etc.) + * @param id The unique identifier of the platform. + * @param displayName The name of the platform. + * @param iconPath The icon path of the platform. */ - public Platform(String name, String os, String technology) { - this.name = name; - this.os = os; - this.technology = technology; - - // The hash code needs to be computed only once to avoid calling String.toLowerCase many times. - this.hashCode = lowerCaseHashCode(name, os, technology); + public Platform(final String id, final String displayName, final String iconPath) { + this.id = id; + this.displayName = displayName; + this.iconPath = iconPath; } /** - * Calculates the hashCode code of the concatenated lowercased strings. - * - * @param elements The elements to be concatenated and hashed. - * @return The hashCode code of the concatenated lowercased strings. + * Adds a connector to the platform. + * @param connectorId The connector unique identifier. + * @param connector The connector as a {@link JsonNode}. */ - private int lowerCaseHashCode(final String... elements) { - int result = 1; - - for (String element : elements) { - result = 31 * result + (element != null ? element.toLowerCase().hashCode() : 0); - } - - return result; + public void addConnector(final String connectorId, final JsonNode connector) { + connectors.put(connectorId, connector); } /** - * We're sorting Platforms by putting entries that starts with "Any " at the end of the list - * - * @param other the {@link Platform} to be compared. - * @see java.lang.Comparable#compareTo(java.lang.Object) + * Adds technology types to the platform. + * @param technologies The technology types to add. */ - @Override - public int compareTo(Platform other) { - if (other == null) { - return 1; - } - - int comparison = this.os.compareToIgnoreCase(other.os); - if (comparison == 0) { - // Special case for platforms that start with "Any " - if (this.name.toLowerCase().startsWith("any ")) { - if (other.name.toLowerCase().startsWith("any ")) { - comparison = this.name.compareToIgnoreCase(other.name); - } else { - comparison = 1; - } - } else if (other.name.toLowerCase().startsWith("any ")) { - comparison = -1; - } else { - comparison = this.name.compareToIgnoreCase(other.name); - } - } - - return comparison; + public void addTechnologies(final Set technologies) { + this.technologies.addAll(technologies); } /** - * Adds information about a connector, including its identifier, display name, and a prerequisite. + * Formats the platforms of a connector. * - * @param connectorId The identifier of the connector. - * @param displayName The display name of the connector. - * @param reliesOn Considered as the technical prerequisites for this connector. + * @param platforms The platforms to format. + * @return A string representation of the platforms. */ - public void addConnectorInformation(final String connectorId, final String displayName, final String reliesOn) { - connectors.put(connectorId, displayName); - prerequisites.add(reliesOn); - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Platform other = (Platform) obj; - // @formatter:off - return - this.name.equalsIgnoreCase(other.name) && - this.os.equalsIgnoreCase(other.os) && - this.technology.equalsIgnoreCase(other.technology); - // @formatter:on + public static String formatPlatforms(final Set platforms) { + return platforms.stream().map(SinkHelper::replaceCommaWithSpace).collect(Collectors.joining(", ")); } /** - * Gets the connectors associated with the platform. + * Gets the technology types supported by the platform. * - * @return A {@code Map} containing connector names as keys and their associated display names as values. + * @return The technology types supported by the platform. */ - public Map getConnectors() { - return connectors - .entrySet() - .stream() - .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> b, LinkedHashMap::new)); + public Set getTechnologies() { + return Collections.unmodifiableSet(technologies); } /** - * Gets the prerequisites associated with the platform. + * Gets the connectors associated with this platform. * - * @return A {@code Set} containing prerequisites. + * @return The connectors associated with this platform. */ - public Set getPrerequisites() { - return prerequisites.stream().collect(Collectors.toCollection(LinkedHashSet::new)); + public Map getConnectors() { + return Collections.unmodifiableMap(connectors); } } diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/package-info.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/package-info.java index 4ac47c6..aaa5484 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/package-info.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/producer/package-info.java @@ -1,7 +1,8 @@ /** * The part of library responsible for producing documentation output.
* - * See {@link org.sentrysoftware.maven.metricshub.connector.producer.MainPageProducer}.
+ * See {@link org.sentrysoftware.maven.metricshub.connector.producer.PlatformsPageProducer}.
+ * See {@link org.sentrysoftware.maven.metricshub.connector.producer.FullListingPageProducer}.
* See {@link org.sentrysoftware.maven.metricshub.connector.producer.ConnectorPageProducer}. */ package org.sentrysoftware.maven.metricshub.connector.producer; From 3f5677698f7d6dfa9214c256e754dfe2deec5253 Mon Sep 17 00:00:00 2001 From: Nassim Boutekedjiret Date: Mon, 13 Jan 2025 19:20:52 +0100 Subject: [PATCH 2/2] Issue #71: Display platform tiles in the connectors directory * Added the possibility to define a default platform icon. --- src/it/metricshub-connectors/verify.groovy | 2 +- .../connector/AbstractConnectorReport.java | 22 ++++++- .../connector/ConnectorsDirectoryReport.java | 66 +++++++++++++++++-- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/src/it/metricshub-connectors/verify.groovy b/src/it/metricshub-connectors/verify.groovy index fbc03a9..2cd8152 100644 --- a/src/it/metricshub-connectors/verify.groovy +++ b/src/it/metricshub-connectors/verify.groovy @@ -309,7 +309,7 @@ platforms.each { platform -> assert directoryHtmlText.indexOf("href=\"${platform.link}\"") > -1 : "Platform '${platform.name}' must link to '${platform.link}'" // Check platform icon - assert directoryHtmlText.indexOf("src=\"images/platforms/${platform.icon}.png\"") > -1 : "Platform '${platform.name}' must have the correct icon '${platform.icon}.png'" + assert directoryHtmlText.indexOf("src=\"./images/platforms/${platform.icon}.png\"") > -1 : "Platform '${platform.name}' must have the correct icon '${platform.icon}.png'" } // Additional checks classes diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java index f7014fc..d216e90 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/AbstractConnectorReport.java @@ -53,10 +53,26 @@ public abstract class AbstractConnectorReport extends AbstractMavenReport { protected File sourceDirectory; /** - * The directory where the platform icons are located. + * The directory where the icons will be copied to in the generated site. */ - @Parameter(defaultValue = "images/platforms", property = "platformIconsDirectory", required = true) - protected String platformIconsDirectory; + @Parameter(defaultValue = "./images/platforms", property = "platformIconsOutputDirectory", required = true) + protected String platformIconsOutputDirectory; + + /** + * The directory where the platform icons are located in the project. + */ + @Parameter( + defaultValue = "${project.basedir}/src/site/resources/images/platforms", + property = "platformIconsInputDirectory", + required = true + ) + protected String platformIconsInputDirectory; + + /** + * The file name of the default icon to be used when a platform icon is not found. + */ + @Parameter(property = "defaultPlatformIconFilename", required = false) + protected String defaultPlatformIconFilename; protected Log logger; diff --git a/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java b/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java index 42f820d..0e6eaf8 100644 --- a/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java +++ b/src/main/java/org/sentrysoftware/maven/metricshub/connector/ConnectorsDirectoryReport.java @@ -31,6 +31,7 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.maven.doxia.sink.Sink; @@ -75,15 +76,17 @@ ) public class ConnectorsDirectoryReport extends AbstractConnectorReport { + private static final String PLATFORM_ICON_PATH_FORMAT = "%s/%s.png"; + /** * Format string for sink creation error messages. */ private static final String SINK_CREATION_ERROR_FORMAT = "Could not create sink for %s in %s"; /** - * Format string to create a subdirectory. + * Format string to create a child path. */ - private static final String SUBDIRECTORY_FORMAT = "%s/%s"; + private static final String CHILD_PATH_FORMAT = "%s/%s"; @Override protected void doReport() throws MavenReportException { @@ -109,7 +112,7 @@ protected void doReport() throws MavenReportException { // Subdirectory within connector subdirectory where we store the pages for each platform. final File platformSubdirectory = new File( - String.format(SUBDIRECTORY_FORMAT, outputDirectory, connectorDirectoryName), + String.format(CHILD_PATH_FORMAT, outputDirectory, connectorDirectoryName), Constants.PLATFORM_SUBDIRECTORY_NAME ); if (!platformSubdirectory.exists() && !platformSubdirectory.mkdirs()) { @@ -129,7 +132,7 @@ protected void doReport() throws MavenReportException { // Subdirectory within connector subdirectory where we store the pages for each tag. final File tagSubdirectory = new File( - String.format(SUBDIRECTORY_FORMAT, outputDirectory, connectorDirectoryName), + String.format(CHILD_PATH_FORMAT, outputDirectory, connectorDirectoryName), Constants.TAG_SUBDIRECTORY_NAME ); if (!tagSubdirectory.exists() && !tagSubdirectory.mkdirs()) { @@ -301,6 +304,9 @@ private Map> determineTags() { * @return a list of platforms sorted by display name. */ private List determinePlatforms() { + // We may have a default icon for all platforms or missing icons for some platforms + final Optional maybeDefaultIconOutputPath = retrieveDefaultPlatformIconOutputPath(); + final Map platforms = new HashMap<>(); for (Map.Entry connectorEntry : connectors.entrySet()) { final JsonNode connector = connectorEntry.getValue(); @@ -312,7 +318,8 @@ private List determinePlatforms() { // Merge or create final Platform platform = platforms.computeIfAbsent( platformId, - id -> new Platform(id, platformName, "%s/%s.png".formatted(platformIconsDirectory, id)) + id -> + new Platform(id, platformName, retrievePlatformIconOutputPath(platformName, id, maybeDefaultIconOutputPath)) ); // Add the connector @@ -326,6 +333,53 @@ private List determinePlatforms() { return platforms.values().stream().sorted(Comparator.comparing(Platform::getDisplayName)).toList(); } + /** + * Retrieves the default icon output path if the default platform icon file exists. + * + * @return The optional default icon output path + */ + private Optional retrieveDefaultPlatformIconOutputPath() { + if ( + defaultPlatformIconFilename != null && new File(platformIconsInputDirectory, defaultPlatformIconFilename).exists() + ) { + return Optional.of(CHILD_PATH_FORMAT.formatted(platformIconsOutputDirectory, defaultPlatformIconFilename)); + } + return Optional.empty(); + } + + /** + * Retrieves the icon path for the specified platform. + * + * @param platformName The name of the platform. + * @param platformId The ID of the platform. + * @param maybeDefaultIconOutputPath The optional default icon output path. + * @return The path to the icon for the specified platform. + * @throws IllegalStateException If the icon for the specified platform is not found. + */ + private String retrievePlatformIconOutputPath( + final String platformName, + String platformId, + final Optional maybeDefaultIconOutputPath + ) { + // The corresponding icon file in the project + final File iconInputFile = new File(PLATFORM_ICON_PATH_FORMAT.formatted(platformIconsInputDirectory, platformId)); + + // Check if the icon file exists in the project + if (iconInputFile.exists()) { + return PLATFORM_ICON_PATH_FORMAT.formatted(platformIconsOutputDirectory, platformId); + } + + logger.info("Icon %s not found for platform: %s.".formatted(iconInputFile.getAbsolutePath(), platformName)); + + logger.info("Attempting to use the default icon for the platform: %s.".formatted(platformName)); + + return maybeDefaultIconOutputPath.orElseThrow(() -> + new IllegalStateException( + "Icon %s not found for platform: %s.".formatted(iconInputFile.getAbsolutePath(), platformName) + ) + ); + } + /** * Converts the given text to kebab-case. * @@ -375,7 +429,7 @@ private void produceSpecifcPlatformPages(final File platformSubdirectory, final private void producePlatformsPage(final List platforms) throws MavenReportException { new PlatformsPageProducer( logger, - SUBDIRECTORY_FORMAT.formatted(Constants.CONNECTOR_SUBDIRECTORY_NAME, Constants.PLATFORM_SUBDIRECTORY_NAME) + CHILD_PATH_FORMAT.formatted(Constants.CONNECTOR_SUBDIRECTORY_NAME, Constants.PLATFORM_SUBDIRECTORY_NAME) ) .produce(getMainSink(), platforms); }