feat(接口测试): 接口定义 postman 导入
This commit is contained in:
parent
1aab595ab0
commit
036d5a5551
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,25 +15,17 @@ 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);
|
String testStr = getApiTestStr(source);
|
||||||
ApiImport apiImport = JSON.parseObject(parsePluginFormat(testStr), ApiImport.class);
|
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||||
apiImport.getScenarios().forEach(scenario -> setScenarioByRequest(scenario, request));
|
if (testObject.get("projectName") == null) {
|
||||||
return apiImport;
|
testStr = parsePluginFormat(testObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiDefinitionImport parseApi(InputStream source, ApiTestImportRequest request) {
|
|
||||||
String testStr = getApiTestStr(source);
|
|
||||||
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) {
|
|
||||||
return testStr;
|
|
||||||
} else {
|
|
||||||
//插件格式
|
//插件格式
|
||||||
JSONArray scenarios = new JSONArray();
|
JSONArray scenarios = new JSONArray();
|
||||||
testObject.keySet().forEach(scenarioName -> {
|
testObject.keySet().forEach(scenarioName -> {
|
||||||
|
@ -62,7 +53,6 @@ public class MsParser extends ApiImportAbstractParser {
|
||||||
result.put("scenarios", scenarios);
|
result.put("scenarios", scenarios);
|
||||||
return result.toJSONString();
|
return result.toJSONString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void parseBody(JSONObject requestObject) {
|
private void parseBody(JSONObject requestObject) {
|
||||||
if (requestObject.containsKey("body")) {
|
if (requestObject.containsKey("body")) {
|
||||||
|
|
|
@ -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())) {
|
||||||
|
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.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.setRaw(postmanBody.getString(bodyMode));
|
||||||
body.setType(MsRequestBodyType.RAW.value());
|
body.setType(MsRequestBodyType.RAW.value());
|
||||||
JSONObject options = postmanBody.getJSONObject("options");
|
JSONObject options = postmanBody.getJSONObject("options");
|
||||||
if (options != null) {
|
if (options != null) {
|
||||||
JSONObject raw = options.getJSONObject(PostmanRequestBodyMode.RAW.value());
|
JSONObject raw = options.getJSONObject(PostmanRequestBodyMode.RAW.value());
|
||||||
if (raw != null) {
|
if (raw != null) {
|
||||||
body.setFormat(raw.getString("language"));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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);
|
|
||||||
body.setType(MsRequestBodyType.KV.value());
|
|
||||||
body.setKvs(parseKeyValue(postmanKeyValues));
|
|
||||||
}
|
}
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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} 是否要转换
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
createTest(item, batchMapper);
|
||||||
});
|
if (i % 300 == 0) {
|
||||||
if (batchNum % 300 == 0) {
|
|
||||||
sqlSession.flushStatements();
|
sqlSession.flushStatements();
|
||||||
}
|
}
|
||||||
batchNum++;
|
|
||||||
}
|
}
|
||||||
sqlSession.flushStatements();
|
sqlSession.flushStatements();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,6 +130,13 @@ public class ApiModuleService {
|
||||||
|
|
||||||
private void checkApiModuleExist(ApiModule node) {
|
private void checkApiModuleExist(ApiModule node) {
|
||||||
if (node.getName() != null) {
|
if (node.getName() != null) {
|
||||||
|
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 example = new ApiModuleExample();
|
||||||
ApiModuleExample.Criteria criteria = example.createCriteria();
|
ApiModuleExample.Criteria criteria = example.createCriteria();
|
||||||
criteria.andNameEqualTo(node.getName())
|
criteria.andNameEqualTo(node.getName())
|
||||||
|
@ -138,10 +149,7 @@ public class ApiModuleService {
|
||||||
if (StringUtils.isNotBlank(node.getId())) {
|
if (StringUtils.isNotBlank(node.getId())) {
|
||||||
criteria.andIdNotEqualTo(node.getId());
|
criteria.andIdNotEqualTo(node.getId());
|
||||||
}
|
}
|
||||||
if (apiModuleMapper.selectByExample(example).size() > 0) {
|
return apiModuleMapper.selectByExample(example);
|
||||||
MSException.throwException(Translator.get("test_case_module_already_exists") + ": " + node.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ApiDefinitionResult> queryByModuleIds(List<String> nodeIds) {
|
private List<ApiDefinitionResult> queryByModuleIds(List<String> nodeIds) {
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in New Issue