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

引入用于备份存储的文件操作消息与回复(上传、删除、下载进度查询)、在 CephBackupStorageBase 中新增相应命令/响应及处理流程,并添加一个查询后处理扩展点接口与若干导入调整。

变更

内聚 / 文件(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/image/DeleteFilesOnBackupStorageHostMsg.java, header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostReply.java
新增上传/删除相关消息和回复类(字段含 backupStorageUuid、taskUuid、url、installPath、md5sum、size、directUploadUrl、unzipInstallPath、filesSize 等),均为 DTO 访问器方法。
消息类 — 备份存储下载进度
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/host/GetFileDownloadProgressReply.java
新增下载进度请求/回复类及主机侧回复字段扩展(completed、progress、size、actualSize、downloadSize、installPath、format、lastOpTime、supportSuspend、unzipInstallPath、unzipFiles 等),并含少量辅助判断方法(如下载完成判断)。
Ceph 实现(核心变更)
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
在 CephBackupStorageBase 中新增 ApiTimeoutManager 注入、文件操作相关常量及 8 个内部命令/响应类(DownloadFileCmd/Response、DeleteFilesCmd/Response、UploadFileCmd/Response、GetDownloadFileProgressCmd/Response),并实现对应消息的处理与 URL/方案解析、MD5/size/路径传播、超时传递等逻辑。
导入与小改动
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
添加或更新对新消息类的导入;BackupStorageBase 用包通配符替换若干镜像类具体导入。
查询扩展点
search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
新增公共接口 AfterQueryExtensionPoint,声明 void fileter(List<ZQLQueryReturn> rs, String zqlText) 方法,作为查询后处理钩子。

序列图

sequenceDiagram
    participant Client
    participant BackupStorage
    participant CephBackupStorage
    participant RemoteHost

    rect rgb(200,220,255)
    note over Client,RemoteHost: 文件上传流程
    Client->>BackupStorage: UploadFileToBackupStorageHostMsg
    BackupStorage->>CephBackupStorage: handleUploadFile()
    CephBackupStorage->>CephBackupStorage: 解析 URL / 超时 / 参数
    CephBackupStorage->>RemoteHost: UploadFileCmd (HTTP POST)
    RemoteHost->>CephBackupStorage: UploadFileResponse (md5, size, installPath)
    CephBackupStorage->>BackupStorage: UploadFileToBackupStorageHostReply
    end

    rect rgb(220,200,255)
    note over Client,RemoteHost: 文件删除流程
    Client->>BackupStorage: DeleteFilesOnBackupStorageHostMsg
    BackupStorage->>CephBackupStorage: handleDeleteFiles()
    CephBackupStorage->>RemoteHost: DeleteFilesCmd (HTTP POST)
    RemoteHost->>CephBackupStorage: DeleteFilesResponse (filesSize, md5, size)
    CephBackupStorage->>BackupStorage: DeleteFilesOnBackupStorageHostReply
    end

    rect rgb(200,255,220)
    note over Client,RemoteHost: 下载进度查询流程
    Client->>BackupStorage: GetFileDownloadProgressMsg
    BackupStorage->>CephBackupStorage: handleGetDownloadProgress()
    CephBackupStorage->>RemoteHost: GetDownloadFileProgressCmd (HTTP GET)
    RemoteHost->>CephBackupStorage: GetDownloadFileProgressResponse (progress, sizes)
    CephBackupStorage->>BackupStorage: GetFileDownloadProgressReply
    end
Loading

代码审查工作量评估

🎯 3 (中等) | ⏱️ ~20 分钟

诗歌

🐰 我在代码地里跳跃忙,
新增上传删除查进度三行唱,
Ceph 小路铺命令与响应,
URL、MD5、大小都带上,
备份世界更清爽又稳当。

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed 拉取请求描述与变更集相关,包含了问题跟踪信息(ZSV-1)和来源信息(gitlab !8937)。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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 2180
@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.

@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/anyun-ZSV-1@@4 branch 2 times, most recently from ba36a3e to a36dcfb Compare December 31, 2025 06:26
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: 0

♻️ Duplicate comments (2)
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (1)

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

Line 2171 调用 reply.setMd5sum(rsp.md5sum),但 GetFileDownloadProgressReply 类(位于 header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java)中未定义 md5sum 字段和对应的 setter 方法,这将导致编译失败。

需要在 GetFileDownloadProgressReply 类中添加 md5sum 字段及其 getter/setter 方法。

🔎 修复建议

header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java 文件中添加以下代码:

private String md5sum;

public String getMd5sum() {
    return md5sum;
}

public void setMd5sum(String md5sum) {
    this.md5sum = md5sum;
}

基于往期评审意见。

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

5-15: 编译错误:缺少 md5sum 字段。

CephBackupStorageBase.java Line 2171 调用了 reply.setMd5sum(rsp.md5sum),但此类未定义 md5sum 字段及其 getter/setter 方法,会导致编译错误。该字段对于文件下载进度查询是必需的,用于返回文件的 MD5 校验和。

🔎 建议添加 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;
+    }

基于往期评审意见。

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

709-717: 建议使用更具描述性的错误消息

这两个方法都返回通用的 "not supported" 错误消息。根据编码规范中关于编写自解释代码的要求,建议提供更详细的错误信息,帮助调用方理解具体是什么操作不被支持以及原因。

🔎 建议的改进
 @Override
 protected void handle(UploadFileToBackupStorageHostMsg msg) {
-    bus.replyErrorByMessageType(msg, "not supported");
+    bus.replyErrorByMessageType(msg, "SFTP backup storage does not support direct file upload to host");
 }

 @Override
 protected void handle(GetFileDownloadProgressMsg msg) {
-    bus.replyErrorByMessageType(msg, "not supported");
+    bus.replyErrorByMessageType(msg, "SFTP backup storage does not support querying file download progress");
 }
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (2)

43-44: 建议移除未使用的导入。

Lines 43-44 导入了 KVMAgentCommandsKVMHost,但在本文件的可见代码中未找到使用这些类的地方。建议移除未使用的导入以保持代码整洁。


379-423: 建议考虑使用私有字段和访问器方法。

新增的命令和响应类(DownloadFileCmdDownloadFileResponse 等)使用了 public 字段而不是私有字段配合 getter/setter 方法。虽然这种模式与本文件中现有的命令类(如 Lines 300-338 的 DownloadCmd)保持一致,但不符合标准的 Java Bean 规范和编码指南中关于封装的最佳实践。

如果这是该代码库中序列化命令对象的既定模式,可以保持现状;否则建议后续重构时统一改为使用私有字段和访问器方法,以提高封装性和可维护性。

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

49-51: 考虑澄清 isDownloadComplete()completed 字段的关系。

该类同时提供了 completed 字段(Line 6)和 isDownloadComplete() 方法。isDownloadComplete() 的逻辑是 actualSize > 0 && actualSize == downloadSize,这与 completed 字段可能存在语义上的重叠。

建议:

  • 如果 completed 表示下载任务结束(成功或失败),而 isDownloadComplete() 表示下载成功且大小匹配,请在方法上添加 Javadoc 注释说明区别
  • 如果两者表示相同含义,考虑移除重复的逻辑以避免混淆
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

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

📒 Files selected for processing (9)
  • 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
  • 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 (4)
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
  • 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
🧰 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:

  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.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
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
🧬 Code graph analysis (2)
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/addon/backup/ExternalBackupStorage.java (1)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)
  • UploadFileToBackupStorageHostMsg (7-46)
🔇 Additional comments (3)
simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (1)

9-9: LGTM!

模拟器后端正确地为新消息类型添加了处理器,返回"不支持"错误。这与模拟器中其他处理器的模式一致(例如 Lines 100-107 的 SyncImageSizeOnBackupStorageMsgGetLocalFileSizeOnBackupStorageMsg)。导入和方法命名符合编码规范。

Also applies to: 142-150

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

10-10: LGTM!

外部备份存储正确地为新消息类型添加了处理器,使用 bus.replyErrorByMessageType 返回"不支持"错误。这与该类中其他未支持操作的处理模式一致(例如 Lines 92, 129, 134 等)。实现符合编码规范。

Also applies to: 167-175

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

2083-2146: LGTM!

handle(UploadFileToBackupStorageHostMsg) 方法的实现逻辑清晰:

  • 正确区分 upload:// 和普通下载 URL 的处理路径
  • 适当地集成了超时管理(Lines 2091, 2112)
  • URI 解析异常处理完善(Lines 2117-2124)
  • URL scheme 验证合理(Lines 2125-2129)
  • 错误处理规范,所有错误情况都正确设置到 reply 并回复

实现符合编码规范要求。

@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/anyun-ZSV-1@@4 branch from a36dcfb to ee5168b Compare January 13, 2026 01:41
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: 1

🤖 Fix all issues with AI agents
In @search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java:
- Around line 7-9: The public interface AfterQueryExtensionPoint has a
misspelled method name fileter; rename this method to filter with the same
signature (void filter(List<ZQLQueryReturn> rs, String zqlText)) and update all
implementing classes and callers to use AfterQueryExtensionPoint.filter; ensure
compilation by updating any overrides of fileter to the new name and run tests
to catch missed references before merging since this is a breaking API change.
🧹 Nitpick comments (3)
simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (1)

142-150: 实现符合预期。

模拟器正确返回"不支持"错误响应。使用 bus.replyErrorByMessageType 比抛出异常更符合消息-响应模式。

不过需注意,该文件中存在不一致的模式:部分处理器抛出 CloudRuntimeException("not supported yet")(如 Lines 101、106),而新处理器使用 replyErrorByMessageType。建议后续统一处理方式。

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

379-425: 新增的命令/响应类使用 public 字段,与现有类的风格不一致。

现有的命令类(如 DownloadCmd,Lines 300-338)使用 private 字段配合 getter/setter。新增的 DownloadFileCmdUploadFileCmd 等类直接使用 public 字段,违反了封装原则并且与现有代码风格不一致。

建议改为 private 字段并添加访问器方法,以保持代码风格统一。

♻️ 示例:将 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...
+    public String getTaskUuid() { return taskUuid; }
+    public void setTaskUuid(String taskUuid) { this.taskUuid = taskUuid; }
+    // ... similar for other fields
 }

2085-2150: 上传文件处理逻辑正确。

实现正确区分了 upload:// 协议和标准 URL 下载的处理流程。URI 解析具有适当的错误处理,scheme 验证也已到位。

一个小建议:考虑将 "upload://" 提取为常量,因为在代码库中可能多处使用。

♻️ 可选:提取协议前缀常量
+    private static final String UPLOAD_URL_PREFIX = "upload://";
+
     @Override
     protected void handle(final UploadFileToBackupStorageHostMsg msg) {
         UploadFileToBackupStorageHostReply reply = new UploadFileToBackupStorageHostReply();

-        if (msg.getUrl().startsWith("upload://")) {
+        if (msg.getUrl().startsWith(UPLOAD_URL_PREFIX)) {
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a36dcfb and ee5168b.

📒 Files selected for processing (11)
  • header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java
  • 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
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.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 (6)
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.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/host/GetFileDownloadProgressReply.java
  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
🧠 Learnings (2)
📚 Learning: 2025-06-19T09:08:57.046Z
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2217
File: header/src/main/java/org/zstack/header/network/l2/L2NetworkCandidateFilterExtensionPoint.java:7-10
Timestamp: 2025-06-19T09:08:57.046Z
Learning: In the zstack project, for simple and self-explanatory interfaces like L2NetworkCandidateFilterExtensionPoint, the team prefers to rely on clear method names and parameters rather than adding detailed Javadoc comments, even when coding guidelines suggest otherwise.

Applied to files:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
📚 Learning: 2025-08-12T03:35:21.034Z
Learnt from: zstack-robot-1
Repo: MatheMatrix/zstack PR: 2419
File: network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java:287-297
Timestamp: 2025-08-12T03:35:21.034Z
Learning: In the ZStack codebase, extension points may be designed for different execution phases/orders in the same operation. For example, IpRangeDeletionExtensionPoint executes during IP range deletion process, while AfterDeleteIpRangeExtensionPoint executes after the entire deletion process is complete. This allows different plugins to hook into appropriate lifecycle stages.

Applied to files:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
🧬 Code graph analysis (1)
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)
🔇 Additional comments (4)
header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java (1)

18-19: LGTM!

新增的 unzipInstallPathunzipFiles 字段及其访问器遵循了类中现有的命名和代码风格规范。

Also applies to: 92-107

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

7-46: LGTM!

消息类结构正确,遵循了现有模式。@NoLogging(type = NoLogging.Type.Uri) 注解正确保护了敏感的 URL 数据不被记录到日志中。

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

2152-2180: LGTM!

进度查询处理器正确映射了所有响应字段到回复对象中,包括 completedprogresssizeactualSizeinstallPathdownloadSizelastOpTimemd5sumsupportSuspend


34-35: 删除未使用的导入。

UploadFileToHostReplyKVMAgentCommandsKVMHost 在文件中未被使用,应予以移除。

⛔ Skipped due to learnings
Learnt from: zstack-robot-2
Repo: MatheMatrix/zstack PR: 2435
File: storage/src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupBase.java:47-47
Timestamp: 2025-08-14T06:56:19.585Z
Learning: 在VolumeSnapshotGroupBase.java中,VmInstanceResourceMetadataManager的注入和SKIP_RESOURCE_ROLLBACK标记虽然在当前版本中未被使用,但这些导入在大型重构PR中是有意为之的,用于保持代码一致性或为后续功能做准备。
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2763
File: sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java:31-31
Timestamp: 2025-10-20T11:27:25.928Z
Learning: UpdateHostKernelInterface API (`sdk/src/main/java/org/zstack/sdk/UpdateHostKernelInterfaceAction.java`) 在 PR #2763 时尚未被实际使用,因此对其参数约束的变更(如 name 字段从必需改为可选)不会造成破坏性影响。

@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/anyun-ZSV-1@@4 branch from ee5168b to 3cb08aa Compare January 13, 2026 06:17
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: 2

🤖 Fix all issues with AI agents
In
@plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:
- Around line 2169-2189: The DeleteFilesOnBackupStorageHost handler is using the
wrong reply and response types; replace the incorrectly instantiated
UploadFileToBackupStorageHostReply with DeleteFilesOnBackupStorageHostReply in
handle(DeleteFilesOnBackupStorageHostMsg msg) and change the httpCall
generic/response class from DownloadFileResponse.class to
DeleteFilesResponse.class (keeping the DeleteFilesCmd and same success/fail
logic), ensuring you set the appropriate fields from DeleteFilesResponse onto
DeleteFilesOnBackupStorageHostReply before bus.reply(msg, reply).

In @search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java:
- Around line 7-9: Rename the misspelled method fileter to filter on the
AfterQueryExtensionPoint interface and update all implementing classes and call
sites to use AfterQueryExtensionPoint.filter(List<ZQLQueryReturn>, String);
ensure method signature remains identical (parameter types and order) and update
javadoc/comments; if you need to avoid a breaking change immediately, add a
default fileter(...) implementation on the interface that delegates to
filter(...) and mark it @Deprecated, then remove the deprecated alias after
downstream updates.
🧹 Nitpick comments (3)
storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java (1)

10-10: 新增的 import 在当前文件中未被使用。

UploadFileToBackupStorageHostMsg 已导入但在 ExternalBackupStorage 类中没有被引用。如果这是为后续实现预留的,建议在实际使用时再添加导入;否则应移除以保持代码整洁。

🔧 可选:移除未使用的导入
-import org.zstack.header.image.UploadFileToBackupStorageHostMsg;
simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java (1)

9-9: 新增的 import 在当前文件中未被使用。

ExternalBackupStorage.java 相同,UploadFileToBackupStorageHostMsg 已导入但在 SimulatorBackupStorage 类中没有被引用。建议在实际需要时再添加导入。

🔧 可选:移除未使用的导入
-import org.zstack.header.image.UploadFileToBackupStorageHostMsg;
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (1)

379-432: 新增的命令类字段风格与现有代码不一致

新增的 DownloadFileCmdUploadFileCmdDeleteFilesCmd 等类使用 public 字段直接暴露,而文件中现有的类(如 DownloadCmdGetDownloadProgressCmd)使用 private 字段配合 getter/setter。建议保持代码风格一致性。

♻️ 建议的重构示例(以 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 ee5168b and 3cb08aa.

📒 Files selected for processing (12)
  • header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostReply.java
  • 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
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.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 (5)
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.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/host/GetFileDownloadProgressReply.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:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostMsg.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostReply.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
🧠 Learnings (2)
📚 Learning: 2025-06-19T09:08:57.046Z
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2217
File: header/src/main/java/org/zstack/header/network/l2/L2NetworkCandidateFilterExtensionPoint.java:7-10
Timestamp: 2025-06-19T09:08:57.046Z
Learning: In the zstack project, for simple and self-explanatory interfaces like L2NetworkCandidateFilterExtensionPoint, the team prefers to rely on clear method names and parameters rather than adding detailed Javadoc comments, even when coding guidelines suggest otherwise.

Applied to files:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
📚 Learning: 2025-08-12T03:35:21.034Z
Learnt from: zstack-robot-1
Repo: MatheMatrix/zstack PR: 2419
File: network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java:287-297
Timestamp: 2025-08-12T03:35:21.034Z
Learning: In the ZStack codebase, extension points may be designed for different execution phases/orders in the same operation. For example, IpRangeDeletionExtensionPoint executes during IP range deletion process, while AfterDeleteIpRangeExtensionPoint executes after the entire deletion process is complete. This allows different plugins to hook into appropriate lifecycle stages.

Applied to files:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
🧬 Code graph analysis (2)
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)
🔇 Additional comments (5)
header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostReply.java (2)

8-14: 类名与字段语义不一致,建议核实设计意图。

类名 DeleteFilesOnBackupStorageHostReply 暗示这是一个删除文件操作的响应,但字段 md5sumdirectUploadUrlunzipInstallPath 更像是上传或下载操作的元数据。filesSize 作为删除操作的结果可以理解(返回被删除文件的大小),但其他字段的用途不太清晰。

请确认:

  1. 这些字段是否确实属于删除操作的响应?
  2. 是否存在复用其他操作 Reply 类的设计意图?

1-55: 其余代码结构符合规范。

@NoLogging(type = NoLogging.Type.Uri) 注解在 directUploadUrl 字段上的使用是恰当的。getter/setter 方法命名遵循 lowerCamelCase 规范。

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

1-28: 消息类设计合理,结构清晰。

该消息类正确地继承了 NeedReplyMessage 并实现了 BackupStorageMessage 接口。使用 List<String> 类型的 filesPath 字段支持批量删除操作是合理的设计。

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

1-46: 代码结构良好,符合消息类设计规范。

该消息类正确地继承了 NeedReplyMessage 并实现了 BackupStorageMessage 接口。@NoLogging(type = NoLogging.Type.Uri) 注解在 url 字段上的使用是恰当的,可以防止敏感 URI 信息被记录到日志中。对应的 UploadFileToBackupStorageHostReply 类已存在,正确继承 MessageReply,配套实现完整。

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

2099-2100: 回复类型正确,字段设置完整

验证确认 UploadFileToBackupStorageHostReplyUploadFileToBackupStorageHostMsg 的正确回复类型。所有必需字段都正确设置:对于 upload:// URL 方案,设置 directUploadUrlhostnamesshPasswordsshPortsshUsername;对于其他 URL 方案,设置 md5sumsizeunzipInstallPathfilesSize。代码实现无问题。

Comment on lines +2169 to +2189
protected void handle(final DeleteFilesOnBackupStorageHostMsg msg) {
UploadFileToBackupStorageHostReply reply = new UploadFileToBackupStorageHostReply();
DeleteFilesCmd cmd = new DeleteFilesCmd();
cmd.filesPath = msg.getFilesPath();
httpCall(DELETE_FILES_PATH, cmd, DownloadFileResponse.class, new ReturnValueCompletion<DownloadFileResponse>(msg) {
@Override
public void fail(ErrorCode err) {
reply.setError(err);
bus.reply(msg, reply);
}

@Override
public void success(DownloadFileResponse rsp) {
reply.setMd5sum(rsp.md5sum);
reply.setSize(rsp.size);
reply.setUnzipInstallPath(rsp.unzipInstallPath);
reply.setFilesSize(rsp.filesSize);
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find DeleteFilesOnBackupStorageHostReply class definition
rg -n "class DeleteFilesOnBackupStorageHost" --type=java -A 2

Repository: MatheMatrix/zstack

Length of output: 890


🏁 Script executed:

#!/bin/bash
# Search for message and reply classes related to DeleteFiles
rg -n "DeleteFilesOnBackupStorage\|DeleteFilesResponse\|DownloadFileResponse" --type=java -B 1 -A 5 | head -100

Repository: MatheMatrix/zstack

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Check the actual file around line 2170
rg -n "protected void handle\(final DeleteFilesOnBackupStorageHostMsg" --type=java -A 25

Repository: MatheMatrix/zstack

Length of output: 3492


🏁 Script executed:

#!/bin/bash
# Find where DeleteFilesOnBackupStorageHostReply or similar reply classes are defined
find . -type f -name "*.java" | xargs grep -l "DeleteFilesOnBackupStorageHost" | head -20

Repository: MatheMatrix/zstack

Length of output: 321


🏁 Script executed:

#!/bin/bash
# Get full DeleteFilesOnBackupStorageHostReply class definition
cat -n header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostReply.java

Repository: MatheMatrix/zstack

Length of output: 1719


🏁 Script executed:

#!/bin/bash
# Search for response classes used in delete operations
rg -n "class.*DeleteFilesResponse\|class.*DeleteFileResponse" --type=java -A 5

Repository: MatheMatrix/zstack

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Check what DownloadFileResponse has and search for alternatives
rg -n "class DownloadFileResponse" --type=java -A 10

Repository: MatheMatrix/zstack

Length of output: 2532


🏁 Script executed:

#!/bin/bash
# Look at surrounding handlers to understand the pattern used
rg -n "protected void handle\(final UploadFileToBackupStorageHostMsg" --type=java -A 70 | head -80

Repository: MatheMatrix/zstack

Length of output: 9239


🏁 Script executed:

#!/bin/bash
# Search for all response classes in CephBackupStorageBase
rg -n "class.*Response extends AgentResponse" plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java

Repository: MatheMatrix/zstack

Length of output: 361


🏁 Script executed:

#!/bin/bash
# Check if there's a DeleteFilesResponse anywhere in the codebase
rg -n "class.*DeleteFiles.*Response" --type=java

Repository: MatheMatrix/zstack

Length of output: 217


🏁 Script executed:

#!/bin/bash
# Look at the UploadFileResponse class to compare
rg -n "class UploadFileResponse" --type=java -A 10

Repository: MatheMatrix/zstack

Length of output: 2509


删除文件处理器使用了错误的回复类型和响应类

此处理方法在第 2170 行和 2173 行存在关键问题:

  1. 回复类型错误:使用 UploadFileToBackupStorageHostReply 而非 DeleteFilesOnBackupStorageHostReply
  2. 响应类错误:httpCall 调用使用 DownloadFileResponse.class 而非 DeleteFilesResponse.class
修复方案
 protected void handle(final DeleteFilesOnBackupStorageHostMsg msg) {
-    UploadFileToBackupStorageHostReply reply = new UploadFileToBackupStorageHostReply();
+    DeleteFilesOnBackupStorageHostReply reply = new DeleteFilesOnBackupStorageHostReply();
     DeleteFilesCmd cmd = new DeleteFilesCmd();
     cmd.filesPath = msg.getFilesPath();
-    httpCall(DELETE_FILES_PATH, cmd, DownloadFileResponse.class, new ReturnValueCompletion<DownloadFileResponse>(msg) {
+    httpCall(DELETE_FILES_PATH, cmd, DeleteFilesResponse.class, new ReturnValueCompletion<DeleteFilesResponse>(msg) {
         @Override
         public void fail(ErrorCode err) {
             reply.setError(err);
             bus.reply(msg, reply);
         }

         @Override
-        public void success(DownloadFileResponse rsp) {
+        public void success(DeleteFilesResponse rsp) {
             reply.setMd5sum(rsp.md5sum);
             reply.setSize(rsp.size);
             reply.setUnzipInstallPath(rsp.unzipInstallPath);
             reply.setFilesSize(rsp.filesSize);
             bus.reply(msg, reply);
         }
     });
 }
🤖 Prompt for AI Agents
In
@plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
around lines 2169 - 2189, The DeleteFilesOnBackupStorageHost handler is using
the wrong reply and response types; replace the incorrectly instantiated
UploadFileToBackupStorageHostReply with DeleteFilesOnBackupStorageHostReply in
handle(DeleteFilesOnBackupStorageHostMsg msg) and change the httpCall
generic/response class from DownloadFileResponse.class to
DeleteFilesResponse.class (keeping the DeleteFilesCmd and same success/fail
logic), ensuring you set the appropriate fields from DeleteFilesResponse onto
DeleteFilesOnBackupStorageHostReply before bus.reply(msg, reply).

Comment on lines +7 to +9
public interface AfterQueryExtensionPoint {
void fileter(List<ZQLQueryReturn> rs, String zqlText);
}
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

方法名拼写错误:fileter 应为 filter

这是一个公共扩展点接口,方法名 fileter 明显是 filter 的拼写错误。由于所有实现类都会使用这个方法名,此错误会传播到整个代码库,后续修复将导致 API 破坏性变更。

根据编码规范,方法名应使用 lowerCamelCase 风格并清晰表达意图。

🐛 修复方法名拼写错误
 public interface AfterQueryExtensionPoint {
-    void fileter(List<ZQLQueryReturn> rs, String zqlText);
+    void filter(List<ZQLQueryReturn> rs, String zqlText);
 }
🤖 Prompt for AI Agents
In @search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java around
lines 7 - 9, Rename the misspelled method fileter to filter on the
AfterQueryExtensionPoint interface and update all implementing classes and call
sites to use AfterQueryExtensionPoint.filter(List<ZQLQueryReturn>, String);
ensure method signature remains identical (parameter types and order) and update
javadoc/comments; if you need to avoid a breaking change immediately, add a
default fileter(...) implementation on the interface that delegates to
filter(...) and mark it @Deprecated, then remove the deprecated alias after
downstream updates.

APIImpact

Resolves: ZSV-1

Change-Id: I656979726c736267776c7262716969726874716d
@MatheMatrix MatheMatrix force-pushed the sync/tao.gan/anyun-ZSV-1@@4 branch from 3cb08aa to 809e21f Compare January 14, 2026 01:40
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: 1

🤖 Fix all issues with AI agents
In
`@plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java`:
- Around line 402-403: DeleteFilesResponse is empty so callers can't get
deletion results; add explicit fields mirroring what the handler/clients expect
(e.g., boolean success, List<String> deletedPaths, Map<String,String>
failedPathsWithErrors and/or String error); update the class DeleteFilesResponse
extends AgentResponse to include those fields with getters/setters and ensure
any code that previously relied on DownloadFileResponse semantics uses the same
field names/types (or adapt the handler to populate the new fields when creating
the DeleteFilesResponse).
♻️ Duplicate comments (3)
search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java (1)

7-9: 方法名拼写错误:fileter 应为 filter

这是公共扩展点接口,方法名拼写错误会传播到所有实现类,后续修复将导致 API 破坏性变更。根据编码规范,方法名应清晰表达意图。

🐛 建议修复
 public interface AfterQueryExtensionPoint {
-    void fileter(List<ZQLQueryReturn> rs, String zqlText);
+    void filter(List<ZQLQueryReturn> rs, String zqlText);
 }
header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java (1)

5-15: 缺少 md5sum 字段导致编译错误。

CephBackupStorageBase.java 第 2213 行调用了 reply.setMd5sum(rsp.md5sum),但此类未定义 md5sum 字段,将导致编译失败。

对比 header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java(包含 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;
+    }
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (1)

2169-2189: 使用了错误的回复类型和响应类。

此处理器存在关键问题:

  1. 第 2170 行:使用 UploadFileToBackupStorageHostReply 而非 DeleteFilesOnBackupStorageHostReply
  2. 第 2173 行:httpCall 使用 DownloadFileResponse.class 而非 DeleteFilesResponse.class
🔧 建议修复
 protected void handle(final DeleteFilesOnBackupStorageHostMsg msg) {
-    UploadFileToBackupStorageHostReply reply = new UploadFileToBackupStorageHostReply();
+    DeleteFilesOnBackupStorageHostReply reply = new DeleteFilesOnBackupStorageHostReply();
     DeleteFilesCmd cmd = new DeleteFilesCmd();
     cmd.filesPath = msg.getFilesPath();
-    httpCall(DELETE_FILES_PATH, cmd, DownloadFileResponse.class, new ReturnValueCompletion<DownloadFileResponse>(msg) {
+    httpCall(DELETE_FILES_PATH, cmd, DeleteFilesResponse.class, new ReturnValueCompletion<DeleteFilesResponse>(msg) {
         `@Override`
         public void fail(ErrorCode err) {
             reply.setError(err);
             bus.reply(msg, reply);
         }

         `@Override`
-        public void success(DownloadFileResponse rsp) {
-            reply.setMd5sum(rsp.md5sum);
-            reply.setSize(rsp.size);
-            reply.setUnzipInstallPath(rsp.unzipInstallPath);
-            reply.setFilesSize(rsp.filesSize);
+        public void success(DeleteFilesResponse rsp) {
+            // 根据 DeleteFilesResponse 实际字段设置回复
             bus.reply(msg, reply);
         }
     });
 }
🧹 Nitpick comments (1)
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (1)

379-432: 字段可见性与现有代码风格不一致。

新增的命令/响应类(如 DownloadFileCmdUploadFileCmd)使用 public 字段,而同文件中现有的类(如 DownloadCmdGetDownloadProgressCmd)使用 private 字段配合 getter/setter。

建议保持一致性,使用 private 字段并提供访问器方法,符合 JavaBean 规范和项目既有风格。

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cb08aa and 809e21f.

📒 Files selected for processing (12)
  • header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostReply.java
  • 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
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.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 (6)
  • simulator/simulatorImpl/src/main/java/org/zstack/simulator/storage/backup/SimulatorBackupStorage.java
  • storage/src/main/java/org/zstack/storage/addon/backup/ExternalBackupStorage.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressMsg.java
  • header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java
  • storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostReply.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/image/DeleteFilesOnBackupStorageHostReply.java
  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
  • header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/image/DeleteFilesOnBackupStorageHostMsg.java
  • header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java
  • plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java
🧠 Learnings (2)
📚 Learning: 2025-06-19T09:08:57.046Z
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2217
File: header/src/main/java/org/zstack/header/network/l2/L2NetworkCandidateFilterExtensionPoint.java:7-10
Timestamp: 2025-06-19T09:08:57.046Z
Learning: In the zstack project, for simple and self-explanatory interfaces like L2NetworkCandidateFilterExtensionPoint, the team prefers to rely on clear method names and parameters rather than adding detailed Javadoc comments, even when coding guidelines suggest otherwise.

Applied to files:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
📚 Learning: 2025-08-12T03:35:21.034Z
Learnt from: zstack-robot-1
Repo: MatheMatrix/zstack PR: 2419
File: network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java:287-297
Timestamp: 2025-08-12T03:35:21.034Z
Learning: In the ZStack codebase, extension points may be designed for different execution phases/orders in the same operation. For example, IpRangeDeletionExtensionPoint executes during IP range deletion process, while AfterDeleteIpRangeExtensionPoint executes after the entire deletion process is complete. This allows different plugins to hook into appropriate lifecycle stages.

Applied to files:

  • search/src/main/java/org/zstack/query/AfterQueryExtensionPoint.java
🧬 Code graph analysis (2)
header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java (1)
header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java (1)
  • GetFileDownloadProgressReply (7-108)
plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java (3)
header/src/main/java/org/zstack/header/host/GetFileDownloadProgressReply.java (1)
  • GetFileDownloadProgressReply (7-108)
header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressReply.java (1)
  • GetFileDownloadProgressReply (5-92)
header/src/main/java/org/zstack/header/host/UploadFileToHostReply.java (1)
  • UploadFileToHostReply (6-35)
🔇 Additional comments (6)
header/src/main/java/org/zstack/header/image/UploadFileToBackupStorageHostMsg.java (1)

1-46: LGTM!

消息类结构正确,遵循项目约定:继承 NeedReplyMessage,实现 BackupStorageMessage 接口,url 字段正确使用 @NoLogging 注解防止敏感信息泄露。

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

1-28: LGTM!

消息类结构正确,遵循项目约定。

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

8-14: 字段语义与删除操作不匹配。

作为"删除文件"操作的回复类,包含 md5sumsizedirectUploadUrlunzipInstallPath 等字段在语义上不太合理。通常删除操作只需返回操作状态或被删除文件的确认信息。

建议确认这些字段是否确实需要,或者是否应该简化此回复类。

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

2099-2167: LGTM!

UploadFileToBackupStorageHostMsg 处理逻辑清晰:

  • 正确区分 upload:// 前缀和其他 URL
  • URI 解析有适当的异常处理
  • 超时配置使用 timeoutManager.getTimeout() 正确获取

2191-2218: 处理器逻辑正确,但依赖 GetFileDownloadProgressReply 添加 md5sum 字段。

第 2213 行调用 reply.setMd5sum(rsp.md5sum),需要在 GetFileDownloadProgressReply 类中添加 md5sum 字段后才能编译通过。


34-35: 导入语句明确且不存在冲突。

虽然 GetFileDownloadProgressReply 类同时存在于 org.zstack.header.storage.backuporg.zstack.header.host 两个包中,但第 34 行的显式导入 org.zstack.header.host.GetFileDownloadProgressReply 在 Java 导入解析中优先于第 42 行的通配符导入 org.zstack.header.storage.backup.*。因此,代码中使用的是 header.host 包中的版本,不存在类型解析歧义。

Likely an incorrect or invalid review comment.

Comment on lines +402 to +403
public static class DeleteFilesResponse extends AgentResponse {
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

DeleteFilesResponse 类为空,缺少必要字段。

当前 DeleteFilesResponse 类没有定义任何字段。即使修复了处理器中的类型错误(使用此类替代 DownloadFileResponse),也无法正确传递响应数据。

请确认删除操作是否需要返回特定信息,如有需要应添加相应字段。

🤖 Prompt for AI Agents
In
`@plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java`
around lines 402 - 403, DeleteFilesResponse is empty so callers can't get
deletion results; add explicit fields mirroring what the handler/clients expect
(e.g., boolean success, List<String> deletedPaths, Map<String,String>
failedPathsWithErrors and/or String error); update the class DeleteFilesResponse
extends AgentResponse to include those fields with getters/setters and ensure
any code that previously relied on DownloadFileResponse semantics uses the same
field names/types (or adapt the handler to populate the new fields when creating
the DeleteFilesResponse).

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