validateClusterLogicParams(ESLogicClusterDTO param, OperationEnum operation,
Integer projectId) {
return clusterLogicService.validateClusterLogicParams(param,operation,projectId);
}
/**
* “将具有给定 id 的集群加入到具有给定 id 的项目中。”
*
* 函数的第一行是注释。编译器会忽略注释
*
* @param logicClusterId 要加入的集群的 ID。
* @param joinProjectId 加入的项目ID
* @return 返回类型是 Result
*/
@Override
public Result joinClusterLogic(Long logicClusterId, Integer joinProjectId) {
final ESLogicClusterDTO param = new ESLogicClusterDTO();
param.setId(logicClusterId);
param.setProjectId(joinProjectId);
param.setType(clusterLogicService.getClusterLogicByIdThatNotContainsProjectId(logicClusterId).getType());
return Result.buildFrom(clusterLogicService.joinClusterLogic(param));
}
/**
* @param level level
* @return Result>
*/
@Override
public Result> getLogicClustersByLevel(Integer level) {
List list = ConvertUtil.list2List(clusterLogicService.listLogicClustersByLevelThatProjectIdStrConvertProjectIdList(level),
ClusterLogicVO.class);
for (ClusterLogicVO clusterLogicVO : list) {
List clusterPhyNames = clusterRegionService.listPhysicClusterNames(clusterLogicVO.getId());
clusterLogicVO.setPhyClusterAssociated(!AriusObjUtils.isEmptyList(clusterPhyNames));
clusterLogicVO.setAssociatedPhyClusterName(clusterPhyNames);
Optional.ofNullable(clusterLogicVO.getProjectId()).map(projectService::getProjectBriefByProjectId)
.map(ProjectBriefVO::getProjectName).ifPresent(clusterLogicVO::setProjectName);
}
return Result.buildSucc(list);
}
@Override
public Result
>> listProjectClusterLogicIdsAndNames(Integer projectId) {
List> res = Lists.newArrayList();
List tempAuthLogicClusters = Lists.newArrayList();
if (AuthConstant.SUPER_PROJECT_ID.equals(projectId)) {
tempAuthLogicClusters.addAll(clusterLogicService.listAllClusterLogics());
} else {
tempAuthLogicClusters.addAll(clusterLogicService.getHasAuthClusterLogicsByProjectId(projectId));
}
for (ClusterLogic clusterLogic : tempAuthLogicClusters) {
Tuple logicClusterId2logicClusterNameTuple = new Tuple<>();
logicClusterId2logicClusterNameTuple.setV1(clusterLogic.getId());
logicClusterId2logicClusterNameTuple.setV2(clusterLogic.getName());
res.add(logicClusterId2logicClusterNameTuple);
}
return Result.buildSucc(res);
}
@Override
public Result> getProjectLogicClusterInfoByType(Integer projectId, Integer type) {
ESLogicClusterDTO logicClusterDTO = new ESLogicClusterDTO();
if (!AuthConstant.SUPER_PROJECT_ID.equals(projectId)) {
logicClusterDTO.setProjectId(projectId);
}
logicClusterDTO.setType(type);
return Result.buildSucc(
ConvertUtil.list2List(clusterLogicService.listClusterLogics(logicClusterDTO), ClusterLogicVO.class));
}
@Override
public Result> listMachineSpec() {
List esMachineNormsPOS = esMachineNormsService.listMachineNorms();
return Result.buildSucc(ConvertUtil.list2List(esMachineNormsPOS, ESClusterNodeSepcVO.class));
}
@Override
public ClusterLogicVO getClusterLogic(Long clusterLogicId, Integer currentProjectId) {
ClusterLogic clusterLogic = clusterLogicService.getClusterLogicByIdAndProjectId(clusterLogicId, currentProjectId);
ClusterLogicVO clusterLogicVO = ConvertUtil.obj2Obj(clusterLogic, ClusterLogicVO.class);
FUTURE_UTIL.runnableTask(() -> buildConsoleClusterVersions(clusterLogicVO))
.runnableTask(() -> buildOpLogicClusterPermission(clusterLogicVO, currentProjectId))
.runnableTask(
() -> Optional.ofNullable(projectService.getProjectBriefByProjectId(clusterLogicVO.getProjectId()))
.map(ProjectBriefVO::getProjectName).ifPresent(clusterLogicVO::setProjectName))
.runnableTask(() -> buildClusterNodeInfo(clusterLogicVO)).waitExecute();
return clusterLogicVO;
}
@Override
public Result addLogicClusterAndClusterRegions(ESLogicClusterWithRegionDTO param,
String operator) throws AdminOperateException {
return clusterRegionManager.batchBindRegionToClusterLogic(param, operator, Boolean.TRUE);
}
/**
* 删除逻辑集群 这里是及其容易触发操作超时的,
* 1.如果模板没有下线干净,那么这里就不能把逻辑集群下线干净,
* 2.如果索引没有下线干净,那么逻辑集群也是不能下线的,否则系统和数据库共同残留下来,业务侧就出现了问题
*
* @param logicClusterId logicclusterid
* @param operator
* @param projectId projectid
* @return {@link Result}<{@link Void}>
* @throws AdminOperateException
*/
@Transactional(rollbackFor = Exception.class)
@Override
public Result deleteLogicCluster(Long logicClusterId, String operator,
Integer projectId) {
//一个逻辑集群对应了多个项目的情况
final List clusterLogicList = clusterLogicService.listClusterLogicByIdThatProjectIdStrConvertProjectIdList(logicClusterId);
if (CollectionUtils.isEmpty(clusterLogicList)) {
return Result.buildSucc();
}
final ClusterLogic clusterLogic = clusterLogicList.stream()
.filter(c -> Objects.equals(c.getProjectId(), projectId)).findFirst()
.orElse(null);
if (Objects.isNull(clusterLogic)) {
return Result.buildFail(String.format("项目【%s】不存在逻辑集群",
projectService.getProjectBriefByProjectId(projectId).getProjectName()));
}
final Result checkProjectCorrectly = ProjectUtils.checkProjectCorrectly(ClusterLogic::getProjectId,
clusterLogic, projectId);
if (checkProjectCorrectly.failed()) {
return checkProjectCorrectly;
}
//获取逻辑模板和索引
ClusterLogicTemplateIndexDetailDTO templateIndexVO = getTemplateIndexVO(clusterLogic, projectId);
try {
//但是索引下线没有完成,导致了脏数据的产生
if (CollectionUtils.isNotEmpty( templateIndexVO.getCatIndexResults())||
CollectionUtils.isNotEmpty(templateIndexVO.getTemplates())){
return Result.buildFail(String.format(
"该集群下还有%d项模板资源、%d项索引资源,如需下线集群,请前往模板管理、索引管理下线掉对应的模板及索引",
Optional.ofNullable(templateIndexVO.getTemplates()).orElse(Collections.emptyList()).size(),
Optional.ofNullable(templateIndexVO.getCatIndexResults()).orElse(Collections.emptyList()).size()
));
}
if (clusterLogicList.size() == 1) {
//将region解绑
ClusterRegion clusterRegion = clusterRegionService.getRegionByLogicClusterId(logicClusterId);
if (Objects.nonNull(clusterRegion)) {
//将region解绑
Result unbindRes = clusterRegionService.unbindRegion(clusterRegion.getId(), logicClusterId,
operator);
if (unbindRes.failed()) {
throw new AdminOperateException(unbindRes.getMessage());
}
}
}
//删除逻辑集群
Result result = clusterLogicService.deleteClusterLogicById(logicClusterId, operator, projectId);
if (result.success()) {
SpringTool.publish(new ClusterLogicEvent(logicClusterId, projectId));
//操作记录 集群下线
operateRecordService.saveOperateRecordWithManualTrigger(clusterLogic.getName(), operator, projectId, logicClusterId,
OperateTypeEnum.MY_CLUSTER_OFFLINE);
return Result.buildSuccWithTips(result.getData(),
String.format("逻辑集群%s下线成功", clusterLogic.getName()));
}
return Result.buildFailWithMsg(result.getData(),String.format("逻辑集群%s下线失败,%s", clusterLogic.getName(),
result.getMessage()));
} catch (AdminOperateException | ElasticsearchTimeoutException e) {
LOGGER.error("class={}||method=deleteLogicCluster||clusterLogic={}||es operation errMsg={}",
getClass().getSimpleName(), clusterLogic.getName(), e);
// 这里必须显示事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return Result.buildFail(String.format("逻辑集群%s下线失败,, 请重新尝试下线集群,多次重试不成功,请联系管理员", clusterLogic.getName()));
} catch (Exception e) {
LOGGER.error("class={}||method=deleteLogicCluster||clusterLogic={}||es operation errMsg={}",
getClass().getSimpleName(), clusterLogic.getName(), e);
// 这里必须显示事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return Result.buildFail("操作失败,请联系管理员");
}
}
private ClusterLogicTemplateIndexDetailDTO getTemplateIndexVO(ClusterLogic clusterLogic,Integer projectId) {
IndexTemplateDTO param = new IndexTemplateDTO();
param.setResourceId(clusterLogic.getId());
param.setProjectId(projectId);
List indexTemplates = indexTemplateService.listLogicTemplates(param);
//通过逻辑集群获取index
List catIndexResults = esIndexCatService.syncGetIndexByCluster(clusterLogic.getName(),projectId);
ClusterLogicTemplateIndexDetailDTO templateIndexVO = new ClusterLogicTemplateIndexDetailDTO();
templateIndexVO.setCatIndexResults(catIndexResults);
templateIndexVO.setTemplates(indexTemplates);
return templateIndexVO;
}
@Override
public Result editLogicCluster(ESLogicClusterDTO param, String operator, Integer projectId) {
final ClusterLogic logic = clusterLogicService.getClusterLogicByIdAndProjectId(param.getId(), projectId);
Result result = clusterLogicService.editClusterLogic(param, operator, projectId);
if (result.success()) {
SpringTool.publish(new ClusterLogicEvent(param.getId(), projectId));
//操作记录 我的集群信息修改
if (StringUtils.isNotBlank(param.getMemo())) {
operateRecordService.saveOperateRecordWithManualTrigger(String.format("%s 修改集群描述,%s-->%s", logic.getName(), logic.getMemo(),
param.getMemo()), operator, projectId, param.getId(),OperateTypeEnum.MY_CLUSTER_INFO_MODIFY);
}
}
return result;
}
@Override
public PaginationResult pageGetClusterLogics(ClusterLogicConditionDTO condition,
Integer projectId) throws NotFindSubclassException, ESOperateException {
BaseHandle baseHandle = handleFactory.getByHandlerNamePer(CLUSTER_LOGIC.getPageSearchType());
if (baseHandle instanceof ClusterLogicPageSearchHandle) {
ClusterLogicPageSearchHandle pageSearchHandle = (ClusterLogicPageSearchHandle) baseHandle;
return pageSearchHandle.doPage(condition, projectId);
}
LOGGER.warn(
"class=ClusterLogicManagerImpl||method=pageGetConsoleClusterVOS||msg=failed to get the ClusterLogicPageSearchHandle");
return PaginationResult.buildFail("分页获取逻辑集群信息失败");
}
@Override
public boolean updateClusterLogicHealth(Long clusterLogicId) {
ESLogicClusterDTO updateLogicClusterDTO = new ESLogicClusterDTO();
Set clusterHealthSet = Sets.newHashSet();
updateLogicClusterDTO.setId(clusterLogicId);
try {
final ClusterRegion clusterRegion = clusterRegionService.getRegionByLogicClusterId(clusterLogicId);
if (Objects.isNull(clusterRegion)) {
LOGGER.error(
"class=ClusterLogicManagerImpl||method=updateClusterLogicHealth||clusterLogicId={}||errMsg=clusterLogicContext is empty",
clusterLogicId);
clusterHealthSet.add(UNKNOWN.getCode());
} else {
clusterHealthSet.add(esClusterService.syncGetClusterHealthEnum(clusterRegion.getPhyClusterName()).getCode());
}
updateLogicClusterDTO.setHealth(ClusterUtils.getClusterLogicHealthByClusterHealth(clusterHealthSet));
setClusterLogicInfo(updateLogicClusterDTO,clusterRegion);
clusterLogicService.editClusterLogicNotCheck(updateLogicClusterDTO);
} catch (Exception e) {
LOGGER.error("class=ClusterLogicManagerImpl||method=updateClusterLogicHealth||clusterLogicId={}||errMsg={}",
clusterLogicId, e.getMessage(), e);
return false;
}
return true;
}
@Override
public Result indexTemplateCount(Long clusterId, String operator,
Integer projectId) {
ClusterLogic clusterLogic = clusterLogicService.getClusterLogicByIdAndProjectId(clusterId,projectId);
ClusterLogicTemplateIndexDetailDTO detailVO = getTemplateIndexVO(clusterLogic,projectId);
ClusterLogicTemplateIndexCountVO countVO = new ClusterLogicTemplateIndexCountVO();
countVO.setCatIndexResults(detailVO.getCatIndexResults().size());
countVO.setTemplateLogicAggregates(detailVO.getTemplates().size());
return Result.buildSucc(countVO);
}
@Override
public Result estimatedDiskSize(Long clusterLogicId, Integer count) {
ClusterLogic clusterLogic =
clusterLogicService.getClusterLogicByIdThatNotContainsProjectId(clusterLogicId);
if (Objects.isNull(clusterLogic)){
return Result.buildFail("逻辑集群不存在");
}
String nodeSpec = clusterLogic.getDataNodeSpec();
if (StringUtils.isNotBlank(nodeSpec)) {
return Result.buildSucc(getUnitSize(nodeSpec.split("-")[2]) * count);
}
return Result.buildSucc(UNKNOWN_SIZE);
}
@Override
public Result getClusterDataNodeSpec(Long clusterLogicId){
ClusterRegion clusterRegion = clusterRegionService.getRegionByLogicClusterId(clusterLogicId);
Result> result = clusterRoleHostService.listByRegionId(clusterRegion.getId().intValue());
ClusterRoleHost clusterRoleHost = result.getData().stream().findFirst().orElse(null);
return Result.buildSucc(clusterRoleHost.getMachineSpec());
}
@Override
public Result> listClusterLogicNameByProjectId(Integer projectId) {
List tempAuthLogicClusters = Lists.newArrayList();
if (AuthConstant.SUPER_PROJECT_ID.equals(projectId)) {
tempAuthLogicClusters.addAll(clusterLogicService.listAllClusterLogics());
} else {
tempAuthLogicClusters.addAll(clusterLogicService.getHasAuthClusterLogicsByProjectId(projectId));
}
List names = tempAuthLogicClusters.stream().map(ClusterLogic::getName).collect(Collectors.toList());
if (CollectionUtils.isEmpty(names)){
return Result.buildFail("无集群信息,请前往集群管理-->我的集群,进行集群申请。");
}
return Result.buildSucc(names);
}
@Override
public Result>> getClusterRelationByProjectId(Integer projectId) {
List> collect;
if (AuthConstant.SUPER_PROJECT_ID.equals(projectId)) {
List phyList = clusterPhyService.listAllClusters();
collect = phyList.stream().map(
clusterPhy -> new Tuple<>(clusterPhy.getCluster(), ConvertUtil.obj2Obj(clusterPhy, ClusterPhyVO.class)))
.collect(Collectors.toList());
} else {
List logicList = clusterLogicService.getOwnedClusterLogicListByProjectId(projectId);
collect = logicList.stream()
.map(clusterLogic -> new Tuple<>(clusterLogic.getName(), getPhyNameByLogic(clusterLogic.getId())))
.collect(Collectors.toList());
}
return Result.buildSucc(collect);
}
@Override
public Result> getClusterLogicPlugins(Long clusterId) {
return Result
.buildSucc(ConvertUtil.list2List(clusterLogicService.getClusterLogicPlugins(clusterId), PluginVO.class));
}
@Override
public Result isLogicClusterRegionIsNotEmpty(Long logicClusterId) {
if (!clusterLogicService.existClusterLogicById(logicClusterId)) {
return Result.buildWithMsg(false, "逻辑集群不存在!");
}
ClusterRegion clusterRegion = clusterRegionService.getRegionByLogicClusterId(logicClusterId);
if (null == clusterRegion) {
return Result.buildWithMsg(false, "逻辑集群Region不存在!");
}
Result> roleHostResult = clusterRoleHostService
.listByRegionId(Math.toIntExact(clusterRegion.getId()));
return Result.buildSucc(roleHostResult.success() && CollectionUtils.isNotEmpty(roleHostResult.getData()));
}
/**************************************************** private method ****************************************************/
/**
* 设置磁盘使用信息
* @param clusterDTO
*/
public void setClusterLogicInfo(ESLogicClusterDTO clusterDTO,ClusterRegion clusterRegion) {
Result> result = clusterRoleHostService
.listByRegionId(Math.toIntExact(clusterRegion.getId()));
if (result.success()) {
List clusterRoleHostList = result.getData().stream().map(ClusterRoleHost::getNodeSet).collect(Collectors.toList());
Long diskTotal = 0L;
Long diskUsage = 0L;
Map> map = eSClusterNodeService
.syncGetNodesDiskUsage(clusterRegion.getPhyClusterName());
Set>> entries = map.entrySet();
for (Map.Entry> entry : entries) {
if (clusterRoleHostList.contains(entry.getKey())) {
diskTotal += entry.getValue().v1();
diskUsage += entry.getValue().v2();
}
}
//设置节点数
clusterDTO.setDataNodeNum(clusterRoleHostList.size());
clusterDTO.setDiskTotal(diskTotal);
clusterDTO.setDiskUsage(diskUsage);
double diskUsagePercent = diskUsage != 0L && diskTotal != 0L ? CommonUtils.divideDoubleAndFormatDouble(
diskUsage,
diskTotal, 2, 1) : 0.0;
clusterDTO.setDiskUsagePercent(diskUsagePercent);
}
//设置es集群版本
ClusterPhy physicalCluster = getLogicClusterAssignedPhysicalClusters(clusterDTO.getId());
if (physicalCluster == null) {
return;
}
clusterDTO.setEsClusterVersion(physicalCluster.getEsVersion());
}
private ClusterPhyVO getPhyNameByLogic(Long clusterLogicId) {
ClusterRegion clusterRegion = clusterRegionService.getRegionByLogicClusterId(clusterLogicId);
ClusterPhy clusterPhy = clusterPhyService.getClusterByName(clusterRegion.getPhyClusterName());
return ConvertUtil.obj2Obj(clusterPhy, ClusterPhyVO.class);
}
/**
* 构建OP逻辑集群权限
* @param clusterLogicVO 逻辑集群
* @param projectIdForAuthJudge 用于判断权限的应用id(供应用管理页面获取关联集群列表使用)
* ,为null则权限为运维人员权限(管理权限)
*/
private void buildOpLogicClusterPermission(ClusterLogicVO clusterLogicVO, Integer projectIdForAuthJudge) {
if (clusterLogicVO == null) {
return;
}
if (projectIdForAuthJudge == null) {
// 未指定需要判断权限的app,取运维人员权限
clusterLogicVO.setAuthId(null);
clusterLogicVO.setAuthType(ProjectClusterLogicAuthEnum.OWN.getCode());
clusterLogicVO.setPermissions(ProjectClusterLogicAuthEnum.OWN.getDesc());
} else {
// 指定了需要判断权限的app
buildLogicClusterPermission(clusterLogicVO, projectIdForAuthJudge);
}
}
/**
* 根据物理集群名获取对应的逻辑集群列表,若传入为空,则返回全量
* @param phyClusterName 物理集群的名称
* @return List 逻辑集群名称列表
*/
@Override
public List listClusterLogicNameByPhyName(String phyClusterName) {
//若传入为空,则返回全量
if (null == phyClusterName) {
return clusterLogicService.listAllClusterLogics()
.stream()
.map(ClusterLogic::getName)
.distinct()
.collect(Collectors.toList());
} else {
return getClusterPhyAssociatedClusterLogicNames(phyClusterName);
}
}
/**
* 返回与给定应用关联的逻辑集群名称列表
*
* @param projectId 项目id
* @return List 逻辑集群名称列表
*/
@Override
public List listClusterLogicNameByApp(Integer projectId) {
List clusterLogicList = clusterLogicService.getHasAuthClusterLogicsByProjectId(projectId);
List names = Lists.newArrayList();
for (ClusterLogic clusterLogic : clusterLogicList) {
names.add(clusterLogic.getName());
}
return names;
}
/**
* 返回与给定物理集群名称关联的逻辑集群名称列表
*
* @param phyClusterName 物理集群的名称。
* @return 与给定集群物理名称关联的集群逻辑名称列表。
*/
@Override
public List