Skip to content

Conversation

@MatheMatrix
Copy link
Owner

APIImpact

Resolves: ZSV-1

Change-Id: I656979726c736267776c7262716969726874716d

sync from gitlab !8937

@coderabbitai
Copy link

coderabbitai bot commented Dec 23, 2025

Walkthrough

为备份存储引入文件上传与下载进度查询消息和处理链。新增四个消息/回复类、在 Ceph 实现中加入上传/下载命令与 HTTP 路径并实现处理;在基类添加抽象处理方法,其他实现返回“未支持”回复。

Changes

Cohort / File(s) 变更摘要
消息类
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java, header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.java, header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java, header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
新增 4 个消息/回复类:请求/回复字段及标准 getter/setter。包含 upload 文件相关字段(backupStorageUuid、taskUuid、url、installPath、md5sum、size 等)与下载进度字段(progress、actualSize、downloadSize、format、lastOpTime、supportSuspend 等),并提供 isDownloadComplete() 便利方法。
Ceph 备份存储实现
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
新增代理命令/响应内部类(DownloadFileCmd/Response、UploadFileCmd/Response、GetDownloadFileProgressCmd/Response)、三个 HTTP 路径常量(FILE_DOWNLOAD_PATH、FILE_UPLOAD_PATH、FILE_UPLOAD_PROGRESS_PATH),注入 ApiTimeoutManager 并实现对 UploadFileToBackupStorageHostMsg 与 GetFileDownloadProgressMsg 的处理逻辑(URL 解析、超时控制、向 Agent 发起请求并映射回复)。
备份存储基类
storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
新增两个抽象保护方法签名:handle(UploadFileToBackupStorageHostMsg) 和 handle(GetFileDownloadProgressMsg),作为子类扩展点。
其他备份存储实现(返回“不支持”)
plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java, simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java, storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
在各实现中新增对应的 handle 方法,直接以“not supported”错误回复 UploadFileToBackupStorageHostMsg 与 GetFileDownloadProgressMsg。
样式/格式微调
header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java
包声明后添加空行,仅格式性改动,无功能性影响。

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant BackupStorageBase
    participant CephBackupStorageBase
    participant Agent
    participant Storage

    rect rgb(220,230,240)
    note over Client,Storage: 文件上传(来自控制面或任务调度)
    Client->>BackupStorageBase: UploadFileToBackupStorageHostMsg
    BackupStorageBase->>CephBackupStorageBase: handle(msg)
    CephBackupStorageBase->>CephBackupStorageBase: 解析 URL、决定 scheme、获取超时
    CephBackupStorageBase->>Agent: UploadFileCmd (HTTP/agent call)
    Agent->>Storage: 写入/接收文件
    Storage-->>Agent: 返回 md5/size
    Agent-->>CephBackupStorageBase: UploadFileResponse
    CephBackupStorageBase->>Client: UploadFileToBackupStorageHostReply
    end

    rect rgb(230,240,220)
    note over Client,Storage: 下载进度查询
    Client->>BackupStorageBase: GetFileDownloadProgressMsg
    BackupStorageBase->>CephBackupStorageBase: handle(msg)
    CephBackupStorageBase->>Agent: GetDownloadFileProgressCmd
    Agent->>Storage: 查询下载/传输状态
    Storage-->>Agent: 返回进度/大小/状态
    Agent-->>CephBackupStorageBase: GetDownloadFileProgressResponse
    CephBackupStorageBase->>Client: GetFileDownloadProgressReply
    end
Loading

代码审查工作量估算

🎯 4 (复杂) | ⏱️ ~45 分钟

兔子之诗

🐰 新消息轻跳跃,
上传进度稳又快,
Ceph 忙碌传文件,
基类留出新窗台,
小兔鼓掌赏芳菲 ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning 标题不完整且描述不清晰,使用了占位符'<description',无法明确说明主要变更内容。 请完成标题描述,明确说明此次变更的主要目的,例如'[volume]: 添加文件上传下载进度查询消息类'。
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed 描述与变更集相关,提及了问题追踪和来源信息,但缺少对实际变更内容的详细说明。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sync/tao.gan/anyun-ZSV-1@@4

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe16e65 and ba36a3e.

⛔ Files ignored due to path filters (1)
  • pom.xml is excluded by !**/*.xml
📒 Files selected for processing (10)
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
  • header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
🚧 Files skipped from review as they are similar to previous changes (3)
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.java
  • header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: ## 1. API 设计要求

  • API 命名:
    • API 名称必须唯一,不能重复。
    • API 消息类需要继承 APIMessage;其返回类必须继承 APIReplyAPIEvent,并在注释中用 @RestResponse 进行标注。
    • API 消息上必须添加注解 @RestRequest,并满足如下规范:
      • path:
        • 针对资源使用复数形式。
        • 当 path 中引用消息类变量时,使用 {variableName} 格式。
      • HTTP 方法对应:
        • 查询操作 → HttpMethod.GET
        • 更新操作 → HttpMethod.PUT
        • 创建操作 → HttpMethod.POST
        • 删除操作 → HttpMethod.DELETE
    • API 类需要实现 __example__ 方法以便生成 API 文档,并确保生成对应的 Groovy API Template 与 API Markdown 文件。

2. 命名与格式规范

  • 类名:

    • 使用 UpperCamelCase 风格。
    • 特殊情况:
      • VO/AO/EO 类型类除外。
      • 抽象类采用 AbstractBase 前缀/后缀。
      • 异常类应以 Exception 结尾。
      • 测试类需要以 TestCase 结尾。
  • 方法名、参数名、成员变量和局部变量:

    • 使用 lowerCamelCase 风格。
  • 常量命名:

    • 全部大写,使用下划线分隔单词。
    • 要求表达清楚,避免使用含糊或不准确的名称。
  • 包名:

    • 统一使用小写,使用点分隔符,每个部分应是一个具有自然语义的英文单词(参考 Spring 框架的结构)。
  • 命名细节:

    • 避免在父子类或同一代码块中出现相同名字的成员或局部变量,防止混淆。
    • 命名缩写:
      • 不允许使用不必要的缩写,如:AbsSchedulerJobcondiFu 等。应使用完整单词提升可读性。

3. 编写自解释代码

  • 意图表达:

    • 避免使用布尔型参数造成含义不明确。例如:
      • 对于 stopAgent(boolean ignoreError),建议拆分为不同函数(如 stopAgentIgnoreError()),或使用枚举表达操作类型。
    • 命名应尽量用完整的单词组合表达意图,并在名称中体现数据类型或用途(例如在常量与变量名称中,将类型词放在末尾)。
  • 注释:

    • 代码应尽量做到自解释,对少于两行的说明可以直接写在代码中。
    • 对于较长的注释,需要仔细校对并随代码更新,确保内容正确。
    • 接口方法不应有多余的修饰符(例如 public),且必须配有有效的 Javadoc 注释。

4. 流程控制和结构优化

  • if...else 的使用:

    • 应尽量减少 if...else 结构的使用,建议:
      • 限制嵌套层级最多为两层,且内层不应再出现 else 分支。
      • 尽早返回(Early Return),将条件判断中的处理逻辑提前结束或抽成独立方法。
      • 使用 Java Stream 或 Lambda 表达式代替冗长的循环与条件判断。
  • 条件判断:

    • if 条件表达不宜过长或过于复杂,必要时可以将条件抽成 boolean 变量描述。
  • 代码块长度:

    • 单个 if 代码块不宜超过一屏显示,以提高可读性和后续维护性。

5. 异常处理与日志

  • 捕获异常的原则:
    • 对于可以通过预检查避免的 RuntimeException(如 NullPointerExceptionIndexOutOfBoundsException 等),不建议使用 try-catch 来进行处理。
    • 捕获异常应仅用于处理真正的意外情况,不应将异常逻辑当作正常流程控制。
    • 在必要时,应继续抛出异常,使上层业务处理者可以转换为用户友好的错误提示。
    • 使用 try-with-resources 语法管理资源,确保在 finally 块中正确关闭资源,并避免在 finally 中返回值。
      ...

Files:

  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
🧬 Code graph analysis (3)
simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (1)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java (1)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java (2)
header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO.java (1)
  • org (11-45)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
🔇 Additional comments (12)
storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java (1)

39-39: 导入语句正确。

新增的 UploadFileToBackupStorageHostMsg 导入语句符合规范。

simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (2)

9-9: 导入语句正确。

新增的 UploadFileToBackupStorageHostMsg 导入符合规范。


142-150: "不支持"的处理方式正确。

对于模拟器实现,两个新增的处理方法正确地返回"不支持"错误。这种处理方式与其他备份存储实现(ExternalBackupStorage、SftpBackupStorage)保持一致,符合测试桩的设计模式。

storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java (2)

10-10: 导入语句正确。

新增的 UploadFileToBackupStorageHostMsg 导入符合规范。


167-175: "不支持"的处理方式正确。

ExternalBackupStorage 作为扩展备份存储,正确地对不支持的操作返回错误。这与该类中其他不支持的操作(如 Lines 92, 129, 134 等)的处理方式保持一致。

header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)

1-46: 消息类实现正确。

UploadFileToBackupStorageHostMsg 类的实现符合规范:

  • 正确继承 NeedReplyMessage 并实现 BackupStorageMessage 接口
  • 字段命名使用 lowerCamelCase 风格
  • URL 字段正确使用 @NoLogging 注解保护敏感信息
  • 所有字段都提供了标准的 getter/setter 方法

作为内部消息类(非 API 消息),无需 @RestRequest 注解和 __example__ 方法。

plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java (1)

709-717: "不支持"的处理方式正确。

SftpBackupStorage 正确地对不支持的文件上传和下载进度查询操作返回错误。这与该备份存储类型的功能定位一致,并且与其他备份存储实现(SimulatorBackupStorage、ExternalBackupStorage)保持了统一的处理模式。

plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (5)

22-22: 新增导入语句正确。

新增的导入语句符合规范:

  • ApiTimeoutManager:用于超时管理
  • GetFileDownloadProgressReplyUploadFileToHostReply:新增的回复类型
  • KVMAgentCommandsKVMHost:KVM 相关依赖
  • URI:用于 URL 解析

所有导入都有实际使用,符合代码规范。

Also applies to: 34-35, 43-44, 59-59


100-101: ApiTimeoutManager 注入正确。

使用 @Autowired 注解注入 ApiTimeoutManager,符合 Spring 依赖注入模式,与该类中其他字段的注入方式保持一致。


379-423: 内部命令/响应类定义正确。

新增的四个内部类(DownloadFileCmdDownloadFileResponseUploadFileCmdUploadFileResponseGetDownloadFileProgressCmdGetDownloadFileProgressResponse)遵循了该文件中现有命令/响应类的设计模式:

  • 使用 public static 修饰符
  • 实现 HasThreadContextSerializable 接口(适用于命令类)
  • 字段使用 @NoLogging 注解保护敏感信息(URL 字段)
  • 提供 public 字段访问方式,与文件中其他命令类保持一致

命名清晰,结构合理。


737-739: 路径常量定义正确。

新增的三个路径常量(FILE_DOWNLOAD_PATHFILE_UPLOAD_PATHFILE_UPLOAD_PROGRESS_PATH)遵循了现有常量的命名规范:

  • 使用 public static final 修饰符
  • 全大写字母加下划线命名风格
  • 路径值符合 RESTful 风格

与文件中其他路径常量(如 DOWNLOAD_IMAGE_PATHPING_PATH 等)保持一致。


2083-2146: 文件上传处理逻辑实现正确。

handle(UploadFileToBackupStorageHostMsg msg) 方法实现完善:

  • 正确区分 upload:// 协议和其他协议的处理逻辑
  • 使用 try-catch 捕获 URISyntaxException,并返回清晰的错误信息
  • 正确调用 timeoutManager.getTimeout() 设置超时时间
  • 使用 httpCall 方法与 Ceph 代理通信,遵循该类的现有模式
  • 错误处理和回复逻辑完整

实现符合该类的编码风格和最佳实践。


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java (1)

692-696: 潜在缺陷:reply 未发送

handle(CalculateImageHashOnBackupStorageMsg) 方法创建了 reply 并设置了错误,但未通过 bus.reply(msg, reply) 发送。这会导致调用方永远收不到响应,可能造成超时。

🔎 建议修复
 @Override
 protected void handle(CalculateImageHashOnBackupStorageMsg msg) {
     CalculateImageHashOnBackupStorageReply reply = new CalculateImageHashOnBackupStorageReply();
     reply.setError(operr("sftp backup storage do not support calculate image hash"));
+    bus.reply(msg, reply);
 }
🧹 Nitpick comments (3)
header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java (1)

3-3: 多余的空行

此处新增的空行看起来是无意义的格式变更。如果这不是代码格式化工具的要求,建议移除以保持代码整洁。

simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (1)

141-150: 实现可行,但与部分现有处理器风格不一致

新增的处理方法使用 bus.replyErrorByMessageType() 返回错误,这是更安全的方式。但请注意,该类中部分现有处理器(如 handle(SyncImageSizeOnBackupStorageMsg) 在 Lines 100-102)使用的是 throw new CloudRuntimeException("not supported yet")

建议保持一致性,或者在后续统一将抛异常的方式改为消息回复方式。

plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (1)

379-423: 新增命令类使用 public 字段,与现有类风格不一致。

当前文件中其他命令类(如 GetDownloadProgressCmdDownloadCmd 等)使用 private 字段配合 getter/setter 方法,而新增的 DownloadFileCmdUploadFileCmdGetDownloadFileProgressCmd 及其响应类直接使用 public 字段。建议保持代码风格一致性。

🔎 建议修改示例(以 DownloadFileCmd 为例)
 public static class DownloadFileCmd extends AgentCommand implements HasThreadContext, Serializable {
-    public String taskUuid;
-    public String installPath;
+    private String taskUuid;
+    private String installPath;
     @NoLogging(type = NoLogging.Type.Uri)
-    public String url;
+    private String url;
     @NoLogging(type = NoLogging.Type.Uri)
-    public String urlScheme;
-    public long timeout;
+    private String urlScheme;
+    private long timeout;
     @NoLogging(type = NoLogging.Type.Uri)
-    public String sendCommandUrl;
+    private String sendCommandUrl;
+
+    // Add getters and setters...
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2648273 and fe16e65.

⛔ Files ignored due to path filters (1)
  • pom.xml is excluded by !**/*.xml
📒 Files selected for processing (10)
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
  • header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: ## 1. API 设计要求

  • API 命名:
    • API 名称必须唯一,不能重复。
    • API 消息类需要继承 APIMessage;其返回类必须继承 APIReplyAPIEvent,并在注释中用 @RestResponse 进行标注。
    • API 消息上必须添加注解 @RestRequest,并满足如下规范:
      • path:
        • 针对资源使用复数形式。
        • 当 path 中引用消息类变量时,使用 {variableName} 格式。
      • HTTP 方法对应:
        • 查询操作 → HttpMethod.GET
        • 更新操作 → HttpMethod.PUT
        • 创建操作 → HttpMethod.POST
        • 删除操作 → HttpMethod.DELETE
    • API 类需要实现 __example__ 方法以便生成 API 文档,并确保生成对应的 Groovy API Template 与 API Markdown 文件。

2. 命名与格式规范

  • 类名:

    • 使用 UpperCamelCase 风格。
    • 特殊情况:
      • VO/AO/EO 类型类除外。
      • 抽象类采用 AbstractBase 前缀/后缀。
      • 异常类应以 Exception 结尾。
      • 测试类需要以 TestCase 结尾。
  • 方法名、参数名、成员变量和局部变量:

    • 使用 lowerCamelCase 风格。
  • 常量命名:

    • 全部大写,使用下划线分隔单词。
    • 要求表达清楚,避免使用含糊或不准确的名称。
  • 包名:

    • 统一使用小写,使用点分隔符,每个部分应是一个具有自然语义的英文单词(参考 Spring 框架的结构)。
  • 命名细节:

    • 避免在父子类或同一代码块中出现相同名字的成员或局部变量,防止混淆。
    • 命名缩写:
      • 不允许使用不必要的缩写,如:AbsSchedulerJobcondiFu 等。应使用完整单词提升可读性。

3. 编写自解释代码

  • 意图表达:

    • 避免使用布尔型参数造成含义不明确。例如:
      • 对于 stopAgent(boolean ignoreError),建议拆分为不同函数(如 stopAgentIgnoreError()),或使用枚举表达操作类型。
    • 命名应尽量用完整的单词组合表达意图,并在名称中体现数据类型或用途(例如在常量与变量名称中,将类型词放在末尾)。
  • 注释:

    • 代码应尽量做到自解释,对少于两行的说明可以直接写在代码中。
    • 对于较长的注释,需要仔细校对并随代码更新,确保内容正确。
    • 接口方法不应有多余的修饰符(例如 public),且必须配有有效的 Javadoc 注释。

4. 流程控制和结构优化

  • if...else 的使用:

    • 应尽量减少 if...else 结构的使用,建议:
      • 限制嵌套层级最多为两层,且内层不应再出现 else 分支。
      • 尽早返回(Early Return),将条件判断中的处理逻辑提前结束或抽成独立方法。
      • 使用 Java Stream 或 Lambda 表达式代替冗长的循环与条件判断。
  • 条件判断:

    • if 条件表达不宜过长或过于复杂,必要时可以将条件抽成 boolean 变量描述。
  • 代码块长度:

    • 单个 if 代码块不宜超过一屏显示,以提高可读性和后续维护性。

5. 异常处理与日志

  • 捕获异常的原则:
    • 对于可以通过预检查避免的 RuntimeException(如 NullPointerExceptionIndexOutOfBoundsException 等),不建议使用 try-catch 来进行处理。
    • 捕获异常应仅用于处理真正的意外情况,不应将异常逻辑当作正常流程控制。
    • 在必要时,应继续抛出异常,使上层业务处理者可以转换为用户友好的错误提示。
    • 使用 try-with-resources 语法管理资源,确保在 finally 块中正确关闭资源,并避免在 finally 中返回值。
      ...

Files:

  • header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.java
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
🧬 Code graph analysis (3)
storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java (1)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (1)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java (1)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
🔇 Additional comments (9)
storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java (1)

166-175: 实现符合既有模式

新增的两个处理方法与该类中其他 handle 方法的实现模式一致,均返回 "not supported" 错误。这符合 ExternalBackupStorage 作为外部备份存储桥接层的定位。

plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java (1)

708-717: 新增处理方法实现正确

新增的两个处理方法正确实现了抽象基类要求,返回 "not supported" 错误。

header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.java (1)

1-35: 新增回复类结构良好

UploadFileToBackupStorageHostReply 类设计合理:

  • 正确继承 MessageReply
  • @NoLogging(type = NoLogging.Type.Uri) 注解正确应用于 directUploadUrl,防止敏感 URL 被记录到日志
  • 字段命名清晰,getter/setter 符合规范
header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java (1)

1-34: 消息类结构正确

GetFileDownloadProgressMsg 类设计符合框架规范:

  • 正确继承 NeedReplyMessage 并实现 BackupStorageMessage 接口
  • getBackupStorageUuid() 方法正确覆盖接口要求
  • 字段设计合理,用于查询下载进度
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)

1-46: 消息类设计良好

UploadFileToBackupStorageHostMsg 类设计符合框架规范:

  • 正确继承 NeedReplyMessage 并实现 BackupStorageMessage 接口
  • @NoLogging(type = NoLogging.Type.Uri) 注解正确应用于 url 字段,防止敏感信息泄露
  • 字段设计完整,包含上传所需的任务标识、URL 和安装路径
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (2)

100-101: LGTM!

新增的 ApiTimeoutManager 注入和端点常量遵循现有代码规范。

Also applies to: 737-739


2083-2146: LGTM!

该方法正确处理了 upload:// 协议和其他 URL 的不同逻辑,URI 解析错误处理完善,使用了 Early Return 模式提高可读性。

header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java (2)

49-51: isDownloadComplete() 方法逻辑可能存在语义问题。

当前实现 actualSize > 0 && actualSize == downloadSize,但字段命名可能引起混淆:

  • actualSize 通常表示文件的实际大小
  • downloadSize 通常表示已下载的大小

如果语义如此,判断下载完成的条件应该是 downloadSize == sizedownloadSize >= actualSize。请确认字段语义是否正确,或考虑添加注释说明字段含义。


17-91: LGTM!

Getter/setter 方法遵循 Java Bean 规范,实现正确。

Comment on lines +5 to +15
public class GetFileDownloadProgressReply extends MessageReply {
private boolean completed;
private int progress;

private long size;
private long actualSize;
private long downloadSize;
private String installPath;
private String format;
private long lastOpTime;
private boolean supportSuspend;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

缺少 md5sum 字段。

CephBackupStorageBase.java 第 2171 行调用了 reply.setMd5sum(rsp.md5sum),但此类未定义 md5sum 字段,会导致编译错误。

🔎 建议添加 md5sum 字段
 public class GetFileDownloadProgressReply extends MessageReply {
     private boolean completed;
     private int progress;
 
     private long size;
     private long actualSize;
     private long downloadSize;
     private String installPath;
     private String format;
     private long lastOpTime;
     private boolean supportSuspend;
+    private String md5sum;
+
+    public String getMd5sum() {
+        return md5sum;
+    }
+
+    public void setMd5sum(String md5sum) {
+        this.md5sum = md5sum;
+    }
🤖 Prompt for AI Agents
In
header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
around lines 5 to 15, the class is missing the md5sum field referenced by
CephBackupStorageBase at line 2171; add a private String md5sum field and
provide its public getter and setter (getMd5sum and setMd5sum) so the
reply.setMd5sum(...) call compiles correctly and follows existing Java bean
style used in this class.

Comment on lines +2148 to +2176
@Override
protected void handle(GetFileDownloadProgressMsg msg) {
GetFileDownloadProgressReply reply = new GetFileDownloadProgressReply();

GetDownloadFileProgressCmd cmd = new GetDownloadFileProgressCmd();
cmd.taskUuid = msg.getTaskUuid();

httpCall(FILE_UPLOAD_PROGRESS_PATH, cmd, GetDownloadFileProgressResponse.class, new ReturnValueCompletion<GetDownloadFileProgressResponse>(msg) {
@Override
public void fail(ErrorCode err) {
reply.setError(err);
bus.reply(msg, reply);
}

@Override
public void success(GetDownloadFileProgressResponse rsp) {
reply.setCompleted(rsp.completed);
reply.setProgress(rsp.progress);
reply.setActualSize(rsp.actualSize);
reply.setSize(rsp.size);
reply.setInstallPath(rsp.installPath);
reply.setDownloadSize(rsp.downloadSize);
reply.setLastOpTime(rsp.lastOpTime);
reply.setMd5sum(rsp.md5sum);
reply.setSupportSuspend(rsp.supportSuspend);
bus.reply(msg, reply);
}
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

编译错误:GetFileDownloadProgressReply 缺少 md5sum 字段。

第 2171 行调用 reply.setMd5sum(rsp.md5sum),但 GetFileDownloadProgressReply 类中未定义 md5sum 字段和对应的 setter 方法,这将导致编译失败。

需要在 GetFileDownloadProgressReply 类中添加 md5sum 字段。

🤖 Prompt for AI Agents
In
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
around lines 2148 to 2176, the code calls reply.setMd5sum(rsp.md5sum) but
GetFileDownloadProgressReply lacks an md5sum field and setter; modify the
GetFileDownloadProgressReply class to add a private String md5sum field plus
public void setMd5sum(String md5sum) and public String getMd5sum() (or matching
types used by rsp.md5sum), then recompile to ensure the reference is resolved.

Comment on lines +125 to +127
abstract protected void handle(UploadFileToBackupStorageHostMsg msg);

abstract protected void handle(GetFileDownloadProgressMsg msg);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

缺少消息路由处理

新增了抽象方法 handle(UploadFileToBackupStorageHostMsg msg)handle(GetFileDownloadProgressMsg msg),但在 handleLocalMessage 方法(Lines 247-289)中未添加对应的消息路由分支。

这将导致这两种消息无法被正确分发到 handle 方法,而是进入 bus.dealWithUnknownMessage(msg) 分支。

🔎 建议在 handleLocalMessage 中添加路由
         } else if (msg instanceof GetBackupStorageManagerHostnameMsg) {
             handle((GetBackupStorageManagerHostnameMsg) msg);
+        } else if (msg instanceof UploadFileToBackupStorageHostMsg) {
+            handle((UploadFileToBackupStorageHostMsg) msg);
+        } else if (msg instanceof GetFileDownloadProgressMsg) {
+            handle((GetFileDownloadProgressMsg) msg);
         } else {
             bus.dealWithUnknownMessage(msg);
         }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java around
lines 125-127 (new abstract methods) and handleLocalMessage around lines
247-289, the two new abstract handlers UploadFileToBackupStorageHostMsg and
GetFileDownloadProgressMsg are not routed and will hit
bus.dealWithUnknownMessage(msg). Add branches in handleLocalMessage that check
for those message types (instanceof UploadFileToBackupStorageHostMsg and
instanceof GetFileDownloadProgressMsg), invoke the corresponding abstract
handle(...) methods, and return after handling so they do not fall through to
the unknown-message branch; also ensure the message classes are imported and any
reply or exception handling follows the existing pattern used for other message
branches.

APIImpact

Resolves: ZSV-1

Change-Id: I656979726c736267776c7262716969726874716d
@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/anyun-ZSV-1@@4 branch from fe16e65 to ba36a3e Compare December 29, 2025 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants