Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 优化分块上传uploadId 空异常处理 #2927 #2928

Merged
merged 5 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ enum class GenericMessageCode(private val businessCode: Int, private val key: St
PIPELINE_REPO_MANUAL_UPLOAD_NOT_ALLOWED(10, "generic.pipeline-repo.manual-upload.not-allowed"),
PIPELINE_ARTIFACT_PATH_ILLEGAL(11, "generic.pipeline.artifact.path.illegal"),
CHUNKED_ARTIFACT_BROKEN(12, "generic.chunked.artifact.broken"),
BLOCK_FILE_NODE_CREATE_FAIL(13, "generic.block.file.node.create.fail"),
BLOCK_UPLOADID_ERROR(13, "generic.block.uploadId.error"),
BLOCK_HEAD_NOT_FOUND(14, "generic.block.node.head.not-found"),
BLOCK_UPDATE_LIST_IS_NULL(15, "generic.block.update.list.is.null")
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ import com.tencent.bkrepo.generic.constant.BKREPO_META
import com.tencent.bkrepo.generic.constant.BKREPO_META_PREFIX
import com.tencent.bkrepo.generic.constant.CHUNKED_UPLOAD
import com.tencent.bkrepo.generic.constant.GenericMessageCode
import com.tencent.bkrepo.generic.constant.HEADER_BLOCK_APPEND
import com.tencent.bkrepo.generic.constant.HEADER_EXPIRES
import com.tencent.bkrepo.generic.constant.HEADER_MD5
import com.tencent.bkrepo.generic.constant.HEADER_OFFSET
import com.tencent.bkrepo.generic.constant.HEADER_OVERWRITE
import com.tencent.bkrepo.generic.constant.HEADER_SEQUENCE
import com.tencent.bkrepo.generic.constant.HEADER_SHA256
import com.tencent.bkrepo.generic.constant.HEADER_SIZE
import com.tencent.bkrepo.generic.constant.HEADER_UPLOAD_ID
import com.tencent.bkrepo.generic.constant.HEADER_UPLOAD_TYPE
import com.tencent.bkrepo.generic.constant.HEADER_OFFSET
import com.tencent.bkrepo.generic.constant.HEADER_SIZE
import com.tencent.bkrepo.generic.constant.HEADER_OVERWRITE
import com.tencent.bkrepo.generic.constant.HEADER_BLOCK_APPEND
import com.tencent.bkrepo.generic.constant.HEADER_EXPIRES
import com.tencent.bkrepo.generic.constant.SEPARATE_UPLOAD
import com.tencent.bkrepo.generic.pojo.ChunkedResponseProperty
import com.tencent.bkrepo.generic.pojo.SeparateBlockInfo
Expand Down Expand Up @@ -186,6 +186,9 @@ class GenericLocalRepository(

when {
isSeparateUpload(uploadType) -> {
if (uploadId.isNullOrEmpty()) {
throw ErrorCodeException(GenericMessageCode.BLOCK_UPLOADID_ERROR, uploadId)
}
onSeparateUpload(context, uploadId)
}
isBlockUpload(uploadId, sequence) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.tencent.bkrepo.common.api.constant.StringPool
import com.tencent.bkrepo.common.api.exception.BadRequestException
import com.tencent.bkrepo.common.api.exception.ErrorCodeException
import com.tencent.bkrepo.common.api.message.CommonMessageCode
import com.tencent.bkrepo.common.api.util.Preconditions
import com.tencent.bkrepo.common.artifact.api.ArtifactFile
import com.tencent.bkrepo.common.artifact.message.ArtifactMessageCode
import com.tencent.bkrepo.common.artifact.pojo.RepositoryCategory
Expand Down Expand Up @@ -98,9 +99,9 @@ class UploadService(

fun startBlockUpload(userId: String, artifactInfo: GenericArtifactInfo): UploadTransactionInfo {
with(artifactInfo) {

val expires = getLongHeader(HEADER_EXPIRES)
val overwrite = getBooleanHeader(HEADER_OVERWRITE)

Preconditions.checkArgument(expires >= 0, "expires")
// 判断文件是否存在
if (!overwrite && nodeService.checkExist(this)) {
logger.warn(
Expand All @@ -117,7 +118,7 @@ class UploadService(
}
val uploadTransaction = UploadTransactionInfo(
uploadId = uploadId,
expireSeconds = TRANSACTION_EXPIRES
expireSeconds = expires
)

logger.info("User[${SecurityUtils.getPrincipal()}] start block upload [$artifactInfo] success: $uploadId.")
Expand All @@ -132,8 +133,6 @@ class UploadService(

val node = nodeService.getNodeDetail(this)

val expires = getLongHeader(HEADER_EXPIRES).takeIf { it > 0 } ?: TRANSACTION_EXPIRES

val oldNodeId = node?.nodeInfo?.id ?: FAKE_SEPARATE
// 如果不允许覆盖且节点已经存在,抛出异常
if (node != null && !overwrite) {
Expand All @@ -146,7 +145,7 @@ class UploadService(
// 创建上传事务信息,设置过期时间
val uploadTransaction = UploadTransactionInfo(
uploadId = uploadId,
expireSeconds = expires
expireSeconds = TRANSACTION_EXPIRES
)
// 记录上传启动的日志
logger.info(
Expand Down Expand Up @@ -201,6 +200,9 @@ class UploadService(
}

fun abortSeparateBlockUpload(userId: String, uploadId: String, artifactInfo: GenericArtifactInfo) {

checkUploadIdIsEmpty(uploadId)

blockNodeService.deleteBlocks(
artifactInfo.projectId,
artifactInfo.repoName,
Expand Down Expand Up @@ -256,11 +258,17 @@ class UploadService(

fun completeSeparateBlockUpload(userId: String, uploadId: String, artifactInfo: GenericArtifactInfo) {

checkUploadIdIsEmpty(uploadId)

val projectId = artifactInfo.projectId
val repoName = artifactInfo.repoName
val artifactFullPath = artifactInfo.getArtifactFullPath()

// 获取并按起始位置排序块信息列表
val blockInfoList = blockNodeService.listBlocksInUploadId(
artifactInfo.projectId,
artifactInfo.repoName,
artifactInfo.getArtifactFullPath(),
projectId,
repoName,
artifactFullPath,
uploadId = uploadId
)

Expand Down Expand Up @@ -291,25 +299,24 @@ class UploadService(

// 删除旧Block
blockNodeService.deleteBlocks(
artifactInfo.projectId,
artifactInfo.repoName,
artifactInfo.getArtifactFullPath()
projectId,
repoName,
artifactFullPath
)

// 更新节点版本信息为null
blockNodeService.updateBlockUploadId(
artifactInfo.projectId,
artifactInfo.repoName,
artifactInfo.getArtifactFullPath(),
projectId,
repoName,
artifactFullPath,
uploadId
)

// 上传完成,记录日志
logger.info(
"User [$userId] successfully completed block upload [uploadId: $uploadId], " +
"file path [${artifactInfo.getArtifactFullPath()}]."
"file path [${artifactFullPath}]."
)

}

fun listBlock(userId: String, uploadId: String, artifactInfo: GenericArtifactInfo): List<BlockInfo> {
Expand All @@ -328,6 +335,8 @@ class UploadService(
artifactInfo: GenericArtifactInfo
): List<SeparateBlockInfo> {

checkUploadIdIsEmpty(uploadId)

val blockInfoList = blockNodeService.listBlocksInUploadId(
artifactInfo.projectId,
artifactInfo.repoName,
Expand All @@ -346,6 +355,13 @@ class UploadService(
}
}

private fun checkUploadIdIsEmpty(uploadId: String) {
// 检查uploadId是否为空""
if (uploadId.isEmpty()) {
throw ErrorCodeException(GenericMessageCode.BLOCK_UPLOADID_ERROR, uploadId)
}
}

private fun getStorageCredentials(artifactInfo: GenericArtifactInfo): StorageCredentials? {
with(artifactInfo) {
val repoDetail = repositoryService.getRepoDetail(projectId, repoName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ generic.pipeline-repo.manual-upload.not-allowed=Manual upload to pipeline reposi
generic.pipeline.metadata.incomplete=Pipeline metadata is incomplete. {0} is missing
generic.pipeline.artifact.path.illegal=Note: The path parameter is incorrect. The specified file[{0}] belongs to the artifact of the pipeline repository[{1}]
generic.chunked.artifact.broken=Chunked artifact broken
generic.block.file.node.create.fail=Block file information node [{0}] is not created or the version is inconsistent
generic.block.uploadId.error=The value of UploadId [{0}] is null or empty. Check whether uploadId in the request header is correct
generic.block.node.head.not-found=Both HEADER_OFFSET and HEADER_FILE_SIZE are null.
generic.block.update.list.is.null=The update list blocks is the empty
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ generic.pipeline-repo.manual-upload.not-allowed=禁止手动上传到流水线
generic.pipeline.metadata.incomplete=流水线元数据不完整. 缺少{0}
generic.pipeline.artifact.path.illegal=注意:path参数出错,指定文件[{0}]属于流水线仓库[{1}]的制品
generic.chunked.artifact.broken=分块上传制品文件已损坏
generic.block.file.node.create.fail=分块文件信息节点[{0}]未创建或版本不一致
generic.block.uploadId.error=UploadId [{0}] 为 null or empty,请检查请求头中uploadId是否正确
generic.block.node.head.not-found=请求头HEADER_OFFSET和HEADER_FILE_SIZE不可为空
generic.block.update.list.is.null=更新分块列表为空
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ generic.pipeline-repo.manual-upload.not-allowed=禁止手動上傳到流水線
generic.pipeline.metadata.incomplete=流水線元數據不完整,缺少{0}
generic.pipeline.artifact.path.illegal=注意:path參數出錯,指定文件[{0}]屬於流水線倉庫[{1}]的製品
generic.chunked.artifact.broken=製品已損壞
generic.block.file.node.create.fail=分塊文件信息節點[{0}]未創建或版本不一致
generic.block.uploadId.error=UploadId [{0}] 為 null 或空,請檢查請求頭中 uploadId 是否正確。
generic.block.node.head.not-found=請求頭 HEADER_OFFSET 和 HEADER_FILE_SIZE 不可為空
generic.block.update.list.is.null=更新分塊列表為空
Loading