diff --git a/backend/pom.xml b/backend/pom.xml index 34721c92c4..0afd90ed95 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -161,6 +161,17 @@ 2.1.7 + com.fit2cloud quartz-spring-boot-starter @@ -296,39 +307,9 @@ - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone - - false - - - - jcenter-snapshots - jcenter - https://jcenter.bintray.com/ - - - fit2cloud-enterprise-release - Fit2Cloud Enterprise Release - http://repository.fit2cloud.com/content/repositories/fit2cloud-enterprise-release/ - - true - - - true - - - - fit2cloud + github fit2cloud - http://repository.fit2cloud.com/content/groups/public/ - - true - - - true - + https://maven.pkg.github.com/fit2cloud/quartz-spring-boot-starter diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index 84cff582b3..e44ed2f5a2 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -50,8 +50,8 @@ public class APITestController { return apiTestService.getApiTestByProjectId(projectId); } - /*查询某个api测试状态*/ - @GetMapping("/list/all/{testId}") + + @GetMapping("/state/get/{testId}") public ApiTest apiState(@PathVariable String testId) { return apiTestService.getApiTestByTestId(testId); } @@ -96,4 +96,10 @@ public class APITestController { return apiTestService.run(request); } + @PostMapping("/import/{platform}") + @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) + public ApiTest testCaseImport(MultipartFile file, @PathVariable String platform) { + return apiTestService.apiTestImport(file, platform); + } + } diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/ApiImport.java b/backend/src/main/java/io/metersphere/api/dto/parse/ApiImport.java new file mode 100644 index 0000000000..deddba481a --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/ApiImport.java @@ -0,0 +1,11 @@ +package io.metersphere.api.dto.parse; + +import io.metersphere.api.dto.scenario.Scenario; +import lombok.Data; + +import java.util.List; + +@Data +public class ApiImport { + private List scenarios; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanCollection.java b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanCollection.java new file mode 100644 index 0000000000..636feab232 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanCollection.java @@ -0,0 +1,13 @@ +package io.metersphere.api.dto.parse.postman; + +import lombok.Data; + +import java.util.List; + +@Data +public class PostmanCollection { + + private PostmanCollectionInfo info; + + private List item; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanCollectionInfo.java b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanCollectionInfo.java new file mode 100644 index 0000000000..d5307a7cda --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanCollectionInfo.java @@ -0,0 +1,13 @@ +package io.metersphere.api.dto.parse.postman; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +@Data +public class PostmanCollectionInfo { + + @JSONField(name = "_postman_id") + private String postmanId; + private String name; + private String schema; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanItem.java b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanItem.java new file mode 100644 index 0000000000..1d780e7d23 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanItem.java @@ -0,0 +1,13 @@ +package io.metersphere.api.dto.parse.postman; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +@Data +public class PostmanItem { + + private String name; + private PostmanRequest request; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanKeyValue.java b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanKeyValue.java new file mode 100644 index 0000000000..c68e4fc114 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanKeyValue.java @@ -0,0 +1,18 @@ +package io.metersphere.api.dto.parse.postman; + +import lombok.Data; + +@Data +public class PostmanKeyValue { + private String key; + private String value; + private String type; + + public PostmanKeyValue() { + } + + public PostmanKeyValue(String key, String value) { + this.key = key; + this.value = value; + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanRequest.java b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanRequest.java new file mode 100644 index 0000000000..59c0e97fa7 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanRequest.java @@ -0,0 +1,18 @@ +package io.metersphere.api.dto.parse.postman; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +import java.util.List; + +@Data +public class PostmanRequest { + + private String method; + private String schema; + private List header; + private JSONObject body; + private JSONObject auth; + private PostmanUrl url; + private String description; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanUrl.java b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanUrl.java new file mode 100644 index 0000000000..55481b4b12 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/postman/PostmanUrl.java @@ -0,0 +1,14 @@ +package io.metersphere.api.dto.parse.postman; + +import lombok.Data; + +import java.util.List; + +@Data +public class PostmanUrl { + + private String raw; + private String protocol; + private String port; + private List query; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerApi.java b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerApi.java new file mode 100644 index 0000000000..9eeeed860d --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerApi.java @@ -0,0 +1,17 @@ +package io.metersphere.api.dto.parse.swagger; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +import java.util.List; + +@Data +public class SwaggerApi { + private String swagger; + private SwaggerInfo info; + private String host; + private String basePath; + private List schemes; + private List tags; + private JSONObject paths; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerInfo.java b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerInfo.java new file mode 100644 index 0000000000..56d538f340 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerInfo.java @@ -0,0 +1,11 @@ +package io.metersphere.api.dto.parse.swagger; + +import lombok.Data; + +@Data +public class SwaggerInfo { + private String version; + private String title; + private String description; + private String termsOfService; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerParameter.java b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerParameter.java new file mode 100644 index 0000000000..63196e0211 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerParameter.java @@ -0,0 +1,13 @@ +package io.metersphere.api.dto.parse.swagger; + +import lombok.Data; + +@Data +public class SwaggerParameter { + private String name; + private String in; + private String description; + private Boolean required; + private String type; + private String format; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerRequest.java b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerRequest.java new file mode 100644 index 0000000000..d4e0e9e59a --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerRequest.java @@ -0,0 +1,16 @@ +package io.metersphere.api.dto.parse.swagger; + +import lombok.Data; + +import java.util.List; + +@Data +public class SwaggerRequest { + private List tags; + private String summary; + private String description; + private String operationId; + private List consumes; + private List produces; + private SwaggerParameter parameters; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerTag.java b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerTag.java new file mode 100644 index 0000000000..14e6ef9bd3 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/parse/swagger/SwaggerTag.java @@ -0,0 +1,9 @@ +package io.metersphere.api.dto.parse.swagger; + +import lombok.Data; + +@Data +public class SwaggerTag { + private String name; + private String description; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/scenario/KeyValue.java b/backend/src/main/java/io/metersphere/api/dto/scenario/KeyValue.java index 26d1450608..67c7311b5d 100644 --- a/backend/src/main/java/io/metersphere/api/dto/scenario/KeyValue.java +++ b/backend/src/main/java/io/metersphere/api/dto/scenario/KeyValue.java @@ -6,4 +6,12 @@ import lombok.Data; public class KeyValue { private String name; private String value; + + public KeyValue() { + } + + public KeyValue(String name, String value) { + this.name = name; + this.value = value; + } } diff --git a/backend/src/main/java/io/metersphere/api/dto/scenario/Request.java b/backend/src/main/java/io/metersphere/api/dto/scenario/Request.java index ce55174015..ccd1e0ec95 100644 --- a/backend/src/main/java/io/metersphere/api/dto/scenario/Request.java +++ b/backend/src/main/java/io/metersphere/api/dto/scenario/Request.java @@ -11,6 +11,8 @@ public class Request { private String name; private String url; private String method; + private Boolean useEnvironment; + private String path; private List parameters; private List headers; private Body body; diff --git a/backend/src/main/java/io/metersphere/api/dto/scenario/Scenario.java b/backend/src/main/java/io/metersphere/api/dto/scenario/Scenario.java index df60feb3b6..960702d351 100644 --- a/backend/src/main/java/io/metersphere/api/dto/scenario/Scenario.java +++ b/backend/src/main/java/io/metersphere/api/dto/scenario/Scenario.java @@ -8,6 +8,7 @@ import java.util.List; public class Scenario { private String name; private String url; + private String environmentId; private List variables; private List headers; private List requests; diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java new file mode 100644 index 0000000000..0e3ef0e4c1 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java @@ -0,0 +1,37 @@ +package io.metersphere.api.parse; + +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.LogUtil; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public abstract class ApiImportAbstractParser implements ApiImportParser { + + protected String getApiTestStr(InputStream source) { + BufferedReader bufferedReader = null; + StringBuilder testStr = null; + try { + bufferedReader = new BufferedReader(new InputStreamReader(source, "UTF-8")); + testStr = new StringBuilder(); + String inputStr = null; + while ((inputStr = bufferedReader.readLine()) != null) { + testStr.append(inputStr); + } + } catch (Exception e) { + MSException.throwException(e.getMessage()); + LogUtil.error(e.getMessage(), e); + } finally { + try { + source.close(); + } catch (IOException e) { + MSException.throwException(e.getMessage()); + LogUtil.error(e.getMessage(), e); + } + } + return testStr.toString(); + } + +} diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java new file mode 100644 index 0000000000..659e9ea6d2 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java @@ -0,0 +1,9 @@ +package io.metersphere.api.parse; + +import io.metersphere.api.dto.parse.ApiImport; + +import java.io.InputStream; + +public interface ApiImportParser { + ApiImport parse(InputStream source); +} diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportParserFactory.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportParserFactory.java new file mode 100644 index 0000000000..d2a25ba819 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportParserFactory.java @@ -0,0 +1,18 @@ +package io.metersphere.api.parse; + +import io.metersphere.commons.constants.ApiImportPlatform; +import io.metersphere.commons.constants.FileType; +import io.metersphere.performance.parse.EngineSourceParser; +import io.metersphere.performance.parse.xml.XmlEngineSourceParse; +import org.apache.commons.lang3.StringUtils; + +public class ApiImportParserFactory { + public static ApiImportParser getApiImportParser(String platform) { + if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) { + return new MsParser(); + } else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) { + return new PostmanParser(); + } + return null; + } +} diff --git a/backend/src/main/java/io/metersphere/api/parse/MsParser.java b/backend/src/main/java/io/metersphere/api/parse/MsParser.java new file mode 100644 index 0000000000..26af2afc63 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/MsParser.java @@ -0,0 +1,18 @@ +package io.metersphere.api.parse; + +import com.alibaba.fastjson.JSON; +import io.metersphere.api.dto.parse.ApiImport; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.LogUtil; + +import java.io.*; + +public class MsParser extends ApiImportAbstractParser { + + @Override + public ApiImport parse(InputStream source) { + String testStr = getApiTestStr(source); + return JSON.parseObject(testStr.toString(), ApiImport.class); + } + +} diff --git a/backend/src/main/java/io/metersphere/api/parse/PostmanParser.java b/backend/src/main/java/io/metersphere/api/parse/PostmanParser.java new file mode 100644 index 0000000000..6345093cd1 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/PostmanParser.java @@ -0,0 +1,95 @@ +package io.metersphere.api.parse; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import io.metersphere.api.dto.parse.ApiImport; +import io.metersphere.api.dto.parse.postman.*; +import io.metersphere.api.dto.scenario.Body; +import io.metersphere.api.dto.scenario.KeyValue; +import io.metersphere.api.dto.scenario.Request; +import io.metersphere.api.dto.scenario.Scenario; +import io.metersphere.commons.constants.MsRequestBodyType; +import io.metersphere.commons.constants.PostmanRequestBodyMode; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.LogUtil; +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class PostmanParser extends ApiImportAbstractParser { + + @Override + public ApiImport parse(InputStream source) { + String testStr = getApiTestStr(source); + PostmanCollection postmanCollection = JSON.parseObject(testStr.toString(), PostmanCollection.class); + PostmanCollectionInfo info = postmanCollection.getInfo(); + List requests = parseRequests(postmanCollection); + ApiImport apiImport = new ApiImport(); + List scenarios = new ArrayList<>(); + Scenario scenario = new Scenario(); + scenario.setRequests(requests); + scenario.setName(info.getName()); + scenarios.add(scenario); + apiImport.setScenarios(scenarios); + return apiImport; + } + + private List parseKeyValue(List postmanKeyValues) { + if (postmanKeyValues == null) { + return null; + } + List keyValues = new ArrayList<>(); + postmanKeyValues.forEach(item -> { + keyValues.add(new KeyValue(item.getKey(), item.getValue())); + }); + return keyValues; + } + + private List parseRequests(PostmanCollection postmanCollection) { + List item = postmanCollection.getItem(); + List requests = new ArrayList<>(); + for (PostmanItem requestItem : item) { + Request request = new Request(); + PostmanRequest requestDesc = requestItem.getRequest(); + PostmanUrl url = requestDesc.getUrl(); + request.setName(requestItem.getName()); + request.setUrl(url.getRaw()); + request.setUseEnvironment(false); + request.setMethod(requestDesc.getMethod()); + request.setHeaders(parseKeyValue(requestDesc.getHeader())); + request.setParameters(parseKeyValue(url.getQuery())); + Body body = new Body(); + JSONObject postmanBody = requestDesc.getBody(); + String bodyMode = postmanBody.getString("mode"); + if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) { + body.setRaw(postmanBody.getString(bodyMode)); + body.setType(MsRequestBodyType.RAW.value()); + String contentType = postmanBody.getJSONObject("options").getJSONObject("raw").getString("language"); + List headers = request.getHeaders(); + boolean hasContentType = false; + for (KeyValue header : headers) { + if (StringUtils.equalsIgnoreCase(header.getName(), "Content-Type")) { + hasContentType = true; + } + } + if (!hasContentType) { + headers.add(new KeyValue("Content-Type", contentType)); + } + } else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) { + List postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class); + body.setType(MsRequestBodyType.KV.value()); + body.setKvs(parseKeyValue(postmanKeyValues)); + } + request.setBody(body); + requests.add(request); + } + return requests; + } + +} diff --git a/backend/src/main/java/io/metersphere/api/parse/SwaggerParser.java b/backend/src/main/java/io/metersphere/api/parse/SwaggerParser.java new file mode 100644 index 0000000000..e3ff9db8f2 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/SwaggerParser.java @@ -0,0 +1,106 @@ +package io.metersphere.api.parse; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.metersphere.api.dto.parse.ApiImport; +import io.metersphere.api.dto.parse.postman.PostmanItem; +import io.metersphere.api.dto.parse.postman.PostmanRequest; +import io.metersphere.api.dto.parse.postman.PostmanUrl; +import io.metersphere.api.dto.parse.swagger.SwaggerApi; +import io.metersphere.api.dto.parse.swagger.SwaggerInfo; +import io.metersphere.api.dto.parse.swagger.SwaggerRequest; +import io.metersphere.api.dto.scenario.Request; +import io.metersphere.api.dto.scenario.Scenario; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class SwaggerParser extends ApiImportAbstractParser { + + @Override + public ApiImport parse(InputStream source) { + String testStr = getApiTestStr(source); + + SwaggerApi swaggerApi = JSON.parseObject(testStr.toString(), SwaggerApi.class); + + SwaggerInfo info = swaggerApi.getInfo(); + + String title = info.getTitle(); + + +// List requests = parseRequests(swaggerApi); +// ApiImport apiImport = new ApiImport(); +// List scenarios = new ArrayList<>(); +// Scenario scenario = new Scenario(); +// scenario.setRequests(requests); +// scenario.setName(info.getName()); +// scenarios.add(scenario); +// apiImport.setScenarios(scenarios); +// return apiImport; + return null; + } + +// private List parseRequests(SwaggerApi swaggerApi) { +// JSONObject paths = swaggerApi.getPaths(); +// +// Set pathNames = paths.keySet(); +// +// for (String path : pathNames) { +// JSONObject pathObject = paths.getJSONObject(path); +// Set methods = pathObject.keySet(); +// for (String method : methods) { +// SwaggerRequest swaggerRequest = JSON.parseObject(pathObject.getJSONObject(method).toJSONString(), SwaggerRequest.class); +// Request request = new Request(); +// request.setName(swaggerRequest.getOperationId()); +// request.setUrl(url.getRaw()); +// request.setPath(.getRaw()); +// request.setUseEnvironment(false); +// request.setMethod(requestDesc.getMethod()); +// request.setHeaders(parseKeyValue(requestDesc.getHeader())); +// request.setParameters(parseKeyValue(url.getQuery())); +// +// } +// } +// +// List item = postmanCollection.getItem(); +// List requests = new ArrayList<>(); +// for (PostmanItem requestItem : item) { +// Request request = new Request(); +// PostmanRequest requestDesc = requestItem.getRequest(); +// PostmanUrl url = requestDesc.getUrl(); +// request.setName(requestItem.getName()); +// request.setUrl(url.getRaw()); +// request.setUseEnvironment(false); +// request.setMethod(requestDesc.getMethod()); +// request.setHeaders(parseKeyValue(requestDesc.getHeader())); +// request.setParameters(parseKeyValue(url.getQuery())); +// Body body = new Body(); +// JSONObject postmanBody = requestDesc.getBody(); +// String bodyMode = postmanBody.getString("mode"); +// if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) { +// body.setRaw(postmanBody.getString(bodyMode)); +// body.setType(MsRequestBodyType.RAW.value()); +// String contentType = postmanBody.getJSONObject("options").getJSONObject("raw").getString("language"); +// List headers = request.getHeaders(); +// boolean hasContentType = false; +// for (KeyValue header : headers) { +// if (StringUtils.equalsIgnoreCase(header.getName(), "Content-Type")) { +// hasContentType = true; +// } +// } +// if (!hasContentType) { +// headers.add(new KeyValue("Content-Type", contentType)); +// } +// } else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) { +// List postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class); +// body.setType(MsRequestBodyType.KV.value()); +// body.setKvs(parseKeyValue(postmanKeyValues)); +// } +// request.setBody(body); +// requests.add(request); +// } +// return requests; +// } +} diff --git a/backend/src/main/java/io/metersphere/api/service/APITestService.java b/backend/src/main/java/io/metersphere/api/service/APITestService.java index fa81f73172..33b9af99cd 100644 --- a/backend/src/main/java/io/metersphere/api/service/APITestService.java +++ b/backend/src/main/java/io/metersphere/api/service/APITestService.java @@ -2,18 +2,25 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.APITestResult; +import io.metersphere.api.dto.parse.ApiImport; import io.metersphere.api.dto.QueryAPITestRequest; import io.metersphere.api.dto.SaveAPITestRequest; import io.metersphere.api.jmeter.JMeterService; +import io.metersphere.api.parse.ApiImportParser; +import io.metersphere.api.parse.ApiImportParserFactory; +import io.metersphere.api.parse.MsParser; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.ApiTestFileMapper; import io.metersphere.base.mapper.ApiTestMapper; +import io.metersphere.base.mapper.TestCaseMapper; import io.metersphere.base.mapper.ext.ExtApiTestMapper; import io.metersphere.commons.constants.APITestStatus; +import io.metersphere.commons.constants.FileType; import io.metersphere.commons.constants.ScheduleGroup; import io.metersphere.commons.constants.ScheduleType; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.BeanUtils; +import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.i18n.Translator; @@ -26,8 +33,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.io.ByteArrayInputStream; -import java.io.InputStream; +import java.io.*; import java.util.List; import java.util.Objects; import java.util.Random; @@ -52,6 +58,8 @@ public class APITestService { private APIReportService apiReportService; @Resource private ScheduleService scheduleService; + @Resource + private TestCaseMapper testCaseMapper; public List list(QueryAPITestRequest request) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); @@ -124,6 +132,20 @@ public class APITestService { } public void delete(String testId) { + + // 是否关联测试用例 + TestCaseExample testCaseExample = new TestCaseExample(); + testCaseExample.createCriteria().andTestIdEqualTo(testId); + List testCases = testCaseMapper.selectByExample(testCaseExample); + if (testCases.size() > 0) { + String caseName = ""; + for (int i = 0; i < testCases.size(); i++) { + caseName = caseName + testCases.get(i).getName() + ","; + } + caseName = caseName.substring(0, caseName.length() - 1); + MSException.throwException(Translator.get("related_case_del_fail_prefix") + caseName + Translator.get("related_case_del_fail_suffix")); + } + deleteFileByTestId(testId); apiReportService.deleteByTestId(testId); apiTestMapper.deleteByPrimaryKey(testId); @@ -163,6 +185,15 @@ public class APITestService { } } + private Boolean isNameExist(SaveAPITestRequest request) { + ApiTestExample example = new ApiTestExample(); + example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId()); + if (apiTestMapper.countByExample(example) > 0) { + return true; + } + return false; + } + private ApiTest updateTest(SaveAPITestRequest request) { checkNameExist(request); final ApiTest test = new ApiTest(); @@ -246,4 +277,37 @@ public class APITestService { private void addOrUpdateApiTestCronJob(Schedule request) { scheduleService.addOrUpdateCronJob(request, ApiTestJob.getJobKey(request.getResourceId()), ApiTestJob.getTriggerKey(request.getResourceId()), ApiTestJob.class); } + + public ApiTest apiTestImport(MultipartFile file, String platform) { + ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(platform); + ApiImport apiImport = null; + try { + apiImport = apiImportParser.parse(file.getInputStream()); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException(Translator.get("parse_data_error")); + } + SaveAPITestRequest request = getImportApiTest(file, apiImport); + return createTest(request); + } + + private SaveAPITestRequest getImportApiTest(MultipartFile file, ApiImport apiImport) { + SaveAPITestRequest request = new SaveAPITestRequest(); + request.setName(file.getOriginalFilename()); + request.setProjectId(""); + request.setScenarioDefinition(apiImport.getScenarios()); + request.setUserId(SessionUtils.getUser().getId()); + request.setId(UUID.randomUUID().toString()); + for (FileType fileType : FileType.values()) { + String suffix = fileType.suffix(); + String name = request.getName(); + if (name.endsWith(suffix)) { + request.setName(name.substring(0, name.length() - suffix.length())); + } + }; + if (isNameExist(request)) { + request.setName(request.getName() + "_" + request.getId().substring(0, 5)); + } + return request; + } } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java index 07c72adb23..e2e485ae2a 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestEnvironmentService.java @@ -3,6 +3,8 @@ package io.metersphere.api.service; import io.metersphere.base.domain.ApiTestEnvironmentExample; import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; import io.metersphere.base.mapper.ApiTestEnvironmentMapper; +import io.metersphere.commons.exception.MSException; +import io.metersphere.i18n.Translator; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,7 +39,20 @@ public class ApiTestEnvironmentService { public String add(ApiTestEnvironmentWithBLOBs apiTestEnvironmentWithBLOBs) { apiTestEnvironmentWithBLOBs.setId(UUID.randomUUID().toString()); + checkEnvironmentExist(apiTestEnvironmentWithBLOBs); apiTestEnvironmentMapper.insert(apiTestEnvironmentWithBLOBs); return apiTestEnvironmentWithBLOBs.getId(); } + + private void checkEnvironmentExist (ApiTestEnvironmentWithBLOBs environment) { + if (environment.getName() != null) { + ApiTestEnvironmentExample example = new ApiTestEnvironmentExample(); + example.createCriteria() + .andNameEqualTo(environment.getName()) + .andProjectIdEqualTo(environment.getProjectId()); + if (apiTestEnvironmentMapper.selectByExample(example).size() > 0) { + MSException.throwException(Translator.get("api_test_environment_already_exists")); + } + } + } } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml index 6c04346e56..8f5cf65ed5 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml @@ -3,9 +3,12 @@