From 3e14b9168f6f7a571bc2bd1f668449aec4700cf5 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Tue, 3 Aug 2021 17:31:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89JMe?= =?UTF-8?q?ter=E6=96=87=E4=BB=B6=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApiDefinitionImportParserFactory.java | 2 + .../parse/JmeterDefinitionParser.java | 504 ++++++++++++++++++ .../api/service/ApiDefinitionService.java | 8 +- .../components/import/ApiImport.vue | 10 +- 4 files changed, 519 insertions(+), 5 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java index 3fb2000af7..9340e90c9e 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/ApiDefinitionImportParserFactory.java @@ -16,6 +16,8 @@ public class ApiDefinitionImportParserFactory { return new HarParser(); }else if (StringUtils.equals(ApiImportPlatform.ESB.name(), platform)) { return new ESBParser(); + } else if (StringUtils.equals(ApiImportPlatform.Jmeter.name(), platform)) { + return new JmeterDefinitionParser(); } return null; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java new file mode 100644 index 0000000000..8fb5d86e4e --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/JmeterDefinitionParser.java @@ -0,0 +1,504 @@ +package io.metersphere.api.dto.definition.parse; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample; +import io.github.ningyu.jmeter.plugin.dubbo.sample.MethodArgument; +import io.github.ningyu.jmeter.plugin.util.Constants; +import io.metersphere.api.dto.ApiTestImportRequest; +import io.metersphere.api.dto.automation.ImportPoolsDTO; +import io.metersphere.api.dto.automation.parse.MsJmeterParser; +import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.sampler.MsDubboSampler; +import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; +import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler; +import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; +import io.metersphere.api.dto.definition.request.sampler.dubbo.MsConfigCenter; +import io.metersphere.api.dto.definition.request.sampler.dubbo.MsConsumerAndService; +import io.metersphere.api.dto.definition.request.sampler.dubbo.MsRegistryCenter; +import io.metersphere.api.dto.scenario.Body; +import io.metersphere.api.dto.scenario.DatabaseConfig; +import io.metersphere.api.dto.scenario.KeyValue; +import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; +import io.metersphere.api.dto.scenario.request.BodyFile; +import io.metersphere.api.dto.scenario.request.RequestType; +import io.metersphere.api.parse.ApiImportAbstractParser; +import io.metersphere.api.service.ApiTestEnvironmentService; +import io.metersphere.base.domain.*; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.BeanUtils; +import io.metersphere.commons.utils.CommonBeanFactory; +import io.metersphere.commons.utils.SessionUtils; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.ConfigTestElement; +import org.apache.jmeter.protocol.http.control.HeaderManager; +import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy; +import org.apache.jmeter.protocol.http.util.HTTPFileArg; +import org.apache.jmeter.protocol.jdbc.config.DataSourceElement; +import org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler; +import org.apache.jmeter.protocol.tcp.sampler.TCPSampler; +import org.apache.jmeter.save.SaveService; +import org.apache.jmeter.testelement.TestPlan; +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 JmeterDefinitionParser extends ApiImportAbstractParser { + private final Map> headerMap = new HashMap<>(); + private ImportPoolsDTO dataPools; + private final String ENV_NAME = "导入数据环境"; + + private ApiModule selectModule; + private ApiModule apiModule; + private String selectModulePath; + private String planName = "default"; + + @Override + public ApiDefinitionImport parse(InputStream inputSource, ApiTestImportRequest request) { + ApiDefinitionImport apiImport = new ApiDefinitionImport(); + this.projectId = request.getProjectId(); + try { + Object scriptWrapper = SaveService.loadElement(inputSource); + HashTree testPlan = this.getHashTree(scriptWrapper); + // 优先初始化数据源及部分参数 + preInitPool(request.getProjectId(), testPlan); + List elements = new ArrayList<>(); + List definitions = new ArrayList<>(); + List definitionCases = new ArrayList<>(); + + jmeterHashTree(testPlan, elements); + + this.selectModule = ApiDefinitionImportUtil.getSelectModule(request.getModuleId()); + if (this.selectModule != null) { + this.selectModulePath = ApiDefinitionImportUtil.getSelectModulePath(this.selectModule.getName(), this.selectModule.getParentId()); + } + this.apiModule = ApiDefinitionImportUtil.buildModule(this.selectModule, this.planName, this.projectId); + + for (MsTestElement element : elements) { + ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = buildApiDefinition(element); + if (apiDefinitionWithBLOBs != null) { + definitions.add(apiDefinitionWithBLOBs); + ApiTestCaseWithBLOBs apiTestCase = new ApiTestCaseWithBLOBs(); + BeanUtils.copyBean(apiTestCase, apiDefinitionWithBLOBs); + apiTestCase.setApiDefinitionId(apiDefinitionWithBLOBs.getId()); + apiTestCase.setStatus("Prepare"); + apiTestCase.setPriority("P0"); + definitionCases.add(apiTestCase); + } + } + apiImport.setData(definitions); + apiImport.setCases(definitionCases); + return apiImport; + } catch (Exception e) { + e.printStackTrace(); + MSException.throwException("当前JMX版本不兼容"); + } + return null; + } + + private void preCreate(HashTree tree) { + for (Object key : tree.keySet()) { + // JDBC 数据池 + if (key instanceof DataSourceElement) { + DataSourceElement dataSourceElement = (DataSourceElement) key; + DatabaseConfig newConfig = new DatabaseConfig(); + newConfig.setUsername(dataSourceElement.getPropertyAsString("username")); + newConfig.setPassword(dataSourceElement.getPropertyAsString("password")); + newConfig.setDriver(dataSourceElement.getPropertyAsString("driver")); + newConfig.setDbUrl(dataSourceElement.getPropertyAsString("dbUrl")); + newConfig.setName(dataSourceElement.getPropertyAsString("dataSource")); + newConfig.setPoolMax(dataSourceElement.getPropertyAsInt("poolMax")); + newConfig.setTimeout(dataSourceElement.getPropertyAsInt("timeout")); + if (dataPools != null && dataPools.getDataSources() != null && dataPools.getDataSources().containsKey(dataSourceElement.getPropertyAsString("dataSource"))) { + DatabaseConfig config = dataPools.getDataSources().get(dataSourceElement.getPropertyAsString("dataSource")); + newConfig.setId(config.getId()); + dataPools.getDataSources().put(dataSourceElement.getPropertyAsString("dataSource"), newConfig); + } else { + newConfig.setId(UUID.randomUUID().toString()); + if (dataPools.getDataSources() == null) { + dataPools.setDataSources(new HashMap<>()); + } + dataPools.getDataSources().put(dataSourceElement.getPropertyAsString("dataSource"), newConfig); + } + } else if (key instanceof HTTPSamplerProxy) { + // 把HTTP 请求下的HeaderManager 取出来 + HashTree node = tree.get(key); + if (node != null) { + for (Object nodeKey : node.keySet()) { + if (nodeKey instanceof HeaderManager) { + if (headerMap.containsKey(key.hashCode())) { + headerMap.get(key.hashCode()).add(nodeKey); + } else { + List objects = new LinkedList() {{ + this.add(nodeKey); + }}; + headerMap.put(key.hashCode(), objects); + } + } + } + } + } + + // 递归子项 + HashTree node = tree.get(key); + if (node != null) { + preCreate(node); + } + } + } + + private void preInitPool(String projectId, HashTree hashTree) { + // 初始化已有数据池 + initDataSource(projectId, ENV_NAME); + // 添加当前jmx 中新的数据池 + preCreate(hashTree); + // 更新数据源 + ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); + if (dataPools.getDataSources() != null) { + dataPools.getEnvConfig().setDatabaseConfigs(new ArrayList<>(dataPools.getDataSources().values())); + } + if (dataPools.getIsCreate()) { + dataPools.getTestEnvironmentWithBLOBs().setConfig(JSON.toJSONString(dataPools.getEnvConfig())); + String id = environmentService.add(dataPools.getTestEnvironmentWithBLOBs()); + dataPools.setEnvId(id); + } else { + dataPools.getTestEnvironmentWithBLOBs().setConfig(JSON.toJSONString(dataPools.getEnvConfig())); + environmentService.update(dataPools.getTestEnvironmentWithBLOBs()); + } + } + + private void initDataSource(String projectId, String name) { + ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); + ApiTestEnvironmentExample example = new ApiTestEnvironmentExample(); + example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo(name); + // 这里的数据只有一条,如果多条则有问题 + List environments = environmentService.selectByExampleWithBLOBs(example); + dataPools = new ImportPoolsDTO(); + if (CollectionUtils.isNotEmpty(environments)) { + dataPools.setIsCreate(false); + dataPools.setTestEnvironmentWithBLOBs(environments.get(0)); + Map dataSources = new HashMap<>(); + environments.forEach(environment -> { + if (environment != null && environment.getConfig() != null) { + EnvironmentConfig envConfig = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class); + dataPools.setEnvConfig(envConfig); + if (envConfig != null && CollectionUtils.isNotEmpty(envConfig.getDatabaseConfigs())) { + envConfig.getDatabaseConfigs().forEach(item -> dataSources.put(item.getName(), item)); + } + } + dataPools.setEnvId(environment.getId()); + dataPools.setDataSources(dataSources); + }); + } else { + dataPools.setIsCreate(true); + ApiTestEnvironmentWithBLOBs apiTestEnvironmentWithBLOBs = new ApiTestEnvironmentWithBLOBs(); + apiTestEnvironmentWithBLOBs.setId(UUID.randomUUID().toString()); + dataPools.setEnvId(apiTestEnvironmentWithBLOBs.getId()); + dataPools.setEnvConfig(new EnvironmentConfig()); + apiTestEnvironmentWithBLOBs.setName(ENV_NAME); + apiTestEnvironmentWithBLOBs.setProjectId(projectId); + dataPools.setTestEnvironmentWithBLOBs(apiTestEnvironmentWithBLOBs); + } + } + + private void preBuildApiDefinition(ApiDefinitionWithBLOBs apiDefinition, MsTestElement element, String protocol) { + apiDefinition.setId(UUID.randomUUID().toString()); + apiDefinition.setName(element.getName()); + apiDefinition.setProjectId(this.projectId); + apiDefinition.setRequest(JSON.toJSONString(element)); + if (this.selectModule != null) { + apiDefinition.setModuleId(this.apiModule.getId()); + if (StringUtils.isNotBlank(this.selectModulePath)) { + apiDefinition.setModulePath(this.selectModulePath + "/" + this.apiModule.getName()); + } else { + apiDefinition.setModulePath("/" + this.apiModule.getName()); + } + } + // todo 除HTTP协议外,其它协议设置默认模块 + apiDefinition.setStatus("Prepare"); + apiDefinition.setProtocol(protocol); + apiDefinition.setUserId(SessionUtils.getUserId()); + apiDefinition.setCreateTime(System.currentTimeMillis()); + apiDefinition.setUpdateTime(System.currentTimeMillis()); + apiDefinition.setCreateUser(SessionUtils.getUserId()); + apiDefinition.setCaseTotal("1"); + } + + private ApiDefinitionWithBLOBs buildApiDefinition(MsTestElement element) { + ApiDefinitionWithBLOBs apiDefinition = null; + if (element instanceof MsHTTPSamplerProxy) { + apiDefinition = new ApiDefinitionWithBLOBs(); + preBuildApiDefinition(apiDefinition, element, RequestType.HTTP); + apiDefinition.setPath(((MsHTTPSamplerProxy) element).getPath()); + apiDefinition.setMethod(((MsHTTPSamplerProxy) element).getMethod()); + apiDefinition.setUserId(SessionUtils.getUserId()); + } else if (element instanceof MsTCPSampler) { + apiDefinition = new ApiDefinitionWithBLOBs(); + preBuildApiDefinition(apiDefinition, element, RequestType.TCP); + apiDefinition.setMethod(RequestType.TCP); + } else if (element instanceof MsJDBCSampler) { + apiDefinition = new ApiDefinitionWithBLOBs(); + preBuildApiDefinition(apiDefinition, element, RequestType.SQL); + apiDefinition.setMethod(RequestType.SQL); + } else if (element instanceof MsDubboSampler) { + apiDefinition = new ApiDefinitionWithBLOBs(); + preBuildApiDefinition(apiDefinition, element, RequestType.DUBBO); + apiDefinition.setProtocol(RequestType.DUBBO); + apiDefinition.setMethod(((MsDubboSampler) element).getMethod()); + } + return apiDefinition; + } + + private HashTree getHashTree(Object scriptWrapper) throws Exception { + Field field = scriptWrapper.getClass().getDeclaredField("testPlan"); + field.setAccessible(true); + return (HashTree) field.get(scriptWrapper); + } + + private void jmeterHashTree(HashTree tree, List elements) { + for (Object key : tree.keySet()) { + MsTestElement elementNode = null; + // 测试计划 + if (key instanceof org.apache.jmeter.testelement.TestPlan) { + this.planName = ((TestPlan) key).getName(); + } + // HTTP请求 + else if (key instanceof HTTPSamplerProxy) { + elementNode = new MsHTTPSamplerProxy(); + ((MsHTTPSamplerProxy) elementNode).setBody(new Body()); + convertHttpSampler((MsHTTPSamplerProxy) elementNode, key); + } + // TCP请求 + else if (key instanceof TCPSampler) { + elementNode = new MsTCPSampler(); + TCPSampler tcpSampler = (TCPSampler) key; + convertTCPSampler((MsTCPSampler) elementNode, tcpSampler); + } + // DUBBO请求 + else if (key instanceof DubboSample) { + DubboSample sampler = (DubboSample) key; + elementNode = new MsDubboSampler(); + convertDubboSample((MsDubboSampler) elementNode, sampler); + } + // JDBC请求 + else if (key instanceof JDBCSampler) { + elementNode = new MsJDBCSampler(); + JDBCSampler jdbcSampler = (JDBCSampler) key; + convertJDBCSampler((MsJDBCSampler) elementNode, jdbcSampler); + } + + if (elementNode != null) { + elements.add(elementNode); + } + // 递归子项 + HashTree node = tree.get(key); + if (node != null) { + jmeterHashTree(node, elements); + } + } + } + + private void convertTCPSampler(MsTCPSampler msTCPSampler, TCPSampler tcpSampler) { + msTCPSampler.setName(tcpSampler.getName()); + msTCPSampler.setType("TCPSampler"); + msTCPSampler.setServer(tcpSampler.getServer()); + msTCPSampler.setPort(tcpSampler.getPort() + ""); + msTCPSampler.setCtimeout(tcpSampler.getConnectTimeout() + ""); + msTCPSampler.setReUseConnection(tcpSampler.getProperty(TCPSampler.RE_USE_CONNECTION).getBooleanValue()); + msTCPSampler.setNodelay(tcpSampler.getProperty(TCPSampler.NODELAY).getBooleanValue()); + msTCPSampler.setCloseConnection(tcpSampler.isCloseConnection()); + msTCPSampler.setSoLinger(tcpSampler.getSoLinger() + ""); + msTCPSampler.setEolByte(tcpSampler.getEolByte() + ""); + msTCPSampler.setRequest(tcpSampler.getRequestData()); + msTCPSampler.setUsername(tcpSampler.getProperty(ConfigTestElement.USERNAME).getStringValue()); + msTCPSampler.setPassword(tcpSampler.getProperty(ConfigTestElement.PASSWORD).getStringValue()); + } + + private void convertJDBCSampler(MsJDBCSampler msJDBCSampler, JDBCSampler jdbcSampler) { + msJDBCSampler.setType("JDBCSampler"); + msJDBCSampler.setName(jdbcSampler.getName()); + msJDBCSampler.setProtocol("SQL"); + msJDBCSampler.setQuery(jdbcSampler.getPropertyAsString("query")); + msJDBCSampler.setQueryTimeout(jdbcSampler.getPropertyAsInt("queryTimeout")); + msJDBCSampler.setResultVariable(jdbcSampler.getPropertyAsString("resultVariable")); + msJDBCSampler.setVariableNames(jdbcSampler.getPropertyAsString("variableNames")); + msJDBCSampler.setEnvironmentId(dataPools.getEnvId()); + if (dataPools.getDataSources() != null && dataPools.getDataSources().get(jdbcSampler.getPropertyAsString("dataSource")) != null) { + msJDBCSampler.setDataSourceId(dataPools.getDataSources().get(jdbcSampler.getPropertyAsString("dataSource")).getId()); + } + msJDBCSampler.setVariables(new LinkedList<>()); + } + + private void convertDubboSample(MsDubboSampler elementNode, DubboSample sampler) { + elementNode.setName(sampler.getName()); + elementNode.setType("DubboSampler"); + elementNode.set_interface(sampler.getPropertyAsString("FIELD_DUBBO_INTERFACE")); + elementNode.setMethod(sampler.getPropertyAsString("FIELD_DUBBO_METHOD")); + + MsConfigCenter configCenter = new MsConfigCenter(); + configCenter.setProtocol(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_PROTOCOL")); + configCenter.setGroup(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_GROUP")); + configCenter.setNamespace(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_NAMESPACE")); + configCenter.setUsername(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_USER_NAME")); + configCenter.setPassword(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_PASSWORD")); + configCenter.setAddress(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_ADDRESS")); + configCenter.setTimeout(sampler.getPropertyAsString("FIELD_DUBBO_CONFIG_CENTER_TIMEOUT")); + elementNode.setConfigCenter(configCenter); + + MsRegistryCenter registryCenter = new MsRegistryCenter(); + registryCenter.setProtocol(sampler.getPropertyAsString("FIELD_DUBBO_REGISTRY_PROTOCOL")); + registryCenter.setAddress(sampler.getPropertyAsString("FIELD_DUBBO_ADDRESS")); + registryCenter.setGroup(sampler.getPropertyAsString("FIELD_DUBBO_REGISTRY_GROUP")); + registryCenter.setUsername(sampler.getPropertyAsString("FIELD_DUBBO_REGISTRY_USER_NAME")); + registryCenter.setPassword(sampler.getPropertyAsString("FIELD_DUBBO_REGISTRY_PASSWORD")); + registryCenter.setTimeout(sampler.getPropertyAsString("FIELD_DUBBO_REGISTRY_TIMEOUT")); + elementNode.setRegistryCenter(registryCenter); + + MsConsumerAndService consumerAndService = new MsConsumerAndService(); + consumerAndService.setAsync(sampler.getPropertyAsString("FIELD_DUBBO_ASYNC")); + consumerAndService.setCluster(sampler.getPropertyAsString("FIELD_DUBBO_CLUSTER")); + consumerAndService.setConnections(sampler.getPropertyAsString("FIELD_DUBBO_CONNECTIONS")); + consumerAndService.setGroup(sampler.getPropertyAsString("FIELD_DUBBO_GROUP")); + consumerAndService.setLoadBalance(sampler.getPropertyAsString("FIELD_DUBBO_LOADBALANCE")); + consumerAndService.setVersion(sampler.getPropertyAsString("FIELD_DUBBO_VERSION")); + consumerAndService.setTimeout(sampler.getPropertyAsString("FIELD_DUBBO_TIMEOUT")); + elementNode.setConsumerAndService(consumerAndService); + + List methodArguments = Constants.getMethodArgs(sampler); + List methodArgs = new LinkedList<>(); + if (CollectionUtils.isNotEmpty(methodArguments)) { + methodArguments.forEach(item -> { + KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue()); + methodArgs.add(keyValue); + }); + } + elementNode.setArgs(methodArgs); + + List arguments = Constants.getAttachmentArgs(sampler); + List attachmentArgs = new LinkedList<>(); + if (CollectionUtils.isNotEmpty(arguments)) { + arguments.forEach(item -> { + KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue()); + attachmentArgs.add(keyValue); + }); + } + elementNode.setAttachmentArgs(attachmentArgs); + } + + private void convertHttpSampler(MsHTTPSamplerProxy samplerProxy, Object key) { + try { + HTTPSamplerProxy source = (HTTPSamplerProxy) key; + BeanUtils.copyBean(samplerProxy, source); + samplerProxy.setRest(new ArrayList() {{ + this.add(new KeyValue()); + }}); + samplerProxy.setArguments(new ArrayList() {{ + this.add(new KeyValue()); + }}); + // 处理HTTP协议的请求头 + if (headerMap.containsKey(key.hashCode())) { + List keyValues = new LinkedList<>(); + headerMap.get(key.hashCode()).forEach(item -> { + HeaderManager headerManager = (HeaderManager) item; + if (headerManager.getHeaders() != null) { + for (int i = 0; i < headerManager.getHeaders().size(); i++) { + keyValues.add(new KeyValue(headerManager.getHeader(i).getName(), headerManager.getHeader(i).getValue())); + } + } + }); + samplerProxy.setHeaders(keyValues); + } + // 初始化body + Body body = new Body(); + body.init(); + body.initKvs(); + body.getKvs().clear(); + body.initBinary(); + body.getBinary().clear(); + samplerProxy.setBody(body); + if (source != null && source.getHTTPFiles().length > 0) { + samplerProxy.getBody().initBinary(); + samplerProxy.getBody().setType(Body.FORM_DATA); + List keyValues = new LinkedList<>(); + for (HTTPFileArg arg : source.getHTTPFiles()) { + List files = new LinkedList<>(); + BodyFile file = new BodyFile(); + file.setId(arg.getParamName()); + String fileName = arg.getPath(); + if (fileName.indexOf("/") != -1) { + fileName = fileName.substring(fileName.lastIndexOf("/") + 1); + } + file.setName(fileName); + files.add(file); + + KeyValue keyValue = new KeyValue(arg.getParamName(), arg.getParamName()); + keyValue.setContentType(arg.getMimeType()); + keyValue.setType("file"); + keyValue.setFiles(files); + keyValues.add(keyValue); + } + samplerProxy.getBody().setKvs(keyValues); + } + samplerProxy.setProtocol(RequestType.HTTP); + samplerProxy.setConnectTimeout(source.getConnectTimeout() + ""); + samplerProxy.setResponseTimeout(source.getResponseTimeout() + ""); + samplerProxy.setPort(source.getPropertyAsString("HTTPSampler.port")); + samplerProxy.setDomain(source.getDomain()); + String bodyType = this.getBodyType(samplerProxy.getHeaders()); + if (source.getArguments() != null) { + if (source.getPostBodyRaw()) { + samplerProxy.getBody().setType(Body.RAW); + source.getArguments().getArgumentsAsMap().forEach((k, v) -> samplerProxy.getBody().setRaw(v)); + samplerProxy.getBody().initKvs(); + } else if (StringUtils.isNotEmpty(bodyType) || ("POST".equalsIgnoreCase(source.getMethod()) && source.getArguments().getArgumentsAsMap().size() > 0)) { + samplerProxy.getBody().setType(Body.WWW_FROM); + source.getArguments().getArgumentsAsMap().forEach((k, v) -> { + KeyValue keyValue = new KeyValue(k, v); + samplerProxy.getBody().getKvs().add(keyValue); + }); + } else if (samplerProxy.getBody() != null && samplerProxy.getBody().getType().equals(Body.FORM_DATA)) { + source.getArguments().getArgumentsAsMap().forEach((k, v) -> { + KeyValue keyValue = new KeyValue(k, v); + samplerProxy.getBody().getKvs().add(keyValue); + }); + } else { + List keyValues = new LinkedList<>(); + source.getArguments().getArgumentsAsMap().forEach((k, v) -> { + KeyValue keyValue = new KeyValue(k, v); + keyValues.add(keyValue); + }); + if (CollectionUtils.isNotEmpty(keyValues)) { + samplerProxy.setArguments(keyValues); + } + } + samplerProxy.getBody().initBinary(); + } + samplerProxy.setPath(source.getPath()); + samplerProxy.setMethod(source.getMethod()); + MsJmeterParser jmeterParser = new MsJmeterParser(); + if (jmeterParser.getUrl(source) != null) { + samplerProxy.setUrl(jmeterParser.getUrl(source)); + } + samplerProxy.setId(UUID.randomUUID().toString()); + samplerProxy.setType("HTTPSamplerProxy"); + body.getKvs().add(new KeyValue()); + body.getBinary().add(new KeyValue()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private String getBodyType(List headers) { + if (CollectionUtils.isNotEmpty(headers)) { + List keyValues = headers.stream().filter(keyValue -> "Content-Type".equals(keyValue.getName()) && "application/x-www-form-urlencoded".equals(keyValue.getValue())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(keyValues)) { + return keyValues.get(0).getValue(); + } + } + return null; + } +} diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 20e3899872..416a34ac50 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -548,11 +548,11 @@ public class ApiDefinitionService { int nextNum = 0; for (int i = 0; i < cases.size(); i++) { ApiTestCaseWithBLOBs item = cases.get(i); - if (i == 0) { - nextNum = apiTestCaseService.getNextNum(item.getApiDefinitionId()); - } else { - nextNum ++; + ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(item.getApiDefinitionId()); + if (apiDefinitionWithBLOBs == null) { + continue; } + nextNum = apiTestCaseService.getNextNum(item.getApiDefinitionId()); checkRequest.setName(item.getName()); checkRequest.setApiDefinitionId(item.getApiDefinitionId()); if (!apiTestCaseService.hasSameCase(checkRequest)) { diff --git a/frontend/src/business/components/api/definition/components/import/ApiImport.vue b/frontend/src/business/components/api/definition/components/import/ApiImport.vue index 47bfa6da5f..5c17c8512b 100644 --- a/frontend/src/business/components/api/definition/components/import/ApiImport.vue +++ b/frontend/src/business/components/api/definition/components/import/ApiImport.vue @@ -164,6 +164,13 @@ exportTip: this.$t('api_test.api_import.esb_export_tip'), suffixes: new Set(['xlsx', 'xls']) }, + jmeterPlatform: { + name: 'JMeter', + value: 'Jmeter', + tip: this.$t('api_test.api_import.jmeter_tip'), + exportTip: this.$t('api_test.api_import.jmeter_export_tip'), + suffixes: new Set(['jmx']) + }, selectedPlatform: {}, selectedPlatformValue: 'Metersphere', result: {}, @@ -189,6 +196,7 @@ this.platforms.push(this.postmanPlanform); this.platforms.push(this.swaggerPlanform); this.platforms.push(this.harPlanform); + this.platforms.push(this.jmeterPlatform); this.selectedPlatform = this.platforms[0]; }, watch: { @@ -381,7 +389,7 @@ } .header-bar { - padding: 10px 30px; + padding: 10px 15px; } .api-import >>> .el-dialog__body {