feat(image): 添加获取 VNC信息功能并优化镜像相关服务
- 在 DeviceImageMappingRes 中添加父镜像名称和创建时间字段 - 优化 DeviceImageMappingService 中镜像信息查询逻辑- 在 ExternalApiClient 中添加获取VNC 信息的接口 - 在 ImageVirtualMachinesController 中添加获取 VNC 信息的控制器方法- 在 ImageVirtualMachinesService接口中添加获取 VNC 信息的方法 - 实现 ImageVirtualMachinesServiceImpl 中获取 VNC 信息的逻辑 - 新增 VncData 类用于存储 VNC 信息master
parent
65365b2a86
commit
3c8d1b833b
|
|
@ -13,10 +13,7 @@ import com.unisinsight.project.service.ImageVirtualMachinesService;
|
|||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
|
@ -154,6 +151,13 @@ public class ImageVirtualMachinesController {
|
|||
log.info("终端卸载文件请求参数为:{}", JSONUtil.toJsonStr(req));
|
||||
return service.removeIso(req);
|
||||
}
|
||||
@ApiOperation(value = "获取VNC信息")
|
||||
@GetMapping("/vnc")
|
||||
public Result<?> getVncData(@RequestParam("vmName") String vmName) {
|
||||
|
||||
log.info("获取VNC信息请求参数为:{}", vmName);
|
||||
return service.getVncData(vmName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
|
|||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @TableName device_image_mapping
|
||||
|
|
@ -59,6 +60,19 @@ public class DeviceImageMappingRes implements Serializable {
|
|||
@JsonProperty(value = "image_file_name")
|
||||
@ApiModelProperty("镜像源文件名称")
|
||||
private String imageFileName;
|
||||
|
||||
/**
|
||||
* 父镜像名称
|
||||
*/
|
||||
@JsonProperty(value = "parent_image_name")
|
||||
@ApiModelProperty("父镜像名称")
|
||||
private String parentImageName;
|
||||
/**
|
||||
* 父镜像名称
|
||||
*/
|
||||
@JsonProperty(value = "create_time")
|
||||
@ApiModelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 还原方式
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.unisinsight.project.entity.res;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author : ch
|
||||
* @version : 1.0
|
||||
* @ClassName : VncData
|
||||
* @Description :
|
||||
* @DATE : Created in 9:41 2025/9/8
|
||||
* <pre> Copyright: Copyright(c) 2025 </pre>
|
||||
* <pre> Company : 紫光汇智信息技术有限公司 </pre>
|
||||
* Modification History:
|
||||
* Date Author Version Discription
|
||||
* --------------------------------------------------------------------------
|
||||
* 2025/09/08 ch 1.0 Why & What is modified: <修改原因描述> *
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class VncData {
|
||||
|
||||
@JsonProperty("host")
|
||||
private String host;
|
||||
@JsonProperty("port")
|
||||
private Integer port;
|
||||
@JsonProperty("url")
|
||||
private String url;
|
||||
@JsonProperty("websocket_url")
|
||||
private String websocketUrl;
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.unisinsight.project.config.FeignConfig;
|
|||
import com.unisinsight.project.entity.dto.*;
|
||||
import com.unisinsight.project.entity.req.*;
|
||||
import com.unisinsight.project.entity.res.ImageStatusRes;
|
||||
import com.unisinsight.project.entity.res.VncData;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
|
@ -90,5 +91,7 @@ public interface ExternalApiClient {
|
|||
|
||||
@GetMapping("/api/v1/network/bridge-interfaces")
|
||||
ApiResponse<List<BridgeInterfaceDTO>> getBridgeInterfaces();
|
||||
@GetMapping("/api/v1/vm/{vmName}/vnc")
|
||||
ApiResponse<VncData> getVncData(@PathVariable("vmName") String vmName);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class ClientNotificationServiceImpl extends NotificationServiceGrpc.Notif
|
|||
private final ConcurrentHashMap<String, StreamObserver<NotificationMessage>> clientStreamMap =
|
||||
new ConcurrentHashMap<>();
|
||||
private final static int MAX_CLIENT_COUNT = 1000;
|
||||
|
||||
public static final String DEFAULT_USER = "NexOS";
|
||||
// 生成客户端连接key的工具方法
|
||||
private String generateClientKey(String clientId, String clientUser) {
|
||||
return clientId + "#" + clientUser;
|
||||
|
|
@ -70,15 +70,7 @@ public class ClientNotificationServiceImpl extends NotificationServiceGrpc.Notif
|
|||
return; // 避免继续执行后续逻辑
|
||||
}
|
||||
|
||||
if (StringUtil.isEmpty(clientUser)) {
|
||||
NotificationMessage errMsg = NotificationMessage.newBuilder()
|
||||
.setCode(HttpStatus.BAD_REQUEST.value())
|
||||
.setMsg("client_user不能为空")
|
||||
.build();
|
||||
responseObserver.onNext(errMsg);
|
||||
responseObserver.onCompleted();
|
||||
return; // 避免继续执行后续逻辑
|
||||
}
|
||||
clientUser= StringUtil.isEmpty(clientUser) ? DEFAULT_USER : clientUser;
|
||||
|
||||
log.info("客户端连接:client_sn:[{}],client_user: [{}]", clientSn, clientUser);
|
||||
|
||||
|
|
@ -93,11 +85,12 @@ public class ClientNotificationServiceImpl extends NotificationServiceGrpc.Notif
|
|||
final io.grpc.Context context = io.grpc.Context.current();
|
||||
|
||||
// 注册一个取消监听器来监听客户端断开连接
|
||||
String finalClientUser = clientUser;
|
||||
context.addListener(context1 -> {
|
||||
// 客户端断开连接时的处理逻辑
|
||||
log.info("通过Context监听到客户端断开连接: {}, 用户: {}", clientSn, clientUser);
|
||||
removeClientConnection(clientSn, clientUser);
|
||||
log.info("清理客户端连接: {}#{}, 剩余客户端数: {}", clientSn, clientUser, clientStreamMap.size());
|
||||
log.info("通过Context监听到客户端断开连接: {}, 用户: {}", clientSn, finalClientUser);
|
||||
removeClientConnection(clientSn, finalClientUser);
|
||||
log.info("清理客户端连接: {}#{}, 剩余客户端数: {}", clientSn, finalClientUser, clientStreamMap.size());
|
||||
}, executorService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,5 +61,7 @@ public interface ImageVirtualMachinesService extends IService<ImageVirtualMachin
|
|||
Result<?> removeIso(ImageVirtualMachinesReq req);
|
||||
|
||||
Result<?> attachIso(ImageVirtualMachinesReq req);
|
||||
|
||||
Result<?> getVncData(String vmName);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,23 +7,18 @@ import cn.hutool.json.JSONUtil;
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.unisinsight.project.entity.dao.DeviceImageMapping;
|
||||
import com.unisinsight.project.entity.dao.Image;
|
||||
import com.unisinsight.project.entity.dao.ImageDesktop;
|
||||
import com.unisinsight.project.entity.dao.UserDeviceGroup;
|
||||
import com.unisinsight.project.entity.dao.*;
|
||||
import com.unisinsight.project.entity.req.DeviceImageMappingReq;
|
||||
import com.unisinsight.project.entity.res.DeviceImageMappingRes;
|
||||
import com.unisinsight.project.exception.Result;
|
||||
import com.unisinsight.project.mapper.DeviceImageMappingMapper;
|
||||
import com.unisinsight.project.mapper.ImageDesktopMapper;
|
||||
import com.unisinsight.project.mapper.ImageMapper;
|
||||
import com.unisinsight.project.mapper.UserDeviceGroupMapper;
|
||||
import com.unisinsight.project.mapper.*;
|
||||
import com.unisinsight.project.service.DeviceImageMappingService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -43,6 +38,8 @@ public class DeviceImageMappingServiceImpl extends ServiceImpl<DeviceImageMappin
|
|||
@Resource
|
||||
private ImageDesktopMapper imageDesktopMapper;
|
||||
@Resource
|
||||
private ImageVirtualMachinesMapper imageVirtualMachinesMapper;
|
||||
@Resource
|
||||
private UserDeviceGroupMapper groupMapper;
|
||||
|
||||
|
||||
|
|
@ -64,11 +61,21 @@ public class DeviceImageMappingServiceImpl extends ServiceImpl<DeviceImageMappin
|
|||
if (CollectionUtil.isNotEmpty(imageIds)) {
|
||||
LambdaQueryWrapper<ImageDesktop> imageLambdaQueryWrapper = new LambdaQueryWrapper<ImageDesktop>().in(ImageDesktop::getId, imageIds);
|
||||
List<ImageDesktop> images = imageDesktopMapper.selectList(imageLambdaQueryWrapper);
|
||||
List<Integer> imageVirtualIdList = images.stream().map(ImageDesktop::getImageVirtualId).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
LambdaQueryWrapper<ImageVirtualMachines> imageVirtualMachinesLambdaQueryWrapper = new LambdaQueryWrapper<ImageVirtualMachines>().in(ImageVirtualMachines::getId, imageVirtualIdList);
|
||||
List<ImageVirtualMachines> imageVirtualMachines = imageVirtualMachinesMapper.selectList(imageVirtualMachinesLambdaQueryWrapper);
|
||||
Map<Long, String> imageVirtualMachinesMap = imageVirtualMachines.stream().collect(Collectors.toMap(ImageVirtualMachines::getId, ImageVirtualMachines::getImageName));
|
||||
|
||||
if (CollectionUtil.isNotEmpty(images)) {
|
||||
deviceImageMappingRes.forEach(deviceImage -> images.forEach(image -> {
|
||||
if (ObjectUtil.isNotEmpty(deviceImage.getImageId()) && image.getId().equals(deviceImage.getImageId())) {
|
||||
deviceImage.setImageName(image.getDesktopName());
|
||||
deviceImage.setImageFileName(image.getDesktopName()+"."+image.getDesktopType());
|
||||
deviceImage.setCreateTime(image.getCreateTime());
|
||||
// 设置父镜像名称
|
||||
if (image.getImageVirtualId() != null) {
|
||||
deviceImage.setParentImageName(imageVirtualMachinesMap.get(image.getImageVirtualId().longValue()));
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.unisinsight.project.entity.req.*;
|
|||
import com.unisinsight.project.entity.res.ImageStatusRes;
|
||||
import com.unisinsight.project.entity.res.ImageVirtualMachinesRes;
|
||||
import com.unisinsight.project.entity.res.PageResult;
|
||||
import com.unisinsight.project.entity.res.VncData;
|
||||
import com.unisinsight.project.exception.BaseErrorCode;
|
||||
import com.unisinsight.project.exception.Result;
|
||||
import com.unisinsight.project.feign.ExternalApiClient;
|
||||
|
|
@ -323,7 +324,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
|
|||
imageDesktop.setDesktopName(fileName);
|
||||
imageDesktop.setDesktopType(type);
|
||||
//制作中
|
||||
imageDesktop.setPublishStatus("0");
|
||||
imageDesktop.setPublishStatus(0);
|
||||
imageDesktop.setStoragePath(detFile);
|
||||
imageDesktop.setImageVirtualId(Math.toIntExact(req.getId()));
|
||||
imageDesktop.setOsVersion(imageVirtualMachines.getOsVersion());
|
||||
|
|
@ -428,7 +429,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
|
|||
updateWrapper.eq(ImageDesktop::getDesktopName, fileName);
|
||||
Long fileSize = externalTorrentClient.getFileSize(detFilePath);
|
||||
log.info("det文件大小: {} 字节", fileSize);
|
||||
updateWrapper.set(ImageDesktop::getPublishStatus, "1");
|
||||
updateWrapper.set(ImageDesktop::getPublishStatus, 1);
|
||||
updateWrapper.set(ImageDesktop::getFileSize, fileSize);
|
||||
updateWrapper.set(ImageDesktop::getPublishTime, DateUtil.date());
|
||||
//转化bt
|
||||
|
|
@ -578,5 +579,14 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
|
|||
return Result.successResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<?> getVncData(String vmName) {
|
||||
ApiResponse<VncData> vncData = externalApiClient.getVncData(vmName);
|
||||
if ("200".equals(vncData.getCode())){
|
||||
return Result.successResult(vncData.getData());
|
||||
}
|
||||
return Result.errorResultMessage(BaseErrorCode.HTTP_ERROR_CODE_500, vncData.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue