From 970bc7818a9ec0d6e125a908c79d0c1844bfea94 Mon Sep 17 00:00:00 2001 From: HuangXin Date: Tue, 14 Jan 2025 10:16:34 +0800 Subject: [PATCH] =?UTF-8?q?OCT=20REM:=201.=20=E5=A2=9E=E5=8A=A0=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=B3=BB=E7=BB=9F=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=202.=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=9B=B8=E5=85=B3=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magent/annotation/AutoExternString.java | 1 - .../impl/AutoExternStringJsonProcess.java | 75 +++++---- .../cmhi/magent/controller/SystemInfoApi.java | 51 ++++++ .../com/cmhi/magent/pojo/po/NetworkInfo.java | 152 ++++-------------- .../cmhi/magent/pojo/po/ProcessorInfo.java | 3 + .../magent/pojo/vo/GetFileStoreInfoResp.java | 56 +++++++ .../magent/pojo/vo/GetMemoryInfoResp.java | 58 +++++++ .../magent/pojo/vo/GetNetworkInfoResp.java | 74 +++++++++ .../magent/service/SystemInfoService.java | 31 ++++ .../service/impl/SystemInfoServiceImpl.java | 68 +++++--- .../magent/controller/SystemInfoApiTest.java | 45 ++++++ .../service/SystemInfoServiceImplTest.java | 114 +++++++++++++ 12 files changed, 546 insertions(+), 182 deletions(-) create mode 100644 src/main/java/com/cmhi/magent/pojo/vo/GetFileStoreInfoResp.java create mode 100644 src/main/java/com/cmhi/magent/pojo/vo/GetMemoryInfoResp.java create mode 100644 src/main/java/com/cmhi/magent/pojo/vo/GetNetworkInfoResp.java create mode 100644 src/test/java/com/cmhi/magent/service/SystemInfoServiceImplTest.java diff --git a/src/main/java/com/cmhi/magent/annotation/AutoExternString.java b/src/main/java/com/cmhi/magent/annotation/AutoExternString.java index b6b6c9c..fc56420 100644 --- a/src/main/java/com/cmhi/magent/annotation/AutoExternString.java +++ b/src/main/java/com/cmhi/magent/annotation/AutoExternString.java @@ -86,7 +86,6 @@ import java.lang.annotation.Target; */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) -@JsonSerialize(using = AutoExternStringJsonProcess.class) public @interface AutoExternString { /** diff --git a/src/main/java/com/cmhi/magent/annotation/impl/AutoExternStringJsonProcess.java b/src/main/java/com/cmhi/magent/annotation/impl/AutoExternStringJsonProcess.java index f09303f..c5b7e61 100644 --- a/src/main/java/com/cmhi/magent/annotation/impl/AutoExternStringJsonProcess.java +++ b/src/main/java/com/cmhi/magent/annotation/impl/AutoExternStringJsonProcess.java @@ -73,6 +73,8 @@ public class AutoExternStringJsonProcess extends JsonSerializer implemen */ private Class> enumClass = null; + private boolean enableFormat = false; + /** * 默认构造方法。 */ @@ -92,12 +94,14 @@ public class AutoExternStringJsonProcess extends JsonSerializer implemen String suffix, UtilsFormatType formatType, String units, - Class> classType) { - this.prefix = prefix; - this.suffix = suffix; - this.formatType = formatType; - this.enumClass = classType; - this.units = units; + Class> classType, + boolean enableFormat) { + this.prefix = prefix; + this.suffix = suffix; + this.formatType = formatType; + this.enumClass = classType; + this.units = units; + this.enableFormat = enableFormat; } /** @@ -115,6 +119,7 @@ public class AutoExternStringJsonProcess extends JsonSerializer implemen public void serialize(Number value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { Long numericValue = null; + // 将字段值转换为 Long 类型 if (value instanceof Long) { numericValue = (Long) value; @@ -126,37 +131,39 @@ public class AutoExternStringJsonProcess extends JsonSerializer implemen // 写入原始字段值 jsonGenerator.writeNumber(numericValue); - // 生成额外字段名 - String filedName = prefix + jsonGenerator.getOutputContext().getCurrentName() + suffix; - jsonGenerator.writeFieldName(filedName); + if (enableFormat) { + // 生成额外字段名 + String filedName = prefix + jsonGenerator.getOutputContext().getCurrentName() + suffix; + jsonGenerator.writeFieldName(filedName); - // 写入额外字段值 - if (formatType == UtilsFormatType.FORMAT_BYTES) { - String formattedValue = FormatUtil.formatBytes(numericValue); - jsonGenerator.writeString(formattedValue); - } else if (formatType == UtilsFormatType.FORMAT_BYTESDECIMAL) { - String formattedValue = FormatUtil.formatBytesDecimal(numericValue); - jsonGenerator.writeString(formattedValue); - } else if (formatType == UtilsFormatType.FORMAT_UNITS) { - String formattedValue = FormatUtil.formatValue(numericValue, units); - jsonGenerator.writeString(formattedValue); - } else if (formatType == UtilsFormatType.FORMAT_ENUM) { - try { - // 将字段值转换为枚举实例 - Method fromValueMethod = enumClass.getMethod("fromValue", int.class); - Enum enumInstance = (Enum) fromValueMethod.invoke(null, (int) value); + // 写入额外字段值 + if (formatType == UtilsFormatType.FORMAT_BYTES) { + String formattedValue = FormatUtil.formatBytes(numericValue); + jsonGenerator.writeString(formattedValue); + } else if (formatType == UtilsFormatType.FORMAT_BYTESDECIMAL) { + String formattedValue = FormatUtil.formatBytesDecimal(numericValue); + jsonGenerator.writeString(formattedValue); + } else if (formatType == UtilsFormatType.FORMAT_UNITS) { + String formattedValue = FormatUtil.formatValue(numericValue, units); + jsonGenerator.writeString(formattedValue); + } else if (formatType == UtilsFormatType.FORMAT_ENUM) { + try { + // 将字段值转换为枚举实例 + Method fromValueMethod = enumClass.getMethod("fromValue", int.class); + Enum enumInstance = (Enum) fromValueMethod.invoke(null, (int) value); - // 调用枚举实例的描述方法 - Method method = enumClass.getMethod("getDescription"); - String description = (String) method.invoke(enumInstance); + // 调用枚举实例的描述方法 + Method method = enumClass.getMethod("getDescription"); + String description = (String) method.invoke(enumInstance); - // 写入描述字符串 - jsonGenerator.writeString(description); - } catch (Exception e) { - throw new IOException("Failed to convert enum value to description", e); + // 写入描述字符串 + jsonGenerator.writeString(description); + } catch (Exception e) { + throw new IOException("Failed to convert enum value to description", e); + } + } else { + jsonGenerator.writeString(numericValue.toString()); } - } else { - jsonGenerator.writeString(numericValue.toString()); } } else { // 如果值为空或不支持,则使用默认序列化方式 @@ -183,7 +190,7 @@ public class AutoExternStringJsonProcess extends JsonSerializer implemen if (annotation != null) { // 根据注解配置创建新的序列化器 return new AutoExternStringJsonProcess(annotation.prefix(), annotation.suffix(), annotation.format(), annotation.units(), - annotation.enumClass()); + annotation.enumClass(), true); } } // 如果字段不存在注解,返回默认实例 diff --git a/src/main/java/com/cmhi/magent/controller/SystemInfoApi.java b/src/main/java/com/cmhi/magent/controller/SystemInfoApi.java index aae0911..220a8af 100644 --- a/src/main/java/com/cmhi/magent/controller/SystemInfoApi.java +++ b/src/main/java/com/cmhi/magent/controller/SystemInfoApi.java @@ -2,7 +2,10 @@ package com.cmhi.magent.controller; import com.cmhi.magent.annotation.EncryptionProtocol; import com.cmhi.magent.annotation.OperationLogAnnotation; +import com.cmhi.magent.pojo.vo.GetFileStoreInfoResp; import com.cmhi.magent.pojo.vo.GetHwInfoResp; +import com.cmhi.magent.pojo.vo.GetMemoryInfoResp; +import com.cmhi.magent.pojo.vo.GetNetworkInfoResp; import com.cmhi.magent.pojo.vo.GetOsInfoResp; import com.cmhi.magent.pojo.vo.GetProcessorInfoResp; import com.cmhi.magent.pojo.vo.ProtocolResp; @@ -100,4 +103,52 @@ public class SystemInfoApi { public ProtocolResp getHwInfo() { return ProtocolResp.result(GetHwInfoResp.builder().hwInfo(systemInfoService.getHardwareInfo()).build()); } + + /** + * 获取网络信息。 + * + *

该接口返回系统网络相关信息。返回数据通过加密协议进行保护,并记录操作日志。

+ * + * @return 封装了网络信息的响应对象。 + */ + @GetMapping("/networkInfo") + @EncryptionProtocol + @OperationLogAnnotation(OperationModule = "SYSLOG_MOD_SYSINFO", + OperationType = "SYSLOG_TYPE_READ", + OperationDesc = "SYSLOG_DESC_GET_HW_INFO") + public ProtocolResp getNetworkInfo() { + return ProtocolResp.result(GetNetworkInfoResp.builder().networkInfo(systemInfoService.getNetworkInfo()).build()); + } + + /** + * 获取内存信息。 + * + *

该接口返回系统内存相关信息。返回数据通过加密协议进行保护,并记录操作日志。

+ * + * @return 封装了网络信息的响应对象。 + */ + @GetMapping("/memoryInfo") + @EncryptionProtocol + @OperationLogAnnotation(OperationModule = "SYSLOG_MOD_SYSINFO", + OperationType = "SYSLOG_TYPE_READ", + OperationDesc = "SYSLOG_DESC_GET_HW_INFO") + public ProtocolResp geMemoryInfo() { + return ProtocolResp.result(GetMemoryInfoResp.builder().memoryInfo(systemInfoService.getMemoryInfo()).build()); + } + + /** + * 获取文件存储信息。 + * + *

该接口返回系统文件系统以及磁盘相关信息。返回数据通过加密协议进行保护,并记录操作日志。

+ * + * @return 封装了文件存储信息的响应对象。 + */ + @GetMapping("/fileStoreInfo") + @EncryptionProtocol + @OperationLogAnnotation(OperationModule = "SYSLOG_MOD_SYSINFO", + OperationType = "SYSLOG_TYPE_READ", + OperationDesc = "SYSLOG_DESC_GET_HW_INFO") + public ProtocolResp geFileStoreInfo() { + return ProtocolResp.result(GetFileStoreInfoResp.builder().fileStoreInfo(systemInfoService.getFileStoreInfo()).build()); + } } diff --git a/src/main/java/com/cmhi/magent/pojo/po/NetworkInfo.java b/src/main/java/com/cmhi/magent/pojo/po/NetworkInfo.java index ff6fd02..ae27245 100644 --- a/src/main/java/com/cmhi/magent/pojo/po/NetworkInfo.java +++ b/src/main/java/com/cmhi/magent/pojo/po/NetworkInfo.java @@ -5,145 +5,55 @@ import com.cmhi.magent.common.UtilsFormatType; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.util.List; + /** - * 网络信息类。 + * NetworkInfo 类表示系统的网络信息,包括网络接口、主机名、域名、DNS 服务器和网关信息。 *

- * 此类用于封装网络的详细信息,包括网络名称、网络类型、网络状态、网络速度等。 - * 主要用于监控系统网络的状态,例如网络连接的速度和稳定性。 + * 该类通过 Lombok 的 {@code @Data} 注解自动生成 getter/setter 方法。 + * 同时集成了 Swagger 3 的注释以支持接口文档的生成。 *

* - *

- * 依赖于 Lombok 的 {@code @Data} 注解,自动生成以下方法: - *

- *
    - *
  • Getter 和 Setter 方法
  • - *
  • {@code toString()} 方法
  • - *
  • {@code equals()} 和 {@code hashCode()} 方法
  • - *
- * - *

- * 此类还集成了自定义注解 {@link AutoExternString},用于在 JSON 序列化时对字段进行额外处理。 - * 例如,自动将网络速度值格式化为更易识别的单位(如 Mbps、Kbps)。 - *

- * - *

使用示例:

- *
- * NetworkInfo networkInfo = new NetworkInfo();
- * networkInfo.setNetworkName("Wi-Fi");
- * networkInfo.setNetworkType("Wireless");
- * networkInfo.setNetworkSpeed(1024L); // 设置网络速度为 1 Mbps
- * 
- * - *

JSON 输出示例:

- *
- * {
- *     "networkName": "Wi-Fi",
- *     "networkType": "Wireless",
- *     "networkSpeed": 1024,
- *     "networkSpeedStr": "1 Mbps"
- * }
- * 
- * - *

注意:{@code @AutoExternString} 注解会自动根据字段值转换为适合的单位,并生成额外的格式化字符串。

- * - *

例如,值 {@code 1024L}(字节/秒)在 JSON 中将自动格式化为 {@code "1 Mbps"}。

- * * @author huangxin@cmhi.chinamobile.com - * @version 1.0.0 - * @since 2025-01-13 + * * @version 1.0.0 + * * @since 2025-01-13 */ @Data public class NetworkInfo { /** - * 网络名称。 - *

- * 该字段记录网络的名称,通常用于标识不同的网络连接,如 Wi-Fi、以太网等。 - * 在 JSON 序列化时,该字段直接输出原始值。 - *

- * - *

示例值:

- *
    - *
  • {@code "Wi-Fi"}。
  • - *
- * - *

JSON 输出示例:

- *
-     * {
-     *     "networkName": "Wi-Fi"
-     * }
-     * 
+ * 系统中所有的网络接口信息。 */ - @Schema(description = "网络名称。", example = "Wi-Fi") - private String networkName; + @Schema(description = "系统中所有的网络接口信息") + private List ifNetwork; /** - * 网络类型。 - *

- * 该字段记录网络的类型,如无线网络(Wireless)、有线网络(Wired)等。 - * 在 JSON 序列化时,该字段直接输出原始值。 - *

- * - *

示例值:

- *
    - *
  • {@code "Wireless"}。
  • - *
- * - *

JSON 输出示例:

- *
-     * {
-     *     "networkType": "Wireless"
-     * }
-     * 
+ * 系统的主机名。 */ - @Schema(description = "网络类型。", example = "Wireless") - private String networkType; + @Schema(description = "系统的主机名") + private String hostName; /** - * 网络状态。 - *

- * 该字段记录网络的当前状态,如已连接(Connected)、断开连接(Disconnected)等。 - * 在 JSON 序列化时,该字段直接输出原始值。 - *

- * - *

示例值:

- *
    - *
  • {@code "Connected"}。
  • - *
- * - *

JSON 输出示例:

- *
-     * {
-     *     "networkStatus": "Connected"
-     * }
-     * 
+ * 系统所在的域名。 */ - @Schema(description = "网络状态。", example = "Connected") - private String networkStatus; + @Schema(description = "系统所在的域名") + private String domainName; /** - * 网络速度(单位:字节/秒)。 - *

- * 该字段记录网络的当前速度,通常用于表示网络连接的带宽或数据传输速率。 - * 在 JSON 序列化时,通过 {@link AutoExternString} 注解生成一个格式化后的额外字段。 - *

- * - *

示例值:

- *
    - *
  • {@code 1024L}(表示 1 Mbps 网络速度)。
  • - *
- * - *

JSON 输出示例:

- *
-     * {
-     *     "networkSpeed": 1024,
-     *     "networkSpeedStr": "1 Mbps"
-     * }
-     * 
- * - * @see AutoExternString + * 系统配置的 DNS 服务器地址列表。 */ - @Schema(description = "网络速度(单位:字节/秒)。", example = "1024") - @AutoExternString(format = UtilsFormatType.FORMAT_BYTES) - private Long networkSpeed; + @Schema(description = "系统配置的 DNS 服务器地址列表") + private String[] dnsServers; + + /** + * 系统的 IPv4 默认网关地址。 + */ + @Schema(description = "系统的 IPv4 默认网关地址") + private String ipv4DefaultGateway; + + /** + * 系统的 IPv6 默认网关地址。 + */ + @Schema(description = "系统的 IPv6 默认网关地址") + private String ipv6DefaultGateway; } diff --git a/src/main/java/com/cmhi/magent/pojo/po/ProcessorInfo.java b/src/main/java/com/cmhi/magent/pojo/po/ProcessorInfo.java index 78954dd..6244e38 100644 --- a/src/main/java/com/cmhi/magent/pojo/po/ProcessorInfo.java +++ b/src/main/java/com/cmhi/magent/pojo/po/ProcessorInfo.java @@ -1,5 +1,7 @@ package com.cmhi.magent.pojo.po; +import com.cmhi.magent.annotation.AutoExternString; +import com.cmhi.magent.common.UtilsFormatType; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -116,6 +118,7 @@ public class ProcessorInfo { *

*/ @Schema(description = "处理器的标称主频(单位:Hz)。", example = "3800000000") + @AutoExternString(format = UtilsFormatType.FORMAT_UNITS, units = "Hz") private Long cpuVendorFreq; /** diff --git a/src/main/java/com/cmhi/magent/pojo/vo/GetFileStoreInfoResp.java b/src/main/java/com/cmhi/magent/pojo/vo/GetFileStoreInfoResp.java new file mode 100644 index 0000000..1c62a5c --- /dev/null +++ b/src/main/java/com/cmhi/magent/pojo/vo/GetFileStoreInfoResp.java @@ -0,0 +1,56 @@ +package com.cmhi.magent.pojo.vo; + +import com.cmhi.magent.pojo.po.BaseRespStatus; +import com.cmhi.magent.pojo.po.FileStoreInfo; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * 文件存储信息响应类 {@code GetFileStoreInfoResp}。 + *

+ * 用于封装文件存储信息的响应结果,继承自 {@link BaseRespStatus},包含状态码、消息以及文件存储的详细信息。 + *

+ * + *

+ * 核心功能: + *

    + *
  • 继承基础响应状态类,统一包含状态码和消息。
  • + *
  • 封装文件存储相关的详细信息,通过 {@code fileStoreInfo} 字段返回。
  • + *
+ *

+ * + *

+ * 使用场景: + *

    + *
  • 用于 RESTful API 的文件存储信息查询接口。
  • + *
  • 适用于系统监控模块,获取文件存储的详细配置信息,例如总存储空间、可用存储空间、文件系统类型等。
  • + *
+ *

+ * + * @author huangxin@cmhi.chinamobile.com + * @version 1.0.0 + * @since 2025-01-07 + */ +@Schema(name = "文件存储信息", description = "包含文件存储的详细信息,如总存储空间、可用存储空间、文件系统类型等。") +@EqualsAndHashCode(callSuper = true) +@Data +@Builder +@JsonPropertyOrder({"fileStoreInfo", "status", "message"}) +@AllArgsConstructor +@NoArgsConstructor +public class GetFileStoreInfoResp extends BaseRespStatus { + + /** + * 文件存储信息内容。 + *

+ * 包含文件存储的详细信息,例如总存储空间、可用存储空间、文件系统类型等。 + * 类型为 {@link FileStoreInfo}。 + *

+ */ + private FileStoreInfo fileStoreInfo; +} diff --git a/src/main/java/com/cmhi/magent/pojo/vo/GetMemoryInfoResp.java b/src/main/java/com/cmhi/magent/pojo/vo/GetMemoryInfoResp.java new file mode 100644 index 0000000..1265404 --- /dev/null +++ b/src/main/java/com/cmhi/magent/pojo/vo/GetMemoryInfoResp.java @@ -0,0 +1,58 @@ +package com.cmhi.magent.pojo.vo; + +import com.cmhi.magent.pojo.po.BaseRespStatus; +import com.cmhi.magent.pojo.po.MemoryInfo; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * 内存信息响应类 {@code GetMemoryInfoResp}。 + *

+ * 用于封装内存信息的响应结果,继承自 {@link BaseRespStatus},包含状态码、消息以及内存的详细信息。 + *

+ * + *

+ * 核心功能: + *

    + *
  • 继承基础响应状态类,统一包含状态码和消息。
  • + *
  • 封装内存相关的详细信息,通过 {@code memoryInfo} 字段返回。
  • + *
+ *

+ * + *

+ * 使用场景: + *

    + *
  • 用于 RESTful API 的内存信息查询接口。
  • + *
  • 适用于系统监控模块,获取内存的详细配置信息,例如总内存、可用内存、内存使用率等。
  • + *
+ *

+ * + *

+ * + * @author huangxin@cmhi.chinamobile.com + * @version 1.0.0 + * @since 2025-01-07 + */ +@Schema(name = "内存信息", description = "包含内存的详细信息,如总内存、可用内存、内存使用率等。") +@EqualsAndHashCode(callSuper = true) +@Data +@Builder +@JsonPropertyOrder({"memoryInfo", "status", "message"}) +@AllArgsConstructor +@NoArgsConstructor +public class GetMemoryInfoResp extends BaseRespStatus { + + /** + * 内存信息内容。 + *

+ * 包含内存的详细信息,例如总内存、可用内存、内存使用率等。 + * 类型为 {@link MemoryInfo}。 + *

+ */ + private MemoryInfo memoryInfo; +} diff --git a/src/main/java/com/cmhi/magent/pojo/vo/GetNetworkInfoResp.java b/src/main/java/com/cmhi/magent/pojo/vo/GetNetworkInfoResp.java new file mode 100644 index 0000000..25c1cef --- /dev/null +++ b/src/main/java/com/cmhi/magent/pojo/vo/GetNetworkInfoResp.java @@ -0,0 +1,74 @@ +package com.cmhi.magent.pojo.vo; + +import com.cmhi.magent.pojo.po.BaseRespStatus; +import com.cmhi.magent.pojo.po.NetworkInfo; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * 网络信息响应类 {@code GetNetworkInfoResp}。 + *

+ * 用于封装网络信息的响应结果,继承自 {@link BaseRespStatus},包含状态码、消息以及网络的详细信息。 + *

+ * + *

+ * 核心功能: + *

    + *
  • 继承基础响应状态类,统一包含状态码和消息。
  • + *
  • 封装网络相关的详细信息,通过 {@code networkInfo} 字段返回。
  • + *
+ *

+ * + *

+ * 使用场景: + *

    + *
  • 用于 RESTful API 的网络信息查询接口。
  • + *
  • 适用于系统监控模块,获取网络的详细配置信息,例如IP地址、MAC地址、网络接口等。
  • + *
+ *

+ * + *

+ * JSON 输出示例: + *

+ * {
+ *     "status": "SUCCESS",
+ *     "message": "Network information retrieved successfully",
+ *     "networkInfo": {
+ *         "ipAddress": "192.168.1.100",
+ *         "macAddress": "00:11:22:33:44:55",
+ *         "networkInterfaces": [
+ *             "eth0",
+ *             "wlan0"
+ *         ]
+ *     }
+ * }
+ * 
+ *

+ * + * @author huangxin@cmhi.chinamobile.com + * @version 1.0.0 + * @since 2025-01-07 + */ +@Schema(name = "网络信息", description = "包含网络的详细信息,如IP地址、MAC地址、网络接口等。") +@EqualsAndHashCode(callSuper = true) +@Data +@Builder +@JsonPropertyOrder({"networkInfo", "status", "message"}) +@AllArgsConstructor +@NoArgsConstructor +public class GetNetworkInfoResp extends BaseRespStatus { + + /** + * 网络信息内容。 + *

+ * 包含网络的详细信息,例如IP地址、MAC地址、网络接口等。 + * 类型为 {@link NetworkInfo}。 + *

+ */ + private NetworkInfo networkInfo; +} diff --git a/src/main/java/com/cmhi/magent/service/SystemInfoService.java b/src/main/java/com/cmhi/magent/service/SystemInfoService.java index 09292fa..4590142 100644 --- a/src/main/java/com/cmhi/magent/service/SystemInfoService.java +++ b/src/main/java/com/cmhi/magent/service/SystemInfoService.java @@ -1,6 +1,9 @@ package com.cmhi.magent.service; +import com.cmhi.magent.pojo.po.FileStoreInfo; import com.cmhi.magent.pojo.po.HwInfo; +import com.cmhi.magent.pojo.po.MemoryInfo; +import com.cmhi.magent.pojo.po.NetworkInfo; import com.cmhi.magent.pojo.po.ProcessorInfo; /** @@ -55,4 +58,32 @@ public interface SystemInfoService { * @return 硬件信息对象 */ HwInfo getHardwareInfo(); + + /** + * 获取网络信息。 + *

+ * 封装网络的相关信息,如网络名称、网络类型、网络状态、网络速度等。结果以 {@link NetworkInfo} 对象形式返回。 + *

+ * + * @return 网络信息对象 + */ + NetworkInfo getNetworkInfo(); + + /** + * 获取内存信息 + *

+ * 封装内存的相关信息,如物理内存大小,可用内存,当前内存占用情况等。结果以 {@link MemoryInfo} 对象形式返回。 + *

+ * @return 返回一个 MemoryInfo 对象,包含内存的详细信息 + */ + MemoryInfo getMemoryInfo(); + + /** + * 获取文件存储信息 + *

+ * 封装操作系统文件系统相关信息,如磁盘大小,分区大小等。结果以 {@link FileStoreInfo} 对象形式返回。 + *

+ * @return 返回一个 MemoryInfo 对象,包含内存的详细信息 + */ + FileStoreInfo getFileStoreInfo(); } diff --git a/src/main/java/com/cmhi/magent/service/impl/SystemInfoServiceImpl.java b/src/main/java/com/cmhi/magent/service/impl/SystemInfoServiceImpl.java index 80dd892..ce9a910 100644 --- a/src/main/java/com/cmhi/magent/service/impl/SystemInfoServiceImpl.java +++ b/src/main/java/com/cmhi/magent/service/impl/SystemInfoServiceImpl.java @@ -1,19 +1,15 @@ package com.cmhi.magent.service.impl; import com.cmhi.magent.pojo.mapper.IObjectConvert; -import com.cmhi.magent.pojo.po.FileStoreDetails; import com.cmhi.magent.pojo.po.FileStoreInfo; import com.cmhi.magent.pojo.po.HwInfo; +import com.cmhi.magent.pojo.po.MemoryInfo; +import com.cmhi.magent.pojo.po.NetworkInfo; import com.cmhi.magent.pojo.po.ProcessorInfo; import com.cmhi.magent.service.SystemInfoService; import org.springframework.stereotype.Service; import oshi.SystemInfo; import oshi.hardware.CentralProcessor; -import oshi.hardware.ComputerSystem; -import oshi.hardware.GlobalMemory; -import oshi.software.os.OSFileStore; - -import java.util.ArrayList; /** * 系统信息服务实现类。 @@ -98,26 +94,46 @@ public class SystemInfoServiceImpl implements SystemInfoService { */ @Override public HwInfo getHardwareInfo() { - ComputerSystem cs = si.getHardware().getComputerSystem(); - GlobalMemory gm = si.getHardware().getMemory(); - HwInfo hw = IObjectConvert.INSTANCE.toHwInfo(si); + return IObjectConvert.INSTANCE.toHwInfo(si); + } - // FileStoreInfo fi = new FileStoreInfo(); - // fi.setFileStore(new ArrayList<>()); - // - // for (OSFileStore os : si.getOperatingSystem().getFileSystem().getFileStores()) { - // fi.getFileStore().add(FileStoreDetails.builder() - // .name(os.getName()) - // .volume(os.getVolume()) - // .mountPoint(os.getMount()) - // .uuid(os.getUUID()) - // .fsType(os.getType()) - // .description(os.getDescription()) - // .freeSpace(os.getFreeSpace()) - // .totalSpace(os.getTotalSpace()) - // .usableSpace(os.getUsableSpace()) - // .build()); - // } - return hw; + /** + * 获取网络信息。 + *

+ * 通过 OSHI 库获取网络接口的详细信息,包括网络名称、网络类型、网络状态、网络速度等, + * 并通过 {@link IObjectConvert} 工具类将其转换为自定义的 {@link NetworkInfo} 对象。 + *

+ * + * @return 包含网络详细信息的 {@link NetworkInfo} 对象。 + */ + @Override + public NetworkInfo getNetworkInfo() { + return IObjectConvert.INSTANCE.toNetworkInfo(si, si.getOperatingSystem().getNetworkParams()); + } + + /** + * 获取内存信息 + *

+ * 封装内存的相关信息,如物理内存大小,可用内存,当前内存占用情况等。结果以 {@link MemoryInfo} 对象形式返回。 + *

+ * + * @return 返回一个 MemoryInfo 对象,包含内存的详细信息 + */ + @Override + public MemoryInfo getMemoryInfo() { + return IObjectConvert.INSTANCE.toMemoryInfo(si.getHardware().getMemory()); + } + + /** + * 获取文件存储信息 + *

+ * 封装操作系统文件系统相关信息,如磁盘大小,分区大小等。结果以 {@link FileStoreInfo} 对象形式返回。 + *

+ * + * @return 返回一个 MemoryInfo 对象,包含内存的详细信息 + */ + @Override + public FileStoreInfo getFileStoreInfo() { + return IObjectConvert.INSTANCE.toFileStoreInfo(si.getOperatingSystem().getFileSystem(), si.getHardware().getDiskStores()); } } diff --git a/src/test/java/com/cmhi/magent/controller/SystemInfoApiTest.java b/src/test/java/com/cmhi/magent/controller/SystemInfoApiTest.java index bf2a5df..ad086d2 100644 --- a/src/test/java/com/cmhi/magent/controller/SystemInfoApiTest.java +++ b/src/test/java/com/cmhi/magent/controller/SystemInfoApiTest.java @@ -1,7 +1,10 @@ package com.cmhi.magent.controller; import com.cmhi.magent.common.TestBaseAuthentication; +import com.cmhi.magent.pojo.vo.GetFileStoreInfoResp; import com.cmhi.magent.pojo.vo.GetHwInfoResp; +import com.cmhi.magent.pojo.vo.GetMemoryInfoResp; +import com.cmhi.magent.pojo.vo.GetNetworkInfoResp; import com.cmhi.magent.pojo.vo.GetOsInfoResp; import com.cmhi.magent.pojo.vo.GetProcessorInfoResp; import org.junit.jupiter.api.Assertions; @@ -57,4 +60,46 @@ public class SystemInfoApiTest extends TestBaseAuthentication { // 验证硬件信息数据的合法性 Assertions.assertNotNull(resp.getHwInfo(), "硬件信息不应为空"); } + + @Test + @DisplayName("获取内存信息") + void testGetMemoryInfo() throws Exception { + // 发起 GET 请求,调用 /api/systemInfo/memoryInfo 接口 + GetMemoryInfoResp resp = (GetMemoryInfoResp) performanceRestful(RequestMethod.GET, null, "/api/systemInfo/memoryInfo", + new Class[] {GetMemoryInfoResp.class}); + + // 验证通用响应数据的合法性 + AssertValidCommonResp(resp); + + // 验证硬件信息数据的合法性 + Assertions.assertNotNull(resp.getMemoryInfo(), "内存信息不应为空"); + } + + @Test + @DisplayName("获取网络信息") + void testGetNetworkInfo() throws Exception { + // 发起 GET 请求,调用 /api/systemInfo/networkInfo 接口 + GetNetworkInfoResp resp = (GetNetworkInfoResp) performanceRestful(RequestMethod.GET, null, "/api/systemInfo/networkInfo", + new Class[] {GetNetworkInfoResp.class}); + + // 验证通用响应数据的合法性 + AssertValidCommonResp(resp); + + // 验证硬件信息数据的合法性 + Assertions.assertNotNull(resp.getNetworkInfo(), "网络信息不应为空"); + } + + @Test + @DisplayName("获取文件存储信息") + void testGetFileStoreInfo() throws Exception { + // 发起 GET 请求,调用 /api/systemInfo/fileStoreInfo 接口 + GetFileStoreInfoResp resp = (GetFileStoreInfoResp) performanceRestful(RequestMethod.GET, null, "/api/systemInfo/fileStoreInfo", + new Class[] {GetFileStoreInfoResp.class}); + + // 验证通用响应数据的合法性 + AssertValidCommonResp(resp); + + // 验证硬件信息数据的合法性 + Assertions.assertNotNull(resp.getFileStoreInfo(), "文件存储信息不应为空"); + } } diff --git a/src/test/java/com/cmhi/magent/service/SystemInfoServiceImplTest.java b/src/test/java/com/cmhi/magent/service/SystemInfoServiceImplTest.java new file mode 100644 index 0000000..5a73048 --- /dev/null +++ b/src/test/java/com/cmhi/magent/service/SystemInfoServiceImplTest.java @@ -0,0 +1,114 @@ +package com.cmhi.magent.service; + +import com.cmhi.magent.misc.HelperUtils; +import com.cmhi.magent.pojo.mapper.IObjectConvert; +import com.cmhi.magent.pojo.po.HwInfo; +import com.cmhi.magent.pojo.po.MemoryDetails; +import com.cmhi.magent.pojo.po.ProcessorInfo; +import com.cmhi.magent.service.impl.SystemInfoServiceImpl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Resource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import oshi.SystemInfo; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HWDiskStore; +import oshi.hardware.NetworkIF; +import oshi.hardware.PhysicalMemory; +import oshi.software.os.FileSystem; +import oshi.software.os.NetworkParams; +import oshi.software.os.OSFileStore; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest +class SystemInfoServiceTest { + + private SystemInfoServiceImpl systemInfoService; // 实现类对象 + + @Resource + private ObjectMapper objectMapper; + + @BeforeEach + void setUp() { + // 实例化实现类 + systemInfoService = new SystemInfoServiceImpl(); + } + + @Test + void testGetOsName() { + // 调用接口方法 + String osName = systemInfoService.getOsName(); + + // 检查返回值是否符合预期(这里只能验证非空,因为操作系统名称依赖具体环境) + assertNotNull(osName, "操作系统名称不能为空!"); + System.out.println("操作系统名称: " + osName); + } + + @Test + void testGetOsBootTimeStamp() { + // 调用接口方法 + long bootTimeStamp = systemInfoService.getOsBootTimeStamp(); + + // 验证时间戳(一般会大于当前时间减去一个合理的范围) + assertTrue(bootTimeStamp > 0, "启动时间戳应该是正值!"); + System.out.println("操作系统启动时间戳: " + bootTimeStamp); + } + + @Test + void testGetProcessInfo() { + // 调用接口方法获取处理器信息 + ProcessorInfo processorInfo = systemInfoService.getProcessInfo(); + + // 检查返回的处理器信息是否合理 + assertNotNull(processorInfo, "处理器信息不能为空!"); + assertTrue(processorInfo.getPhysicalCores() > 0, "处理器核心数量应该大于0!"); + assertTrue(processorInfo.getLogicalCpu() >= processorInfo.getPhysicalCores(), "线程数量应该不小于核心数量!"); + assertTrue(processorInfo.getCpuVendorFreq() > 0, "CPU频率应该大于0!"); + System.out.println( + "处理器信息: 核心数量 = " + processorInfo.getPhysicalCores() + ", 线程数量 = " + processorInfo.getLogicalCpu() + ", 主频 = " + processorInfo.getCpuVendorFreq() + " GHz"); + } + + @Test + void testGetHardwareInfo() { + // // 调用接口方法获取硬件信息 + // HwInfo hardwareInfo = systemInfoService.getHardwareInfo(); + // + // // 检查返回的硬件信息是否合理 + // assertNotNull(hardwareInfo, "硬件信息不能为空!"); + // assertTrue(hardwareInfo.get() > 0, "内存大小应该大于0!"); + // assertTrue(hardwareInfo.getDiskCapacity() > 0, "磁盘容量应该大于0!"); + // System.out.println("硬件信息: 内存大小 = " + hardwareInfo.getMemorySize() + + // " GB, 磁盘容量 = " + hardwareInfo.getDiskCapacity() + " GB"); + } + + @Test + void testGetMemoryInfo() throws JsonProcessingException { + SystemInfo si = new SystemInfo(); + GlobalMemory memory = si.getHardware().getMemory(); + List ph = memory.getPhysicalMemory(); + List d = si.getHardware().getDiskStores(); + FileSystem fs = si.getOperatingSystem().getFileSystem(); + List os = fs.getFileStores(true); + List nf = si.getHardware().getNetworkIFs(true); + NetworkParams np = si.getOperatingSystem().getNetworkParams(); + + MemoryDetails md = new MemoryDetails(); + md.setFreeMemory(1000L); + md.setTotalMemory(3000L); + + HwInfo hw = IObjectConvert.INSTANCE.toHwInfo(si); + System.out.println(HelperUtils.getJson(hw)); + // System.out.println(HelperUtils.getJson(d)); + // System.out.println(HelperUtils.getJson(fs)); + + //System.out.println(objectMapper.writeValueAsString(md)); + // System.out.println(HelperUtils.getJson(memory)); + // System.out.println(HelperUtils.getJson(ph)); + } +} \ No newline at end of file