Skip to content

ZCF-3300 <feature>[license]: support license lsclient#3893

Open
zstack-robot-1 wants to merge 1 commit intofeature-5.5.22-zcf-temporaryfrom
sync/hanyu.liang/zcf-3300@@2
Open

ZCF-3300 <feature>[license]: support license lsclient#3893
zstack-robot-1 wants to merge 1 commit intofeature-5.5.22-zcf-temporaryfrom
sync/hanyu.liang/zcf-3300@@2

Conversation

@zstack-robot-1
Copy link
Copy Markdown
Collaborator

Summary

  • Support testlib routing for LS client endpoints under /v1/sites/** and /v1/quota/**.
  • Support multipart request parsing in testlib for LS bootstrap API coverage.

Jira

Verification

  • testlib module compile passed during development.
  • premium integration cases covering LS client lifecycle and quota behavior passed in companion MR.

sync from gitlab !9775

Support testlib simulator routing and multipart parsing for License Server client API tests.

Resolves: ZCF-3300

Change-Id: I4a80faaf48aa174bebc5186b8b76033a9b6968b7
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

代码审查概览

该PR为HTTP多部分请求处理添加了完整支持。更新了TestLibController的路由映射,添加了多部分请求的检测与早期分发机制,并在EnvSpec中实现了多部分请求体的提取与解析逻辑。

变更分布

多部分请求处理实现

审查层级 / 文件 概述
路由配置
testlib/src/main/java/org/zstack/testlib/TestLibController.java
@RequestMapping注解扩展了URL模式,显式增加了/v1/sites/**/v1/quota/**前缀以及既有的catch-all模式。
多部分检测
testlib/src/main/java/org/zstack/testlib/TestLibController.java
新增isMultipartRequest私有辅助方法,通过检查Content-Type是否以multipart/开头来标识多部分请求。
请求分发
testlib/src/main/java/org/zstack/testlib/TestLibController.java
请求处理器添加了早期返回路径,多部分请求直接委托给Test.handleHttp,非多部分请求保留原有异步处理。
请求体提取
testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy
getEntityFromRequest方法现在根据Content-Type分支处理:多部分请求读取多部分内容,其他请求通过servlet reader逐行读取。
多部分解析实现
testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy
添加readMultipartBodyreadSpringMultipartBody方法用于读取多部分原始字节或委托Spring解析,appendMultipartPart方法序列化多部分字段和文件。

代码审查工作量估计

🎯 3 (中等复杂度) | ⏱️ ~22 分钟

庆祝诗

🐰 多部分之梦在此成真,
请求流转如丝线纷纷,
从控制器到解析层,
每个字节都有归属,
Content-Type 引路,
数据流向更清晰!


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Title check ❌ Error 标题包含JIRA密钥(ZCF-3300)、类型前缀([feature])和范围([license]),但描述部分与实际变更不匹配,实际变更涉及testlib路由和多部分请求解析,而标题仅提及license lsclient支持。 建议修改标题为:'ZCF-3300 [testlib]: support multipart requests and LS client routing'以准确反映实际代码变更内容。
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed 描述清晰地说明了两个主要变更:testlib路由扩展支持/v1/sites/和/v1/quota/,以及多部分请求解析支持,与实际代码变更完全对应。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/hanyu.liang/zcf-3300@@2

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

Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy`:
- Around line 1001-1006: The code repeatedly calls req.getReader() causing
potential inconsistent reads; change to obtain a single BufferedReader reader =
req.getReader() (or def reader) before the loop, use that reader in the while
loop that appends lines (instead of calling req.getReader().readLine()), and
ensure the reader is closed in a finally block (or try-with-resources) to
guarantee a single, safe close; update the block around the loop in
EnvSpec.groovy where String line is used so all read/close operations reference
this single reader variable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: a0e468ad-d803-4c32-9c4d-87a474a162a0

📥 Commits

Reviewing files that changed from the base of the PR and between 7f86605 and c0a9d03.

📒 Files selected for processing (2)
  • testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy
  • testlib/src/main/java/org/zstack/testlib/TestLibController.java

Comment on lines +1001 to +1006
String line
while ((line = req.getReader().readLine()) != null) {
sb.append(line)
}
req.getReader().close()
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 只读验证:定位该方法内对 getReader() 的重复调用点
rg -n -C2 'getEntityFromRequest|req\.getReader\(\)\.readLine\(\)|req\.getReader\(\)\.close\(\)' testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy

Repository: MatheMatrix/zstack

Length of output: 768


🏁 Script executed:

#!/bin/bash
# Verification only: locate repeated getReader() calls within this method
rg -n -C2 'getEntityFromRequest|req\.getReader\(\)\.readLine\(\)|req\.getReader\(\)\.close\(\)' testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy

Repository: MatheMatrix/zstack

Length of output: 768


避免重复调用 req.getReader(),改为单次获取并统一关闭。

第 1002 行和第 1005 行重复调用 getReader(),在不同 Servlet 实现下可能带来读取不一致或异常风险。建议单次获取 reader 后复用并在 finally 中关闭。

建议修复
-            String line
-            while ((line = req.getReader().readLine()) != null) {
-                sb.append(line)
-            }
-            req.getReader().close()
+            def reader = req.getReader()
+            try {
+                String line
+                while ((line = reader.readLine()) != null) {
+                    sb.append(line)
+                }
+            } finally {
+                reader.close()
+            }
📝 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
String line
while ((line = req.getReader().readLine()) != null) {
sb.append(line)
}
req.getReader().close()
}
def reader = req.getReader()
try {
String line
while ((line = reader.readLine()) != null) {
sb.append(line)
}
} finally {
reader.close()
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy` around lines 1001 -
1006, The code repeatedly calls req.getReader() causing potential inconsistent
reads; change to obtain a single BufferedReader reader = req.getReader() (or def
reader) before the loop, use that reader in the while loop that appends lines
(instead of calling req.getReader().readLine()), and ensure the reader is closed
in a finally block (or try-with-resources) to guarantee a single, safe close;
update the block around the loop in EnvSpec.groovy where String line is used so
all read/close operations reference this single reader variable.

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.

2 participants