This is an automated email from the ASF dual-hosted git repository.
liuhaopeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git
The following commit(s) were added to refs/heads/main by this push:
new 031058fc BIGTOP-4402: Fix component related jobs (#202)
031058fc is described below
commit 031058fca9137f285892e772703021bee10eb2ad
Author: Zhiguo Wu <[email protected]>
AuthorDate: Wed Apr 9 15:25:14 2025 +0800
BIGTOP-4402: Fix component related jobs (#202)
---
.../manager/server/command/job/AbstractJob.java | 8 +++++
.../command/job/component/ComponentAddJob.java | 42 +++++++++++++++++++---
.../command/job/service/AbstractServiceJob.java | 2 +-
.../server/command/stage/AbstractStage.java | 8 +++++
.../command/validator/ClusterStartValidator.java | 13 +++++++
...artValidator.java => ComponentOpValidator.java} | 35 ++++++++++--------
.../manager/server/enums/ApiExceptionEnum.java | 5 +++
.../bigtop/manager/server/enums/LocaleKeys.java | 5 +++
.../bigtop/manager/server/model/vo/CommandVO.java | 2 ++
.../server/service/impl/JobServiceImpl.java | 25 ++++++++++---
.../main/resources/i18n/messages_en_US.properties | 5 +++
.../main/resources/i18n/messages_zh_CN.properties | 5 +++
12 files changed, 132 insertions(+), 23 deletions(-)
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
index ec7dd6c0..64e83876 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/AbstractJob.java
@@ -32,8 +32,12 @@ import
org.apache.bigtop.manager.server.command.helper.JobCacheHelper;
import org.apache.bigtop.manager.server.command.stage.Stage;
import org.apache.bigtop.manager.server.command.stage.StageContext;
import org.apache.bigtop.manager.server.command.task.Task;
+import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
+import org.apache.bigtop.manager.server.exception.ApiException;
import org.apache.bigtop.manager.server.holder.SpringContextHolder;
+import org.apache.commons.collections4.CollectionUtils;
+
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
@@ -67,6 +71,10 @@ public abstract class AbstractJob implements Job {
beforeCreateStages();
createStages();
+
+ if (CollectionUtils.isEmpty(stages)) {
+ throw new ApiException(ApiExceptionEnum.JOB_HAS_NO_STAGES);
+ }
}
protected void injectBeans() {
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/component/ComponentAddJob.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/component/ComponentAddJob.java
index 99a3fd01..9bca282f 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/component/ComponentAddJob.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/component/ComponentAddJob.java
@@ -22,6 +22,7 @@ import org.apache.bigtop.manager.common.enums.Command;
import org.apache.bigtop.manager.dao.po.ComponentPO;
import org.apache.bigtop.manager.dao.po.HostPO;
import org.apache.bigtop.manager.dao.po.ServicePO;
+import org.apache.bigtop.manager.dao.query.ComponentQuery;
import org.apache.bigtop.manager.server.command.helper.ComponentStageHelper;
import org.apache.bigtop.manager.server.command.job.JobContext;
import org.apache.bigtop.manager.server.enums.HealthyStatusEnum;
@@ -32,7 +33,10 @@ import org.apache.bigtop.manager.server.model.dto.ServiceDTO;
import org.apache.bigtop.manager.server.model.dto.command.ComponentCommandDTO;
import org.apache.bigtop.manager.server.utils.StackUtils;
+import org.apache.commons.collections4.CollectionUtils;
+
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -93,6 +97,10 @@ public class ComponentAddJob extends AbstractComponentJob {
List<ComponentPO> componentPOList = new ArrayList<>();
List<String> hostnames = componentCommand.getHostnames();
for (String hostname : hostnames) {
+ if (checkComponentInstalled(componentName, hostname)) {
+ continue;
+ }
+
HostPO hostPO = hostDao.findByHostname(hostname);
ComponentDTO componentDTO =
StackUtils.getComponentDTO(componentName);
ComponentPO componentPO =
ComponentConverter.INSTANCE.fromDTO2PO(componentDTO);
@@ -103,10 +111,36 @@ public class ComponentAddJob extends AbstractComponentJob
{
componentPOList.add(componentPO);
}
- componentDao.saveAll(componentPOList);
+ if (CollectionUtils.isNotEmpty(componentPOList)) {
+ componentDao.saveAll(componentPOList);
+
+ // Require restart after adding new components
+ servicePO.setRestartFlag(true);
+ serviceDao.partialUpdateById(servicePO);
+ }
+ }
+
+ protected Map<String, List<String>> getComponentHostsMap() {
+ Map<String, List<String>> componentHostsMap = new HashMap<>();
+
+
jobContext.getCommandDTO().getComponentCommands().forEach(componentCommand -> {
+ String componentName = componentCommand.getComponentName();
+ List<String> hostnames = componentCommand.getHostnames();
+ for (String hostname : hostnames) {
+ if (!checkComponentInstalled(componentName, hostname)) {
+ List<String> list =
componentHostsMap.computeIfAbsent(componentName, k -> new ArrayList<>());
+ list.add(hostname);
+ }
+ }
+ });
+
+ return componentHostsMap;
+ }
- // Require restart after adding new components
- servicePO.setRestartFlag(true);
- serviceDao.partialUpdateById(servicePO);
+ private Boolean checkComponentInstalled(String componentName, String
hostname) {
+ ComponentQuery query =
+
ComponentQuery.builder().name(componentName).hostname(hostname).build();
+ List<ComponentPO> componentPOList = componentDao.findByQuery(query);
+ return componentPOList.size() == 1;
}
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/service/AbstractServiceJob.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/service/AbstractServiceJob.java
index d32400b9..c8ab24ab 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/service/AbstractServiceJob.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/job/service/AbstractServiceJob.java
@@ -66,7 +66,7 @@ public abstract class AbstractServiceJob extends AbstractJob {
protected Map<String, List<String>> getComponentHostsMap() {
List<String> serviceNames = getServiceNames();
ComponentQuery componentQuery = ComponentQuery.builder()
- .clusterId(clusterPO.getId())
+ .clusterId(clusterPO == null ? 0L : clusterPO.getId())
.serviceNames(serviceNames)
.build();
List<ComponentPO> componentPOList =
componentDao.findByQuery(componentQuery);
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
index 47f99871..7aeab038 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java
@@ -24,8 +24,12 @@ import org.apache.bigtop.manager.dao.po.StagePO;
import org.apache.bigtop.manager.dao.repository.HostDao;
import org.apache.bigtop.manager.dao.repository.StageDao;
import org.apache.bigtop.manager.server.command.task.Task;
+import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
+import org.apache.bigtop.manager.server.exception.ApiException;
import org.apache.bigtop.manager.server.holder.SpringContextHolder;
+import org.apache.commons.collections4.CollectionUtils;
+
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
@@ -57,6 +61,10 @@ public abstract class AbstractStage implements Stage {
for (String hostname : stageContext.getHostnames()) {
tasks.add(createTask(hostname));
}
+
+ if (CollectionUtils.isEmpty(tasks)) {
+ throw new ApiException(ApiExceptionEnum.STAGE_HAS_NO_TASKS,
getName());
+ }
}
protected void injectBeans() {
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
index e8677430..1d8da921 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
@@ -19,7 +19,10 @@
package org.apache.bigtop.manager.server.command.validator;
import org.apache.bigtop.manager.common.enums.Command;
+import org.apache.bigtop.manager.dao.po.ComponentPO;
import org.apache.bigtop.manager.dao.po.ServicePO;
+import org.apache.bigtop.manager.dao.query.ComponentQuery;
+import org.apache.bigtop.manager.dao.repository.ComponentDao;
import org.apache.bigtop.manager.dao.repository.ServiceDao;
import org.apache.bigtop.manager.server.command.CommandIdentifier;
import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
@@ -39,6 +42,9 @@ public class ClusterStartValidator implements
CommandValidator {
@Resource
private ServiceDao serviceDao;
+ @Resource
+ private ComponentDao componentDao;
+
@Override
public List<CommandIdentifier> getCommandIdentifiers() {
return List.of(new CommandIdentifier(CommandLevel.CLUSTER,
Command.START));
@@ -52,5 +58,12 @@ public class ClusterStartValidator implements
CommandValidator {
if (CollectionUtils.isEmpty(servicePOList)) {
throw new ApiException(ApiExceptionEnum.CLUSTER_HAS_NO_SERVICES);
}
+
+ ComponentQuery componentQuery =
+ ComponentQuery.builder().clusterId(clusterId).build();
+ List<ComponentPO> componentPOList =
componentDao.findByQuery(componentQuery);
+ if (CollectionUtils.isEmpty(componentPOList)) {
+ throw new ApiException(ApiExceptionEnum.CLUSTER_HAS_NO_COMPONENTS);
+ }
}
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ComponentOpValidator.java
similarity index 53%
copy from
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
copy to
bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ComponentOpValidator.java
index e8677430..86d529db 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ClusterStartValidator.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/validator/ComponentOpValidator.java
@@ -18,39 +18,46 @@
*/
package org.apache.bigtop.manager.server.command.validator;
+import org.apache.bigtop.manager.common.constants.ComponentCategories;
import org.apache.bigtop.manager.common.enums.Command;
-import org.apache.bigtop.manager.dao.po.ServicePO;
-import org.apache.bigtop.manager.dao.repository.ServiceDao;
import org.apache.bigtop.manager.server.command.CommandIdentifier;
import org.apache.bigtop.manager.server.enums.ApiExceptionEnum;
import org.apache.bigtop.manager.server.enums.CommandLevel;
import org.apache.bigtop.manager.server.exception.ApiException;
-
-import org.apache.commons.collections4.CollectionUtils;
+import org.apache.bigtop.manager.server.model.dto.ComponentDTO;
+import org.apache.bigtop.manager.server.model.dto.command.ComponentCommandDTO;
+import org.apache.bigtop.manager.server.utils.StackUtils;
import org.springframework.stereotype.Component;
-import jakarta.annotation.Resource;
import java.util.List;
+import java.util.Objects;
@Component
-public class ClusterStartValidator implements CommandValidator {
-
- @Resource
- private ServiceDao serviceDao;
+public class ComponentOpValidator implements CommandValidator {
@Override
public List<CommandIdentifier> getCommandIdentifiers() {
- return List.of(new CommandIdentifier(CommandLevel.CLUSTER,
Command.START));
+ return List.of(
+ new CommandIdentifier(CommandLevel.COMPONENT, Command.START),
+ new CommandIdentifier(CommandLevel.COMPONENT, Command.STOP),
+ new CommandIdentifier(CommandLevel.COMPONENT,
Command.RESTART));
}
@Override
public void validate(ValidatorContext context) {
- Long clusterId = context.getCommandDTO().getClusterId();
- List<ServicePO> servicePOList = serviceDao.findByClusterId(clusterId);
+ boolean allClient = true;
+ List<ComponentCommandDTO> componentCommands =
context.getCommandDTO().getComponentCommands();
+ for (ComponentCommandDTO componentCommandDTO : componentCommands) {
+ String componentName = componentCommandDTO.getComponentName();
+ ComponentDTO componentDTO =
StackUtils.getComponentDTO(componentName);
+ if (!Objects.equals(componentDTO.getCategory(),
ComponentCategories.CLIENT)) {
+ allClient = false;
+ }
+ }
- if (CollectionUtils.isEmpty(servicePOList)) {
- throw new ApiException(ApiExceptionEnum.CLUSTER_HAS_NO_SERVICES);
+ if (allClient) {
+ throw new ApiException(ApiExceptionEnum.COMPONENT_HAS_NO_SUCH_OP);
}
}
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
index d98ccede..a4641c8c 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/ApiExceptionEnum.java
@@ -36,6 +36,8 @@ public enum ApiExceptionEnum {
CLUSTER_HAS_HOSTS(11002, LocaleKeys.CLUSTER_HAS_HOSTS),
CLUSTER_HAS_SERVICES(11003, LocaleKeys.CLUSTER_HAS_SERVICES),
CLUSTER_HAS_NO_SERVICES(11004, LocaleKeys.CLUSTER_HAS_NO_SERVICES),
+ CLUSTER_HAS_COMPONENTS(11005, LocaleKeys.CLUSTER_HAS_COMPONENTS),
+ CLUSTER_HAS_NO_COMPONENTS(11005, LocaleKeys.CLUSTER_HAS_NO_COMPONENTS),
// Host Exceptions -- 12000 ~ 12999
HOST_NOT_FOUND(12000, LocaleKeys.HOST_NOT_FOUND),
@@ -57,10 +59,13 @@ public enum ApiExceptionEnum {
// Component Exceptions -- 15000 ~ 15999
COMPONENT_NOT_FOUND(15000, LocaleKeys.COMPONENT_NOT_FOUND),
COMPONENT_IS_RUNNING(15001, LocaleKeys.COMPONENT_IS_RUNNING),
+ COMPONENT_HAS_NO_SUCH_OP(15002, LocaleKeys.COMPONENT_HAS_NO_SUCH_OP),
// Job Exceptions -- 16000 ~ 16999
JOB_NOT_FOUND(16000, LocaleKeys.JOB_NOT_FOUND),
JOB_NOT_RETRYABLE(16001, LocaleKeys.JOB_NOT_RETRYABLE),
+ JOB_HAS_NO_STAGES(16002, LocaleKeys.JOB_HAS_NO_STAGES),
+ STAGE_HAS_NO_TASKS(16003, LocaleKeys.STAGE_HAS_NO_TASKS),
// Configuration Exceptions -- 17000 ~ 17999
CONFIG_NOT_FOUND(17000, LocaleKeys.CONFIG_NOT_FOUND),
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
index 132f141b..fbf5e5c1 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/enums/LocaleKeys.java
@@ -39,6 +39,8 @@ public enum LocaleKeys {
CLUSTER_HAS_HOSTS("cluster.has.hosts"),
CLUSTER_HAS_SERVICES("cluster.has.services"),
CLUSTER_HAS_NO_SERVICES("cluster.has.no.services"),
+ CLUSTER_HAS_COMPONENTS("cluster.has.components"),
+ CLUSTER_HAS_NO_COMPONENTS("cluster.has.no.components"),
HOST_NOT_FOUND("host.not.found"),
HOST_ASSIGNED("host.assigned"),
@@ -56,9 +58,12 @@ public enum LocaleKeys {
COMPONENT_NOT_FOUND("component.not.found"),
COMPONENT_IS_RUNNING("component.is.running"),
+ COMPONENT_HAS_NO_SUCH_OP("component.has.no.such.op"),
JOB_NOT_FOUND("job.not.found"),
JOB_NOT_RETRYABLE("job.not.retryable"),
+ JOB_HAS_NO_STAGES("job.has.no.stages"),
+ STAGE_HAS_NO_TASKS("stage.has.no.tasks"),
CONFIG_NOT_FOUND("config.not.found"),
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/CommandVO.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/CommandVO.java
index 6dae92b1..8293409b 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/CommandVO.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/model/vo/CommandVO.java
@@ -25,5 +25,7 @@ public class CommandVO {
private Long id;
+ private String name;
+
private String state;
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
index 2a208f97..a8d6de66 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java
@@ -88,10 +88,14 @@ public class JobServiceImpl implements JobService {
.contains(JobState.fromString(stagePO.getState())))
.toList();
JobVO jobVO = JobConverter.INSTANCE.fromPO2VO(jobPO);
- jobVO.setProgress(new BigDecimal(runningStagePOList.size())
- .divide(new BigDecimal(stagePOList.size()), 2,
RoundingMode.HALF_UP)
- .multiply(new BigDecimal(100))
- .intValue());
+ if (stagePOList.isEmpty()) {
+ jobVO.setProgress(1);
+ } else {
+ jobVO.setProgress(new BigDecimal(runningStagePOList.size())
+ .divide(new BigDecimal(stagePOList.size()), 2,
RoundingMode.HALF_UP)
+ .multiply(new BigDecimal(100))
+ .intValue());
+ }
jobVOList.add(jobVO);
}
@@ -107,12 +111,17 @@ public class JobServiceImpl implements JobService {
JobPO jobPO = jobDao.findById(jobId);
List<StageVO> stages = new ArrayList<>();
List<StagePO> stagePOList = stageDao.findByJobId(jobId);
+ List<StagePO> runningStagePOList = new ArrayList<>();
for (int i = 0; i < stagePOList.size(); i++) {
StagePO stagePO = findCorrectStagePO(stagePOList, i + 1);
if (stagePO == null) {
throw new ApiException(ApiExceptionEnum.JOB_NOT_FOUND);
}
+ if (List.of(JobState.PROCESSING,
JobState.SUCCESSFUL).contains(JobState.fromString(stagePO.getState()))) {
+ runningStagePOList.add(stagePO);
+ }
+
StageVO stageVO = StageConverter.INSTANCE.fromPO2VO(stagePO);
List<TaskPO> taskPOList = taskDao.findByStageId(stagePO.getId());
List<TaskVO> taskVOList =
TaskConverter.INSTANCE.fromPO2VO(taskPOList);
@@ -121,6 +130,14 @@ public class JobServiceImpl implements JobService {
}
JobVO jobVO = JobConverter.INSTANCE.fromPO2VO(jobPO);
+ if (stagePOList.isEmpty()) {
+ jobVO.setProgress(1);
+ } else {
+ jobVO.setProgress(new BigDecimal(runningStagePOList.size())
+ .divide(new BigDecimal(stagePOList.size()), 2,
RoundingMode.HALF_UP)
+ .multiply(new BigDecimal(100))
+ .intValue());
+ }
jobVO.setStages(stages);
return jobVO;
}
diff --git
a/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
b/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
index d9a5b0fa..e4701245 100644
--- a/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
+++ b/bigtop-manager-server/src/main/resources/i18n/messages_en_US.properties
@@ -33,6 +33,8 @@ cluster.exists=Cluster already exists
cluster.has.hosts=Cluster still has hosts, please remove them first
cluster.has.services=Cluster still has services, please remove them first
cluster.has.no.services=Cluster has no services, please add one first
+cluster.has.components=Cluster still has components, please remove them first
+cluster.has.no.components=Cluster has no components, please add one first
host.not.found=Host not exist
host.assigned=Hosts [{0}] already assigned to another cluster
@@ -50,9 +52,12 @@ service.has.components=Service still has components, please
remove them first
component.not.found=Component not exist
component.is.running=Component is running, please stop it first
+component.has.no.such.op=Client component does not support this operation
job.not.found=Job not exist
job.not.retryable=Job is not retryable when it's not failed
+job.has.no.stages=Job has no stage created
+stage.has.no.tasks=Stage [{0}] has no task created
config.not.found=Config not exist
diff --git
a/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
b/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
index aaa4eebc..4bad9570 100644
--- a/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
+++ b/bigtop-manager-server/src/main/resources/i18n/messages_zh_CN.properties
@@ -33,6 +33,8 @@ cluster.exists=集群已存在
cluster.has.hosts=集群上仍有主机,请先移除
cluster.has.services=集群上仍有服务,请先移除
cluster.has.no.services=集群上没有服务,请先添加
+cluster.has.components=集群上仍有组件,请先移除
+cluster.has.no.components=集群上没有组件,请先添加
host.not.found=主机不存在
host.assigned=主机 [{0}] 已属于其他集群
@@ -50,9 +52,12 @@ service.has.components=服务上仍有组件,请先移除
component.not.found=组件不存在
component.is.running=组件正在运行,请先停止
+component.has.no.such.op=客户端组件不支持该操作
job.not.found=任务不存在
job.not.retryable=任务非失败状态,无法重试
+job.has.no.stages=任务没有创建阶段
+stage.has.no.tasks=阶段 [{0}] 没有创建任务
config.not.found=配置不存在