package tech.powerjob.server.web.controller;
|
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.multipart.MultipartFile;
|
import tech.powerjob.common.OmsConstant;
|
import tech.powerjob.common.response.ResultDTO;
|
import tech.powerjob.server.auth.Permission;
|
import tech.powerjob.server.auth.RoleScope;
|
import tech.powerjob.server.auth.interceptor.ApiPermission;
|
import tech.powerjob.server.common.constants.ContainerSourceType;
|
import tech.powerjob.common.enums.SwitchableStatus;
|
import tech.powerjob.server.common.utils.OmsFileUtils;
|
import tech.powerjob.server.core.container.ContainerService;
|
import tech.powerjob.server.core.container.ContainerTemplateGenerator;
|
import tech.powerjob.server.persistence.remote.model.AppInfoDO;
|
import tech.powerjob.server.persistence.remote.model.ContainerInfoDO;
|
import tech.powerjob.server.persistence.remote.repository.AppInfoRepository;
|
import tech.powerjob.server.persistence.remote.repository.ContainerInfoRepository;
|
import tech.powerjob.server.web.request.GenerateContainerTemplateRequest;
|
import tech.powerjob.server.web.request.SaveContainerInfoRequest;
|
import tech.powerjob.server.web.response.ContainerInfoVO;
|
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.File;
|
import java.io.IOException;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* 容器信息控制层
|
*
|
* @author tjq
|
* @since 2020/5/15
|
*/
|
@Slf4j
|
@RestController
|
@RequestMapping("/container")
|
public class ContainerController {
|
|
private final ContainerService containerService;
|
|
private final AppInfoRepository appInfoRepository;
|
|
private final ContainerInfoRepository containerInfoRepository;
|
|
public ContainerController(ContainerService containerService, AppInfoRepository appInfoRepository, ContainerInfoRepository containerInfoRepository) {
|
this.containerService = containerService;
|
this.appInfoRepository = appInfoRepository;
|
this.containerInfoRepository = containerInfoRepository;
|
}
|
|
/**
|
* 暴露给 worker 的下载端口,制品本身 version 不可枚举,不单独鉴权
|
* 如果对此有安全性需求,可自行实现加密鉴权逻辑,或者干脆走自己的下载通道下载制品
|
* @param version 容器版本
|
* @param response 响应
|
* @throws IOException 异常
|
*/
|
@GetMapping("/downloadJar")
|
public void downloadJar(String version, HttpServletResponse response) throws IOException {
|
File file = containerService.fetchContainerJarFile(version);
|
if (file.exists()) {
|
OmsFileUtils.file2HttpResponse(file, response);
|
} else {
|
log.error("[Container] can't find container by version[{}], please deploy first!", version);
|
}
|
}
|
|
@PostMapping("/downloadContainerTemplate")
|
@ApiPermission(name = "Container-DownloadContainerTemplate", roleScope = RoleScope.APP, requiredPermission = Permission.READ)
|
public void downloadContainerTemplate(@RequestBody GenerateContainerTemplateRequest req, HttpServletResponse response) throws IOException {
|
File zipFile = ContainerTemplateGenerator.generate(req.getGroup(), req.getArtifact(), req.getName(), req.getPackageName(), req.getJavaVersion());
|
OmsFileUtils.file2HttpResponse(zipFile, response);
|
}
|
|
@PostMapping("/jarUpload")
|
@ApiPermission(name = "Container-JarUpload", roleScope = RoleScope.APP, requiredPermission = Permission.OPS)
|
public ResultDTO<String> fileUpload(@RequestParam("file") MultipartFile file) throws Exception {
|
if (file == null || file.isEmpty()) {
|
return ResultDTO.failed("empty file");
|
}
|
return ResultDTO.success(containerService.uploadContainerJarFile(file));
|
}
|
|
@PostMapping("/save")
|
@ApiPermission(name = "Container-Save", roleScope = RoleScope.APP, requiredPermission = Permission.OPS)
|
public ResultDTO<Void> saveContainer(@RequestBody SaveContainerInfoRequest request) {
|
request.valid();
|
|
ContainerInfoDO container = new ContainerInfoDO();
|
BeanUtils.copyProperties(request, container);
|
container.setSourceType(request.getSourceType().getV());
|
container.setStatus(request.getStatus().getV());
|
|
containerService.save(container);
|
return ResultDTO.success(null);
|
}
|
|
@GetMapping("/delete")
|
@ApiPermission(name = "Container-Delete", roleScope = RoleScope.APP, requiredPermission = Permission.OPS)
|
public ResultDTO<Void> deleteContainer(Long appId, Long containerId) {
|
containerService.delete(appId, containerId);
|
return ResultDTO.success(null);
|
}
|
|
@GetMapping("/list")
|
@ApiPermission(name = "Container-List", roleScope = RoleScope.APP, requiredPermission = Permission.READ)
|
public ResultDTO<List<ContainerInfoVO>> listContainers(Long appId) {
|
List<ContainerInfoVO> res = containerInfoRepository.findByAppIdAndStatusNot(appId, SwitchableStatus.DELETED.getV())
|
.stream().map(ContainerController::convert).collect(Collectors.toList());
|
return ResultDTO.success(res);
|
}
|
|
@GetMapping("/listDeployedWorker")
|
@ApiPermission(name = "Container-ListDeployedWorker", roleScope = RoleScope.APP, requiredPermission = Permission.READ)
|
public ResultDTO<String> listDeployedWorker(Long appId, Long containerId, HttpServletResponse response) {
|
AppInfoDO appInfoDO = appInfoRepository.findById(appId).orElseThrow(() -> new IllegalArgumentException("can't find app by id:" + appId));
|
String targetServer = appInfoDO.getCurrentServer();
|
|
if (StringUtils.isEmpty(targetServer)) {
|
return ResultDTO.failed("No workers have even registered!");
|
}
|
|
return ResultDTO.success(containerService.fetchDeployedInfo(appId, containerId));
|
}
|
|
private static ContainerInfoVO convert(ContainerInfoDO containerInfoDO) {
|
ContainerInfoVO vo = new ContainerInfoVO();
|
BeanUtils.copyProperties(containerInfoDO, vo);
|
if (containerInfoDO.getLastDeployTime() == null) {
|
vo.setLastDeployTime("N/A");
|
}else {
|
vo.setLastDeployTime(DateFormatUtils.format(containerInfoDO.getLastDeployTime(), OmsConstant.TIME_PATTERN));
|
}
|
SwitchableStatus status = SwitchableStatus.of(containerInfoDO.getStatus());
|
vo.setStatus(status.name());
|
ContainerSourceType sourceType = ContainerSourceType.of(containerInfoDO.getSourceType());
|
vo.setSourceType(sourceType.name());
|
return vo;
|
}
|
}
|