parent
9d17e273e9
commit
3db8b599c9
|
@ -1,5 +1,61 @@
|
||||||
-- set innodb lock wait timeout
|
-- set innodb lock wait timeout
|
||||||
SET SESSION innodb_lock_wait_timeout = 7200;
|
SET SESSION innodb_lock_wait_timeout = 7200;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS api_definition;
|
||||||
|
CREATE TABLE api_definition(
|
||||||
|
`id` VARCHAR(50) NOT NULL COMMENT '接口pk' ,
|
||||||
|
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||||
|
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
||||||
|
`update_time` BIGINT NOT NULL COMMENT '修改时间' ,
|
||||||
|
`update_user` VARCHAR(50) NOT NULL COMMENT '修改人' ,
|
||||||
|
`delete_user` VARCHAR(50) COMMENT '删除人' ,
|
||||||
|
`delete_time` BIGINT COMMENT '删除时间' ,
|
||||||
|
`deleted` BIT(1) NOT NULL DEFAULT 0 COMMENT '删除状态' ,
|
||||||
|
`name` VARCHAR(255) NOT NULL COMMENT '接口名称' ,
|
||||||
|
`method` VARCHAR(50) NOT NULL COMMENT '接口类型' ,
|
||||||
|
`protocol` VARCHAR(20) NOT NULL COMMENT '接口协议' ,
|
||||||
|
`path` VARCHAR(255) DEFAULT '' COMMENT '接口路径-只有HTTP协议有值' ,
|
||||||
|
`module_path` VARCHAR(1000) COMMENT '模块全路径-用于导入处理' ,
|
||||||
|
`status` VARCHAR(50) NOT NULL COMMENT '接口状态/进行中/已完成' ,
|
||||||
|
`module_id` VARCHAR(50) DEFAULT 'NONE' COMMENT '模块fk' ,
|
||||||
|
`num` INT COMMENT '自定义id' ,
|
||||||
|
`tags` VARCHAR(1000) COMMENT '标签' ,
|
||||||
|
`pos` BIGINT NOT NULL COMMENT '自定义排序' ,
|
||||||
|
`sync_enable` BIT(1) NOT NULL DEFAULT 0 COMMENT '是否启用同步' ,
|
||||||
|
`sync_time` BIGINT COMMENT '同步开始时间' ,
|
||||||
|
`project_id` VARCHAR(50) NOT NULL COMMENT '项目fk' ,
|
||||||
|
`environment_id` VARCHAR(50) COMMENT '环境fk' ,
|
||||||
|
`latest` BIT(1) NOT NULL DEFAULT 0 COMMENT '是否为最新版本 0:否,1:是' ,
|
||||||
|
`version_id` VARCHAR(50) COMMENT '版本fk' ,
|
||||||
|
`ref_id` VARCHAR(50) COMMENT '版本引用fk' ,
|
||||||
|
`description` VARCHAR(500) COMMENT '描述' ,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
) COMMENT = '接口定义';
|
||||||
|
|
||||||
|
|
||||||
|
CREATE INDEX idx_project_id ON api_definition(project_id);
|
||||||
|
CREATE INDEX idx_module_id ON api_definition(module_id);
|
||||||
|
CREATE INDEX idx_ref_id ON api_definition(ref_id);
|
||||||
|
CREATE INDEX idx_version_id ON api_definition(version_id);
|
||||||
|
CREATE INDEX idx_method ON api_definition(method);
|
||||||
|
CREATE INDEX idx_status ON api_definition(status);
|
||||||
|
CREATE INDEX idx_pos ON api_definition(pos);
|
||||||
|
CREATE INDEX idx_protocol ON api_definition(protocol);
|
||||||
|
CREATE INDEX idx_create_time ON api_definition(create_time);
|
||||||
|
CREATE INDEX idx_create_user ON api_definition(create_user);
|
||||||
|
CREATE INDEX idx_name ON api_definition(name);
|
||||||
|
CREATE INDEX idx_path ON api_definition(path);
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS api_definition_blob;
|
||||||
|
CREATE TABLE api_definition_blob(
|
||||||
|
`id` VARCHAR(50) NOT NULL COMMENT '接口fk/ 一对一关系' ,
|
||||||
|
`request` LONGBLOB COMMENT '请求内容' ,
|
||||||
|
`response` LONGBLOB COMMENT '响应内容' ,
|
||||||
|
`remark` BLOB COMMENT '备注' ,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
) COMMENT = '接口定义详情内容';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- set innodb lock wait timeout to default
|
-- set innodb lock wait timeout to default
|
||||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
|
@ -0,0 +1,18 @@
|
||||||
|
package io.metersphere.sdk.util;
|
||||||
|
|
||||||
|
import com.github.pagehelper.Page;
|
||||||
|
|
||||||
|
public class PageUtils {
|
||||||
|
public static <T> Pager<T> setPageInfo(Page page, T list) {
|
||||||
|
try {
|
||||||
|
Pager<T> pager = new Pager<>();
|
||||||
|
pager.setList(list);
|
||||||
|
pager.setPageSize(page.getPages());
|
||||||
|
pager.setCurrent(page.getPageNum());
|
||||||
|
pager.setTotal(page.getTotal());
|
||||||
|
return pager;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error saving current page number data!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.metersphere.sdk.util;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Pager<T> {
|
||||||
|
private T list;
|
||||||
|
private long total;
|
||||||
|
private long pageSize;
|
||||||
|
private long current;
|
||||||
|
|
||||||
|
public Pager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pager(T list, long total, long pageSize, long current) {
|
||||||
|
this.list = list;
|
||||||
|
this.total = total;
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.current = current;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,16 @@
|
||||||
package io.metersphere.api.controller;
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import com.github.pagehelper.Page;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import io.metersphere.api.domain.ApiDefinition;
|
||||||
import io.metersphere.api.dto.ApiDefinitionDTO;
|
import io.metersphere.api.dto.ApiDefinitionDTO;
|
||||||
|
import io.metersphere.api.dto.ApiDefinitionListRequest;
|
||||||
import io.metersphere.api.service.ApiDefinitionService;
|
import io.metersphere.api.service.ApiDefinitionService;
|
||||||
|
import io.metersphere.sdk.util.PageUtils;
|
||||||
|
import io.metersphere.sdk.util.Pager;
|
||||||
import io.metersphere.validation.groups.Created;
|
import io.metersphere.validation.groups.Created;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
@ -23,4 +30,12 @@ public class ApiDefinitionController {
|
||||||
@RequestParam(value = "files") List<MultipartFile> bodyFiles) {
|
@RequestParam(value = "files") List<MultipartFile> bodyFiles) {
|
||||||
return apiDefinitionService.create(request, bodyFiles);
|
return apiDefinitionService.create(request, bodyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/page")
|
||||||
|
public Pager<List<ApiDefinition>> list(@Validated @RequestBody ApiDefinitionListRequest request) {
|
||||||
|
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||||
|
StringUtils.isNotBlank(request.getOrderColumn()) ? request.getOrderColumn() : "create_time desc");
|
||||||
|
return PageUtils.setPageInfo(page, apiDefinitionService.list(request));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ApiDefinitionListRequest {
|
||||||
|
private String name;
|
||||||
|
private String path;
|
||||||
|
private String method;
|
||||||
|
private String protocol;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
private String OrderColumn;
|
||||||
|
|
||||||
|
@Min(value = 1, message = "当前页码必须大于0")
|
||||||
|
private int current;
|
||||||
|
@Min(value = 5, message = "每页显示条数必须不小于5")
|
||||||
|
private int pageSize;
|
||||||
|
}
|
|
@ -1,6 +1,13 @@
|
||||||
package io.metersphere.api.service;
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiDefinition;
|
||||||
|
import io.metersphere.api.domain.ApiDefinitionExample;
|
||||||
import io.metersphere.api.dto.ApiDefinitionDTO;
|
import io.metersphere.api.dto.ApiDefinitionDTO;
|
||||||
|
import io.metersphere.api.dto.ApiDefinitionListRequest;
|
||||||
|
import io.metersphere.api.mapper.ApiDefinitionMapper;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@ -9,7 +16,34 @@ import java.util.List;
|
||||||
@Service
|
@Service
|
||||||
public class ApiDefinitionService {
|
public class ApiDefinitionService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApiDefinitionMapper apiDefinitionMapper;
|
||||||
|
|
||||||
public ApiDefinitionDTO create(ApiDefinitionDTO request, List<MultipartFile> bodyFiles) {
|
public ApiDefinitionDTO create(ApiDefinitionDTO request, List<MultipartFile> bodyFiles) {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<ApiDefinition> list(@NotNull ApiDefinitionListRequest request) {
|
||||||
|
ApiDefinitionExample example = new ApiDefinitionExample();
|
||||||
|
ApiDefinitionExample.Criteria criteria = example.createCriteria();
|
||||||
|
criteria.andProjectIdEqualTo(request.getProjectId());
|
||||||
|
if (StringUtils.isNotBlank(request.getName())) {
|
||||||
|
criteria.andNameLike("%" + request.getName() + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(request.getPath())) {
|
||||||
|
criteria.andPathEqualTo(request.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(request.getMethod())) {
|
||||||
|
criteria.andMethodEqualTo(request.getMethod());
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(request.getProtocol())) {
|
||||||
|
criteria.andProtocolEqualTo(request.getProtocol());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return apiDefinitionMapper.selectByExample(example);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,30 @@
|
||||||
package io.metersphere.api.controller;
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiDefinition;
|
||||||
import io.metersphere.api.dto.ApiDefinitionDTO;
|
import io.metersphere.api.dto.ApiDefinitionDTO;
|
||||||
|
import io.metersphere.api.dto.ApiDefinitionListRequest;
|
||||||
|
import io.metersphere.sdk.controller.handler.ResultHolder;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.sdk.util.LogUtils;
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import io.metersphere.sdk.util.Pager;
|
||||||
import io.metersphere.utils.JsonUtils;
|
import io.metersphere.utils.JsonUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.*;
|
||||||
import org.junit.jupiter.api.Order;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.context.jdbc.Sql;
|
||||||
|
import org.springframework.test.context.jdbc.SqlConfig;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,4 +76,75 @@ public class ApiDefinitionControllerTests {
|
||||||
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(jsonPath("$.data.id").value("test-api-id"));
|
.andExpect(jsonPath("$.data.id").value("test-api-id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//正常接口获取
|
||||||
|
@Test
|
||||||
|
@Sql(scripts = {"/sql/init_api_definition.sql"},
|
||||||
|
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
|
||||||
|
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
|
||||||
|
@Order(2)
|
||||||
|
public void listSuccess() throws Exception {
|
||||||
|
int pageSize = 10;
|
||||||
|
int current = 1;
|
||||||
|
ApiDefinitionListRequest request = new ApiDefinitionListRequest();
|
||||||
|
request.setCurrent(current);
|
||||||
|
request.setPageSize(pageSize);
|
||||||
|
request.setProjectId("test-project-id");
|
||||||
|
|
||||||
|
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.multipart(prefix + "/page")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.content(JsonUtils.toJSONString(request)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
MockHttpServletResponse mockResponse = mvcResult.getResponse();
|
||||||
|
|
||||||
|
String returnData = mockResponse.getContentAsString();
|
||||||
|
ResultHolder resultHolder = JsonUtils.parseObject(returnData, ResultHolder.class);
|
||||||
|
|
||||||
|
//返回请求正常
|
||||||
|
Assertions.assertNotNull(resultHolder);
|
||||||
|
|
||||||
|
Pager<ApiDefinition> returnPager = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||||
|
|
||||||
|
//返回值不为空
|
||||||
|
Assertions.assertNotNull(returnPager);
|
||||||
|
//返回值的页码和当前页码相同
|
||||||
|
Assertions.assertEquals(returnPager.getCurrent(), current);
|
||||||
|
//返回的数据量不超过规定要返回的数据量相同
|
||||||
|
Assertions.assertTrue(((List<ApiDefinition>) returnPager.getList()).size() <= pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//没有传入必填值
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void listError() throws Exception {
|
||||||
|
// projectId为空
|
||||||
|
ApiDefinitionListRequest request = new ApiDefinitionListRequest();
|
||||||
|
request.setCurrent(1);
|
||||||
|
request.setPageSize(20);
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.multipart(prefix + "/page")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.content(JsonUtils.toJSONString(request)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isBadRequest());
|
||||||
|
|
||||||
|
//pageSize为空
|
||||||
|
request = new ApiDefinitionListRequest();
|
||||||
|
request.setCurrent(1);
|
||||||
|
request.setProjectId("test-project-id");
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.multipart(prefix + "/page")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.content(JsonUtils.toJSONString(request)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isBadRequest());
|
||||||
|
|
||||||
|
//current为空
|
||||||
|
request = new ApiDefinitionListRequest();
|
||||||
|
request.setPageSize(20);
|
||||||
|
request.setProjectId("test-project-id");
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.multipart(prefix + "/page")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.content(JsonUtils.toJSONString(request)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isBadRequest());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 插入测试数据
|
||||||
|
INSERT INTO `api_definition` VALUES ('101', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-11', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
||||||
|
INSERT INTO `api_definition` VALUES ('102', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-12', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
||||||
|
INSERT INTO `api_definition` VALUES ('103', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-13', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
||||||
|
INSERT INTO `api_definition` VALUES ('104', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-14', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
||||||
|
INSERT INTO `api_definition` VALUES ('105', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-15', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
||||||
|
INSERT INTO `api_definition` VALUES ('106', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-16', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
||||||
|
INSERT INTO `api_definition` VALUES ('107', 1, 'sty', 1, 'sty', NULL, NULL, b'0', 'sty-test-17', 'TCP', 'TCP', '', NULL, 'Prepared', 'NONE', NULL, NULL, 1, b'0', NULL, 'test-project-id', NULL, b'0', NULL, NULL, NULL);
|
Loading…
Reference in New Issue