Skip to content

Conversation

@zstack-robot-1
Copy link
Collaborator

Resolves: ZSTAC-79237

Change-Id: I646365206a7923767067706e7a6e667a796f686d

sync from gitlab !8715

@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

总体概览

在许可容量管理系统中添加了新的 resourceInfo 字段。该字段涵盖数据库schema、请求操作类和库存对象类三个层次,用于存储额外的资源信息,类型均为文本。

变更清单

内聚体 / 文件 变更摘要
数据库Schema升级
conf/db/upgrade/V4.8.36__schema.sql
zstack.LicenseAuthorizedCapacityVO 表中添加 resourceInfo 列(text类型,DEFAULT NULL),位于 resourceUuidquotaType 之间
SDK请求操作类
sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java
新增公共字段 resourceInfo(String类型),附带 @Param 注解
库存对象类
sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java
新增公共字段 resourceInfo(String类型),以及相应的 getter 和 setter 方法

代码审核工作量评估

🎯 1 (简单) | ⏱️ ~5分钟

  • 所有变更为一致性的结构性添加(新增单个字段),跨越三个文件
  • 无复杂逻辑、业务规则或控制流变更
  • 遵循既有代码模式,属于重复性变更

诗歌

🐰 一只兔子的歌:

资源信息添加日,
三层架构共相宜,
Schema、请求、库存齐,
字段流转如织锦,
许可容量更完美!✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
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 (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题清晰地总结了主要变更:修复ARM和VMware附加组件未消耗主许可证配额的问题,与代码变更(添加resourceInfo字段用于许可证容量管理)相关。
Description check ✅ Passed 描述包含问题追踪ID(ZSTAC-79237)、变更ID和来源说明,与变更集相关,提供了必要的上下文信息。
✨ 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/hanyu.liang/fix-79237@@2

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

@MatheMatrix MatheMatrix force-pushed the sync/hanyu.liang/fix-79237@@2 branch from 6602a49 to db1afef Compare November 18, 2025 08:50
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6602a49 and db1afef.

📒 Files selected for processing (4)
  • conf/db/upgrade/V4.8.36__schema.sql (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (3 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • conf/db/upgrade/V4.8.36__schema.sql
🧰 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:

  • sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java
  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java
🔇 Additional comments (6)
sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (2)

15-15: 代码简化改进良好

将完全限定类型(如 java.lang.String)简化为简单类型(如 String)提升了代码可读性,符合最佳实践。

Also applies to: 29-29, 32-32, 35-35, 38-38, 41-41, 78-79


43-44: 修正所有必填字段的 emptyString 配置

验证发现,框架的 ApiMessageParamValidator 仅检查 null 值,不处理 emptyString 参数。因此,设置 emptyString = true 对必填字段无实际约束效果。

RequestLicenseCapacityAction 中,所有 6 个 required = true 的字段都被配置为 emptyString = true,这造成逻辑矛盾:必填字段不应允许空字符串。

需修正以下字段(行 36、39、42、45、48、51):

  • resourceUuid
  • quotaType
  • quota
  • clientAuthorizedNodeUuid
  • licenseType
  • resourceInfo

emptyString = true 改为 emptyString = false,确保必填字段包含有意义的值。

⛔ Skipped due to learnings
Learnt from: ZStack-Robot
Repo: MatheMatrix/zstack PR: 2828
File: sdk/src/main/java/org/zstack/sdk/DeleteHostKernelInterfaceAction.java:28-28
Timestamp: 2025-10-29T03:29:06.923Z
Learning: 在 ZStack SDK 的 Param 注解中:
- nonempty 参数应该用于集合类型(List等),用于检查集合是否为空
- emptyString 参数才是用于 String 类型,用于检查字符串是否为空或空白
- 对于 String 类型字段,应该使用 nonempty = false 和 emptyString = false(如果不允许空字符串)
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2199
File: plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:745-745
Timestamp: 2025-06-19T10:34:39.243Z
Learning: SecurityGroupApiInterceptor.java 中需要对以下类型的外部字符串参数进行 trim 处理:1) IP相关字段(getAllowedCidr, getSrcIpRange, getDstIpRange) 2) 端口字段(getDstPortRange) 3) UUID字段(getRemoteSecurityGroupUuid等) 4) 描述字段(getDescription) 5) 枚举字符串字段(getProtocol, getAction, getState, getType)。这些参数在进入 validateIps, validatePorts 以及所有 validate 方法之前都应当被 trim,以防止空格、换行符等不可见字符影响验证逻辑。
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2199
File: plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:745-745
Timestamp: 2025-06-19T10:34:39.243Z
Learning: 在 SecurityGroupApiInterceptor.java 中,所有来自 API Message 的外部字符串参数(如 IP 范围、端口范围、安全组 UUID、描述等)都应当在 validate 方法中进行 trim 处理,以防止用户在浏览器中复制粘贴带有空格、换行符、回车符等不可见字符的数据影响验证逻辑。
Learnt from: MatheMatrix
Repo: MatheMatrix/zstack PR: 2410
File: compute/src/main/java/org/zstack/compute/vm/VmInstanceHelper.java:334-356
Timestamp: 2025-08-10T13:42:01.027Z
Learning: 在 ZStack 的 `VmInstanceHelper.validateVmNicParams` 方法中,当 vmNicParams 非空但 l3NetworkUuids 为空时的报错文案 "l3NetworkUuids and vmNicInventories mustn't both be empty or both be set" 需要保持不变,以维持与现有 i18n 的一致性,即使文案中提到的是 vmNicInventories 而非 vmNicParams。
Learnt from: zstack-robot-1
Repo: MatheMatrix/zstack PR: 2763
File: sdk/src/main/java/org/zstack/sdk/GetCandidateHostKernelInterfacesAction.java:37-38
Timestamp: 2025-10-20T11:28:00.984Z
Learning: SDK Action 类(如 GetCandidateHostKernelInterfacesAction)中的 Param 注解是自动生成的,使用默认参数值,即使某些属性(如布尔字段上的 emptyString)在语义上可能不适用,也不应修改这些注解。
Learnt from: zstack-robot-2
Repo: MatheMatrix/zstack PR: 1986
File: plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:182-193
Timestamp: 2025-04-16T16:36:31.251Z
Learning: 在 ZStack 中,当 API 消息类的字段使用 `APIParam(resourceType = X.class)` 注解时,框架会自动验证提供的 UUID 对应的资源在数据库中是否存在。因此,在 API 拦截器的 `validate` 方法中,无需再对这些资源进行存在性检查。
sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java (2)

8-14: 类型简化改进良好

字段类型从 java.lang.String 简化为 String,提升了代码可读性,改动正确。

Also applies to: 16-22


48-54: 新增字段实现无问题,无需修改

platformUsedByOtherNode 字段的实现完全符合要求:

  • 字段命名正确(lowerCamelCase)
  • Getter/Setter 方法标准规范
  • 作为 DTO 类,原始类型 long 默认初始化为 0,无需显式初始化
  • 与同类字段 addOnUsedByOtherNode 保持一致的实现模式
  • 已正确集成到 GetLicenseAuthorizedCapacityResult API 返回结构中
sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (2)

7-13: 类型简化重构正确

所有字段类型从完全限定的 java.lang.Stringjava.lang.Long 简化为 StringLong,getter/setter 方法签名同步更新,改动一致且正确,提升了代码可读性。

Also applies to: 15-21, 23-29, 39-45, 47-53, 55-61, 63-69


31-37: 新增 resourceInfo 字段实现正确

新增的 resourceInfo 字段与数据库 schema 变更(V4.8.36__schema.sql 中添加的 resourceInfo 列)保持一致,字段定义、命名规范和 getter/setter 方法均符合 JavaBean 约定,实现正确。

Comment on lines 56 to 62
public java.util.Map addOnUsedByOtherNode;
public void setAddOnUsedByOtherNode(java.util.Map addOnUsedByOtherNode) {
this.addOnUsedByOtherNode = addOnUsedByOtherNode;
}
public java.util.Map getAddOnUsedByOtherNode() {
return this.addOnUsedByOtherNode;
}
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

缺少泛型参数导致类型不安全

addOnUsedByOtherNode 字段声明为原始 java.util.Map 类型,缺少泛型参数。这会导致:

  1. 编译时无法进行类型检查
  2. 运行时可能抛出 ClassCastException
  3. 不符合 Java 编码最佳实践

根据字段名称推测,应该使用 java.util.Map<String, Long> 来表示插件类型到使用量的映射。

建议应用以下修改:

-    public java.util.Map addOnUsedByOtherNode;
-    public void setAddOnUsedByOtherNode(java.util.Map addOnUsedByOtherNode) {
+    public java.util.Map<String, Long> addOnUsedByOtherNode;
+    public void setAddOnUsedByOtherNode(java.util.Map<String, Long> addOnUsedByOtherNode) {
         this.addOnUsedByOtherNode = addOnUsedByOtherNode;
     }
-    public java.util.Map getAddOnUsedByOtherNode() {
+    public java.util.Map<String, Long> getAddOnUsedByOtherNode() {
         return this.addOnUsedByOtherNode;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public java.util.Map addOnUsedByOtherNode;
public void setAddOnUsedByOtherNode(java.util.Map addOnUsedByOtherNode) {
this.addOnUsedByOtherNode = addOnUsedByOtherNode;
}
public java.util.Map getAddOnUsedByOtherNode() {
return this.addOnUsedByOtherNode;
}
public java.util.Map<String, Long> addOnUsedByOtherNode;
public void setAddOnUsedByOtherNode(java.util.Map<String, Long> addOnUsedByOtherNode) {
this.addOnUsedByOtherNode = addOnUsedByOtherNode;
}
public java.util.Map<String, Long> getAddOnUsedByOtherNode() {
return this.addOnUsedByOtherNode;
}
🤖 Prompt for AI Agents
In
sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java
around lines 56 to 62, the addOnUsedByOtherNode field and its getter/setter use
the raw type java.util.Map which is unsafe; change the field declaration and the
get/set method signatures to use java.util.Map<String, Long> (and update
parameter/return types accordingly) so the mapping from addon identifier
(String) to usage count (Long) is type-safe and avoids unchecked conversions.

@MatheMatrix MatheMatrix force-pushed the sync/hanyu.liang/fix-79237@@2 branch from db1afef to f1204c4 Compare November 18, 2025 09:47
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

🧹 Nitpick comments (1)
sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1)

31-37: 建议:添加 JavaDoc 注释说明字段用途。

新增的 resourceInfo 字段及其访问器方法遵循了该类的标准模式,实现正确。但缺少 JavaDoc 注释来说明该字段的含义、用途和预期内容格式。

根据 PR 目标(修复 ARM 和 VMware 插件许可证配额消耗问题),建议添加注释说明 resourceInfo 存储的具体信息类型,例如:

  • 是否存储 ARM/VMware 等平台标识?
  • 格式是 JSON 还是纯文本?
  • 有哪些可能的取值?

示例:

+    /**
+     * 资源附加信息,用于标识 ARM、VMware 等特定平台类型
+     * 格式:JSON 字符串或平台标识符
+     */
     public java.lang.String resourceInfo;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db1afef and f1204c4.

📒 Files selected for processing (4)
  • conf/db/upgrade/V4.8.36__schema.sql (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • conf/db/upgrade/V4.8.36__schema.sql
  • sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.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:

  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java
🔇 Additional comments (1)
sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (1)

43-44: Let me search for test files or usage examples to get more context:

添加JavaDoc注释并实现__example__方法以完善API文档。

发现resourceInfo字段缺少JavaDoc注释,这违反了编码规范(第3和API设计部分要求接口方法需要完善的Javadoc)。同时,整个RequestLicenseCapacityAction类缺少__example__方法,而根据编码指南第1条,API类应实现此方法以便生成API文档。

建议:

  1. resourceInfo字段添加JavaDoc注释,说明该字段的用途、预期格式和示例值
  2. RequestLicenseCapacityAction类中实现__example__方法,生成对应的Groovy API模板和Markdown文档
  3. 通过git diff确认resourceInfo字段是否为新增字段,如为新增必填字段,需在发版说明中标注为破坏性变更或考虑降低required标志以保持向后兼容

@MatheMatrix MatheMatrix force-pushed the sync/hanyu.liang/fix-79237@@2 branch from f1204c4 to bb3b78c Compare November 19, 2025 03:33
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

Caution

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

⚠️ Outside diff range comments (1)
conf/db/upgrade/V4.8.36__schema.sql (1)

57-58: 使用了已弃用的时间戳默认值。

根据编码规范,不应使用 DEFAULT '0000-00-00 00:00:00',应改用 DEFAULT CURRENT_TIMESTAMP 或与其他表保持一致的 DEFAULT '1999-12-31 23:59:59'

应用此修改以符合规范:

-    `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
-    `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+    `lastOpDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59' ON UPDATE CURRENT_TIMESTAMP,
+    `createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59',

基于编码规范要求。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1204c4 and bb3b78c.

📒 Files selected for processing (4)
  • conf/db/upgrade/V4.8.36__schema.sql (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/TotalLicenseAuthorizedCapacityView.java
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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:

  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java
**/*.sql

⚙️ CodeRabbit configuration file

**/*.sql: Review the SQL code, make sure has no errors and confirm that:

  • Upgrading scene has been carefully handled
  • Do not use DEFAULT 0000-00-00 00:00:00 , use DEFAULT CURRENT_TIMESTAMP instead
  • When NOT NULL exists, must use stored procedure or other functions to process historical data, this is very very important

Files:

  • conf/db/upgrade/V4.8.36__schema.sql
🧠 Learnings (1)
📚 Learning: 2025-08-03T04:10:21.683Z
Learnt from: zstack-robot-1
Repo: MatheMatrix/zstack PR: 0
File: :0-0
Timestamp: 2025-08-03T04:10:21.683Z
Learning: ZStack 数据库升级脚本 V4.10.16__schema.sql 中的 UPGRADE_VM_METADATA_TABLES_DIRECT 存储过程使用直接 RENAME TABLE 操作,不具备幂等性。需要通过 information_schema 检查表和约束的存在性来确保脚本可以安全重复执行。

Applied to files:

  • conf/db/upgrade/V4.8.36__schema.sql
🔇 Additional comments (2)
sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (1)

43-44: LGTM!新增可选参数实现正确。

字段 resourceInfo 作为可选参数添加,遵循了命名规范(lowerCamelCase),注解配置正确,与代码库中的其他可选参数保持一致。

sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1)

31-37: LGTM!新增字段及访问器实现符合规范。

字段 resourceInfo 及其 getter/setter 方法遵循了标准的 Java Bean 规范,命名符合 lowerCamelCase 约定,与类中其他字段保持一致。

`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`nodeUuid` char(32) NOT NULL,
`resourceUuid` char(32) DEFAULT NULL,
`resourceInfo` text DEFAULT NULL,
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

升级场景未正确处理,新列不会被添加到已存在的表中。

由于这是升级脚本(V4.8.36),若生产环境中 LicenseAuthorizedCapacityVO 表已存在,使用 CREATE TABLE IF NOT EXISTS 不会添加新列 resourceInfo。必须使用 ALTER TABLE 语句,并通过查询 information_schema 来确保幂等性。

应用此修改以正确添加列:

-CREATE TABLE IF NOT EXISTS `zstack`.`LicenseAuthorizedCapacityVO` (
-    `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
-    `nodeUuid` char(32) NOT NULL,
-    `resourceUuid` char(32) DEFAULT NULL,
-    `resourceInfo` text DEFAULT NULL,
-    `quotaType` varchar(64) NOT NULL,
-    `quota` bigint unsigned DEFAULT 0,
-    `licenseType` varchar(64) NOT NULL,
-    `type` varchar(64) NOT NULL,
-    `lastOpDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59' ON UPDATE CURRENT_TIMESTAMP,
-    `createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59',
-    PRIMARY KEY (`id`),
-    CONSTRAINT `fkLicenseAuthorizedCapacityLicenseAuthorizedNode` FOREIGN KEY (`nodeUuid`) REFERENCES `LicenseAuthorizedNodeVO` (`uuid`) ON DELETE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加幂等的 ALTER TABLE 语句:

DELIMITER $$
CREATE PROCEDURE AddResourceInfoColumn()
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.COLUMNS
        WHERE TABLE_SCHEMA = 'zstack'
        AND TABLE_NAME = 'LicenseAuthorizedCapacityVO'
        AND COLUMN_NAME = 'resourceInfo'
    ) THEN
        ALTER TABLE `zstack`.`LicenseAuthorizedCapacityVO`
        ADD COLUMN `resourceInfo` text DEFAULT NULL AFTER `resourceUuid`;
    END IF;
END$$
DELIMITER ;

CALL AddResourceInfoColumn();
DROP PROCEDURE IF EXISTS AddResourceInfoColumn;

根据 learnings 和编码规范要求。

🤖 Prompt for AI Agents
In conf/db/upgrade/V4.8.36__schema.sql around line 17, the upgrade script
currently adds `resourceInfo` via a CREATE TABLE/column definition which won’t
add the new column when the LicenseAuthorizedCapacityVO table already exists;
replace that with an idempotent ALTER flow that queries information_schema for
TABLE_SCHEMA='zstack', TABLE_NAME='LicenseAuthorizedCapacityVO' and
COLUMN_NAME='resourceInfo' and only runs ALTER TABLE ... ADD COLUMN
`resourceInfo` text DEFAULT NULL AFTER `resourceUuid` if the column is missing;
implement this check-and-add as a CREATE PROCEDURE / CALL / DROP PROCEDURE
sequence (or equivalent conditional SQL) so the migration is safe to run
multiple times and works on existing production tables.

…nse quota

Resolves: ZSTAC-79237

Change-Id: I646365206a7923767067706e7a6e667a796f686d
@MatheMatrix MatheMatrix force-pushed the sync/hanyu.liang/fix-79237@@2 branch from bb3b78c to 0e8c2d1 Compare November 19, 2025 10:05
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

🧹 Nitpick comments (2)
sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (1)

43-44: 建议添加字段文档说明其用途和格式

新增的 resourceInfo 字段缺少 Javadoc 注释,无法从代码中了解该字段的具体用途、预期内容格式或取值范围。结合 PR 标题(关于 ARM 和 VMware 附加组件的许可证配额修复),建议添加注释说明该字段存储的是什么类型的资源信息(例如:平台类型、架构信息等)。

建议添加类似以下的 Javadoc 注释:

+    /**
+     * Additional resource information, e.g., platform type (ARM/VMware) or architecture details
+     * for license capacity tracking
+     */
     @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
     public java.lang.String resourceInfo;
sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1)

31-37: 建议添加字段文档说明

新增的 resourceInfo 字段缺少 Javadoc 注释。虽然该类是简单的 Inventory 类(DTO),但为了与 RequestLicenseCapacityAction 中的同名字段保持一致,建议添加相同的文档说明,明确该字段的用途和内容格式。

建议添加 Javadoc 注释:

+    /**
+     * Additional resource information, e.g., platform type (ARM/VMware) or architecture details
+     */
     public java.lang.String resourceInfo;
     public void setResourceInfo(java.lang.String resourceInfo) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb3b78c and 0e8c2d1.

📒 Files selected for processing (3)
  • conf/db/upgrade/V4.8.36__schema.sql (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java (1 hunks)
  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • conf/db/upgrade/V4.8.36__schema.sql
🧰 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:

  • sdk/src/main/java/org/zstack/sdk/license/api/server/RequestLicenseCapacityAction.java
  • sdk/src/main/java/org/zstack/sdk/license/header/server/LicenseAuthorizedCapacityInventory.java

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