diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt index b036f747d35..f4a404cb323 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt @@ -279,6 +279,8 @@ object ProcessMessageCode { const val MAXIMUM_NUMBER_CONCURRENCY_ILLEGAL = "2101178" // 最大并发数量非法 const val PIPELINE_BUILD_HAS_ENDED_CANNOT_BE_CANCELED = "2101179" // 流水线: 流水线构建已结束,不能取消 const val GET_PIPELINE_ATOM_INFO_NO_PERMISSION = "2101180" // 无权访问插件{0}的流水线信息,请联系组件管理员 + const val GROUP_IS_EXIST = "2101181" // 分组({0})已存在/group ({0}) is already exist + const val GROUP_LABEL_IS_EXIST = "2101182" // 分组标签({0})已存在/group label ({0}) is already exist const val BK_SUCCESSFULLY_DISTRIBUTED = "bkSuccessfullyDistributed" // 跨项目构件分发成功,共分发了{0}个文件 const val BK_SUCCESSFULLY_FAILED = "bkSuccessfullyFailed" // 跨项目构件分发失败, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineGroupDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineGroupDao.kt index a6c1792532c..7ad7adacfce 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineGroupDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineGroupDao.kt @@ -29,11 +29,11 @@ package com.tencent.devops.process.dao.label import com.tencent.devops.model.process.tables.TPipelineGroup import com.tencent.devops.model.process.tables.records.TPipelineGroupRecord +import java.time.LocalDateTime import org.jooq.DSLContext import org.jooq.Result import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository -import java.time.LocalDateTime /** * 用户分组管理 @@ -129,6 +129,19 @@ class PipelineGroupDao { } } + fun countByName( + dslContext: DSLContext, + projectId: String, + name: String + ): Long { + with(TPipelineGroup.T_PIPELINE_GROUP) { + return dslContext.selectCount().from(this) + .where(PROJECT_ID.eq(projectId)) + .and(NAME.eq(name)) + .fetchOne(0, Long::class.java)!! + } + } + fun get(dslContext: DSLContext, id: Long): TPipelineGroupRecord? { with(TPipelineGroup.T_PIPELINE_GROUP) { return dslContext.selectFrom(this) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineLabelDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineLabelDao.kt index 36075dc1254..535c3224111 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineLabelDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/label/PipelineLabelDao.kt @@ -29,11 +29,11 @@ package com.tencent.devops.process.dao.label import com.tencent.devops.model.process.tables.TPipelineLabel import com.tencent.devops.model.process.tables.records.TPipelineLabelRecord +import java.time.LocalDateTime import org.jooq.DSLContext import org.jooq.Result import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository -import java.time.LocalDateTime /** * 流水线标签 @@ -136,6 +136,19 @@ class PipelineLabelDao { } } + fun countByGroupName( + dslContext: DSLContext, + projectId: String, + groupId: Long, + name: String + ): Long { + with(TPipelineLabel.T_PIPELINE_LABEL) { + return dslContext.selectCount().from(this) + .where(GROUP_ID.eq(groupId).and(PROJECT_ID.eq(projectId)).and(NAME.eq(name))) + .fetchOne(0, Long::class.java)!! + } + } + fun getByGroupIds( dslContext: DSLContext, projectId: String, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/label/PipelineGroupService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/label/PipelineGroupService.kt index c210effe1d7..8e2ccccbafb 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/label/PipelineGroupService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/label/PipelineGroupService.kt @@ -38,9 +38,11 @@ import com.tencent.devops.common.event.pojo.measure.PipelineLabelRelateInfo import com.tencent.devops.model.process.tables.records.TPipelineFavorRecord import com.tencent.devops.model.process.tables.records.TPipelineGroupRecord import com.tencent.devops.model.process.tables.records.TPipelineLabelRecord +import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.constant.ProcessMessageCode.ERROR_GROUP_COUNT_EXCEEDS_LIMIT -import com.tencent.devops.process.constant.ProcessMessageCode.ERROR_LABEL_COUNT_EXCEEDS_LIMIT import com.tencent.devops.process.constant.ProcessMessageCode.ERROR_LABEL_NAME_TOO_LONG +import com.tencent.devops.process.constant.ProcessMessageCode.GROUP_IS_EXIST +import com.tencent.devops.process.constant.ProcessMessageCode.GROUP_LABEL_IS_EXIST import com.tencent.devops.process.dao.PipelineFavorDao import com.tencent.devops.process.dao.label.PipelineGroupDao import com.tencent.devops.process.dao.label.PipelineLabelDao @@ -55,16 +57,14 @@ import com.tencent.devops.process.pojo.classify.PipelineLabelCreate import com.tencent.devops.process.pojo.classify.PipelineLabelUpdate import com.tencent.devops.process.service.measure.MeasureEventDispatcher import com.tencent.devops.project.api.service.ServiceAllocIdResource +import java.time.LocalDateTime import org.jooq.DSLContext import org.jooq.Result import org.jooq.impl.DSL import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired -import org.springframework.dao.DataAccessException import org.springframework.dao.DuplicateKeyException import org.springframework.stereotype.Service -import java.sql.SQLIntegrityConstraintViolationException -import java.time.LocalDateTime @Suppress("ALL") @Service @@ -137,46 +137,48 @@ class PipelineGroupService @Autowired constructor( } fun addGroup(userId: String, pipelineGroup: PipelineGroupCreate): Boolean { - try { - val groupCount = pipelineGroupDao.count(dslContext = dslContext, projectId = pipelineGroup.projectId) - if (groupCount >= MAX_GROUP_UNDER_PROJECT) { - throw ErrorCodeException( - errorCode = ERROR_GROUP_COUNT_EXCEEDS_LIMIT, - defaultMessage = "At most $MAX_GROUP_UNDER_PROJECT label groups under a project" - ) - } - val id = client.get(ServiceAllocIdResource::class).generateSegmentId("PIPELINE_GROUP").data - pipelineGroupDao.create( - dslContext = dslContext, - projectId = pipelineGroup.projectId, - name = pipelineGroup.name, - userId = userId, - id = id + val count = pipelineGroupDao.countByName(dslContext, pipelineGroup.projectId, pipelineGroup.name) + if (count >= 1) { + logger.warn("Fail to create the group $pipelineGroup by userId $userId") + throw ErrorCodeException( + errorCode = GROUP_IS_EXIST, + params = arrayOf("${pipelineGroup.projectId}-${pipelineGroup.name}") ) - } catch (t: DataAccessException) { - if (t.cause is SQLIntegrityConstraintViolationException) { - logger.warn("Fail to create the group $pipelineGroup by userId $userId") - throw OperationException("The group is already exist") - } else throw t } + val groupCount = pipelineGroupDao.count(dslContext = dslContext, projectId = pipelineGroup.projectId) + if (groupCount >= MAX_GROUP_UNDER_PROJECT) { + throw ErrorCodeException( + errorCode = ERROR_GROUP_COUNT_EXCEEDS_LIMIT, + defaultMessage = "At most $MAX_GROUP_UNDER_PROJECT label groups under a project" + ) + } + val id = client.get(ServiceAllocIdResource::class).generateSegmentId("PIPELINE_GROUP").data + pipelineGroupDao.create( + dslContext = dslContext, + projectId = pipelineGroup.projectId, + name = pipelineGroup.name, + userId = userId, + id = id + ) return true } fun updateGroup(userId: String, pipelineGroup: PipelineGroupUpdate): Boolean { - try { - return pipelineGroupDao.update( - dslContext = dslContext, - projectId = pipelineGroup.projectId, - groupId = decode(pipelineGroup.id), - name = pipelineGroup.name, - userId = userId + val count = pipelineGroupDao.countByName(dslContext, pipelineGroup.projectId, pipelineGroup.name) + if (count >= 1) { + logger.warn("Fail to create the group $pipelineGroup by userId $userId") + throw ErrorCodeException( + errorCode = GROUP_IS_EXIST, + params = arrayOf("${pipelineGroup.projectId}-${pipelineGroup.name}") ) - } catch (t: DataAccessException) { - if (t.cause is SQLIntegrityConstraintViolationException) { - logger.warn("Fail to create the group $pipelineGroup by userId $userId") - throw OperationException("The group is already exist") - } else throw t } + return pipelineGroupDao.update( + dslContext = dslContext, + projectId = pipelineGroup.projectId, + groupId = decode(pipelineGroup.id), + name = pipelineGroup.name, + userId = userId + ) } fun deleteGroup(userId: String, projectId: String, groupId: String): Boolean { @@ -200,39 +202,46 @@ class PipelineGroupService @Autowired constructor( } fun addLabel(userId: String, projectId: String, pipelineLabel: PipelineLabelCreate): Boolean { - try { - val groupId = decode(pipelineLabel.groupId) - val labelCount = pipelineLabelDao.countByGroupId( - dslContext = dslContext, - projectId = projectId, - groupId = groupId + val groupId = decode(pipelineLabel.groupId) + val labelNameCount = pipelineLabelDao.countByGroupName( + dslContext = dslContext, + projectId = projectId, + groupId = groupId, + name = pipelineLabel.name + ) + if (labelNameCount >= 1) { + logger.warn("Fail to add the label $pipelineLabel by userId $userId") + throw ErrorCodeException( + errorCode = GROUP_LABEL_IS_EXIST, + params = arrayOf("${pipelineLabel.groupId}-${pipelineLabel.name}") ) - if (labelCount >= MAX_LABEL_UNDER_GROUP) { - throw ErrorCodeException( - errorCode = ERROR_LABEL_COUNT_EXCEEDS_LIMIT, - defaultMessage = "No more than $MAX_LABEL_UNDER_GROUP labels under a label group" - ) - } - if (pipelineLabel.name.length > MAX_LABEL_NAME_LENGTH) { - throw ErrorCodeException( - errorCode = ERROR_LABEL_NAME_TOO_LONG, - defaultMessage = "label name cannot exceed $MAX_LABEL_NAME_LENGTH characters" - ) - } - val id = client.get(ServiceAllocIdResource::class).generateSegmentId("PIPELINE_LABEL").data - pipelineLabelDao.create( - dslContext = dslContext, - projectId = projectId, - groupId = groupId, - name = pipelineLabel.name, - userId = userId, - id = id + } + val labelCount = pipelineLabelDao.countByGroupId( + dslContext = dslContext, + projectId = projectId, + groupId = groupId + ) + if (labelCount >= MAX_LABEL_UNDER_GROUP) { + throw ErrorCodeException( + errorCode = ProcessMessageCode.ERROR_LABEL_COUNT_EXCEEDS_LIMIT, + defaultMessage = "No more than $MAX_LABEL_UNDER_GROUP labels under a label group" ) - } catch (t: DuplicateKeyException) { - logger.warn("Fail to add the label $pipelineLabel by userId $userId") - throw OperationException("The label is already exist") } - + if (pipelineLabel.name.length > MAX_LABEL_NAME_LENGTH) { + throw ErrorCodeException( + errorCode = ERROR_LABEL_NAME_TOO_LONG, + defaultMessage = "label name cannot exceed $MAX_LABEL_NAME_LENGTH characters" + ) + } + val id = client.get(ServiceAllocIdResource::class).generateSegmentId("PIPELINE_LABEL").data + pipelineLabelDao.create( + dslContext = dslContext, + projectId = projectId, + groupId = groupId, + name = pipelineLabel.name, + userId = userId, + id = id + ) return true } @@ -265,43 +274,52 @@ class PipelineGroupService @Autowired constructor( } fun updateLabel(userId: String, projectId: String, pipelineLabel: PipelineLabelUpdate): Boolean { - try { - if (pipelineLabel.name.length > MAX_LABEL_NAME_LENGTH) { - throw ErrorCodeException( - errorCode = ERROR_LABEL_NAME_TOO_LONG, - defaultMessage = "label name cannot exceed $MAX_LABEL_NAME_LENGTH characters" - ) - } - val result = pipelineLabelDao.update( - dslContext = dslContext, - projectId = projectId, - labelId = decode(pipelineLabel.id), - name = pipelineLabel.name, - userId = userId + val groupId = decode(pipelineLabel.groupId) + val labelNameCount = pipelineLabelDao.countByGroupName( + dslContext = dslContext, + projectId = projectId, + groupId = groupId, + name = pipelineLabel.name + ) + if (labelNameCount >= 1) { + logger.warn("Fail to add the label $pipelineLabel by userId $userId") + throw ErrorCodeException( + errorCode = GROUP_LABEL_IS_EXIST, + params = arrayOf("${pipelineLabel.groupId}-${pipelineLabel.name}") ) - if (result) { - measureEventDispatcher.dispatch( - LabelChangeMetricsBroadCastEvent( - projectId = projectId, - userId = userId, - type = PipelineLabelChangeTypeEnum.UPDATE, - statisticsTime = LocalDateTime.now(), - pipelineLabelRelateInfos = listOf( - PipelineLabelRelateInfo( - projectId = projectId, - labelId = decode(pipelineLabel.id), - name = pipelineLabel.name - ) + } + if (pipelineLabel.name.length > MAX_LABEL_NAME_LENGTH) { + throw ErrorCodeException( + errorCode = ERROR_LABEL_NAME_TOO_LONG, + defaultMessage = "label name cannot exceed $MAX_LABEL_NAME_LENGTH characters" + ) + } + val result = pipelineLabelDao.update( + dslContext = dslContext, + projectId = projectId, + labelId = decode(pipelineLabel.id), + name = pipelineLabel.name, + userId = userId + ) + if (result) { + measureEventDispatcher.dispatch( + LabelChangeMetricsBroadCastEvent( + projectId = projectId, + userId = userId, + type = PipelineLabelChangeTypeEnum.UPDATE, + statisticsTime = LocalDateTime.now(), + pipelineLabelRelateInfos = listOf( + PipelineLabelRelateInfo( + projectId = projectId, + labelId = decode(pipelineLabel.id), + name = pipelineLabel.name ) ) ) - logger.info("LableChangeMetricsBroadCastEvent: updateLabel $projectId|${decode(pipelineLabel.id)}") - } - return result - } catch (t: DuplicateKeyException) { - logger.warn("Fail to update the label $pipelineLabel by userId $userId") - throw OperationException("The label is already exist") + ) + logger.info("LableChangeMetricsBroadCastEvent: updateLabel $projectId|${decode(pipelineLabel.id)}") } + return result } fun deletePipelineLabel(userId: String, projectId: String, pipelineId: String) { diff --git a/support-files/i18n/process/message_en_US.properties b/support-files/i18n/process/message_en_US.properties index 95e46f05f6e..7d5c928eea0 100644 --- a/support-files/i18n/process/message_en_US.properties +++ b/support-files/i18n/process/message_en_US.properties @@ -178,6 +178,8 @@ 2101178=Illegal maximum number of concurrency 2101179=Pipeline: pipeline build has ended and cannot be canceled 2101180=You do not have access to the pipeline information for plugin {0}. Please contact the component administrator. +2101181=group ({0}) is already exist +2101182=group label ({0}) is already exist ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=Currently build ID BK_CI_BUILD_JOB_ID=Pipelined JOB ID diff --git a/support-files/i18n/process/message_zh_CN.properties b/support-files/i18n/process/message_zh_CN.properties index edfeace52c8..ad6ca666b3b 100644 --- a/support-files/i18n/process/message_zh_CN.properties +++ b/support-files/i18n/process/message_zh_CN.properties @@ -178,6 +178,8 @@ 2101178=最大并发数量非法 2101179=流水线: 流水线构建已结束,不能取消 2101180=无权访问插件{0}的流水线信息,请联系组件管理员 +2101181=分组({0})已存在 +2101182=分组标签({0})已存在 ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=当前构建ID BK_CI_BUILD_JOB_ID=流水线JOB ID