From d087529ac09ad3e8cb9e63c75465ad7799074736 Mon Sep 17 00:00:00 2001 From: wangyu096 Date: Mon, 6 Jan 2025 16:12:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Job=20=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=20#3369?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job/common/cc/sdk/BaseCmdbApiClient.java | 12 +- .../i18n/exception/message.properties | 3 +- .../i18n/exception/message_en.properties | 3 +- .../i18n/exception/message_en_US.properties | 2 +- .../i18n/exception/message_zh.properties | 3 +- .../i18n/exception/message_zh_CN.properties | 3 +- ...{EsbIamClient.java => EsbIamV1Client.java} | 10 +- .../iam/service/impl/AppAuthServiceImpl.java | 6 +- .../iam/service/impl/AuthServiceImpl.java | 10 +- .../bk/job/common/constant/ErrorCode.java | 10 +- .../job/common/constant/JobCommonHeaders.java | 5 + .../common/constant/TenantIdConstants.java | 17 ++ .../job/common/metrics/CommonMetricNames.java | 8 +- .../bk/job/common/model/dto/BkUserDTO.java | 11 + .../tenant/TenantAutoConfiguration.java | 39 ++++ .../job/common/tenant/TenantEnvService.java | 31 +++ .../job/common/tenant/TenantProperties.java | 44 ++++ .../main/resources/META-INF/spring.factories | 3 +- .../esb/config/BkApiGatewayProperties.java | 10 + .../common/esb/constants/BkErrorCodeEnum.java | 120 ++++++++++ .../esb/exception/BkOpenApiException.java | 43 ++++ .../bk/job/common/esb/model/EsbResp.java | 6 +- .../bk/job/common/esb/model/OpenApiError.java | 73 ++++++ .../common/esb/model/OpenApiRequestInfo.java | 20 ++ .../job/common/esb/model/OpenApiResponse.java | 36 +++ .../job/common/esb/model/OpenApiV1Error.java | 33 +++ ...TO.java => OpenApiApplyPermissionDTO.java} | 2 +- ...{BkApiClient.java => BaseBkApiClient.java} | 211 +++++++----------- .../bk/job/common/esb/sdk/BkApiContext.java | 5 +- .../bk/job/common/esb/sdk/BkApiV1Client.java | 95 ++++++++ .../bk/job/common/esb/sdk/BkApiV2Client.java | 72 ++++++ .../tencent/bk/job/common/gse/GseClient.java | 6 +- .../gse/config/GseAutoConfiguration.java | 4 +- .../service/GseV2AgentStateClientImpl.java | 4 +- ...V2ApiClient.java => GseV2ApiV1Client.java} | 10 +- .../common/gse/v2/GseV2AutoConfiguration.java | 8 +- .../config/NoticeAutoConfiguration.java | 10 +- ...oticeClient.java => BkNoticeV1Client.java} | 22 +- ...msiApiClient.java => CmsiApiV1Client.java} | 10 +- .../paas/config/CmsiAutoConfiguration.java | 10 +- .../paas/config/LoginAutoConfiguration.java | 23 +- .../paas/config/UserMgrAutoConfiguration.java | 15 +- .../paas/login/StandardLoginClient.java | 102 ++------- .../paas/login/v3/BkLoginApiClient.java | 112 ++++++++++ .../common/paas/login/v3/OpenApiBkUser.java | 43 ++++ .../job/common/paas/model/OpenApiTenant.java | 27 +++ .../common/paas/model/TenantStatusEnum.java | 40 ++++ .../common/paas/user/UserMgrApiClient.java | 83 +++++-- .../bk/job/execute/config/GseConfig.java | 4 +- .../src/main/resources/logback-spring.xml | 8 +- .../src/test/resources/application-test.yml | 3 + .../bk/job/manage/config/GseConfig.java | 4 +- .../config/listener/NotifyInitListener.java | 6 +- .../notify/impl/NotifyEsbChannelDAOImpl.java | 6 +- .../impl/ScopeAgentStatusServiceImpl.java | 6 +- .../service/impl/WatchableSendMsgService.java | 6 +- .../bk/job/manage/task/ScheduledTasks.java | 3 +- .../bk/job/upgrader/iam/ApiClientUtils.java | 6 +- ...gePublicScriptPermissionMigrationTask.java | 6 +- .../UseAccountPermissionMigrationTask.java | 6 +- ...job_manage_20250103-1000_V3.12.0_mysql.sql | 37 +++ 61 files changed, 1214 insertions(+), 362 deletions(-) rename src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/{EsbIamClient.java => EsbIamV1Client.java} (96%) create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantAutoConfiguration.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantEnvService.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantProperties.java create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/constants/BkErrorCodeEnum.java create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/exception/BkOpenApiException.java create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiError.java create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiResponse.java create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiV1Error.java rename src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/{EsbApplyPermissionDTO.java => OpenApiApplyPermissionDTO.java} (97%) rename src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/{BkApiClient.java => BaseBkApiClient.java} (62%) create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV1Client.java create mode 100644 src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV2Client.java rename src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/{GseV2ApiClient.java => GseV2ApiV1Client.java} (97%) rename src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/{BkNoticeClient.java => BkNoticeV1Client.java} (89%) rename src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/{CmsiApiClient.java => CmsiApiV1Client.java} (96%) create mode 100644 src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/BkLoginApiClient.java create mode 100644 src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/OpenApiBkUser.java create mode 100644 src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/OpenApiTenant.java create mode 100644 src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/TenantStatusEnum.java create mode 100644 support-files/sql/job-manage/0032_job_manage_20250103-1000_V3.12.0_mysql.sql diff --git a/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/sdk/BaseCmdbApiClient.java b/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/sdk/BaseCmdbApiClient.java index eea37a52f0..b43c78cdb3 100644 --- a/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/sdk/BaseCmdbApiClient.java +++ b/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/sdk/BaseCmdbApiClient.java @@ -37,7 +37,7 @@ import com.tencent.bk.job.common.esb.model.EsbReq; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; +import com.tencent.bk.job.common.esb.sdk.BkApiV1Client; import com.tencent.bk.job.common.exception.InternalCmdbException; import com.tencent.bk.job.common.exception.InternalException; import com.tencent.bk.job.common.metrics.CommonMetricNames; @@ -101,11 +101,11 @@ public class BaseCmdbApiClient { /** * CMDB ESB API 客户端 */ - protected BkApiClient esbCmdbApiClient; + protected BkApiV1Client esbCmdbApiClient; /** * CMDB 蓝鲸网关 API 客户端 */ - protected BkApiClient apiGwCmdbApiClient; + protected BkApiV1Client apiGwCmdbApiClient; static { interfaceNameMap.put(SEARCH_BIZ_INST_TOPO, "search_biz_inst_topo"); @@ -136,14 +136,14 @@ protected BaseCmdbApiClient(FlowController flowController, MeterRegistry meterRegistry, String lang) { WatchableHttpHelper httpHelper = HttpHelperFactory.getRetryableHttpHelper(); - this.esbCmdbApiClient = new BkApiClient(meterRegistry, + this.esbCmdbApiClient = new BkApiV1Client(meterRegistry, CmdbMetricNames.CMDB_API_PREFIX, esbProperties.getService().getUrl(), httpHelper, lang ); this.esbCmdbApiClient.setLogger(LoggerFactory.getLogger(this.getClass())); - this.apiGwCmdbApiClient = new BkApiClient(meterRegistry, + this.apiGwCmdbApiClient = new BkApiV1Client(meterRegistry, CmdbMetricNames.CMDB_API_PREFIX, bkApiGatewayProperties.getCmdb().getUrl(), httpHelper, @@ -218,7 +218,7 @@ protected EsbResp requestCmdbApi(ApiGwType apiGwType, } } - private BkApiClient getApiClientByApiGwType(ApiGwType apiGwType) { + private BkApiV1Client getApiClientByApiGwType(ApiGwType apiGwType) { switch (apiGwType) { case ESB: return esbCmdbApiClient; diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties index 65f76cb227..a572087b79 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties @@ -63,9 +63,10 @@ 1211003=根据动态分组 ID 查找主机失败,动态分组 ID :{0},原因:{1},请确认指定的动态分组在业务下是否存在 1211004=根据业务ID查找动态分组失败,业务 ID :{0},原因:{1},请确认指定的业务是否存在动态分组 1213001=CMSI 接口访问异常 -1213002=用户管理接口访问异常 1213003=调用 CMSI 接口获取通知渠道数据异常 1213004=调用 CMSI 接口发送通知失败,错误码:{0},错误信息:{1} +1219001=蓝鲸登录接口访问异常 +1220001=用户管理接口访问异常 1214001=ARTIFACTORY API 返回数据异常 1214002=制品库中找不到节点:{0},请到制品库核实 diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties index 3721e11e79..cfcfcabfb4 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties @@ -63,9 +63,10 @@ 1211003=Fail to find host by dynamic group, id:{0}, reason:{1}, please confirm the specified dynamic group in business 1211004=Fail to find dynamic group by biz, id:{0}, reason:{1}, please confirm dynamic group in the specified business 1213001=Fail to request CMSI API -1213002=Fail to request UserManage API 1213003=CMSI exception when get notify channels 1213004=CMSI exception when send notify, error_code={0}, error_msg={1} +1219001=Fail to request bk-login API +1220001=Fail to request bk-user-manage API 1214001=ARTIFACTORY API returned data exception 1214002=Cannot find node in bkrepo:{0}, please check in bkrepo diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties index 3721e11e79..3e541da597 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties @@ -63,9 +63,9 @@ 1211003=Fail to find host by dynamic group, id:{0}, reason:{1}, please confirm the specified dynamic group in business 1211004=Fail to find dynamic group by biz, id:{0}, reason:{1}, please confirm dynamic group in the specified business 1213001=Fail to request CMSI API -1213002=Fail to request UserManage API 1213003=CMSI exception when get notify channels 1213004=CMSI exception when send notify, error_code={0}, error_msg={1} +1220001=Fail to request bk-user-manage API 1214001=ARTIFACTORY API returned data exception 1214002=Cannot find node in bkrepo:{0}, please check in bkrepo diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties index 65f76cb227..a572087b79 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties @@ -63,9 +63,10 @@ 1211003=根据动态分组 ID 查找主机失败,动态分组 ID :{0},原因:{1},请确认指定的动态分组在业务下是否存在 1211004=根据业务ID查找动态分组失败,业务 ID :{0},原因:{1},请确认指定的业务是否存在动态分组 1213001=CMSI 接口访问异常 -1213002=用户管理接口访问异常 1213003=调用 CMSI 接口获取通知渠道数据异常 1213004=调用 CMSI 接口发送通知失败,错误码:{0},错误信息:{1} +1219001=蓝鲸登录接口访问异常 +1220001=用户管理接口访问异常 1214001=ARTIFACTORY API 返回数据异常 1214002=制品库中找不到节点:{0},请到制品库核实 diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties index eb820bfee7..2846c9ddd1 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties @@ -63,9 +63,10 @@ 1211003=根据动态分组 ID 查找主机失败,动态分组 ID :{0},原因:{1},请确认指定的动态分组在业务下是否存在 1211004=根据业务ID查找动态分组失败,业务 ID :{0},原因:{1},请确认指定的业务是否存在动态分组 1213001=CMSI 接口访问异常 -1213002=用户管理接口访问异常 1213003=调用 CMSI 接口获取通知渠道数据异常 1213004=调用 CMSI 接口发送通知失败,错误码:{0},错误信息:{1} +1219001=蓝鲸登录接口访问异常 +1220001=用户管理接口访问异常 1214001=ARTIFACTORY API 返回数据异常 1214002=制品库中找不到节点:{0},请到制品库核实 diff --git a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/EsbIamClient.java b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/EsbIamV1Client.java similarity index 96% rename from src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/EsbIamClient.java rename to src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/EsbIamV1Client.java index 7de3a870d7..9e0b80a4ce 100644 --- a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/EsbIamClient.java +++ b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/client/EsbIamV1Client.java @@ -33,7 +33,7 @@ import com.tencent.bk.job.common.esb.model.EsbReq; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; +import com.tencent.bk.job.common.esb.sdk.BkApiV1Client; import com.tencent.bk.job.common.exception.InternalIamException; import com.tencent.bk.job.common.iam.dto.AuthByPathReq; import com.tencent.bk.job.common.iam.dto.BatchAuthByPathReq; @@ -64,7 +64,7 @@ * IAM API 调用客户端 */ @Slf4j -public class EsbIamClient extends BkApiClient implements IIamClient { +public class EsbIamV1Client extends BkApiV1Client implements IIamClient { private static final String API_GET_APPLY_URL = "/api/c/compapi/v2/iam/application/"; private static final String API_REGISTER_RESOURCE_URL = @@ -76,9 +76,9 @@ public class EsbIamClient extends BkApiClient implements IIamClient { private final BkApiAuthorization authorization; - public EsbIamClient(MeterRegistry meterRegistry, - AppProperties appProperties, - EsbProperties esbProperties) { + public EsbIamV1Client(MeterRegistry meterRegistry, + AppProperties appProperties, + EsbProperties esbProperties) { super( meterRegistry, IAM_API, diff --git a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java index 95bf443960..b74275e87b 100644 --- a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java +++ b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java @@ -27,7 +27,7 @@ import com.tencent.bk.job.common.constant.ResourceScopeTypeEnum; import com.tencent.bk.job.common.esb.config.AppProperties; import com.tencent.bk.job.common.esb.config.EsbProperties; -import com.tencent.bk.job.common.iam.client.EsbIamClient; +import com.tencent.bk.job.common.iam.client.EsbIamV1Client; import com.tencent.bk.job.common.iam.config.JobIamProperties; import com.tencent.bk.job.common.iam.constant.ActionId; import com.tencent.bk.job.common.iam.constant.ResourceTypeEnum; @@ -68,7 +68,7 @@ public class AppAuthServiceImpl extends BasicAuthService implements AppAuthServi private final BusinessAuthHelper businessAuthHelper; private final PolicyService policyService; private final JobIamProperties jobIamProperties; - private final EsbIamClient iamClient; + private final EsbIamV1Client iamClient; private ResourceNameQueryService resourceNameQueryService; public AppAuthServiceImpl(AuthHelper authHelper, @@ -82,7 +82,7 @@ public AppAuthServiceImpl(AuthHelper authHelper, this.businessAuthHelper = businessAuthHelper; this.policyService = policyService; this.jobIamProperties = jobIamProperties; - this.iamClient = new EsbIamClient( + this.iamClient = new EsbIamV1Client( meterRegistry, new AppProperties(iamConfiguration.getAppCode(), iamConfiguration.getAppSecret()), esbProperties); diff --git a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java index a6a12645b5..1ea2ea1eff 100644 --- a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java +++ b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java @@ -29,12 +29,12 @@ import com.tencent.bk.job.common.esb.config.EsbProperties; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.iam.EsbActionDTO; -import com.tencent.bk.job.common.esb.model.iam.EsbApplyPermissionDTO; +import com.tencent.bk.job.common.esb.model.iam.OpenApiApplyPermissionDTO; import com.tencent.bk.job.common.esb.model.iam.EsbInstanceDTO; import com.tencent.bk.job.common.esb.model.iam.EsbRelatedResourceTypeDTO; import com.tencent.bk.job.common.exception.InternalException; import com.tencent.bk.job.common.i18n.service.MessageI18nService; -import com.tencent.bk.job.common.iam.client.EsbIamClient; +import com.tencent.bk.job.common.iam.client.EsbIamV1Client; import com.tencent.bk.job.common.iam.constant.ActionInfo; import com.tencent.bk.job.common.iam.constant.Actions; import com.tencent.bk.job.common.iam.constant.ResourceTypeEnum; @@ -70,7 +70,7 @@ @Slf4j public class AuthServiceImpl extends BasicAuthService implements AuthService { private final AuthHelper authHelper; - private final EsbIamClient iamClient; + private final EsbIamV1Client iamClient; private final MessageI18nService i18nService; private ResourceNameQueryService resourceNameQueryService; @@ -81,7 +81,7 @@ public AuthServiceImpl(AuthHelper authHelper, MeterRegistry meterRegistry) { this.authHelper = authHelper; this.i18nService = i18nService; - this.iamClient = new EsbIamClient( + this.iamClient = new EsbIamV1Client( meterRegistry, new AppProperties(iamConfiguration.getAppCode(), iamConfiguration.getAppSecret()), esbProperties); @@ -313,7 +313,7 @@ private Map>> groupResourcesByActio @Override public EsbResp buildEsbAuthFailResp(List permissionActionResources) { List actions = buildApplyActions(permissionActionResources); - EsbApplyPermissionDTO applyPermission = new EsbApplyPermissionDTO(); + OpenApiApplyPermissionDTO applyPermission = new OpenApiApplyPermissionDTO(); applyPermission.setSystemId(SystemId.JOB); applyPermission.setSystemName(i18nService.getI18n("system.bk_job")); applyPermission.setActions(actions.stream().map(this::convertToEsbAction).collect(Collectors.toList())); diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java index ae221decd1..5664262beb 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java @@ -58,11 +58,8 @@ public class ErrorCode { // 根据业务ID查找动态分组失败,业务ID:{0},原因:{1},请确认指定的业务是否存在动态分组 public static final int FAIL_TO_FIND_DYNAMIC_GROUP_BY_BIZ = 1211004; - // PaaS异常 // CMSI接口访问异常 public static final int CMSI_API_ACCESS_ERROR = 1213001; - // 用户管理接口访问异常 - public static final int USER_MANAGE_API_ACCESS_ERROR = 1213002; // 调用CMSI接口获取通知渠道数据异常 public static final int CMSI_MSG_CHANNEL_DATA_ERROR = 1213003; // 调用CMSI接口发送通知失败,错误码:{0},错误信息:{1} @@ -96,6 +93,13 @@ public class ErrorCode { // 蓝鲸OpenAI接口数据超时 public static final int BK_OPEN_AI_API_DATA_TIMEOUT = 1218003; + // bk-login(蓝鲸登录) 接口调用异常 + public static final int BK_LOGIN_API_ERROR = 1219001; + + // bk-user-manage(用户管理) 接口调用异常 + public static final int BK_USER_MANAGE_API_ERROR = 1220001; + + // ======== 系统错误-权限错误 ==================// // 用户({0})权限不足,请前往权限中心确认并申请补充后重试 public static final int PERMISSION_DENIED = 1238001; diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/JobCommonHeaders.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/JobCommonHeaders.java index cafe8f8a9f..2518f44693 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/JobCommonHeaders.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/JobCommonHeaders.java @@ -47,4 +47,9 @@ public interface JobCommonHeaders { * 蓝鲸网关-从网关来的请求,与ESB请求区分 */ String BK_GATEWAY_FROM = "X-Bkapi-From"; + + /** + * 租户 ID + */ + String BK_TENANT_ID = "X-Bk-Tenant-Id"; } diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java new file mode 100644 index 0000000000..745f3b6b8c --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java @@ -0,0 +1,17 @@ +package com.tencent.bk.job.common.constant; + +/** + * 租户 ID 常量 + */ +public interface TenantIdConstants { + + /** + * 单租户环境默认租户 ID + */ + String SINGLE_TENANT_ENV_DEFAULT_TENANT_ID = "default"; + + /** + * 多租户环境默认租户 ID + */ + String MULTI_TENANT_ENV_DEFAULT_TENANT_ID = "system"; +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/metrics/CommonMetricNames.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/metrics/CommonMetricNames.java index 1b659596bf..c8b73c69ed 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/metrics/CommonMetricNames.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/metrics/CommonMetricNames.java @@ -31,19 +31,19 @@ public class CommonMetricNames { /** * 仅统计调用ESB BK-LOGIN API的HTTP请求过程 */ - public static final String ESB_BK_LOGIN_API_HTTP = "job.client.bk.login.api.http"; + public static final String BK_LOGIN_API_HTTP = "job.client.bk.login.api.http"; /** * 仅统计调用ESB BK-LOGIN API的整个过程,含反序列化 */ - public static final String ESB_BK_LOGIN_API = "job.client.bk.login.api"; + public static final String BK_LOGIN_API = "job.client.bk.login.api"; /** * 仅统计调用ESB USER-MANAGE API的HTTP请求过程 */ - public static final String ESB_USER_MANAGE_API_HTTP = "job.client.user.manage.api.http"; + public static final String USER_MANAGE_API_HTTP = "job.client.user.manage.api.http"; /** * 统计调用ESB 用户管理 API的整个过程,含反序列化 */ - public static final String ESB_USER_MANAGE_API = "job.client.user.manage.api"; + public static final String USER_MANAGE_API = "job.client.user.manage.api"; /** * 仅统计调用ESB CMSI API的HTTP请求过程 */ diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/BkUserDTO.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/BkUserDTO.java index 2f71fcb040..c986c46788 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/BkUserDTO.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/BkUserDTO.java @@ -24,6 +24,7 @@ package com.tencent.bk.job.common.model.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -72,4 +73,14 @@ public class BkUserDTO { * 用户微信 */ private String wxUserId; + + /** + * 用户所属租户 ID + */ + private String tenantId; + + /** + * 用户语言,枚举值:zh-cn / en + */ + private String language; } diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantAutoConfiguration.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantAutoConfiguration.java new file mode 100644 index 0000000000..ee82002d99 --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantAutoConfiguration.java @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +package com.tencent.bk.job.common.tenant; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +@EnableConfigurationProperties(TenantProperties.class) +public class TenantAutoConfiguration { + + @Bean + public TenantEnvService tenantEnvService(TenantProperties tenantProperties) { + return new TenantEnvService(tenantProperties); + } +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantEnvService.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantEnvService.java new file mode 100644 index 0000000000..5913a18879 --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantEnvService.java @@ -0,0 +1,31 @@ +package com.tencent.bk.job.common.tenant; + +import com.tencent.bk.job.common.constant.TenantIdConstants; + +/** + * 租户环境信息 Service + */ +public class TenantEnvService { + + private final TenantProperties tenantProperties; + + public TenantEnvService(TenantProperties tenantProperties) { + this.tenantProperties = tenantProperties; + } + + + /** + * 该环境是否支持多租户 + */ + public boolean isTenantEnabled() { + return tenantProperties.isEnabled(); + } + + /** + * 获取默认的租户 ID + */ + public String getDefaultTenantId() { + return isTenantEnabled() ? TenantIdConstants.MULTI_TENANT_ENV_DEFAULT_TENANT_ID : + TenantIdConstants.SINGLE_TENANT_ENV_DEFAULT_TENANT_ID; + } +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantProperties.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantProperties.java new file mode 100644 index 0000000000..62c78f9add --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/tenant/TenantProperties.java @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +package com.tencent.bk.job.common.tenant; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * 多租户配置 + */ +@Getter +@Setter +@ToString +@ConfigurationProperties(prefix = "tenant") +public class TenantProperties { + /** + * 是否支持多租户 + */ + private boolean enabled; +} diff --git a/src/backend/commons/common/src/main/resources/META-INF/spring.factories b/src/backend/commons/common/src/main/resources/META-INF/spring.factories index 09450a20ce..af1fafec4d 100644 --- a/src/backend/commons/common/src/main/resources/META-INF/spring.factories +++ b/src/backend/commons/common/src/main/resources/META-INF/spring.factories @@ -1,2 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.tencent.bk.job.common.service.config.JobCommonAutoConfiguration +com.tencent.bk.job.common.service.config.JobCommonAutoConfiguration, \ +com.tencent.bk.job.common.tenant.TenantAutoConfiguration diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/config/BkApiGatewayProperties.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/config/BkApiGatewayProperties.java index f143a2b4d8..42188f86ba 100644 --- a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/config/BkApiGatewayProperties.java +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/config/BkApiGatewayProperties.java @@ -45,6 +45,16 @@ public class BkApiGatewayProperties { private ApiGwConfig bkApiGateway; + /** + * 蓝鲸登录相关配置 + */ + private ApiGwConfig bkLogin; + + /** + * 蓝鲸用户管理相关配置 + */ + private ApiGwConfig bkUser; + @Getter @Setter @ToString diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/constants/BkErrorCodeEnum.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/constants/BkErrorCodeEnum.java new file mode 100644 index 0000000000..282c1372f0 --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/constants/BkErrorCodeEnum.java @@ -0,0 +1,120 @@ +package com.tencent.bk.job.common.esb.constants; + +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * 蓝鲸通用错误分类定义 + */ +public enum BkErrorCodeEnum { + /** + * 参数不合法 + */ + INVALID_ARGUMENT("INVALID_ARGUMENT", 400), + /** + * 参数符合参数格式,但参数不符合业务规则 + */ + INVALID_REQUEST("INVALID_REQUEST", 400), + /** + * 客户端指定了无效范围 + */ + OUT_OF_RANGE("OUT_OF_RANGE", 400), + /** + * 请求无法在当前系统状态下执行,例如删除非空目录 + */ + FAILED_PRECONDITION("FAILED_PRECONDITION", 400), + /** + * 未提供身份认证凭证 + */ + UNAUTHENTICATED("UNAUTHENTICATED", 401), + /** + * 权限中心没有相关权限(有协议要求) + */ + IAM_NO_PERMISSION("IAM_NO_PERMISSION", 403), + /** + * 没有相关权限(非权限中心) + */ + NO_PERMISSION("NO_PERMISSION", 403), + /** + * 资源不存在 + */ + NOT_FOUND("NOT_FOUND", 404), + /** + * 客户端尝试创建的资源已存在 + */ + ALREADY_EXISTS("ALREADY_EXISTS", 409), + /** + * 并发冲突,例如读取/修改/写入冲突 + */ + ABORTED("ABORTED", 409), + /** + * 超过频率限制 + */ + RATELIMIT_EXCEED("RATELIMIT_EXCEED", 429), + /** + * 资源配额不足 + */ + RESOURCE_EXHAUSTED("RESOURCE_EXHAUSTED", 429), + /** + * 出现内部服务器错误 + */ + INTERNAL("INTERNAL", 500), + /** + * 出现未知的服务器错误 + */ + UNKNOWN("UNKNOWN", 500), + /** + * API 方法未通过服务器实现 + */ + NOT_IMPLEMENTED("NOT_IMPLEMENTED", 501), + /** + * 服务不可用。通常是由于服务器宕机了 + */ + UNAVAILABLE("UNAVAILABLE", 503); + + private final String errorCode; + private final int statusCode; + + BkErrorCodeEnum(String errorCode, int statusCode) { + this.errorCode = errorCode; + this.statusCode = statusCode; + } + + public String getErrorCode() { + return errorCode; + } + + public int getStatusCode() { + return statusCode; + } + + public static BkErrorCodeEnum valOf(String errorCode) { + for (BkErrorCodeEnum errorType : values()) { + if (errorType.getErrorCode().equals(errorCode)) { + return errorType; + } + } + throw new IllegalArgumentException("No BkErrorCodeEnum constant: " + errorCode); + } +} diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/exception/BkOpenApiException.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/exception/BkOpenApiException.java new file mode 100644 index 0000000000..ce1292a5fc --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/exception/BkOpenApiException.java @@ -0,0 +1,43 @@ +package com.tencent.bk.job.common.esb.exception; + +import com.tencent.bk.job.common.esb.model.OpenApiError; +import com.tencent.bk.job.common.esb.model.OpenApiV1Error; +import lombok.Getter; + +/** + * 蓝鲸 Open API 调用异常 + */ +@Getter +public class BkOpenApiException extends RuntimeException { + + /** + * http 状态码 + */ + private final int statusCode; + + /** + * 蓝鲸 v2(新版)错误信息 + */ + private OpenApiError error; + + /** + * 蓝鲸 v1 版本错误信息 + */ + private OpenApiV1Error openApiV1Error; + + + public BkOpenApiException(int statusCode) { + this.statusCode = statusCode; + } + + public BkOpenApiException(int statusCode, OpenApiError error) { + this.statusCode = statusCode; + this.error = error; + } + + public BkOpenApiException(int statusCode, OpenApiV1Error openApiV1Error) { + this.statusCode = statusCode; + this.openApiV1Error = openApiV1Error; + } + +} diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/EsbResp.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/EsbResp.java index a6722407e1..1ffa686698 100644 --- a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/EsbResp.java +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/EsbResp.java @@ -28,7 +28,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.tencent.bk.job.common.constant.ErrorCode; -import com.tencent.bk.job.common.esb.model.iam.EsbApplyPermissionDTO; +import com.tencent.bk.job.common.esb.model.iam.OpenApiApplyPermissionDTO; import com.tencent.bk.job.common.exception.ServiceException; import com.tencent.bk.job.common.model.ValidateResult; import com.tencent.bk.job.common.model.error.ErrorDetailDTO; @@ -61,7 +61,7 @@ public class EsbResp { /** * 无权限返回数据 */ - private EsbApplyPermissionDTO permission; + private OpenApiApplyPermissionDTO permission; private EsbResp(T data) { this.code = ErrorCode.RESULT_OK; @@ -101,7 +101,7 @@ public static EsbResp buildCommonFailResp(ServiceException e) { return buildCommonFailResp(e.getErrorCode(), e.getErrorParams(), null); } - public static EsbResp buildAuthFailResult(EsbApplyPermissionDTO permission) { + public static EsbResp buildAuthFailResult(OpenApiApplyPermissionDTO permission) { EsbResp esbResp = buildCommonFailResp(ErrorCode.BK_PERMISSION_DENIED, new String[]{JobContextUtil.getUsername()}, null); esbResp.setPermission(permission); diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiError.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiError.java new file mode 100644 index 0000000000..1398efb33c --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiError.java @@ -0,0 +1,73 @@ +package com.tencent.bk.job.common.esb.model; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.tencent.bk.job.common.esb.constants.BkErrorCodeEnum; +import com.tencent.bk.job.common.esb.model.iam.OpenApiApplyPermissionDTO; +import lombok.Data; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * 蓝鲸新版 http open api 协议定义的标准响应 - 错误信息 + */ +@Data +@JsonDeserialize(using = OpenApiError.OpenApiErrorDeserializer.class) +public class OpenApiError { + + /** + * 语义化的错误英文标识, 整个蓝鲸会定义一套通用的错误大分类; 作用: 上游编码基于这个做代码层面的逻辑判断(所以必须是确定的枚举); + * + * @see BkErrorCodeEnum + */ + private String code; + + /** + * 给用户看到的错误说明, 需要支持国际化 + */ + private String message; + + /** + * 返回的数据用于给调用方针对这个code做相应的一些处理, 例如无权限返回申请权限信息, 登录认证失败返回跳转url等 + */ + private Object data; + + /** + * 错误详情 + */ + private List> details; + + static class OpenApiErrorDeserializer extends JsonDeserializer { + @Override + public OpenApiError deserialize(JsonParser p, DeserializationContext ctx) throws IOException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + JsonNode node = mapper.readTree(p); + + OpenApiError error = new OpenApiError(); + error.setCode(node.get("code").asText()); + error.setMessage(node.get("message").asText()); + List> details = mapper.convertValue( + node.get("details"), + mapper.getTypeFactory().constructCollectionType(List.class, Map.class) + ); + error.setDetails(details); + + // 根据 code 字段的值来处理 data 字段 + String code = error.getCode(); + if (BkErrorCodeEnum.IAM_NO_PERMISSION.getErrorCode().equals(code)) { + error.setData(mapper.treeToValue(node.get("data"), OpenApiApplyPermissionDTO.class)); + } else { + // 处理其他类型的 data + error.setData(node.get("data")); + } + + return error; + } + } +} diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiRequestInfo.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiRequestInfo.java index 67b4b57bf1..947f3c0496 100644 --- a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiRequestInfo.java +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiRequestInfo.java @@ -28,10 +28,13 @@ import com.tencent.bk.job.common.util.http.RetryModeEnum; import lombok.Data; import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -62,6 +65,8 @@ public class OpenApiRequestInfo { */ private final Boolean idempotent; + private final List
headers; + public OpenApiRequestInfo(Builder builder) { this.method = builder.method; this.uri = builder.uri; @@ -71,6 +76,7 @@ public OpenApiRequestInfo(Builder builder) { this.authorization = builder.authorization; this.retryMode = builder.retryMode; this.idempotent = builder.idempotent; + this.headers = builder.headers; } public static Builder builder() { @@ -86,6 +92,7 @@ public static class Builder { private BkApiAuthorization authorization; private RetryModeEnum retryMode = RetryModeEnum.SAFE_GUARANTEED; private Boolean idempotent; + private List
headers; public Builder method(HttpMethodEnum method) { this.method = method; @@ -145,6 +152,19 @@ public Builder setIdempotent(Boolean idempotent) { return this; } + public Builder setHeaders(List
herders) { + this.headers = herders; + return this; + } + + public Builder addHeader(Header header) { + if (headers == null) { + headers = new ArrayList<>(); + } + headers.add(header); + return this; + } + public OpenApiRequestInfo build() { return new OpenApiRequestInfo<>(this); } diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiResponse.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiResponse.java new file mode 100644 index 0000000000..d88f227e38 --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiResponse.java @@ -0,0 +1,36 @@ +package com.tencent.bk.job.common.esb.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.tencent.bk.job.common.esb.model.iam.OpenApiApplyPermissionDTO; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * 蓝鲸新版 http open api 协议定义的标准响应 + */ +@Data +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Slf4j +public class OpenApiResponse { + + private T data; + + private OpenApiError error; + + /** + * 无权限返回数据 + */ + private OpenApiApplyPermissionDTO permission; + + private OpenApiResponse(T data) { + this.data = data; + } + + + public static OpenApiResponse success(T data) { + return new OpenApiResponse<>(data); + } + +} diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiV1Error.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiV1Error.java new file mode 100644 index 0000000000..3a366aeaca --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/OpenApiV1Error.java @@ -0,0 +1,33 @@ +package com.tencent.bk.job.common.esb.model; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.tencent.bk.job.common.esb.constants.BkErrorCodeEnum; +import com.tencent.bk.job.common.esb.model.iam.OpenApiApplyPermissionDTO; +import lombok.Data; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * 蓝鲸旧版 http open api 协议定义的标准响应 + */ +@Data +public class OpenApiV1Error { + + /** + * 错误码 + * @see com.tencent.bk.job.common.constant.ErrorCode + */ + private Integer code; + + /** + * 给用户看到的错误说明 + */ + private String message; +} diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/EsbApplyPermissionDTO.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/OpenApiApplyPermissionDTO.java similarity index 97% rename from src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/EsbApplyPermissionDTO.java rename to src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/OpenApiApplyPermissionDTO.java index b6c1637029..10f05359a4 100644 --- a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/EsbApplyPermissionDTO.java +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/model/iam/OpenApiApplyPermissionDTO.java @@ -34,7 +34,7 @@ * 返回给第三方api调用者的无权限申请url信息 */ @Data -public class EsbApplyPermissionDTO { +public class OpenApiApplyPermissionDTO { @JsonProperty("system_id") private String systemId; @JsonProperty("system_name") diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiClient.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BaseBkApiClient.java similarity index 62% rename from src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiClient.java rename to src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BaseBkApiClient.java index 4888ff8aec..a694952367 100644 --- a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiClient.java +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BaseBkApiClient.java @@ -1,3 +1,5 @@ +package com.tencent.bk.job.common.esb.sdk; + /* * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. * @@ -22,17 +24,15 @@ * IN THE SOFTWARE. */ -package com.tencent.bk.job.common.esb.sdk; - import com.fasterxml.jackson.core.type.TypeReference; import com.tencent.bk.job.common.constant.ErrorCode; import com.tencent.bk.job.common.constant.HttpMethodEnum; import com.tencent.bk.job.common.constant.JobCommonHeaders; import com.tencent.bk.job.common.esb.constants.EsbLang; +import com.tencent.bk.job.common.esb.exception.BkOpenApiException; import com.tencent.bk.job.common.esb.interceptor.LogBkApiRequestIdInterceptor; import com.tencent.bk.job.common.esb.metrics.EsbMetricTags; import com.tencent.bk.job.common.esb.model.BkApiAuthorization; -import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; import com.tencent.bk.job.common.exception.InternalException; import com.tencent.bk.job.common.util.JobContextUtil; @@ -44,6 +44,7 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tags; +import lombok.Setter; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; @@ -51,18 +52,21 @@ import org.apache.http.message.BasicHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.concurrent.TimeUnit; import static com.tencent.bk.job.common.constant.HttpHeader.HDR_BK_LANG; import static com.tencent.bk.job.common.i18n.locale.LocaleUtils.COMMON_LANG_HEADER; /** - * 蓝鲸API(组件 API(ESB)、网关 API(蓝鲸 ApiGateway))调用客户端 + * 蓝鲸API(组件 API(ESB)、网关 API(蓝鲸 ApiGateway))调用客户端基础类 */ -public class BkApiClient { +public class BaseBkApiClient { private String lang; private Logger log = LoggerFactory.getLogger(this.getClass()); @@ -74,6 +78,8 @@ public class BkApiClient { * API调用度量指标名称 */ private final String metricName; + + @Setter private JsonMapper jsonMapper = JsonMapper.nonNullMapper(); /** @@ -82,34 +88,25 @@ public class BkApiClient { * @param baseAccessUrl API 服务访问地址 * @param defaultHttpHelper http 请求处理客户端 */ - public BkApiClient(MeterRegistry meterRegistry, - String metricName, - String baseAccessUrl, - HttpHelper defaultHttpHelper) { + public BaseBkApiClient(MeterRegistry meterRegistry, + String metricName, + String baseAccessUrl, + HttpHelper defaultHttpHelper) { this.meterRegistry = meterRegistry; this.metricName = metricName; this.baseAccessUrl = baseAccessUrl; this.defaultHttpHelper = defaultHttpHelper; } - public BkApiClient(MeterRegistry meterRegistry, - String metricName, - String baseAccessUrl, - HttpHelper defaultHttpHelper, - String lang) { + public BaseBkApiClient(MeterRegistry meterRegistry, + String metricName, + String baseAccessUrl, + HttpHelper defaultHttpHelper, + String lang) { this(meterRegistry, metricName, baseAccessUrl, defaultHttpHelper); this.lang = lang; } - /** - * 配置自定义的 JsonMapper, 用于序列化 Json 数据 - * - * @param jsonMapper jsonMapper - */ - public void setJsonMapper(JsonMapper jsonMapper) { - this.jsonMapper = jsonMapper; - } - /** * 配置自定义的日志 logger * @@ -119,21 +116,21 @@ public void setLogger(Logger logger) { this.log = logger; } - public EsbResp doRequest(OpenApiRequestInfo requestInfo, - TypeReference> typeReference, - HttpHelper httpHelper) { + public R doRequest(OpenApiRequestInfo requestInfo, + TypeReference typeReference, + HttpHelper httpHelper) throws BkOpenApiException { return doRequest(requestInfo, typeReference, null, httpHelper); } - public EsbResp doRequest(OpenApiRequestInfo requestInfo, - TypeReference> typeReference) { + public R doRequest(OpenApiRequestInfo requestInfo, + TypeReference typeReference) throws BkOpenApiException { return doRequest(requestInfo, typeReference, null); } - public EsbResp doRequest(OpenApiRequestInfo requestInfo, - TypeReference> typeReference, - BkApiLogStrategy logStrategy, - HttpHelper httpHelper) { + public R doRequest(OpenApiRequestInfo requestInfo, + TypeReference typeReference, + BkApiLogStrategy logStrategy, + HttpHelper httpHelper) throws BkOpenApiException { HttpMethodEnum httpMethod = requestInfo.getMethod(); BkApiContext apiContext = new BkApiContext<>(httpMethod.name(), requestInfo.getUri(), requestInfo.getBody(), null, null, 0, false); @@ -173,65 +170,12 @@ public EsbResp doRequest(OpenApiRequestInfo requestInfo, } } - public R requestApiAndWrapResponse(OpenApiRequestInfo requestInfo, - TypeReference typeReference, - HttpHelper httpHelper) { - if (log.isInfoEnabled()) { - log.info("[AbstractBkApiClient] Request|method={}|uri={}|reqStr={}", - requestInfo.getMethod().name(), requestInfo.getUri(), - requestInfo.getBody() != null ? JsonUtils.toJsonWithoutSkippedFields(requestInfo.getBody()) : null); - } - String uri = requestInfo.getUri(); - String respStr = null; - String status = EsbMetricTags.VALUE_STATUS_OK; - HttpMethodEnum httpMethod = requestInfo.getMethod(); - long start = System.currentTimeMillis(); - String bkApiRequestId = null; - boolean success = true; - try { - HttpResponse response = requestApi(httpHelper, requestInfo); - bkApiRequestId = extractBkApiRequestId(response); - respStr = response.getEntity(); - if (StringUtils.isBlank(respStr)) { - String errorMsg = "[AbstractBkApiClient] " + httpMethod.name() + " " - + uri + ", error: " + "Response is blank"; - log.warn( - "[AbstractBkApiClient] fail: Response is blank| requestId={}|method={}|uri={}", - bkApiRequestId, - httpMethod.name(), - uri - ); - status = EsbMetricTags.VALUE_STATUS_ERROR; - throw new InternalException(errorMsg, ErrorCode.API_ERROR); - } - return jsonMapper.fromJson(respStr, typeReference); - } catch (Throwable e) { - success = false; - String errorMsg = "Fail to request api|method=" + httpMethod.name() - + "|uri=" + uri; - log.error(errorMsg, e); - status = EsbMetricTags.VALUE_STATUS_ERROR; - throw new InternalException("Fail to request bk api", e, ErrorCode.API_ERROR); - } finally { - long cost = System.currentTimeMillis() - start; - if (meterRegistry != null) { - meterRegistry.timer(metricName, buildMetricTags(uri, status)) - .record(cost, TimeUnit.MILLISECONDS); - } - if (log.isInfoEnabled()) { - log.info("[AbstractBkApiClient] Response|requestId={}|method={}|uri={}|success={}" - + "|costTime={}|resp={}", - bkApiRequestId, httpMethod.name(), requestInfo.getUri(), success, cost, respStr); - } - } - } - - private EsbResp requestApiAndWrapResponse(OpenApiRequestInfo requestInfo, - BkApiContext apiContext, - TypeReference> typeReference, - HttpHelper httpHelper) { + private R requestApiAndWrapResponse(OpenApiRequestInfo requestInfo, + BkApiContext apiContext, + TypeReference typeReference, + HttpHelper httpHelper) throws BkOpenApiException { String uri = apiContext.getUri(); - EsbResp esbResp; + R responseBody; String respStr; String status = EsbMetricTags.VALUE_STATUS_OK; HttpMethodEnum httpMethod = requestInfo.getMethod(); @@ -246,8 +190,7 @@ private EsbResp requestApiAndWrapResponse(OpenApiRequestInfo reques apiContext.setOriginResp(response.getEntity()); if (StringUtils.isBlank(respStr)) { - String errorMsg = "[AbstractBkApiClient] " + httpMethod.name() + " " - + uri + ", error: " + "Response is blank"; + String errorMsg = httpMethod.name() + " " + uri + ", error: " + "Response is blank"; log.warn("[AbstractBkApiClient] fail: Response is blank| bkApiRequestId={}|method={}|uri={}", apiContext.getRequestId(), httpMethod.name(), uri); status = EsbMetricTags.VALUE_STATUS_ERROR; @@ -255,45 +198,25 @@ private EsbResp requestApiAndWrapResponse(OpenApiRequestInfo reques } long deserializeStartTimestamp = System.currentTimeMillis(); - esbResp = jsonMapper.fromJson(respStr, typeReference); + responseBody = jsonMapper.fromJson(respStr, typeReference); apiContext.setDeserializeCostTime(System.currentTimeMillis() - deserializeStartTimestamp); - apiContext.setResp(esbResp); - if (!esbResp.isSuccess()) { - log.warn( - "[AbstractBkApiClient] fail:response code!=0" + - "|bkApiRequestId={}|code={}|message={}|method={}|uri={}|reqStr={}|respStr={}", - apiContext.getRequestId(), - esbResp.getCode(), - esbResp.getMessage(), - httpMethod.name(), - uri, - apiContext.getReq() != null ? JsonUtils.toJsonWithoutSkippedFields(apiContext.getReq()) : null, - respStr - ); + apiContext.setResp(responseBody); + if (isResponseError(response, responseBody)) { status = EsbMetricTags.VALUE_STATUS_ERROR; + apiContext.setSuccess(false); + handleResponseError(response, responseBody); + } else { + apiContext.setSuccess(true); } - if (esbResp.getData() == null) { - log.warn( - "[AbstractBkApiClient] warn: response data is null" + - "|bkApiRequestId={}|code={}|message={}|method={}|uri={}|reqStr={}|respStr={}", - apiContext.getRequestId(), - esbResp.getCode(), - esbResp.getMessage(), - httpMethod.name(), - uri, - apiContext.getReq() != null ? JsonUtils.toJsonWithoutSkippedFields(apiContext.getReq()) : null, - respStr - ); - } - apiContext.setSuccess(true); - return esbResp; + return responseBody; + } catch (BkOpenApiException e) { + throw e; } catch (Throwable e) { - String errorMsg = "Fail to request api|method=" + httpMethod.name() - + "|uri=" + uri; + String errorMsg = "Fail to request api|method=" + httpMethod.name() + "|uri=" + uri; log.error(errorMsg, e); apiContext.setSuccess(false); status = EsbMetricTags.VALUE_STATUS_ERROR; - throw new InternalException("Fail to request bk api", e, ErrorCode.API_ERROR); + throw new InternalException("Request bk open api error", ErrorCode.API_ERROR); } finally { long cost = System.currentTimeMillis() - startTimestamp; apiContext.setCostTime(cost); @@ -328,7 +251,7 @@ private Iterable buildMetricTags(String uri, String status) { private HttpResponse requestApi(HttpHelper httpHelper, OpenApiRequestInfo requestInfo) { String url = buildApiUrl(requestInfo.buildFinalUri()); - Header[] headers = buildBkApiRequestHeaders(requestInfo.getAuthorization()); + Header[] headers = buildBkApiRequestHeaders(requestInfo); HttpRequest httpRequest = HttpRequest.builder(requestInfo.getMethod(), url) .setHeaders(headers) .setKeepAlive(true) @@ -337,7 +260,7 @@ private HttpResponse requestApi(HttpHelper httpHelper, OpenApiRequestInfo .setStringEntity(requestInfo.getBody() != null ? jsonMapper.toJson(requestInfo.getBody()) : null) .build(); - return chooseHttpHelper(httpHelper).requestForSuccessResp(httpRequest); + return chooseHttpHelper(httpHelper).request(httpRequest); } private HttpHelper chooseHttpHelper(HttpHelper httpHelper) { @@ -354,16 +277,23 @@ private String buildApiUrl(String uri) { return url; } - private Header[] buildBkApiRequestHeaders(BkApiAuthorization authorization) { - Header[] header = new Header[3]; - header[0] = new BasicHeader("Content-Type", "application/json"); - header[1] = buildBkApiAuthorizationHeader(authorization); + private Header[] buildBkApiRequestHeaders(OpenApiRequestInfo requestInfo) { + List
headers = new ArrayList<>(); + headers.add(new BasicHeader("Content-Type", "application/json")); + headers.add(buildBkApiAuthorizationHeader(requestInfo.getAuthorization())); + headers.add(buildBkApiAuthorizationHeader(requestInfo.getAuthorization())); if (StringUtils.isNotEmpty(lang)) { - header[2] = new BasicHeader(HDR_BK_LANG, lang); + headers.add(new BasicHeader(HDR_BK_LANG, lang)); } else { - header[2] = new BasicHeader(HDR_BK_LANG, getLangFromRequest()); + headers.add(new BasicHeader(HDR_BK_LANG, getLangFromRequest())); + } + + if (CollectionUtils.isNotEmpty(requestInfo.getHeaders())) { + headers.addAll(requestInfo.getHeaders()); } - return header; + + Header[] headerArray = new Header[headers.size()]; + return headers.toArray(headerArray); } private Header buildBkApiAuthorizationHeader(BkApiAuthorization authorization) { @@ -402,4 +332,19 @@ protected static HttpResponseInterceptor getLogBkApiRequestIdInterceptor() { return new LogBkApiRequestIdInterceptor(); } + protected boolean isResponseError(HttpResponse httpResponse, Object responseBody) { + // http code - 2xx + HttpStatus httpStatus = HttpStatus.resolve(httpResponse.getStatusCode()); + if (httpStatus == null) { + return true; + } + return !httpStatus.is2xxSuccessful(); + } + + protected void handleResponseError(HttpResponse httpResponse, Object responseBody) + throws BkOpenApiException { + throw new BkOpenApiException(httpResponse.getStatusCode()); + } + } + diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiContext.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiContext.java index 58d60ae8d9..85f1023ec9 100644 --- a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiContext.java +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiContext.java @@ -24,7 +24,6 @@ package com.tencent.bk.job.common.esb.sdk; -import com.tencent.bk.job.common.esb.model.EsbResp; import lombok.Data; /** @@ -49,7 +48,7 @@ public class BkApiContext { /** * 反序列化之后的 API 响应 */ - private EsbResp resp; + private R resp; /** * API 调用耗时 */ @@ -76,7 +75,7 @@ public BkApiContext(String method, String uri, T req, String originResp, - EsbResp resp, + R resp, long costTime, boolean success) { this.method = method; diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV1Client.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV1Client.java new file mode 100644 index 0000000000..0d77f587d1 --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV1Client.java @@ -0,0 +1,95 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +package com.tencent.bk.job.common.esb.sdk; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.tencent.bk.job.common.esb.exception.BkOpenApiException; +import com.tencent.bk.job.common.esb.model.EsbResp; +import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; +import com.tencent.bk.job.common.esb.model.OpenApiV1Error; +import com.tencent.bk.job.common.util.http.HttpHelper; +import com.tencent.bk.job.common.util.http.HttpResponse; +import io.micrometer.core.instrument.MeterRegistry; + +/** + * 蓝鲸API(组件 API(ESB)、网关 API(蓝鲸 ApiGateway))调用客户端 (v1版本) + */ +public class BkApiV1Client extends BaseBkApiClient { + + /** + * @param meterRegistry MeterRegistry + * @param metricName API http 请求指标名称 + * @param baseAccessUrl API 服务访问地址 + * @param defaultHttpHelper http 请求处理客户端 + */ + public BkApiV1Client(MeterRegistry meterRegistry, + String metricName, + String baseAccessUrl, + HttpHelper defaultHttpHelper) { + super(meterRegistry, metricName, baseAccessUrl, defaultHttpHelper); + } + + /** + * @param meterRegistry MeterRegistry + * @param metricName API http 请求指标名称 + * @param baseAccessUrl API 服务访问地址 + * @param defaultHttpHelper http 请求处理客户端 + * @param lang 语言 + */ + public BkApiV1Client(MeterRegistry meterRegistry, + String metricName, + String baseAccessUrl, + HttpHelper defaultHttpHelper, + String lang) { + super(meterRegistry, metricName, baseAccessUrl, defaultHttpHelper, lang); + } + + public EsbResp request(OpenApiRequestInfo requestInfo, + TypeReference> typeReference, + HttpHelper httpHelper) throws BkOpenApiException { + return doRequest(requestInfo, typeReference, null, httpHelper); + } + + public EsbResp request(OpenApiRequestInfo requestInfo, + TypeReference> typeReference) throws BkOpenApiException { + return doRequest(requestInfo, typeReference, null); + } + + @Override + protected boolean isResponseError(HttpResponse httpResponse, Object responseBody) { + EsbResp esbResp = (EsbResp) responseBody; + return super.isResponseError(httpResponse, responseBody) && !esbResp.isSuccess(); + } + + @Override + protected void handleResponseError(HttpResponse httpResponse, Object responseBody) + throws BkOpenApiException { + EsbResp esbResp = (EsbResp) responseBody; + OpenApiV1Error error = new OpenApiV1Error(); + error.setCode(esbResp.getCode()); + error.setMessage(esbResp.getMessage()); + throw new BkOpenApiException(httpResponse.getStatusCode(), error); + } +} diff --git a/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV2Client.java b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV2Client.java new file mode 100644 index 0000000000..61f9a73150 --- /dev/null +++ b/src/backend/commons/esb-sdk/src/main/java/com/tencent/bk/job/common/esb/sdk/BkApiV2Client.java @@ -0,0 +1,72 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +package com.tencent.bk.job.common.esb.sdk; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.tencent.bk.job.common.esb.exception.BkOpenApiException; +import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; +import com.tencent.bk.job.common.esb.model.OpenApiResponse; +import com.tencent.bk.job.common.util.http.HttpHelper; +import com.tencent.bk.job.common.util.http.HttpResponse; +import io.micrometer.core.instrument.MeterRegistry; + +/** + * 网关 API(蓝鲸 ApiGateway))调用客户端 (v2版本) + */ +public class BkApiV2Client extends BaseBkApiClient { + + /** + * @param meterRegistry MeterRegistry + * @param metricName API http 请求指标名称 + * @param baseAccessUrl API 服务访问地址 + * @param defaultHttpHelper http 请求处理客户端 + */ + public BkApiV2Client(MeterRegistry meterRegistry, + String metricName, + String baseAccessUrl, + HttpHelper defaultHttpHelper) { + super(meterRegistry, metricName, baseAccessUrl, defaultHttpHelper); + } + + public OpenApiResponse request(OpenApiRequestInfo requestInfo, + TypeReference> typeReference, + HttpHelper httpHelper) throws BkOpenApiException { + return doRequest(requestInfo, typeReference, null, httpHelper); + } + + public OpenApiResponse request( + OpenApiRequestInfo requestInfo, + TypeReference> typeReference) throws BkOpenApiException { + + return doRequest(requestInfo, typeReference, null); + } + + @Override + protected void handleResponseError(HttpResponse httpResponse, Object responseBody) + throws BkOpenApiException { + OpenApiResponse response = (OpenApiResponse) responseBody; + throw new BkOpenApiException(httpResponse.getStatusCode(), response.getError()); + } +} diff --git a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/GseClient.java b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/GseClient.java index 886ae6c48d..284bf5600d 100644 --- a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/GseClient.java +++ b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/GseClient.java @@ -28,7 +28,7 @@ import com.tencent.bk.job.common.exception.InternalException; import com.tencent.bk.job.common.gse.util.AgentUtils; import com.tencent.bk.job.common.gse.v1.GseV1ApiClient; -import com.tencent.bk.job.common.gse.v2.GseV2ApiClient; +import com.tencent.bk.job.common.gse.v2.GseV2ApiV1Client; import com.tencent.bk.job.common.gse.v2.model.ExecuteScriptRequest; import com.tencent.bk.job.common.gse.v2.model.FileTaskResult; import com.tencent.bk.job.common.gse.v2.model.GetExecuteScriptResultRequest; @@ -53,11 +53,11 @@ public class GseClient implements IGseClient { private final GseV1ApiClient gseV1ApiClient; - private final GseV2ApiClient gseV2ApiClient; + private final GseV2ApiV1Client gseV2ApiClient; public GseClient(GseV1ApiClient gseV1ApiClient, - GseV2ApiClient gseV2ApiClient) { + GseV2ApiV1Client gseV2ApiClient) { this.gseV1ApiClient = gseV1ApiClient; this.gseV2ApiClient = gseV2ApiClient; log.info("Init gseClient, gseV1ApiClient: {}, gseV2ApiClient: {}", gseV1ApiClient, gseV2ApiClient); diff --git a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/config/GseAutoConfiguration.java b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/config/GseAutoConfiguration.java index 5d7319671b..09d2bcf899 100644 --- a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/config/GseAutoConfiguration.java +++ b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/config/GseAutoConfiguration.java @@ -35,7 +35,7 @@ import com.tencent.bk.job.common.gse.service.PreferV2AgentStateClientImpl; import com.tencent.bk.job.common.gse.v1.GseV1ApiClient; import com.tencent.bk.job.common.gse.v1.config.GseV1AutoConfiguration; -import com.tencent.bk.job.common.gse.v2.GseV2ApiClient; +import com.tencent.bk.job.common.gse.v2.GseV2ApiV1Client; import com.tencent.bk.job.common.gse.v2.GseV2AutoConfiguration; import io.micrometer.core.instrument.MeterRegistry; import lombok.extern.slf4j.Slf4j; @@ -66,7 +66,7 @@ public class GseAutoConfiguration { @Bean("GseApiClient") public GseClient gseClient(ObjectProvider gseV1ApiClient, - ObjectProvider gseV2ApiClient) { + ObjectProvider gseV2ApiClient) { return new GseClient(gseV1ApiClient.getIfAvailable(), gseV2ApiClient.getIfAvailable()); } diff --git a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/service/GseV2AgentStateClientImpl.java b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/service/GseV2AgentStateClientImpl.java index 0d32cdfa42..6cd61e3ccd 100644 --- a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/service/GseV2AgentStateClientImpl.java +++ b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/service/GseV2AgentStateClientImpl.java @@ -26,7 +26,7 @@ import com.tencent.bk.job.common.gse.config.AgentStateQueryConfig; import com.tencent.bk.job.common.gse.service.model.HostAgentStateQuery; -import com.tencent.bk.job.common.gse.v2.GseV2ApiClient; +import com.tencent.bk.job.common.gse.v2.GseV2ApiV1Client; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.ThreadPoolExecutor; @@ -35,7 +35,7 @@ public class GseV2AgentStateClientImpl extends SingleChannelAgentStateClientImpl { public GseV2AgentStateClientImpl(AgentStateQueryConfig agentStateQueryConfig, - GseV2ApiClient gseV2ApiClient, + GseV2ApiV1Client gseV2ApiClient, ThreadPoolExecutor threadPoolExecutor) { super(agentStateQueryConfig, gseV2ApiClient, threadPoolExecutor); } diff --git a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2ApiClient.java b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2ApiV1Client.java similarity index 97% rename from src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2ApiClient.java rename to src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2ApiV1Client.java index bba3048092..47d6a40427 100644 --- a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2ApiClient.java +++ b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2ApiV1Client.java @@ -31,7 +31,7 @@ import com.tencent.bk.job.common.esb.model.BkApiAuthorization; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; +import com.tencent.bk.job.common.esb.sdk.BkApiV1Client; import com.tencent.bk.job.common.esb.sdk.BkApiContext; import com.tencent.bk.job.common.esb.sdk.BkApiLogStrategy; import com.tencent.bk.job.common.gse.IGseClient; @@ -61,7 +61,7 @@ import java.util.List; @Slf4j -public class GseV2ApiClient extends BkApiClient implements IGseClient { +public class GseV2ApiV1Client extends BkApiV1Client implements IGseClient { private static final String URI_LIST_AGENT_STATE = "/api/v2/cluster/list_agent_state"; private static final String URI_ASYNC_EXECUTE_SCRIPT = "/api/v2/task/extensions/async_execute_script"; @@ -74,9 +74,9 @@ public class GseV2ApiClient extends BkApiClient implements IGseClient { "/api/v2/task/extensions/async_terminate_execute_script"; private final BkApiAuthorization gseBkApiAuthorization; - public GseV2ApiClient(MeterRegistry meterRegistry, - AppProperties appProperties, - BkApiGatewayProperties bkApiGatewayProperties) { + public GseV2ApiV1Client(MeterRegistry meterRegistry, + AppProperties appProperties, + BkApiGatewayProperties bkApiGatewayProperties) { super(meterRegistry, GseMetricNames.GSE_V2_API_METRICS_NAME_PREFIX, diff --git a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2AutoConfiguration.java b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2AutoConfiguration.java index 61a8eb2905..5b55015c04 100644 --- a/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2AutoConfiguration.java +++ b/src/backend/commons/gse-sdk/src/main/java/com/tencent/bk/job/common/gse/v2/GseV2AutoConfiguration.java @@ -39,9 +39,9 @@ public class GseV2AutoConfiguration { @Bean("gseV2ApiClient") - public GseV2ApiClient gseV2ApiClient(MeterRegistry meterRegistry, - AppProperties appProperties, - BkApiGatewayProperties bkApiGatewayProperties) { - return new GseV2ApiClient(meterRegistry, appProperties, bkApiGatewayProperties); + public GseV2ApiV1Client gseV2ApiClient(MeterRegistry meterRegistry, + AppProperties appProperties, + BkApiGatewayProperties bkApiGatewayProperties) { + return new GseV2ApiV1Client(meterRegistry, appProperties, bkApiGatewayProperties); } } diff --git a/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/config/NoticeAutoConfiguration.java b/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/config/NoticeAutoConfiguration.java index a51a34904a..2d7a2e3f4d 100644 --- a/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/config/NoticeAutoConfiguration.java +++ b/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/config/NoticeAutoConfiguration.java @@ -26,7 +26,7 @@ import com.tencent.bk.job.common.esb.config.AppProperties; import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties; -import com.tencent.bk.job.common.notice.impl.BkNoticeClient; +import com.tencent.bk.job.common.notice.impl.BkNoticeV1Client; import io.micrometer.core.instrument.MeterRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -39,10 +39,10 @@ public class NoticeAutoConfiguration { @Bean - public BkNoticeClient bkNoticeClient(MeterRegistry meterRegistry, - AppProperties appProperties, - BkApiGatewayProperties bkApiGatewayProperties) { - return new BkNoticeClient(meterRegistry, appProperties, bkApiGatewayProperties); + public BkNoticeV1Client bkNoticeClient(MeterRegistry meterRegistry, + AppProperties appProperties, + BkApiGatewayProperties bkApiGatewayProperties) { + return new BkNoticeV1Client(meterRegistry, appProperties, bkApiGatewayProperties); } } diff --git a/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/BkNoticeClient.java b/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/BkNoticeV1Client.java similarity index 89% rename from src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/BkNoticeClient.java rename to src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/BkNoticeV1Client.java index 9f45eb0a51..7bb925c172 100644 --- a/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/BkNoticeClient.java +++ b/src/backend/commons/notice-sdk/src/main/java/com/tencent/bk/job/common/notice/impl/BkNoticeV1Client.java @@ -29,13 +29,12 @@ import com.tencent.bk.job.common.constant.HttpMethodEnum; import com.tencent.bk.job.common.esb.config.AppProperties; import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties; +import com.tencent.bk.job.common.esb.exception.BkOpenApiException; import com.tencent.bk.job.common.esb.model.BkApiAuthorization; import com.tencent.bk.job.common.esb.model.EsbReq; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; -import com.tencent.bk.job.common.exception.HttpStatusException; -import com.tencent.bk.job.common.exception.InternalException; +import com.tencent.bk.job.common.esb.sdk.BkApiV1Client; import com.tencent.bk.job.common.metrics.CommonMetricNames; import com.tencent.bk.job.common.notice.IBkNoticeClient; import com.tencent.bk.job.common.notice.exception.BkNoticeException; @@ -51,7 +50,7 @@ import java.util.List; @SuppressWarnings("SameParameterValue") -public class BkNoticeClient extends BkApiClient implements IBkNoticeClient { +public class BkNoticeV1Client extends BkApiV1Client implements IBkNoticeClient { private static final String URI_REGISTER_APPLICATION = "/apigw/v1/register/"; private static final String URI_GET_CURRENT_ANNOUNCEMENTS = "/apigw/v1/announcement/get_current_announcements/"; @@ -59,9 +58,9 @@ public class BkNoticeClient extends BkApiClient implements IBkNoticeClient { private final AppProperties appProperties; private final BkApiAuthorization authorization; - public BkNoticeClient(MeterRegistry meterRegistry, - AppProperties appProperties, - BkApiGatewayProperties bkApiGatewayProperties) { + public BkNoticeV1Client(MeterRegistry meterRegistry, + AppProperties appProperties, + BkApiGatewayProperties bkApiGatewayProperties) { super( meterRegistry, CommonMetricNames.BK_NOTICE_API, @@ -154,13 +153,10 @@ private EsbResp requestBkNoticeApi(HttpMethodEnum method, .setIdempotent(idempotent) .build(); return doRequest(requestInfo, typeReference); - } catch (InternalException e) { + } catch (BkOpenApiException e) { // 接口不存在的场景需要使用指定错误码以便前端兼容处理 - if (e.getCause() instanceof HttpStatusException) { - HttpStatusException httpStatusException = (HttpStatusException) e.getCause(); - if (httpStatusException.getHttpStatus() == HttpStatus.SC_NOT_FOUND) { - throw new BkNoticeException(e, ErrorCode.BK_NOTICE_API_NOT_FOUND, new String[]{uri}); - } + if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) { + throw new BkNoticeException(e, ErrorCode.BK_NOTICE_API_NOT_FOUND, new String[]{uri}); } throw new BkNoticeException(e, ErrorCode.BK_NOTICE_API_DATA_ERROR, null); } catch (Exception e) { diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/CmsiApiClient.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/CmsiApiV1Client.java similarity index 96% rename from src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/CmsiApiClient.java rename to src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/CmsiApiV1Client.java index c9d4f9a606..4e61e1f24d 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/CmsiApiClient.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/cmsi/CmsiApiV1Client.java @@ -34,7 +34,7 @@ import com.tencent.bk.job.common.esb.model.EsbReq; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; +import com.tencent.bk.job.common.esb.sdk.BkApiV1Client; import com.tencent.bk.job.common.exception.InternalCmsiException; import com.tencent.bk.job.common.metrics.CommonMetricNames; import com.tencent.bk.job.common.model.error.ErrorType; @@ -57,16 +57,16 @@ * 消息通知 API 客户端 */ @Slf4j -public class CmsiApiClient extends BkApiClient { +public class CmsiApiV1Client extends BkApiV1Client { private static final String API_GET_NOTIFY_CHANNEL_LIST = "/api/c/compapi/cmsi/get_msg_type/"; private static final String API_POST_SEND_MSG = "/api/c/compapi/cmsi/send_msg/"; private final BkApiAuthorization authorization; - public CmsiApiClient(EsbProperties esbProperties, - AppProperties appProperties, - MeterRegistry meterRegistry) { + public CmsiApiV1Client(EsbProperties esbProperties, + AppProperties appProperties, + MeterRegistry meterRegistry) { super( meterRegistry, ESB_CMSI_API, diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/CmsiAutoConfiguration.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/CmsiAutoConfiguration.java index fe5f4a1fd9..fe1fdd84b9 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/CmsiAutoConfiguration.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/CmsiAutoConfiguration.java @@ -26,7 +26,7 @@ import com.tencent.bk.job.common.esb.config.AppProperties; import com.tencent.bk.job.common.esb.config.EsbProperties; -import com.tencent.bk.job.common.paas.cmsi.CmsiApiClient; +import com.tencent.bk.job.common.paas.cmsi.CmsiApiV1Client; import io.micrometer.core.instrument.MeterRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.ObjectProvider; @@ -38,11 +38,11 @@ public class CmsiAutoConfiguration { @Bean - public CmsiApiClient cmsiApiClient(AppProperties appProperties, - EsbProperties esbProperties, - ObjectProvider meterRegistryObjectProvider) { + public CmsiApiV1Client cmsiApiClient(AppProperties appProperties, + EsbProperties esbProperties, + ObjectProvider meterRegistryObjectProvider) { log.info("Init CmsiApiClient"); - return new CmsiApiClient(esbProperties, appProperties, meterRegistryObjectProvider.getIfAvailable()); + return new CmsiApiV1Client(esbProperties, appProperties, meterRegistryObjectProvider.getIfAvailable()); } } diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/LoginAutoConfiguration.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/LoginAutoConfiguration.java index 631c85326a..1f120916b5 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/LoginAutoConfiguration.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/LoginAutoConfiguration.java @@ -25,10 +25,11 @@ package com.tencent.bk.job.common.paas.config; import com.tencent.bk.job.common.esb.config.AppProperties; -import com.tencent.bk.job.common.esb.config.EsbProperties; +import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties; import com.tencent.bk.job.common.paas.login.CustomLoginClient; import com.tencent.bk.job.common.paas.login.ILoginClient; import com.tencent.bk.job.common.paas.login.StandardLoginClient; +import com.tencent.bk.job.common.paas.login.v3.BkLoginApiClient; import io.micrometer.core.instrument.MeterRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.ObjectProvider; @@ -51,18 +52,22 @@ public ILoginClient customLoginClient(@Autowired LoginConfiguration loginConfigu return new CustomLoginClient(loginConfiguration.getCustomLoginApiUrl()); } + @Bean + @ConditionalOnProperty(value = "paas.login.custom.enabled", havingValue = "false", matchIfMissing = true) + public BkLoginApiClient bkLoginApiClient(BkApiGatewayProperties bkApiGatewayProperties, + AppProperties appProperties, + ObjectProvider meterRegistryObjectProvider) { + log.info("Init LoginApiClient"); + return new BkLoginApiClient(bkApiGatewayProperties, appProperties, + meterRegistryObjectProvider.getIfAvailable()); + } + @Bean @ConditionalOnProperty(value = "paas.login.custom.enabled", havingValue = "false", matchIfMissing = true) @Primary - public ILoginClient standardLoginClient(AppProperties appProperties, - EsbProperties esbProperties, - ObjectProvider meterRegistryObjectProvider) { + public ILoginClient standardLoginClient(BkLoginApiClient bkLoginApiClient) { log.info("Init StandardLoginClient"); - return new StandardLoginClient( - esbProperties, - appProperties, - meterRegistryObjectProvider.getIfAvailable() - ); + return new StandardLoginClient(bkLoginApiClient); } } diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/UserMgrAutoConfiguration.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/UserMgrAutoConfiguration.java index ebc6f48c35..40fb1d20e4 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/UserMgrAutoConfiguration.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/config/UserMgrAutoConfiguration.java @@ -25,8 +25,9 @@ package com.tencent.bk.job.common.paas.config; import com.tencent.bk.job.common.esb.config.AppProperties; -import com.tencent.bk.job.common.esb.config.EsbProperties; +import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties; import com.tencent.bk.job.common.paas.user.UserMgrApiClient; +import com.tencent.bk.job.common.tenant.TenantEnvService; import io.micrometer.core.instrument.MeterRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.ObjectProvider; @@ -39,10 +40,16 @@ public class UserMgrAutoConfiguration { @Bean public UserMgrApiClient userMgrApiClient(AppProperties appProperties, - EsbProperties esbProperties, - ObjectProvider meterRegistryObjectProvider) { + BkApiGatewayProperties bkApiGatewayProperties, + ObjectProvider meterRegistryObjectProvider, + TenantEnvService tenantEnvService) { log.info("Init UserMgrApiClient"); - return new UserMgrApiClient(esbProperties, appProperties, meterRegistryObjectProvider.getIfAvailable()); + return new UserMgrApiClient( + bkApiGatewayProperties, + appProperties, + meterRegistryObjectProvider.getIfAvailable(), + tenantEnvService + ); } } diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/StandardLoginClient.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/StandardLoginClient.java index 3f41589aae..0712ed7d25 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/StandardLoginClient.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/StandardLoginClient.java @@ -24,52 +24,18 @@ package com.tencent.bk.job.common.paas.login; -import com.fasterxml.jackson.core.type.TypeReference; -import com.tencent.bk.job.common.constant.ErrorCode; -import com.tencent.bk.job.common.constant.HttpMethodEnum; -import com.tencent.bk.job.common.esb.config.AppProperties; -import com.tencent.bk.job.common.esb.config.EsbProperties; -import com.tencent.bk.job.common.esb.model.BkApiAuthorization; -import com.tencent.bk.job.common.esb.model.EsbResp; -import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; -import com.tencent.bk.job.common.exception.InternalUserManageException; -import com.tencent.bk.job.common.metrics.CommonMetricNames; import com.tencent.bk.job.common.model.dto.BkUserDTO; -import com.tencent.bk.job.common.paas.exception.AppPermissionDeniedException; -import com.tencent.bk.job.common.paas.model.EsbUserDto; -import com.tencent.bk.job.common.util.http.HttpHelperFactory; -import com.tencent.bk.job.common.util.http.HttpMetricUtil; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tag; +import com.tencent.bk.job.common.paas.login.v3.BkLoginApiClient; +import com.tencent.bk.job.common.paas.login.v3.OpenApiBkUser; import lombok.extern.slf4j.Slf4j; -import static com.tencent.bk.job.common.metrics.CommonMetricNames.ESB_BK_LOGIN_API; - @Slf4j -public class StandardLoginClient extends BkApiClient implements ILoginClient { - - // 用户认证失败,即用户登录态无效 - private static final Integer ESB_CODE_USER_NOT_LOGIN = 1302100; - // 用户不存在 - private static final Integer ESB_CODE_USER_NOT_EXIST = 1302103; - // 用户认证成功,但用户无应用访问权限 - private static final Integer ESB_CODE_USER_NO_APP_PERMISSION = 1302403; +public class StandardLoginClient implements ILoginClient { - private static final String API_GET_USER_INFO = "/api/c/compapi/v2/bk_login/get_user/"; + private final BkLoginApiClient bkLoginApiClient; - private final AppProperties appProperties; - - public StandardLoginClient(EsbProperties esbProperties, AppProperties appProperties, MeterRegistry meterRegistry) { - super( - meterRegistry, - ESB_BK_LOGIN_API, - esbProperties.getService().getUrl(), - HttpHelperFactory.createHttpHelper( - httpClientBuilder -> httpClientBuilder.addInterceptorLast(getLogBkApiRequestIdInterceptor()) - ) - ); - this.appProperties = appProperties; + public StandardLoginClient(BkLoginApiClient bkLoginApiClient) { + this.bkLoginApiClient = bkLoginApiClient; } /** @@ -80,56 +46,16 @@ public StandardLoginClient(EsbProperties esbProperties, AppProperties appPropert */ @Override public BkUserDTO getUserInfoByToken(String bkToken) { - try { - HttpMetricUtil.setHttpMetricName(CommonMetricNames.ESB_BK_LOGIN_API_HTTP); - HttpMetricUtil.addTagForCurrentMetric( - Tag.of("api_name", API_GET_USER_INFO) - ); - EsbResp esbResp = doRequest( - OpenApiRequestInfo.builder() - .method(HttpMethodEnum.GET) - .uri(API_GET_USER_INFO) - .addQueryParam("bk_token", bkToken) - .authorization(BkApiAuthorization.bkTokenUserAuthorization( - appProperties.getCode(), appProperties.getSecret(), bkToken)) - .build(), - new TypeReference>() { - } - ); - Integer code = esbResp.getCode(); - if (ErrorCode.RESULT_OK == code) { - return convertToBkUserDTO(esbResp.getData()); - } else { - handleNotOkResp(esbResp); - return null; - } - } catch (Exception e) { - String errorMsg = "Get " + API_GET_USER_INFO + " error"; - log.error(errorMsg, e); - throw new InternalUserManageException(errorMsg, e, ErrorCode.USER_MANAGE_API_ACCESS_ERROR); - } finally { - HttpMetricUtil.clearHttpMetric(); - } - } - - private void handleNotOkResp(EsbResp esbResp) { - Integer code = esbResp.getCode(); - if (ESB_CODE_USER_NO_APP_PERMISSION.equals(code)) { - throw new AppPermissionDeniedException(esbResp.getMessage()); - } else if (ESB_CODE_USER_NOT_LOGIN.equals(code)) { - log.info("User not login, esbResp.code={}, esbResp.message={}", esbResp.getCode(), esbResp.getMessage()); - } else if (ESB_CODE_USER_NOT_EXIST.equals(code)) { - log.info("User not exist, esbResp.code={}, esbResp.message={}", esbResp.getCode(), esbResp.getMessage()); + OpenApiBkUser bkUser = bkLoginApiClient.getBkUserByToken(bkToken); + if (bkUser == null) { + return null; } - } - - private BkUserDTO convertToBkUserDTO(EsbUserDto esbUserDto) { BkUserDTO bkUserDTO = new BkUserDTO(); - bkUserDTO.setUsername(esbUserDto.getUsername()); - bkUserDTO.setEmail(esbUserDto.getEmail()); - bkUserDTO.setPhone(esbUserDto.getPhone()); - bkUserDTO.setWxUserId(esbUserDto.getWxUserId()); - bkUserDTO.setTimeZone(esbUserDto.getTimeZone()); + bkUserDTO.setUsername(bkUser.getUsername()); + bkUserDTO.setDisplayName(bkUser.getDisplayName()); + bkUserDTO.setTimeZone(bkUser.getTimeZone()); + bkUserDTO.setTenantId(bkUser.getTenantId()); + bkUserDTO.setLanguage(bkUser.getLanguage()); return bkUserDTO; } } diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/BkLoginApiClient.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/BkLoginApiClient.java new file mode 100644 index 0000000000..0acc29d62e --- /dev/null +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/BkLoginApiClient.java @@ -0,0 +1,112 @@ +package com.tencent.bk.job.common.paas.login.v3; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.tencent.bk.job.common.constant.ErrorCode; +import com.tencent.bk.job.common.constant.HttpMethodEnum; +import com.tencent.bk.job.common.constant.JobCommonHeaders; +import com.tencent.bk.job.common.esb.config.AppProperties; +import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties; +import com.tencent.bk.job.common.esb.exception.BkOpenApiException; +import com.tencent.bk.job.common.esb.model.BkApiAuthorization; +import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; +import com.tencent.bk.job.common.esb.model.OpenApiResponse; +import com.tencent.bk.job.common.esb.sdk.BkApiV2Client; +import com.tencent.bk.job.common.exception.InternalException; +import com.tencent.bk.job.common.util.http.HttpHelperFactory; +import com.tencent.bk.job.common.util.http.HttpMetricUtil; +import com.tencent.bk.job.common.util.json.JsonUtils; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpStatus; +import org.apache.http.message.BasicHeader; + +import java.util.function.Function; + +import static com.tencent.bk.job.common.metrics.CommonMetricNames.BK_LOGIN_API; +import static com.tencent.bk.job.common.metrics.CommonMetricNames.BK_LOGIN_API_HTTP; + +@Slf4j +public class BkLoginApiClient extends BkApiV2Client { + + public static final String API_URL_USERINFO = "/login/api/v3/open/bk-tokens/userinfo"; + + protected final BkApiAuthorization authorization; + + + public BkLoginApiClient(BkApiGatewayProperties bkApiGatewayProperties, + AppProperties appProperties, + MeterRegistry meterRegistry) { + super( + meterRegistry, + BK_LOGIN_API, + bkApiGatewayProperties.getBkLogin().getUrl(), + HttpHelperFactory.createHttpHelper( + httpClientBuilder -> httpClientBuilder.addInterceptorLast(getLogBkApiRequestIdInterceptor()) + ) + ); + this.authorization = BkApiAuthorization.appAuthorization( + appProperties.getCode(), appProperties.getSecret()); + } + + + /** + * 根据 token 获取用户信息 + * + * @param token 用户登录 token + * @return 用户信息 + */ + public OpenApiBkUser getBkUserByToken(String token) { + OpenApiResponse response = requestBkLoginApi( + "get_bk_token_userinfo", + OpenApiRequestInfo + .builder() + .method(HttpMethodEnum.GET) + .uri(API_URL_USERINFO) + .queryParams("bk_token=" + token) + .body(null) + // 登录相关 API ,需要写死租户 ID 为 system + .addHeader(new BasicHeader(JobCommonHeaders.BK_TENANT_ID, "system")) + .authorization(authorization) + .build(), + request -> { + try { + return doRequest(request, new TypeReference>() { + }); + } catch (BkOpenApiException e) { + if (e.getStatusCode() == HttpStatus.SC_BAD_REQUEST) { + // http status = 400 表示登录态已过期 + return OpenApiResponse.success(null); + } else { + throw e; + } + } + } + ); + + return response.getData(); + } + + + protected OpenApiResponse requestBkLoginApi( + String apiName, + OpenApiRequestInfo request, + Function, OpenApiResponse> requestHandler) { + + try { + HttpMetricUtil.setHttpMetricName(BK_LOGIN_API_HTTP); + HttpMetricUtil.addTagForCurrentMetric(Tag.of("api_name", apiName)); + return requestHandler.apply(request); + } catch (Throwable e) { + String errorMsg = "Fail to request bk-login api|method=" + request.getMethod() + + "|uri=" + request.getUri() + "|queryParams=" + + request.getQueryParams() + "|body=" + + JsonUtils.toJsonWithoutSkippedFields(JsonUtils.toJsonWithoutSkippedFields(request.getBody())); + log.error(errorMsg, e); + throw new InternalException(e.getMessage(), e, ErrorCode.BK_LOGIN_API_ERROR); + } finally { + HttpMetricUtil.clearHttpMetric(); + } + } + +} diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/OpenApiBkUser.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/OpenApiBkUser.java new file mode 100644 index 0000000000..5b3cc2bcc5 --- /dev/null +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/login/v3/OpenApiBkUser.java @@ -0,0 +1,43 @@ +package com.tencent.bk.job.common.paas.login.v3; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * 用户信息 + */ +@Data +public class OpenApiBkUser { + + /** + * 用户唯一标识,全局唯一 + */ + @JsonProperty("bk_username") + private String username; + + /** + * 用户所属租户 ID + */ + @JsonProperty("tenant_id") + private String tenantId; + + /** + * 用户展示名 + */ + @JsonProperty("display_name") + private String displayName; + + /** + * 用户语言,枚举值:zh-cn / en + */ + @JsonProperty("language") + private String language; + + /** + * 用户所在时区 + */ + @JsonProperty("time_zone") + private String timeZone; + + +} diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/OpenApiTenant.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/OpenApiTenant.java new file mode 100644 index 0000000000..66042e8307 --- /dev/null +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/OpenApiTenant.java @@ -0,0 +1,27 @@ +package com.tencent.bk.job.common.paas.model; + +import lombok.Data; + +/** + * 租户信息 + */ +@Data +public class OpenApiTenant { + + /** + * 租户 ID + */ + private String id; + + /** + * 租户名 + */ + private String name; + + /** + * 租户状态,enabled 表示启用,disabled 表示禁用 + * + * @see TenantStatusEnum + */ + private String status; +} diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/TenantStatusEnum.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/TenantStatusEnum.java new file mode 100644 index 0000000000..9e437f941d --- /dev/null +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/model/TenantStatusEnum.java @@ -0,0 +1,40 @@ +package com.tencent.bk.job.common.paas.model; + +/** + * 租户状态 + */ +public enum TenantStatusEnum { + + /** + * 启用 + */ + ENABLED(Constants.ENABLED), + /** + * 禁用 + */ + DISABLED(Constants.DISABLED); + + TenantStatusEnum(String status) { + this.status = status; + } + + public interface Constants { + String ENABLED = "enabled"; + String DISABLED = "disabled"; + } + + private final String status; + + public static TenantStatusEnum valOf(String status) { + for (TenantStatusEnum value : values()) { + if (value.status.equalsIgnoreCase(status)) { + return value; + } + } + throw new IllegalArgumentException("No TenantStatusEnum constant: " + status); + } + + public String getStatus() { + return status; + } +} diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java index adaad49bf7..393d691fcc 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java @@ -27,54 +27,64 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.tencent.bk.job.common.constant.ErrorCode; import com.tencent.bk.job.common.constant.HttpMethodEnum; +import com.tencent.bk.job.common.constant.JobCommonHeaders; import com.tencent.bk.job.common.esb.config.AppProperties; -import com.tencent.bk.job.common.esb.config.EsbProperties; -import com.tencent.bk.job.common.esb.constants.EsbLang; +import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties; import com.tencent.bk.job.common.esb.metrics.EsbMetricTags; import com.tencent.bk.job.common.esb.model.BkApiAuthorization; import com.tencent.bk.job.common.esb.model.EsbResp; import com.tencent.bk.job.common.esb.model.OpenApiRequestInfo; -import com.tencent.bk.job.common.esb.sdk.BkApiClient; +import com.tencent.bk.job.common.esb.model.OpenApiResponse; +import com.tencent.bk.job.common.esb.sdk.BkApiV2Client; +import com.tencent.bk.job.common.exception.InternalException; import com.tencent.bk.job.common.exception.InternalUserManageException; -import com.tencent.bk.job.common.metrics.CommonMetricNames; import com.tencent.bk.job.common.model.dto.BkUserDTO; import com.tencent.bk.job.common.paas.model.EsbListUsersResult; import com.tencent.bk.job.common.paas.model.GetUserListReq; +import com.tencent.bk.job.common.paas.model.OpenApiTenant; +import com.tencent.bk.job.common.tenant.TenantEnvService; import com.tencent.bk.job.common.util.http.HttpHelperFactory; import com.tencent.bk.job.common.util.http.HttpMetricUtil; +import com.tencent.bk.job.common.util.json.JsonUtils; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.apache.http.message.BasicHeader; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Function; -import static com.tencent.bk.job.common.metrics.CommonMetricNames.ESB_USER_MANAGE_API; +import static com.tencent.bk.job.common.metrics.CommonMetricNames.USER_MANAGE_API; +import static com.tencent.bk.job.common.metrics.CommonMetricNames.USER_MANAGE_API_HTTP; /** * 用户管理 API 客户端 */ @Slf4j -public class UserMgrApiClient extends BkApiClient { +public class UserMgrApiClient extends BkApiV2Client { private static final String API_GET_USER_LIST = "/api/c/compapi/v2/usermanage/list_users/"; private final BkApiAuthorization authorization; - public UserMgrApiClient(EsbProperties esbProperties, + private final TenantEnvService tenantEnvService; + + public UserMgrApiClient(BkApiGatewayProperties bkApiGatewayProperties, AppProperties appProperties, - MeterRegistry meterRegistry) { + MeterRegistry meterRegistry, + TenantEnvService tenantEnvService) { super(meterRegistry, - ESB_USER_MANAGE_API, - esbProperties.getService().getUrl(), - HttpHelperFactory.getRetryableHttpHelper(), - EsbLang.EN + USER_MANAGE_API, + bkApiGatewayProperties.getBkUser().getUrl(), + HttpHelperFactory.getRetryableHttpHelper() ); this.authorization = BkApiAuthorization.appAuthorization(appProperties.getCode(), - appProperties.getSecret(), "admin"); + appProperties.getSecret()); + this.tenantEnvService = tenantEnvService; } public List getAllUserList() { @@ -83,7 +93,7 @@ public List getAllUserList() { try { GetUserListReq req = buildGetUserListReq(fields); - HttpMetricUtil.setHttpMetricName(CommonMetricNames.ESB_USER_MANAGE_API_HTTP); + HttpMetricUtil.setHttpMetricName(USER_MANAGE_API_HTTP); HttpMetricUtil.addTagForCurrentMetric( Tag.of(EsbMetricTags.KEY_API_NAME, API_GET_USER_LIST) ); @@ -101,7 +111,7 @@ public List getAllUserList() { } catch (Exception e) { String errorMsg = "Get " + API_GET_USER_LIST + " error"; log.error(errorMsg, e); - throw new InternalUserManageException(errorMsg, e, ErrorCode.USER_MANAGE_API_ACCESS_ERROR); + throw new InternalUserManageException(errorMsg, e, ErrorCode.BK_USER_MANAGE_API_ERROR); } finally { HttpMetricUtil.clearHttpMetric(); } @@ -136,4 +146,47 @@ private List convert(List esbUserList) { return userList; } + + /** + * 获取全量租户 + */ + public List listAllTenant() { + OpenApiResponse> response = requestBkUserApi( + "list_tenant", + OpenApiRequestInfo + .builder() + .method(HttpMethodEnum.GET) + .uri("/api/v3/open/tenants") + .addHeader(new BasicHeader(JobCommonHeaders.BK_TENANT_ID, tenantEnvService.getDefaultTenantId())) + .authorization(authorization) + .build(), + request -> doRequest(request, new TypeReference>>() { + }) + ); + + return response.getData(); + } + + + protected OpenApiResponse requestBkUserApi( + String apiName, + OpenApiRequestInfo request, + Function, OpenApiResponse> requestHandler) { + + try { + HttpMetricUtil.setHttpMetricName(USER_MANAGE_API_HTTP); + HttpMetricUtil.addTagForCurrentMetric(Tag.of("api_name", apiName)); + return requestHandler.apply(request); + } catch (Throwable e) { + String errorMsg = "Fail to request bk-user api|method=" + request.getMethod() + + "|uri=" + request.getUri() + "|queryParams=" + + request.getQueryParams() + "|body=" + + JsonUtils.toJsonWithoutSkippedFields(JsonUtils.toJsonWithoutSkippedFields(request.getBody())); + log.error(errorMsg, e); + throw new InternalException(e.getMessage(), e, ErrorCode.BK_USER_MANAGE_API_ERROR); + } finally { + HttpMetricUtil.clearHttpMetric(); + } + } + } diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/config/GseConfig.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/config/GseConfig.java index 7a719dc371..4ba63a57e8 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/config/GseConfig.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/config/GseConfig.java @@ -33,7 +33,7 @@ import com.tencent.bk.job.common.gse.service.GseV2AgentStateClientImpl; import com.tencent.bk.job.common.gse.service.UseV2ByFeatureAgentStateClientImpl; import com.tencent.bk.job.common.gse.v1.GseV1ApiClient; -import com.tencent.bk.job.common.gse.v2.GseV2ApiClient; +import com.tencent.bk.job.common.gse.v2.GseV2ApiV1Client; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; @@ -66,7 +66,7 @@ public GseV1AgentStateClientImpl gseV1AgentStateClient(AgentStateQueryConfig age @Bean(EXECUTE_BEAN_GSE_V2_AGENT_STATE_CLIENT) public GseV2AgentStateClientImpl gseV2AgentStateClient(AgentStateQueryConfig agentStateQueryConfig, - ObjectProvider gseV2ApiClient, + ObjectProvider gseV2ApiClient, @Qualifier(DefaultBeanNames.AGENT_STATUS_QUERY_THREAD_POOL_EXECUTOR) ThreadPoolExecutor threadPoolExecutor) { return new GseV2AgentStateClientImpl( diff --git a/src/backend/job-manage/boot-job-manage/src/main/resources/logback-spring.xml b/src/backend/job-manage/boot-job-manage/src/main/resources/logback-spring.xml index 9f69e27f46..9bd041ccea 100644 --- a/src/backend/job-manage/boot-job-manage/src/main/resources/logback-spring.xml +++ b/src/backend/job-manage/boot-job-manage/src/main/resources/logback-spring.xml @@ -47,7 +47,7 @@ - + @@ -57,7 +57,7 @@ - + @@ -68,7 +68,7 @@ - + @@ -80,7 +80,7 @@ - + diff --git a/src/backend/job-manage/boot-job-manage/src/test/resources/application-test.yml b/src/backend/job-manage/boot-job-manage/src/test/resources/application-test.yml index 0400e83847..ab1d157219 100644 --- a/src/backend/job-manage/boot-job-manage/src/test/resources/application-test.yml +++ b/src/backend/job-manage/boot-job-manage/src/test/resources/application-test.yml @@ -33,6 +33,9 @@ bk-api-gateway: url: bk-notice.apigw.com cmdb: url: cmdb.apigw.com + bk-login: + url : bk-login.apigw.com esb: service: url: esb.service + diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/GseConfig.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/GseConfig.java index 93b0117b30..f8f00dfbe5 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/GseConfig.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/GseConfig.java @@ -33,7 +33,7 @@ import com.tencent.bk.job.common.gse.service.GseV2AgentStateClientImpl; import com.tencent.bk.job.common.gse.service.UseV2ByFeatureAgentStateClientImpl; import com.tencent.bk.job.common.gse.v1.GseV1ApiClient; -import com.tencent.bk.job.common.gse.v2.GseV2ApiClient; +import com.tencent.bk.job.common.gse.v2.GseV2ApiV1Client; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; @@ -66,7 +66,7 @@ public GseV1AgentStateClientImpl gseV1AgentStateClient(AgentStateQueryConfig age @Bean(MANAGE_BEAN_GSE_V2_AGENT_STATE_CLIENT) public GseV2AgentStateClientImpl gseV2AgentStateClient(AgentStateQueryConfig agentStateQueryConfig, - ObjectProvider gseV2ApiClient, + ObjectProvider gseV2ApiClient, @Qualifier(DefaultBeanNames.AGENT_STATUS_QUERY_THREAD_POOL_EXECUTOR) ThreadPoolExecutor threadPoolExecutor) { return new GseV2AgentStateClientImpl( diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/listener/NotifyInitListener.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/listener/NotifyInitListener.java index 958b20a47f..90ee302b82 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/listener/NotifyInitListener.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/config/listener/NotifyInitListener.java @@ -25,7 +25,7 @@ package com.tencent.bk.job.manage.config.listener; import com.tencent.bk.job.common.mysql.JobTransactional; -import com.tencent.bk.job.common.paas.cmsi.CmsiApiClient; +import com.tencent.bk.job.common.paas.cmsi.CmsiApiV1Client; import com.tencent.bk.job.common.paas.model.EsbNotifyChannelDTO; import com.tencent.bk.job.common.util.StringUtil; import com.tencent.bk.job.manage.api.common.constants.notify.ExecuteStatusEnum; @@ -60,7 +60,7 @@ @Profile("!test") public class NotifyInitListener implements ApplicationListener { - private final CmsiApiClient cmsiApiClient; + private final CmsiApiV1Client cmsiApiClient; private final GlobalSettingsService globalSettingsService; private final NotifyService notifyService; private final AvailableEsbChannelDAO availableEsbChannelDAO; @@ -70,7 +70,7 @@ public class NotifyInitListener implements ApplicationListener> esbChannelCache = CacheBuilder.newBuilder() .maximumSize(10).expireAfterWrite(10, TimeUnit.MINUTES). build(new CacheLoader>() { @@ -73,7 +73,7 @@ public List load(@NonNull String searchKey) { } ); - public NotifyEsbChannelDAOImpl(CmsiApiClient cmsiApiClient) { + public NotifyEsbChannelDAOImpl(CmsiApiV1Client cmsiApiClient) { this.cmsiApiClient = cmsiApiClient; } diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/agent/status/impl/ScopeAgentStatusServiceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/agent/status/impl/ScopeAgentStatusServiceImpl.java index ebcd0d72c5..3633d0c84d 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/agent/status/impl/ScopeAgentStatusServiceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/agent/status/impl/ScopeAgentStatusServiceImpl.java @@ -2,7 +2,7 @@ import com.tencent.bk.job.common.gse.IGseClient; import com.tencent.bk.job.common.gse.v1.GseV1ApiClient; -import com.tencent.bk.job.common.gse.v2.GseV2ApiClient; +import com.tencent.bk.job.common.gse.v2.GseV2ApiV1Client; import com.tencent.bk.job.common.gse.v2.model.req.ListAgentStateReq; import com.tencent.bk.job.common.gse.v2.model.resp.AgentState; import com.tencent.bk.job.common.model.dto.ResourceScope; @@ -22,10 +22,10 @@ public class ScopeAgentStatusServiceImpl implements ScopeAgentStatusService { private final GseV1ApiClient gseV1ApiClient; - private final GseV2ApiClient gseV2ApiClient; + private final GseV2ApiV1Client gseV2ApiClient; public ScopeAgentStatusServiceImpl(@Autowired(required = false) GseV1ApiClient gseV1ApiClient, - @Autowired(required = false) GseV2ApiClient gseV2ApiClient) { + @Autowired(required = false) GseV2ApiV1Client gseV2ApiClient) { this.gseV1ApiClient = gseV1ApiClient; this.gseV2ApiClient = gseV2ApiClient; } diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/WatchableSendMsgService.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/WatchableSendMsgService.java index d7f6317a4e..f5dce12346 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/WatchableSendMsgService.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/WatchableSendMsgService.java @@ -25,7 +25,7 @@ package com.tencent.bk.job.manage.service.impl; import com.tencent.bk.job.common.esb.metrics.EsbApiTimed; -import com.tencent.bk.job.common.paas.cmsi.CmsiApiClient; +import com.tencent.bk.job.common.paas.cmsi.CmsiApiV1Client; import com.tencent.bk.job.manage.metrics.MetricsConstants; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; @@ -43,11 +43,11 @@ @Service public class WatchableSendMsgService { - private final CmsiApiClient cmsiApiClient; + private final CmsiApiV1Client cmsiApiClient; private final MeterRegistry meterRegistry; @Autowired - public WatchableSendMsgService(CmsiApiClient cmsiApiClient, + public WatchableSendMsgService(CmsiApiV1Client cmsiApiClient, MeterRegistry meterRegistry) { this.cmsiApiClient = cmsiApiClient; this.meterRegistry = meterRegistry; diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/task/ScheduledTasks.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/task/ScheduledTasks.java index 4bde99c310..da1210159f 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/task/ScheduledTasks.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/task/ScheduledTasks.java @@ -48,7 +48,8 @@ public ScheduledTasks( EsbUserInfoUpdateTask esbUserInfoUpdateTask, SyncService syncService, UserUploadFileCleanTask userUploadFileCleanTask, - ClearDeletedHostsTask clearDeletedHostsTask, ApplicationCache applicationCache) { + ClearDeletedHostsTask clearDeletedHostsTask, + ApplicationCache applicationCache) { this.esbUserInfoUpdateTask = esbUserInfoUpdateTask; this.syncService = syncService; this.userUploadFileCleanTask = userUploadFileCleanTask; diff --git a/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/iam/ApiClientUtils.java b/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/iam/ApiClientUtils.java index 74ac3cd4b6..475bcd8449 100644 --- a/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/iam/ApiClientUtils.java +++ b/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/iam/ApiClientUtils.java @@ -26,20 +26,20 @@ import com.tencent.bk.job.common.esb.config.AppProperties; import com.tencent.bk.job.common.esb.config.EsbProperties; -import com.tencent.bk.job.common.iam.client.EsbIamClient; +import com.tencent.bk.job.common.iam.client.EsbIamV1Client; import com.tencent.bk.job.upgrader.task.param.ParamNameConsts; import java.util.Properties; public class ApiClientUtils { - public static EsbIamClient buildEsbIamClient(Properties properties) { + public static EsbIamV1Client buildEsbIamClient(Properties properties) { EsbProperties esbProperties = new EsbProperties(); EsbProperties.EsbServiceConfig esbServiceConfig = new EsbProperties.EsbServiceConfig(); esbServiceConfig.setUrl((String) properties.get(ParamNameConsts.CONFIG_PROPERTY_ESB_SERVICE_URL)); esbProperties.setService(esbServiceConfig); - return new EsbIamClient( + return new EsbIamV1Client( null, new AppProperties( (String) properties.get(ParamNameConsts.CONFIG_PROPERTY_APP_CODE), diff --git a/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/ManagePublicScriptPermissionMigrationTask.java b/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/ManagePublicScriptPermissionMigrationTask.java index 704b06280c..9e3c4c54bf 100644 --- a/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/ManagePublicScriptPermissionMigrationTask.java +++ b/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/ManagePublicScriptPermissionMigrationTask.java @@ -24,7 +24,7 @@ package com.tencent.bk.job.upgrader.task; -import com.tencent.bk.job.common.iam.client.EsbIamClient; +import com.tencent.bk.job.common.iam.client.EsbIamV1Client; import com.tencent.bk.job.common.iam.constant.ActionId; import com.tencent.bk.job.common.iam.constant.ResourceTypeEnum; import com.tencent.bk.job.common.iam.dto.EsbIamAction; @@ -58,7 +58,7 @@ public class ManagePublicScriptPermissionMigrationTask extends BaseUpgradeTask { private IamClient iamClient; - private EsbIamClient esbIamClient; + private EsbIamV1Client esbIamClient; public ManagePublicScriptPermissionMigrationTask(Properties properties) { super(properties); @@ -76,7 +76,7 @@ private IamClient getIamClient() { return iamClient; } - private EsbIamClient getEsbIamClient() { + private EsbIamV1Client getEsbIamClient() { if (this.esbIamClient == null) { this.esbIamClient = ApiClientUtils.buildEsbIamClient(getProperties()); } diff --git a/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/UseAccountPermissionMigrationTask.java b/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/UseAccountPermissionMigrationTask.java index 196232b13f..c1aef4a31c 100644 --- a/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/UseAccountPermissionMigrationTask.java +++ b/src/backend/upgrader/src/main/java/com/tencent/bk/job/upgrader/task/UseAccountPermissionMigrationTask.java @@ -24,7 +24,7 @@ package com.tencent.bk.job.upgrader.task; -import com.tencent.bk.job.common.iam.client.EsbIamClient; +import com.tencent.bk.job.common.iam.client.EsbIamV1Client; import com.tencent.bk.job.common.iam.constant.ActionId; import com.tencent.bk.job.common.iam.constant.ResourceTypeEnum; import com.tencent.bk.job.common.iam.dto.EsbIamAction; @@ -76,7 +76,7 @@ public class UseAccountPermissionMigrationTask extends BaseUpgradeTask { private JobClient jobManageClient; private IamClient iamClient; - private EsbIamClient esbIamClient; + private EsbIamV1Client esbIamClient; private List basicAppInfoList; private Map appInfoMap; @@ -111,7 +111,7 @@ private IamClient getIamClient() { return iamClient; } - private EsbIamClient getEsbIamClient() { + private EsbIamV1Client getEsbIamClient() { if (this.esbIamClient == null) { this.esbIamClient = ApiClientUtils.buildEsbIamClient(getProperties()); } diff --git a/support-files/sql/job-manage/0032_job_manage_20250103-1000_V3.12.0_mysql.sql b/support-files/sql/job-manage/0032_job_manage_20250103-1000_V3.12.0_mysql.sql new file mode 100644 index 0000000000..586f00f34a --- /dev/null +++ b/support-files/sql/job-manage/0032_job_manage_20250103-1000_V3.12.0_mysql.sql @@ -0,0 +1,37 @@ +USE job_manage; + +SET NAMES utf8mb4; + +DROP PROCEDURE IF EXISTS job_schema_update; + +DELIMITER + +CREATE PROCEDURE job_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; + SELECT DATABASE() INTO db; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.columns + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'application' + AND COLUMN_NAME = 'tenant_id') THEN + ALTER TABLE application ADD COLUMN tenant_id VARCHAR(32) NOT NULL DEFAULT 'default'; + END IF; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'application' + AND INDEX_NAME = 'idx_tenant_id') THEN + ALTER TABLE application ADD INDEX idx_tenant_id(`tenant_id`); + END IF; + +COMMIT; +END +DELIMITER ; +CALL job_schema_update(); + +DROP PROCEDURE IF EXISTS job_schema_update;