From bc3731b8cbc2a4fd72f0b54b67de72b34aafa1a0 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Mon, 22 Feb 2021 12:09:29 +0800 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/dto/ApiTestImportRequest.java | 1 + .../parse/ApiScenarioImportUtil.java | 50 +++++ .../dto/automation/parse/MsJmeterParser.java | 7 +- .../dto/automation/parse/MsPostmanParser.java | 205 ------------------ .../automation/parse/MsScenarioParser.java | 49 +++-- .../parse/PostmanScenarioParser.java | 82 +++++++ .../dto/automation/parse/ScenarioImport.java | 2 +- .../parse/ScenarioImportAbstractParser.java | 169 --------------- .../parse/ScenarioImportParser.java | 9 - .../parse/ScenarioImportParserFactory.java | 5 +- .../definition/parse/ApiDefinitionImport.java | 4 - .../ApiDefinitionImportParserFactory.java} | 9 +- .../parse/ApiDefinitionImportUtil.java | 52 +++++ .../definition/parse/MsDefinitionParser.java | 99 +++++++++ .../parse/PostmanDefinitionParser.java | 58 +++++ .../definition}/parse/Swagger2Parser.java | 5 +- .../definition}/parse/Swagger3Parser.java | 5 +- .../parse/SwaggerAbstractParser.java | 7 +- .../api/parse/ApiImportAbstractParser.java | 69 +++--- .../api/parse/ApiImportParser.java | 5 +- .../api/parse/MsAbstractParser.java | 99 +++++++++ .../io/metersphere/api/parse/MsParser.java | 192 ---------------- ....java => PostmanAbstractParserParser.java} | 71 ++---- .../api/parse/ScenarioMsParser.java | 71 ------ .../api/service/ApiAutomationService.java | 8 +- .../api/service/ApiDefinitionService.java | 9 +- 26 files changed, 553 insertions(+), 789 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java delete mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/parse/MsPostmanParser.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java delete mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportAbstractParser.java delete mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParser.java rename backend/src/main/java/io/metersphere/api/{parse/ApiImportParserFactory.java => dto/definition/parse/ApiDefinitionImportParserFactory.java} (67%) create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportUtil.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java rename backend/src/main/java/io/metersphere/api/{ => dto/definition}/parse/Swagger2Parser.java (98%) rename backend/src/main/java/io/metersphere/api/{ => dto/definition}/parse/Swagger3Parser.java (98%) rename backend/src/main/java/io/metersphere/api/{ => dto/definition}/parse/SwaggerAbstractParser.java (65%) create mode 100644 backend/src/main/java/io/metersphere/api/parse/MsAbstractParser.java delete mode 100644 backend/src/main/java/io/metersphere/api/parse/MsParser.java rename backend/src/main/java/io/metersphere/api/parse/{PostmanParser.java => PostmanAbstractParserParser.java} (65%) delete mode 100644 backend/src/main/java/io/metersphere/api/parse/ScenarioMsParser.java diff --git a/backend/src/main/java/io/metersphere/api/dto/ApiTestImportRequest.java b/backend/src/main/java/io/metersphere/api/dto/ApiTestImportRequest.java index e76fa7403e..3764e9d0c7 100644 --- a/backend/src/main/java/io/metersphere/api/dto/ApiTestImportRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/ApiTestImportRequest.java @@ -14,6 +14,7 @@ public class ApiTestImportRequest { private String platform; private Boolean useEnvironment; private String swaggerUrl; + private String fileName; //导入策略 private String modeId; private String userId; diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java new file mode 100644 index 0000000000..39e4d8fee8 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ApiScenarioImportUtil.java @@ -0,0 +1,50 @@ +package io.metersphere.api.dto.automation.parse; + +import io.metersphere.api.dto.automation.ApiScenarioModuleDTO; +import io.metersphere.api.service.ApiScenarioModuleService; +import io.metersphere.base.domain.ApiScenarioModule; +import io.metersphere.commons.utils.BeanUtils; +import io.metersphere.commons.utils.CommonBeanFactory; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +public class ApiScenarioImportUtil { + + public static ApiScenarioModule getSelectModule(String moduleId) { + ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class); + if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) { + ApiScenarioModule module = new ApiScenarioModule(); + ApiScenarioModuleDTO moduleDTO = apiModuleService.getNode(moduleId); + if (moduleDTO != null) { + BeanUtils.copyBean(module, moduleDTO); + } + return module; + } + return null; + } + + public static ApiScenarioModule buildModule(ApiScenarioModule parentModule, String name, String projectId) { + ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class); + ApiScenarioModule module; + if (parentModule != null) { + module = apiModuleService.getNewModule(name, projectId, parentModule.getLevel() + 1); + module.setParentId(parentModule.getId()); + } else { + module = apiModuleService.getNewModule(name, projectId, 1); + } + createModule(module); + return module; + } + + public static void createModule(ApiScenarioModule module) { + ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class); + List apiModules = apiModuleService.selectSameModule(module); + if (CollectionUtils.isEmpty(apiModules)) { + apiModuleService.addNode(module); + } else { + module.setId(apiModules.get(0).getId()); + } + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java index 067a2478d2..2659108e3f 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsJmeterParser.java @@ -37,6 +37,7 @@ import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.dto.scenario.request.BodyFile; import io.metersphere.api.dto.scenario.request.RequestType; +import io.metersphere.api.parse.ApiImportAbstractParser; import io.metersphere.api.service.ApiTestEnvironmentService; import io.metersphere.base.domain.ApiScenarioModule; import io.metersphere.base.domain.ApiScenarioWithBLOBs; @@ -76,7 +77,7 @@ import java.io.InputStream; import java.lang.reflect.Field; import java.util.*; -public class MsJmeterParser extends ScenarioImportAbstractParser { +public class MsJmeterParser extends ApiImportAbstractParser { private final String ENV_NAME = "导入数据环境"; @Override @@ -93,7 +94,7 @@ public class MsJmeterParser extends ScenarioImportAbstractParser { this.projectId = request.getProjectId(); ScenarioImport scenarioImport = new ScenarioImport(); scenarioImport.setData(paseObj(scenario, request)); - scenarioImport.setProjectid(request.getProjectId()); + scenarioImport.setProjectId(request.getProjectId()); return scenarioImport; } catch (Exception e) { e.printStackTrace(); @@ -105,7 +106,7 @@ public class MsJmeterParser extends ScenarioImportAbstractParser { private List paseObj(MsScenario msScenario, ApiTestImportRequest request) { List scenarioWithBLOBsList = new ArrayList<>(); ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs(); - ApiScenarioModule module = buildModule(getSelectModule(request.getModuleId()), msScenario.getName()); + ApiScenarioModule module = ApiScenarioImportUtil.buildModule(ApiScenarioImportUtil.getSelectModule(request.getModuleId()), msScenario.getName(), this.projectId); scenarioWithBLOBs.setName(msScenario.getName()); scenarioWithBLOBs.setProjectId(request.getProjectId()); if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) { diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsPostmanParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsPostmanParser.java deleted file mode 100644 index f88bfc339d..0000000000 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsPostmanParser.java +++ /dev/null @@ -1,205 +0,0 @@ -package io.metersphere.api.dto.automation.parse; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; -import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; -import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; -import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; -import io.metersphere.api.dto.parse.postman.*; -import io.metersphere.api.dto.scenario.Body; -import io.metersphere.api.dto.scenario.KeyValue; -import io.metersphere.base.domain.ApiScenarioModule; -import io.metersphere.base.domain.ApiScenarioWithBLOBs; -import io.metersphere.commons.constants.MsRequestBodyType; -import io.metersphere.commons.constants.PostmanRequestBodyMode; -import io.metersphere.commons.constants.VariableTypeConstants; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; - -public class MsPostmanParser extends ScenarioImportAbstractParser { - - @Override - public ScenarioImport parse(InputStream source, ApiTestImportRequest request) { - String testStr = getApiTestStr(source); - PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class); - List variables = postmanCollection.getVariable(); - ScenarioImport scenarioImport = new ScenarioImport(); - // 场景步骤 - LinkedList apiScenarioWithBLOBs = new LinkedList<>(); - PostmanCollectionInfo info = postmanCollection.getInfo(); - ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs(); - scenario.setName(info.getName()); - - MsScenario msScenario = new MsScenario(); - msScenario.setName(info.getName()); - this.projectId = request.getProjectId(); - parseItem(postmanCollection.getItem(), variables, msScenario, apiScenarioWithBLOBs); - // 生成场景对象 - List scenarioWithBLOBs = new LinkedList<>(); - paseScenario(scenarioWithBLOBs, msScenario, request); - scenarioImport.setData(scenarioWithBLOBs); - return scenarioImport; - } - - private void paseScenario(List scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) { - ApiScenarioModule module = buildModule(getSelectModule(request.getModuleId()), msScenario.getName()); - ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs(); - scenarioWithBLOBs.setName(msScenario.getName()); - scenarioWithBLOBs.setProjectId(request.getProjectId()); - if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) { - scenarioWithBLOBs.setStepTotal(msScenario.getHashTree().size()); - } - if (module != null) { - scenarioWithBLOBs.setApiScenarioModuleId(module.getId()); - scenarioWithBLOBs.setModulePath("/" + module.getName()); - } - scenarioWithBLOBs.setId(UUID.randomUUID().toString()); - scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(msScenario)); - scenarioWithBLOBsList.add(scenarioWithBLOBs); - } - - private void parseItem(List items, List variables, MsScenario scenario, LinkedList results) { - for (PostmanItem item : items) { - List childItems = item.getItem(); - if (childItems != null) { - parseItem(childItems, variables, scenario, results); - } else { - MsHTTPSamplerProxy request = parsePostman(item); - if (request != null) { - results.add(request); - } - } - } - scenario.setVariables(parseScenarioVariable(variables)); - scenario.setHashTree(results); - } - - private MsHTTPSamplerProxy parsePostman(PostmanItem requestItem) { - PostmanRequest requestDesc = requestItem.getRequest(); - if (requestDesc == null) { - return null; - } - requestDesc.getAuth(); // todo 认证方式等待优化 - PostmanUrl url = requestDesc.getUrl(); - MsHTTPSamplerProxy request = buildRequest(requestItem.getName(), url.getRaw(), requestDesc.getMethod()); - if (StringUtils.isNotBlank(request.getPath())) { - String path = request.getPath().split("\\?")[0]; - path = path.replace("{{", "${"); - path = path.replace("}}", "}"); - request.setPath(path); - } else { - request.setPath("/"); - } - parseBody(request.getBody(), requestDesc); - request.setArguments(parseKeyValue(url.getQuery())); - request.setHeaders(parseKeyValue(requestDesc.getHeader())); - addBodyHeader(request); - addPreScript(request, requestItem.getEvent()); - return request; - } - - private void addPreScript(MsHTTPSamplerProxy request, List event) { - if (request != null && CollectionUtils.isNotEmpty(event)) { - StringBuilder scriptStr = new StringBuilder(); - event = event.stream() - .filter(item -> item.getScript() != null) - .collect(Collectors.toList()); - event.forEach(item -> { - PostmanScript script = item.getScript(); - if (script != null) { - List exec = script.getExec(); - if (CollectionUtils.isNotEmpty(exec)) { - exec.forEach(col -> { - if (StringUtils.isNotEmpty(col)) { - scriptStr.append(col + "/n"); - } - }); - } - } - }); - if (StringUtils.isNotBlank(scriptStr)) { - MsJSR223PreProcessor jsr223PreProcessor = new MsJSR223PreProcessor(); - jsr223PreProcessor.setName("JSR223PreProcessor"); - jsr223PreProcessor.setScriptLanguage("javascript"); - jsr223PreProcessor.setScript(scriptStr.toString()); - LinkedList hashTree = new LinkedList<>(); - hashTree.add(jsr223PreProcessor); - request.setHashTree(hashTree); - } - } - } - - 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(), item.getDescription(), item.getContentType()))); - return keyValues; - } - - private List parseScenarioVariable(List postmanKeyValues) { - if (postmanKeyValues == null) { - return null; - } - List keyValues = new ArrayList<>(); - postmanKeyValues.forEach(item -> keyValues.add(new ScenarioVariable(item.getKey(), item.getValue(), item.getDescription(), VariableTypeConstants.CONSTANT.name()))); - return keyValues; - } - - private void parseBody(Body body, PostmanRequest requestDesc) { - JSONObject postmanBody = requestDesc.getBody(); - if (postmanBody == null) { - return; - } - String bodyMode = postmanBody.getString("mode"); - if (StringUtils.isNotEmpty(bodyMode) && StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) { - parseRawBody(body, postmanBody, bodyMode); - } else if (StringUtils.isNotEmpty(bodyMode) && StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) { - List postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class); - body.setKvs(parseKeyValue(postmanKeyValues)); - if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value())) { - body.setType(Body.FORM_DATA); - } else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) { - body.setType(Body.WWW_FROM); - } - } else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FILE.value())) { - body.setType(Body.BINARY); - body.setKvs(new ArrayList<>()); - } - } - - private void parseRawBody(Body body, JSONObject postmanBody, String bodyMode) { - body.setRaw(postmanBody.getString(bodyMode)); - body.setType(MsRequestBodyType.RAW.value()); - JSONObject options = postmanBody.getJSONObject("options"); - if (options != null) { - JSONObject raw = options.getJSONObject(PostmanRequestBodyMode.RAW.value()); - if (raw != null && raw.getString("language") != null) { - String bodyType = ""; - switch (raw.getString("language")) { - case "json": - bodyType = Body.JSON; - break; - case "xml": - bodyType = Body.XML; - break; - default: - bodyType = Body.RAW; - } - body.setType(bodyType); - } - } - } - -} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java index b3b5104971..2bfbc8e7e4 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/MsScenarioParser.java @@ -1,26 +1,49 @@ package io.metersphere.api.dto.automation.parse; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; import io.metersphere.api.dto.ApiTestImportRequest; +import io.metersphere.api.dto.definition.request.MsScenario; +import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.parse.MsAbstractParser; import io.metersphere.base.domain.ApiScenarioModule; import io.metersphere.base.domain.ApiScenarioWithBLOBs; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import java.io.InputStream; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; +import java.util.*; -public class MsScenarioParser extends ScenarioImportAbstractParser { +public class MsScenarioParser extends MsAbstractParser { @Override public ScenarioImport parse(InputStream source, ApiTestImportRequest request) { String testStr = getApiTestStr(source); this.projectId = request.getProjectId(); - ScenarioImport scenarioImport = parseMsFormat(testStr, request); - return scenarioImport; + JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField); + if (testObject.get("projectName") != null || testObject.get("projectId") != null ) { + return parseMsFormat(testStr, request); + } else { + ScenarioImport apiImport = new ScenarioImport(); + ArrayList apiScenarioWithBLOBs = new ArrayList<>(); + apiScenarioWithBLOBs.add(parsePluginFormat(testObject, request)); + apiImport.setData(apiScenarioWithBLOBs); + return apiImport; + } + } + + protected ApiScenarioWithBLOBs parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest) { + LinkedList results = new LinkedList<>(); + testObject.keySet().forEach(tag -> { + results.addAll(parseMsHTTPSamplerProxy(testObject, tag)); + }); + MsScenario msScenario = new MsScenario(); + msScenario.setName(importRequest.getFileName()); + msScenario.setHashTree(results); + ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario); + scenarioWithBLOBs.setApiScenarioModuleId(importRequest.getModuleId()); + return scenarioWithBLOBs; } private ScenarioImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) { @@ -31,7 +54,7 @@ public class MsScenarioParser extends ScenarioImportAbstractParser { if (StringUtils.isBlank(item.getModulePath())) { item.setApiScenarioModuleId(null); } - parseModule(item, importRequest); + parseModule(item.getModulePath(), importRequest, item); item.setId(UUID.randomUUID().toString()); item.setProjectId(this.projectId); }); @@ -39,8 +62,7 @@ public class MsScenarioParser extends ScenarioImportAbstractParser { return apiDefinitionImport; } - private void parseModule(ApiScenarioWithBLOBs apiDefinition, ApiTestImportRequest importRequest) { - String modulePath = apiDefinition.getModulePath(); + protected void parseModule(String modulePath, ApiTestImportRequest importRequest, ApiScenarioWithBLOBs apiScenarioWithBLOBs) { if (StringUtils.isEmpty(modulePath)) { return; } @@ -51,15 +73,14 @@ public class MsScenarioParser extends ScenarioImportAbstractParser { modulePath = modulePath.substring(0, modulePath.length() - 1); } List modules = Arrays.asList(modulePath.split("/")); - ApiScenarioModule parent = getSelectModule(importRequest.getModuleId()); + ApiScenarioModule parent = ApiScenarioImportUtil.getSelectModule(importRequest.getModuleId()); Iterator iterator = modules.iterator(); while (iterator.hasNext()) { String item = iterator.next(); - parent = buildModule(parent, item); + parent = ApiScenarioImportUtil.buildModule(parent, item, this.projectId); if (!iterator.hasNext()) { - apiDefinition.setApiScenarioModuleId(parent.getId()); + apiScenarioWithBLOBs.setApiScenarioModuleId(parent.getId()); } } } - } diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java new file mode 100644 index 0000000000..201feeed86 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/PostmanScenarioParser.java @@ -0,0 +1,82 @@ +package io.metersphere.api.dto.automation.parse; + +import com.alibaba.fastjson.JSON; +import io.metersphere.api.dto.ApiTestImportRequest; +import io.metersphere.api.dto.definition.request.MsScenario; +import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; +import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; +import io.metersphere.api.dto.parse.postman.PostmanCollection; +import io.metersphere.api.dto.parse.postman.PostmanCollectionInfo; +import io.metersphere.api.dto.parse.postman.PostmanItem; +import io.metersphere.api.dto.parse.postman.PostmanKeyValue; +import io.metersphere.api.parse.PostmanAbstractParserParser; +import io.metersphere.base.domain.ApiScenarioModule; +import io.metersphere.base.domain.ApiScenarioWithBLOBs; +import io.metersphere.commons.constants.VariableTypeConstants; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public class PostmanScenarioParser extends PostmanAbstractParserParser { + + @Override + public ScenarioImport parse(InputStream source, ApiTestImportRequest request) { + String testStr = getApiTestStr(source); + PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class); + List variables = postmanCollection.getVariable(); + ScenarioImport scenarioImport = new ScenarioImport(); + // 场景步骤 + LinkedList apiScenarioWithBLOBs = new LinkedList<>(); + PostmanCollectionInfo info = postmanCollection.getInfo(); + ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs(); + scenario.setName(info.getName()); + + MsScenario msScenario = new MsScenario(); + msScenario.setName(info.getName()); + this.projectId = request.getProjectId(); + parseItem(postmanCollection.getItem(), variables, msScenario, apiScenarioWithBLOBs); + // 生成场景对象 + List scenarioWithBLOBs = new LinkedList<>(); + parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario, request); + scenarioImport.setData(scenarioWithBLOBs); + return scenarioImport; + } + + private void parseScenarioWithBLOBs(List scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) { + ApiScenarioModule module = ApiScenarioImportUtil.buildModule(ApiScenarioImportUtil.getSelectModule(request.getModuleId()), msScenario.getName(), this.projectId); + ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario); + if (module != null) { + scenarioWithBLOBs.setApiScenarioModuleId(module.getId()); + scenarioWithBLOBs.setModulePath("/" + module.getName()); + } + scenarioWithBLOBsList.add(scenarioWithBLOBs); + } + + private void parseItem(List items, List variables, MsScenario scenario, LinkedList results) { + for (PostmanItem item : items) { + List childItems = item.getItem(); + if (childItems != null) { + parseItem(childItems, variables, scenario, results); + } else { + MsHTTPSamplerProxy request = parsePostman(item); + if (request != null) { + results.add(request); + } + } + } + scenario.setVariables(parseScenarioVariable(variables)); + scenario.setHashTree(results); + } + + private List parseScenarioVariable(List postmanKeyValues) { + if (postmanKeyValues == null) { + return null; + } + List keyValues = new ArrayList<>(); + postmanKeyValues.forEach(item -> keyValues.add(new ScenarioVariable(item.getKey(), item.getValue(), item.getDescription(), VariableTypeConstants.CONSTANT.name()))); + return keyValues; + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImport.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImport.java index 81b6c08139..22ba1d268b 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImport.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImport.java @@ -7,6 +7,6 @@ import java.util.List; @Data public class ScenarioImport { - private String projectid; + private String projectId; private List data; } diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportAbstractParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportAbstractParser.java deleted file mode 100644 index 3ba5bc40ac..0000000000 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportAbstractParser.java +++ /dev/null @@ -1,169 +0,0 @@ -package io.metersphere.api.dto.automation.parse; - -import io.metersphere.api.dto.automation.ApiScenarioModuleDTO; -import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; -import io.metersphere.api.dto.scenario.Body; -import io.metersphere.api.dto.scenario.KeyValue; -import io.metersphere.api.dto.scenario.request.RequestType; -import io.metersphere.api.service.ApiScenarioModuleService; -import io.metersphere.base.domain.ApiScenarioModule; -import io.metersphere.commons.exception.MSException; -import io.metersphere.commons.utils.BeanUtils; -import io.metersphere.commons.utils.CommonBeanFactory; -import io.metersphere.commons.utils.LogUtil; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public abstract class ScenarioImportAbstractParser implements ScenarioImportParser { - protected ApiScenarioModuleService apiModuleService; - protected String projectId; - - protected ApiScenarioModule getSelectModule(String moduleId) { - apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class); - if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) { - ApiScenarioModule module = new ApiScenarioModule(); - ApiScenarioModuleDTO moduleDTO = apiModuleService.getNode(moduleId); - if (moduleDTO != null) { - BeanUtils.copyBean(module, moduleDTO); - } - return module; - } - return null; - } - - protected ApiScenarioModule buildModule(ApiScenarioModule parentModule, String name) { - apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class); - ApiScenarioModule module; - if (parentModule != null) { - module = apiModuleService.getNewModule(name, this.projectId, parentModule.getLevel() + 1); - module.setParentId(parentModule.getId()); - } else { - module = apiModuleService.getNewModule(name, this.projectId, 1); - } - createModule(module); - return module; - } - - protected void createModule(ApiScenarioModule module) { - List apiModules = apiModuleService.selectSameModule(module); - if (CollectionUtils.isEmpty(apiModules)) { - apiModuleService.addNode(module); - } else { - module.setId(apiModules.get(0).getId()); - } - } - - protected String getApiTestStr(InputStream source) { - StringBuilder testStr = null; - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) { - testStr = new StringBuilder(); - String inputStr; - while ((inputStr = bufferedReader.readLine()) != null) { - testStr.append(inputStr); - } - } catch (Exception e) { - MSException.throwException(e.getMessage()); - LogUtil.error(e.getMessage(), e); - } finally { - try { - if (source != null) { - source.close(); - } - } catch (IOException e) { - MSException.throwException(e.getMessage()); - LogUtil.error(e.getMessage(), e); - } - } - return testStr.toString(); - } - - private String formatPath(String url) { - try { - URL urlObject = new URL(url); - StringBuilder pathBuffer = new StringBuilder(urlObject.getPath()); - if (StringUtils.isNotEmpty(urlObject.getQuery())) { - pathBuffer.append("?").append(urlObject.getQuery()); - } - return pathBuffer.toString(); - } catch (Exception ex) { - return url; - } - } - - protected MsHTTPSamplerProxy buildRequest(String name, String path, String method) { - MsHTTPSamplerProxy request = new MsHTTPSamplerProxy(); - request.setName(name); - // 路径去掉域名/IP 地址,保留方法名称及参数 - request.setPath(formatPath(path)); - request.setMethod(method); - request.setProtocol(RequestType.HTTP); - request.setId(UUID.randomUUID().toString()); - request.setHeaders(new ArrayList<>()); - request.setArguments(new ArrayList<>()); - request.setRest(new ArrayList<>()); - request.setAuthManager(null); - Body body = new Body(); - body.initKvs(); - body.initBinary(); - request.setBody(body); - return request; - } - - protected void addHeader(List headers, String key, String value, String description, String contentType, boolean required) { - boolean hasContentType = false; - for (KeyValue header : headers) { - if (StringUtils.equalsIgnoreCase(header.getName(), key)) { - hasContentType = true; - } - } - if (!hasContentType) { - headers.add(new KeyValue(key, value, description, contentType, required)); - } - } - - protected void addHeader(List headers, String key, String value) { - addHeader(headers, key, value, "", "", true); - } - - protected void addContentType(List headers, String contentType) { - addHeader(headers, "Content-Type", contentType); - } - - protected void addBodyHeader(MsHTTPSamplerProxy request) { - String contentType = ""; - if (request.getBody() != null && StringUtils.isNotBlank(request.getBody().getType())) { - switch (request.getBody().getType()) { - case Body.JSON: - contentType = "application/json"; - break; - case Body.WWW_FROM: - contentType = "application/x-www-form-urlencoded"; - break; - case Body.XML: - contentType = "application/xml"; - break; - case Body.BINARY: - contentType = "application/octet-stream"; - break; - } - List headers = request.getHeaders(); - if (headers == null) { - headers = new ArrayList<>(); - request.setHeaders(headers); - } - addContentType(request.getHeaders(), contentType); - - } - } - -} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParser.java deleted file mode 100644 index 4586440473..0000000000 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParser.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.metersphere.api.dto.automation.parse; - -import io.metersphere.api.dto.ApiTestImportRequest; - -import java.io.InputStream; - -public interface ScenarioImportParser { - ScenarioImport parse(InputStream source, ApiTestImportRequest request); -} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParserFactory.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParserFactory.java index fc251b0ddc..b2509a9eed 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParserFactory.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/ScenarioImportParserFactory.java @@ -1,14 +1,15 @@ package io.metersphere.api.dto.automation.parse; +import io.metersphere.api.parse.ApiImportParser; import io.metersphere.commons.constants.ApiImportPlatform; import org.apache.commons.lang3.StringUtils; public class ScenarioImportParserFactory { - public static ScenarioImportParser getImportParser(String platform) { + public static ApiImportParser getImportParser(String platform) { if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) { return new MsScenarioParser(); } else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) { - return new MsPostmanParser(); + return new PostmanScenarioParser(); } else if (StringUtils.equals(ApiImportPlatform.Jmeter.name(), platform)) { return new MsJmeterParser(); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java index a92d0d1bf8..c58d775624 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImport.java @@ -14,10 +14,6 @@ public class ApiDefinitionImport { private String protocol; private List data; - //导入场景 - private MsScenario scenarioDefinition; - private List scenarioDefinitionData; - // 新版本带用例导出 private List cases; } diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportParserFactory.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java similarity index 67% rename from backend/src/main/java/io/metersphere/api/parse/ApiImportParserFactory.java rename to backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java index ee41450068..3b73d92f0c 100644 --- a/backend/src/main/java/io/metersphere/api/parse/ApiImportParserFactory.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java @@ -1,14 +1,15 @@ -package io.metersphere.api.parse; +package io.metersphere.api.dto.definition.parse; +import io.metersphere.api.parse.ApiImportParser; import io.metersphere.commons.constants.ApiImportPlatform; import org.apache.commons.lang3.StringUtils; -public class ApiImportParserFactory { +public class ApiDefinitionImportParserFactory { public static ApiImportParser getApiImportParser(String platform) { if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) { - return new MsParser(); + return new MsDefinitionParser(); } else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) { - return new PostmanParser(); + return new PostmanDefinitionParser(); } else if (StringUtils.equals(ApiImportPlatform.Swagger2.name(), platform)) { return new Swagger2Parser(); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportUtil.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportUtil.java new file mode 100644 index 0000000000..78df96ac1e --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportUtil.java @@ -0,0 +1,52 @@ +package io.metersphere.api.dto.definition.parse; + +import io.metersphere.api.dto.definition.ApiModuleDTO; +import io.metersphere.api.dto.scenario.request.RequestType; +import io.metersphere.api.service.ApiModuleService; +import io.metersphere.base.domain.ApiModule; +import io.metersphere.commons.utils.BeanUtils; +import io.metersphere.commons.utils.CommonBeanFactory; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +public class ApiDefinitionImportUtil { + + public static ApiModule getSelectModule(String moduleId) { + ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); + if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) { + ApiModule module = new ApiModule(); + ApiModuleDTO moduleDTO = apiModuleService.getNode(moduleId); + if (moduleDTO != null) { + BeanUtils.copyBean(module, moduleDTO); + } + return module; + } + return null; + } + + public static ApiModule buildModule(ApiModule parentModule, String name, String projectId) { + ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); + ApiModule module; + if (parentModule != null) { + module = apiModuleService.getNewModule(name, projectId, parentModule.getLevel() + 1); + module.setParentId(parentModule.getId()); + } else { + module = apiModuleService.getNewModule(name, projectId, 1); + } + createModule(module); + return module; + } + + public static void createModule(ApiModule module) { + ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); + module.setProtocol(RequestType.HTTP); + List apiModules = apiModuleService.selectSameModule(module); + if (CollectionUtils.isEmpty(apiModules)) { + apiModuleService.addNode(module); + } else { + module.setId(apiModules.get(0).getId()); + } + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java new file mode 100644 index 0000000000..c5194c0c8b --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/MsDefinitionParser.java @@ -0,0 +1,99 @@ +package io.metersphere.api.dto.definition.parse; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import io.metersphere.api.dto.ApiTestImportRequest; +import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; +import io.metersphere.api.dto.scenario.request.RequestType; +import io.metersphere.api.parse.MsAbstractParser; +import io.metersphere.base.domain.ApiDefinitionWithBLOBs; +import io.metersphere.base.domain.ApiModule; +import io.metersphere.commons.constants.ApiImportPlatform; +import org.apache.commons.lang3.StringUtils; + +import java.io.InputStream; +import java.util.*; + +public class MsDefinitionParser extends MsAbstractParser { + + @Override + public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) { + String testStr = getApiTestStr(source); + JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField); + this.projectId = request.getProjectId(); + if (testObject.get("projectName") != null || testObject.get("projectId") != null ) { + return parseMsFormat(testStr, request); + } else { + request.setPlatform(ApiImportPlatform.Plugin.name()); + ApiDefinitionImport apiImport = new ApiDefinitionImport(); + apiImport.setProtocol(RequestType.HTTP); + apiImport.setData(parsePluginFormat(testObject, request, true)); + return apiImport; + } + } + + protected List parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest, Boolean isCreateModule) { + List results = new ArrayList<>(); + testObject.keySet().forEach(tag -> { + String moduleId = null; + if (isCreateModule) { + moduleId = ApiDefinitionImportUtil.buildModule(ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()), tag, this.projectId).getId(); + } + List msHTTPSamplerProxies = parseMsHTTPSamplerProxy(testObject, tag); + for (MsHTTPSamplerProxy msHTTPSamplerProxy : msHTTPSamplerProxies) { + ApiDefinitionWithBLOBs apiDefinition = buildApiDefinition(msHTTPSamplerProxy.getId(), msHTTPSamplerProxy.getName(), msHTTPSamplerProxy.getPath(), msHTTPSamplerProxy.getMethod(), importRequest); + apiDefinition.setModuleId(moduleId); + apiDefinition.setProjectId(this.projectId); + apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy)); + apiDefinition.setName(apiDefinition.getPath() + " [" + apiDefinition.getMethod() + "]"); + results.add(apiDefinition); + } + }); + return results; + } + + private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) { + ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class); + apiDefinitionImport.getData().forEach(apiDefinition -> { + parseApiDefinition(apiDefinition, importRequest); + }); + return apiDefinitionImport; + } + + private void parseApiDefinition(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest importRequest) { + String id = UUID.randomUUID().toString(); + if (StringUtils.isBlank(apiDefinition.getModulePath())) { + apiDefinition.setModuleId(null); + } + parseModule(apiDefinition.getModulePath(), importRequest, apiDefinition); + apiDefinition.setId(id); + apiDefinition.setProjectId(this.projectId); + String request = apiDefinition.getRequest(); + JSONObject requestObj = JSONObject.parseObject(request); + requestObj.put("id", id); + apiDefinition.setRequest(JSONObject.toJSONString(requestObj)); + } + + private void parseModule(String modulePath, ApiTestImportRequest importRequest, ApiDefinitionWithBLOBs apiDefinition) { + if (StringUtils.isEmpty(modulePath)) { + return; + } + if (modulePath.startsWith("/")) { + modulePath = modulePath.substring(1, modulePath.length()); + } + if (modulePath.endsWith("/")) { + modulePath = modulePath.substring(0, modulePath.length() - 1); + } + List modules = Arrays.asList(modulePath.split("/")); + ApiModule parent = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()); + Iterator iterator = modules.iterator(); + while (iterator.hasNext()) { + String item = iterator.next(); + parent = ApiDefinitionImportUtil.buildModule(parent, item, this.projectId); + if (!iterator.hasNext()) { + apiDefinition.setModuleId(parent.getId()); + } + } + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java new file mode 100644 index 0000000000..d3de371f77 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/PostmanDefinitionParser.java @@ -0,0 +1,58 @@ +package io.metersphere.api.dto.definition.parse; + +import com.alibaba.fastjson.JSON; +import io.metersphere.api.dto.ApiTestImportRequest; +import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; +import io.metersphere.api.dto.parse.postman.PostmanCollection; +import io.metersphere.api.dto.parse.postman.PostmanItem; +import io.metersphere.api.dto.parse.postman.PostmanKeyValue; +import io.metersphere.api.parse.PostmanAbstractParserParser; +import io.metersphere.base.domain.ApiDefinitionWithBLOBs; +import io.metersphere.base.domain.ApiModule; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class PostmanDefinitionParser extends PostmanAbstractParserParser { + + @Override + public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) { + String testStr = getApiTestStr(source); + this.projectId = request.getProjectId(); + PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class); + List variables = postmanCollection.getVariable(); + ApiDefinitionImport apiImport = new ApiDefinitionImport(); + List results = new ArrayList<>(); + parseItem(postmanCollection.getItem(), variables, results, + ApiDefinitionImportUtil.buildModule(ApiDefinitionImportUtil.getSelectModule(request.getModuleId()), postmanCollection.getInfo().getName(), this.projectId), true); + apiImport.setData(results); + return apiImport; + } + + protected void parseItem(List items, List variables, List results, ApiModule parentModule, Boolean isCreateModule) { + for (PostmanItem item : items) { + List childItems = item.getItem(); + if (childItems != null) { + ApiModule module = null; + if (isCreateModule) { + module = ApiDefinitionImportUtil.buildModule(parentModule, item.getName(), this.projectId); + } + parseItem(childItems, variables, results, module, isCreateModule); + } else { + MsHTTPSamplerProxy msHTTPSamplerProxy = parsePostman(item); + ApiDefinitionWithBLOBs request = buildApiDefinition(msHTTPSamplerProxy.getId(), msHTTPSamplerProxy.getName(), + msHTTPSamplerProxy.getPath(), msHTTPSamplerProxy.getMethod(), new ApiTestImportRequest()); + request.setPath(msHTTPSamplerProxy.getPath()); + request.setRequest(JSON.toJSONString(msHTTPSamplerProxy)); + + if (request != null) { + results.add(request); + } + if (parentModule != null) { + request.setModuleId(parentModule.getId()); + } + } + } + } +} diff --git a/backend/src/main/java/io/metersphere/api/parse/Swagger2Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java similarity index 98% rename from backend/src/main/java/io/metersphere/api/parse/Swagger2Parser.java rename to backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java index 00765494e9..f41ef16da4 100644 --- a/backend/src/main/java/io/metersphere/api/parse/Swagger2Parser.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java @@ -1,10 +1,9 @@ -package io.metersphere.api.parse; +package io.metersphere.api.dto.definition.parse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.response.HttpResponse; import io.metersphere.api.dto.scenario.Body; @@ -57,7 +56,7 @@ public class Swagger2Parser extends SwaggerAbstractParser { List results = new ArrayList<>(); - ApiModule parentNode = getSelectModule(importRequest.getModuleId()); + ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()); for (String pathName : pathNames) { Path path = paths.get(pathName); diff --git a/backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java similarity index 98% rename from backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java rename to backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java index 80b1b75684..e7602cfe18 100644 --- a/backend/src/main/java/io/metersphere/api/parse/Swagger3Parser.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java @@ -1,10 +1,9 @@ -package io.metersphere.api.parse; +package io.metersphere.api.dto.definition.parse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.response.HttpResponse; import io.metersphere.api.dto.scenario.Body; @@ -78,7 +77,7 @@ public class Swagger3Parser extends SwaggerAbstractParser { List results = new ArrayList<>(); - ApiModule parentNode = getSelectModule(importRequest.getModuleId()); + ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()); for (String pathName : pathNames) { PathItem pathItem = paths.get(pathName); diff --git a/backend/src/main/java/io/metersphere/api/parse/SwaggerAbstractParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/SwaggerAbstractParser.java similarity index 65% rename from backend/src/main/java/io/metersphere/api/parse/SwaggerAbstractParser.java rename to backend/src/main/java/io/metersphere/api/dto/definition/parse/SwaggerAbstractParser.java index 187550d4eb..86e37543a8 100644 --- a/backend/src/main/java/io/metersphere/api/parse/SwaggerAbstractParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/SwaggerAbstractParser.java @@ -1,16 +1,17 @@ -package io.metersphere.api.parse; +package io.metersphere.api.dto.definition.parse; +import io.metersphere.api.parse.ApiImportAbstractParser; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ApiModule; import java.util.List; -public abstract class SwaggerAbstractParser extends ApiImportAbstractParser { +public abstract class SwaggerAbstractParser extends ApiImportAbstractParser { protected void buildModule(ApiModule parentModule, ApiDefinitionWithBLOBs apiDefinition, List tags) { if (tags != null) { tags.forEach(tag -> { - ApiModule module = buildModule(parentModule, tag); + ApiModule module = ApiDefinitionImportUtil.buildModule(parentModule, tag, this.projectId); apiDefinition.setModuleId(module.getId()); }); } diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java index e5d2729d8b..34cbaaa326 100644 --- a/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportAbstractParser.java @@ -1,18 +1,16 @@ package io.metersphere.api.parse; +import com.alibaba.fastjson.JSON; import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.ApiModuleDTO; +import io.metersphere.api.dto.definition.request.MsScenario; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.Scenario; import io.metersphere.api.dto.scenario.request.RequestType; -import io.metersphere.api.service.ApiModuleService; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; -import io.metersphere.base.domain.ApiModule; +import io.metersphere.base.domain.ApiScenarioWithBLOBs; import io.metersphere.commons.exception.MSException; -import io.metersphere.commons.utils.BeanUtils; -import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.SessionUtils; import org.apache.commons.collections.CollectionUtils; @@ -29,10 +27,9 @@ import java.util.List; import java.util.Optional; import java.util.UUID; -public abstract class ApiImportAbstractParser implements ApiImportParser { +public abstract class ApiImportAbstractParser implements ApiImportParser { protected String projectId; - protected ApiModuleService apiModuleService; protected String getApiTestStr(InputStream source) { StringBuilder testStr = null; @@ -47,7 +44,9 @@ public abstract class ApiImportAbstractParser implements ApiImportParser { LogUtil.error(e.getMessage(), e); } finally { try { - source.close(); + if (source != null) { + source.close(); + } } catch (IOException e) { MSException.throwException(e.getMessage()); LogUtil.error(e.getMessage(), e); @@ -62,42 +61,6 @@ public abstract class ApiImportAbstractParser implements ApiImportParser { } } - protected ApiModule getSelectModule(String moduleId) { - apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); - if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) { - ApiModule module = new ApiModule(); - ApiModuleDTO moduleDTO = apiModuleService.getNode(moduleId); - if (moduleDTO != null) { - BeanUtils.copyBean(module, moduleDTO); - } - return module; - } - return null; - } - - protected ApiModule buildModule(ApiModule parentModule, String name) { - apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); - ApiModule module; - if (parentModule != null) { - module = apiModuleService.getNewModule(name, this.projectId, parentModule.getLevel() + 1); - module.setParentId(parentModule.getId()); - } else { - module = apiModuleService.getNewModule(name, this.projectId, 1); - } - createModule(module); - return module; - } - - protected void createModule(ApiModule module) { - module.setProtocol(RequestType.HTTP); - List apiModules = apiModuleService.selectSameModule(module); - if (CollectionUtils.isEmpty(apiModules)) { - apiModuleService.addNode(module); - } else { - module.setId(apiModules.get(0).getId()); - } - } - protected String getBodyType(String contentType) { String bodyType = ""; switch (contentType) { @@ -233,4 +196,22 @@ public abstract class ApiImportAbstractParser implements ApiImportParser { headers.add(new KeyValue(key, value, description, contentType, required)); } } + + protected ApiScenarioWithBLOBs parseScenario(MsScenario msScenario) { +// ApiScenarioModule module = ApiScenarioImportUtil.buildModule(ApiScenarioImportUtil.getSelectModule(request.getModuleId()), msScenario.getName(), this.projectId); + ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs(); + scenarioWithBLOBs.setName(msScenario.getName()); + scenarioWithBLOBs.setProjectId(this.projectId); + if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) { + scenarioWithBLOBs.setStepTotal(msScenario.getHashTree().size()); + } +// if (module != null) { +// scenarioWithBLOBs.setApiScenarioModuleId(module.getId()); +// scenarioWithBLOBs.setModulePath("/" + module.getName()); +// } + scenarioWithBLOBs.setId(UUID.randomUUID().toString()); + scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(msScenario)); + return scenarioWithBLOBs; +// scenarioWithBLOBsList.add(scenarioWithBLOBs); + } } diff --git a/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java b/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java index ee308cd82a..d3017c710a 100644 --- a/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/ApiImportParser.java @@ -1,10 +1,9 @@ package io.metersphere.api.parse; import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import java.io.InputStream; -public interface ApiImportParser { - ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request); +public interface ApiImportParser { + T parse(InputStream source, ApiTestImportRequest request); } diff --git a/backend/src/main/java/io/metersphere/api/parse/MsAbstractParser.java b/backend/src/main/java/io/metersphere/api/parse/MsAbstractParser.java new file mode 100644 index 0000000000..f8c3b0b598 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/parse/MsAbstractParser.java @@ -0,0 +1,99 @@ +package io.metersphere.api.parse; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; +import io.metersphere.api.dto.scenario.Body; +import io.metersphere.api.dto.scenario.KeyValue; +import io.metersphere.commons.utils.LogUtil; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.List; + +public abstract class MsAbstractParser extends ApiImportAbstractParser { + + protected List parseMsHTTPSamplerProxy(JSONObject testObject, String tag) { + JSONObject requests = testObject.getJSONObject(tag); + List msHTTPSamplerProxies = new ArrayList<>(); + requests.keySet().forEach(requestName -> { + JSONObject requestObject = requests.getJSONObject(requestName); + String path = requestObject.getString("url"); + String method = requestObject.getString("method"); + MsHTTPSamplerProxy request = buildRequest(requestName, path, method); + parseBody(requestObject, request.getBody()); + parseHeader(requestObject, request.getHeaders()); + parsePath(request); + msHTTPSamplerProxies.add(request); + }); + return msHTTPSamplerProxies; + } + + private void parsePath(MsHTTPSamplerProxy request) { + if (StringUtils.isNotBlank(request.getPath())) { + String[] split = request.getPath().split("\\?"); + String path = split[0]; + parseQueryParameters(split, request.getArguments()); + request.setPath(path); + } else { + request.setPath("/"); + } + } + + private void parseQueryParameters(String[] split, List arguments) { + if (split.length > 1) { + try { + String queryParams = split[1]; + queryParams = URLDecoder.decode(queryParams, "UTF-8"); + String[] params = queryParams.split("&"); + for (String param : params) { + String[] kv = param.split("="); + arguments.add(new KeyValue(kv[0], kv.length < 2 ? null : kv[1])); + } + } catch (UnsupportedEncodingException e) { + LogUtil.info(e.getMessage(), e); + return; + } + } + } + private void parseHeader(JSONObject requestObject, List msHeaders) { + JSONArray headers = requestObject.getJSONArray("headers"); + if (CollectionUtils.isNotEmpty(headers)) { + for (int i = 0; i < headers.size(); i++) { + JSONObject header = headers.getJSONObject(i); + msHeaders.add(new KeyValue(header.getString("name"), header.getString("value"))); + } + } + } + + private void parseBody(JSONObject requestObject, Body msBody) { + if (requestObject.containsKey("body")) { + Object body = requestObject.get("body"); + if (body instanceof JSONArray) { + JSONArray bodies = requestObject.getJSONArray("body"); + if (bodies != null) { + StringBuilder bodyStr = new StringBuilder(); + for (int i = 0; i < bodies.size(); i++) { + String tmp = bodies.getString(i); + bodyStr.append(tmp); + } + msBody.setType(Body.RAW); + msBody.setRaw(bodyStr.toString()); + } + } else if (body instanceof JSONObject) { + JSONObject bodyObj = requestObject.getJSONObject("body"); + if (bodyObj != null) { + ArrayList kvs = new ArrayList<>(); + bodyObj.keySet().forEach(key -> { + kvs.add(new KeyValue(key, bodyObj.getString(key))); + }); + msBody.setKvs(kvs); + msBody.setType(Body.WWW_FROM); + } + } + } + } +} diff --git a/backend/src/main/java/io/metersphere/api/parse/MsParser.java b/backend/src/main/java/io/metersphere/api/parse/MsParser.java deleted file mode 100644 index 815529dc92..0000000000 --- a/backend/src/main/java/io/metersphere/api/parse/MsParser.java +++ /dev/null @@ -1,192 +0,0 @@ -package io.metersphere.api.parse; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.Feature; -import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; -import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; -import io.metersphere.api.dto.scenario.Body; -import io.metersphere.api.dto.scenario.KeyValue; -import io.metersphere.api.dto.scenario.request.RequestType; -import io.metersphere.api.service.ApiModuleService; -import io.metersphere.base.domain.ApiDefinitionWithBLOBs; -import io.metersphere.base.domain.ApiModule; -import io.metersphere.base.domain.ApiTestCaseWithBLOBs; -import io.metersphere.commons.constants.ApiImportPlatform; -import io.metersphere.commons.utils.CommonBeanFactory; -import io.metersphere.commons.utils.LogUtil; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; - -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.*; -import java.util.function.Consumer; - -public class MsParser extends ApiImportAbstractParser { - - @Override - public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) { - String testStr = getApiTestStr(source); - JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField); - apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); - this.projectId = request.getProjectId(); - if (testObject.get("projectName") != null) { - return parseMsFormat(testStr, request); - } else { - request.setPlatform(ApiImportPlatform.Plugin.name()); - return parsePluginFormat(testObject, request, true); - } - } - - private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) { - ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class); - apiDefinitionImport.getData().forEach(apiDefinition -> { - parseApiDefinition(apiDefinition, importRequest); - }); - return apiDefinitionImport; - } - - private void parseApiDefinition(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest importRequest) { - String id = UUID.randomUUID().toString(); - if (StringUtils.isBlank(apiDefinition.getModulePath())) { - apiDefinition.setModuleId(null); - } - parseModule(apiDefinition.getModulePath(), importRequest, apiDefinition::setModuleId); - apiDefinition.setId(id); - apiDefinition.setProjectId(this.projectId); - String request = apiDefinition.getRequest(); - JSONObject requestObj = JSONObject.parseObject(request); - requestObj.put("id", id); - apiDefinition.setRequest(JSONObject.toJSONString(requestObj)); - } - - protected ApiDefinitionImport parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest, Boolean isCreateModule) { - List results = new ArrayList<>(); - ApiDefinitionImport apiImport = new ApiDefinitionImport(); - apiImport.setProtocol(RequestType.HTTP); - apiImport.setData(results); - testObject.keySet().forEach(tag -> { - - String moduleId = ""; - if (isCreateModule) { - moduleId = buildModule(getSelectModule(importRequest.getModuleId()), tag).getId(); - } - JSONObject requests = testObject.getJSONObject(tag); - - String finalModuleId = moduleId; - - requests.keySet().forEach(requestName -> { - - JSONObject requestObject = requests.getJSONObject(requestName); - String path = requestObject.getString("url"); - String method = requestObject.getString("method"); - - MsHTTPSamplerProxy request = buildRequest(requestName, path, method); - ApiDefinitionWithBLOBs apiDefinition = buildApiDefinition(request.getId(), requestName, path, method,importRequest); - - apiDefinition.setModuleId(finalModuleId); - apiDefinition.setProjectId(this.projectId); - parseBody(requestObject, request.getBody()); - parseHeader(requestObject, request.getHeaders()); - parsePath(request, apiDefinition); - apiDefinition.setRequest(JSONObject.toJSONString(request)); - results.add(apiDefinition); - }); - }); - return apiImport; - } - - private void parsePath(MsHTTPSamplerProxy request, ApiDefinitionWithBLOBs apiDefinition) { - if (StringUtils.isNotBlank(request.getPath())) { - String[] split = request.getPath().split("\\?"); - String path = split[0]; - parseQueryParameters(split, request.getArguments()); - request.setPath(path); - apiDefinition.setPath(path); - } else { - request.setPath("/"); - apiDefinition.setPath("/"); - } - apiDefinition.setName(apiDefinition.getPath() + " [" + apiDefinition.getMethod() + "]"); - } - - private void parseQueryParameters(String[] split, List arguments) { - if (split.length > 1) { - try { - String queryParams = split[1]; - queryParams = URLDecoder.decode(queryParams, "UTF-8"); - String[] params = queryParams.split("&"); - for (String param : params) { - String[] kv = param.split("="); - arguments.add(new KeyValue(kv[0], kv[1])); - } - } catch (UnsupportedEncodingException e) { - LogUtil.info(e.getMessage(), e); - return; - } - } - } - private void parseHeader(JSONObject requestObject, List msHeaders) { - JSONArray headers = requestObject.getJSONArray("headers"); - if (CollectionUtils.isNotEmpty(headers)) { - for (int i = 0; i < headers.size(); i++) { - JSONObject header = headers.getJSONObject(i); - msHeaders.add(new KeyValue(header.getString("name"), header.getString("value"))); - } - } - } - - private void parseBody(JSONObject requestObject, Body msBody) { - if (requestObject.containsKey("body")) { - Object body = requestObject.get("body"); - if (body instanceof JSONArray) { - JSONArray bodies = requestObject.getJSONArray("body"); - if (bodies != null) { - StringBuilder bodyStr = new StringBuilder(); - for (int i = 0; i < bodies.size(); i++) { - String tmp = bodies.getString(i); - bodyStr.append(tmp); - } - msBody.setType(Body.RAW); - msBody.setRaw(bodyStr.toString()); - } - } else if (body instanceof JSONObject) { - JSONObject bodyObj = requestObject.getJSONObject("body"); - if (bodyObj != null) { - ArrayList kvs = new ArrayList<>(); - bodyObj.keySet().forEach(key -> { - kvs.add(new KeyValue(key, bodyObj.getString(key))); - }); - msBody.setKvs(kvs); - msBody.setType(Body.WWW_FROM); - } - } - } - } - - protected void parseModule(String modulePath, ApiTestImportRequest importRequest, Consumer consumer) { - if (StringUtils.isBlank(modulePath)) { - return; - } - if (modulePath.startsWith("/")) { - modulePath = modulePath.substring(1, modulePath.length()); - } - if (modulePath.endsWith("/")) { - modulePath = modulePath.substring(0, modulePath.length() - 1); - } - List modules = Arrays.asList(modulePath.split("/")); - ApiModule parent = getSelectModule(importRequest.getModuleId()); - Iterator iterator = modules.iterator(); - while (iterator.hasNext()) { - String item = iterator.next(); - parent = buildModule(parent, item); - if (!iterator.hasNext()) { - consumer.accept(parent.getId()); - } - } - } -} diff --git a/backend/src/main/java/io/metersphere/api/parse/PostmanParser.java b/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java similarity index 65% rename from backend/src/main/java/io/metersphere/api/parse/PostmanParser.java rename to backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java index 393b07a3e3..30ddb82533 100644 --- a/backend/src/main/java/io/metersphere/api/parse/PostmanParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java @@ -2,64 +2,25 @@ package io.metersphere.api.parse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.parse.postman.*; import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.KeyValue; -import io.metersphere.base.domain.ApiDefinitionWithBLOBs; -import io.metersphere.base.domain.ApiModule; import io.metersphere.commons.constants.MsRequestBodyType; import io.metersphere.commons.constants.PostmanRequestBodyMode; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import java.io.InputStream; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; -public class PostmanParser extends ApiImportAbstractParser { +public abstract class PostmanAbstractParserParser extends ApiImportAbstractParser { - @Override - public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) { - String testStr = getApiTestStr(source); - this.projectId = request.getProjectId(); - PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class); - List variables = postmanCollection.getVariable(); - ApiDefinitionImport apiImport = new ApiDefinitionImport(); - List results = new ArrayList<>(); - parseItem(postmanCollection.getItem(), variables, results, buildModule(getSelectModule(request.getModuleId()), postmanCollection.getInfo().getName()), true); - apiImport.setData(results); - return apiImport; - } - - protected void parseItem(List items, List variables, List results, ApiModule parentModule, Boolean isCreateModule) { - for (PostmanItem item : items) { - List childItems = item.getItem(); - if (childItems != null) { - ApiModule module = null; - if (isCreateModule) { - module = buildModule(parentModule, item.getName()); - } - parseItem(childItems, variables, results, module, isCreateModule); - } else { - ApiDefinitionWithBLOBs request = parsePostman(item); - if (request != null) { - results.add(request); - } - if (parentModule != null) { - request.setModuleId(parentModule.getId()); - } - } - } - } - - private ApiDefinitionWithBLOBs parsePostman(PostmanItem requestItem) { + protected MsHTTPSamplerProxy parsePostman(PostmanItem requestItem) { PostmanRequest requestDesc = requestItem.getRequest(); if (requestDesc == null) { return null; @@ -67,44 +28,45 @@ public class PostmanParser extends ApiImportAbstractParser { requestDesc.getAuth(); // todo 认证方式等待优化 PostmanUrl url = requestDesc.getUrl(); MsHTTPSamplerProxy request = buildRequest(requestItem.getName(), url.getRaw(), requestDesc.getMethod()); - ApiDefinitionWithBLOBs apiDefinition = - buildApiDefinition(request.getId(), requestItem.getName(), url.getRaw(), requestDesc.getMethod(),new ApiTestImportRequest()); if (StringUtils.isNotBlank(request.getPath())) { String path = request.getPath().split("\\?")[0]; path = path.replace("{{", "${"); path = path.replace("}}", "}"); request.setPath(path); - apiDefinition.setPath(path); } else { request.setPath("/"); - apiDefinition.setPath("/"); } parseBody(request.getBody(), requestDesc); request.setArguments(parseKeyValue(url.getQuery())); request.setHeaders(parseKeyValue(requestDesc.getHeader())); addBodyHeader(request); addPreScript(request, requestItem.getEvent()); - apiDefinition.setRequest(JSON.toJSONString(request)); - return apiDefinition; + return request; } + private void addPreScript(MsHTTPSamplerProxy request, List event) { - if (CollectionUtils.isNotEmpty(event)) { + if (request != null && CollectionUtils.isNotEmpty(event)) { StringBuilder scriptStr = new StringBuilder(); event = event.stream() .filter(item -> item.getScript() != null) .collect(Collectors.toList()); event.forEach(item -> { PostmanScript script = item.getScript(); - List exec = script.getExec(); - if (CollectionUtils.isNotEmpty(exec)) { - exec.forEach(col -> { - scriptStr.append(col + "/n"); - }); + if (script != null) { + List exec = script.getExec(); + if (CollectionUtils.isNotEmpty(exec)) { + exec.forEach(col -> { + if (StringUtils.isNotEmpty(col)) { + scriptStr.append(col + "/n"); + } + }); + } } }); if (StringUtils.isNotBlank(scriptStr)) { MsJSR223PreProcessor jsr223PreProcessor = new MsJSR223PreProcessor(); + jsr223PreProcessor.setName("JSR223PreProcessor"); jsr223PreProcessor.setScriptLanguage("javascript"); jsr223PreProcessor.setScript(scriptStr.toString()); LinkedList hashTree = new LinkedList<>(); @@ -129,6 +91,9 @@ public class PostmanParser extends ApiImportAbstractParser { return; } String bodyMode = postmanBody.getString("mode"); + if (StringUtils.isBlank(bodyMode)) { + return; + } if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) { parseRawBody(body, postmanBody, bodyMode); } else if (StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) { diff --git a/backend/src/main/java/io/metersphere/api/parse/ScenarioMsParser.java b/backend/src/main/java/io/metersphere/api/parse/ScenarioMsParser.java deleted file mode 100644 index 88327c189b..0000000000 --- a/backend/src/main/java/io/metersphere/api/parse/ScenarioMsParser.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.metersphere.api.parse; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.Feature; -import io.metersphere.api.dto.ApiTestImportRequest; -import io.metersphere.api.dto.automation.ApiScenrioExportResult; -import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; -import io.metersphere.api.dto.definition.request.MsScenario; -import io.metersphere.api.dto.definition.request.MsTestElement; -import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; -import io.metersphere.api.service.ApiModuleService; -import io.metersphere.base.domain.ApiScenarioWithBLOBs; -import io.metersphere.commons.constants.ApiImportPlatform; -import io.metersphere.commons.utils.CommonBeanFactory; -import org.apache.commons.lang3.StringUtils; - -import java.io.InputStream; -import java.util.LinkedList; -import java.util.UUID; - -public class ScenarioMsParser extends MsParser { - - @Override - public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) { - String testStr = getApiTestStr(source); - JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField); - apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class); - this.projectId = request.getProjectId(); - if (testObject.get("projectId") != null) { - return parseMsFormat(testStr, request); - } else { - request.setPlatform(ApiImportPlatform.Plugin.name()); - ApiDefinitionImport apiDefinitionImport = parsePluginFormat(testObject, request, false); - MsScenario msScenario = new MsScenario(); - LinkedList msHTTPSamplerProxies = new LinkedList<>(); - apiDefinitionImport.getData().forEach(res -> { - msHTTPSamplerProxies.add(JSONObject.parseObject(res.getRequest(), MsHTTPSamplerProxy.class)); - }); - msScenario.setHashTree(msHTTPSamplerProxies); - msScenario.setType("scenario"); - apiDefinitionImport.setScenarioDefinition(msScenario); - return apiDefinitionImport; - } - } - - private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) { - ApiScenrioExportResult apiScenrioExportResult = JSON.parseObject(testStr, ApiScenrioExportResult.class); - apiScenrioExportResult.getData().forEach(scenario -> { - parseApiDefinition(scenario, importRequest); - }); - ApiDefinitionImport apiDefinitionImport = new ApiDefinitionImport(); - apiDefinitionImport.setScenarioDefinitionData(apiScenrioExportResult.getData()); - return apiDefinitionImport; - } - - private void parseApiDefinition(ApiScenarioWithBLOBs scenario, ApiTestImportRequest importRequest) { - String id = UUID.randomUUID().toString(); - if (StringUtils.isBlank(scenario.getModulePath())) { - scenario.setApiScenarioModuleId(null); - } -// parseModule(scenario.getModulePath(), importRequest, scenario::setApiScenarioModuleId); - scenario.setId(id); - scenario.setProjectId(this.projectId); - String scenarioDefinition = scenario.getScenarioDefinition(); - JSONObject scenarioDefinitionObj = JSONObject.parseObject(scenarioDefinition); - scenarioDefinitionObj.put("id", id); - scenarioDefinitionObj.put("name", scenario.getName()); - scenario.setScenarioDefinition(JSONObject.toJSONString(scenarioDefinitionObj)); - } -} diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 027fe93ec5..7036fcd2c1 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -10,7 +10,6 @@ import io.metersphere.api.dto.DeleteAPIReportRequest; import io.metersphere.api.dto.JmxInfoDTO; import io.metersphere.api.dto.automation.*; import io.metersphere.api.dto.automation.parse.ScenarioImport; -import io.metersphere.api.dto.automation.parse.ScenarioImportParser; import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory; import io.metersphere.api.dto.datacount.ApiDataCountResult; import io.metersphere.api.dto.definition.RunDefinitionRequest; @@ -18,6 +17,7 @@ import io.metersphere.api.dto.definition.request.*; import io.metersphere.api.dto.definition.request.variable.ScenarioVariable; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.jmeter.JMeterService; +import io.metersphere.api.parse.ApiImportParser; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.ApiScenarioMapper; import io.metersphere.base.mapper.ApiScenarioReportMapper; @@ -791,10 +791,12 @@ public class ApiAutomationService { } public ScenarioImport scenarioImport(MultipartFile file, ApiTestImportRequest request) { - ScenarioImportParser apiImportParser = ScenarioImportParserFactory.getImportParser(request.getPlatform()); + ApiImportParser apiImportParser = ScenarioImportParserFactory.getImportParser(request.getPlatform()); ScenarioImport apiImport = null; + Optional.ofNullable(file) + .ifPresent(item -> request.setFileName(file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")))); try { - apiImport = Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request); + apiImport = (ScenarioImport) Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request); } catch (Exception e) { LogUtil.error(e.getMessage(), e); MSException.throwException(Translator.get("parse_data_error")); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 6e1577576e..455bf493a4 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -18,7 +18,7 @@ import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.RequestResult; import io.metersphere.api.jmeter.TestResult; import io.metersphere.api.parse.ApiImportParser; -import io.metersphere.api.parse.ApiImportParserFactory; +import io.metersphere.api.dto.definition.parse.ApiDefinitionImportParserFactory; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.ext.*; @@ -382,6 +382,9 @@ public class ApiDefinitionService { apiTestCase.setUpdateUserId(SessionUtils.getUserId()); apiTestCase.setNum(getNextNum(apiTestCase.getApiDefinitionId())); apiTestCase.setPriority("P0"); + if (apiTestCase.getName().length() > 255) { + apiTestCase.setName(apiTestCase.getName().substring(0, 255)); + } if (!isInsert) { apiTestCase.setName(apiTestCase.getName() + "_" + apiTestCase.getId().substring(0, 5)); } @@ -490,10 +493,10 @@ public class ApiDefinitionService { public ApiDefinitionImport apiTestImport(MultipartFile file, ApiTestImportRequest request) { - ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform()); + ApiImportParser apiImportParser = ApiDefinitionImportParserFactory.getApiImportParser(request.getPlatform()); ApiDefinitionImport apiImport = null; try { - apiImport = Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request); + apiImport = (ApiDefinitionImport) Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request); } catch (Exception e) { LogUtil.error(e.getMessage(), e); MSException.throwException(Translator.get("parse_data_error")); From 192b8ed7576192b0acf5777337f09129d76bf4f8 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Mon, 22 Feb 2021 12:41:46 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20K8S=20=E8=B5=84=E6=BA=90=E6=B1=A0?= =?UTF-8?q?=E6=94=AF=E6=8C=81nodeSelector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/settings/system/TestResourcePool.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/business/components/settings/system/TestResourcePool.vue b/frontend/src/business/components/settings/system/TestResourcePool.vue index 2daae39968..b7473f2e15 100644 --- a/frontend/src/business/components/settings/system/TestResourcePool.vue +++ b/frontend/src/business/components/settings/system/TestResourcePool.vue @@ -254,8 +254,12 @@ export default { let resultValidate = {validate: true, msg: this.$t('test_resource_pool.fill_the_data')}; this.infoList.forEach(info => { for (let key in info) { + // 排除非必填项 + if (key === 'nodeSelector') { + continue; + } if (info[key] != '0' && !info[key]) { - resultValidate.validate = false + resultValidate.validate = false; return false; } } From 0acadee0612bade207e76cbed65194094626517f Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Mon, 22 Feb 2021 13:03:00 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix=EF=BC=9Apostman=20=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=8C=85=E5=90=ABTests=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/api/parse/PostmanAbstractParserParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java b/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java index 30ddb82533..3b1647184a 100644 --- a/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java +++ b/backend/src/main/java/io/metersphere/api/parse/PostmanAbstractParserParser.java @@ -53,12 +53,12 @@ public abstract class PostmanAbstractParserParser extends ApiImportAbstractPa .collect(Collectors.toList()); event.forEach(item -> { PostmanScript script = item.getScript(); - if (script != null) { + if (script != null && item.getListen().contains("prerequest")) { List exec = script.getExec(); if (CollectionUtils.isNotEmpty(exec)) { exec.forEach(col -> { if (StringUtils.isNotEmpty(col)) { - scriptStr.append(col + "/n"); + scriptStr.append(col + "\n"); } }); } From 2a7ccf7b24898a3f59b44012773990b0c8fba0c3 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Mon, 22 Feb 2021 13:57:40 +0800 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20=E7=BB=9F=E4=B8=80=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=9A=E4=B9=89=E5=92=8C=E5=9C=BA=E6=99=AF=E5=AF=BC?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/api/dto/definition/ApiExportResult.java | 2 ++ .../java/io/metersphere/api/service/ApiDefinitionService.java | 2 ++ .../components/api/definition/components/list/ApiList.vue | 4 ++++ frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 6 files changed, 11 insertions(+) diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiExportResult.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiExportResult.java index ff0046a54a..c63c8ae4bd 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiExportResult.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiExportResult.java @@ -12,6 +12,8 @@ import java.util.List; public class ApiExportResult { private String projectName; private String protocol; + private String projectId; + private String version; private List data; private List cases; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 455bf493a4..ac220eb41e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -747,6 +747,8 @@ public class ApiDefinitionService { apiExportResult.setCases(apiTestCaseService.selectCasesBydApiIds(request.getIds())); apiExportResult.setProjectName(request.getProjectId()); apiExportResult.setProtocol(request.getProtocol()); + apiExportResult.setProjectId(request.getProjectId()); + apiExportResult.setVersion(System.getenv("MS_VERSION")); return apiExportResult; } } diff --git a/frontend/src/business/components/api/definition/components/list/ApiList.vue b/frontend/src/business/components/api/definition/components/list/ApiList.vue index f34a489085..6f1ce29ae9 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiList.vue @@ -699,6 +699,10 @@ export default { exportApi() { let param = this.buildBatchParam(); param.protocol = this.currentProtocol; + if (param.ids === undefined || param.ids.length < 1) { + this.$warning(this.$t("api_test.definition.check_select")); + return; + } this.result = this.$post("/api/definition/export", param, response => { let obj = response.data; obj.protocol = this.currentProtocol; diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 23b39a5bec..8bcd8596c3 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -533,6 +533,7 @@ export default { api_case_passing_rate: "Use case pass rate", create_tip: "Note: Detailed interface information can be filled out on the edit page", api_import: "Api Import", + check_select: "Please check the API", select_comp: { no_data: "No Data", add_data: "Add Data" diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 22447fbcc4..00631b2f49 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -533,6 +533,7 @@ export default { api_case_passing_rate: "用例通过率", create_tip: "注: 详细的接口信息可以在编辑页面填写", api_import: "接口导入", + check_select: "请勾选接口", select_comp: { no_data: "无数据", add_data: "去添加" diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 24b19c5646..5f0466d424 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -532,6 +532,7 @@ export default { api_case_passing_rate: "用例通過率", create_tip: "註: 詳細的接口信息可以在編輯頁面填寫", api_import: "接口導入", + check_select: "請勾選接口", select_comp: { no_data: "無數據", add_data: "去添加"