/**
* Copyright 2016 vip.com.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* </p>
*/
package com.vip.saturn.job.console.service.impl;
import java.text.DateFormat;
import java.util.*;
import javax.annotation.Resource;
import com.vip.saturn.job.console.exception.SaturnJobConsoleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.google.common.base.Strings;
import com.vip.saturn.job.console.domain.JobStatus;
import com.vip.saturn.job.console.domain.ServerBriefInfo;
import com.vip.saturn.job.console.domain.ServerStatus;
import com.vip.saturn.job.console.repository.zookeeper.CuratorRepository;
import com.vip.saturn.job.console.service.JobDimensionService;
import com.vip.saturn.job.console.service.ServerDimensionService;
import com.vip.saturn.job.console.utils.ExecutorNodePath;
import com.vip.saturn.job.console.utils.JobNodePath;
@Service
public class ServerDimensionServiceImpl implements ServerDimensionService {
protected static Logger AUDITLOGGER = LoggerFactory.getLogger("AUDITLOG");
private static final Logger logger = LoggerFactory.getLogger(ServerDimensionServiceImpl.class);
private DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
@Resource
private CuratorRepository curatorRepository;
@Resource
private JobDimensionService jobDimensionService;
@Override
public Map<String, Object> getAllServersBriefInfo() {
CuratorRepository.CuratorFrameworkOp curatorFrameworkOp = curatorRepository.inSessionClient();
HashMap<String,Object> model = new HashMap<String,Object>();
Map<String,ServerBriefInfo> sbfMap = new LinkedHashMap<String,ServerBriefInfo>();
List<String> jobs = new ArrayList<>();
try {
jobs = jobDimensionService.getAllUnSystemJobs(curatorFrameworkOp);
} catch (SaturnJobConsoleException e) {
logger.error(e.getMessage(), e);
}
Map<String, Map<String, Integer>> jobNameExecutorNameTotalLevel = new HashMap<>();
String executorNodePath = ExecutorNodePath.getExecutorNodePath();
if(curatorFrameworkOp.checkExists(executorNodePath)) {
List<String> executors = curatorFrameworkOp.getChildren(executorNodePath);
if(!CollectionUtils.isEmpty(executors)){
for(String executor : executors){
ServerBriefInfo sbf = new ServerBriefInfo(executor);
String ip = curatorFrameworkOp.getData(ExecutorNodePath.getExecutorNodePath(executor, "ip"));
sbf.setServerIp(ip);
String lastBeginTime = curatorFrameworkOp.getData(ExecutorNodePath.getExecutorNodePath(sbf.getExecutorName(),"lastBeginTime"));
sbf.setLastBeginTime(null == lastBeginTime ? null : dateFormat.format(new Date(Long.parseLong(lastBeginTime))));
if(!Strings.isNullOrEmpty(ip)){
sbf.setStatus(ServerStatus.ONLINE);
} else {
sbf.setStatus(ServerStatus.OFFLINE);
}
sbf.setVersion(curatorFrameworkOp.getData(ExecutorNodePath.getExecutorNodePath(executor, "version")));
if(!CollectionUtils.isEmpty(jobs)){
for (String jobName : jobs) {
String serverNodePath = JobNodePath.getServerNodePath(jobName);
if(!curatorFrameworkOp.checkExists(serverNodePath)) {
continue;
}
if(Strings.isNullOrEmpty(sbf.getServerIp())){
String serverIp = curatorFrameworkOp.getData(JobNodePath.getServerNodePath(jobName, executor, "ip"));
sbf.setServerIp(serverIp);
}
Map<String, Integer> executorNameWithTotalLevel = null;
if(jobNameExecutorNameTotalLevel.containsKey(jobName)) {
executorNameWithTotalLevel = jobNameExecutorNameTotalLevel.get(jobName);
} else {
executorNameWithTotalLevel = new LinkedHashMap<>();
jobNameExecutorNameTotalLevel.put(jobName, executorNameWithTotalLevel);
}
if(ServerStatus.ONLINE.equals(sbf.getStatus())){// 负荷分布图只显示online的Executor
executorNameWithTotalLevel.put(executor, 0);
}
String sharding = curatorFrameworkOp.getData(JobNodePath.getServerNodePath(jobName, executor, "sharding"));
if(!Strings.isNullOrEmpty(sharding)){
sbf.setHasSharding(true);// 如果有分片信息则前端需要屏蔽删除按钮
if(JobStatus.STOPPED.equals(jobDimensionService.getJobStatus(jobName))){
continue;// 作业状态为STOPPED的即使有残留分片也不显示该分片
}
if(ServerStatus.OFFLINE.equals(sbf.getStatus())){// offline的executor即使有残留分片也不显示该分片
continue;
}
// concat executorSharding
String executorSharding = jobName + ":" + sharding;
if(Strings.isNullOrEmpty(sbf.getSharding())){// 如果有分片信息则前端需要屏蔽删除按钮
sbf.setSharding(executorSharding);
}else{
sbf.setSharding(sbf.getSharding() + "<br/>" + executorSharding);
}
// calculate totalLoadLevel
String loadLevelNode = curatorFrameworkOp.getData(JobNodePath.getConfigNodePath(jobName, "loadLevel"));
Integer loadLevel = 1;
if(!Strings.isNullOrEmpty(loadLevelNode)){
loadLevel = Integer.parseInt(loadLevelNode);
}
Integer totalLoadLevel = sbf.getTotalLoadLevel();
int thisJobsLoad = (sharding.split(",").length * loadLevel);
sbf.setTotalLoadLevel((sbf.getTotalLoadLevel() == null?0:totalLoadLevel) + thisJobsLoad);
executorNameWithTotalLevel.put(executor, thisJobsLoad);
}
}
}
sbfMap.put(executor, sbf);
}
}
model.put("serverInfos", sbfMap.values());
model.put("jobShardLoadLevels", jobNameExecutorNameTotalLevel);
}
return model;
}
@Override
public ServerStatus getExecutorStatus(String executor) {
CuratorRepository.CuratorFrameworkOp curatorFrameworkOp = curatorRepository.inSessionClient();
if (curatorFrameworkOp.checkExists(ExecutorNodePath.getExecutorNodePath(executor, "ip"))) {
return ServerStatus.ONLINE;
}
return ServerStatus.OFFLINE;
}
@Override
public void removeOffLineExecutor(String executor) {
CuratorRepository.CuratorFrameworkOp curatorFrameworkOp = curatorRepository.inSessionClient();
curatorFrameworkOp.deleteRecursive(ExecutorNodePath.getExecutorNodePath(executor));
List<String> jobNames = new ArrayList<>();
try {
jobNames = jobDimensionService.getAllJobs(curatorFrameworkOp);
} catch (SaturnJobConsoleException e) {
logger.error(e.getMessage(), e);
}
if (CollectionUtils.isEmpty(jobNames)) {
return;
}
for (String jobName : jobNames) {
String executorNode = JobNodePath.getServerNodePath(jobName, executor);
if (!curatorFrameworkOp.checkExists(executorNode)) {
continue;
}
curatorFrameworkOp.deleteRecursive(executorNode);
}
}
@Override
public boolean isRunning(String jobName, String executor) {
CuratorRepository.CuratorFrameworkOp curatorFrameworkOp = curatorRepository.inSessionClient();
String status = curatorFrameworkOp.getData(JobNodePath.getServerStatus(jobName, executor));
if ("RUNNING".equals(status)) {
return true;
}
return false;
}
@Override
public boolean isReady(String jobName, String executor) {
CuratorRepository.CuratorFrameworkOp curatorFrameworkOp = curatorRepository.inSessionClient();
String status = curatorFrameworkOp.getData(JobNodePath.getServerStatus(jobName, executor));
if ("READY".equals(status)) {
return true;
}
return false;
}
}