Skip to content

<fix>[sftp]: add 60s timeout to SFTP backup storage connect syncJsonPost#4114

Closed
zstack-robot-2 wants to merge 1 commit into
5.5.22from
sync/songtao.liu/fix/ZSTAC-67815-clean
Closed

<fix>[sftp]: add 60s timeout to SFTP backup storage connect syncJsonPost#4114
zstack-robot-2 wants to merge 1 commit into
5.5.22from
sync/songtao.liu/fix/ZSTAC-67815-clean

Conversation

@zstack-robot-2
Copy link
Copy Markdown
Collaborator

Root Cause

SftpBackupStorage.continueConnect() uses syncJsonPost(url, cmd, ConnectResponse.class) without timeout. When SFTP agent HTTP layer is unreachable, this blocks indefinitely in BackupStorageBase.chainSubmit context, permanently holding the per-BS queue slot.

Fix

Add TimeUnit.SECONDS, 60 timeout to syncJsonPost call, ensuring 60s failure → completion.fail() → chain.next() releases queue slot.

Resolves: ZSTAC-67815

sync from gitlab !10012

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Review Change Stack

Warning

Review limit reached

@MatheMatrix, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 21 minutes and 43 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ 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: e1929988-dc2a-47c6-9c32-bcb96fb3bc1c

📥 Commits

Reviewing files that changed from the base of the PR and between 46d1102 and c81ce08.

📒 Files selected for processing (2)
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageGlobalProperty.java

概述

PR 为 SFTP 备份存储的连接请求添加了 60 秒超时,使用 TimeUnit.SECONDS 参数化;并通过新增集成测试验证该超时功能的正确实现。

变更说明

SFTP 连接超时

层级 / 文件(s) 概述
连接超时实现
plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
导入 java.util.concurrent.TimeUnitcontinueConnect 方法中的 restf.syncJsonPost 调用改用带超时参数的重载,设置超时单位为秒、超时值为 60。
连接超时集成测试
test/src/test/groovy/org/zstack/test/integration/storage/backup/sftp/SftpBackupStorageConnectTimeoutCase.groovy
新增 SftpBackupStorageConnectTimeoutCase 集成测试类,配置测试环境并模拟 SFTP 连接接口返回成功;验证创建的备份存储处于 Connected 状态。

序列图

不适用于此变更。

🎯 2 (Simple) | ⏱️ ~10 分钟

🐰 超时添加微小,测试验证周全,

队列从此不再饥饿,

SFTP 连接稳且安,代理不可达也无患!✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR标题完全符合指定格式且长度正确,清晰描述了主要变更:为SFTP备份存储连接添加60秒超时。
Description check ✅ Passed PR描述详细说明了根本原因、修复方案和关联问题,完全相关且与变更集相符。
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/songtao.liu/fix/ZSTAC-67815-clean

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

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

342-342: ⚡ Quick win

将连接超时值提取为具名常量,避免魔法值。

这里直接写 60 可读性和可维护性较弱,建议提取为类级常量(例如 CONNECT_TIMEOUT_SECONDS),并使用 60Llong timeout 参数语义一致。

♻️ 建议修改
 public class SftpBackupStorage extends BackupStorageBase {
     private static final CLogger logger = Utils.getLogger(SftpBackupStorage.class);
+    private static final long CONNECT_TIMEOUT_SECONDS = 60L;
...
-                ConnectResponse rsp = restf.syncJsonPost(url, cmd, ConnectResponse.class, TimeUnit.SECONDS, 60);
+                ConnectResponse rsp = restf.syncJsonPost(url, cmd, ConnectResponse.class, TimeUnit.SECONDS, CONNECT_TIMEOUT_SECONDS);

As per coding guidelines: “避免使用魔法值(Magic Value)”。

🤖 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
`@plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java`
at line 342, The restf.syncJsonPost call in SftpBackupStorage uses a magic
literal 60 for the timeout; extract this into a class-level constant (e.g.,
CONNECT_TIMEOUT_SECONDS) and replace the literal with that constant (use 60L to
match the long timeout parameter), updating the restf.syncJsonPost invocation to
pass CONNECT_TIMEOUT_SECONDS so the timeout value is named and maintainable.
🤖 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
`@test/src/test/groovy/org/zstack/test/integration/storage/backup/sftp/SftpBackupStorageConnectTimeoutCase.groovy`:
- Around line 82-103: Add a negative test branch to testSftpConnectWithTimeout
that simulates a CONNECT_PATH delay exceeding the 60s timeout: use
env.simulator(SftpBackupStorageConstant.CONNECT_PATH) to introduce a long
sleep/delay and return no successful ConnectResponse, then call
addSftpBackupStorage and assert it fails within the expected timeout
(throws/returns error) and does not block further operations (for example,
immediately perform another lightweight addSftpBackupStorage or query and assert
it succeeds). Ensure assertions reference the test method name
testSftpConnectWithTimeout, the simulator hook
SftpBackupStorageConstant.CONNECT_PATH, and the
addSftpBackupStorage/BackupStorageInventory flow so the failure and non-blocking
behavior are validated.

---

Nitpick comments:
In
`@plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java`:
- Line 342: The restf.syncJsonPost call in SftpBackupStorage uses a magic
literal 60 for the timeout; extract this into a class-level constant (e.g.,
CONNECT_TIMEOUT_SECONDS) and replace the literal with that constant (use 60L to
match the long timeout parameter), updating the restf.syncJsonPost invocation to
pass CONNECT_TIMEOUT_SECONDS so the timeout value is named and maintainable.
🪄 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: b6e3c009-3592-47e3-95af-69768cc1f3f7

📥 Commits

Reviewing files that changed from the base of the PR and between a621cf2 and 46d1102.

📒 Files selected for processing (2)
  • plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java
  • test/src/test/groovy/org/zstack/test/integration/storage/backup/sftp/SftpBackupStorageConnectTimeoutCase.groovy

Comment on lines +82 to +103
void testSftpConnectWithTimeout() {
env.simulator(SftpBackupStorageConstant.CONNECT_PATH) {
def rsp = new SftpBackupStorageCommands.ConnectResponse()
rsp.totalCapacity = SizeUnit.GIGABYTE.toByte(1000)
rsp.availableCapacity = SizeUnit.GIGABYTE.toByte(1000)
rsp.success = true
return rsp
}

BackupStorageInventory bs = addSftpBackupStorage {
name = "sftp-timeout-test"
description = "test SFTP connect with timeout"
username = "root"
password = "password"
hostname = "localhost"
url = "/data"
}

assert bs != null
assert bs.uuid != null
assert bs.status == "Connected"
}
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 | 🟠 Major | 🏗️ Heavy lift

当前用例未覆盖“超时触发失败并解除阻塞”的核心场景。

该测试只验证 CONNECT 正常返回时可连接成功;即使去掉超时参数,这个用例也会通过,无法证明 ZSTAC-67815 的关键修复生效。建议补充一个超时/不可达分支(例如让 CONNECT_PATH 延迟超过 60 秒),并断言请求在预期窗口内失败且不会造成后续操作长期阻塞。

🤖 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
`@test/src/test/groovy/org/zstack/test/integration/storage/backup/sftp/SftpBackupStorageConnectTimeoutCase.groovy`
around lines 82 - 103, Add a negative test branch to testSftpConnectWithTimeout
that simulates a CONNECT_PATH delay exceeding the 60s timeout: use
env.simulator(SftpBackupStorageConstant.CONNECT_PATH) to introduce a long
sleep/delay and return no successful ConnectResponse, then call
addSftpBackupStorage and assert it fails within the expected timeout
(throws/returns error) and does not block further operations (for example,
immediately perform another lightweight addSftpBackupStorage or query and assert
it succeeds). Ensure assertions reference the test method name
testSftpConnectWithTimeout, the simulator hook
SftpBackupStorageConstant.CONNECT_PATH, and the
addSftpBackupStorage/BackupStorageInventory flow so the failure and non-blocking
behavior are validated.

@MatheMatrix MatheMatrix force-pushed the sync/songtao.liu/fix/ZSTAC-67815-clean branch 2 times, most recently from baeb946 to b9c2f6c Compare May 28, 2026 06:04
Resolves: ZSTAC-67815
Change-Id: I2d789c3f4561ab78e90cd23ef45a678901234567
@MatheMatrix MatheMatrix force-pushed the sync/songtao.liu/fix/ZSTAC-67815-clean branch from b9c2f6c to c81ce08 Compare May 28, 2026 06:12
@MatheMatrix MatheMatrix deleted the sync/songtao.liu/fix/ZSTAC-67815-clean branch May 28, 2026 07:25
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