refactor(image): 重构镜像服务相关代码

- 移除 ImageConfigProperties 类,改为直接在 application.yml 中配置 URL
- 新增 ExternalApiClient 接口,用于调用外部 API
- 更新 ImageCreateReq、ImageUpdateReq等请求类的字段
- 修改 ImageVirtualMachines、ImageTool等实体类的字段类型- 重构 ImageVirtualMachinesServiceImpl 中的镜像操作方法
- 更新相关控制器和服务类以适应新的接口和数据结构
master
chenhao 2025-09-02 16:57:59 +08:00
parent 550fda7ce2
commit a421493709
16 changed files with 155 additions and 228 deletions

View File

@ -4,6 +4,7 @@ import cn.hutool.json.JSONUtil;
import com.unisinsight.project.entity.req.DeviceReq; import com.unisinsight.project.entity.req.DeviceReq;
import com.unisinsight.project.entity.req.DeviceUserReq; import com.unisinsight.project.entity.req.DeviceUserReq;
import com.unisinsight.project.entity.req.LoginReq; import com.unisinsight.project.entity.req.LoginReq;
import com.unisinsight.project.entity.res.ImageDesktopRes;
import com.unisinsight.project.exception.BaseErrorCode; import com.unisinsight.project.exception.BaseErrorCode;
import com.unisinsight.project.exception.Result; import com.unisinsight.project.exception.Result;
import com.unisinsight.project.service.ClientService; import com.unisinsight.project.service.ClientService;

View File

@ -7,6 +7,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.Date;
/** /**
* (ImageDesktop) * (ImageDesktop)
@ -87,7 +89,7 @@ public class ImageDesktop extends Model<ImageDesktop> {
@TableField(value = "create_time", fill = FieldFill.INSERT) @TableField(value = "create_time", fill = FieldFill.INSERT)
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -103,7 +105,7 @@ public class ImageDesktop extends Model<ImageDesktop> {
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/
@ -135,7 +137,7 @@ public class ImageDesktop extends Model<ImageDesktop> {
@TableField(value = "publish_time") @TableField(value = "publish_time")
@ApiModelProperty("发布时间") @ApiModelProperty("发布时间")
private String publishTime; private Date publishTime;
} }

View File

@ -7,6 +7,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.Date;
/** /**
* (ImageTool) * (ImageTool)
@ -63,7 +65,7 @@ public class ImageTool extends Model<ImageTool> {
@TableField(value = "create_time", fill = FieldFill.INSERT) @TableField(value = "create_time", fill = FieldFill.INSERT)
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -79,7 +81,7 @@ public class ImageTool extends Model<ImageTool> {
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/
@ -93,9 +95,9 @@ public class ImageTool extends Model<ImageTool> {
**/ **/
@TableField(value = "upload_time") @TableField(value = "upload_time", fill = FieldFill.INSERT)
@ApiModelProperty("上传时间") @ApiModelProperty("上传时间")
private String uploadTime; private Date uploadTime;
/** /**
* *
**/ **/

View File

@ -3,10 +3,13 @@ package com.unisinsight.project.entity.dao;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.Date;
/** /**
* (ImageVirtualMachines) * (ImageVirtualMachines)
@ -48,18 +51,32 @@ public class ImageVirtualMachines extends Model<ImageVirtualMachines> {
@TableField(value = "os_version") @TableField(value = "os_version")
@ApiModelProperty("操作系统") @ApiModelProperty("操作系统")
private String osVersion; private String osVersion;
@TableField("os_variant")
@ApiModelProperty("操作系统版本")
private String osVariant;
/** /**
* *
**/ **/
@TableField(value = "storage_path") @TableField(value = "storage_path")
@ApiModelProperty("镜像存储路径") @ApiModelProperty("镜像存储路径")
private String storagePath; private String storagePath;
@TableField("storage_pool_name")
@ApiModelProperty("存储卷名称")
private String storagePoolName;
/**
*
**/
@TableField("image_tool_name")
@ApiModelProperty("驱动名称")
private String imageToolName;
/** /**
* *
**/ **/
@TableField(value = "create_time", fill = FieldFill.INSERT) @TableField(value = "create_time", fill = FieldFill.INSERT)
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -71,7 +88,7 @@ public class ImageVirtualMachines extends Model<ImageVirtualMachines> {
**/ **/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/

View File

@ -23,7 +23,7 @@ import lombok.NoArgsConstructor;
@Builder @Builder
public class ImageCreateReq { public class ImageCreateReq {
@JsonProperty("name") @JsonProperty("vm_name")
private String name; private String name;
@JsonProperty("os_type") @JsonProperty("os_type")
private String osType; private String osType;
@ -35,8 +35,7 @@ public class ImageCreateReq {
private Integer memory; private Integer memory;
@JsonProperty("disk_size") @JsonProperty("disk_size")
private Integer diskSize; private Integer diskSize;
@JsonProperty("disk_format")
private String diskFormat;
@JsonProperty("storage_pool_name") @JsonProperty("storage_pool_name")
private String storagePoolName; private String storagePoolName;
@JsonProperty("network_name") @JsonProperty("network_name")

View File

@ -6,6 +6,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.Date;
/** /**
* (ImageTool) * (ImageTool)
* *
@ -50,7 +52,7 @@ public class ImageToolReq {
**/ **/
@JsonProperty("create_time") @JsonProperty("create_time")
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -62,7 +64,7 @@ public class ImageToolReq {
**/ **/
@JsonProperty("update_time") @JsonProperty("update_time")
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/
@ -74,7 +76,7 @@ public class ImageToolReq {
**/ **/
@JsonProperty("upload_time") @JsonProperty("upload_time")
@ApiModelProperty("上传时间") @ApiModelProperty("上传时间")
private String uploadTime; private Date uploadTime;
/** /**
* *
**/ **/

View File

@ -30,8 +30,12 @@ public class ImageUpdateReq {
private Integer vcpus; private Integer vcpus;
@JsonProperty("memory") @JsonProperty("memory")
private Integer memory; private Integer memory;
@JsonProperty("disk_size")
private Integer diskSize;
@JsonProperty("network_name") @JsonProperty("network_name")
private String networkName; private String networkName;
@JsonProperty("STORAGE_POOL_NAME")
private String storagePoolName;
@JsonProperty("autostart") @JsonProperty("autostart")
private Boolean autostart; private Boolean autostart;
@JsonProperty("auto_mount_virtio") @JsonProperty("auto_mount_virtio")

View File

@ -6,6 +6,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.Date;
/** /**
* (ImageVirtualMachines) * (ImageVirtualMachines)
* *
@ -45,6 +47,12 @@ public class ImageVirtualMachinesReq {
@JsonProperty("os_version") @JsonProperty("os_version")
@ApiModelProperty("操作系统") @ApiModelProperty("操作系统")
private String osVersion; private String osVersion;
/**
*
**/
@JsonProperty("os_variant")
@ApiModelProperty("操作系统版本")
private String osVariant;
/** /**
* *
**/ **/
@ -71,7 +79,7 @@ public class ImageVirtualMachinesReq {
**/ **/
@JsonProperty("create_time") @JsonProperty("create_time")
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -83,7 +91,7 @@ public class ImageVirtualMachinesReq {
**/ **/
@JsonProperty("update_time") @JsonProperty("update_time")
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/
@ -118,7 +126,7 @@ public class ImageVirtualMachinesReq {
* (GB) * (GB)
**/ **/
@JsonProperty("memory_total") @JsonProperty("memory_total")
@ApiModelProperty("内存大小(GB)") @ApiModelProperty("内存大小(MB)")
private Integer memoryTotal; private Integer memoryTotal;
/** /**
* (GB) * (GB)

View File

@ -24,16 +24,7 @@ import java.util.List;
@Data @Data
public class ImageStatusRes { public class ImageStatusRes {
@JsonProperty("code")
private String code;
@JsonProperty("message")
private String message;
@JsonProperty("data")
private DataDTO data;
@NoArgsConstructor
@Data
public static class DataDTO {
@JsonProperty("items") @JsonProperty("items")
private List<ItemsDTO> items; private List<ItemsDTO> items;
@JsonProperty("total") @JsonProperty("total")
@ -124,5 +115,5 @@ public class ImageStatusRes {
private String network; private String network;
} }
} }
}
} }

View File

@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
* (ImageTool) * (ImageTool)
@ -52,7 +53,7 @@ public class ImageToolRes implements Serializable {
**/ **/
@JsonProperty("create_time") @JsonProperty("create_time")
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -64,7 +65,7 @@ public class ImageToolRes implements Serializable {
**/ **/
@JsonProperty("update_time") @JsonProperty("update_time")
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/
@ -76,7 +77,7 @@ public class ImageToolRes implements Serializable {
**/ **/
@JsonProperty("upload_time") @JsonProperty("upload_time")
@ApiModelProperty("上传时间") @ApiModelProperty("上传时间")
private String uploadTime; private Date uploadTime;
/** /**
* *
**/ **/

View File

@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
* (ImageVirtualMachines) * (ImageVirtualMachines)
@ -53,6 +54,9 @@ public class ImageVirtualMachinesRes implements Serializable {
@JsonProperty("os_version") @JsonProperty("os_version")
@ApiModelProperty("操作系统") @ApiModelProperty("操作系统")
private String osVersion; private String osVersion;
@JsonProperty("os_variant")
@ApiModelProperty("操作系统版本")
private String osVariant;
/** /**
* *
**/ **/
@ -64,7 +68,7 @@ public class ImageVirtualMachinesRes implements Serializable {
**/ **/
@JsonProperty("create_time") @JsonProperty("create_time")
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private String createTime; private Date createTime;
/** /**
* *
**/ **/
@ -76,7 +80,7 @@ public class ImageVirtualMachinesRes implements Serializable {
**/ **/
@JsonProperty("update_time") @JsonProperty("update_time")
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private String updateTime; private Date updateTime;
/** /**
* *
**/ **/
@ -125,9 +129,20 @@ public class ImageVirtualMachinesRes implements Serializable {
@JsonProperty("network_module") @JsonProperty("network_module")
@ApiModelProperty("网络模块") @ApiModelProperty("网络模块")
private String networkModule; private String networkModule;
@JsonProperty("storage_pool_name")
@ApiModelProperty("存储卷名称")
private String storagePoolName;
/**
*
**/
@JsonProperty("image_tool_name")
@ApiModelProperty("驱动名称")
private String imageToolName;
@JsonProperty("vnc_data") @JsonProperty("vnc_data")
@ApiModelProperty("远程连接信息") @ApiModelProperty("远程连接信息")
private ImageStatusRes.DataDTO.ItemsDTO.VncDTO vncData; private ImageStatusRes.ItemsDTO.VncDTO vncData;
} }

View File

@ -5,11 +5,14 @@ import com.unisinsight.project.entity.dto.ApiResponse;
import com.unisinsight.project.entity.dto.Network; import com.unisinsight.project.entity.dto.Network;
import com.unisinsight.project.entity.dto.NetworkData; import com.unisinsight.project.entity.dto.NetworkData;
import com.unisinsight.project.entity.dto.StoragePoolData; import com.unisinsight.project.entity.dto.StoragePoolData;
import com.unisinsight.project.entity.req.NetworkManageReq; import com.unisinsight.project.entity.req.*;
import com.unisinsight.project.entity.req.StoragePoolReq; import com.unisinsight.project.entity.res.ImageStatusRes;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/** /**
* API * API
*/ */
@ -52,4 +55,32 @@ public interface ExternalApiClient {
@GetMapping("/api/v1/storage/pools") @GetMapping("/api/v1/storage/pools")
ApiResponse<StoragePoolData> listStorage(@RequestParam("page")int page, @RequestParam("page_size")int pageSize); ApiResponse<StoragePoolData> listStorage(@RequestParam("page")int page, @RequestParam("page_size")int pageSize);
// 镜像虚拟机相关接口
@PostMapping("/api/v1/vm/batch-status")
ApiResponse<ImageStatusRes> getImageStatusData(@RequestBody Map<String, Object> requestBody);
@PostMapping("/api/v1/vm/create")
ApiResponse<ImageStatusRes> createImage(@RequestBody ImageCreateReq createReq);
@PostMapping("/api/v1/vm/update")
ApiResponse<ImageStatusRes> updateImage(@RequestBody ImageUpdateReq updateReq);
@PostMapping("/api/v1/vm/delete")
ApiResponse<ImageStatusRes> deleteImage(@RequestBody ImageDeleteReq deleteReq);
@PostMapping("/api/v1/vm/clone-to-desktop")
ApiResponse<ImageStatusRes> cloneTemplate(@RequestBody ImageCloneToDesktopReq cloneReq);
@PostMapping("/api/v1/vm/start")
ApiResponse<ImageStatusRes> startImage(@RequestBody ImageOperationReq operationReq);
@PostMapping("/api/v1/vm/shutdown")
ApiResponse<ImageStatusRes> shutdownImage(@RequestBody ImageOperationReq operationReq);
@PostMapping("/api/v1/vm/destroy")
ApiResponse<ImageStatusRes> destroyImage(@RequestBody ImageOperationReq operationReq);
@PostMapping("/api/v1/vm/reboot")
ApiResponse<ImageStatusRes> rebootImage(@RequestBody ImageOperationReq operationReq);
} }

View File

@ -1,106 +0,0 @@
package com.unisinsight.project.properties;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author : ch
* @version : 1.0
* @ClassName : ImageConfigProperties
* @Description :
* @DATE : Created in 15:52 2025/8/25
* <pre> Copyright: Copyright(c) 2025 </pre>
* <pre> Company : </pre>
* Modification History:
* Date Author Version Discription
* --------------------------------------------------------------------------
* 2025/08/25 ch 1.0 Why & What is modified: <> *
*/
@Component
@ConfigurationProperties(prefix = "image")
@Data
public class ImageConfigProperties {
/**
* URL
*/
private String baseUrl;
/**
* URL
*/
@Getter(value=AccessLevel.NONE)
private String statusUrl;
@Getter(value=AccessLevel.NONE)
private String createUrl;
@Getter(value=AccessLevel.NONE)
private String deleteUrl;
@Getter(value=AccessLevel.NONE)
private String updateUrl;
@Getter(value=AccessLevel.NONE)
private String startUrl;
@Getter(value=AccessLevel.NONE)
private String shutdownUrl;
@Getter(value=AccessLevel.NONE)
private String destroyUrl;
@Getter(value=AccessLevel.NONE)
private String rebootUrl;
@Getter(value=AccessLevel.NONE)
private String pauseUrl;
@Getter(value=AccessLevel.NONE)
private String resumeUrl;
@Getter(value=AccessLevel.NONE)
private String cloneToDesktopUrl;
public String getStatusUrl() {
return baseUrl+statusUrl;
}
public String getCreateUrl() {
return baseUrl+createUrl;
}
public String getDeleteUrl() {
return baseUrl+deleteUrl;
}
public String getUpdateUrl() {
return baseUrl+updateUrl;
}
public String getStartUrl() {
return baseUrl+startUrl;
}
public String getShutdownUrl() {
return baseUrl+shutdownUrl;
}
public String getDestroyUrl() {
return baseUrl+destroyUrl;
}
public String getRebootUrl() {
return baseUrl+rebootUrl;
}
public String getPauseUrl() {
return baseUrl+pauseUrl;
}
public String getResumeUrl() {
return baseUrl+resumeUrl;
}
public String getCloneToDesktopUrl() {
return baseUrl+cloneToDesktopUrl;
}
}

View File

@ -147,10 +147,7 @@ public class ImageToolServiceImpl extends ServiceImpl<ImageToolMapper, ImageTool
imageTool.setFileVersion(fileVersion); imageTool.setFileVersion(fileVersion);
imageTool.setFileType(fileType); imageTool.setFileType(fileType);
imageTool.setStorePath(completion.getFilePath()); imageTool.setStorePath(completion.getFilePath());
imageTool.setUploadTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
imageTool.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
imageTool.setCreateUser("admin"); imageTool.setCreateUser("admin");
imageTool.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
imageTool.setUpdateUser("admin"); imageTool.setUpdateUser("admin");
if (description != null && !description.isEmpty()) { if (description != null && !description.isEmpty()) {
imageTool.setDescription(description); imageTool.setDescription(description);

View File

@ -12,6 +12,7 @@ import com.unisinsight.project.entity.dao.Image;
import com.unisinsight.project.entity.dao.ImageTool; import com.unisinsight.project.entity.dao.ImageTool;
import com.unisinsight.project.entity.dao.ImageVirtualMachines; import com.unisinsight.project.entity.dao.ImageVirtualMachines;
import com.unisinsight.project.entity.dao.ImageDesktop; import com.unisinsight.project.entity.dao.ImageDesktop;
import com.unisinsight.project.entity.dto.ApiResponse;
import com.unisinsight.project.entity.req.DeleteIdReq; import com.unisinsight.project.entity.req.DeleteIdReq;
import com.unisinsight.project.entity.req.ImageCloneToDesktopReq; import com.unisinsight.project.entity.req.ImageCloneToDesktopReq;
import com.unisinsight.project.entity.req.ImageCreateReq; import com.unisinsight.project.entity.req.ImageCreateReq;
@ -24,8 +25,9 @@ import com.unisinsight.project.entity.res.ImageVirtualMachinesRes;
import com.unisinsight.project.entity.res.PageResult; import com.unisinsight.project.entity.res.PageResult;
import com.unisinsight.project.exception.BaseErrorCode; import com.unisinsight.project.exception.BaseErrorCode;
import com.unisinsight.project.exception.Result; import com.unisinsight.project.exception.Result;
import com.unisinsight.project.feign.ExternalApiClient;
import com.unisinsight.project.mapper.ImageVirtualMachinesMapper; import com.unisinsight.project.mapper.ImageVirtualMachinesMapper;
import com.unisinsight.project.properties.ImageConfigProperties;
import com.unisinsight.project.service.ImageDesktopService; import com.unisinsight.project.service.ImageDesktopService;
import com.unisinsight.project.service.ImageService; import com.unisinsight.project.service.ImageService;
import com.unisinsight.project.service.ImageToolService; import com.unisinsight.project.service.ImageToolService;
@ -35,9 +37,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.*;
@ -57,10 +57,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
private ImageVirtualMachinesMapper machinesMapper; private ImageVirtualMachinesMapper machinesMapper;
@Autowired @Autowired
private ImageService imageService; private ImageService imageService;
@Resource
private RestTemplate restTemplate;
@Autowired @Autowired
private ImageConfigProperties imageConfigProperties; private ExternalApiClient externalApiClient;
@Resource @Resource
private ImageToolService imageToolService; private ImageToolService imageToolService;
@Autowired @Autowired
@ -92,14 +90,14 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
//查询虚拟机数据 //查询虚拟机数据
List<String> nameList = data.stream().map(ImageVirtualMachinesRes::getImageName).filter(Objects::nonNull).distinct().collect(Collectors.toList()); List<String> nameList = data.stream().map(ImageVirtualMachinesRes::getImageName).filter(Objects::nonNull).distinct().collect(Collectors.toList());
// 添加请求参数 // 添加请求参数
Map<String, ImageStatusRes.DataDTO.ItemsDTO> imageStatusData = getImageStatusData(nameList); Map<String, ImageStatusRes.ItemsDTO> imageStatusData = getImageStatusData(nameList);
for (ImageVirtualMachinesRes res : data) { for (ImageVirtualMachinesRes res : data) {
if (res.getImageSystemId() != null && StringUtils.isNotEmpty(imageMap.get(res.getImageSystemId()))) { if (res.getImageSystemId() != null && StringUtils.isNotEmpty(imageMap.get(res.getImageSystemId()))) {
res.setImageSystemName(imageMap.get(res.getImageSystemId())); res.setImageSystemName(imageMap.get(res.getImageSystemId()));
} }
if (imageStatusData.containsKey(res.getImageName())) { if (imageStatusData.containsKey(res.getImageName())) {
ImageStatusRes.DataDTO.ItemsDTO itemsDTO = imageStatusData.get(res.getImageName()); ImageStatusRes.ItemsDTO itemsDTO = imageStatusData.get(res.getImageName());
res.setImageStatus(itemsDTO.getState()); res.setImageStatus(itemsDTO.getState());
res.setVncData(itemsDTO.getVnc()); res.setVncData(itemsDTO.getVnc());
} }
@ -111,23 +109,20 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
} }
} }
private Map<String, ImageStatusRes.DataDTO.ItemsDTO> getImageStatusData(List<String> nameList) { private Map<String, ImageStatusRes.ItemsDTO> getImageStatusData(List<String> nameList) {
Map<String, Object> requestBody = new HashMap<>(); Map<String, Object> requestBody = new HashMap<>();
requestBody.put("page", 1); requestBody.put("page", 1);
requestBody.put("page_size", 100); requestBody.put("page_size", 100);
requestBody.put("vm_names", nameList); requestBody.put("vm_names", nameList);
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.getImageStatusData(requestBody);
headers.setContentType(MediaType.APPLICATION_JSON); if (response != null && "200".equals(response.getCode()) && response.getData() != null) {
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers); List<ImageStatusRes.ItemsDTO> items = response.getData().getItems();
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(imageConfigProperties.getStatusUrl(), HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (exchange.getBody() != null && "200".equals(exchange.getBody().getCode()) && exchange.getBody().getData() != null) {
List<ImageStatusRes.DataDTO.ItemsDTO> items = exchange.getBody().getData().getItems();
if (CollUtil.isNotEmpty(items)) { if (CollUtil.isNotEmpty(items)) {
return items.stream().collect(Collectors.toMap(ImageStatusRes.DataDTO.ItemsDTO::getName, Function.identity(), (k1, k2) -> k1)); return items.stream().collect(Collectors.toMap(ImageStatusRes.ItemsDTO::getName, Function.identity(), (k1, k2) -> k1));
} }
} }
log.error("根据名称[{}]请求接口,返回数据为空:{}", nameList, exchange.getBody()); log.error("根据名称[{}]请求接口,返回数据为空:{}", nameList, response);
return Collections.emptyMap(); return Collections.emptyMap();
} }
@ -149,7 +144,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
Image systemImage = imageService.getOne(imageLambdaQueryWrapper); Image systemImage = imageService.getOne(imageLambdaQueryWrapper);
//查询驱动信息 //查询驱动信息
LambdaQueryWrapper<ImageTool> imageToolLambdaQueryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<ImageTool> imageToolLambdaQueryWrapper = new LambdaQueryWrapper<>();
imageToolLambdaQueryWrapper.eq(ImageTool::getFileName, imageVirtualMachinesReq.getImageName()); imageToolLambdaQueryWrapper.eq(ImageTool::getFileName, imageVirtualMachinesReq.getImageToolName());
ImageTool imageTool = imageToolService.getOne(imageToolLambdaQueryWrapper); ImageTool imageTool = imageToolService.getOne(imageToolLambdaQueryWrapper);
@ -157,24 +152,24 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
ImageCreateReq createReq = ImageCreateReq.builder() ImageCreateReq createReq = ImageCreateReq.builder()
.name(imageVirtualMachinesReq.getImageName()) .name(imageVirtualMachinesReq.getImageName())
.osType(imageVirtualMachinesReq.getOsVersion()) .osType(imageVirtualMachinesReq.getOsVersion())
.osVariant((systemImage!=null && StringUtils.isNotEmpty(systemImage.getImageVersion()))?systemImage.getImageVersion():"generic") .osVariant(StringUtils.isNotEmpty(imageVirtualMachinesReq.getOsVariant()) ? imageVirtualMachinesReq.getOsVariant() : "generic")
.vcpus(imageVirtualMachinesReq.getCpuTotal()) .vcpus(imageVirtualMachinesReq.getCpuTotal())
.memory(imageVirtualMachinesReq.getMemoryTotal()) .memory(imageVirtualMachinesReq.getMemoryTotal())
.diskSize(imageVirtualMachinesReq.getSystemTotal()) .diskSize(imageVirtualMachinesReq.getSystemTotal())
//存储池 //存储池
.storagePoolName(imageVirtualMachinesReq.getStoragePoolName()) .storagePoolName(imageVirtualMachinesReq.getStoragePoolName())
.networkName(imageVirtualMachinesReq.getNetworkModule()) .networkName(imageVirtualMachinesReq.getNetworkModule())
.isoPath(imageVirtualMachinesReq.getStoragePath()) .isoPath(systemImage.getStoragePath())
.autoMountVirtio(false)
.autostart(false)
//驱动 //驱动
.virtioWinPath(imageTool.getStorePath()) .virtioWinPath(imageTool.getStorePath())
.description(imageVirtualMachinesReq.getDescription()) .description(imageVirtualMachinesReq.getDescription())
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.createImage(createReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageCreateReq> requestEntity = new HttpEntity<>(createReq, headers);
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(imageConfigProperties.getCreateUrl(), HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)){
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "创建虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "创建虚拟机失败");
} }
@ -193,22 +188,24 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
@Override @Override
public Result<?> update(ImageVirtualMachinesReq imageVirtualMachinesReq) { public Result<?> update(ImageVirtualMachinesReq imageVirtualMachinesReq) {
// todo 调用镜像修改服务 //查询驱动信息
LambdaQueryWrapper<ImageTool> imageToolLambdaQueryWrapper = new LambdaQueryWrapper<>();
imageToolLambdaQueryWrapper.eq(ImageTool::getFileName, imageVirtualMachinesReq.getImageName());
ImageTool imageTool = imageToolService.getOne(imageToolLambdaQueryWrapper);
// 调用镜像修改服务
ImageUpdateReq updateReq = ImageUpdateReq.builder() ImageUpdateReq updateReq = ImageUpdateReq.builder()
.vmName(imageVirtualMachinesReq.getImageName()) .vmName(imageVirtualMachinesReq.getImageName())
.vcpus(imageVirtualMachinesReq.getCpuTotal()) .vcpus(imageVirtualMachinesReq.getCpuTotal())
.memory(imageVirtualMachinesReq.getMemoryTotal()) .memory(imageVirtualMachinesReq.getMemoryTotal())
.diskSize(imageVirtualMachinesReq.getSystemTotal())
.storagePoolName(imageVirtualMachinesReq.getStoragePoolName())
.networkName(imageVirtualMachinesReq.getNetworkModule()) .networkName(imageVirtualMachinesReq.getNetworkModule())
//驱动 //驱动
// .virtioWinPath(imageVirtualMachinesReq.getStoragePath()) .virtioWinPath(imageTool.getStorePath())
.description(imageVirtualMachinesReq.getDescription()) .description(imageVirtualMachinesReq.getDescription())
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.updateImage(updateReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageUpdateReq> requestEntity = new HttpEntity<>(updateReq, headers);
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(imageConfigProperties.getUpdateUrl(), HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)){
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "修改虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "修改虚拟机失败");
} }
@ -251,11 +248,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
.vmName(imageVirtualMachines.getImageName()) .vmName(imageVirtualMachines.getImageName())
.deleteStorage(true) .deleteStorage(true)
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.deleteImage(deleteReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageDeleteReq> requestEntity = new HttpEntity<>(deleteReq, headers);
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(imageConfigProperties.getDeleteUrl(), HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "删除虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "删除虚拟机失败");
} }
@ -271,6 +265,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
@Override @Override
public Result<?> cloneTemplate(ImageVirtualMachinesReq req) { public Result<?> cloneTemplate(ImageVirtualMachinesReq req) {
// todo 改为调用脚本方式执行
// 查询虚拟机信息 // 查询虚拟机信息
ImageVirtualMachines imageVirtualMachines = machinesMapper.selectById(req.getId()); ImageVirtualMachines imageVirtualMachines = machinesMapper.selectById(req.getId());
if (ObjectUtils.isEmpty(imageVirtualMachines)) { if (ObjectUtils.isEmpty(imageVirtualMachines)) {
@ -286,12 +281,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
.description("从虚拟机克隆的桌面镜像") .description("从虚拟机克隆的桌面镜像")
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.cloneTemplate(cloneReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageCloneToDesktopReq> requestEntity = new HttpEntity<>(cloneReq, headers);
String cloneToDesktopUrl = imageConfigProperties.getCloneToDesktopUrl();
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(cloneToDesktopUrl, HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "克隆虚拟机到桌面镜像失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "克隆虚拟机到桌面镜像失败");
} }
@ -330,11 +321,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
ImageOperationReq operationReq = ImageOperationReq.builder() ImageOperationReq operationReq = ImageOperationReq.builder()
.vmName(imageVirtualMachines.getImageName()) .vmName(imageVirtualMachines.getImageName())
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.startImage(operationReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageOperationReq> requestEntity = new HttpEntity<>(operationReq, headers);
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(imageConfigProperties.getStartUrl(), HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "启动虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "启动虚拟机失败");
} }
@ -354,12 +342,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
ImageOperationReq operationReq = ImageOperationReq.builder() ImageOperationReq operationReq = ImageOperationReq.builder()
.vmName(imageVirtualMachines.getImageName()) .vmName(imageVirtualMachines.getImageName())
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.shutdownImage(operationReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageOperationReq> requestEntity = new HttpEntity<>(operationReq, headers);
String shutdownUrl = imageConfigProperties.getShutdownUrl();
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(shutdownUrl, HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "关闭虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "关闭虚拟机失败");
} }
@ -379,12 +363,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
ImageOperationReq operationReq = ImageOperationReq.builder() ImageOperationReq operationReq = ImageOperationReq.builder()
.vmName(imageVirtualMachines.getImageName()) .vmName(imageVirtualMachines.getImageName())
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.destroyImage(operationReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageOperationReq> requestEntity = new HttpEntity<>(operationReq, headers);
String destroyUrl = imageConfigProperties.getDestroyUrl();
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(destroyUrl, HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "强制关闭虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "强制关闭虚拟机失败");
} }
@ -404,12 +384,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
ImageOperationReq operationReq = ImageOperationReq.builder() ImageOperationReq operationReq = ImageOperationReq.builder()
.vmName(imageVirtualMachines.getImageName()) .vmName(imageVirtualMachines.getImageName())
.build(); .build();
HttpHeaders headers = new HttpHeaders(); ApiResponse<ImageStatusRes> response = externalApiClient.rebootImage(operationReq);
headers.setContentType(MediaType.APPLICATION_JSON); if (response == null || !"200".equals(response.getCode())) {
HttpEntity<ImageOperationReq> requestEntity = new HttpEntity<>(operationReq, headers);
String rebootUrl = imageConfigProperties.getRebootUrl();
ResponseEntity<ImageStatusRes> exchange = restTemplate.exchange(rebootUrl, HttpMethod.POST, requestEntity, ImageStatusRes.class);
if (!exchange.getStatusCode().equals(HttpStatus.OK)) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "重启虚拟机失败"); return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "重启虚拟机失败");
} }

View File

@ -8,19 +8,6 @@ file:
bt-url: http://10.100.51.86:8114 bt-url: http://10.100.51.86:8114
tool: tool:
dir: /vms/tool/iso dir: /vms/tool/iso
image:
base-url: http://10.100.51.178:5173
status-url: /api/v1/vm/batch-status
create-url: /api/v1/vm/create
delete-url: /api/v1/vm/delete
update-url: /api/v1/vm/update
start-url: /api/v1/vm/start
shutdown-url: /api/v1/vm/shutdown
destroy-url: /api/v1/vm/destroy
reboot-url: /api/v1/vm/reboot
pause-url: /api/v1/vm/pause
resume-url: /api/v1/vm/resume
clone-to-desktop-url: /api/v1/vm/clone-to-desktop
spring: spring:
servlet: servlet:
multipart: multipart:
@ -63,7 +50,7 @@ mybatis-plus:
grpc: grpc:
server: server:
# 指定Grpc暴露的端口后续客户端通过这个端口访问 # 指定Grpc暴露的端口后续客户端通过这个端口访问
port: 50051 port: 51051
# Feign 配置 # Feign 配置
feign: feign: