feat(接口测试): jmx导入
This commit is contained in:
parent
3710ed3370
commit
68276ef05d
|
@ -123,6 +123,7 @@ module_not_null=所属模块不能为空格
|
|||
user_not_exists=该项目下无该用户
|
||||
test_case_already_exists=该项目下已存在该测试用例
|
||||
parse_data_error=解析数据出错
|
||||
parse_empty_data=未解析到数据
|
||||
missing_header_information=缺少头部信息
|
||||
test_case_exist=该项目下已存在用例:
|
||||
node_deep_limit=节点深度不超过8层!
|
||||
|
|
|
@ -123,6 +123,7 @@ module_starts_with=The module must start with '/'
|
|||
user_not_exists=The user in this project is not exists
|
||||
test_case_already_exists=The test case in this project is exists
|
||||
parse_data_error=Parse data error
|
||||
parse_empty_data=Parse empty data
|
||||
missing_header_information=Missing header information
|
||||
test_case_exist=A test case already exists under this project:
|
||||
node_deep_limit=The node depth does not exceed 8 layers!
|
||||
|
|
|
@ -124,6 +124,7 @@ module_starts_with=所属模块必须以'/'开始
|
|||
user_not_exists=该项目下无该用户
|
||||
test_case_already_exists=该项目下已存在该测试用例
|
||||
parse_data_error=解析数据出错
|
||||
parse_empty_data=未解析到数据
|
||||
missing_header_information=缺少头部信息
|
||||
test_case_exist=该项目下已存在用例:
|
||||
node_deep_limit=节点深度不超过8层!
|
||||
|
|
|
@ -124,6 +124,7 @@ module_starts_with=所屬模塊必須以'/'開始
|
|||
user_not_exists=該項目下無該用戶
|
||||
test_case_already_exists=該項目下已存在該測試用例
|
||||
parse_data_error=解析數據出錯
|
||||
parse_empty_data=未解析到数据
|
||||
missing_header_information=缺少頭部信息
|
||||
test_case_exist=該項目下已存在用例:
|
||||
node_deep_limit=節點深度不超過8層!
|
||||
|
|
|
@ -312,7 +312,7 @@ public class ApiDefinitionController {
|
|||
@PostMapping(value = "/export/{type}")
|
||||
@Operation(summary = "接口测试-接口管理-导出接口定义")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_EXPORT)
|
||||
public ApiExportResponse export(@RequestBody ApiDefinitionBatchRequest request, @PathVariable String type) {
|
||||
public ApiExportResponse export(@RequestBody ApiDefinitionBatchExportRequest request, @PathVariable String type) {
|
||||
return apiDefinitionExportService.export(request, type, SessionUtils.getUserId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.api.dto.converter;
|
|||
import io.metersphere.api.dto.definition.ApiDefinitionMockDTO;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -17,7 +18,7 @@ public class ApiImportDataAnalysisResult {
|
|||
|
||||
// 新增接口数据
|
||||
List<ApiDefinitionDetail> insertApiList = new ArrayList<>();
|
||||
// 存在的接口数据. Map<导入的接口 , 已存在的接口>
|
||||
// 存在的接口数据
|
||||
List<ExistenceApiDefinitionDetail> existenceApiList = new ArrayList<>();
|
||||
// 接口的用例数据
|
||||
Map<String, List<ApiTestCaseDTO>> apiIdAndTestCaseMap = new HashMap<>();
|
||||
|
@ -27,4 +28,8 @@ public class ApiImportDataAnalysisResult {
|
|||
public void addExistenceApi(ApiDefinitionDetail importApi, ApiDefinitionDetail exportApi) {
|
||||
this.existenceApiList.add(new ExistenceApiDefinitionDetail(importApi, exportApi));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return CollectionUtils.isEmpty(insertApiList) && CollectionUtils.isEmpty(existenceApiList);
|
||||
}
|
||||
}
|
|
@ -20,4 +20,14 @@ public class ApiImportFileParseResult {
|
|||
private Map<String, List<ApiTestCaseDTO>> caseMap = new HashMap<>();
|
||||
// mock数据
|
||||
private Map<String, List<ApiDefinitionMockDTO>> mockMap = new HashMap<>();
|
||||
|
||||
public List<String> getApiProtocols() {
|
||||
List<String> protocols = new ArrayList<>();
|
||||
for (ApiDefinitionDetail apiDefinitionDetail : data) {
|
||||
if (!protocols.contains(apiDefinitionDetail.getProtocol())) {
|
||||
protocols.add(apiDefinitionDetail.getProtocol());
|
||||
}
|
||||
}
|
||||
return protocols;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package io.metersphere.api.dto.definition;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lan
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ApiDefinitionBatchExportRequest extends ApiDefinitionBatchRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@Schema(description = "是否同步导出接口用例")
|
||||
private boolean exportApiCase;
|
||||
|
||||
@Schema(description = "是否同步导出接口Mock")
|
||||
private boolean exportApiMock;
|
||||
|
||||
@Schema(description = "排序字段(model中的字段 : asc/desc)")
|
||||
private Map<@Valid @Pattern(regexp = "^[A-Za-z]+$") String, @Valid @NotBlank String> sort;
|
||||
|
||||
public String getSortString() {
|
||||
if (sort == null || sort.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, String> entry : sort.entrySet()) {
|
||||
String column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
|
||||
sb.append(column)
|
||||
.append(StringUtils.SPACE)
|
||||
.append(StringUtils.equalsIgnoreCase(entry.getValue(), "DESC") ? "DESC" : "ASC")
|
||||
.append(",");
|
||||
}
|
||||
return sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
}
|
|
@ -32,10 +32,4 @@ public class ApiDefinitionBatchRequest extends TableBatchProcessDTO implements S
|
|||
|
||||
@Schema(description = "模块ID(根据模块树查询时要把当前节点以及子节点都放在这里。)")
|
||||
private List<@NotBlank String> moduleIds;
|
||||
|
||||
@Schema(description = "是否同步导出接口用例")
|
||||
private boolean exportApiCase;
|
||||
|
||||
@Schema(description = "是否同步导出接口Mock")
|
||||
private boolean exportApiMock;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ public interface ExtApiDefinitionMapper {
|
|||
|
||||
List<String> getIds(@Param("request") TableBatchProcessDTO request, @Param("projectId") String projectId, @Param("protocols") List<String> protocols, @Param("deleted") boolean deleted);
|
||||
|
||||
List<String> getIdsBySort(@Param("request") TableBatchProcessDTO request, @Param("projectId") String projectId, @Param("protocols") List<String> protocols, @Param("orderColumns") String orderColumns);
|
||||
|
||||
List<String> getRefIds(@Param("ids") List<String> ids, @Param("deleted") boolean deleted);
|
||||
|
||||
List<String> getIdsByRefId(@Param("refIds") List<String> refIds, @Param("deleted") boolean deleted);
|
||||
|
|
|
@ -89,6 +89,28 @@
|
|||
<include refid="queryWhereConditionByBaseQueryRequest"/>
|
||||
</select>
|
||||
|
||||
<select id="getIdsBySort" resultType="java.lang.String">
|
||||
SELECT id
|
||||
FROM api_definition
|
||||
where project_id = #{projectId} and deleted is false
|
||||
<if test="protocols != null and protocols.size() > 0">
|
||||
AND protocol in
|
||||
<foreach collection="protocols" item="protocol" separator="," open="(" close=")">
|
||||
#{protocol}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.moduleIds != null and request.moduleIds.size() != 0">
|
||||
AND module_id IN
|
||||
<foreach collection="request.moduleIds" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<include refid="queryWhereConditionByBaseQueryRequest"/>
|
||||
<if test="orderColumns != null">
|
||||
ORDER BY #{orderColumns}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getRefIds" resultType="java.lang.String">
|
||||
SELECT
|
||||
|
|
|
@ -30,8 +30,4 @@ public interface ApiDefinitionImportParser<T> {
|
|||
*/
|
||||
ApiImportDataAnalysisResult generateInsertAndUpdateData(ApiImportFileParseResult importParser, List<ApiDefinitionDetail> existenceApiDefinitionList);
|
||||
|
||||
/**
|
||||
* 获取解析协议类型
|
||||
*/
|
||||
String getParseProtocol();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package io.metersphere.api.parser;
|
||||
|
||||
import io.metersphere.api.constants.ApiImportPlatform;
|
||||
import io.metersphere.api.parser.api.HarParserApiDefinition;
|
||||
import io.metersphere.api.parser.api.MetersphereParserApiDefinition;
|
||||
import io.metersphere.api.parser.api.PostmanParserApiDefinition;
|
||||
import io.metersphere.api.parser.api.Swagger3ParserApiDefinition;
|
||||
import io.metersphere.api.parser.api.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ImportParserFactory {
|
||||
|
@ -17,6 +14,8 @@ public class ImportParserFactory {
|
|||
return new MetersphereParserApiDefinition();
|
||||
} else if (StringUtils.equalsIgnoreCase(ApiImportPlatform.Har.name(), platform)) {
|
||||
return new HarParserApiDefinition();
|
||||
} else if (StringUtils.equalsIgnoreCase(ApiImportPlatform.Jmeter.name(), platform)) {
|
||||
return new JmeterParserApiDefinition();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -270,33 +270,6 @@ public class HarParserApiDefinition extends HttpApiDefinitionImportAbstractParse
|
|||
|
||||
return resultList;
|
||||
}
|
||||
// private void addBodyHeader(MsHTTPElement request) {
|
||||
// String contentType = StringUtils.EMPTY;
|
||||
// if (request.getBody() != null && StringUtils.isNotBlank(request.getBody().getType())) {
|
||||
// switch (request.getBody().getType()) {
|
||||
// case Body.WWW_FROM:
|
||||
// contentType = "application/x-www-form-urlencoded";
|
||||
// break;
|
||||
// case Body.JSON_STR:
|
||||
// contentType = "application/json";
|
||||
// break;
|
||||
// case Body.XML:
|
||||
// contentType = "application/xml";
|
||||
// break;
|
||||
// case Body.BINARY:
|
||||
// contentType = "application/octet-stream";
|
||||
// break;
|
||||
// }
|
||||
// List<KeyValue> headers = request.getHeaders();
|
||||
// if (headers == null) {
|
||||
// headers = new ArrayList<>();
|
||||
// request.setHeaders(headers);
|
||||
// }
|
||||
// if (StringUtils.isNotEmpty(contentType)) {
|
||||
// addContentType(request.getHeaders(), contentType);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void parseParameters(HarRequest harRequest, MsHTTPElement request) {
|
||||
List<HarQueryParam> queryStringList = harRequest.queryString;
|
||||
|
|
|
@ -12,9 +12,9 @@ import io.metersphere.api.dto.request.http.MsHTTPElement;
|
|||
import io.metersphere.api.dto.request.http.body.*;
|
||||
import io.metersphere.api.parser.ApiDefinitionImportParser;
|
||||
import io.metersphere.project.dto.environment.auth.NoAuth;
|
||||
import io.metersphere.project.dto.environment.http.HttpConfig;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -30,11 +30,6 @@ import java.util.stream.Collectors;
|
|||
|
||||
public abstract class HttpApiDefinitionImportAbstractParser<T> implements ApiDefinitionImportParser<T> {
|
||||
|
||||
@Override
|
||||
public String getParseProtocol() {
|
||||
return HttpConfig.HttpProtocolType.HTTP.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiImportDataAnalysisResult generateInsertAndUpdateData(ApiImportFileParseResult importParser, List<ApiDefinitionDetail> existenceApiDefinitionList) {
|
||||
// API类型,通过 Method & Path 组合判断,接口是否存在
|
||||
|
@ -62,16 +57,6 @@ public abstract class HttpApiDefinitionImportAbstractParser<T> implements ApiDef
|
|||
return insertAndUpdateData;
|
||||
}
|
||||
|
||||
public String getUniqueName(String originalName, List<String> existenceNameList) {
|
||||
String returnName = originalName;
|
||||
int index = 1;
|
||||
while (existenceNameList.contains(returnName)) {
|
||||
returnName = originalName + " - " + index;
|
||||
index++;
|
||||
}
|
||||
return returnName;
|
||||
}
|
||||
|
||||
protected String getApiTestStr(InputStream source) {
|
||||
StringBuilder testStr = null;
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
|
||||
|
@ -91,6 +76,7 @@ public abstract class HttpApiDefinitionImportAbstractParser<T> implements ApiDef
|
|||
|
||||
protected ApiDefinitionDetail buildApiDefinition(String name, String path, String method, String modulePath, ImportRequest importRequest) {
|
||||
ApiDefinitionDetail apiDefinition = new ApiDefinitionDetail();
|
||||
apiDefinition.setId(IDGenerator.nextStr());
|
||||
apiDefinition.setName(name);
|
||||
apiDefinition.setPath(formatPath(path));
|
||||
apiDefinition.setProtocol(importRequest.getProtocol());
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
package io.metersphere.api.parser.api;
|
||||
|
||||
import io.metersphere.api.constants.ApiConstants;
|
||||
import io.metersphere.api.domain.ApiDefinition;
|
||||
import io.metersphere.api.dto.converter.ApiDefinitionDetail;
|
||||
import io.metersphere.api.dto.converter.ApiImportDataAnalysisResult;
|
||||
import io.metersphere.api.dto.converter.ApiImportFileParseResult;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||
import io.metersphere.api.dto.request.ImportRequest;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.parser.ApiDefinitionImportParser;
|
||||
import io.metersphere.api.parser.ms.MsTestElementParser;
|
||||
import io.metersphere.api.utils.ApiDefinitionImportUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsProtocolTestElement;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.dto.ProtocolDTO;
|
||||
import io.metersphere.system.service.ApiPluginService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JmeterParserApiDefinition implements ApiDefinitionImportParser<ApiImportFileParseResult> {
|
||||
|
||||
|
||||
@Override
|
||||
public ApiImportFileParseResult parse(InputStream inputSource, ImportRequest request) throws Exception {
|
||||
try {
|
||||
Object scriptWrapper = SaveService.loadElement(inputSource);
|
||||
HashTree hashTree = this.getHashTree(scriptWrapper);
|
||||
MsTestElementParser parser = new MsTestElementParser();
|
||||
AbstractMsTestElement msTestElement = parser.parse(hashTree);
|
||||
List<AbstractMsProtocolTestElement> msElement = parser.getAbstractMsProtocolTestElement(msTestElement);
|
||||
LinkedHashMap<ApiDefinitionDetail, List<ApiTestCaseDTO>> allImportDetails = this.parseImportFile(request.getProjectId(), msElement);
|
||||
return this.genApiDefinitionImport(allImportDetails);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
throw new MSException("当前JMX版本不兼容");
|
||||
}
|
||||
}
|
||||
|
||||
private ApiImportFileParseResult genApiDefinitionImport(LinkedHashMap<ApiDefinitionDetail, List<ApiTestCaseDTO>> allImportDetails) {
|
||||
Map<ApiDefinitionDetail, List<ApiTestCaseDTO>> groupWithUniqueIdentification = this.mergeApiCaseWithUniqueIdentification(allImportDetails);
|
||||
ApiImportFileParseResult returnDTO = new ApiImportFileParseResult();
|
||||
groupWithUniqueIdentification.forEach((definitionImportDetail, caseData) -> {
|
||||
String apiID = IDGenerator.nextStr();
|
||||
definitionImportDetail.setId(apiID);
|
||||
returnDTO.getData().add(definitionImportDetail);
|
||||
caseData.forEach(item -> {
|
||||
item.setId(IDGenerator.nextStr());
|
||||
item.setApiDefinitionId(apiID);
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(caseData)) {
|
||||
returnDTO.getCaseMap().put(apiID, caseData);
|
||||
}
|
||||
});
|
||||
|
||||
return returnDTO;
|
||||
}
|
||||
|
||||
private Map<ApiDefinitionDetail, List<ApiTestCaseDTO>> mergeApiCaseWithUniqueIdentification(LinkedHashMap<ApiDefinitionDetail, List<ApiTestCaseDTO>> allImportDetails) {
|
||||
Map<ApiDefinitionDetail, List<ApiTestCaseDTO>> returnMap = new HashMap<>();
|
||||
Map<String, ApiDefinitionDetail> filterApiMap = new HashMap<>();
|
||||
Map<String, List<ApiTestCaseDTO>> uniqueCaseMap = new HashMap<>();
|
||||
allImportDetails.forEach((api, apiCase) -> {
|
||||
String key = api.getMethod() + StringUtils.SPACE + api.getPath();
|
||||
if (!filterApiMap.containsKey(key)) {
|
||||
filterApiMap.put(key, api);
|
||||
}
|
||||
if (uniqueCaseMap.containsKey(key)) {
|
||||
uniqueCaseMap.get(key).addAll(apiCase);
|
||||
} else {
|
||||
uniqueCaseMap.put(key, apiCase);
|
||||
}
|
||||
});
|
||||
filterApiMap.forEach((key, api) -> {
|
||||
returnMap.put(api, ApiDefinitionImportUtils.apiCaseRename(uniqueCaseMap.get(key)));
|
||||
});
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
private LinkedHashMap<ApiDefinitionDetail, List<ApiTestCaseDTO>> parseImportFile(String projectId, List<AbstractMsProtocolTestElement> msElement) {
|
||||
LinkedHashMap<ApiDefinitionDetail, List<ApiTestCaseDTO>> returnMap = new LinkedHashMap<>();
|
||||
|
||||
ApiPluginService apiPluginService = CommonBeanFactory.getBean(ApiPluginService.class);
|
||||
assert apiPluginService != null;
|
||||
|
||||
List<ProtocolDTO> protocolDTOList = apiPluginService.getProtocolsByProjectId(projectId);
|
||||
|
||||
Map<String, String> polymorphicNameMap = protocolDTOList.stream().collect(Collectors.toMap(ProtocolDTO::getPolymorphicName, ProtocolDTO::getProtocol));
|
||||
|
||||
for (AbstractMsProtocolTestElement protocolTestElement : msElement) {
|
||||
ApiDefinitionDetail definition = new ApiDefinitionDetail();
|
||||
definition.setName(protocolTestElement.getName());
|
||||
if (protocolTestElement instanceof MsHTTPElement msHTTPElement) {
|
||||
definition.setMethod(msHTTPElement.getMethod());
|
||||
definition.setPath(msHTTPElement.getPath());
|
||||
definition.setProtocol(ApiConstants.HTTP_PROTOCOL);
|
||||
} else {
|
||||
definition.setProtocol(polymorphicNameMap.get(protocolTestElement.getClass().getSimpleName()));
|
||||
definition.setMethod(definition.getProtocol());
|
||||
}
|
||||
if (StringUtils.isBlank(definition.getProtocol())) {
|
||||
continue;
|
||||
}
|
||||
definition.setRequest(protocolTestElement);
|
||||
definition.setResponse(new ArrayList<>());
|
||||
|
||||
|
||||
ApiTestCaseDTO apiTestCaseDTO = new ApiTestCaseDTO();
|
||||
apiTestCaseDTO.setName(definition.getName());
|
||||
apiTestCaseDTO.setPriority("P0");
|
||||
apiTestCaseDTO.setStatus(definition.getStatus());
|
||||
apiTestCaseDTO.setProjectId(definition.getProjectId());
|
||||
apiTestCaseDTO.setFollow(false);
|
||||
apiTestCaseDTO.setMethod(definition.getMethod());
|
||||
apiTestCaseDTO.setPath(definition.getPath());
|
||||
apiTestCaseDTO.setRequest(definition.getRequest());
|
||||
apiTestCaseDTO.setProtocol(definition.getProtocol());
|
||||
apiTestCaseDTO.setProjectId(definition.getProjectId());
|
||||
|
||||
returnMap.put(definition, new ArrayList<>(Collections.singletonList(apiTestCaseDTO)));
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
private HashTree getHashTree(Object scriptWrapper) throws Exception {
|
||||
Field field = scriptWrapper.getClass().getDeclaredField("testPlan");
|
||||
field.setAccessible(true);
|
||||
return (HashTree) field.get(scriptWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiImportDataAnalysisResult generateInsertAndUpdateData(ApiImportFileParseResult importParser, List<ApiDefinitionDetail> existenceApiDefinitionList) {
|
||||
List<ApiDefinitionDetail> importDataList = importParser.getData();
|
||||
Map<String, List<ApiDefinitionDetail>> protocolImportMap = importDataList.stream().collect(Collectors.groupingBy(ApiDefinitionDetail::getProtocol));
|
||||
Map<String, List<ApiDefinitionDetail>> existenceProtocolMap = existenceApiDefinitionList.stream().collect(Collectors.groupingBy(ApiDefinitionDetail::getProtocol));
|
||||
|
||||
ApiImportDataAnalysisResult insertAndUpdateData = new ApiImportDataAnalysisResult();
|
||||
for (Map.Entry<String, List<ApiDefinitionDetail>> entry : protocolImportMap.entrySet()) {
|
||||
List<ApiDefinitionDetail> importList = entry.getValue();
|
||||
List<ApiDefinitionDetail> existenceList = existenceProtocolMap.get(entry.getKey());
|
||||
|
||||
ApiImportDataAnalysisResult httpResult = compareApiData(importList, existenceList, entry.getKey());
|
||||
insertAndUpdateData.getInsertApiList().addAll(httpResult.getInsertApiList());
|
||||
insertAndUpdateData.getExistenceApiList().addAll(httpResult.getExistenceApiList());
|
||||
}
|
||||
insertAndUpdateData.getApiIdAndTestCaseMap().putAll(importParser.getCaseMap());
|
||||
return insertAndUpdateData;
|
||||
}
|
||||
|
||||
private ApiImportDataAnalysisResult compareApiData(List<ApiDefinitionDetail> importData, List<ApiDefinitionDetail> existenceApiData, String protocol) {
|
||||
ApiImportDataAnalysisResult insertAndUpdateData = new ApiImportDataAnalysisResult();
|
||||
|
||||
if (CollectionUtils.isEmpty(importData)) {
|
||||
return insertAndUpdateData;
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(existenceApiData)) {
|
||||
insertAndUpdateData.setInsertApiList(importData);
|
||||
return insertAndUpdateData;
|
||||
}
|
||||
|
||||
// API类型,通过 Method & Path 组合判断,接口是否存在
|
||||
Map<String, ApiDefinitionDetail> savedApiDefinitionMap = null;
|
||||
Map<String, ApiDefinitionDetail> importDataMap = null;
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(protocol, ApiConstants.HTTP_PROTOCOL)) {
|
||||
savedApiDefinitionMap = existenceApiData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), t -> t, (oldValue, newValue) -> newValue));
|
||||
importDataMap = importData.stream().collect(Collectors.toMap(t -> t.getMethod() + t.getPath(), t -> t, (oldValue, newValue) -> newValue));
|
||||
} else {
|
||||
savedApiDefinitionMap = existenceApiData.stream().collect(Collectors.toMap(ApiDefinition::getName, t -> t, (oldValue, newValue) -> newValue));
|
||||
importDataMap = importData.stream().collect(Collectors.toMap(ApiDefinition::getName, t -> t, (oldValue, newValue) -> newValue));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, ApiDefinitionDetail> entry : importDataMap.entrySet()) {
|
||||
if (savedApiDefinitionMap.containsKey(entry.getKey())) {
|
||||
insertAndUpdateData.addExistenceApi(entry.getValue(), savedApiDefinitionMap.get(entry.getKey()));
|
||||
} else {
|
||||
insertAndUpdateData.getInsertApiList().add(entry.getValue());
|
||||
}
|
||||
}
|
||||
return insertAndUpdateData;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
|||
import io.metersphere.api.dto.export.MetersphereApiExportResponse;
|
||||
import io.metersphere.api.dto.request.ImportRequest;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.api.utils.ApiDefinitionImportUtils;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
|
@ -60,44 +61,16 @@ public class MetersphereParserApiDefinition extends HttpApiDefinitionImportAbstr
|
|||
}
|
||||
returnDTO.getData().add(definitionImportDetail);
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
returnDTO.getCaseMap().put(apiID, this.apiCaseRename(caseList));
|
||||
returnDTO.getCaseMap().put(apiID, ApiDefinitionImportUtils.apiCaseRename(caseList));
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(mockList)) {
|
||||
returnDTO.getMockMap().put(apiID, this.apiMockRename(mockList));
|
||||
returnDTO.getMockMap().put(apiID, ApiDefinitionImportUtils.apiMockRename(mockList));
|
||||
}
|
||||
});
|
||||
|
||||
return returnDTO;
|
||||
}
|
||||
|
||||
private List<ApiTestCaseDTO> apiCaseRename(List<ApiTestCaseDTO> caseList) {
|
||||
List<ApiTestCaseDTO> returnList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
List<String> caseNameList = new ArrayList<>();
|
||||
for (ApiTestCaseDTO apiCase : caseList) {
|
||||
String uniqueName = this.getUniqueName(apiCase.getName(), caseNameList);
|
||||
apiCase.setName(uniqueName);
|
||||
caseNameList.add(uniqueName);
|
||||
returnList.add(apiCase);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private List<ApiDefinitionMockDTO> apiMockRename(List<ApiDefinitionMockDTO> caseList) {
|
||||
List<ApiDefinitionMockDTO> returnList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
List<String> caseNameList = new ArrayList<>();
|
||||
for (ApiDefinitionMockDTO apiMock : caseList) {
|
||||
String uniqueName = this.getUniqueName(apiMock.getName(), caseNameList);
|
||||
apiMock.setName(uniqueName);
|
||||
caseNameList.add(uniqueName);
|
||||
returnList.add(apiMock);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
//合并相同路径下的用例和mock
|
||||
private List<ApiDefinitionExportDetail> mergeApiCaseWithUniqueIdentification(List<ApiDefinitionExportDetail> apiDefinitions) {
|
||||
List<ApiDefinitionExportDetail> returnList = new ArrayList<>();
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
|||
import io.metersphere.api.dto.request.ImportRequest;
|
||||
import io.metersphere.api.parser.api.postman.PostmanCollection;
|
||||
import io.metersphere.api.parser.api.postman.PostmanItem;
|
||||
import io.metersphere.api.utils.ApiDefinitionImportUtils;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
|
@ -109,23 +110,9 @@ public class PostmanParserApiDefinition extends PostmanAbstractParserParserApiDe
|
|||
}
|
||||
});
|
||||
filterApiMap.forEach((key, api) -> {
|
||||
returnMap.put(api, this.apiCaseRename(uniqueCaseMap.get(key)));
|
||||
returnMap.put(api, ApiDefinitionImportUtils.apiRename(uniqueCaseMap.get(key)));
|
||||
});
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
private List<ApiDefinitionDetail> apiCaseRename(List<ApiDefinitionDetail> caseList) {
|
||||
List<ApiDefinitionDetail> returnList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
List<String> caseNameList = new ArrayList<>();
|
||||
for (ApiDefinitionDetail apiCase : caseList) {
|
||||
String uniqueName = this.getUniqueName(apiCase.getName(), caseNameList);
|
||||
apiCase.setName(uniqueName);
|
||||
caseNameList.add(uniqueName);
|
||||
returnList.add(apiCase);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,30 @@
|
|||
package io.metersphere.api.parser.ms;
|
||||
|
||||
import io.metersphere.api.dto.ApiFile;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.dto.request.http.MsHeader;
|
||||
import io.metersphere.api.dto.request.http.QueryParam;
|
||||
import io.metersphere.api.dto.request.http.body.*;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.KeyValueEnableParam;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.protocol.http.control.HeaderManager;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPArgument;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||
import org.apache.jmeter.testelement.property.JMeterProperty;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -13,9 +33,151 @@ import org.apache.jorphan.collections.HashTree;
|
|||
public class HTTPSamplerConverter extends AbstractMsElementConverter<HTTPSamplerProxy> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, HTTPSamplerProxy httpSampler, HashTree hashTree) {
|
||||
MsHTTPElement msHTTPElement = new MsHTTPElement();
|
||||
// todo 解析HTTP请求
|
||||
MsHTTPElement msHTTPElement = this.convertHttpSampler(httpSampler);
|
||||
parent.getChildren().add(msHTTPElement);
|
||||
parseChild(msHTTPElement, httpSampler, hashTree);
|
||||
}
|
||||
|
||||
private MsHTTPElement convertHttpSampler(HTTPSamplerProxy source) {
|
||||
MsHTTPElement samplerProxy = new MsHTTPElement();
|
||||
samplerProxy.setQuery(new ArrayList<>());
|
||||
samplerProxy.setRest(new ArrayList<>());
|
||||
try {
|
||||
|
||||
BeanUtils.copyBean(samplerProxy, source);
|
||||
// 处理HTTP协议的请求头
|
||||
List<MsHeader> headerKvList = new LinkedList<>();
|
||||
HeaderManager headerManager = source.getHeaderManager();
|
||||
if (headerManager != null && headerManager.getHeaders() != null) {
|
||||
for (int i = 0; i < headerManager.getHeaders().size(); i++) {
|
||||
String headerKey = headerManager.getHeader(i).getName();
|
||||
String value = headerManager.getHeader(i).getValue();
|
||||
headerKvList.add(new MsHeader() {{
|
||||
this.setKey(headerKey);
|
||||
this.setValue(value);
|
||||
}});
|
||||
}
|
||||
}
|
||||
samplerProxy.setHeaders(headerKvList);
|
||||
// 初始化body
|
||||
Body body = new Body();
|
||||
body.setJsonBody(new JsonBody());
|
||||
body.setFormDataBody(new FormDataBody());
|
||||
body.setWwwFormBody(new WWWFormBody());
|
||||
body.setRawBody(new RawBody());
|
||||
body.setXmlBody(new XmlBody());
|
||||
samplerProxy.setBody(body);
|
||||
if (source.getHTTPFiles().length > 0) {
|
||||
samplerProxy.getBody().setBodyType(Body.BodyType.FORM_DATA.name());
|
||||
List<FormDataKV> keyValues = new LinkedList<>();
|
||||
for (HTTPFileArg arg : source.getHTTPFiles()) {
|
||||
FormDataKV keyValue = getFormDataKV(arg);
|
||||
keyValues.add(keyValue);
|
||||
}
|
||||
samplerProxy.getBody().setFormDataBody(new FormDataBody() {{
|
||||
this.setFormValues(keyValues);
|
||||
}});
|
||||
}
|
||||
samplerProxy.getOtherConfig().setConnectTimeout((long) source.getConnectTimeout());
|
||||
samplerProxy.getOtherConfig().setResponseTimeout((long) source.getResponseTimeout());
|
||||
samplerProxy.getOtherConfig().setFollowRedirects(source.getFollowRedirects());
|
||||
samplerProxy.getOtherConfig().setAutoRedirects(source.getAutoRedirects());
|
||||
|
||||
if (source.getArguments() != null) {
|
||||
String bodyType = this.getBodyType(samplerProxy.getHeaders());
|
||||
if (source.getPostBodyRaw()) {
|
||||
List<MsHeader> headers = samplerProxy.getHeaders();
|
||||
boolean jsonType = false;
|
||||
if (CollectionUtils.isNotEmpty(headers)) {
|
||||
for (MsHeader header : headers) {
|
||||
if (StringUtils.equals(header.getKey(), "Content-Type") && StringUtils.equals(header.getValue(), "application/json")) {
|
||||
samplerProxy.getBody().setBodyType(Body.BodyType.JSON.name());
|
||||
jsonType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!jsonType) {
|
||||
samplerProxy.getBody().setBodyType(Body.BodyType.RAW.name());
|
||||
}
|
||||
source.getArguments().getArgumentsAsMap().forEach((k, v) -> samplerProxy.getBody().setRawBody(new RawBody() {{
|
||||
this.setValue(v);
|
||||
}}));
|
||||
} else if (StringUtils.isNotEmpty(bodyType) || ("POST".equalsIgnoreCase(source.getMethod()) && source.getArguments().getArgumentsAsMap().size() > 0)) {
|
||||
samplerProxy.getBody().setBodyType(Body.BodyType.WWW_FORM.name());
|
||||
List<WWWFormKV> keyValues = new LinkedList<>();
|
||||
source.getArguments().getArguments().forEach(params -> {
|
||||
WWWFormKV keyValue = new WWWFormKV();
|
||||
parseParams(params, keyValue);
|
||||
keyValues.add(keyValue);
|
||||
});
|
||||
samplerProxy.getBody().setWwwFormBody(new WWWFormBody() {{
|
||||
this.setFormValues(keyValues);
|
||||
}});
|
||||
} else if (samplerProxy.getBody() != null && samplerProxy.getBody().getBodyType().equals(Body.BodyType.FORM_DATA.name())) {
|
||||
source.getArguments().getArguments().forEach(params -> {
|
||||
FormDataKV keyValue = new FormDataKV();
|
||||
parseParams(params, keyValue);
|
||||
samplerProxy.getBody().getFormDataBody().getFormValues().add(keyValue);
|
||||
});
|
||||
} else {
|
||||
List<QueryParam> keyValues = new LinkedList<>();
|
||||
source.getArguments().getArguments().forEach(params -> {
|
||||
QueryParam keyValue = new QueryParam();
|
||||
parseParams(params, keyValue);
|
||||
keyValues.add(keyValue);
|
||||
});
|
||||
if (CollectionUtils.isNotEmpty(keyValues)) {
|
||||
samplerProxy.setQuery(keyValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
samplerProxy.setPath(source.getPath());
|
||||
samplerProxy.setMethod(source.getMethod());
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
}
|
||||
return samplerProxy;
|
||||
}
|
||||
|
||||
private String getBodyType(List<MsHeader> headers) {
|
||||
if (CollectionUtils.isNotEmpty(headers)) {
|
||||
List<MsHeader> keyValues = headers.stream().filter(keyValue -> "Content-Type".equals(keyValue.getKey()) && "application/x-www-form-urlencoded".equals(keyValue.getValue())).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(keyValues)) {
|
||||
return keyValues.getFirst().getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FormDataKV getFormDataKV(HTTPFileArg arg) {
|
||||
ApiFile file = new ApiFile();
|
||||
file.setFileId(arg.getParamName());
|
||||
String fileName = arg.getPath();
|
||||
if (fileName.contains("/")) {
|
||||
fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
|
||||
}
|
||||
file.setFileName(fileName);
|
||||
|
||||
FormDataKV keyValue = new FormDataKV();
|
||||
keyValue.setKey(arg.getParamName());
|
||||
keyValue.setValue(arg.getParamName());
|
||||
keyValue.setContentType(arg.getMimeType());
|
||||
keyValue.setContentType("file");
|
||||
keyValue.setFiles(Collections.singletonList(file));
|
||||
return keyValue;
|
||||
}
|
||||
|
||||
private void parseParams(JMeterProperty params, KeyValueEnableParam keyValue) {
|
||||
if (params == null || keyValue == null) {
|
||||
return;
|
||||
}
|
||||
Object objValue = params.getObjectValue();
|
||||
if (objValue instanceof HTTPArgument) {
|
||||
HTTPArgument argument = (HTTPArgument) objValue;
|
||||
keyValue.setKey(argument.getName());
|
||||
keyValue.setValue(argument.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package io.metersphere.api.parser.ms;
|
||||
|
||||
import io.metersphere.api.parser.ms.http.HeaderManagerConverter;
|
||||
import io.metersphere.api.parser.ms.http.post.*;
|
||||
import io.metersphere.api.parser.ms.http.pre.BeanShellPreProcessConverter;
|
||||
import io.metersphere.api.parser.ms.http.pre.JDBCPreProcessConverter;
|
||||
import io.metersphere.api.parser.ms.http.pre.JSR223PreProcessConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.sdk.util.PluginLogUtils;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
@ -30,6 +35,22 @@ public class MsElementConverterRegister {
|
|||
register(TestPlanConverter.class);
|
||||
register(ThreadGroupConverter.class);
|
||||
register(HTTPSamplerConverter.class);
|
||||
register(HeaderManagerConverter.class);
|
||||
|
||||
register(BeanShellPostProcessConverter.class);
|
||||
register(ConstantTimerConverter.class);
|
||||
register(JDBCPostProcessConverter.class);
|
||||
register(JSONPostProcessorConverter.class);
|
||||
register(JSR223PostProcessConverter.class);
|
||||
register(RegexExtractorConverter.class);
|
||||
register(XPath2ExtractorConverter.class);
|
||||
register(XPathExtractorConverter.class);
|
||||
|
||||
register(BeanShellPreProcessConverter.class);
|
||||
register(JDBCPreProcessConverter.class);
|
||||
register(JSR223PreProcessConverter.class);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package io.metersphere.api.parser.ms;
|
||||
|
||||
import io.metersphere.api.dto.request.MsScenario;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsProtocolTestElement;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-27 10:07
|
||||
|
@ -22,4 +26,16 @@ public class MsTestElementParser {
|
|||
}
|
||||
return msScenario;
|
||||
}
|
||||
|
||||
public List<AbstractMsProtocolTestElement> getAbstractMsProtocolTestElement(AbstractMsTestElement msTestElement) {
|
||||
List<AbstractMsProtocolTestElement> result = new ArrayList<>();
|
||||
if (msTestElement instanceof AbstractMsProtocolTestElement abstractMsProtocolTestElement) {
|
||||
result.add(abstractMsProtocolTestElement);
|
||||
} else {
|
||||
for (AbstractMsTestElement child : msTestElement.getChildren()) {
|
||||
result.addAll(this.getAbstractMsProtocolTestElement(child));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package io.metersphere.api.parser.ms.http;
|
||||
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.dto.request.http.MsHeader;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import org.apache.jmeter.protocol.http.control.HeaderManager;
|
||||
import org.apache.jmeter.testelement.property.CollectionProperty;
|
||||
import org.apache.jmeter.testelement.property.JMeterProperty;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class HeaderManagerConverter extends AbstractMsElementConverter<HeaderManager> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, HeaderManager element, HashTree hashTree) {
|
||||
if (parent instanceof MsHTTPElement msHTTPElement) {
|
||||
// 处理HTTP协议的请求头
|
||||
List<MsHeader> headerKvList = msHTTPElement.getHeaders() == null ? new LinkedList<>() : msHTTPElement.getHeaders();
|
||||
CollectionProperty collectionProperty = element.getHeaders();
|
||||
List<String> extendsHeaderKey = headerKvList.stream().map(MsHeader::getKey).toList();
|
||||
for (int i = 0; i < collectionProperty.size(); i++) {
|
||||
JMeterProperty jMeterProperty = collectionProperty.get(i);
|
||||
String key = jMeterProperty.getName();
|
||||
if (!extendsHeaderKey.contains(key)) {
|
||||
headerKvList.add(new MsHeader() {{
|
||||
this.setKey(key);
|
||||
this.setValue(jMeterProperty.getStringValue());
|
||||
}});
|
||||
}
|
||||
}
|
||||
msHTTPElement.setHeaders(headerKvList);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import org.apache.jmeter.extractor.BeanShellPostProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class BeanShellPostProcessConverter extends AbstractMsElementConverter<BeanShellPostProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, BeanShellPostProcessor element, HashTree hashTree) {
|
||||
ScriptProcessor msScriptElement = new ScriptProcessor();
|
||||
msScriptElement.setEnable(element.isEnabled());
|
||||
msScriptElement.setScriptLanguage(ScriptLanguageType.BEANSHELL.name());
|
||||
msScriptElement.setName(element.getPropertyAsString("TestElement.name"));
|
||||
msScriptElement.setScript(element.getPropertyAsString("script"));
|
||||
ConverterUtils.addPostProcess(parent, msScriptElement);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.TimeWaitingProcessor;
|
||||
import org.apache.jmeter.timers.ConstantTimer;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class ConstantTimerConverter extends AbstractMsElementConverter<ConstantTimer> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, ConstantTimer element, HashTree hashTree) {
|
||||
TimeWaitingProcessor msProcessor = new TimeWaitingProcessor();
|
||||
msProcessor.setDelay(Long.parseLong(element.getDelay()));
|
||||
msProcessor.setEnable(element.isEnabled());
|
||||
msProcessor.setName(element.getName());
|
||||
ConverterUtils.addPreProcess(parent, msProcessor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import org.apache.jmeter.protocol.jdbc.processor.JDBCPostProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class JDBCPostProcessConverter extends AbstractMsElementConverter<JDBCPostProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, JDBCPostProcessor element, HashTree hashTree) {
|
||||
ConverterUtils.addPostProcess(parent, ConverterUtils.genJDBCProcessor(element));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.extract.JSONPathExtract;
|
||||
import io.metersphere.project.api.processor.extract.ResultMatchingExtract;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class JSONPostProcessorConverter extends AbstractMsElementConverter<JSONPostProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, JSONPostProcessor element, HashTree hashTree) {
|
||||
JSONPathExtract jsonPathExtract = new JSONPathExtract();
|
||||
jsonPathExtract.setVariableName(element.getRefNames());
|
||||
jsonPathExtract.setExpression(element.getJsonPathExpressions());
|
||||
jsonPathExtract.setEnable(element.isEnabled());
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(element.getMatchNumbers(), "-1")) {
|
||||
jsonPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.ALL.name());
|
||||
jsonPathExtract.setResultMatchingRuleNum(-1);
|
||||
} else if (StringUtils.equalsIgnoreCase(element.getMatchNumbers(), "0")) {
|
||||
jsonPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.RANDOM.name());
|
||||
jsonPathExtract.setResultMatchingRuleNum(0);
|
||||
} else {
|
||||
jsonPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.SPECIFIC.name());
|
||||
try {
|
||||
jsonPathExtract.setResultMatchingRuleNum(Integer.parseInt(element.getMatchNumbers()));
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
ConverterUtils.addPostExtract(parent, jsonPathExtract);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import org.apache.jmeter.extractor.JSR223PostProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class JSR223PostProcessConverter extends AbstractMsElementConverter<JSR223PostProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, JSR223PostProcessor element, HashTree hashTree) {
|
||||
ScriptProcessor msScriptElement = new ScriptProcessor();
|
||||
msScriptElement.setScriptLanguage(element.getScriptLanguage());
|
||||
msScriptElement.setEnable(element.isEnabled());
|
||||
msScriptElement.setName(element.getPropertyAsString("TestElement.name"));
|
||||
msScriptElement.setScript(element.getPropertyAsString("script"));
|
||||
ConverterUtils.addPostProcess(parent, msScriptElement);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.extract.RegexExtract;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.extractor.RegexExtractor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class RegexExtractorConverter extends AbstractMsElementConverter<RegexExtractor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, RegexExtractor element, HashTree hashTree) {
|
||||
RegexExtract regexExtract = new RegexExtract();
|
||||
regexExtract.setVariableName(element.getRefName());
|
||||
regexExtract.setExpression(element.getRegex());
|
||||
regexExtract.setEnable(element.isEnabled());
|
||||
regexExtract.setExtractScope(this.getUseField(element));
|
||||
regexExtract.setResultMatchingRuleNum(element.getMatchNumber());
|
||||
|
||||
ConverterUtils.addPostExtract(parent, regexExtract);
|
||||
}
|
||||
|
||||
private String getUseField(RegexExtractor element) {
|
||||
String useHeaders = element.getPropertyAsString("RegexExtractor.useHeaders");
|
||||
if (StringUtils.equalsIgnoreCase(useHeaders, "false")) {
|
||||
return RegexExtract.ExtractScope.BODY.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "unescaped")) {
|
||||
return RegexExtract.ExtractScope.UNESCAPED_BODY.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "as_document")) {
|
||||
return RegexExtract.ExtractScope.BODY_AS_DOCUMENT.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "true")) {
|
||||
return RegexExtract.ExtractScope.RESPONSE_HEADERS.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "request_headers")) {
|
||||
return RegexExtract.ExtractScope.REQUEST_HEADERS.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "URL")) {
|
||||
return RegexExtract.ExtractScope.URL.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "code")) {
|
||||
return RegexExtract.ExtractScope.RESPONSE_CODE.name();
|
||||
} else if (StringUtils.equalsIgnoreCase(useHeaders, "message")) {
|
||||
return RegexExtract.ExtractScope.RESPONSE_MESSAGE.name();
|
||||
}
|
||||
return useHeaders;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import org.apache.jmeter.assertions.ResponseAssertion;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class ResponseAssertionConverter extends AbstractMsElementConverter<ResponseAssertion> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, ResponseAssertion element, HashTree hashTree) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.extract.ResultMatchingExtract;
|
||||
import io.metersphere.project.api.processor.extract.XPathExtract;
|
||||
import org.apache.jmeter.extractor.XPath2Extractor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class XPath2ExtractorConverter extends AbstractMsElementConverter<XPath2Extractor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, XPath2Extractor element, HashTree hashTree) {
|
||||
XPathExtract xPathExtract = new XPathExtract();
|
||||
xPathExtract.setEnable(element.isEnabled());
|
||||
xPathExtract.setResponseFormat(XPathExtract.ResponseFormat.XML.name());
|
||||
xPathExtract.setVariableName(element.getRefName());
|
||||
xPathExtract.setExpression(element.getXPathQuery());
|
||||
|
||||
if (element.getMatchNumber() == -1) {
|
||||
xPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.ALL.name());
|
||||
xPathExtract.setResultMatchingRuleNum(-1);
|
||||
} else if (element.getMatchNumber() == 0) {
|
||||
xPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.RANDOM.name());
|
||||
xPathExtract.setResultMatchingRuleNum(0);
|
||||
} else {
|
||||
xPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.SPECIFIC.name());
|
||||
xPathExtract.setResultMatchingRuleNum(element.getMatchNumber());
|
||||
}
|
||||
// xPathExtract.setVariableType(element.getPropertyAsString("type"));
|
||||
// xPathExtract.setExpression(element.getPropertyAsString("expression"));
|
||||
|
||||
ConverterUtils.addPostExtract(parent, xPathExtract);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package io.metersphere.api.parser.ms.http.post;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.extract.JSONPathExtract;
|
||||
import io.metersphere.project.api.processor.extract.RegexExtract;
|
||||
import io.metersphere.project.api.processor.extract.ResultMatchingExtract;
|
||||
import io.metersphere.project.api.processor.extract.XPathExtract;
|
||||
import org.apache.jmeter.extractor.XPathExtractor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class XPathExtractorConverter extends AbstractMsElementConverter<XPathExtractor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, XPathExtractor element, HashTree hashTree) {
|
||||
|
||||
JSONPathExtract jsonPathExtract = new JSONPathExtract();
|
||||
RegexExtract regexExtract = new RegexExtract();
|
||||
|
||||
XPathExtract xPathExtract = new XPathExtract();
|
||||
xPathExtract.setEnable(element.isEnabled());
|
||||
xPathExtract.setResponseFormat(XPathExtract.ResponseFormat.HTML.name());
|
||||
xPathExtract.setVariableName(element.getRefName());
|
||||
xPathExtract.setExpression(element.getXPathQuery());
|
||||
|
||||
if (element.getMatchNumber() == -1) {
|
||||
xPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.ALL.name());
|
||||
xPathExtract.setResultMatchingRuleNum(-1);
|
||||
} else if (element.getMatchNumber() == 0) {
|
||||
xPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.RANDOM.name());
|
||||
xPathExtract.setResultMatchingRuleNum(0);
|
||||
} else {
|
||||
xPathExtract.setResultMatchingRule(ResultMatchingExtract.ResultMatchingRuleType.SPECIFIC.name());
|
||||
xPathExtract.setResultMatchingRuleNum(element.getMatchNumber());
|
||||
}
|
||||
ConverterUtils.addPostExtract(parent, xPathExtract);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package io.metersphere.api.parser.ms.http.pre;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import org.apache.jmeter.modifiers.BeanShellPreProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class BeanShellPreProcessConverter extends AbstractMsElementConverter<BeanShellPreProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, BeanShellPreProcessor element, HashTree hashTree) {
|
||||
ScriptProcessor msScriptElement = new ScriptProcessor();
|
||||
msScriptElement.setEnable(element.isEnabled());
|
||||
msScriptElement.setScriptLanguage(ScriptLanguageType.BEANSHELL.name());
|
||||
msScriptElement.setName(element.getPropertyAsString("TestElement.name"));
|
||||
msScriptElement.setScript(element.getPropertyAsString("script"));
|
||||
ConverterUtils.addPreProcess(parent, msScriptElement);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.api.parser.ms.http.pre;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import org.apache.jmeter.protocol.jdbc.processor.JDBCPreProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class JDBCPreProcessConverter extends AbstractMsElementConverter<JDBCPreProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, JDBCPreProcessor element, HashTree hashTree) {
|
||||
ConverterUtils.addPreProcess(parent, ConverterUtils.genJDBCProcessor(element));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.api.parser.ms.http.pre;
|
||||
|
||||
import io.metersphere.api.utils.ConverterUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsElementConverter;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import org.apache.jmeter.modifiers.JSR223PreProcessor;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class JSR223PreProcessConverter extends AbstractMsElementConverter<JSR223PreProcessor> {
|
||||
@Override
|
||||
public void toMsElement(AbstractMsTestElement parent, JSR223PreProcessor element, HashTree hashTree) {
|
||||
|
||||
ScriptProcessor msScriptElement = new ScriptProcessor();
|
||||
msScriptElement.setScriptLanguage(element.getScriptLanguage());
|
||||
msScriptElement.setEnable(element.isEnabled());
|
||||
msScriptElement.setName(element.getPropertyAsString("TestElement.name"));
|
||||
msScriptElement.setScript(element.getPropertyAsString("script"));
|
||||
|
||||
ConverterUtils.addPreProcess(parent, msScriptElement);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
package io.metersphere.api.service.definition;
|
||||
|
||||
import io.metersphere.api.domain.*;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionBatchRequest;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionWithBlob;
|
||||
import io.metersphere.api.dto.definition.ApiMockWithBlob;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseWithBlob;
|
||||
import io.metersphere.api.domain.ApiDefinitionModule;
|
||||
import io.metersphere.api.domain.ApiDefinitionModuleExample;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.export.ApiExportResponse;
|
||||
import io.metersphere.api.mapper.*;
|
||||
import io.metersphere.api.parser.api.MetersphereExportParser;
|
||||
|
@ -16,6 +14,7 @@ import io.metersphere.sdk.exception.MSException;
|
|||
import io.metersphere.system.utils.CustomFieldUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -45,12 +44,12 @@ public class ApiDefinitionExportService {
|
|||
private ApiDefinitionMapper apiDefinitionMapper;
|
||||
|
||||
|
||||
public ApiExportResponse export(ApiDefinitionBatchRequest request, String type, String userId) {
|
||||
List<String> ids = getBatchApiIds(request, request.getProjectId(), List.of(ModuleConstants.NODE_PROTOCOL_HTTP), false, userId);
|
||||
public ApiExportResponse export(ApiDefinitionBatchExportRequest request, String type, String userId) {
|
||||
List<String> ids = this.getBatchExportApiIds(request, request.getProjectId(), userId);
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return null;
|
||||
}
|
||||
List<ApiDefinitionWithBlob> list = extApiDefinitionMapper.selectApiDefinitionWithBlob(ids);
|
||||
List<ApiDefinitionWithBlob> list = this.selectAndSortByIds(ids);
|
||||
List<String> moduleIds = list.stream().map(ApiDefinitionWithBlob::getModuleId).toList();
|
||||
ApiDefinitionModuleExample example = new ApiDefinitionModuleExample();
|
||||
example.createCriteria().andIdIn(moduleIds);
|
||||
|
@ -63,20 +62,26 @@ public class ApiDefinitionExportService {
|
|||
};
|
||||
}
|
||||
|
||||
private List<String> getBatchApiIds(ApiDefinitionBatchRequest request, String projectId, List<String> protocols, boolean deleted, String userId) {
|
||||
private List<ApiDefinitionWithBlob> selectAndSortByIds(List<String> ids) {
|
||||
Map<String, ApiDefinitionWithBlob> apiMap = extApiDefinitionMapper.selectApiDefinitionWithBlob(ids).stream().collect(Collectors.toMap(ApiDefinitionWithBlob::getId, v -> v));
|
||||
return ids.stream().map(apiMap::get).toList();
|
||||
}
|
||||
|
||||
private List<String> getBatchExportApiIds(ApiDefinitionBatchExportRequest request, String exportType, String userId) {
|
||||
List<String> protocols = request.getProtocols();
|
||||
if (StringUtils.equalsIgnoreCase(exportType, "swagger")) {
|
||||
protocols = List.of(ModuleConstants.NODE_PROTOCOL_HTTP);
|
||||
}
|
||||
|
||||
if (request.isSelectAll()) {
|
||||
CustomFieldUtils.setBaseQueryRequestCustomMultipleFields(request.getCondition(), userId);
|
||||
List<String> ids = extApiDefinitionMapper.getIds(request, projectId, protocols, deleted);
|
||||
List<String> ids = extApiDefinitionMapper.getIdsBySort(request, request.getProjectId(), protocols, request.getSortString());
|
||||
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||
ids.removeAll(request.getExcludeIds());
|
||||
}
|
||||
return ids;
|
||||
} else {
|
||||
request.getSelectIds().removeAll(request.getExcludeIds());
|
||||
ApiDefinitionExample definitionExample = new ApiDefinitionExample();
|
||||
definitionExample.createCriteria().andIdIn(request.getSelectIds()).andProtocolIn(protocols).andDeletedEqualTo(deleted);
|
||||
List<ApiDefinition> apiDefinitions = apiDefinitionMapper.selectByExample(definitionExample);
|
||||
return apiDefinitions.stream().map(ApiDefinition::getId).toList();
|
||||
return request.getSelectIds();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,15 +95,11 @@ public class ApiDefinitionExportService {
|
|||
}
|
||||
}
|
||||
|
||||
@Resource
|
||||
private ApiTestCaseBlobMapper apiTestCaseBlobMapper;
|
||||
|
||||
private ApiExportResponse exportMetersphere(ApiDefinitionBatchRequest request, List<ApiDefinitionWithBlob> list, Map<String, String> moduleMap) {
|
||||
private ApiExportResponse exportMetersphere(ApiDefinitionBatchExportRequest request, List<ApiDefinitionWithBlob> list, Map<String, String> moduleMap) {
|
||||
try {
|
||||
List<String> apiIds = list.stream().map(ApiDefinitionWithBlob::getId).toList();
|
||||
List<ApiTestCaseWithBlob> apiTestCaseWithBlobs = new ArrayList<>();
|
||||
List<ApiMockWithBlob> apiMockWithBlobs = new ArrayList<>();
|
||||
List<ApiTestCaseBlob> apiTestCaseBlobs = new ArrayList<>();
|
||||
if (request.isExportApiCase()) {
|
||||
apiTestCaseWithBlobs = extApiTestCaseMapper.selectAllDetailByApiIds(apiIds);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,10 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.project.utils.NodeSortUtils.DEFAULT_NODE_INTERVAL_POS;
|
||||
|
@ -99,6 +102,9 @@ public class ApiDefinitionImportService {
|
|||
if (StringUtils.isBlank(request.getProjectId())) {
|
||||
request.setProjectId(projectId);
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(request.getType(), ApiImportPlatform.Jmeter.name())) {
|
||||
request.setSyncCase(true);
|
||||
}
|
||||
//判断是否是定时任务进入
|
||||
if (StringUtils.equals(request.getType(), "SCHEDULE")) {
|
||||
request.setProtocol(ModuleConstants.NODE_PROTOCOL_HTTP);
|
||||
|
@ -118,22 +124,26 @@ public class ApiDefinitionImportService {
|
|||
this.initImportRequestAndCheck(file, request, projectId);
|
||||
ApiDefinitionImportParser<?> runService = ImportParserFactory.getImportParser(request.getPlatform());
|
||||
assert runService != null;
|
||||
ApiImportDataAnalysisResult apiImportDataAnalysisResult;
|
||||
ApiImportDataAnalysisResult apiImportDataAnalysisResult = new ApiImportDataAnalysisResult();
|
||||
try {
|
||||
//解析文件
|
||||
ApiImportFileParseResult fileParseResult = (ApiImportFileParseResult) runService.parse(file == null ? null : file.getInputStream(), request);
|
||||
|
||||
if (!CollectionUtils.isEmpty(fileParseResult.getData())) {
|
||||
ApiDefinitionPageRequest pageRequest = new ApiDefinitionPageRequest();
|
||||
pageRequest.setProjectId(request.getProjectId());
|
||||
pageRequest.setProtocols(Collections.singletonList(runService.getParseProtocol()));
|
||||
pageRequest.setProtocols(fileParseResult.getApiProtocols());
|
||||
List<ApiDefinitionDetail> existenceApiDefinitionList = extApiDefinitionMapper.importList(pageRequest);
|
||||
//分析有哪些数据需要新增、有哪些数据需要更新
|
||||
apiImportDataAnalysisResult = runService.generateInsertAndUpdateData(fileParseResult, existenceApiDefinitionList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e.getMessage(), e);
|
||||
throw new MSException(Translator.get("parse_data_error"));
|
||||
}
|
||||
|
||||
if (apiImportDataAnalysisResult.isEmpty()) {
|
||||
throw new MSException(Translator.get("parse_empty_data"));
|
||||
}
|
||||
try {
|
||||
//初始化版本信息,用于保存,以及以后真对具体版本导入进行拓展
|
||||
String defaultVersion = extBaseProjectVersionMapper.getDefaultVersion(request.getProjectId());
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package io.metersphere.api.utils;
|
||||
|
||||
import io.metersphere.api.constants.ApiImportPlatform;
|
||||
import io.metersphere.api.dto.converter.ApiDefinitionDetail;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionMockDTO;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||
import io.metersphere.api.dto.request.ImportRequest;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||
|
@ -8,6 +11,10 @@ import io.metersphere.sdk.exception.MSException;
|
|||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.log.dto.LogDTO;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ApiDefinitionImportUtils {
|
||||
|
@ -48,4 +55,56 @@ public class ApiDefinitionImportUtils {
|
|||
dto.setOriginalValue(JSON.toJSONBytes(importData));
|
||||
return dto;
|
||||
}
|
||||
|
||||
public static List<ApiDefinitionDetail> apiRename(List<ApiDefinitionDetail> caseList) {
|
||||
List<ApiDefinitionDetail> returnList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
List<String> caseNameList = new ArrayList<>();
|
||||
for (ApiDefinitionDetail apiCase : caseList) {
|
||||
String uniqueName = getUniqueName(apiCase.getName(), caseNameList);
|
||||
apiCase.setName(uniqueName);
|
||||
caseNameList.add(uniqueName);
|
||||
returnList.add(apiCase);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static List<ApiTestCaseDTO> apiCaseRename(List<ApiTestCaseDTO> caseList) {
|
||||
List<ApiTestCaseDTO> returnList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
List<String> caseNameList = new ArrayList<>();
|
||||
for (ApiTestCaseDTO apiCase : caseList) {
|
||||
String uniqueName = getUniqueName(apiCase.getName(), caseNameList);
|
||||
apiCase.setName(uniqueName);
|
||||
caseNameList.add(uniqueName);
|
||||
returnList.add(apiCase);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static List<ApiDefinitionMockDTO> apiMockRename(List<ApiDefinitionMockDTO> caseList) {
|
||||
List<ApiDefinitionMockDTO> returnList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(caseList)) {
|
||||
List<String> caseNameList = new ArrayList<>();
|
||||
for (ApiDefinitionMockDTO apiMock : caseList) {
|
||||
String uniqueName = ApiDefinitionImportUtils.getUniqueName(apiMock.getName(), caseNameList);
|
||||
apiMock.setName(uniqueName);
|
||||
caseNameList.add(uniqueName);
|
||||
returnList.add(apiMock);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private static String getUniqueName(String originalName, List<String> existenceNameList) {
|
||||
String returnName = originalName;
|
||||
int index = 1;
|
||||
while (existenceNameList.contains(returnName)) {
|
||||
returnName = originalName + " - " + index;
|
||||
index++;
|
||||
}
|
||||
return returnName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
package io.metersphere.api.utils;
|
||||
|
||||
import io.metersphere.api.dto.request.MsCommonElement;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.processor.ExtractPostProcessor;
|
||||
import io.metersphere.project.api.processor.MsProcessor;
|
||||
import io.metersphere.project.api.processor.SQLProcessor;
|
||||
import io.metersphere.project.api.processor.extract.MsExtract;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.jmeter.testelement.AbstractTestElement;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class ConverterUtils {
|
||||
public static void addPreProcess(AbstractMsTestElement parent, MsProcessor msProcessor) {
|
||||
if (CollectionUtils.isEmpty(parent.getChildren())) {
|
||||
MsCommonElement msCommonElement = new MsCommonElement();
|
||||
msCommonElement.getPreProcessorConfig().getProcessors().add(msProcessor);
|
||||
LinkedList<AbstractMsTestElement> children = new LinkedList<>();
|
||||
children.add(msCommonElement);
|
||||
parent.setChildren(children);
|
||||
} else {
|
||||
AbstractMsTestElement child = parent.getChildren().getFirst();
|
||||
if (child instanceof MsCommonElement msCommonElement) {
|
||||
msCommonElement.getPreProcessorConfig().getProcessors().add(msProcessor);
|
||||
} else {
|
||||
MsCommonElement msCommonElement = new MsCommonElement();
|
||||
msCommonElement.getPreProcessorConfig().getProcessors().add(msProcessor);
|
||||
parent.getChildren().add(msCommonElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addPostProcess(AbstractMsTestElement parent, MsProcessor msProcessor) {
|
||||
if (CollectionUtils.isEmpty(parent.getChildren())) {
|
||||
MsCommonElement msCommonElement = new MsCommonElement();
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(msProcessor);
|
||||
LinkedList<AbstractMsTestElement> children = new LinkedList<>();
|
||||
children.add(msCommonElement);
|
||||
parent.setChildren(children);
|
||||
} else {
|
||||
AbstractMsTestElement child = parent.getChildren().getFirst();
|
||||
if (child instanceof MsCommonElement msCommonElement) {
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(msProcessor);
|
||||
} else {
|
||||
MsCommonElement msCommonElement = new MsCommonElement();
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(msProcessor);
|
||||
parent.getChildren().add(msCommonElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addPostExtract(AbstractMsTestElement parent, MsExtract msExtract) {
|
||||
if (CollectionUtils.isEmpty(parent.getChildren())) {
|
||||
ExtractPostProcessor extractPostProcessor = new ExtractPostProcessor();
|
||||
extractPostProcessor.getExtractors().add(msExtract);
|
||||
|
||||
MsCommonElement msCommonElement = new MsCommonElement();
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(extractPostProcessor);
|
||||
LinkedList<AbstractMsTestElement> children = new LinkedList<>();
|
||||
children.add(msCommonElement);
|
||||
parent.setChildren(children);
|
||||
} else {
|
||||
AbstractMsTestElement child = parent.getChildren().getFirst();
|
||||
if (child instanceof MsCommonElement msCommonElement) {
|
||||
ExtractPostProcessor extractPostProcessor = null;
|
||||
for (Object processor : msCommonElement.getPostProcessorConfig().getProcessors()) {
|
||||
if (processor instanceof ExtractPostProcessor) {
|
||||
extractPostProcessor = (ExtractPostProcessor) processor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (extractPostProcessor == null) {
|
||||
extractPostProcessor = new ExtractPostProcessor();
|
||||
extractPostProcessor.getExtractors().add(msExtract);
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(extractPostProcessor);
|
||||
} else {
|
||||
extractPostProcessor.getExtractors().add(msExtract);
|
||||
}
|
||||
} else {
|
||||
ExtractPostProcessor extractPostProcessor = new ExtractPostProcessor();
|
||||
extractPostProcessor.getExtractors().add(msExtract);
|
||||
|
||||
MsCommonElement msCommonElement = new MsCommonElement();
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(extractPostProcessor);
|
||||
parent.getChildren().add(msCommonElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SQLProcessor genJDBCProcessor(AbstractTestElement element) {
|
||||
SQLProcessor msScriptElement = new SQLProcessor();
|
||||
msScriptElement.setEnable(element.isEnabled());
|
||||
msScriptElement.setName(element.getName());
|
||||
msScriptElement.setScript(element.getPropertyAsString("query"));
|
||||
try {
|
||||
msScriptElement.setQueryTimeout(element.getPropertyAsLong("queryTimeout"));
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
msScriptElement.setResultVariable(element.getPropertyAsString("resultVariable"));
|
||||
msScriptElement.setVariableNames(element.getPropertyAsString("variableNames"));
|
||||
return msScriptElement;
|
||||
}
|
||||
}
|
|
@ -1759,6 +1759,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
|
||||
//导入类型以及文件后缀
|
||||
Map<String, String> importTypeAndSuffix = new LinkedHashMap<>();
|
||||
// importTypeAndSuffix.put("jmeter", "jmx");
|
||||
importTypeAndSuffix.put("metersphere", "json");
|
||||
importTypeAndSuffix.put("postman", "json");
|
||||
importTypeAndSuffix.put("har", "har");
|
||||
|
@ -1997,11 +1998,40 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
Assertions.assertEquals(newApiDefinition.size(), 0);
|
||||
Assertions.assertEquals(newApiBlobList.size(), 0);
|
||||
Assertions.assertEquals(newApiTestCaseList.size(), 0);
|
||||
|
||||
}
|
||||
|
||||
// 最后测试一把JMeter。 5个请求,其中有4个重复的。 导入之后应该是2个请求5个用例,其中1个请求有4个用例
|
||||
File httpJmx = new File(
|
||||
this.getClass().getClassLoader().getResource("file/import/jmeter/post-page.jmx")
|
||||
.getPath()
|
||||
);
|
||||
|
||||
FileInputStream inputStream = new FileInputStream(new File(Objects.requireNonNull(this.getClass().getClassLoader().getResource("file/import/jmeter/post-page.jmx")).getPath()));
|
||||
MockMultipartFile file = new MockMultipartFile("file", "post-page.jmx", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream);
|
||||
ImportRequest request = new ImportRequest();
|
||||
request.setProjectId(importProject.getId());
|
||||
request.setUserId("admin");
|
||||
request.setPlatform("Jmeter");
|
||||
request.setSyncCase(true);
|
||||
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
||||
paramMap.add("request", JSON.toJSONString(request));
|
||||
paramMap.add("file", file);
|
||||
this.requestMultipartWithOkAndReturn(IMPORT, paramMap);
|
||||
List<ApiDefinitionModule> apiDefinitionModuleList = apiDefinitionModuleMapper.selectByExample(moduleExample);
|
||||
Assertions.assertEquals(0, apiDefinitionModuleList.size());
|
||||
List<ApiDefinitionBlob> apiDefinitionBlobs = apiDefinitionImportTestService.selectBlobByProjectId(importProject.getId());
|
||||
Assertions.assertEquals(2, apiDefinitionBlobs.size());
|
||||
|
||||
List<ApiTestCase> newApiTestCaseList = apiTestCaseMapper.selectByExample(apiTestCaseExample);
|
||||
Assertions.assertEquals(5, newApiTestCaseList.size());
|
||||
//去重处理
|
||||
List<String> apiDefinitionIdList = newApiTestCaseList.stream().map(ApiTestCase::getApiDefinitionId).distinct().collect(Collectors.toList());
|
||||
Assertions.assertEquals(2, apiDefinitionIdList.size());
|
||||
}
|
||||
|
||||
private void testExportAndImport(String exportProjectId, List<ApiDefinitionBlob> exportApiBlobs) throws Exception {
|
||||
ApiDefinitionBatchRequest exportRequest = new ApiDefinitionBatchRequest();
|
||||
ApiDefinitionBatchExportRequest exportRequest = new ApiDefinitionBatchExportRequest();
|
||||
exportRequest.setProjectId(exportProjectId);
|
||||
exportRequest.setSelectAll(true);
|
||||
exportRequest.setExportApiCase(true);
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.1">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<PostThreadGroup guiclass="PostThreadGroupGui" testclass="PostThreadGroup" testname="tearDown线程组" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">1</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">1</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||
</PostThreadGroup>
|
||||
<hashTree>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP请求" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">mbd.baidu.com</stringProp>
|
||||
<stringProp name="HTTPSampler.port"></stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">https</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path"></stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="察看结果树" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
|
@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
|
|||
import io.metersphere.project.api.processor.extract.MsExtract;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -17,5 +18,5 @@ public class ExtractPostProcessor extends MsProcessor {
|
|||
/**
|
||||
* 提取器列表
|
||||
*/
|
||||
private List<MsExtract> extractors;
|
||||
private List<MsExtract> extractors = new ArrayList<>();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotBlank;
|
|||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -52,5 +53,5 @@ public class SQLProcessor extends MsProcessor {
|
|||
* 提取参数
|
||||
*/
|
||||
@Valid
|
||||
private List<KeyValueParam> extractParams;
|
||||
private List<KeyValueParam> extractParams = new ArrayList<>();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.metersphere.plugin.api.spi.AbstractApiPlugin;
|
|||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.plugin.api.spi.AbstractProtocolPlugin;
|
||||
import io.metersphere.plugin.api.spi.MsTestElement;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.PluginScenarioType;
|
||||
import io.metersphere.sdk.dto.api.task.ApiExecuteFileInfo;
|
||||
|
@ -64,6 +65,15 @@ public class ApiPluginService {
|
|||
return protocols;
|
||||
}
|
||||
|
||||
public List<ProtocolDTO> getProtocolsByProjectId(String projectId) {
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
if (project == null) {
|
||||
return new ArrayList<>();
|
||||
} else {
|
||||
return this.getProtocols(project.getOrganizationId());
|
||||
}
|
||||
}
|
||||
|
||||
private List<PluginWrapper> getOrgProtocolPluginWrappers(String orgId) {
|
||||
return getOrgApiPluginWrappers(orgId).stream()
|
||||
.filter(plugin -> plugin.getPlugin() instanceof AbstractProtocolPlugin)
|
||||
|
|
Loading…
Reference in New Issue