feat(接口测试): 接口定义 postman 导入

This commit is contained in:
chenjianxing 2020-12-07 20:17:25 +08:00
parent 1aab595ab0
commit 036d5a5551
12 changed files with 219 additions and 257 deletions

View File

@ -3,7 +3,6 @@ package io.metersphere.api.dto.definition.parse;
import io.metersphere.api.dto.definition.ApiDefinitionResult; import io.metersphere.api.dto.definition.ApiDefinitionResult;
import lombok.Data; import lombok.Data;
import java.util.HashMap;
import java.util.List; import java.util.List;
@Data @Data
@ -11,5 +10,4 @@ public class ApiDefinitionImport {
private String projectName; private String projectName;
private String protocol; private String protocol;
private List<ApiDefinitionResult> data; private List<ApiDefinitionResult> data;
private HashMap<String, List<ApiDefinitionResult>> resultMap;
} }

View File

@ -7,6 +7,8 @@ public class PostmanKeyValue {
private String key; private String key;
private String value; private String value;
private String type; private String type;
private String description;
private String contentType;
public PostmanKeyValue() { public PostmanKeyValue() {
} }

View File

@ -20,22 +20,23 @@ public class KeyValue {
private boolean required; private boolean required;
public KeyValue() { public KeyValue() {
this.enable = true; this(null, null);
this.required = true;
} }
public KeyValue(String name, String value) { public KeyValue(String name, String value) {
this.name = name; this(name, value, null);
this.value = value;
this.enable = true;
this.required = true;
} }
public KeyValue(String name, String value, String description) { public KeyValue(String name, String value, String description) {
this(name, value, description, null);
}
public KeyValue(String name, String value, String description, String contentType) {
this.name = name; this.name = name;
this.value = value; this.value = value;
this.enable = true;
this.description = description; this.description = description;
this.contentType = contentType;
this.enable = true;
this.required = true; this.required = true;
} }

View File

@ -1,11 +1,19 @@
package io.metersphere.api.parse; package io.metersphere.api.parse;
import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.ApiDefinitionResult;
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.KeyValue;
import io.metersphere.api.dto.scenario.Scenario; import io.metersphere.api.dto.scenario.Scenario;
import io.metersphere.api.dto.scenario.request.HttpRequest; import io.metersphere.api.dto.scenario.request.HttpRequest;
import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.service.ApiModuleService;
import io.metersphere.base.domain.ApiModule;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -16,9 +24,13 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; 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) { protected String getApiTestStr(InputStream source) {
StringBuilder testStr = null; StringBuilder testStr = null;
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) { try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
@ -47,6 +59,42 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
} }
} }
protected void createModule(ApiModule module) {
module.setProtocol(RequestType.HTTP);
List<ApiModule> apiModules = apiModuleService.selectSameModule(module);
if (CollectionUtils.isEmpty(apiModules)) {
apiModuleService.addNode(module);
} else {
module.setId(apiModules.get(0).getId());
}
}
protected ApiDefinitionResult buildApiDefinition(String id, String name, String path, String method) {
ApiDefinitionResult apiDefinition = new ApiDefinitionResult();
apiDefinition.setName(name);
apiDefinition.setPath(path);
apiDefinition.setProtocol(RequestType.HTTP);
apiDefinition.setMethod(method);
apiDefinition.setId(id);
apiDefinition.setProjectId(this.projectId);
apiDefinition.setUserId(SessionUtils.getUserId());
return apiDefinition;
}
protected MsHTTPSamplerProxy buildRequest(String name, String path, String method) {
MsHTTPSamplerProxy request = new MsHTTPSamplerProxy();
request.setName(name);
request.setPath(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.setBody(new Body());
return request;
}
protected void addContentType(HttpRequest request, String contentType) { protected void addContentType(HttpRequest request, String contentType) {
// addHeader(request, "Content-Type", contentType); // addHeader(request, "Content-Type", contentType);
} }

View File

@ -2,12 +2,9 @@ package io.metersphere.api.parse;
import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.parse.ApiImport;
import java.io.InputStream; import java.io.InputStream;
public interface ApiImportParser { public interface ApiImportParser {
ApiImport parse(InputStream source, ApiTestImportRequest request); ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request);
ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request);
} }

View File

@ -6,7 +6,6 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.Feature;
import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.parse.ApiImport;
import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.commons.constants.MsRequestBodyType; import io.metersphere.commons.constants.MsRequestBodyType;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -16,52 +15,43 @@ import java.io.InputStream;
public class MsParser extends ApiImportAbstractParser { public class MsParser extends ApiImportAbstractParser {
@Override @Override
public ApiImport parse(InputStream source, ApiTestImportRequest request) { public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
String testStr = getApiTestStr(source);
ApiImport apiImport = JSON.parseObject(parsePluginFormat(testStr), ApiImport.class);
apiImport.getScenarios().forEach(scenario -> setScenarioByRequest(scenario, request));
return apiImport;
}
@Override
public ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request) {
String testStr = getApiTestStr(source); String testStr = getApiTestStr(source);
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
if (testObject.get("projectName") == null) {
testStr = parsePluginFormat(testObject);
}
ApiDefinitionImport apiImport = JSON.parseObject(testStr, ApiDefinitionImport.class); ApiDefinitionImport apiImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
return apiImport; return apiImport;
} }
private String parsePluginFormat(String testStr) { private String parsePluginFormat( JSONObject testObject) {
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField); //插件格式
if (testObject.get("scenarios") != null) { JSONArray scenarios = new JSONArray();
return testStr; testObject.keySet().forEach(scenarioName -> {
} else { JSONObject scenario = new JSONObject();
//插件格式 scenario.put("name", scenarioName);
JSONArray scenarios = new JSONArray(); JSONArray requestsObjects = new JSONArray();
testObject.keySet().forEach(scenarioName -> { JSONObject requestsObject = testObject.getJSONObject(scenarioName);
JSONObject scenario = new JSONObject(); requestsObject.keySet().forEach(requestName -> {
scenario.put("name", scenarioName); JSONObject requestObject = new JSONObject(true);
JSONArray requestsObjects = new JSONArray(); JSONObject requestTmpObject = requestsObject.getJSONObject(requestName);
JSONObject requestsObject = testObject.getJSONObject(scenarioName); //排序确保type在第一个否则转换失败
requestsObject.keySet().forEach(requestName -> { if (StringUtils.isBlank(requestTmpObject.getString("type"))) {
JSONObject requestObject = new JSONObject(true); requestObject.put("type", RequestType.HTTP);
JSONObject requestTmpObject = requestsObject.getJSONObject(requestName); }
//排序确保type在第一个否则转换失败
if (StringUtils.isBlank(requestTmpObject.getString("type"))) {
requestObject.put("type", RequestType.HTTP);
}
requestTmpObject.keySet().forEach(key -> requestObject.put(key, requestTmpObject.get(key))); requestTmpObject.keySet().forEach(key -> requestObject.put(key, requestTmpObject.get(key)));
requestObject.put("name", requestName); requestObject.put("name", requestName);
parseBody(requestObject); parseBody(requestObject);
requestsObjects.add(requestObject); requestsObjects.add(requestObject);
});
scenario.put("requests", requestsObjects);
scenarios.add(scenario);
}); });
JSONObject result = new JSONObject(); scenario.put("requests", requestsObjects);
result.put("scenarios", scenarios); scenarios.add(scenario);
return result.toJSONString(); });
} JSONObject result = new JSONObject();
result.put("scenarios", scenarios);
return result.toJSONString();
} }
private void parseBody(JSONObject requestObject) { private void parseBody(JSONObject requestObject) {

View File

@ -5,180 +5,135 @@ import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.ApiDefinitionResult; import io.metersphere.api.dto.definition.ApiDefinitionResult;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.configurations.MsHeaderManager;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.parse.ApiImport;
import io.metersphere.api.dto.parse.postman.*; import io.metersphere.api.dto.parse.postman.*;
import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.Scenario; import io.metersphere.api.service.ApiModuleService;
import io.metersphere.api.dto.scenario.request.HttpRequest; import io.metersphere.base.domain.ApiModule;
import io.metersphere.api.dto.scenario.request.Request;
import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.commons.constants.MsRequestBodyType; import io.metersphere.commons.constants.MsRequestBodyType;
import io.metersphere.commons.constants.PostmanRequestBodyMode; import io.metersphere.commons.constants.PostmanRequestBodyMode;
import io.metersphere.commons.utils.CommonBeanFactory;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.jorphan.collections.HashTree;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID;
public class PostmanParser extends ApiImportAbstractParser { public class PostmanParser extends ApiImportAbstractParser {
@Override @Override
public ApiImport parse(InputStream source, ApiTestImportRequest request) { public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
String testStr = getApiTestStr(source);
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
PostmanCollectionInfo info = postmanCollection.getInfo();
List<PostmanKeyValue> variables = postmanCollection.getVariable();
ApiImport apiImport = new ApiImport();
List<Scenario> scenarios = new ArrayList<>();
Scenario scenario = new Scenario();
scenario.setName(info.getName());
setScenarioByRequest(scenario, request);
parseItem(postmanCollection.getItem(), scenario, variables, scenarios);
apiImport.setScenarios(scenarios);
return apiImport;
}
@Override
public ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request) {
String testStr = getApiTestStr(source); String testStr = getApiTestStr(source);
this.projectId = request.getProjectId();
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class); PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
List<PostmanKeyValue> variables = postmanCollection.getVariable(); List<PostmanKeyValue> variables = postmanCollection.getVariable();
ApiDefinitionImport apiImport = new ApiDefinitionImport(); ApiDefinitionImport apiImport = new ApiDefinitionImport();
List<ApiDefinitionResult> requests = new ArrayList<>(); List<ApiDefinitionResult> results = new ArrayList<>();
parseItem(postmanCollection.getItem(), variables, results, buildModule(postmanCollection.getInfo().getName(), null));
parseItem(postmanCollection.getItem(), variables, requests); apiImport.setData(results);
apiImport.setData(requests);
return apiImport; return apiImport;
} }
private void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionResult> scenarios) { private void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionResult> results, ApiModule parentModule) {
for (PostmanItem item : items) { for (PostmanItem item : items) {
List<PostmanItem> childItems = item.getItem(); List<PostmanItem> childItems = item.getItem();
if (childItems != null) { if (childItems != null) {
parseItem(childItems, variables, scenarios); ApiModule module = buildModule(item.getName(), parentModule);
parseItem(childItems, variables, results, module);
} else { } else {
ApiDefinitionResult request = parsePostman(item); ApiDefinitionResult request = parsePostman(item);
if (request != null) { if (request != null) {
scenarios.add(request); results.add(request);
}
if (parentModule != null) {
request.setModuleId(parentModule.getId());
} }
} }
} }
} }
private ApiModule buildModule(String name, ApiModule parentModule) {
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;
}
private ApiDefinitionResult parsePostman(PostmanItem requestItem) { private ApiDefinitionResult parsePostman(PostmanItem requestItem) {
PostmanRequest requestDesc = requestItem.getRequest(); PostmanRequest requestDesc = requestItem.getRequest();
if (requestDesc == null) { if (requestDesc == null) {
return null; return null;
} }
requestDesc.getAuth(); // todo 认证方式等待优化
PostmanUrl url = requestDesc.getUrl(); PostmanUrl url = requestDesc.getUrl();
ApiDefinitionResult request = new ApiDefinitionResult(); MsHTTPSamplerProxy request = buildRequest(requestItem.getName(), url.getRaw(), requestDesc.getMethod());
request.setName(requestItem.getName()); ApiDefinitionResult apiDefinition =
request.setPath(url.getRaw()); buildApiDefinition(request.getId(), requestItem.getName(), url.getRaw(), requestDesc.getMethod());
request.setMethod(requestDesc.getMethod()); parseBody(request.getBody(), requestDesc);
request.setProtocol(RequestType.HTTP); request.setArguments(parseKeyValue(url.getQuery()));
MsHTTPSamplerProxy requestElement = new MsHTTPSamplerProxy(); request.setHeaders(parseKeyValue(requestDesc.getHeader()));
requestElement.setName(requestItem.getName() + "Postman MHTTPSamplerProxy"); apiDefinition.setRequest(JSON.toJSONString(request));
requestElement.setBody(parseBody(requestDesc)); return apiDefinition;
requestElement.setArguments(parseKeyValue(url.getQuery()));
requestElement.setProtocol(RequestType.HTTP);
requestElement.setPath(url.getRaw());
requestElement.setMethod(requestDesc.getMethod());
requestElement.setId(UUID.randomUUID().toString());
requestElement.setRest(new ArrayList<KeyValue>());
MsHeaderManager headerManager = new MsHeaderManager();
headerManager.setId(UUID.randomUUID().toString());
headerManager.setName(requestItem.getName() + "Postman MsHeaderManager");
headerManager.setHeaders(parseKeyValue(requestDesc.getHeader()));
HashTree tree = new HashTree();
tree.add(headerManager);
LinkedList<MsTestElement> list = new LinkedList<>();
list.add(headerManager);
requestElement.setHashTree(list);
request.setRequest(JSON.toJSONString(requestElement));
return request;
} }
private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) { private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) {
if (postmanKeyValues == null) { if (postmanKeyValues == null) {
return null; return null;
} }
List<KeyValue> keyValues = new ArrayList<>(); List<KeyValue> keyValues = new ArrayList<>();
postmanKeyValues.forEach(item -> keyValues.add(new KeyValue(item.getKey(), item.getValue()))); postmanKeyValues.forEach(item -> keyValues.add(new KeyValue(item.getKey(), item.getValue(), item.getDescription(), item.getContentType())));
return keyValues; return keyValues;
} }
private void parseItem(List<PostmanItem> items, Scenario scenario, List<PostmanKeyValue> variables, List<Scenario> scenarios) { private void parseBody(Body body, PostmanRequest requestDesc) {
List<Request> requests = new ArrayList<>();
for (PostmanItem item : items) {
List<PostmanItem> childItems = item.getItem();
if (childItems != null) {
Scenario subScenario = new Scenario();
subScenario.setName(item.getName());
subScenario.setEnvironmentId(scenario.getEnvironmentId());
parseItem(childItems, subScenario, variables, scenarios);
} else {
Request request = parseRequest(item);
if (request != null) {
requests.add(request);
}
}
}
scenario.setVariables(parseKeyValue(variables));
scenario.setRequests(requests);
scenarios.add(scenario);
}
private Request parseRequest(PostmanItem requestItem) {
HttpRequest request = new HttpRequest();
PostmanRequest requestDesc = requestItem.getRequest();
if (requestDesc == null) {
return null;
}
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()));
request.setBody(parseBody(requestDesc));
return request;
}
private Body parseBody(PostmanRequest requestDesc) {
Body body = new Body();
JSONObject postmanBody = requestDesc.getBody(); JSONObject postmanBody = requestDesc.getBody();
if (postmanBody == null) { if (postmanBody == null) {
return null; return;
} }
String bodyMode = postmanBody.getString("mode"); String bodyMode = postmanBody.getString("mode");
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) { if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
body.setRaw(postmanBody.getString(bodyMode)); parseRawBody(body, postmanBody, bodyMode);
body.setType(MsRequestBodyType.RAW.value()); } else if (StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) {
JSONObject options = postmanBody.getJSONObject("options");
if (options != null) {
JSONObject raw = options.getJSONObject(PostmanRequestBodyMode.RAW.value());
if (raw != null) {
body.setFormat(raw.getString("language"));
}
}
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class); List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
body.setType(MsRequestBodyType.KV.value());
body.setKvs(parseKeyValue(postmanKeyValues)); 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<>());
} }
return body;
} }
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) {
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);
}
}
}
} }

View File

@ -8,11 +8,13 @@ import io.metersphere.api.dto.definition.ApiDefinitionResult;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.definition.response.HttpResponse; import io.metersphere.api.dto.definition.response.HttpResponse;
import io.metersphere.api.dto.parse.ApiImport;
import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.service.ApiModuleService;
import io.metersphere.base.domain.ApiModule;
import io.metersphere.commons.constants.SwaggerParameterType; import io.metersphere.commons.constants.SwaggerParameterType;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.swagger.models.*; import io.swagger.models.*;
import io.swagger.models.parameters.*; import io.swagger.models.parameters.*;
import io.swagger.models.properties.*; import io.swagger.models.properties.*;
@ -28,7 +30,7 @@ public class Swagger2Parser extends ApiImportAbstractParser {
private Map<String, Model> definitions = null; private Map<String, Model> definitions = null;
@Override @Override
public ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request) { public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
Swagger swagger; Swagger swagger;
if (StringUtils.isNotBlank(request.getSwaggerUrl())) { if (StringUtils.isNotBlank(request.getSwaggerUrl())) {
swagger = new SwaggerParser().read(request.getSwaggerUrl()); swagger = new SwaggerParser().read(request.getSwaggerUrl());
@ -36,22 +38,18 @@ public class Swagger2Parser extends ApiImportAbstractParser {
swagger = new SwaggerParser().readWithInfo(getApiTestStr(source)).getSwagger(); swagger = new SwaggerParser().readWithInfo(getApiTestStr(source)).getSwagger();
} }
ApiDefinitionImport definitionImport = new ApiDefinitionImport(); ApiDefinitionImport definitionImport = new ApiDefinitionImport();
definitionImport.setResultMap(parseRequests(swagger)); this.projectId = request.getProjectId();
definitionImport.setData(parseRequests(swagger));
return definitionImport; return definitionImport;
} }
@Override private List<ApiDefinitionResult> parseRequests(Swagger swagger) {
public ApiImport parse(InputStream source, ApiTestImportRequest request) {
return null;
}
private HashMap<String, List<ApiDefinitionResult>> parseRequests(Swagger swagger) {
Map<String, Path> paths = swagger.getPaths(); Map<String, Path> paths = swagger.getPaths();
Set<String> pathNames = paths.keySet(); Set<String> pathNames = paths.keySet();
this.definitions = swagger.getDefinitions(); this.definitions = swagger.getDefinitions();
HashMap<String, List<ApiDefinitionResult>> moduleMap = new HashMap<>(); List<ApiDefinitionResult> results = new ArrayList<>();
for (String pathName : pathNames) { for (String pathName : pathNames) {
Path path = paths.get(pathName); Path path = paths.get(pathName);
@ -59,76 +57,55 @@ public class Swagger2Parser extends ApiImportAbstractParser {
Set<HttpMethod> httpMethods = operationMap.keySet(); Set<HttpMethod> httpMethods = operationMap.keySet();
for (HttpMethod method : httpMethods) { for (HttpMethod method : httpMethods) {
Operation operation = operationMap.get(method); Operation operation = operationMap.get(method);
ApiDefinitionResult apiDefinition = buildApiDefinition(operation, pathName, method.name());
MsHTTPSamplerProxy request = buildRequest(operation, pathName, method.name()); MsHTTPSamplerProxy request = buildRequest(operation, pathName, method.name());
ApiDefinitionResult apiDefinition = buildApiDefinition(request.getId(), operation, pathName, method.name());
parseParameters(operation, request); parseParameters(operation, request);
apiDefinition.setRequest(JSON.toJSONString(request)); apiDefinition.setRequest(JSON.toJSONString(request));
apiDefinition.setId(request.getId());
apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation.getResponses()))); apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation.getResponses())));
buildResultMap(moduleMap, apiDefinition, operation); buildModule(apiDefinition, operation);
results.add(apiDefinition);
} }
} }
this.definitions = null; this.definitions = null;
return moduleMap; return results;
} }
private void buildResultMap(HashMap<String, List<ApiDefinitionResult>> moduleMap, private void buildModule(ApiDefinitionResult apiDefinition, Operation operation) {
ApiDefinitionResult apiDefinition, Operation operation) {
List<String> tags = operation.getTags(); List<String> tags = operation.getTags();
if (tags != null) { if (tags != null) {
tags.forEach(tag -> { tags.forEach(tag -> {
List<ApiDefinitionResult> list = moduleMap.get(tag); apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
if (list == null) { ApiModule module = apiModuleService.getNewModule(tag, this.projectId, 1);
list = new ArrayList<>(); createModule(module);
moduleMap.put(tag, list); apiDefinition.setModuleId(module.getId());
}
list.add(apiDefinition);
}); });
} else {
List<ApiDefinitionResult> list = moduleMap.get("#default");
if (list == null) {
list = new ArrayList<>();
moduleMap.put("#default", list);
}
list.add(apiDefinition);
} }
} }
private ApiDefinitionResult buildApiDefinition(Operation operation, String path, String method) { private ApiDefinitionResult buildApiDefinition(String id, Operation operation, String path, String method) {
ApiDefinitionResult apiDefinition = new ApiDefinitionResult(); String name = "";
if (StringUtils.isNotBlank(operation.getSummary())) { if (StringUtils.isNotBlank(operation.getSummary())) {
apiDefinition.setName(operation.getSummary()); name = operation.getSummary();
} else { } else {
apiDefinition.setName(operation.getOperationId()); name = operation.getOperationId();
} }
apiDefinition.setPath(path); return buildApiDefinition(id, name, path, method);
apiDefinition.setProtocol(RequestType.HTTP);
apiDefinition.setMethod(method);
return apiDefinition;
} }
private MsHTTPSamplerProxy buildRequest(Operation operation, String path, String method) { private MsHTTPSamplerProxy buildRequest(Operation operation, String path, String method) {
MsHTTPSamplerProxy request = new MsHTTPSamplerProxy(); String name = "";
if (StringUtils.isNotBlank(operation.getSummary())) { if (StringUtils.isNotBlank(operation.getSummary())) {
request.setName(operation.getSummary()); name = operation.getSummary();
} else { } else {
request.setName(operation.getOperationId()); name = operation.getOperationId();
} }
request.setPath(path); return buildRequest(name, path, method);
request.setMethod(method);
request.setProtocol(RequestType.HTTP);
return request;
} }
private void parseParameters(Operation operation, MsHTTPSamplerProxy request) { private void parseParameters(Operation operation, MsHTTPSamplerProxy request) {
List<Parameter> parameters = operation.getParameters(); List<Parameter> parameters = operation.getParameters();
request.setId(UUID.randomUUID().toString());
request.setHeaders(new ArrayList<>());
request.setArguments(new ArrayList<>());
request.setRest(new ArrayList<>());
request.setBody(new Body());
request.getBody().setType(getBodyType(operation)); request.getBody().setType(getBodyType(operation));
// todo 路径变量 {xxx} 是否要转换 // todo 路径变量 {xxx} 是否要转换

View File

@ -323,7 +323,7 @@ public class ApiDefinitionService {
ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform()); ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform());
ApiDefinitionImport apiImport = null; ApiDefinitionImport apiImport = null;
try { try {
apiImport = Objects.requireNonNull(apiImportParser).parseApi(file == null ? null : file.getInputStream(), request); apiImport = Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request);
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);
MSException.throwException(Translator.get("parse_data_error")); MSException.throwException(Translator.get("parse_data_error"));
@ -335,30 +335,16 @@ public class ApiDefinitionService {
private void importApiTest(ApiTestImportRequest importRequest, ApiDefinitionImport apiImport) { private void importApiTest(ApiTestImportRequest importRequest, ApiDefinitionImport apiImport) {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class); ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
HashMap<String, List<ApiDefinitionResult>> resultMap = apiImport.getResultMap(); List<ApiDefinitionResult> data = apiImport.getData();
Integer batchNum = 1; for (int i = 0; i < data.size(); i++) {
for (String key : resultMap.keySet()) { ApiDefinitionResult item = data.get(i);
List<ApiDefinitionResult> apiDefinitions = resultMap.get(key); if (item.getName().length() > 255) {
ApiModule newModule = apiModuleService.getNewModule(key, importRequest.getProjectId(), 1); item.setName(item.getName().substring(0, 255));
newModule.setProtocol(RequestType.HTTP);
if (!StringUtils.equals(key, "#default")) {
apiModuleService.addNode(newModule);
} }
createTest(item, batchMapper);
apiDefinitions.forEach(item -> { if (i % 300 == 0) {
item.setProjectId(importRequest.getProjectId());
if (!StringUtils.equals(key, "#default")) {
item.setModuleId(newModule.getId());
}
item.setModulePath(importRequest.getModulePath());
item.setEnvironmentId(importRequest.getEnvironmentId());
item.setUserId(SessionUtils.getUserId());
createTest(item, batchMapper);
});
if (batchNum % 300 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();
} }
batchNum++;
} }
sqlSession.flushStatements(); sqlSession.flushStatements();
} }

View File

@ -98,6 +98,10 @@ public class ApiModuleService {
public String addNode(ApiModule node) { public String addNode(ApiModule node) {
validateNode(node); validateNode(node);
return addNodeWithoutValidate(node);
}
public String addNodeWithoutValidate(ApiModule node) {
node.setCreateTime(System.currentTimeMillis()); node.setCreateTime(System.currentTimeMillis());
node.setUpdateTime(System.currentTimeMillis()); node.setUpdateTime(System.currentTimeMillis());
node.setId(UUID.randomUUID().toString()); node.setId(UUID.randomUUID().toString());
@ -126,24 +130,28 @@ public class ApiModuleService {
private void checkApiModuleExist(ApiModule node) { private void checkApiModuleExist(ApiModule node) {
if (node.getName() != null) { if (node.getName() != null) {
ApiModuleExample example = new ApiModuleExample(); if (selectSameModule(node).size() > 0) {
ApiModuleExample.Criteria criteria = example.createCriteria();
criteria.andNameEqualTo(node.getName())
.andProjectIdEqualTo(node.getProjectId());
if (StringUtils.isNotBlank(node.getParentId())) {
criteria.andParentIdEqualTo(node.getParentId());
} else {
criteria.andParentIdIsNull();
}
if (StringUtils.isNotBlank(node.getId())) {
criteria.andIdNotEqualTo(node.getId());
}
if (apiModuleMapper.selectByExample(example).size() > 0) {
MSException.throwException(Translator.get("test_case_module_already_exists") + ": " + node.getName()); MSException.throwException(Translator.get("test_case_module_already_exists") + ": " + node.getName());
} }
} }
} }
public List<ApiModule> selectSameModule(ApiModule node) {
ApiModuleExample example = new ApiModuleExample();
ApiModuleExample.Criteria criteria = example.createCriteria();
criteria.andNameEqualTo(node.getName())
.andProjectIdEqualTo(node.getProjectId());
if (StringUtils.isNotBlank(node.getParentId())) {
criteria.andParentIdEqualTo(node.getParentId());
} else {
criteria.andParentIdIsNull();
}
if (StringUtils.isNotBlank(node.getId())) {
criteria.andIdNotEqualTo(node.getId());
}
return apiModuleMapper.selectByExample(example);
}
private List<ApiDefinitionResult> queryByModuleIds(List<String> nodeIds) { private List<ApiDefinitionResult> queryByModuleIds(List<String> nodeIds) {
ApiDefinitionRequest apiDefinitionRequest = new ApiDefinitionRequest(); ApiDefinitionRequest apiDefinitionRequest = new ApiDefinitionRequest();
apiDefinitionRequest.setModuleIds(nodeIds); apiDefinitionRequest.setModuleIds(nodeIds);

View File

@ -18,7 +18,7 @@ CREATE TABLE IF NOT EXISTS `api_definition` (
`name` varchar(255) NOT NULL COMMENT 'Test name', `name` varchar(255) NOT NULL COMMENT 'Test name',
`method` varchar(64) NOT NULL COMMENT 'method', `method` varchar(64) NOT NULL COMMENT 'method',
`protocol` varchar(255) NOT NULL COMMENT 'request protocol', `protocol` varchar(255) NOT NULL COMMENT 'request protocol',
`path` varchar(255) DEFAULT NULL COMMENT 'request path', `path` varchar(1000) DEFAULT NULL COMMENT 'request path',
`module_path` varchar(1000) COMMENT 'module path', `module_path` varchar(1000) COMMENT 'module path',
`description` varchar(255) DEFAULT NULL COMMENT 'Test description', `description` varchar(255) DEFAULT NULL COMMENT 'Test description',
`environment_id` varchar(50) DEFAULT NULL COMMENT 'environment id', `environment_id` varchar(50) DEFAULT NULL COMMENT 'environment id',

View File

@ -18,7 +18,7 @@
</el-tab-pane> </el-tab-pane>
<!--query 参数--> <!--query 参数-->
<el-tab-pane :label="$t('api_test.definition.request.query_param')" name="parameters" :disabled="request.arguments.length>1"> <el-tab-pane :label="$t('api_test.definition.request.query_param')" name="parameters">
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.query_info')" placement="top-start" slot="label"> <el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.query_info')" placement="top-start" slot="label">
<span>{{$t('api_test.definition.request.query_param')}} <span>{{$t('api_test.definition.request.query_param')}}
<div class="el-step__icon is-text ms-api-col ms-query" v-if="request.arguments.length>1"> <div class="el-step__icon is-text ms-api-col ms-query" v-if="request.arguments.length>1">