feat:存储池和网络代码调用第三方
parent
5ec93514ad
commit
837afec179
|
|
@ -23,6 +23,7 @@
|
|||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<protobuf.version>3.23.4</protobuf.version>
|
||||
<spring-cloud.version>2021.0.5</spring-cloud.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
@ -32,6 +33,11 @@
|
|||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Configuration Processor (可选) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
@ -124,7 +130,19 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ package com.unisinsight.project;
|
|||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* 分片上传应用启动类
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@MapperScan(basePackages = "com.unisinsight.project.mapper")
|
||||
@EnableFeignClients(basePackages = "com.unisinsight.project.feign")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package com.unisinsight.project.config;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.Request;
|
||||
import feign.Retryer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class FeignConfig {
|
||||
|
||||
/**
|
||||
* 配置请求日志级别
|
||||
*/
|
||||
@Bean
|
||||
public Logger.Level feignLoggerLevel() {
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置超时时间
|
||||
*/
|
||||
@Bean
|
||||
public Request.Options options() {
|
||||
return new Request.Options(5000, 10000); // 连接超时5秒,读取超时10秒
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置重试机制
|
||||
*/
|
||||
@Bean
|
||||
public Retryer retryer() {
|
||||
return new Retryer.Default(1000, 2000, 3); // 初始间隔1秒,最大间隔2秒,最多重试3次
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
|
||||
package com.unisinsight.project.entity.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 通用API响应结果类
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(description = "API响应结果")
|
||||
public class ApiResponse<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "响应码")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "响应消息")
|
||||
private String message;
|
||||
|
||||
@ApiModelProperty(value = "响应数据")
|
||||
private T data;
|
||||
|
||||
public ApiResponse() {}
|
||||
|
||||
public ApiResponse(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ApiResponse(String code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应
|
||||
*/
|
||||
public static <T> ApiResponse<T> success() {
|
||||
return new ApiResponse<>("200", "操作成功");
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> success(T data) {
|
||||
return new ApiResponse<>("200", "操作成功", data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> success(String message, T data) {
|
||||
return new ApiResponse<>("200", message, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应
|
||||
*/
|
||||
public static <T> ApiResponse<T> error(String message) {
|
||||
return new ApiResponse<>("500", message);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> error(String code, String message) {
|
||||
return new ApiResponse<>(code, message);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> error(String code, String message, T data) {
|
||||
return new ApiResponse<>(code, message, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数校验错误
|
||||
*/
|
||||
public static <T> ApiResponse<T> badRequest(String message) {
|
||||
return new ApiResponse<>("400", message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限错误
|
||||
*/
|
||||
public static <T> ApiResponse<T> forbidden(String message) {
|
||||
return new ApiResponse<>("403", message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未找到
|
||||
*/
|
||||
public static <T> ApiResponse<T> notFound(String message) {
|
||||
return new ApiResponse<>("404", message);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,9 @@ public class StoragePoolReq {
|
|||
@ApiModelProperty(value = "id")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty("自动启动,默认是")
|
||||
private boolean autostart = true;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
@NotBlank(message = "名称不能为空")
|
||||
@Size(max = 64, message = "名称长度不能超过64个字符")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package com.unisinsight.project.feign;
|
||||
|
||||
import com.unisinsight.project.config.FeignConfig;
|
||||
import com.unisinsight.project.entity.dto.ApiResponse;
|
||||
import com.unisinsight.project.entity.req.NetworkManageReq;
|
||||
import com.unisinsight.project.entity.req.StoragePoolReq;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* 第三方API客户端
|
||||
*/
|
||||
@FeignClient(
|
||||
name = "external-api-client",
|
||||
url = "${external.api.url:http://10.100.51.118:8000}",
|
||||
configuration = FeignConfig.class
|
||||
)
|
||||
public interface ExternalApiClient {
|
||||
|
||||
@PostMapping("/api/v1/network/create")
|
||||
ApiResponse createNetwork(@RequestBody NetworkManageReq networkManageReq);
|
||||
|
||||
@DeleteMapping("/api/v1/network/{network_name}")
|
||||
ApiResponse deleteNetwork(@PathVariable("network_name") String networkName);
|
||||
|
||||
@PostMapping("/api/v1/network/update")
|
||||
ApiResponse updateNetwork(@RequestBody NetworkManageReq networkManageReq);
|
||||
|
||||
@PostMapping("/api/v1/network/start")
|
||||
ApiResponse startNetwork(@RequestBody NetworkManageReq networkManageReq);
|
||||
|
||||
@PostMapping("/api/v1/network/stop")
|
||||
ApiResponse stopNetwork(@RequestBody NetworkManageReq networkManageReq);
|
||||
|
||||
@PostMapping("/api/v1/storage/pools")
|
||||
ApiResponse createStorage(@RequestBody StoragePoolReq storagePoolReq);
|
||||
|
||||
@PostMapping("/api/v1/storage/pools/start")
|
||||
ApiResponse startStorage(@RequestBody StoragePoolReq storagePoolReq);
|
||||
|
||||
@PostMapping("/api/v1/storage/pools/stop")
|
||||
ApiResponse stopStorage(@RequestBody StoragePoolReq storagePoolReq);
|
||||
|
||||
@DeleteMapping("/api/v1/storage/pools/{pool_name}")
|
||||
ApiResponse deleteStorage(@PathVariable("pool_name") String poolName);
|
||||
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ public interface StoragePoolService {
|
|||
/**
|
||||
* 新增存储池
|
||||
*
|
||||
* @param storagePool 存储池对象
|
||||
* @param storagePoolReq
|
||||
* @return StoragePool 返回新增的存储池对象
|
||||
*/
|
||||
StoragePool addStoragePool(StoragePoolReq storagePoolReq);
|
||||
|
|
@ -22,7 +22,7 @@ public interface StoragePoolService {
|
|||
/**
|
||||
* 根据ID更新存储池信息
|
||||
*
|
||||
* @param storagePool 存储池对象
|
||||
* @param storagePoolReq
|
||||
* @return boolean 是否更新成功
|
||||
*/
|
||||
boolean updateStoragePool(StoragePoolReq storagePoolReq);
|
||||
|
|
@ -46,11 +46,7 @@ public interface StoragePoolService {
|
|||
/**
|
||||
* 分页查询存储池列表
|
||||
*
|
||||
* @param currentPage 当前页码
|
||||
* @param pageSize 每页大小
|
||||
* @param name 存储池名称(可选查询条件)
|
||||
* @param type 存储池类型(可选查询条件)
|
||||
* @param status 存储池状态(可选查询条件)
|
||||
* @param storagePoolReq
|
||||
* @return Page<StoragePool> 分页结果
|
||||
*/
|
||||
PageResult<StoragePool> pageStoragePools(StoragePoolReq storagePoolReq);
|
||||
|
|
|
|||
|
|
@ -5,16 +5,19 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.unisinsight.project.entity.dao.NetworkManage;
|
||||
import com.unisinsight.project.entity.dto.ApiResponse;
|
||||
import com.unisinsight.project.entity.req.NetworkManagePageReq;
|
||||
import com.unisinsight.project.entity.req.NetworkManageReq;
|
||||
import com.unisinsight.project.entity.res.PageResult;
|
||||
import com.unisinsight.project.exception.BusinessException;
|
||||
import com.unisinsight.project.feign.ExternalApiClient;
|
||||
import com.unisinsight.project.mapper.NetworkManageMapper;
|
||||
import com.unisinsight.project.service.NetworkManageService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -24,6 +27,8 @@ import java.util.List;
|
|||
@Service
|
||||
public class NetworkManageServiceImpl extends ServiceImpl<NetworkManageMapper, NetworkManage> implements NetworkManageService {
|
||||
|
||||
@Resource
|
||||
private ExternalApiClient client;
|
||||
/**
|
||||
* 新增网络管理信息
|
||||
*
|
||||
|
|
@ -38,6 +43,16 @@ public class NetworkManageServiceImpl extends ServiceImpl<NetworkManageMapper, N
|
|||
if (this.count(queryWrapper) > 0) {
|
||||
throw new BusinessException("网络名称'" + networkManageReq.getName() + "'已存在,请使用其他名称");
|
||||
}
|
||||
|
||||
// 调用虚拟机创建存储池
|
||||
try {
|
||||
ApiResponse response = client.createNetwork(networkManageReq);
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
// 设置创建时间和更新时间
|
||||
NetworkManage networkManage = new NetworkManage();
|
||||
BeanUtils.copyProperties(networkManageReq, networkManage);
|
||||
|
|
@ -76,8 +91,33 @@ public class NetworkManageServiceImpl extends ServiceImpl<NetworkManageMapper, N
|
|||
}
|
||||
existing.setName(networkManageReq.getName());
|
||||
}
|
||||
|
||||
// 调用虚拟机创建存储池
|
||||
try {
|
||||
ApiResponse response = client.updateNetwork(networkManageReq);
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 修改状态
|
||||
if(networkManageReq.getStatus() != null ){
|
||||
try {
|
||||
networkManageReq.setName(existing.getName());
|
||||
ApiResponse response;
|
||||
if(1==networkManageReq.getStatus()){
|
||||
response = client.startNetwork(networkManageReq);
|
||||
} else {
|
||||
response =client.stopNetwork(networkManageReq);
|
||||
}
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
existing.setStatus(networkManageReq.getStatus());
|
||||
}
|
||||
return this.updateById(existing);
|
||||
|
|
@ -90,8 +130,19 @@ public class NetworkManageServiceImpl extends ServiceImpl<NetworkManageMapper, N
|
|||
* @return boolean 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteNetworkManage(Integer id) {
|
||||
NetworkManage existing = this.getById(id);
|
||||
if (existing == null) {
|
||||
throw new BusinessException("网络管理信息不存在");
|
||||
}
|
||||
try {
|
||||
ApiResponse response = client.deleteNetwork(existing.getName());
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
return this.removeById(id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,18 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.unisinsight.project.entity.dao.NetworkManage;
|
||||
import com.unisinsight.project.entity.dao.StoragePool;
|
||||
import com.unisinsight.project.entity.dto.ApiResponse;
|
||||
import com.unisinsight.project.entity.req.StoragePoolReq;
|
||||
import com.unisinsight.project.entity.res.PageResult;
|
||||
import com.unisinsight.project.exception.BusinessException;
|
||||
import com.unisinsight.project.feign.ExternalApiClient;
|
||||
import com.unisinsight.project.mapper.StoragePoolMapper;
|
||||
import com.unisinsight.project.service.StoragePoolService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
|
|
@ -22,6 +25,9 @@ import java.util.Date;
|
|||
@Service
|
||||
public class StoragePoolServiceImpl extends ServiceImpl<StoragePoolMapper, StoragePool> implements StoragePoolService {
|
||||
|
||||
@Resource
|
||||
private ExternalApiClient client;
|
||||
|
||||
/**
|
||||
* 新增存储池
|
||||
*
|
||||
|
|
@ -37,6 +43,17 @@ public class StoragePoolServiceImpl extends ServiceImpl<StoragePoolMapper, Stora
|
|||
throw new BusinessException("存储池名称'" + storagePoolReq.getName() + "'已存在,请使用其他名称");
|
||||
}
|
||||
|
||||
// 调用虚拟机创建存储池
|
||||
try {
|
||||
ApiResponse response = client.createStorage(storagePoolReq);
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 本地保存
|
||||
StoragePool storagePool = new StoragePool();
|
||||
BeanUtils.copyProperties(storagePoolReq, storagePool);
|
||||
storagePool.setCreateTime(new Date());
|
||||
|
|
@ -49,7 +66,7 @@ public class StoragePoolServiceImpl extends ServiceImpl<StoragePoolMapper, Stora
|
|||
/**
|
||||
* 根据ID更新存储池信息
|
||||
*
|
||||
* @param storagePoolReq
|
||||
* @param storagePoolReq
|
||||
* @return boolean 是否更新成功
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -59,21 +76,36 @@ public class StoragePoolServiceImpl extends ServiceImpl<StoragePoolMapper, Stora
|
|||
return false;
|
||||
}
|
||||
|
||||
// 不能修改名称
|
||||
// 如果名称不为空且与原名称不同,则进行重名校验
|
||||
if (storagePoolReq.getName() != null && !storagePoolReq.getName().isEmpty()
|
||||
&& !storagePoolReq.getName().equals(existing.getName())) {
|
||||
// 检查新名称是否重复
|
||||
QueryWrapper<StoragePool> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("name", storagePoolReq.getName());
|
||||
if (this.count(queryWrapper) > 0) {
|
||||
throw new BusinessException("存储池名称'" + storagePoolReq.getName() + "'已存在,请使用其他名称");
|
||||
}
|
||||
existing.setName(storagePoolReq.getName());
|
||||
}
|
||||
// if (storagePoolReq.getName() != null && !storagePoolReq.getName().isEmpty()
|
||||
// && !storagePoolReq.getName().equals(existing.getName())) {
|
||||
// // 检查新名称是否重复
|
||||
// QueryWrapper<StoragePool> queryWrapper = new QueryWrapper<>();
|
||||
// queryWrapper.eq("name", storagePoolReq.getName());
|
||||
// if (this.count(queryWrapper) > 0) {
|
||||
// throw new BusinessException("存储池名称'" + storagePoolReq.getName() + "'已存在,请使用其他名称");
|
||||
// }
|
||||
// existing.setName(storagePoolReq.getName());
|
||||
// }
|
||||
|
||||
// 调用虚拟机创建存储池
|
||||
// 修改状态
|
||||
if (storagePoolReq.getStatus() != null
|
||||
&& !storagePoolReq.getStatus().equals(existing.getStatus())) {
|
||||
if (storagePoolReq.getStatus() != null) {
|
||||
try {
|
||||
storagePoolReq.setName(existing.getName());
|
||||
ApiResponse response;
|
||||
if(1==storagePoolReq.getStatus()){
|
||||
response = client.startStorage(storagePoolReq);
|
||||
} else {
|
||||
response =client.stopStorage(storagePoolReq);
|
||||
}
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
existing.setStatus(storagePoolReq.getStatus());
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +122,19 @@ public class StoragePoolServiceImpl extends ServiceImpl<StoragePoolMapper, Stora
|
|||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteStoragePool(Long id) {
|
||||
StoragePool existing = this.getById(id);
|
||||
if (existing == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ApiResponse response = client.deleteStorage(existing.getName());
|
||||
if (!"200".equals(response.getCode())) {
|
||||
throw new BusinessException("调用外部接口失败: " + response.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("调用外部接口失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
return this.removeById(id);
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +152,7 @@ public class StoragePoolServiceImpl extends ServiceImpl<StoragePoolMapper, Stora
|
|||
/**
|
||||
* 分页查询存储池列表
|
||||
*
|
||||
* @param storagePoolReq
|
||||
* @param storagePoolReq
|
||||
* @return Page<StoragePool> 分页结果
|
||||
*/
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -55,4 +55,19 @@ mybatis-plus:
|
|||
grpc:
|
||||
server:
|
||||
# 指定Grpc暴露的端口,后续客户端通过这个端口访问
|
||||
port: 51051
|
||||
port: 51051
|
||||
|
||||
# Feign 配置
|
||||
feign:
|
||||
client:
|
||||
config:
|
||||
external-api-client: # 对应 FeignClient 的 name
|
||||
logger-level: full # 完整日志级别
|
||||
default: # 全局默认配置
|
||||
logger-level: basic
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.unisinsight.project.feign: debug # Feign 客户端包路径
|
||||
com.unisinsight.project.feign.ExternalApiClient: debug
|
||||
Loading…
Reference in New Issue