/** * 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.controller; import java.util.Collection; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import com.vip.saturn.job.console.domain.*; import com.vip.saturn.job.console.exception.SaturnJobConsoleException; import com.vip.saturn.job.console.utils.SaturnConstants; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.google.common.base.Strings; import com.vip.saturn.job.console.service.ExecutorService; import com.vip.saturn.job.console.service.JobDimensionService; import com.vip.saturn.job.console.service.JobOperationService; import com.vip.saturn.job.console.service.RegistryCenterService; import com.vip.saturn.job.console.service.ServerDimensionService; @RestController @RequestMapping("job") public class JobOperationController extends AbstractController { protected static Logger AUDITLOGGER = LoggerFactory.getLogger("AUDITLOG"); protected static Logger LOGGER = LoggerFactory.getLogger(JobOperationController.class); protected static final int DEFAULT_RECORD_COUNT = 100; @Resource private JobDimensionService jobDimensionService; @Resource private JobOperationService jobOperationService; @Resource private ServerDimensionService serverDimensionService; @Resource private ExecutorService executorService; @Resource private RegistryCenterService registryCenterService; @RequestMapping(value = "toggleJobEnabledState", method = RequestMethod.POST) public RequestResult toggleJobEnabledState(HttpServletRequest request, String jobName, Boolean state, Boolean confirmed) { RequestResult requestResult = new RequestResult(); if(state == null) { requestResult.setSuccess(false); requestResult.setMessage("更改的状态有误。"); return requestResult; } Boolean isJobEnabled = jobDimensionService.isJobEnabled(jobName); if (isJobEnabled == state) { if (state) { requestResult.setSuccess(false); requestResult.setMessage("作业已经是启动状态。"); return requestResult; } else { requestResult.setSuccess(false); requestResult.setMessage("作业已经是禁用状态。"); return requestResult; } } if(confirmed != null && !confirmed) { try { if (state) { // 启用时,检查其依赖的作业是否已经启动 List<JobConfig> dependentJobsStatus = jobDimensionService.getDependentJobsStatus(jobName); if (dependentJobsStatus != null) { String unableJobs = ""; for (JobConfig jobConfig : dependentJobsStatus) { if (!jobConfig.getEnabled()) { unableJobs += jobConfig.getJobName() + ","; } } if (!unableJobs.equals("")) { requestResult.setSuccess(false); requestResult.setMessage("该作业依赖的作业(" + unableJobs.substring(0, unableJobs.length() - 1) + ")不处于启用状态,是否继续启用该作业?"); requestResult.setObj("confirmDependencies"); return requestResult; } } } else { // 禁用时,检查依赖它的作业是否已经禁用 List<JobConfig> dependedJobsStatus = jobDimensionService.getDependedJobsStatus(jobName); if (dependedJobsStatus != null) { String enableJobs = ""; for (JobConfig jobConfig : dependedJobsStatus) { if (jobConfig.getEnabled()) { enableJobs += jobConfig.getJobName() + ","; } } if (!enableJobs.equals("")) { requestResult.setSuccess(false); requestResult.setMessage("依赖该作业的作业(" + enableJobs.substring(0, enableJobs.length() - 1) + ")不处于禁用状态,是否继续禁用作业?"); requestResult.setObj("confirmDependencies"); return requestResult; } } } } catch (SaturnJobConsoleException e) { requestResult.setSuccess(false); requestResult.setMessage(e.getMessage()); return requestResult; } catch (Exception e) { requestResult.setSuccess(false); requestResult.setMessage(e.toString()); return requestResult; } } JobStatus js = jobDimensionService.getJobStatus(jobName); // enabled job if (state) { if (JobStatus.STOPPED.equals(js)) { jobOperationService.setJobEnabledState(jobName, state); requestResult.setSuccess(true); return requestResult; } else { requestResult.setSuccess(false); requestResult.setMessage("作业不处于stopped状态,不能启用。"); return requestResult; } } else { if (JobStatus.RUNNING.equals(js) || JobStatus.READY.equals(js)) { jobOperationService.setJobEnabledState(jobName, state); requestResult.setSuccess(true); return requestResult; } else { requestResult.setSuccess(false); requestResult.setMessage("作业不处于running或ready状态,不能禁用。"); return requestResult; } } } @RequestMapping(value = "batchToggleJobEnabledState", method = RequestMethod.POST) public RequestResult batchToggleJobEnabledState(HttpServletRequest request, String jobNames,Boolean state, Boolean confirmed) { RequestResult requestResult = new RequestResult(); if(state == null) { requestResult.setSuccess(false); requestResult.setMessage("更改的状态有误。"); return requestResult; } String[] jobNameArr = jobNames.split(","); if(jobNameArr == null || jobNameArr.length == 0){ requestResult.setSuccess(false); requestResult.setMessage("没有选中任何要操作的作业。"); return requestResult; } if(confirmed != null && !confirmed) { for(String jobName : jobNameArr) { if(jobName != null && jobName.trim().length() > 0) { jobName = jobName.trim(); try { if (state) { // 启用时,检查其依赖的作业是否已经启动 List<JobConfig> dependentJobsStatus = jobDimensionService.getDependentJobsStatus(jobName); if (dependentJobsStatus != null) { String unableJobs = ""; for (JobConfig jobConfig : dependentJobsStatus) { if (!jobConfig.getEnabled()) { unableJobs += jobConfig.getJobName() + ","; } } if (!unableJobs.equals("")) { requestResult.setSuccess(false); requestResult.setMessage("有作业依赖的作业还没启用,是否继续批量启用作业?"); requestResult.setObj("confirmDependencies"); return requestResult; } } } else { // 禁用时,检查依赖它的作业是否已经禁用 List<JobConfig> dependedJobsStatus = jobDimensionService.getDependedJobsStatus(jobName); if (dependedJobsStatus != null) { String enableJobs = ""; for (JobConfig jobConfig : dependedJobsStatus) { if (jobConfig.getEnabled()) { enableJobs += jobConfig.getJobName(); } } if (!enableJobs.equals("")) { requestResult.setSuccess(false); requestResult.setMessage("有作业被依赖的作业还没禁用,是否继续批量禁用作业?"); requestResult.setObj("confirmDependencies"); return requestResult; } } } } catch (SaturnJobConsoleException e) { requestResult.setSuccess(false); requestResult.setMessage(e.getMessage()); return requestResult; } catch (Exception e) { requestResult.setSuccess(false); requestResult.setMessage(e.toString()); return requestResult; } } } } StringBuilder messageSbf = new StringBuilder(); for(String jobName : jobNameArr){ try{ Boolean isJobEnabled = jobDimensionService.isJobEnabled(jobName); if (isJobEnabled == state) { if (state) { messageSbf.append("作业【" + jobName +"】已经是启动状态,"); } else { messageSbf.append("作业【" + jobName +"】已经是禁用状态,"); } } JobStatus js = jobDimensionService.getJobStatus(jobName); // enabled job if (state) { if (JobStatus.STOPPED.equals(js)) { jobOperationService.setJobEnabledState(jobName, state); } else { messageSbf.append("作业【"+jobName+"】不处于stopped状态,不能启用,"); } } else { if (JobStatus.RUNNING.equals(js) || JobStatus.READY.equals(js)) { jobOperationService.setJobEnabledState(jobName, state); } else { messageSbf.append("作业【"+jobName+"】不处于running或ready状态,不能禁用,"); } } }catch(Exception e){ AUDITLOGGER.error(e.getMessage(), e); messageSbf.append("操作作业【"+jobName+"】出现内部错误,"); continue; } } if(messageSbf.length() == 0){ requestResult.setSuccess(true); return requestResult; } else { requestResult.setSuccess(false); requestResult.setMessage(messageSbf.substring(0, messageSbf.length() - 1)); //去掉最后一个逗号 return requestResult; } } @RequestMapping(value = "remove/executor", method = RequestMethod.POST) @ResponseBody public String removeExecutor(final String executor, final HttpServletRequest request) { if (executor.contains(",")) { StringBuilder removeAllExecutorMsg = new StringBuilder(); // 多个executor String[] executors = executor.split(","); for (int i = 0; i < executors.length; i++) { String delExecutor = executors[i]; String removeOneExecutorMsg = removeOneExecutor(delExecutor); if(!SaturnConstants.DEAL_SUCCESS.equals(removeOneExecutorMsg)){ removeAllExecutorMsg.append(removeOneExecutorMsg).append(","); } } if(StringUtils.isBlank(removeAllExecutorMsg.toString())){ return SaturnConstants.DEAL_SUCCESS; } return removeAllExecutorMsg.substring(0,removeAllExecutorMsg.toString().length()-1); } return removeOneExecutor(executor); } private String removeOneExecutor(String delExecutor) { if ( ServerStatus.ONLINE.equals(serverDimensionService.getExecutorStatus(delExecutor))) { return "无法删除ONLINE的Executor:("+delExecutor+")"; } serverDimensionService.removeOffLineExecutor(delExecutor); return SaturnConstants.DEAL_SUCCESS; } @RequestMapping(value = "remove/job", method = RequestMethod.POST) public RequestResult removeStoppedJob(String jobName, HttpServletRequest request) throws InterruptedException { RequestResult requestResult = new RequestResult(); JobStatus jobStatus = jobDimensionService.getJobStatus(jobName); if (JobStatus.STOPPED.equals(jobStatus)) { String result = executorService.removeJob(jobName); if(SaturnConstants.DEAL_SUCCESS.equals(result)) { requestResult.setSuccess(true); return requestResult; } else { requestResult.setSuccess(false); requestResult.setMessage(result); return requestResult; } // let zk and the watchers update theirselves. } else { requestResult.setSuccess(false); requestResult.setMessage("作业【"+jobName+ "】不处于STOPPED状态,不能删除."); return requestResult; } } @RequestMapping(value = "batchRemove/jobs", method = RequestMethod.POST) public String batchRemoveStoppedJob(final String jobNames, HttpServletRequest request) throws InterruptedException { String[] jobNamesArr = jobNames.split(","); if(jobNamesArr == null || jobNamesArr.length == 0){ AUDITLOGGER.warn("batchRemoveJobs is null"); return "批量删除作业为空"; } StringBuilder errorLog = new StringBuilder(); for(String jobName : jobNamesArr){ JobStatus jobStatus = jobDimensionService.getJobStatus(jobName); if (JobStatus.STOPPED.equals(jobStatus)) { String removeResult = executorService.removeJob(jobName); if(!SaturnConstants.DEAL_SUCCESS.equals(removeResult)){ errorLog.append(removeResult).append(","); } // let zk and the watchers update theirselves. } else { errorLog.append("作业【"+jobName+ "】不处于STOPPED状态,不能删除.").append(","); continue; } } if(Strings.isNullOrEmpty(errorLog.toString())){ return SaturnConstants.DEAL_SUCCESS; } if(errorLog.toString().split(",").length != jobNamesArr.length){ return errorLog.toString()+"其他作业已成功删除";// 说明有作业已被成功删除,加个后缀提示 } return errorLog.substring(0,errorLog.length()-1).toString();// 去掉最后一个逗号 } @RequestMapping(value = "runAllOneTime", method = RequestMethod.POST) @ResponseBody public String runAllOneTime(final JobServer jobServer, HttpServletRequest request) { JobStatus js = jobDimensionService.getJobStatus(jobServer.getJobName()); if (JobStatus.READY.equals(js)) { Collection<JobServer> servers = jobDimensionService.getServers(jobServer.getJobName()); if (servers != null) { for (JobServer server: servers) { if (ServerStatus.ONLINE.equals(server.getStatus())) { jobOperationService.runAtOnceByJobnameAndExecutorName( jobServer.getJobName(), server.getExecutorName()); } } return SaturnConstants.DEAL_SUCCESS; } return "无online executor."; } else { return "作业不在ready状态,不能执行立即运行。"; } } @RequestMapping(value = "stopAllOneTime", method = RequestMethod.POST) @ResponseBody public String stopAllOneTime(final JobServer jobServer, HttpServletRequest request) { String jobName = jobServer.getJobName(); String jobType = jobDimensionService.getJobType(jobName); if(jobType != null && (jobType.equals(JobBriefInfo.JobType.MSG_JOB.name()))) { boolean jobEnabled = jobDimensionService.isJobEnabled(jobName); if(jobEnabled) { return "作业不处于禁用状态,不能强行终止作业。"; } else { return stopOnceTime(jobName); } } else { JobStatus js = jobDimensionService.getJobStatus(jobServer.getJobName()); if (JobStatus.STOPPING.equals(js)) { return stopOnceTime(jobName); } return "作业不处于stopping状态,不能强行终止作业。"; } } private String stopOnceTime(String jobName) { Collection<JobServer> servers = jobDimensionService.getServers(jobName); if (servers == null || servers.size() == 0) { return "该作业没有executor接管,不能强行终止作业。"; } for (JobServer server : servers) { jobOperationService.stopAtOnceByJobnameAndExecutorName(jobName, server.getExecutorName()); } return SaturnConstants.DEAL_SUCCESS; } }