refactor: add resource pool node check and return map

This commit is contained in:
guoyuqi 2023-07-17 19:47:04 +08:00 committed by 刘瑞斌
parent 14355b0562
commit c979e9ee7f
9 changed files with 225 additions and 28 deletions

View File

@ -0,0 +1,13 @@
package io.metersphere.sdk.dto;
import io.metersphere.system.domain.TestResourcePool;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TestResourcePoolReturnDTO extends TestResourcePool {
private TestResourceReturnDTO testResourceReturnDTO;
@Schema(title = "资源池是否在使用中")
private Boolean inUsed;
}

View File

@ -0,0 +1,89 @@
package io.metersphere.sdk.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
/**
*用来返回TestResourceBlob的结构
*/
@Getter
@Setter
public class TestResourceReturnDTO {
/**
* type为 node时, 性能测试的镜像
*/
@Schema(title = "type为node时, 性能测试的镜像")
private String loadTestImage;
/**
* type为 node时, 性能测试jvm配置
*/
@Schema(title = "type为node时, 性能测试jvm配置")
private String loadTestHeap;
/**
* type为 node时, 接口测试 性能测试 node 节点配置
*/
@Schema(title = "type为node时, 接口测试,性能测试node节点配置")
private List<TestResourceNodeDTO> nodesList;
/**
* type为 k8s 接口测试性能测试的ip
*/
@Schema(title = "type为k8s时接口测试性能测试的ip")
private String ip;
/**
* type为 k8s 接口测试性能测试的token
*/
@Schema(title = "type为k8s时接口测试性能测试的token")
private String token;
/**
* type为 k8s 接口测试性能测试的命名空间
*/
@Schema(title = "type为k8s时接口测试性能测试的命名空间")
private String nameSpaces;
/**
* type为 k8s 接口测试性能测试UI测试的最大并发数
*/
@Schema(title = "type为k8s时接口测试性能测试UI测试的最大并发数")
private Integer concurrentNumber;
/**
* type为 k8s 接口测试性能测试的单pod 最大线程数
*/
@Schema(title = "type为k8s时接口测试性能测试的单pod最大线程数")
private Integer podThreads;
/**
* type为 k8s 性能测试自定义JOB模版 string
*/
@Schema(title = " type为k8s时性能测试自定义JOB模版string")
private String jobDefinition;
/**
* type为 k8s 接口测试镜像
*/
@Schema(title = "type为k8s时接口测试镜像")
private String apiTestImage;
/**
* type为 k8s 接口测试deployName
*/
@Schema(title = "type为k8s时接口测试deployName")
private String deployName;
/**
* UI测试的grid配置
*/
@Schema(title = "UI测试的grid配置")
private String uiGrid;
/**
* 关联的组织id集合
*/
@Schema(title = "关联的组织id和名称map")
private Map<String,String> orgIdNameMap;
}

View File

@ -32,11 +32,29 @@ public class NodeResourcePoolService {
restTemplateWithTimeOut.setRequestFactory(httpRequestFactory);
}
public boolean validate(TestResourceDTO testResourceDTO) {
public boolean validate(TestResourceDTO testResourceDTO, Boolean usedApiType) {
List<TestResourceNodeDTO> nodesList = testResourceDTO.getNodesList();
if (CollectionUtils.isEmpty(nodesList)) {
throw new MSException(Translator.get("no_nodes_message"));
}
boolean isValid = true;
for (TestResourceNodeDTO testResourceNodeDTO : nodesList) {
if (StringUtils.isBlank(testResourceNodeDTO.getIp())) {
throw new MSException(Translator.get("ip_is_null"));
}
if (StringUtils.isBlank(testResourceNodeDTO.getPort())) {
throw new MSException(Translator.get("port_is_null"));
}
if (testResourceNodeDTO.getConcurrentNumber() == null) {
throw new MSException(Translator.get("concurrent_number_is_null"));
}
if (!usedApiType) {
if (StringUtils.isBlank(testResourceNodeDTO.getMonitor())) {
throw new MSException(Translator.get("monitor_number_is_null"));
}
}
isValid = validateNode(testResourceNodeDTO);
}
//校验节点
List<ImmutablePair<String, String>> ipPort = nodesList.stream()
.map(resource -> {
@ -47,10 +65,6 @@ public class NodeResourcePoolService {
if (ipPort.size() < nodesList.size()) {
throw new MSException(Translator.get("duplicate_node_ip_port"));
}
boolean isValid = true;
for (TestResourceNodeDTO testResourceNodeDTO : nodesList) {
isValid = validateNode(testResourceNodeDTO);
}
return isValid;
}

View File

@ -12,6 +12,7 @@ import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.*;
import io.metersphere.system.mapper.OrganizationMapper;
import io.metersphere.system.mapper.TestResourcePoolBlobMapper;
import io.metersphere.system.mapper.TestResourcePoolMapper;
import io.metersphere.system.mapper.TestResourcePoolOrganizationMapper;
@ -25,9 +26,7 @@ import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
@Slf4j
@Service
@ -117,7 +116,7 @@ public class TestResourcePoolService {
if (StringUtils.equalsIgnoreCase(type, ResourcePoolTypeEnum.NODE.name())) {
NodeResourcePoolService resourcePoolService = CommonBeanFactory.getBean(NodeResourcePoolService.class);
if (resourcePoolService != null) {
return resourcePoolService.validate(testResourceDTO);
return resourcePoolService.validate(testResourceDTO, usedApiType);
} else {
return false;
}
@ -234,23 +233,39 @@ public class TestResourcePoolService {
}
}
public TestResourcePoolDTO getTestResourcePoolDetail(String testResourcePoolId) {
TestResourcePoolDTO testResourcePoolDTO = new TestResourcePoolDTO();
public TestResourcePoolReturnDTO getTestResourcePoolDetail(String testResourcePoolId) {
TestResourcePoolReturnDTO testResourcePoolReturnDTO = new TestResourcePoolReturnDTO();
TestResourcePool testResourcePool = testResourcePoolMapper.selectByPrimaryKey(testResourcePoolId);
if (testResourcePool == null) {
throw new MSException(Translator.get("test_resource_pool_not_exists"));
}
TestResourcePoolBlob testResourcePoolBlob = testResourcePoolBlobMapper.selectByPrimaryKey(testResourcePoolId);
if (testResourcePoolBlob == null) {
BeanUtils.copyBean(testResourcePoolDTO, testResourcePool);
return testResourcePoolDTO;
BeanUtils.copyBean(testResourcePoolReturnDTO, testResourcePool);
return testResourcePoolReturnDTO;
}
byte[] configuration = testResourcePoolBlob.getConfiguration();
String testResourceDTOStr = new String(configuration);
TestResourceDTO testResourceDTO = JSON.parseObject(testResourceDTOStr, TestResourceDTO.class);
BeanUtils.copyBean(testResourcePoolDTO, testResourcePool);
testResourcePoolDTO.setTestResourceDTO(testResourceDTO);
return testResourcePoolDTO;
TestResourceReturnDTO testResourceReturnDTO = new TestResourceReturnDTO();
BeanUtils.copyBean(testResourceReturnDTO, testResourceDTO);
List<String> orgIds = testResourceDTO.getOrgIds();
Map<String,String> orgIdNameMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(orgIds)) {
for (String orgId : orgIds) {
OrganizationMapper organizationMapper = CommonBeanFactory.getBean(OrganizationMapper.class);
Organization organization = organizationMapper.selectByPrimaryKey(orgId);
if (organization != null) {
orgIdNameMap.put(orgId,organization.getName());
} else {
orgIdNameMap.put(orgId,Translator.get("organization_not_exists"));
}
}
}
testResourceReturnDTO.setOrgIdNameMap(orgIdNameMap);
BeanUtils.copyBean(testResourcePoolReturnDTO, testResourcePool);
testResourcePoolReturnDTO.setTestResourceReturnDTO(testResourceReturnDTO);
return testResourcePoolReturnDTO;
}
public LogDTO addLog(TestResourcePoolRequest request) {

View File

@ -79,6 +79,9 @@ test_resource_pool_not_exists=Test resource pool not exists
test_resource_pool_invalid=Test resource pool invalid
selenium_grid_is_null=selenium_grid cannot be null
ip_is_null=ip address/domain name cannot be null
port_is_null = Port cannot be null
concurrent_number_is_null = ConcurrentNumber cannot be null
monitor_is_null = Monitor cannot be null
token_is_null = Token can not be null
namespace_is_null=Namespaces can not be null
deploy_name_is_null=Deploy Name cannot be null

View File

@ -62,7 +62,7 @@ startTime_must_be_less_than_endTime=开始日期必须小于结束日期
start_time_is_null=开始日期不能为空
end_time_is_null=结束日期不能为空
organization_not_exists=工作空间不存在
organization_not_exists=组织不存在
#test resource pool
test_resource_pool_id_is_null=资源池ID不能为空
test_resource_pool_name_is_null=资源池名称不能为空
@ -77,6 +77,9 @@ test_resource_pool_not_exists=测试资源池不存在
test_resource_pool_invalid=当前测试使用的资源池处于禁用状态
selenium_grid_is_null=selenium_grid不能为空
ip_is_null=ip 地址/域名不能为空
port_is_null = 节点端口不能为空
concurrent_number_is_null = 节点最大线程数不能为空
monitor_is_null = node节点监控器不能为空
token_is_null = Token 不能为空
namespace_is_null=命名空间不能为空
deploy_name_is_null=Deploy Name 不能为空

View File

@ -63,7 +63,7 @@ start_time_is_null=開始日期不能為空
end_time_is_null=結束日期不能為空
#organization
organization_not_exists=工作空間不存在
organization_not_exists=組織不存在
#test resource pool
test_resource_pool_id_is_null=資源池ID不能為空
test_resource_pool_name_is_null=資源池名稱不能為空
@ -79,6 +79,9 @@ test_resource_pool_not_exists=測試資源池不存在
test_resource_pool_invalid=當前測試使用的資源池處於禁用狀態
selenium_grid_is_null=selenium_grid不能為空
ip_is_null=ip 地址/域名不能為空
port_is_null = 節點端口不能為空
concurrent_number_is_null = 節點最大線程數不能為空
monitor_is_null = node節點監控器不能為空
token_is_null = Token 不能為空
namespace_is_null=命名空間不能為空
deploy_name_is_null=Deploy Name 不能為空

View File

@ -6,6 +6,7 @@ import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.dto.QueryResourcePoolRequest;
import io.metersphere.sdk.dto.TestResourcePoolDTO;
import io.metersphere.sdk.dto.TestResourcePoolRequest;
import io.metersphere.sdk.dto.TestResourcePoolReturnDTO;
import io.metersphere.sdk.log.annotation.Log;
import io.metersphere.sdk.log.constants.OperationLogType;
import io.metersphere.sdk.service.TestResourcePoolService;
@ -78,7 +79,7 @@ public class TestResourcePoolController {
@GetMapping("/detail/{poolId}")
@Operation(summary = "查看资源池详细")
@RequiresPermissions(PermissionConstants.SYSTEM_TEST_RESOURCE_POOL_READ)
public TestResourcePoolDTO getTestResourcePoolDetail(@PathVariable(value = "poolId") String testResourcePoolId) {
public TestResourcePoolReturnDTO getTestResourcePoolDetail(@PathVariable(value = "poolId") String testResourcePoolId) {
return testResourcePoolService.getTestResourcePoolDetail(testResourcePoolId);
}

View File

@ -6,6 +6,7 @@ import io.metersphere.sdk.constants.ResourcePoolTypeEnum;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.controller.handler.ResultHolder;
import io.metersphere.sdk.dto.TestResourceDTO;
import io.metersphere.sdk.dto.TestResourceNodeDTO;
import io.metersphere.sdk.dto.TestResourcePoolRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.dto.QueryResourcePoolRequest;
@ -28,6 +29,7 @@ import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@ -69,6 +71,7 @@ class TestResourcePoolControllerTests extends BaseTest {
"\"deployName\":\"hello\",\n" +
"\"uiGrid\":\"localhost:4444\"\n" +
"}";
private static final String configuration = "{\n" +
" \"loadTestImage\": \"123\",\n" +
" \"loadTestHeap\": \"123\",\n" +
@ -344,19 +347,43 @@ class TestResourcePoolControllerTests extends BaseTest {
url = TEST_RESOURCE_POOL_UPDATE;
}
TestResourcePoolRequest testResourcePoolRequest = generatorDto(true, false, false, false);
TestResourcePoolRequest testResourcePoolRequest = generatorDto(true,true, false, false, false, false,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池类型为空
testResourcePoolRequest = generatorDto(false, true, false, false);
testResourcePoolRequest = generatorDto(true, false, true, false, false, false,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点集合为空
testResourcePoolRequest = generatorDto(false, false, true, false);
//api 类型 资源池节点集合为空
testResourcePoolRequest = generatorDto(true, false, false, true, false, false,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空 ip 为空
testResourcePoolRequest = generatorDto(true, false, false, true, false, true,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空 port 为空
testResourcePoolRequest = generatorDto(true, false, false, true, false, false,true,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空 最大线程数 为空
testResourcePoolRequest = generatorDto(true, false, false, true, false, false,false,false,true);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//性能测试类型 资源池节点集合为空
testResourcePoolRequest = generatorDto(false, false, false, true, false, false,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空ip为空
testResourcePoolRequest = generatorDto(false, false, false, true, false, true,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空 port 为空
testResourcePoolRequest = generatorDto(false, false, false, true, false, false,true,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空 port 为空
testResourcePoolRequest = generatorDto(false, false, false, true, false, false,false,true,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//资源池节点不为空但是内容为空 最大线程数 为空
testResourcePoolRequest = generatorDto(false, false, false, true, false, false,false,false,true);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//应用组织
testResourcePoolRequest = generatorDto(false, false, false, true);
testResourcePoolRequest = generatorDto(true,false, false, false, true, false,false,false,false);
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
//部分组织
testResourcePoolRequest = generatorDto(false, false, false, false);
testResourcePoolRequest = generatorDto(true,false, false, false, false, false, false,false,false);
testResourcePoolRequest.setAllOrg(false);
testResourcePoolRequest.setTestResourceDTO(JSON.parseObject(configurationWidthOutOrgIds, TestResourceDTO.class));
this.requestPost(url, testResourcePoolRequest, ERROR_REQUEST_MATCHER);
@ -398,7 +425,7 @@ class TestResourcePoolControllerTests extends BaseTest {
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
private TestResourcePoolRequest generatorDto(boolean noName, boolean noType, boolean noResources, boolean noAllOrg) {
private TestResourcePoolRequest generatorDto(boolean useApiType, boolean noName, boolean noType, boolean noResources, boolean noAllOrg, boolean noIp, boolean noPort, boolean noMonitor, boolean noConcurrentNumber) {
TestResourcePoolRequest testResourcePoolDTO = new TestResourcePoolRequest();
//没名字
if (!noName) {
@ -413,9 +440,38 @@ class TestResourcePoolControllerTests extends BaseTest {
testResourcePoolDTO.setApiTest(true);
setResources(testResourcePoolDTO,true);
}else {
testResourcePoolDTO.setApiTest(true);
testResourcePoolDTO.setApiTest(useApiType);
testResourcePoolDTO.setLoadTest(!useApiType);
TestResourceDTO testResourceDTO = JSON.parseObject(configuration, TestResourceDTO.class);
testResourceDTO.setNodesList(null);
//有资源池用途为API 或者 性能测试的校验 IP port monitor ConcurrentNumber 为空
TestResourceNodeDTO testResourceNodeDTO = new TestResourceNodeDTO();
if (noIp) {
testResourceNodeDTO.setIp("");
} else {
testResourceNodeDTO.setIp("172.2.130.1");
}
if (noPort) {
testResourceNodeDTO.setPort("");
} else {
testResourceNodeDTO.setPort("3306");
}
if (noMonitor) {
testResourceNodeDTO.setMonitor(" ");
} else {
testResourceNodeDTO.setMonitor("11");
}
if (noConcurrentNumber){
testResourceNodeDTO.setConcurrentNumber(null);
} else {
testResourceNodeDTO.setConcurrentNumber(1);
}
if (!noIp && !noPort && !noMonitor && ! noConcurrentNumber) {
testResourceDTO.setNodesList(null);
} else {
List<TestResourceNodeDTO>testResourceNodeDTOS = new ArrayList<>();
testResourceNodeDTOS.add(testResourceNodeDTO);
testResourceDTO.setNodesList(testResourceNodeDTOS);
}
testResourcePoolDTO.setTestResourceDTO(testResourceDTO);
}
//没选全部