use of com.vip.saturn.job.console.exception.SaturnJobConsoleException in project Saturn by vipshop.
the class JobOperationServiceImpl method deleteJob.
@Transactional
@Override
public void deleteJob(String jobName, CuratorRepository.CuratorFrameworkOp curatorFrameworkOp) throws SaturnJobConsoleException {
try {
String enabledNodePath = JobNodePath.getConfigNodePath(jobName, "enabled");
long creationTime = curatorFrameworkOp.getCtime(enabledNodePath);
long timeDiff = System.currentTimeMillis() - creationTime;
if (timeDiff < SaturnConstants.JOB_CAN_BE_DELETE_TIME_LIMIT) {
String errMessage = "Job cannot be deleted until " + (SaturnConstants.JOB_CAN_BE_DELETE_TIME_LIMIT / 1000) + " seconds after job creation";
throw new SaturnJobConsoleHttpException(HttpStatus.BAD_REQUEST.value(), errMessage);
}
// 1.作业的executor全online的情况,添加toDelete节点,触发监听器动态删除节点
String toDeleteNodePath = JobNodePath.getConfigNodePath(jobName, "toDelete");
if (curatorFrameworkOp.checkExists(toDeleteNodePath)) {
curatorFrameworkOp.deleteRecursive(toDeleteNodePath);
}
curatorFrameworkOp.create(toDeleteNodePath);
for (int i = 0; i < 20; i++) {
// 2.作业的executor全offline的情况,或有几个online,几个offline的情况
String jobServerPath = JobNodePath.getServerNodePath(jobName);
if (!curatorFrameworkOp.checkExists(jobServerPath)) {
// (1)如果不存在$Job/JobName/servers节点,说明该作业没有任何executor接管,可直接删除作业节点
curatorFrameworkOp.deleteRecursive(JobNodePath.getJobNodePath(jobName));
return;
}
// (2)如果该作业servers下没有任何executor,可直接删除作业节点
List<String> executors = curatorFrameworkOp.getChildren(jobServerPath);
if (CollectionUtils.isEmpty(executors)) {
curatorFrameworkOp.deleteRecursive(JobNodePath.getJobNodePath(jobName));
return;
}
// (3)只要该作业没有一个能运行的该作业的executor在线,那么直接删除作业节点
boolean hasOnlineExecutor = false;
for (String executor : executors) {
if (curatorFrameworkOp.checkExists(ExecutorNodePath.getExecutorNodePath(executor, "ip")) && curatorFrameworkOp.checkExists(JobNodePath.getServerStatus(jobName, executor))) {
hasOnlineExecutor = true;
} else {
curatorFrameworkOp.deleteRecursive(JobNodePath.getServerNodePath(jobName, executor));
}
}
if (!hasOnlineExecutor) {
curatorFrameworkOp.deleteRecursive(JobNodePath.getJobNodePath(jobName));
}
Thread.sleep(200);
}
} catch (SaturnJobConsoleException e) {
throw e;
} catch (Throwable t) {
log.error("exception is thrown during delete job", t);
throw new SaturnJobConsoleHttpException(HttpStatus.INTERNAL_SERVER_ERROR.value(), t.getMessage(), t);
}
}
use of com.vip.saturn.job.console.exception.SaturnJobConsoleException in project Saturn by vipshop.
the class JobOperationServiceImpl method validateJobConfig.
@Override
public void validateJobConfig(JobConfig jobConfig) throws SaturnJobConsoleException {
// 作业名必填
if (jobConfig.getJobName() == null || jobConfig.getJobName().trim().isEmpty()) {
throw new SaturnJobConsoleException("作业名必填");
}
// 作业名只允许包含:数字0-9、小写字符a-z、大写字符A-Z、下划线_
if (!jobConfig.getJobName().matches("[0-9a-zA-Z_]*")) {
throw new SaturnJobConsoleException("作业名只允许包含:数字0-9、小写字符a-z、大写字符A-Z、下划线_");
}
// 依赖的作业只允许包含:数字0-9、小写字符a-z、大写字符A-Z、下划线_、英文逗号,
if (jobConfig.getDependencies() != null && !jobConfig.getDependencies().matches("[0-9a-zA-Z_,]*")) {
throw new SaturnJobConsoleException("依赖的作业只允许包含:数字0-9、小写字符a-z、大写字符A-Z、下划线_、英文逗号,");
}
// 作业类型必填
if (jobConfig.getJobType() == null || jobConfig.getJobType().trim().isEmpty()) {
throw new SaturnJobConsoleException("作业类型必填");
}
// 验证作业类型
if (JobBriefInfo.JobType.getJobType(jobConfig.getJobType()).equals(JobBriefInfo.JobType.UNKOWN_JOB)) {
throw new SaturnJobConsoleException("作业类型未知");
}
// 验证VSHELL类型版本兼容性
if (JobBriefInfo.JobType.getJobType(jobConfig.getJobType()).equals(JobBriefInfo.JobType.VSHELL) && jobDimensionService.isNewSaturn("1.1.2") != 2) {
throw new SaturnJobConsoleException("Shell消息作业导入要求所有executor版本都是1.1.2及以上");
}
// 如果是JAVA/MSG作业
if (jobConfig.getJobType().equals(JobBriefInfo.JobType.JAVA_JOB.name()) || jobConfig.getJobType().equals(JobBriefInfo.JobType.MSG_JOB.name())) {
// 作业实现类必填
if (jobConfig.getJobClass() == null || jobConfig.getJobClass().trim().isEmpty()) {
throw new SaturnJobConsoleException("对于JAVA/MSG作业,作业实现类必填");
}
}
// 如果是JAVA/SHELL作业
if (jobConfig.getJobType().equals(JobBriefInfo.JobType.JAVA_JOB.name()) || jobConfig.getJobType().equals(JobBriefInfo.JobType.SHELL_JOB.name())) {
// cron表达式必填
if (jobConfig.getCron() == null || jobConfig.getCron().trim().isEmpty()) {
throw new SaturnJobConsoleException("对于JAVA/SHELL作业,cron表达式必填");
}
// cron表达式语法验证
try {
CronExpression.validateExpression(jobConfig.getCron());
} catch (ParseException e) {
throw new SaturnJobConsoleException("cron表达式语法有误," + e.toString());
}
} else {
jobConfig.setCron("");
// 其他类型的不需要持久化保存cron表达式
;
}
if (jobConfig.getLocalMode() != null && jobConfig.getLocalMode()) {
if (jobConfig.getShardingItemParameters() == null) {
throw new SaturnJobConsoleException("对于本地模式作业,分片参数必填。");
} else {
String[] split = jobConfig.getShardingItemParameters().split(",");
boolean includeXing = false;
for (String tmp : split) {
String[] split2 = tmp.split("=");
if ("*".equalsIgnoreCase(split2[0].trim())) {
includeXing = true;
break;
}
}
if (!includeXing) {
throw new SaturnJobConsoleException("对于本地模式作业,分片参数必须包含如*=xx。");
}
}
} else {
// 分片参数不能小于分片总数
if (jobConfig.getShardingTotalCount() == null || jobConfig.getShardingTotalCount() < 1) {
throw new SaturnJobConsoleException("分片数不能为空,并且不能小于1");
}
if (jobConfig.getShardingTotalCount() > 0) {
if (jobConfig.getShardingItemParameters() == null || jobConfig.getShardingItemParameters().trim().isEmpty() || jobConfig.getShardingItemParameters().split(",").length < jobConfig.getShardingTotalCount()) {
throw new SaturnJobConsoleException("分片参数不能小于分片总数");
}
}
}
// 不能添加系统作业
if (jobConfig.getJobMode() != null && jobConfig.getJobMode().startsWith(JobMode.SYSTEM_PREFIX)) {
throw new SaturnJobConsoleException("作业模式有误,不能添加系统作业");
}
}
use of com.vip.saturn.job.console.exception.SaturnJobConsoleException in project Saturn by vipshop.
the class NamespaceZkClusterMappingServiceImpl method moveNamespaceBatchTo.
@Override
public void moveNamespaceBatchTo(final String namespaces, final String zkClusterKeyNew, final String lastUpdatedBy, final boolean updateDBOnly) throws SaturnJobConsoleException {
final List<String> namespaceList = new ArrayList<>();
String[] split = namespaces.split(",");
if (split != null) {
for (String tmp : split) {
String namespace = tmp.trim();
if (!namespace.isEmpty()) {
namespaceList.add(namespace);
}
}
}
int size = namespaceList.size();
final MoveNamespaceBatchStatus moveNamespaceBatchStatus = new MoveNamespaceBatchStatus(size);
temporarySharedStatusService.delete(ShareStatusModuleNames.MOVE_NAMESPACE_BATCH_STATUS);
temporarySharedStatusService.create(ShareStatusModuleNames.MOVE_NAMESPACE_BATCH_STATUS, gson.toJson(moveNamespaceBatchStatus));
moveNamespaceBatchThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
for (String namespace : namespaceList) {
try {
moveNamespaceBatchStatus.setMoving(namespace);
temporarySharedStatusService.update(ShareStatusModuleNames.MOVE_NAMESPACE_BATCH_STATUS, gson.toJson(moveNamespaceBatchStatus));
moveNamespaceTo(namespace, zkClusterKeyNew, lastUpdatedBy, updateDBOnly);
moveNamespaceBatchStatus.incrementSuccessCount();
} catch (SaturnJobConsoleException e) {
if (("The namespace(" + namespace + ") is in " + zkClusterKeyNew).equals(e.getMessage())) {
moveNamespaceBatchStatus.incrementIgnoreCount();
} else {
moveNamespaceBatchStatus.incrementFailCount();
}
} finally {
moveNamespaceBatchStatus.setMoving("");
moveNamespaceBatchStatus.decrementUnDoCount();
temporarySharedStatusService.update(ShareStatusModuleNames.MOVE_NAMESPACE_BATCH_STATUS, gson.toJson(moveNamespaceBatchStatus));
}
}
} finally {
moveNamespaceBatchStatus.setFinished(true);
temporarySharedStatusService.update(ShareStatusModuleNames.MOVE_NAMESPACE_BATCH_STATUS, gson.toJson(moveNamespaceBatchStatus));
}
}
});
}
use of com.vip.saturn.job.console.exception.SaturnJobConsoleException in project Saturn by vipshop.
the class NamespaceZkClusterMappingServiceImpl method moveNamespaceTo.
@Transactional(rollbackFor = { SaturnJobConsoleException.class })
@Override
public void moveNamespaceTo(String namespace, String zkClusterKeyNew, String lastUpdatedBy, boolean updateDBOnly) throws SaturnJobConsoleException {
try {
log.info("start move {} to {}", namespace, zkClusterKeyNew);
if (updateDBOnly) {
namespaceZkclusterMapping4SqlService.update(namespace, null, zkClusterKeyNew, lastUpdatedBy);
} else {
String zkClusterKey = namespaceZkclusterMapping4SqlService.getZkClusterKey(namespace);
if (zkClusterKey != null && zkClusterKey.equals(zkClusterKeyNew)) {
// see
throw new SaturnJobConsoleException("The namespace(" + namespace + ") is in " + zkClusterKey);
// moveNamespaceBatchTo
// before
// modify
}
ZkCluster zkCluster = registryCenterService.getZkCluster(zkClusterKeyNew);
if (zkCluster == null) {
throw new SaturnJobConsoleException("The " + zkClusterKeyNew + " is not exists");
}
if (zkCluster.isOffline()) {
throw new SaturnJobConsoleException("The " + zkClusterKeyNew + " zkCluster is offline");
}
String zkAddr = zkCluster.getZkAddr();
CuratorRepository.CuratorFrameworkOp curatorFrameworkOp = registryCenterService.connectOnly(zkAddr, null);
if (curatorFrameworkOp == null) {
throw new SaturnJobConsoleException("The " + zkClusterKeyNew + " zkCluster is offline");
}
CuratorFramework curatorFramework = curatorFrameworkOp.getCuratorFramework();
CuratorRepository.CuratorFrameworkOp curatorFrameworkOpByNamespace = registryCenterService.connectOnly(zkAddr, namespace);
CuratorFramework curatorFrameworkByNamespace = curatorFrameworkOpByNamespace.getCuratorFramework();
try {
String namespaceNodePath = "/" + namespace;
if (curatorFramework.checkExists().forPath(namespaceNodePath) != null) {
curatorFramework.delete().deletingChildrenIfNeeded().forPath(namespaceNodePath);
}
String jobsNodePath = namespaceNodePath + JobNodePath.get$JobsNodePath();
curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(jobsNodePath);
List<CurrentJobConfig> configs = currentJobConfigService.findConfigsByNamespace(namespace);
log.info("get configs success, {}", namespace);
if (configs != null) {
for (CurrentJobConfig jobConfig : configs) {
jobOperationService.persistJobFromDB(jobConfig, curatorFrameworkOpByNamespace);
log.info("move {}-{} to zk success", namespace, jobConfig.getJobName());
}
}
} finally {
curatorFramework.close();
curatorFrameworkByNamespace.close();
}
log.info("move {} to zk {} success", namespace, zkClusterKeyNew);
namespaceZkclusterMapping4SqlService.update(namespace, null, zkClusterKeyNew, lastUpdatedBy);
log.info("update mapping table success, {}-{}", namespace, zkClusterKeyNew);
}
} catch (SaturnJobConsoleException e) {
log.error(e.getMessage(), e);
throw e;
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new SaturnJobConsoleException(e);
} finally {
log.info("end move {} to {}", namespace, zkClusterKeyNew);
}
}
use of com.vip.saturn.job.console.exception.SaturnJobConsoleException in project Saturn by vipshop.
the class ContainerController method getRegistryRepositoryTags.
@RequestMapping(value = "/getRegistryRepositoryTags", method = RequestMethod.GET)
public RequestResult getRegistryRepositoryTags(String repository, HttpServletRequest request) {
RequestResult requestResult = new RequestResult();
try {
if (repository == null) {
throw new SaturnJobConsoleException("The repository cannot be null");
}
String constraints = containerService.getRegistryRepositoryTags(repository);
requestResult.setSuccess(true);
requestResult.setObj(constraints);
} catch (SaturnJobConsoleException e) {
requestResult.setSuccess(false);
requestResult.setMessage(e.getMessage());
} catch (Throwable t) {
requestResult.setSuccess(false);
requestResult.setMessage(t.toString());
}
return requestResult;
}
Aggregations