Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
6ce41bdbde
|
@ -3,7 +3,6 @@ package io.metersphere.api.dto.definition.parse;
|
|||
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
|
@ -11,5 +10,4 @@ public class ApiDefinitionImport {
|
|||
private String projectName;
|
||||
private String protocol;
|
||||
private List<ApiDefinitionResult> data;
|
||||
private HashMap<String, List<ApiDefinitionResult>> resultMap;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ public class PostmanKeyValue {
|
|||
private String key;
|
||||
private String value;
|
||||
private String type;
|
||||
private String description;
|
||||
private String contentType;
|
||||
|
||||
public PostmanKeyValue() {
|
||||
}
|
||||
|
|
|
@ -20,22 +20,23 @@ public class KeyValue {
|
|||
private boolean required;
|
||||
|
||||
public KeyValue() {
|
||||
this.enable = true;
|
||||
this.required = true;
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public KeyValue(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.enable = true;
|
||||
this.required = true;
|
||||
this(name, value, null);
|
||||
}
|
||||
|
||||
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.value = value;
|
||||
this.enable = true;
|
||||
this.description = description;
|
||||
this.contentType = contentType;
|
||||
this.enable = true;
|
||||
this.required = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
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.Scenario;
|
||||
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.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
@ -16,9 +24,13 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||
|
||||
protected String projectId;
|
||||
protected ApiModuleService apiModuleService;
|
||||
|
||||
protected String getApiTestStr(InputStream source) {
|
||||
StringBuilder testStr = null;
|
||||
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) {
|
||||
// addHeader(request, "Content-Type", contentType);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,9 @@ package io.metersphere.api.parse;
|
|||
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.parse.ApiImport;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface ApiImportParser {
|
||||
ApiImport parse(InputStream source, ApiTestImportRequest request);
|
||||
ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request);
|
||||
|
||||
ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request);
|
||||
}
|
||||
|
|
|
@ -5,66 +5,94 @@ 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.ApiDefinitionResult;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.parse.ApiImport;
|
||||
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.commons.constants.MsRequestBodyType;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import io.metersphere.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MsParser extends ApiImportAbstractParser {
|
||||
|
||||
@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);
|
||||
ApiDefinitionImport apiImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
|
||||
return apiImport;
|
||||
}
|
||||
|
||||
private String parsePluginFormat(String testStr) {
|
||||
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||
if (testObject.get("scenarios") != null) {
|
||||
return testStr;
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
this.projectId = request.getProjectId();
|
||||
if (testObject.get("projectName") != null) {
|
||||
return parseMsFormat(testStr, request);
|
||||
} else {
|
||||
//插件格式
|
||||
JSONArray scenarios = new JSONArray();
|
||||
testObject.keySet().forEach(scenarioName -> {
|
||||
JSONObject scenario = new JSONObject();
|
||||
scenario.put("name", scenarioName);
|
||||
JSONArray requestsObjects = new JSONArray();
|
||||
JSONObject requestsObject = testObject.getJSONObject(scenarioName);
|
||||
requestsObject.keySet().forEach(requestName -> {
|
||||
JSONObject requestObject = new JSONObject(true);
|
||||
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)));
|
||||
requestObject.put("name", requestName);
|
||||
parseBody(requestObject);
|
||||
requestsObjects.add(requestObject);
|
||||
});
|
||||
scenario.put("requests", requestsObjects);
|
||||
scenarios.add(scenario);
|
||||
});
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("scenarios", scenarios);
|
||||
return result.toJSONString();
|
||||
return parsePluginFormat(testObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseBody(JSONObject requestObject) {
|
||||
private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
|
||||
|
||||
ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
|
||||
List<ApiDefinitionResult> data = apiDefinitionImport.getData();
|
||||
data.forEach(apiDefinition -> {
|
||||
String id = UUID.randomUUID().toString();
|
||||
apiDefinition.setModuleId(null);
|
||||
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));
|
||||
});
|
||||
return apiDefinitionImport;
|
||||
}
|
||||
|
||||
private ApiDefinitionImport parsePluginFormat(JSONObject testObject) {
|
||||
List<ApiDefinitionResult> results = new ArrayList<>();
|
||||
ApiDefinitionImport apiImport = new ApiDefinitionImport();
|
||||
apiImport.setProtocol(RequestType.HTTP);
|
||||
apiImport.setData(results);
|
||||
testObject.keySet().forEach(tag -> {
|
||||
ApiModule module = apiModuleService.getNewModule(tag, this.projectId, 1);
|
||||
createModule(module);
|
||||
JSONObject requests = testObject.getJSONObject(tag);
|
||||
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);
|
||||
ApiDefinitionResult apiDefinition = buildApiDefinition(request.getId(), requestName, path, method);
|
||||
apiDefinition.setModuleId(module.getId());
|
||||
apiDefinition.setProjectId(this.projectId);
|
||||
|
||||
parseBody(requestObject, request.getBody());
|
||||
parseHeader(requestObject, request.getHeaders());
|
||||
apiDefinition.setRequest(JSONObject.toJSONString(request));
|
||||
results.add(apiDefinition);
|
||||
});
|
||||
});
|
||||
return apiImport;
|
||||
}
|
||||
|
||||
private void parseHeader(JSONObject requestObject, List<KeyValue> 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) {
|
||||
|
@ -75,25 +103,18 @@ public class MsParser extends ApiImportAbstractParser {
|
|||
String tmp = bodies.getString(i);
|
||||
bodyStr.append(tmp);
|
||||
}
|
||||
JSONObject bodyObject = new JSONObject();
|
||||
bodyObject.put("raw", bodyStr);
|
||||
bodyObject.put("type", MsRequestBodyType.RAW.value());
|
||||
requestObject.put("body", bodyObject);
|
||||
msBody.setType(Body.RAW);
|
||||
msBody.setRaw(bodyStr.toString());
|
||||
}
|
||||
} else if (body instanceof JSONObject) {
|
||||
JSONObject bodyObj = requestObject.getJSONObject("body");
|
||||
if (bodyObj != null) {
|
||||
JSONArray kvs = new JSONArray();
|
||||
ArrayList<KeyValue> kvs = new ArrayList<>();
|
||||
bodyObj.keySet().forEach(key -> {
|
||||
JSONObject kv = new JSONObject();
|
||||
kv.put("name", key);
|
||||
kv.put("value", bodyObj.getString(key));
|
||||
kvs.add(kv);
|
||||
kvs.add(new KeyValue(key, bodyObj.getString(key)));
|
||||
});
|
||||
JSONObject bodyRes = new JSONObject();
|
||||
bodyRes.put("kvs", kvs);
|
||||
bodyRes.put("type", MsRequestBodyType.KV.value());
|
||||
requestObject.put("body", bodyRes);
|
||||
msBody.setKvs(kvs);
|
||||
msBody.setType(Body.WWW_FROM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,180 +5,135 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||
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.parse.ApiImport;
|
||||
import io.metersphere.api.dto.parse.postman.*;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.api.dto.scenario.Scenario;
|
||||
import io.metersphere.api.dto.scenario.request.HttpRequest;
|
||||
import io.metersphere.api.dto.scenario.request.Request;
|
||||
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.MsRequestBodyType;
|
||||
import io.metersphere.commons.constants.PostmanRequestBodyMode;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PostmanParser extends ApiImportAbstractParser {
|
||||
|
||||
@Override
|
||||
public ApiImport 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) {
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
this.projectId = request.getProjectId();
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
|
||||
List<PostmanKeyValue> variables = postmanCollection.getVariable();
|
||||
ApiDefinitionImport apiImport = new ApiDefinitionImport();
|
||||
List<ApiDefinitionResult> requests = new ArrayList<>();
|
||||
|
||||
parseItem(postmanCollection.getItem(), variables, requests);
|
||||
apiImport.setData(requests);
|
||||
List<ApiDefinitionResult> results = new ArrayList<>();
|
||||
parseItem(postmanCollection.getItem(), variables, results, buildModule(postmanCollection.getInfo().getName(), null));
|
||||
apiImport.setData(results);
|
||||
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) {
|
||||
List<PostmanItem> childItems = item.getItem();
|
||||
if (childItems != null) {
|
||||
parseItem(childItems, variables, scenarios);
|
||||
ApiModule module = buildModule(item.getName(), parentModule);
|
||||
parseItem(childItems, variables, results, module);
|
||||
} else {
|
||||
ApiDefinitionResult request = parsePostman(item);
|
||||
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) {
|
||||
PostmanRequest requestDesc = requestItem.getRequest();
|
||||
if (requestDesc == null) {
|
||||
return null;
|
||||
}
|
||||
requestDesc.getAuth(); // todo 认证方式等待优化
|
||||
PostmanUrl url = requestDesc.getUrl();
|
||||
ApiDefinitionResult request = new ApiDefinitionResult();
|
||||
request.setName(requestItem.getName());
|
||||
request.setPath(url.getRaw());
|
||||
request.setMethod(requestDesc.getMethod());
|
||||
request.setProtocol(RequestType.HTTP);
|
||||
MsHTTPSamplerProxy requestElement = new MsHTTPSamplerProxy();
|
||||
requestElement.setName(requestItem.getName() + "Postman MHTTPSamplerProxy");
|
||||
requestElement.setBody(parseBody(requestDesc));
|
||||
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;
|
||||
MsHTTPSamplerProxy request = buildRequest(requestItem.getName(), url.getRaw(), requestDesc.getMethod());
|
||||
ApiDefinitionResult apiDefinition =
|
||||
buildApiDefinition(request.getId(), requestItem.getName(), url.getRaw(), requestDesc.getMethod());
|
||||
parseBody(request.getBody(), requestDesc);
|
||||
request.setArguments(parseKeyValue(url.getQuery()));
|
||||
request.setHeaders(parseKeyValue(requestDesc.getHeader()));
|
||||
apiDefinition.setRequest(JSON.toJSONString(request));
|
||||
return apiDefinition;
|
||||
}
|
||||
|
||||
|
||||
private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) {
|
||||
if (postmanKeyValues == null) {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
private void parseItem(List<PostmanItem> items, Scenario scenario, List<PostmanKeyValue> variables, List<Scenario> scenarios) {
|
||||
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();
|
||||
private void parseBody(Body body, PostmanRequest requestDesc) {
|
||||
JSONObject postmanBody = requestDesc.getBody();
|
||||
if (postmanBody == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
String bodyMode = postmanBody.getString("mode");
|
||||
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||
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) {
|
||||
body.setFormat(raw.getString("language"));
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
parseRawBody(body, postmanBody, bodyMode);
|
||||
} else if (StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
|
||||
body.setType(MsRequestBodyType.KV.value());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.request.sampler.MsHTTPSamplerProxy;
|
||||
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.KeyValue;
|
||||
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.utils.CommonBeanFactory;
|
||||
import io.swagger.models.*;
|
||||
import io.swagger.models.parameters.*;
|
||||
import io.swagger.models.properties.*;
|
||||
|
@ -28,7 +30,7 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
private Map<String, Model> definitions = null;
|
||||
|
||||
@Override
|
||||
public ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request) {
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
Swagger swagger;
|
||||
if (StringUtils.isNotBlank(request.getSwaggerUrl())) {
|
||||
swagger = new SwaggerParser().read(request.getSwaggerUrl());
|
||||
|
@ -36,22 +38,18 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
swagger = new SwaggerParser().readWithInfo(getApiTestStr(source)).getSwagger();
|
||||
}
|
||||
ApiDefinitionImport definitionImport = new ApiDefinitionImport();
|
||||
definitionImport.setResultMap(parseRequests(swagger));
|
||||
this.projectId = request.getProjectId();
|
||||
definitionImport.setData(parseRequests(swagger));
|
||||
return definitionImport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private HashMap<String, List<ApiDefinitionResult>> parseRequests(Swagger swagger) {
|
||||
private List<ApiDefinitionResult> parseRequests(Swagger swagger) {
|
||||
Map<String, Path> paths = swagger.getPaths();
|
||||
Set<String> pathNames = paths.keySet();
|
||||
|
||||
this.definitions = swagger.getDefinitions();
|
||||
|
||||
HashMap<String, List<ApiDefinitionResult>> moduleMap = new HashMap<>();
|
||||
List<ApiDefinitionResult> results = new ArrayList<>();
|
||||
|
||||
for (String pathName : pathNames) {
|
||||
Path path = paths.get(pathName);
|
||||
|
@ -59,76 +57,55 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
Set<HttpMethod> httpMethods = operationMap.keySet();
|
||||
for (HttpMethod method : httpMethods) {
|
||||
Operation operation = operationMap.get(method);
|
||||
|
||||
ApiDefinitionResult apiDefinition = buildApiDefinition(operation, pathName, method.name());
|
||||
MsHTTPSamplerProxy request = buildRequest(operation, pathName, method.name());
|
||||
ApiDefinitionResult apiDefinition = buildApiDefinition(request.getId(), operation, pathName, method.name());
|
||||
parseParameters(operation, request);
|
||||
apiDefinition.setRequest(JSON.toJSONString(request));
|
||||
apiDefinition.setId(request.getId());
|
||||
apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation.getResponses())));
|
||||
buildResultMap(moduleMap, apiDefinition, operation);
|
||||
buildModule(apiDefinition, operation);
|
||||
results.add(apiDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
this.definitions = null;
|
||||
return moduleMap;
|
||||
return results;
|
||||
}
|
||||
|
||||
private void buildResultMap(HashMap<String, List<ApiDefinitionResult>> moduleMap,
|
||||
ApiDefinitionResult apiDefinition, Operation operation) {
|
||||
private void buildModule(ApiDefinitionResult apiDefinition, Operation operation) {
|
||||
List<String> tags = operation.getTags();
|
||||
if (tags != null) {
|
||||
tags.forEach(tag -> {
|
||||
List<ApiDefinitionResult> list = moduleMap.get(tag);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
moduleMap.put(tag, list);
|
||||
}
|
||||
list.add(apiDefinition);
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
ApiModule module = apiModuleService.getNewModule(tag, this.projectId, 1);
|
||||
createModule(module);
|
||||
apiDefinition.setModuleId(module.getId());
|
||||
});
|
||||
} 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) {
|
||||
ApiDefinitionResult apiDefinition = new ApiDefinitionResult();
|
||||
private ApiDefinitionResult buildApiDefinition(String id, Operation operation, String path, String method) {
|
||||
String name = "";
|
||||
if (StringUtils.isNotBlank(operation.getSummary())) {
|
||||
apiDefinition.setName(operation.getSummary());
|
||||
name = operation.getSummary();
|
||||
} else {
|
||||
apiDefinition.setName(operation.getOperationId());
|
||||
name = operation.getOperationId();
|
||||
}
|
||||
apiDefinition.setPath(path);
|
||||
apiDefinition.setProtocol(RequestType.HTTP);
|
||||
apiDefinition.setMethod(method);
|
||||
return apiDefinition;
|
||||
return buildApiDefinition(id, name, path, method);
|
||||
}
|
||||
|
||||
private MsHTTPSamplerProxy buildRequest(Operation operation, String path, String method) {
|
||||
MsHTTPSamplerProxy request = new MsHTTPSamplerProxy();
|
||||
String name = "";
|
||||
if (StringUtils.isNotBlank(operation.getSummary())) {
|
||||
request.setName(operation.getSummary());
|
||||
name = operation.getSummary();
|
||||
} else {
|
||||
request.setName(operation.getOperationId());
|
||||
name = operation.getOperationId();
|
||||
}
|
||||
request.setPath(path);
|
||||
request.setMethod(method);
|
||||
request.setProtocol(RequestType.HTTP);
|
||||
return request;
|
||||
return buildRequest(name, path, method);
|
||||
}
|
||||
|
||||
private void parseParameters(Operation operation, MsHTTPSamplerProxy request) {
|
||||
|
||||
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));
|
||||
|
||||
// todo 路径变量 {xxx} 是否要转换
|
||||
|
@ -179,9 +156,9 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
case "application/xml":
|
||||
bodyType = Body.XML;
|
||||
break;
|
||||
// case "": //todo binary 啥类型
|
||||
// bodyType = Body.BINARY;
|
||||
// break;
|
||||
case "":
|
||||
bodyType = Body.BINARY;
|
||||
break;
|
||||
default:
|
||||
bodyType = Body.RAW;
|
||||
}
|
||||
|
@ -258,7 +235,6 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
refSet.add(simpleRef);
|
||||
if (model != null) {
|
||||
JSONObject bodyParameters = getBodyParameters(model.getProperties(), refSet);
|
||||
//body.setRaw(bodyParameters.toJSONString());
|
||||
return bodyParameters.toJSONString();
|
||||
}
|
||||
} else if (schema instanceof ArrayModel) {
|
||||
|
@ -273,7 +249,6 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
Model model = definitions.get(simpleRef);
|
||||
JSONArray propertyList = new JSONArray();
|
||||
propertyList.add(getBodyParameters(model.getProperties(), refSet));
|
||||
// body.setRaw(propertyList.toString());
|
||||
return propertyList.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ public class ApiDefinitionService {
|
|||
ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform());
|
||||
ApiDefinitionImport apiImport = null;
|
||||
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) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("parse_data_error"));
|
||||
|
@ -335,30 +335,16 @@ public class ApiDefinitionService {
|
|||
private void importApiTest(ApiTestImportRequest importRequest, ApiDefinitionImport apiImport) {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
|
||||
HashMap<String, List<ApiDefinitionResult>> resultMap = apiImport.getResultMap();
|
||||
Integer batchNum = 1;
|
||||
for (String key : resultMap.keySet()) {
|
||||
List<ApiDefinitionResult> apiDefinitions = resultMap.get(key);
|
||||
ApiModule newModule = apiModuleService.getNewModule(key, importRequest.getProjectId(), 1);
|
||||
newModule.setProtocol(RequestType.HTTP);
|
||||
if (!StringUtils.equals(key, "#default")) {
|
||||
apiModuleService.addNode(newModule);
|
||||
List<ApiDefinitionResult> data = apiImport.getData();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ApiDefinitionResult item = data.get(i);
|
||||
if (item.getName().length() > 255) {
|
||||
item.setName(item.getName().substring(0, 255));
|
||||
}
|
||||
|
||||
apiDefinitions.forEach(item -> {
|
||||
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) {
|
||||
createTest(item, batchMapper);
|
||||
if (i % 300 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
batchNum++;
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
|
|
@ -98,6 +98,10 @@ public class ApiModuleService {
|
|||
|
||||
public String addNode(ApiModule node) {
|
||||
validateNode(node);
|
||||
return addNodeWithoutValidate(node);
|
||||
}
|
||||
|
||||
public String addNodeWithoutValidate(ApiModule node) {
|
||||
node.setCreateTime(System.currentTimeMillis());
|
||||
node.setUpdateTime(System.currentTimeMillis());
|
||||
node.setId(UUID.randomUUID().toString());
|
||||
|
@ -126,24 +130,28 @@ public class ApiModuleService {
|
|||
|
||||
private void checkApiModuleExist(ApiModule node) {
|
||||
if (node.getName() != null) {
|
||||
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());
|
||||
}
|
||||
if (apiModuleMapper.selectByExample(example).size() > 0) {
|
||||
if (selectSameModule(node).size() > 0) {
|
||||
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) {
|
||||
ApiDefinitionRequest apiDefinitionRequest = new ApiDefinitionRequest();
|
||||
apiDefinitionRequest.setModuleIds(nodeIds);
|
||||
|
|
|
@ -18,7 +18,7 @@ CREATE TABLE IF NOT EXISTS `api_definition` (
|
|||
`name` varchar(255) NOT NULL COMMENT 'Test name',
|
||||
`method` varchar(64) NOT NULL COMMENT 'method',
|
||||
`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',
|
||||
`description` varchar(255) DEFAULT NULL COMMENT 'Test description',
|
||||
`environment_id` varchar(50) DEFAULT NULL COMMENT 'environment id',
|
||||
|
|
|
@ -86,6 +86,7 @@ export default {
|
|||
background-color: rgb(44, 42, 72);
|
||||
color: rgb(245, 245, 245);
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</el-tab-pane>
|
||||
|
||||
<!--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">
|
||||
<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">
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
.el-menu >>> .el-menu-item {
|
||||
box-sizing: border-box;
|
||||
height: 37px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8a972a198775b3783ed6e4cef27197e53d1ebdc8
|
||||
Subproject commit a22a3005d9bd254793fcf634d72539cbdf31be3a
|
Loading…
Reference in New Issue